bitgo
Version:
BitGo JavaScript SDK
622 lines • 99.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sinon = require("sinon");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const openpgp = require("openpgp");
const nock = require("nock");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../../../../src");
const MPCv2PartiesEnum = sdk_core_1.ECDSAUtils.MPCv2PartiesEnum;
describe('signTxRequest:', function () {
let tssUtils;
let wallet;
let bitgo;
let baseCoin;
let bitgoGpgKey;
let bitgoPrvKeyObj;
const coinName = 'sol';
const reqId = new sdk_core_1.RequestTracer();
const txRequestId = 'randomTxReqId';
const signableHex = '02010206c2d5b5f4fb9a9bcd8a2f303e4d06f78d8ded300713f456da2abff0b3ea0185aa051a34bc8acd438763976f96876115050f73828553566d111d7ac8bffebf587c4f5f5987bfe26aa66013efd96d36360f2b4336c91f993259fb56051305614d42f2ea13f8ff9d7958dbf269c6e36bfdf5cb5c43de4b4e1d3efb7dab3d5d028604000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea94000003a621f6d1cc4b8fb2a739aa08e4034da0fc588ece3bd857630de30f7edde45dd0204030205010404000000040200030c02000000f0a29a3b00000000';
const serializedTxHex = `02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bc9df0b397bec2ed3b6444a8c33f38267cc08b5fb2a7d37e26b6c487e26d15b7c07830eb78e26a88db5de4aa6986a327f09aed8c01533e5b972748ddf60b80f${signableHex}`;
const messageRaw = 'TOO MANY SECRETS';
const messageEncoded = Buffer.from(messageRaw).toString('hex');
const txParams = {
recipients: [
{
address: 'HMEgbR4S2hLKfst2VZUVpHVUu4FioFPyW5iUuJvZdMvs',
amount: '999990000',
},
],
};
const txRequest = {
txRequestId,
enterpriseId: '4517abfb-f567-4b7a-9f91-407509d29403',
transactions: [
{
unsignedTx: {
serializedTxHex,
signableHex,
derivationPath: 'm/0', // Needs this when key derivation is supported
},
state: 'pendingSignature',
signatureShares: [],
},
],
unsignedTxs: [],
date: new Date().toISOString(),
intent: { intentType: 'payment' },
latest: true,
state: 'pendingUserSignature',
walletType: 'hot',
walletId: 'walletId',
policiesChecked: true,
version: 1,
userId: 'userId',
apiVersion: 'full',
};
const txRequestForMessageSigning = {
txRequestId,
enterpriseId: '4517abfb-f567-4b7a-9f91-407509d29403',
messages: [
{
messageRaw,
messageEncoded,
derivationPath: 'm/0',
state: 'pendingSignature',
signatureShares: [],
},
],
unsignedTxs: [],
date: new Date().toISOString(),
intent: { intentType: 'payment' },
latest: true,
state: 'pendingUserSignature',
walletType: 'hot',
walletId: 'walletId',
policiesChecked: true,
version: 1,
userId: 'userId',
apiVersion: 'full',
};
let userKeyShare;
let backupKeyShare;
let bitgoKeyShare;
before(async () => {
bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
bitgoGpgKey = await openpgp.generateKey({
userIDs: [{ name: 'bitgo', email: 'bitgo@test.com' }],
curve: 'ed25519',
format: 'armored',
});
bitgoPrvKeyObj = await openpgp.readPrivateKey({ armoredKey: bitgoGpgKey.privateKey });
const constants = {
mpc: {
bitgoPublicKey: bitgoGpgKey.publicKey,
bitgoEddsaMpcv2PublicKey: bitgoGpgKey.publicKey,
},
};
nock(bgUrl).get('/api/v1/client/constants').times(20).reply(200, { ttl: 3600, constants });
const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
userKeyShare = userDkg.getKeyShare();
backupKeyShare = backupDkg.getKeyShare();
bitgoKeyShare = bitgoDkg.getKeyShare();
baseCoin = bitgo.coin(coinName);
const walletData = {
id: txRequest.walletId,
enterprise: txRequest.enterpriseId,
coin: coinName,
coinSpecific: {
rootAddress: 'E7Z6pFfUhjx2dFjdB9Ws2KnKepXoq62TeF5uaCVSvqQV',
},
multisigType: 'tss',
multisigTypeVersion: 'MPCv2',
};
wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
tssUtils = new sdk_core_1.EDDSAUtils.EddsaMPCv2Utils(bitgo, baseCoin, wallet);
});
beforeEach(async function () {
await nockGetBitgoPublicKeyBasedOnFeatureFlags(coinName, txRequest.enterpriseId, bitgoGpgKey);
});
after(function () {
nock.cleanAll();
});
afterEach(function () {
nock.cleanAll();
});
it('successfully signs a txRequest with user key for an mps hot wallet with WP', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('successfully signs a txRequest with backup key for an mps hot wallet with WP', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 0, MPCv2PartiesEnum.BACKUP);
await Promise.all(nockPromises);
const backupPrvBase64 = Buffer.from(backupKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest,
prv: backupPrvBase64,
mpcv2PartyId: MPCv2PartiesEnum.BACKUP,
reqId,
txParams,
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('successfully signs a txRequest with a message for an mps hot wallet with WP', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequestForMessageSigning, sdk_core_1.RequestType.message);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequestForMessage({
txRequest: txRequestForMessageSigning,
prv: userPrvBase64,
reqId,
messageRaw: txRequestForMessageSigning.messages[0].messageRaw,
bufferToSign: Buffer.from(messageEncoded, 'hex'),
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('should throw if round 1 response has wrong type', async function () {
nock('https://bitgo.fakeurl')
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`)
.reply(200, {
txRequestId,
transactions: [
{
signatureShares: [
{
from: sdk_core_1.SignatureShareType.BITGO,
to: sdk_core_1.SignatureShareType.USER,
share: JSON.stringify({ type: 'round2Output', data: {} }),
},
],
},
],
});
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({ txRequest, prv: userPrvBase64, reqId, txParams })
.should.be.rejectedWith(/Unexpected signature share response/);
});
it('should throw if round 2 response has wrong type', async function () {
const messageBuffer = Buffer.from(signableHex, 'hex');
const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(MPCv2PartiesEnum.BITGO);
await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, txRequest.transactions[0].unsignedTx.derivationPath, MPCv2PartiesEnum.USER);
const bitgoMsg1 = bitgoDsg.getFirstMessage();
// Round 1: return a valid round1Output so the orchestration can proceed
nock('https://bitgo.fakeurl')
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
.reply(200, async (_uri, body) => {
const parsedShare = JSON.parse(body.signatureShares[0].share);
const userMsg1Bytes = Buffer.from(parsedShare.data.msg1.message, 'base64');
const userDeserializedMsg1 = {
from: MPCv2PartiesEnum.USER,
payload: new Uint8Array(userMsg1Bytes),
};
// Advance bitgo session (we don't need bitgoMsg2 for this test)
bitgoDsg.handleIncomingMessages([bitgoMsg1, userDeserializedMsg1]);
const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoPrvKeyObj);
const round1Output = {
type: 'round1Output',
data: { msg1: bitgoSignedMsg1 },
};
return {
txRequestId,
transactions: [
{
signatureShares: [
{
from: sdk_core_1.SignatureShareType.BITGO,
to: sdk_core_1.SignatureShareType.USER,
share: JSON.stringify(round1Output),
},
],
},
],
};
});
// Round 2: return a share with wrong type (round3Output instead of round2Output)
nock('https://bitgo.fakeurl')
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
.reply(200, {
txRequestId,
transactions: [
{
signatureShares: [
{
from: sdk_core_1.SignatureShareType.USER,
to: sdk_core_1.SignatureShareType.BITGO,
share: 'placeholder',
},
{
from: sdk_core_1.SignatureShareType.BITGO,
to: sdk_core_1.SignatureShareType.USER,
share: JSON.stringify({ type: 'round3Output', data: {} }),
},
],
},
],
});
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({ txRequest, prv: userPrvBase64, reqId, txParams })
.should.be.rejectedWith(/Unexpected signature share response. Unable to parse data./);
});
it('successfully signs a txRequest after receiving multiple 429 errors in round 2', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('successfully signs a txRequest after receiving multiple 429 errors in round 1', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3, MPCv2PartiesEnum.USER, 1);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('successfully signs a txRequest after receiving multiple 429 errors in round 3', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3, MPCv2PartiesEnum.USER, 3);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
});
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.true();
});
it('fails to sign a txRequest after receiving over 3 429 errors in round 2', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 4);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
})
.should.be.rejectedWith('Too many requests, slow down!');
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.false();
nockPromises[2].isDone().should.be.false();
nockPromises[3].isDone().should.be.false();
});
it('should throw if round 3 response is malformed', async function () {
const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 0, MPCv2PartiesEnum.USER, 2, true);
await Promise.all(nockPromises);
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({
txRequest,
prv: userPrvBase64,
reqId,
txParams,
})
.should.be.rejectedWith('Invalid txRequest object after round 3');
nockPromises[0].isDone().should.be.true();
nockPromises[1].isDone().should.be.true();
nockPromises[2].isDone().should.be.true();
nockPromises[3].isDone().should.be.false();
});
describe('resolveEffectiveTxParams guard (WCI-1111)', function () {
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
it('throws InvalidTransactionError when txParams is absent and intent has no recipients (malicious/empty-recipient path)', async function () {
// Simulate the stakingAuthorize attack vector: intent has no recipients
// and intentType is not on the NO_RECIPIENT_TX_TYPES allowlist.
const maliciousTxRequest = {
...txRequest,
intent: { intentType: 'stakingAuthorize' },
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({
txRequest: maliciousTxRequest,
prv: userPrvBase64,
reqId,
// No txParams — the re-sign path that was previously vulnerable
})
.should.be.rejectedWith(sdk_core_1.InvalidTransactionError);
});
it('throws InvalidTransactionError when txParams has empty recipients and intentType is not allowlisted', async function () {
const maliciousTxRequest = {
...txRequest,
intent: { intentType: 'payment' },
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils
.signTxRequest({
txRequest: maliciousTxRequest,
prv: userPrvBase64,
reqId,
txParams: { recipients: [] },
})
.should.be.rejectedWith(sdk_core_1.InvalidTransactionError);
});
it('does not throw for allowlisted no-recipient intentType (deactivate)', async function () {
sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
await Promise.all(nockPromises);
const noRecipientTxRequest = {
...txRequest,
intent: { intentType: 'deactivate' },
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest: noRecipientTxRequest,
prv: userPrvBase64,
reqId,
// No txParams — legitimate no-recipient flow
});
});
it('does not throw for allowlisted no-recipient intentType (consolidate)', async function () {
sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
await Promise.all(nockPromises);
const consolidateTxRequest = {
...txRequest,
intent: { intentType: 'consolidate' },
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest: consolidateTxRequest,
prv: userPrvBase64,
reqId,
});
});
it('uses intent recipients when txParams is absent and intent has recipients', async function () {
sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
await Promise.all(nockPromises);
const intentRecipientTxRequest = {
...txRequest,
intent: {
intentType: 'payment',
recipients: [
{
address: { address: 'HMEgbR4S2hLKfst2VZUVpHVUu4FioFPyW5iUuJvZdMvs' },
amount: { value: '999990000', symbol: 'sol' },
},
],
},
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
// Should not throw — intent provides the recipients
await tssUtils.signTxRequest({
txRequest: intentRecipientTxRequest,
prv: userPrvBase64,
reqId,
});
});
it('does not throw for staking intent with stakingRequestId (generic staking signal)', async function () {
sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
await Promise.all(nockPromises);
const stakingTxRequest = {
...txRequest,
intent: {
intentType: 'delegate',
stakingRequestId: 'staking-req-id-123',
},
};
const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
await tssUtils.signTxRequest({
txRequest: stakingTxRequest,
prv: userPrvBase64,
reqId,
});
});
});
async function getNockPromisesForEddsaSigning(txRequest, requestType = sdk_core_1.RequestType.tx, rateLimitErrorCount = 0, signerPartyId = MPCv2PartiesEnum.USER, rateLimitRound = 2, malformedRound3Response = false) {
const txOrMessageToSign = requestType === sdk_core_1.RequestType.message
? txRequest.messages[0].messageEncoded
: txRequest.transactions[0].unsignedTx.signableHex;
const messageBuffer = Buffer.from(txOrMessageToSign, 'hex');
const bitgoSession = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(MPCv2PartiesEnum.BITGO);
await bitgoSession.initDsg(bitgoKeyShare, messageBuffer, txRequest.transactions?.[0].unsignedTx.derivationPath || 'm/0', signerPartyId);
const bitgoMsg1 = bitgoSession.getFirstMessage();
let bitgoMsg2;
return [
await nockTxRequestResponseSignatureShareRoundOne(bitgoSession, txRequest, bitgoMsg1, bitgoPrvKeyObj, (msg) => {
bitgoMsg2 = msg;
}, requestType, signerPartyId, rateLimitRound === 1 ? rateLimitErrorCount : 0),
await nockTxRequestResponseSignatureShareRoundTwo(txRequest, () => bitgoMsg2, bitgoPrvKeyObj, requestType, rateLimitRound === 2 ? rateLimitErrorCount : 0, signerPartyId),
await nockTxRequestResponseSignatureShareRoundThree(txRequest, requestType, signerPartyId, rateLimitRound === 3 ? rateLimitErrorCount : 0, malformedRound3Response),
await nockSendTxRequest(txRequest, requestType),
];
}
});
async function nockGetBitgoPublicKeyBasedOnFeatureFlags(coin, enterpriseId, bitgoGpgKeyPair) {
const bitgoGPGPublicKeyResponse = {
name: 'irrelevant',
publicKey: bitgoGpgKeyPair.publicKey,
mpcv2PublicKey: bitgoGpgKeyPair.publicKey,
eddsaMpcv2PublicKey: bitgoGpgKeyPair.publicKey,
enterpriseId,
};
nock('https://bitgo.fakeurl')
.get(`/api/v2/${coin}/tss/pubkey`)
.times(4)
.query({ enterpriseId })
.reply(200, bitgoGPGPublicKeyResponse);
return bitgoGPGPublicKeyResponse;
}
async function nockTxRequestResponseSignatureShareRoundOne(bitgoSession, txRequest, bitgoMsg1, bitgoGpgPrivKey, saveBitgoMsg2, requestType = sdk_core_1.RequestType.tx, signerPartyId = MPCv2PartiesEnum.USER, rateLimitErrorCount = 0) {
const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
const scope = nock('https://bitgo.fakeurl');
if (rateLimitErrorCount > 0) {
scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
.times(rateLimitErrorCount)
.reply(429, {
error: 'Too many requests, slow down!',
name: 'TooManyRequests',
requestId: 'cm5qx01lh0013b2ek2sxl4w00',
context: {},
});
}
return scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
.reply(200, async (_uri, body) => {
const parsedShare = JSON.parse(body.signatureShares[0].share);
const userMsg1Bytes = Buffer.from(parsedShare.data.msg1.message, 'base64');
const userDeserializedMsg1 = {
from: signerPartyId,
payload: new Uint8Array(userMsg1Bytes),
};
const [bitgoMsg2] = bitgoSession.handleIncomingMessages([bitgoMsg1, userDeserializedMsg1]);
saveBitgoMsg2(bitgoMsg2);
const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
const round1Output = {
type: 'round1Output',
data: { msg1: bitgoSignedMsg1 },
};
const resource = requestType === sdk_core_1.RequestType.message ? 'messages' : 'transactions';
return {
txRequestId: txRequest.txRequestId,
[resource]: [
{
signatureShares: [
{
from: sdk_core_1.SignatureShareType.BITGO,
to: signerShareType,
share: JSON.stringify(round1Output),
},
],
},
],
};
});
}
async function nockTxRequestResponseSignatureShareRoundTwo(txRequest, getBitgoMsg2, bitgoGpgPrivKey, requestType = sdk_core_1.RequestType.tx, rateLimitErrorCount = 0, signerPartyId = MPCv2PartiesEnum.USER) {
const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
const scope = nock('https://bitgo.fakeurl');
const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
if (rateLimitErrorCount > 0) {
scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
.times(rateLimitErrorCount)
.reply(429, {
error: 'Too many requests, slow down!',
name: 'TooManyRequests',
requestId: 'cm5qx01lh0013b2ek2sxl4w00',
context: {},
});
}
return scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
.reply(200, async () => {
const bitgoMsg2 = getBitgoMsg2();
const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
const round2Output = {
type: 'round2Output',
data: { msg2: bitgoSignedMsg2 },
};
const resource = requestType === sdk_core_1.RequestType.message ? 'messages' : 'transactions';
return {
txRequestId: txRequest.txRequestId,
[resource]: [
{
signatureShares: [
{
from: signerShareType,
to: sdk_core_1.SignatureShareType.BITGO,
share: 'placeholder',
},
{
from: sdk_core_1.SignatureShareType.BITGO,
to: signerShareType,
share: JSON.stringify(round2Output),
},
],
},
],
};
});
}
async function nockTxRequestResponseSignatureShareRoundThree(txRequest, requestType = sdk_core_1.RequestType.tx, signerPartyId = MPCv2PartiesEnum.USER, rateLimitErrorCount = 0, malformedResponse = false) {
const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
const scope = nock('https://bitgo.fakeurl');
if (rateLimitErrorCount > 0) {
scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round3Input')
.times(rateLimitErrorCount)
.reply(429, {
error: 'Too many requests, slow down!',
name: 'TooManyRequests',
requestId: 'cm5qx01lh0013b2ek2sxl4w00',
context: {},
});
}
return scope
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round3Input')
.reply(200, malformedResponse
? { txRequestId: `${txRequest.txRequestId}-unexpected` }
: {
txRequestId: txRequest.txRequestId,
signatureShares: [
{
from: signerShareType,
to: sdk_core_1.SignatureShareType.BITGO,
share: 'placeholder',
},
],
});
}
async function nockSendTxRequest(txRequest, requestType = sdk_core_1.RequestType.tx) {
const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
return nock('https://bitgo.fakeurl')
.post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/send`)
.reply(200, {
txRequestId: txRequest.txRequestId,
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnblR4UmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC9pbnRlcm5hbC90c3NVdGlscy9lZGRzYU1QQ3YyL3NpZ25UeFJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBK0I7QUFDL0IsOENBYXlCO0FBQ3pCLG9EQUE4RTtBQUM5RSxtQ0FBbUM7QUFDbkMsNkJBQThCO0FBQzlCLDhDQUF3RDtBQVF4RCwrQ0FBOEM7QUFFOUMsTUFBTSxnQkFBZ0IsR0FBRyxxQkFBVSxDQUFDLGdCQUFnQixDQUFDO0FBT3JELFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN6QixJQUFJLFFBQW9DLENBQUM7SUFDekMsSUFBSSxNQUFjLENBQUM7SUFDbkIsSUFBSSxLQUF5QixDQUFDO0lBQzlCLElBQUksUUFBa0IsQ0FBQztJQUN2QixJQUFJLFdBQWtGLENBQUM7SUFDdkYsSUFBSSxjQUFrQyxDQUFDO0lBQ3ZDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztJQUV2QixNQUFNLEtBQUssR0FBRyxJQUFJLHdCQUFhLEVBQUUsQ0FBQztJQUNsQyxNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUM7SUFDcEMsTUFBTSxXQUFXLEdBQ2Ysa2dCQUFrZ0IsQ0FBQztJQUNyZ0IsTUFBTSxlQUFlLEdBQUcscVFBQXFRLFdBQVcsRUFBRSxDQUFDO0lBQzNTLE1BQU0sVUFBVSxHQUFHLGtCQUFrQixDQUFDO0lBQ3RDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9ELE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFO1lBQ1Y7Z0JBQ0UsT0FBTyxFQUFFLDhDQUE4QztnQkFDdkQsTUFBTSxFQUFFLFdBQVc7YUFDcEI7U0FDRjtLQUNGLENBQUM7SUFDRixNQUFNLFNBQVMsR0FBYztRQUMzQixX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Qyx1QkFBdUIsQ0FBQztTQUNqQyxJQUFJLENBQUMsa0JBQWtCLFNBQVMsQ0FBQyxRQUFRLGVBQWUsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFLLE9BQU8sQ0FBQztTQUM3RixLQUFLLENBQUMsR0FBRyxFQUFFO1FBQ1YsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXO0tBQ25DLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0Z29HUEdQdWJsaWNLZXksXG4gIGNvbW1vbixcbiAgRUNEU0FVdGlscyxcbiAgRUREU0FVdGlscyxcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIFJlcXVlc3RUcmFjZXIsXG4gIFJlcXVlc3RUeXBlLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgU2lnbmF0dXJlU2hhcmVUeXBlLFxuICBUeFJlcXVlc3QsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEVkZHNhTVBTRHNnLCBNUFNDb21tcywgTVBTVHlwZXMsIE1QU1V0aWwgfSBmcm9tICdAYml0Z28vc2RrLWxpYi1tcGMnO1xuaW1wb3J0ICogYXMgb3BlbnBncCBmcm9tICdvcGVucGdwJztcbmltcG9ydCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHsgVGVzdGFibGVCRywgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7XG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjJztcblxuY29uc3QgTVBDdjJQYXJ0aWVzRW51bSA9IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bTtcblxuaW50ZXJmYWNlIFNpZ25hdHVyZVNoYXJlQXBpQm9keSB7XG4gIHNpZ25hdHVyZVNoYXJlczogU2lnbmF0dXJlU2hhcmVSZWNvcmRbXTtcbiAgc2lnbmVyR3BnUHVibGljS2V5OiBzdHJpbmc7XG59XG5cbmRlc2NyaWJlKCdzaWduVHhSZXF1ZXN0OicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHRzc1V0aWxzOiBFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscztcbiAgbGV0IHdhbGxldDogV2FsbGV0O1xuICBsZXQgYml0Z286IFRlc3RhYmxlQkcgJiBCaXRHbztcbiAgbGV0IGJhc2VDb2luOiBCYXNlQ29pbjtcbiAgbGV0IGJpdGdvR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4gJiB7IHJldm9jYXRpb25DZXJ0aWZpY2F0ZTogc3RyaW5nIH07XG4gIGxldCBiaXRnb1BydktleU9iajogb3BlbnBncC5Qcml2YXRlS2V5O1xuICBjb25zdCBjb2luTmFtZSA9ICdzb2wnO1xuXG4gIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgY29uc3QgdHhSZXF1ZXN0SWQgPSAncmFuZG9tVHhSZXFJZCc7XG4gIGNvbnN0IHNpZ25hYmxlSGV4ID1cbiAgICAnMDIwMTAyMDZjMmQ1YjVmNGZiOWE5YmNkOGEyZjMwM2U0ZDA2Zjc4ZDhkZWQzMDA3MTNmNDU2ZGEyYWJmZjBiM2VhMDE4NWFhMDUxYTM0YmM4YWNkNDM4NzYzOTc2Zjk2ODc2MTE1MDUwZjczODI4NTUzNTY2ZDExMWQ3YWM4YmZmZWJmNTg3YzRmNWY1OTg3YmZlMjZhYTY2MDEzZWZkOTZkMzYzNjBmMmI0MzM2YzkxZjk5MzI1OWZiNTYwNTEzMDU2MTRkNDJmMmVhMTNmOGZmOWQ3OTU4ZGJmMjY5YzZlMzZiZmRmNWNiNWM0M2RlNGI0ZTFkM2VmYjdkYWIzZDVkMDI4NjA0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDAzYTYyMWY2ZDFjYzRiOGZiMmE3MzlhYTA4ZTQwMzRkYTBmYzU4OGVjZTNiZDg1NzYzMGRlMzBmN2VkZGU0NWRkMDIwNDAzMDIwNTAxMDQwNDAwMDAwMDA0MDIwMDAzMGMwMjAwMDAwMGYwYTI5YTNiMDAwMDAwMDAnO1xuICBjb25zdCBzZXJpYWxpemVkVHhIZXggPSBgMDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDNiYzlkZjBiMzk3YmVjMmVkM2I2NDQ0YThjMzNmMzgyNjdjYzA4YjVmYjJhN2QzN2UyNmI2YzQ4N2UyNmQxNWI3YzA3ODMwZWI3OGUyNmE4OGRiNWRlNGFhNjk4NmEzMjdmMDlhZWQ4YzAxNTMzZTViOTcyNzQ4ZGRmNjBiODBmJHtzaWduYWJsZUhleH1gO1xuICBjb25zdCBtZXNzYWdlUmF3ID0gJ1RPTyBNQU5ZIFNFQ1JFVFMnO1xuICBjb25zdCBtZXNzYWdlRW5jb2RlZCA9IEJ1ZmZlci5mcm9tKG1lc3NhZ2VSYXcpLnRvU3RyaW5nKCdoZXgnKTtcbiAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgcmVjaXBpZW50czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiAnSE1FZ2JSNFMyaExLZnN0MlZaVVZwSFZVdTRGaW9GUHlXNWlVdUp2WmRNdnMnLFxuICAgICAgICBhbW91bnQ6ICc5OTk5OTAwMDAnLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZCxcbiAgICBlbnRlcnByaXNlSWQ6ICc0NTE3YWJmYi1mNTY3LTRiN2EtOWY5MS00MDc1MDlkMjk0MDMnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJywgLy8gTmVlZHMgdGhpcyB3aGVuIGtleSBkZXJpdmF0aW9uIGlzIHN1cHBvcnRlZFxuICAgICAgICB9LFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdTaWduYXR1cmUnLFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgfSxcbiAgICBdLFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIGxhdGVzdDogdHJ1ZSxcbiAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICBwb2xpY2llc0NoZWNrZWQ6IHRydWUsXG4gICAgdmVyc2lvbjogMSxcbiAgICB1c2VySWQ6ICd1c2VySWQnLFxuICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgfTtcblxuICBjb25zdCB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZzogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkLFxuICAgIGVudGVycHJpc2VJZDogJzQ1MTdhYmZiLWY1NjctNGI3YS05ZjkxLTQwNzUwOWQyOTQwMycsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZVJhdyxcbiAgICAgICAgbWVzc2FnZUVuY29kZWQsXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgc3RhdGU6ICdwZW5kaW5nU2lnbmF0dXJlJyxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICB1bnNpZ25lZFR4czogW10sXG4gICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSxcbiAgICBsYXRlc3Q6IHRydWUsXG4gICAgc3RhdGU6ICdwZW5kaW5nVXNlclNpZ25hdHVyZScsXG4gICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgcG9saWNpZXNDaGVja2VkOiB0cnVlLFxuICAgIHZlcnNpb246IDEsXG4gICAgdXNlcklkOiAndXNlcklkJyxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gIH07XG5cbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcblxuICBiZWZvcmUoYXN5bmMgKCkgPT4ge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgIGJpdGdvR3BnS2V5ID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbeyBuYW1lOiAnYml0Z28nLCBlbWFpbDogJ2JpdGdvQHRlc3QuY29tJyB9XSxcbiAgICAgIGN1cnZlOiAnZWQyNTUxOScsXG4gICAgICBmb3JtYXQ6ICdhcm1vcmVkJyxcbiAgICB9KTtcbiAgICBiaXRnb1BydktleU9iaiA9IGF3YWl0IG9wZW5wZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiaXRnb0dwZ0tleS5wcml2YXRlS2V5IH0pO1xuICAgIGNvbnN0IGNvbnN0YW50cyA9IHtcbiAgICAgIG1wYzoge1xuICAgICAgICBiaXRnb1B1YmxpY0tleTogYml0Z29HcGdLZXkucHVibGljS2V5LFxuICAgICAgICBiaXRnb0VkZHNhTXBjdjJQdWJsaWNLZXk6IGJpdGdvR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnRpbWVzKDIwKS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHMgfSk7XG5cbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnLCBiaXRnb0RrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICB1c2VyS2V5U2hhcmUgPSB1c2VyRGtnLmdldEtleVNoYXJlKCk7XG4gICAgYmFja3VwS2V5U2hhcmUgPSBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcblxuICAgIGJhc2VDb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG5cbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6IHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIGVudGVycHJpc2U6IHR4UmVxdWVzdC5lbnRlcnByaXNlSWQsXG4gICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICByb290QWRkcmVzczogJ0U3WjZwRmZVaGp4MmRGamRCOVdzMktuS2VwWG9xNjJUZUY1dWFDVlN2cVFWJyxcbiAgICAgIH0sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgbXVsdGlzaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICB9O1xuICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB3YWxsZXREYXRhKTtcbiAgICB0c3NVdGlscyA9IG5ldyBFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4sIHdhbGxldCk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGF3YWl0IG5vY2tHZXRCaXRnb1B1YmxpY0tleUJhc2VkT25GZWF0dXJlRmxhZ3MoY29pbk5hbWUsIHR4UmVxdWVzdC5lbnRlcnByaXNlSWQhLCBiaXRnb0dwZ0tleSk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IHdpdGggdXNlciBrZXkgZm9yIGFuIG1wcyBob3Qgd2FsbGV0IHdpdGggV1AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgIHJlcUlkLFxuICAgICAgdHhQYXJhbXMsXG4gICAgfSk7XG4gICAgbm9ja1Byb21pc2VzWzBdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzFdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzNdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gIH0pO1xuXG4gIGl0KCdzdWNjZXNzZnVsbHkgc2lnbnMgYSB0eFJlcXVlc3Qgd2l0aCBiYWNrdXAga2V5IGZvciBhbiBtcHMgaG90IHdhbGxldCB3aXRoIFdQJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3QsIFJlcXVlc3RUeXBlLnR4LCAwLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IGJhY2t1cFBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKGJhY2t1cEtleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IGJhY2t1cFBydkJhc2U2NCxcbiAgICAgIG1wY3YyUGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICByZXFJZCxcbiAgICAgIHR4UGFyYW1zLFxuICAgIH0pO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IHdpdGggYSBtZXNzYWdlIGZvciBhbiBtcHMgaG90IHdhbGxldCB3aXRoIFdQJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZywgUmVxdWVzdFR5cGUubWVzc2FnZSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0Rm9yTWVzc2FnZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdEZvck1lc3NhZ2VTaWduaW5nLFxuICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgcmVxSWQsXG4gICAgICBtZXNzYWdlUmF3OiB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZy5tZXNzYWdlcyFbMF0ubWVzc2FnZVJhdyxcbiAgICAgIGJ1ZmZlclRvU2lnbjogQnVmZmVyLmZyb20obWVzc2FnZUVuY29kZWQsICdoZXgnKSxcbiAgICB9KTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMl0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbM10uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiByb3VuZCAxIHJlc3BvbnNlIGhhcyB3cm9uZyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAucG9zdChgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NpZ25gKVxuICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICAgICAgICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7fSB9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAuc2lnblR4UmVxdWVzdCh7IHR4UmVxdWVzdCwgcHJ2OiB1c2VyUHJ2QmFzZTY0LCByZXFJZCwgdHhQYXJhbXMgfSlcbiAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9VbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS8pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IGlmIHJvdW5kIDIgcmVzcG9uc2UgaGFzIHdyb25nIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGF3YWl0IGJpdGdvRHNnLmluaXREc2coXG4gICAgICBiaXRnb0tleVNoYXJlLFxuICAgICAgbWVzc2FnZUJ1ZmZlcixcbiAgICAgIHR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGgsXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgLy8gUm91bmQgMTogcmV0dXJuIGEgdmFsaWQgcm91bmQxT3V0cHV0IHNvIHRoZSBvcmNoZXN0cmF0aW9uIGNhbiBwcm9jZWVkXG4gICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgIC5wb3N0KFxuICAgICAgICBgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NpZ25gLFxuICAgICAgICAoYm9keSkgPT5cbiAgICAgICAgICAoSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQpLnR5cGUgPT09ICdyb3VuZDFJbnB1dCdcbiAgICAgIClcbiAgICAgIC5yZXBseShcbiAgICAgICAgMjAwLFxuICAgICAgICBhc3luYyAoX3VyaTogc3RyaW5nLCBib2R5OiB7IHNpZ25hdHVyZVNoYXJlczogU2lnbmF0dXJlU2hhcmVSZWNvcmRbXTsgc2lnbmVyR3BnUHVibGljS2V5OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZFNoYXJlID0gSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQ7XG4gICAgICAgICAgY29uc3QgdXNlck1zZzFCeXRlcyA9IEJ1ZmZlci5mcm9tKHBhcnNlZFNoYXJlLmRhdGEubXNnMS5tZXNzYWdlLCAnYmFzZTY0Jyk7XG4gICAgICAgICAgY29uc3QgdXNlckRlc2VyaWFsaXplZE1zZzE6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAgICAgICBwYXlsb2FkOiBuZXcgVWludDhBcnJheSh1c2VyTXNnMUJ5dGVzKSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIEFkdmFuY2UgYml0Z28gc2Vzc2lvbiAod2UgZG9uJ3QgbmVlZCBiaXRnb01zZzIgZm9yIHRoaXMgdGVzdClcbiAgICAgICAgICBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJEZXNlcmlhbGl6ZWRNc2cxXSk7XG4gICAgICAgICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb1BydktleU9iaik7XG4gICAgICAgICAgY29uc3Qgcm91bmQxT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQgPSB7XG4gICAgICAgICAgICB0eXBlOiAncm91bmQxT3V0cHV0JyxcbiAgICAgICAgICAgIGRhdGE6IHsgbXNnMTogYml0Z29TaWduZWRNc2cxIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICAgICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHJvdW5kMU91dHB1dCksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAvLyBSb3VuZCAyOiByZXR1cm4gYSBzaGFyZSB3aXRoIHdyb25nIHR5cGUgKHJvdW5kM091dHB1dCBpbnN0ZWFkIG9mIHJvdW5kMk91dHB1dClcbiAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgLnBvc3QoXG4gICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0vdHJhbnNhY3Rpb25zLzAvc2lnbmAsXG4gICAgICAgIChib2R5KSA9PlxuICAgICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCkudHlwZSA9PT0gJ3JvdW5kMklucHV0J1xuICAgICAgKVxuICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHNoYXJlOiAncGxhY2Vob2xkZXInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQzT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgLnNpZ25UeFJlcXVlc3QoeyB0eFJlcXVlc3QsIHBydjogdXNlclBydkJhc2U2NCwgcmVxSWQsIHR4UGFyYW1zIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLi8pO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IGFmdGVyIHJlY2VpdmluZyBtdWx0aXBsZSA0MjkgZXJyb3JzIGluIHJvdW5kIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDMpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICByZXFJZCxcbiAgICAgIHR4UGFyYW1zLFxuICAgIH0pO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IGFmdGVyIHJlY2VpdmluZyBtdWx0aXBsZSA0MjkgZXJyb3JzIGluIHJvdW5kIDEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDMsIE1QQ3YyUGFydGllc0VudW0uVVNFUiwgMSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgIHJlcUlkLFxuICAgICAgdHhQYXJhbXMsXG4gICAgfSk7XG4gICAgbm9ja1Byb21pc2VzWzBdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzFdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzNdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gIH0pO1xuXG4gIGl0KCdzdWNjZXNzZnVsbHkgc2lnbnMgYSB0eFJlcXVlc3QgYWZ0ZXIgcmVjZWl2aW5nIG11bHRpcGxlIDQyOSBlcnJvcnMgaW4gcm91bmQgMycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0LCBSZXF1ZXN0VHlwZS50eCwgMywgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCAzKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChub2NrUHJvbWlzZXMpO1xuXG4gICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGF3YWl0IHRzc1V0aWxzLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgcmVxSWQsXG4gICAgICB0eFBhcmFtcyxcbiAgICB9KTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMl0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbM10uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgfSk7XG5cbiAgaXQoJ2ZhaWxzIHRvIHNpZ24gYSB0eFJlcXVlc3QgYWZ0ZXIgcmVjZWl2aW5nIG92ZXIgMyA0MjkgZXJyb3JzIGluIHJvdW5kIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDQpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgIC5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0LFxuICAgICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICAgIHJlcUlkLFxuICAgICAgICB0eFBhcmFtcyxcbiAgICAgIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVG9vIG1hbnkgcmVxdWVzdHMsIHNsb3cgZG93biEnKTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiByb3VuZCAzIHJlc3BvbnNlIGlzIG1hbGZvcm1lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcoXG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBSZXF1ZXN0VHlwZS50eCxcbiAgICAgIDAsXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAyLFxuICAgICAgdHJ1ZVxuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgcmVxSWQsXG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgfSlcbiAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHR4UmVxdWVzdCBvYmplY3QgYWZ0ZXIgcm91bmQgMycpO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Jlc29sdmVFZmZlY3RpdmVUeFBhcmFtcyBndWFyZCAoV0NJLTExMTEpJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBzYW5kYm94OiBzaW5vbi5TaW5vblNhbmRib3g7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIEludmFsaWRUcmFuc2FjdGlvbkVycm9yIHdoZW4gdHhQYXJhbXMgaXMgYWJzZW50IGFuZCBpbnRlbnQgaGFzIG5vIHJlY2lwaWVudHMgKG1hbGljaW91cy9lbXB0eS1yZWNpcGllbnQgcGF0aCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBTaW11bGF0ZSB0aGUgc3Rha2luZ0F1dGhvcml6ZSBhdHRhY2sgdmVjdG9yOiBpbnRlbnQgaGFzIG5vIHJlY2lwaWVudHNcbiAgICAgIC8vIGFuZCBpbnRlbnRUeXBlIGlzIG5vdCBvbiB0aGUgTk9fUkVDSVBJRU5UX1RYX1RZUEVTIGFsbG93bGlzdC5cbiAgICAgIGNvbnN0IG1hbGljaW91c1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAnc3Rha2luZ0F1dGhvcml6ZScgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogbWFsaWNpb3VzVHhSZXF1ZXN0LFxuICAgICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAvLyBObyB0eFBhcmFtcyDigJQgdGhlIHJlLXNpZ24gcGF0aCB0aGF0IHdhcyBwcmV2aW91c2x5IHZ1bG5lcmFibGVcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvciB3aGVuIHR4UGFyYW1zIGhhcyBlbXB0eSByZWNpcGllbnRzIGFuZCBpbnRlbnRUeXBlIGlzIG5vdCBhbGxvd2xpc3RlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1hbGljaW91c1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogbWFsaWNpb3VzVHhSZXF1ZXN0LFxuICAgICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB0eFBhcmFtczogeyByZWNpcGllbnRzOiBbXSB9LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnZG9lcyBub3QgdGhyb3cgZm9yIGFsbG93bGlzdGVkIG5vLXJlY2lwaWVudCBpbnRlbnRUeXBlIChkZWFjdGl2YXRlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3guc3R1YihiYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICAgIGNvbnN0IG5vUmVjaXBpZW50VHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWFjdGl2YXRlJyB9IGFzIGFueSxcbiAgICAgIH07XG4gICAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0OiBub1JlY2lwaWVudFR4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgICAgLy8gTm8gdHhQYXJhbXMg4oCUIGxlZ2l0aW1hdGUgbm8tcmVjaXBpZW50IGZsb3dcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RvZXMgbm90IHRocm93IGZvciBhbGxvd2xpc3RlZCBuby1yZWNpcGllbnQgaW50ZW50VHlwZSAoY29uc29saWRhdGUpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5zdHViKGJhc2VDb2luLCAndmVyaWZ5VHJhbnNhY3Rpb24nKS5yZXNvbHZlcyh0cnVlKTtcbiAgICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3QpO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgICAgY29uc3QgY29uc29saWRhdGVUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgICAgLi4udHhSZXF1ZXN0LFxuICAgICAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ2NvbnNvbGlkYXRlJyB9IGFzIGFueSxcbiAgICAgIH07XG4gICAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0OiBjb25zb2xpZGF0ZVR4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3VzZXMgaW50ZW50IHJlY2lwaWVudHMgd2hlbiB0eFBhcmFtcyBpcyBhYnNlbnQgYW5kIGludGVudCBoYXMgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3guc3R1YihiYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICAgIGNvbnN0IGludGVudFJlY2lwaWVudFR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDoge1xuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IHsgYWRkcmVzczogJ0hNRWdiUjRTMmhMS2ZzdDJWWlVWcEhWVXU0RmlvRlB5VzVpVXVKdlpkTXZzJyB9LFxuICAgICAgICAgICAgICBhbW91bnQ6IHsgdmFsdWU6ICc5OTk5OTAwMDAnLCBzeW1ib2w6ICdzb2wnIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgIC8vIFNob3VsZCBub3QgdGhyb3cg4oCUIGludGVudCBwcm92aWRlcyB0aGUgcmVjaXBpZW50c1xuICAgICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgIHR4UmVxdWVzdDogaW50ZW50UmVjaXBpZW50VHhSZXF1ZXN0LFxuICAgICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICAgIHJlcUlkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZG9lcyBub3QgdGhyb3cgZm9yIHN0YWtpbmcgaW50ZW50IHdpdGggc3Rha2luZ1JlcXVlc3RJZCAoZ2VuZXJpYyBzdGFraW5nIHNpZ25hbCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnN0dWIoYmFzZUNvaW4sICd2ZXJpZnlUcmFuc2FjdGlvbicpLnJlc29sdmVzKHRydWUpO1xuICAgICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCk7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChub2NrUHJvbWlzZXMpO1xuXG4gICAgICBjb25zdCBzdGFraW5nVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgaW50ZW50OiB7XG4gICAgICAgICAgaW50ZW50VHlwZTogJ2RlbGVnYXRlJyxcbiAgICAgICAgICBzdGFraW5nUmVxdWVzdElkOiAnc3Rha2luZy1yZXEtaWQtMTIzJyxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgIHR4UmVxdWVzdDogc3Rha2luZ1R4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcoXG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlID0gUmVxdWVzdFR5cGUudHgsXG4gICAgcmF0ZUxpbWl0RXJyb3JDb3VudCA9IDAsXG4gICAgc2lnbmVyUGFydHlJZDogRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtID0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIHJhdGVMaW1pdFJvdW5kID0gMixcbiAgICBtYWxmb3JtZWRSb3VuZDNSZXNwb25zZSA9IGZhbHNlXG4gICk6IFByb21pc2U8bm9jay5TY29wZVtdPiB7XG4gICAgY29uc3QgdHhPck1lc3NhZ2VUb1NpZ24gPVxuICAgICAgcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2VcbiAgICAgICAgPyB0eFJlcXVlc3QubWVzc2FnZXMhWzBdLm1lc3NhZ2VFbmNvZGVkIVxuICAgICAgICA6IHR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnVuc2lnbmVkVHguc2lnbmFibGVIZXg7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHR4T3JNZXNzYWdlVG9TaWduLCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29TZXNzaW9uID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb1Nlc3Npb24uaW5pdERzZyhcbiAgICAgIGJpdGdvS2V5U2hhcmUsXG4gICAgICBtZXNzYWdlQnVmZmVyLFxuICAgICAgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucz8uWzBdLnVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGggfHwgJ20vMCcsXG4gICAgICBzaWduZXJQYXJ0eUlkXG4gICAgKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb1Nlc3Npb24uZ2V0Rmlyc3RNZXNzYWdlKCk7XG4gICAgbGV0IGJpdGdvTXNnMjogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSB8IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBbXG4gICAgICBhd2FpdCBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICAgICAgICBiaXRnb1Nlc3Npb24sXG4gICAgICAgIHR4UmVxdWVzdCxcbiAgICAgICAgYml0Z29Nc2cxLFxuICAgICAgICBiaXRnb1BydktleU9iaixcbiAgICAgICAgKG1zZykgPT4ge1xuICAgICAgICAgIGJpdGdvTXNnMiA9IG1zZztcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICAgIHNpZ25lclBhcnR5SWQsXG4gICAgICAgIHJhdGVMaW1pdFJvdW5kID09PSAxID8gcmF0ZUxpbWl0RXJyb3JDb3VudCA6IDBcbiAgICAgICksXG4gICAgICBhd2FpdCBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kVHdvKFxuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgICgpID0+IGJpdGdvTXNnMiEsXG4gICAgICAgIGJpdGdvUHJ2S2V5T2JqLFxuICAgICAgICByZXF1ZXN0VHlwZSxcbiAgICAgICAgcmF0ZUxpbWl0Um91bmQgPT09IDIgPyByYXRlTGltaXRFcnJvckNvdW50IDogMCxcbiAgICAgICAgc2lnbmVyUGFydHlJZFxuICAgICAgKSxcbiAgICAgIGF3YWl0IG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZShcbiAgICAgICAgdHhSZXF1ZXN0LFxuICAgICAgICByZXF1ZXN0VHlwZSxcbiAgICAgICAgc2lnbmVyUGFydHlJZCxcbiAgICAgICAgcmF0ZUxpbWl0Um91bmQgPT09IDMgPyByYXRlTGltaXRFcnJvckNvdW50IDogMCxcbiAgICAgICAgbWFsZm9ybWVkUm91bmQzUmVzcG9uc2VcbiAgICAgICksXG4gICAgICBhd2FpdCBub2NrU2VuZFR4UmVxdWVzdCh0eFJlcXVlc3QsIHJlcXVlc3RUeXBlKSxcbiAgICBdO1xuICB9XG59KTtcblxuYXN5bmMgZnVuY3Rpb24gbm9ja0dldEJpdGdvUHVibGljS2V5QmFzZWRPbkZlYXR1cmVGbGFncyhcbiAgY29pbjogc3RyaW5nLFxuICBlbnRlcnByaXNlSWQ6IHN0cmluZyxcbiAgYml0Z29HcGdLZXlQYWlyOiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz5cbik6IFByb21pc2U8Qml0Z29HUEdQdWJsaWNLZXk+IHtcbiAgY29uc3QgYml0Z29HUEdQdWJsaWNLZXlSZXNwb25zZTogQml0Z29HUEdQdWJsaWNLZXkgPSB7XG4gICAgbmFtZTogJ2lycmVsZXZhbnQnLFxuICAgIHB1YmxpY0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICBtcGN2MlB1YmxpY0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICBlZGRzYU1wY3YyUHVibGljS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgIGVudGVycHJpc2VJZCxcbiAgfTtcbiAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAuZ2V0KGAvYXBpL3YyLyR7Y29pbn0vdHNzL3B1YmtleWApXG4gICAgLnRpbWVzKDQpXG4gICAgLnF1ZXJ5KHsgZW50ZXJwcmlzZUlkIH0pXG4gICAgLnJlcGx5KDIwMCwgYml0Z29HUEdQdWJsaWNLZXlSZXNwb25zZSk7XG4gIHJldHVybiBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICBiaXRnb1Nlc3Npb246IEVkZHNhTVBTRHNnLkRTRyxcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIGJpdGdvTXNnMTogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSxcbiAgYml0Z29HcGdQcml2S2V5OiBvcGVucGdwLlByaXZhdGVLZXksXG4gIHNhdmVCaXRnb01zZzI6IChtc2c6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UpID0+IHZvaWQsXG4gIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4LFxuICBzaWduZXJQYXJ0eUlkOiBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0gPSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gIHJhdGVMaW1pdEVycm9yQ291bnQgPSAwXG4pOiBQcm9taXNlPG5vY2suU2NvcGU+IHtcbiAgY29uc3Qgcm91dGUgPSByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSA/ICcvbWVzc2FnZXMvMCcgOiAnL3RyYW5zYWN0aW9ucy8wJztcbiAgY29uc3Qgc2lnbmVyU2hhcmVUeXBlID0gc2lnbmVyUGFydHlJZCA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSID8gU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIgOiBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQO1xuICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpO1xuXG4gIGlmIChyYXRlTGltaXRFcnJvckNvdW50ID4gMCkge1xuICAgIHNjb3BlXG4gICAgICAucG9zdChcbiAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgICAoYm9keSkgPT5cbiAgICAgICAgICAoSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQpLnR5cGUgPT09ICdyb3VuZDFJbnB1dCdcbiAgICAgIClcbiAgICAgIC50aW1lcyhyYXRlTGltaXRFcnJvckNvdW50KVxuICAgICAgLnJlcGx5KDQyOSwge1xuICAgICAgICBlcnJvcjogJ1RvbyBtYW55IHJlcXVlc3RzLCBzbG93IGRvd24hJyxcbiAgICAgICAgbmFtZTogJ1Rvb01hbnlSZXF1ZXN0cycsXG4gICAgICAgIHJlcXVlc3RJZDogJ2NtNXF4MDFsaDAwMTNiMmVrMnN4bDR3MDAnLFxuICAgICAgICBjb250ZXh0OiB7fSxcbiAgICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNjb3BlXG4gICAgLnBvc3QoXG4gICAgICBgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9JHtyb3V0ZX0vc2lnbmAsXG4gICAgICAoYm9keSkgPT5cbiAgICAgICAgKEpTT04ucGFyc2UoYm9keS5zaWduYXR1cmVTaGFyZXNbMF0uc2hhcmUpIGFzIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0KS50eXBlID09PSAncm91bmQxSW5wdXQnXG4gICAgKVxuICAgIC5yZXBseSgyMDAsIGFzeW5jIChfdXJpOiBzdHJpbmcsIGJvZHk6IFNpZ25hdHVyZVNoYXJlQXBpQm9keSkgPT4ge1xuICAgICAgY29uc3QgcGFyc2VkU2hhcmUgPSBKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dDtcbiAgICAgIGNvbnN0IHVzZXJNc2cxQnl0ZXMgPSBCdWZmZXIuZnJvbShwYXJzZWRTaGFyZS5kYXRhLm1zZzEubWVzc2FnZSwgJ2Jhc2U2NCcpO1xuICAgICAgY29uc3QgdXNlckRlc2VyaWFsaXplZE1zZzE6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgPSB7XG4gICAgICAgIGZyb206IHNpZ25lclBhcnR5SWQsXG4gICAgICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJNc2cxQnl0ZXMpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29TZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JpdGdvTXNnMSwgdXNlckRlc2VyaWFsaXplZE1zZzFdKTtcbiAgICAgIHNhdmVCaXRnb01zZzIoYml0Z29Nc2cyKTtcblxuICAgICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgICAgY29uc3Qgcm91bmQxT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQgPSB7XG4gICAgICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgICAgICBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc291cmNlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnbWVzc2FnZXMnIDogJ3RyYW5zYWN0aW9ucyc7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICBbcmVzb3VyY2VdOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQxT3V0cHV0KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUd28oXG4gIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICBnZXRCaXRnb01zZzI6ICgpID0+IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UsXG4gIGJpdGdvR3BnUHJpdktleTogb3BlbnBncC5Qcml2YXRlS2V5LFxuICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGUgPSBSZXF1ZXN0VHlwZS50eCxcbiAgcmF0ZUxpbWl0RXJyb3JDb3VudCA9IDAsXG4gIHNpZ25lclBhcnR5SWQ6IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bSA9IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuKTogUHJvbWlzZTxub2NrLlNjb3BlPiB7XG4gIGNvbnN0IHJvdXRlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnL21lc3NhZ2VzLzAnIDogJy90cmFuc2FjdGlvbnMvMCc7XG4gIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJyk7XG4gIGNvbnN0IHNpZ25lclNoYXJlVHlwZSA9IHNpZ25lclBhcnR5SWQgPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiA/IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSIDogU2lnbmF0dXJlU2hhcmVUeXBlLkJBQ0tVUDtcblxuICBpZiAocmF0ZUxpbWl0RXJyb3JDb3VudCA+IDApIHtcbiAgICBzY29wZVxuICAgICAgLnBvc3QoXG4gICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zaWduYCxcbiAgICAgICAgKGJvZHkpID0+XG4gICAgICAgICAgKEpTT04ucGFyc2UoYm9keS5zaWduYXR1cmVTaGFyZXNbMF0uc2hhcmUpIGFzIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0KS50eXBlID09PSAncm91bmQySW5wdXQnXG4gICAgICApXG4gICAgICAudGltZXMocmF0ZUxpbWl0RXJyb3JDb3VudClcbiAgICAgIC5yZXBseSg0MjksIHtcbiAgICAgICAgZXJyb3I6ICdUb28gbWFueSByZXF1ZXN0cywgc2xvdyBkb3duIScsXG4gICAgICAgIG5hbWU6ICdUb29NYW55UmVxdWVzdHMnLFxuICAgICAgICByZXF1ZXN0SWQ6ICdjbTVxeDAxbGgwMDEzYjJlazJzeGw0dzAwJyxcbiAgICAgICAgY29udGV4dDoge30sXG4gICAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzY29wZVxuICAgIC5wb3N0KFxuICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgKGJvZHkpID0+XG4gICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCkudHlwZSA9PT0gJ3JvdW5kMklucHV0J1xuICAgIClcbiAgICAucmVwbHkoMjAwLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBiaXRnb01zZzIgPSBnZXRCaXRnb01zZzIoKTtcbiAgICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgICB0eXBlOiAncm91bmQyT3V0cHV0JyxcbiAgICAgICAgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNvdXJjZSA9IHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS5tZXNzYWdlID8gJ21lc3NhZ2VzJyA6ICd0cmFuc2FjdGlvbnMnO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgW3Jlc291cmNlXTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZnJvbTogc2lnbmVyU2hhcmVUeXBlLFxuICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgc2hhcmU6ICdwbGFjZWhvbGRlcicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQyT3V0cHV0KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZShcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4LFxuICBzaWduZXJQYXJ0eUlkOiBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0gPSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gIHJhdGVMaW1pdEVycm9yQ291bnQgPSAwLFxuICBtYWxmb3JtZWRSZXNwb25zZSA9IGZhbHNlXG4pOiBQcm9taXNlPG5vY2suU2NvcGU+IHtcbiAgY29uc3Qgcm91dGUgPSByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSA/ICcvbWVzc2FnZXMvMCcgOiAnL3RyYW5zYWN0aW9ucy8wJztcbiAgY29uc3Qgc2lnbmVyU2hhcmVUeXBlID0gc2lnbmVyUGFydHlJZCA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSID8gU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIgOiBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQO1xuICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpO1xuXG4gIGlmIChyYXRlTGltaXRFcnJvckNvdW50ID4gMCkge1xuICAgIHNjb3BlXG4gICAgICAucG9zdChcbiAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgICAoYm9keTogU2lnbmF0dXJlU2hhcmVBcGlCb2R5KSA9PlxuICAgICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCkudHlwZSA9PT0gJ3JvdW5kM0lucHV0J1xuICAgICAgKVxuICAgICAgLnRpbWVzKHJhdGVMaW1pdEVycm9yQ291bnQpXG4gICAgICAucmVwbHkoNDI5LCB7XG4gICAgICAgIGVycm9yOiAnVG9vIG1hbnkgcmVxdWVzdHMsIHNsb3cgZG93biEnLFxuICAgICAgICBuYW1lOiAnVG9vTWFueVJlcXVlc3RzJyxcbiAgICAgICAgcmVxdWVzdElkOiAnY201cXgwMWxoMDAxM2IyZWsyc3hsNHcwMCcsXG4gICAgICAgIGNvbnRleHQ6IHt9LFxuICAgICAgfSk7XG4gIH1cblxuICByZXR1cm4gc2NvcGVcbiAgICAucG9zdChcbiAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zaWduYCxcbiAgICAgIChib2R5OiBTaWduYXR1cmVTaGFyZUFwaUJvZHkpID0+XG4gICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCkudHlwZSA9PT0gJ3JvdW5kM0lucHV0J1xuICAgIClcbiAgICAucmVwbHkoXG4gICAgICAyMDAsXG4gICAgICBtYWxmb3JtZWRSZXNwb25zZVxuICAgICAgICA/IHsgdHhSZXF1ZXN0SWQ6IGAke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0tdW5leHBlY3RlZGAgfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZyb206IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHNoYXJlOiAncGxhY2Vob2xkZXInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9XG4gICAgKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbm9ja1NlbmRUeFJlcXVlc3QodHhSZXF1ZXN0OiBUeFJlcXVlc3QsIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4KTogUHJvbWlzZTxub2NrLlNjb3BlPiB7XG4gIGNvbnN0IHJvdXRlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnL21lc3NhZ2VzLzAnIDogJy90cmFuc2FjdGlvbnMvMCc7XG4gIHJldHVybiBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zZW5kYClcbiAgICAucmVwbHkoMjAwLCB7XG4gICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgIH0pO1xufVxuIl19