PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-sol/dist/test/unit
Просмотр файла: instructionParamsFactory.staking.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const should_1 = __importDefault(require("should"));
const testData = __importStar(require("../resources/sol"));
const instructionParamsFactory_1 = require("../../src/lib/instructionParamsFactory");
const sdk_core_1 = require("@bitgo/sdk-core");
const constants_1 = require("../../src/lib/constants");
const web3_js_1 = require("@solana/web3.js");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
describe('Instruction Parser Staking Tests: ', function () {
describe('Activate staking instructions ', function () {
it('Should parse activate stake tx instructions with memo and durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const stakingActivateParams = {
type: constants_1.InstructionBuilderTypes.StakingActivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
validator: validator.toString(),
amount,
isMarinade: false,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [
nonceAdvanceInstruction,
...stakingActivateInstructions,
...stakingDelegateInstructions,
memoInstruction,
];
const instructionsData = [nonceAdvanceParams, memoParams, stakingActivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse activate stake tx instructions with memo and durable nonce with instructions in any order', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const stakingActivateParams = {
type: constants_1.InstructionBuilderTypes.StakingActivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
validator: validator.toString(),
amount,
isMarinade: false,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [
memoInstruction,
...stakingActivateInstructions,
...stakingDelegateInstructions,
nonceAdvanceInstruction,
];
const instructionsData = [memoParams, nonceAdvanceParams, stakingActivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse activate stake tx instructions without memo or durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
// Instructions
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
// Params
const stakingActivateParams = {
type: constants_1.InstructionBuilderTypes.StakingActivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
validator: validator.toString(),
amount,
isMarinade: false,
},
};
const instructions = [...stakingActivateInstructions, ...stakingDelegateInstructions];
const instructionsData = [stakingActivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse activate stake tx instructions if there are unexpected instructions', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
// Instructions
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
}).instructions;
// Params
const stakingActivateParams = {
type: constants_1.InstructionBuilderTypes.StakingActivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
validator: validator.toString(),
amount,
isMarinade: false,
},
};
const instructions = [
...stakingActivateInstructions,
...stakingDelegateInstructions,
...stakingDeactivateInstructions,
];
const instructionsData = [stakingActivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should fail to parse activate stake tx instructions if there are missing instructions', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
// Instructions
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
should_1.default.throws(() => {
const instructions = [stakingActivateInstructions[1], ...stakingDelegateInstructions];
(0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
}, 'Invalid staking activate transaction, missing create stake account instruction');
should_1.default.throws(() => {
const instructions = [stakingActivateInstructions[0]];
(0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingActivate, instructions);
}, 'Invalid staking activate transaction, missing initialize stake account/delegate instruction');
});
});
describe('Deactivate staking instructions ', function () {
it('Should parse deactivate stake tx instructions with memo and durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const stakingDeactivateParams = {
type: constants_1.InstructionBuilderTypes.StakingDeactivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount: undefined,
unstakingAddress: undefined,
isMarinade: false,
recipients: undefined,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [nonceAdvanceInstruction, ...stakingDeactivateInstructions, memoInstruction];
const instructionsData = [nonceAdvanceParams, memoParams, stakingDeactivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse deactivate stake tx instructions with memo and durable nonce with instructions in any order', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const stakingDeactivateParams = {
type: constants_1.InstructionBuilderTypes.StakingDeactivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount: undefined,
unstakingAddress: undefined,
isMarinade: false,
recipients: undefined,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [memoInstruction, ...stakingDeactivateInstructions, nonceAdvanceInstruction];
const instructionsData = [memoParams, nonceAdvanceParams, stakingDeactivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse deactivate stake tx instructions without memo or durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
// Instructions
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
}).instructions;
// Params
const stakingDeactivateParams = {
type: constants_1.InstructionBuilderTypes.StakingDeactivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount: undefined,
unstakingAddress: undefined,
isMarinade: false,
recipients: undefined,
},
};
const instructions = [...stakingDeactivateInstructions];
const instructionsData = [stakingDeactivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse deactivate stake tx instructions if there are unexpected instructions', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
// Instructions
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
}).instructions;
// Params
const stakingActivateParams = {
type: constants_1.InstructionBuilderTypes.StakingDeactivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount: undefined,
unstakingAddress: undefined,
isMarinade: false,
recipients: undefined,
},
};
const instructions = [
...stakingActivateInstructions,
...stakingDelegateInstructions,
...stakingDeactivateInstructions,
];
const instructionsData = [stakingActivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
describe('Partially deactivate stake instructions', function () {
describe('Input validation', function () {
it('Should throw an error if the Allocate instruction is missing', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, missing allocate unstake account instruction');
});
it('Should throw an error if the Assign instruction is missing', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space: web3_js_1.StakeProgram.space,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, missing assign unstake account instruction');
});
it('Should throw an error if the Split instruction is missing', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, missing split stake account instruction');
});
it('Should throw an error if the transfer instruction is missing for partial', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space: web3_js_1.StakeProgram.space,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, missing funding of unstake address instruction');
});
it('Should throw an error if the allocated account does not match the assigned account', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: new web3_js_1.Keypair().publicKey,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, must allocate and assign the same public key');
});
[199, 201].forEach((space) => {
it(`Should throw an error if the correct amount of space is not allocated for the split account - ${space}`, () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw(`Invalid partial deactivate stake transaction, unstaking account must allocate ${web3_js_1.StakeProgram.space} bytes`);
});
});
it('Should throw an error if the allocated account is not assigned to the StakeProgram', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.SystemProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, the unstake account must be assigned to the Stake Program');
});
it('Should throw an error if the split account is not allocated', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const key = new web3_js_1.Keypair().publicKey;
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: key,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: key,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: stakingAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, must allocate the unstaking account');
});
it('Should throw an error if the stake account and the split account are the same account', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: stakingAccount,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: stakingAccount,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: stakingAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
const instructions = [
nonceAdvanceInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
(0, should_1.default)(() => (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions)).throw('Invalid partial deactivate stake transaction, the unstaking account must be different from the Stake Account');
});
});
it('Should parse partial deactivate stake tx instructions with memo and durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const splitStakeAccount = new web3_js_1.PublicKey(testData.splitStakeAccount.pub);
const memo = 'test memo';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
// transfer
const transferInstruction = web3_js_1.SystemProgram.transfer({
fromPubkey: new web3_js_1.PublicKey(fromAccount),
toPubkey: new web3_js_1.PublicKey(splitStakeAccount),
lamports: parseInt(constants_1.STAKE_ACCOUNT_RENT_EXEMPT_AMOUNT.toString(), 10),
});
const allocateInstruction = web3_js_1.SystemProgram.allocate({
accountPubkey: splitStakeAccount,
space: web3_js_1.StakeProgram.space,
});
const assignInstruction = web3_js_1.SystemProgram.assign({
accountPubkey: splitStakeAccount,
programId: web3_js_1.StakeProgram.programId,
});
const splitInstructions = web3_js_1.StakeProgram.split({
stakePubkey: stakingAccount,
authorizedPubkey: fromAccount,
splitStakePubkey: splitStakeAccount,
lamports: 100000,
}, 0).instructions;
const stakingDeactivateInstructions = web3_js_1.StakeProgram.deactivate({
authorizedPubkey: fromAccount,
stakePubkey: splitStakeAccount,
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const stakingDeactivateParams = {
type: constants_1.InstructionBuilderTypes.StakingDeactivate,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount: '100000',
unstakingAddress: splitStakeAccount.toString(),
isMarinade: false,
recipients: undefined,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [
nonceAdvanceInstruction,
transferInstruction,
allocateInstruction,
assignInstruction,
...splitInstructions,
...stakingDeactivateInstructions,
memoInstruction,
];
const instructionsData = [nonceAdvanceParams, memoParams, stakingDeactivateParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingDeactivate, instructions);
should_1.default.deepEqual(result, instructionsData);
});
});
});
describe('Withdraw stake instructions ', function () {
it('Should parse withdraw stake tx instructions with memo and durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const memo = 'test memo';
const amount = '100000';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const withdrawStakeInstructions = web3_js_1.StakeProgram.withdraw({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
toPubkey: fromAccount,
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const withdrawStakeParams = {
type: constants_1.InstructionBuilderTypes.StakingWithdraw,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [nonceAdvanceInstruction, ...withdrawStakeInstructions, memoInstruction];
const instructionsData = [nonceAdvanceParams, withdrawStakeParams, memoParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingWithdraw, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse withdraw stake tx instructions with memo and durable nonce with instructions in any order', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const nonceAccount = testData.nonceAccount.pub;
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const memo = 'test memo';
const amount = '100000';
// Instructions
const nonceAdvanceInstruction = web3_js_1.SystemProgram.nonceAdvance({
noncePubkey: new web3_js_1.PublicKey(nonceAccount),
authorizedPubkey: fromAccount,
});
const withdrawStakeInstructions = web3_js_1.StakeProgram.withdraw({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
toPubkey: fromAccount,
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const memoInstruction = new web3_js_1.TransactionInstruction({
keys: [],
programId: new web3_js_1.PublicKey(constants_1.MEMO_PROGRAM_PK),
data: Buffer.from(memo),
});
// Params
const nonceAdvanceParams = {
type: constants_1.InstructionBuilderTypes.NonceAdvance,
params: { walletNonceAddress: nonceAccount, authWalletAddress: fromAccount.toString() },
};
const withdrawStakeParams = {
type: constants_1.InstructionBuilderTypes.StakingWithdraw,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount,
},
};
const memoParams = {
type: constants_1.InstructionBuilderTypes.Memo,
params: { memo },
};
const instructions = [memoInstruction, ...withdrawStakeInstructions, nonceAdvanceInstruction];
const instructionsData = [memoParams, withdrawStakeParams, nonceAdvanceParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingWithdraw, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse withdraw stake tx instructions without memo or durable nonce', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const amount = '100000';
// Instructions
const withdrawStakeInstructions = web3_js_1.StakeProgram.withdraw({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
toPubkey: fromAccount,
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
// Params
const withdrawStakeParams = {
type: constants_1.InstructionBuilderTypes.StakingWithdraw,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount,
},
};
const instructions = [...withdrawStakeInstructions];
const instructionsData = [withdrawStakeParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingWithdraw, instructions);
should_1.default.deepEqual(result, instructionsData);
});
it('Should parse withdraw stake tx instructions if there are unexpected instructions', () => {
const fromAccount = new web3_js_1.PublicKey(testData.authAccount.pub);
const stakingAccount = new web3_js_1.PublicKey(testData.stakeAccount.pub);
const validator = new web3_js_1.PublicKey(testData.validator.pub);
const amount = '100000';
// Instructions
const stakingActivateInstructions = web3_js_1.StakeProgram.createAccount({
fromPubkey: fromAccount,
stakePubkey: stakingAccount,
authorized: {
staker: fromAccount,
withdrawer: fromAccount,
},
lockup: new web3_js_1.Lockup(0, 0, fromAccount),
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
const stakingDelegateInstructions = web3_js_1.StakeProgram.delegate({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
votePubkey: validator,
}).instructions;
const withdrawStakeInstructions = web3_js_1.StakeProgram.withdraw({
authorizedPubkey: fromAccount,
stakePubkey: stakingAccount,
toPubkey: fromAccount,
lamports: new bignumber_js_1.default(amount).toNumber(),
}).instructions;
// Params
const withdrawStakeParams = {
type: constants_1.InstructionBuilderTypes.StakingWithdraw,
params: {
fromAddress: fromAccount.toString(),
stakingAddress: stakingAccount.toString(),
amount,
},
};
const instructions = [
...stakingActivateInstructions,
...stakingDelegateInstructions,
...withdrawStakeInstructions,
];
const instructionsData = [withdrawStakeParams];
const result = (0, instructionParamsFactory_1.instructionParamsFactory)(sdk_core_1.TransactionType.StakingWithdraw, instructions);
should_1.default.deepEqual(result, instructionsData);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5LnN0YWtpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5LnN0YWtpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZDO0FBQzdDLHFGQUFrRjtBQUNsRiw4Q0FBa0Q7QUFFbEQsdURBQXFIO0FBQ3JILDZDQU95QjtBQUN6QixnRUFBcUM7QUFFckMsUUFBUSxDQUFDLG9DQUFvQyxFQUFFO0lBQzdDLFFBQVEsQ0FBQyxnQ0FBZ0MsRUFBRTtRQUN6QyxFQUFFLENBQUMseUVBQXlFLEVBQUUsR0FBRyxFQUFFO1lBQ2pGLE1BQU0sV0FBVyxHQUFHLElBQUksbUJBQVMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzVELE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDO1lBQy9DLE1BQU0sY0FBYyxHQUFHLElBQUksbUJBQVMsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sU0FBUyxHQUFHLElBQUksbUJBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQztZQUN4QixNQUFNLElBQUksR0FBRyxXQUFXLENBQUM7WUFFekIsZUFBZTtZQUNmLE1BQU0sdUJBQXVCLEdBQUcsdUJBQWEsQ0FBQyxZQUFZLENBQUM7Z0JBQ3pELFdBQVcsRUFBRSxJQUFJLG1CQUFTLENBQUMsWUFBWSxDQUFDO2dCQUN4QyxnQkFBZ0IsRUFBRSxXQUFXO2FBQzlCLENBQUMsQ0FBQztZQUVILE1BQU0sMkJBQTJCLEdBQUcsc0JBQVksQ0FBQyxhQUFhLENBQUM7Z0JB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WUFBWSxHQUFHO2dCQUNuQixHQUFHLDJCQUEyQjtnQkFDOUIsR0FBRywyQkFBMkI7Z0JBQzlCLEdBQUcseUJBQXlCO2FBQzdCLENBQUM7WUFDRixNQUFNLGdCQUFnQixHQUFHLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUMvQyxNQUFNLE1BQU0sR0FBRyxJQUFBLG1EQUF3QixFQUFDLDBCQUFlLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQ3ZGLGdCQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL3Jlc291cmNlcy9zb2wnO1xuaW1wb3J0IHsgaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5IH0gZnJvbSAnLi4vLi4vc3JjL2xpYi9pbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnknO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEluc3RydWN0aW9uUGFyYW1zLCBOb25jZSwgU3Rha2luZ0FjdGl2YXRlLCBTdGFraW5nRGVhY3RpdmF0ZSwgU3Rha2luZ1dpdGhkcmF3IH0gZnJvbSAnLi4vLi4vc3JjL2xpYi9pZmFjZSc7XG5pbXBvcnQgeyBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcywgTUVNT19QUk9HUkFNX1BLLCBTVEFLRV9BQ0NPVU5UX1JFTlRfRVhFTVBUX0FNT1VOVCB9IGZyb20gJy4uLy4uL3NyYy9saWIvY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIEtleXBhaXIgYXMgU29sS2V5cGFpcixcbiAgTG9ja3VwLFxuICBQdWJsaWNLZXksXG4gIFN0YWtlUHJvZ3JhbSxcbiAgU3lzdGVtUHJvZ3JhbSxcbiAgVHJhbnNhY3Rpb25JbnN0cnVjdGlvbixcbn0gZnJvbSAnQHNvbGFuYS93ZWIzLmpzJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcblxuZGVzY3JpYmUoJ0luc3RydWN0aW9uIFBhcnNlciBTdGFraW5nIFRlc3RzOiAnLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdBY3RpdmF0ZSBzdGFraW5nIGluc3RydWN0aW9ucyAnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ1Nob3VsZCBwYXJzZSBhY3RpdmF0ZSBzdGFrZSB0eCBpbnN0cnVjdGlvbnMgd2l0aCBtZW1vIGFuZCBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBub25jZUFjY291bnQgPSB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViO1xuICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS52YWxpZGF0b3IucHViKTtcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMDAnO1xuICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5ub25jZUFkdmFuY2Uoe1xuICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uY3JlYXRlQWNjb3VudCh7XG4gICAgICAgIGZyb21QdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIGF1dGhvcml6ZWQ6IHtcbiAgICAgICAgICBzdGFrZXI6IGZyb21BY2NvdW50LFxuICAgICAgICAgIHdpdGhkcmF3ZXI6IGZyb21BY2NvdW50LFxuICAgICAgICB9LFxuICAgICAgICBsb2NrdXA6IG5ldyBMb2NrdXAoMCwgMCwgZnJvbUFjY291bnQpLFxuICAgICAgICBsYW1wb3J0czogbmV3IEJpZ051bWJlcihhbW91bnQpLnRvTnVtYmVyKCksXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdEZWxlZ2F0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWxlZ2F0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHZvdGVQdWJrZXk6IHZhbGlkYXRvcixcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICBrZXlzOiBbXSxcbiAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFBhcmFtc1xuICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlUGFyYW1zOiBOb25jZSA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuTm9uY2VBZHZhbmNlLFxuICAgICAgICBwYXJhbXM6IHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQsIGF1dGhXYWxsZXRBZGRyZXNzOiBmcm9tQWNjb3VudC50b1N0cmluZygpIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzdGFraW5nQWN0aXZhdGVQYXJhbXM6IFN0YWtpbmdBY3RpdmF0ZSA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuU3Rha2luZ0FjdGl2YXRlLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICB2YWxpZGF0b3I6IHZhbGlkYXRvci50b1N0cmluZygpLFxuICAgICAgICAgIGFtb3VudCxcbiAgICAgICAgICBpc01hcmluYWRlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1lbW9QYXJhbXM6IEluc3RydWN0aW9uUGFyYW1zID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5NZW1vLFxuICAgICAgICBwYXJhbXM6IHsgbWVtbyB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICBub25jZUFkdmFuY2VJbnN0cnVjdGlvbixcbiAgICAgICAgLi4uc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAuLi5zdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgIG1lbW9JbnN0cnVjdGlvbixcbiAgICAgIF07XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gW25vbmNlQWR2YW5jZVBhcmFtcywgbWVtb1BhcmFtcywgc3Rha2luZ0FjdGl2YXRlUGFyYW1zXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlLCBpbnN0cnVjdGlvbnMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQsIGluc3RydWN0aW9uc0RhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBwYXJzZSBhY3RpdmF0ZSBzdGFrZSB0eCBpbnN0cnVjdGlvbnMgd2l0aCBtZW1vIGFuZCBkdXJhYmxlIG5vbmNlIHdpdGggaW5zdHJ1Y3Rpb25zIGluIGFueSBvcmRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEudmFsaWRhdG9yLnB1Yik7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwJztcbiAgICAgIGNvbnN0IG1lbW8gPSAndGVzdCBtZW1vJztcblxuICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgbm9uY2VQdWJrZXk6IG5ldyBQdWJsaWNLZXkobm9uY2VBY2NvdW50KSxcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmNyZWF0ZUFjY291bnQoe1xuICAgICAgICBmcm9tUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICBhdXRob3JpemVkOiB7XG4gICAgICAgICAgc3Rha2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB3aXRoZHJhd2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja3VwOiBuZXcgTG9ja3VwKDAsIDAsIGZyb21BY2NvdW50KSxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVsZWdhdGUoe1xuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICB2b3RlUHVia2V5OiB2YWxpZGF0b3IsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAga2V5czogW10sXG4gICAgICAgIHByb2dyYW1JZDogbmV3IFB1YmxpY0tleShNRU1PX1BST0dSQU1fUEspLFxuICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQYXJhbXNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZVBhcmFtczogTm9uY2UgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLk5vbmNlQWR2YW5jZSxcbiAgICAgICAgcGFyYW1zOiB7IHdhbGxldE5vbmNlQWRkcmVzczogbm9uY2VBY2NvdW50LCBhdXRoV2FsbGV0QWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlUGFyYW1zOiBTdGFraW5nQWN0aXZhdGUgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLlN0YWtpbmdBY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgdmFsaWRhdG9yOiB2YWxpZGF0b3IudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtZW1vUGFyYW1zOiBJbnN0cnVjdGlvblBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuTWVtbyxcbiAgICAgICAgcGFyYW1zOiB7IG1lbW8gfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtcbiAgICAgICAgbWVtb0luc3RydWN0aW9uLFxuICAgICAgICAuLi5zdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgIC4uLnN0YWtpbmdEZWxlZ2F0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24sXG4gICAgICBdO1xuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IFttZW1vUGFyYW1zLCBub25jZUFkdmFuY2VQYXJhbXMsIHN0YWtpbmdBY3RpdmF0ZVBhcmFtc107XG4gICAgICBjb25zdCByZXN1bHQgPSBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LCBpbnN0cnVjdGlvbnNEYXRhKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgcGFyc2UgYWN0aXZhdGUgc3Rha2UgdHggaW5zdHJ1Y3Rpb25zIHdpdGhvdXQgbWVtbyBvciBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnZhbGlkYXRvci5wdWIpO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMCc7XG5cbiAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmNyZWF0ZUFjY291bnQoe1xuICAgICAgICBmcm9tUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICBhdXRob3JpemVkOiB7XG4gICAgICAgICAgc3Rha2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB3aXRoZHJhd2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja3VwOiBuZXcgTG9ja3VwKDAsIDAsIGZyb21BY2NvdW50KSxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVsZWdhdGUoe1xuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICB2b3RlUHVia2V5OiB2YWxpZGF0b3IsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIC8vIFBhcmFtc1xuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlUGFyYW1zOiBTdGFraW5nQWN0aXZhdGUgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLlN0YWtpbmdBY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgdmFsaWRhdG9yOiB2YWxpZGF0b3IudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbLi4uc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zLCAuLi5zdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnNdO1xuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IFtzdGFraW5nQWN0aXZhdGVQYXJhbXNdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQWN0aXZhdGUsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHBhcnNlIGFjdGl2YXRlIHN0YWtlIHR4IGluc3RydWN0aW9ucyBpZiB0aGVyZSBhcmUgdW5leHBlY3RlZCBpbnN0cnVjdGlvbnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEudmFsaWRhdG9yLnB1Yik7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwJztcblxuICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICBjb25zdCBzdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uY3JlYXRlQWNjb3VudCh7XG4gICAgICAgIGZyb21QdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIGF1dGhvcml6ZWQ6IHtcbiAgICAgICAgICBzdGFrZXI6IGZyb21BY2NvdW50LFxuICAgICAgICAgIHdpdGhkcmF3ZXI6IGZyb21BY2NvdW50LFxuICAgICAgICB9LFxuICAgICAgICBsb2NrdXA6IG5ldyBMb2NrdXAoMCwgMCwgZnJvbUFjY291bnQpLFxuICAgICAgICBsYW1wb3J0czogbmV3IEJpZ051bWJlcihhbW91bnQpLnRvTnVtYmVyKCksXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdEZWxlZ2F0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWxlZ2F0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHZvdGVQdWJrZXk6IHZhbGlkYXRvcixcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVhY3RpdmF0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIC8vIFBhcmFtc1xuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlUGFyYW1zOiBTdGFraW5nQWN0aXZhdGUgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLlN0YWtpbmdBY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgdmFsaWRhdG9yOiB2YWxpZGF0b3IudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbXG4gICAgICAgIC4uLnN0YWtpbmdBY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgLi4uc3Rha2luZ0RlbGVnYXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgIF07XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gW3N0YWtpbmdBY3RpdmF0ZVBhcmFtc107XG4gICAgICBjb25zdCByZXN1bHQgPSBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LCBpbnN0cnVjdGlvbnNEYXRhKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgZmFpbCB0byBwYXJzZSBhY3RpdmF0ZSBzdGFrZSB0eCBpbnN0cnVjdGlvbnMgaWYgdGhlcmUgYXJlIG1pc3NpbmcgaW5zdHJ1Y3Rpb25zJywgKCkgPT4ge1xuICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnZhbGlkYXRvci5wdWIpO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMCc7XG5cbiAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgY29uc3Qgc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmNyZWF0ZUFjY291bnQoe1xuICAgICAgICBmcm9tUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICBhdXRob3JpemVkOiB7XG4gICAgICAgICAgc3Rha2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB3aXRoZHJhd2VyOiBmcm9tQWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja3VwOiBuZXcgTG9ja3VwKDAsIDAsIGZyb21BY2NvdW50KSxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVsZWdhdGUoe1xuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgc3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICB2b3RlUHVia2V5OiB2YWxpZGF0b3IsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zWzFdLCAuLi5zdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnNdO1xuICAgICAgICBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKTtcbiAgICAgIH0sICdJbnZhbGlkIHN0YWtpbmcgYWN0aXZhdGUgdHJhbnNhY3Rpb24sIG1pc3NpbmcgY3JlYXRlIHN0YWtlIGFjY291bnQgaW5zdHJ1Y3Rpb24nKTtcblxuICAgICAgc2hvdWxkLnRocm93cygoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtzdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnNbMF1dO1xuICAgICAgICBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKTtcbiAgICAgIH0sICdJbnZhbGlkIHN0YWtpbmcgYWN0aXZhdGUgdHJhbnNhY3Rpb24sIG1pc3NpbmcgaW5pdGlhbGl6ZSBzdGFrZSBhY2NvdW50L2RlbGVnYXRlIGluc3RydWN0aW9uJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdEZWFjdGl2YXRlIHN0YWtpbmcgaW5zdHJ1Y3Rpb25zICcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnU2hvdWxkIHBhcnNlIGRlYWN0aXZhdGUgc3Rha2UgdHggaW5zdHJ1Y3Rpb25zIHdpdGggbWVtbyBhbmQgZHVyYWJsZSBub25jZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IG1lbW8gPSAndGVzdCBtZW1vJztcblxuICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgbm9uY2VQdWJrZXk6IG5ldyBQdWJsaWNLZXkobm9uY2VBY2NvdW50KSxcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVhY3RpdmF0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAga2V5czogW10sXG4gICAgICAgIHByb2dyYW1JZDogbmV3IFB1YmxpY0tleShNRU1PX1BST0dSQU1fUEspLFxuICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQYXJhbXNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZVBhcmFtczogTm9uY2UgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLk5vbmNlQWR2YW5jZSxcbiAgICAgICAgcGFyYW1zOiB7IHdhbGxldE5vbmNlQWRkcmVzczogbm9uY2VBY2NvdW50LCBhdXRoV2FsbGV0QWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVQYXJhbXM6IFN0YWtpbmdEZWFjdGl2YXRlID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5TdGFraW5nRGVhY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgdW5zdGFraW5nQWRkcmVzczogdW5kZWZpbmVkLFxuICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1lbW9QYXJhbXM6IEluc3RydWN0aW9uUGFyYW1zID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5NZW1vLFxuICAgICAgICBwYXJhbXM6IHsgbWVtbyB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW25vbmNlQWR2YW5jZUluc3RydWN0aW9uLCAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucywgbWVtb0luc3RydWN0aW9uXTtcbiAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSBbbm9uY2VBZHZhbmNlUGFyYW1zLCBtZW1vUGFyYW1zLCBzdGFraW5nRGVhY3RpdmF0ZVBhcmFtc107XG4gICAgICBjb25zdCByZXN1bHQgPSBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlLCBpbnN0cnVjdGlvbnMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQsIGluc3RydWN0aW9uc0RhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBwYXJzZSBkZWFjdGl2YXRlIHN0YWtlIHR4IGluc3RydWN0aW9ucyB3aXRoIG1lbW8gYW5kIGR1cmFibGUgbm9uY2Ugd2l0aCBpbnN0cnVjdGlvbnMgaW4gYW55IG9yZGVyJywgKCkgPT4ge1xuICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBub25jZUFjY291bnQgPSB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViO1xuICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5ub25jZUFkdmFuY2Uoe1xuICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICBrZXlzOiBbXSxcbiAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFBhcmFtc1xuICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlUGFyYW1zOiBOb25jZSA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuTm9uY2VBZHZhbmNlLFxuICAgICAgICBwYXJhbXM6IHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQsIGF1dGhXYWxsZXRBZGRyZXNzOiBmcm9tQWNjb3VudC50b1N0cmluZygpIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZVBhcmFtczogU3Rha2luZ0RlYWN0aXZhdGUgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLlN0YWtpbmdEZWFjdGl2YXRlLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgICAgcmVjaXBpZW50czogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWVtb1BhcmFtczogSW5zdHJ1Y3Rpb25QYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLk1lbW8sXG4gICAgICAgIHBhcmFtczogeyBtZW1vIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbbWVtb0luc3RydWN0aW9uLCAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucywgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb25dO1xuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IFttZW1vUGFyYW1zLCBub25jZUFkdmFuY2VQYXJhbXMsIHN0YWtpbmdEZWFjdGl2YXRlUGFyYW1zXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHBhcnNlIGRlYWN0aXZhdGUgc3Rha2UgdHggaW5zdHJ1Y3Rpb25zIHdpdGhvdXQgbWVtbyBvciBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG5cbiAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVhY3RpdmF0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIC8vIFBhcmFtc1xuICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVQYXJhbXM6IFN0YWtpbmdEZWFjdGl2YXRlID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5TdGFraW5nRGVhY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgdW5zdGFraW5nQWRkcmVzczogdW5kZWZpbmVkLFxuICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFsuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9uc107XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gW3N0YWtpbmdEZWFjdGl2YXRlUGFyYW1zXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHBhcnNlIGRlYWN0aXZhdGUgc3Rha2UgdHggaW5zdHJ1Y3Rpb25zIGlmIHRoZXJlIGFyZSB1bmV4cGVjdGVkIGluc3RydWN0aW9ucycsICgpID0+IHtcbiAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS52YWxpZGF0b3IucHViKTtcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMDAnO1xuXG4gICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgIGNvbnN0IHN0YWtpbmdBY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5jcmVhdGVBY2NvdW50KHtcbiAgICAgICAgZnJvbVB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgYXV0aG9yaXplZDoge1xuICAgICAgICAgIHN0YWtlcjogZnJvbUFjY291bnQsXG4gICAgICAgICAgd2l0aGRyYXdlcjogZnJvbUFjY291bnQsXG4gICAgICAgIH0sXG4gICAgICAgIGxvY2t1cDogbmV3IExvY2t1cCgwLCAwLCBmcm9tQWNjb3VudCksXG4gICAgICAgIGxhbXBvcnRzOiBuZXcgQmlnTnVtYmVyKGFtb3VudCkudG9OdW1iZXIoKSxcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgY29uc3Qgc3Rha2luZ0RlbGVnYXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmRlbGVnYXRlKHtcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgdm90ZVB1YmtleTogdmFsaWRhdG9yLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgLy8gUGFyYW1zXG4gICAgICBjb25zdCBzdGFraW5nQWN0aXZhdGVQYXJhbXM6IFN0YWtpbmdEZWFjdGl2YXRlID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5TdGFraW5nRGVhY3RpdmF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6IHN0YWtpbmdBY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgYW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgdW5zdGFraW5nQWRkcmVzczogdW5kZWZpbmVkLFxuICAgICAgICAgIGlzTWFyaW5hZGU6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtcbiAgICAgICAgLi4uc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAuLi5zdGFraW5nRGVsZWdhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgIC4uLnN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSBbc3Rha2luZ0FjdGl2YXRlUGFyYW1zXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnUGFydGlhbGx5IGRlYWN0aXZhdGUgc3Rha2UgaW5zdHJ1Y3Rpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgZGVzY3JpYmUoJ0lucHV0IHZhbGlkYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdTaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEFsbG9jYXRlIGluc3RydWN0aW9uIGlzIG1pc3NpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgc3BsaXRTdGFrZUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnNwbGl0U3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLm5vbmNlQWR2YW5jZSh7XG4gICAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBTdGFrZVByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3BsaXRJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uc3BsaXQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICAgIHNwbGl0U3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IHN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmRlYWN0aXZhdGUoe1xuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgICBwcm9ncmFtSWQ6IG5ldyBQdWJsaWNLZXkoTUVNT19QUk9HUkFNX1BLKSxcbiAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICAgICAgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBhc3NpZ25JbnN0cnVjdGlvbixcbiAgICAgICAgICAgIC4uLnNwbGl0SW5zdHJ1Y3Rpb25zLFxuICAgICAgICAgICAgLi4uc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICBtZW1vSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgXTtcbiAgICAgICAgICBzaG91bGQoKCkgPT4gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKSkudGhyb3coXG4gICAgICAgICAgICAnSW52YWxpZCBwYXJ0aWFsIGRlYWN0aXZhdGUgc3Rha2UgdHJhbnNhY3Rpb24sIG1pc3NpbmcgYWxsb2NhdGUgdW5zdGFrZSBhY2NvdW50IGluc3RydWN0aW9uJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdTaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEFzc2lnbiBpbnN0cnVjdGlvbiBpcyBtaXNzaW5nJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgICAgIGNvbnN0IG5vbmNlQWNjb3VudCA9IHRlc3REYXRhLm5vbmNlQWNjb3VudC5wdWI7XG4gICAgICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgICAgIGNvbnN0IHNwbGl0U3Rha2VBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zcGxpdFN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgICAgIGNvbnN0IG1lbW8gPSAndGVzdCBtZW1vJztcblxuICAgICAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5ub25jZUFkdmFuY2Uoe1xuICAgICAgICAgICAgbm9uY2VQdWJrZXk6IG5ldyBQdWJsaWNLZXkobm9uY2VBY2NvdW50KSxcbiAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgYWxsb2NhdGVJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYWxsb2NhdGUoe1xuICAgICAgICAgICAgYWNjb3VudFB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgICBzcGFjZTogU3Rha2VQcm9ncmFtLnNwYWNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3BsaXRJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uc3BsaXQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICAgIHNwbGl0U3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IHN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmRlYWN0aXZhdGUoe1xuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgICBwcm9ncmFtSWQ6IG5ldyBQdWJsaWNLZXkoTUVNT19QUk9HUkFNX1BLKSxcbiAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICAgICAgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBhbGxvY2F0ZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgLi4uc3BsaXRJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgICAgIG1lbW9JbnN0cnVjdGlvbixcbiAgICAgICAgICBdO1xuICAgICAgICAgIHNob3VsZCgoKSA9PiBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlLCBpbnN0cnVjdGlvbnMpKS50aHJvdyhcbiAgICAgICAgICAgICdJbnZhbGlkIHBhcnRpYWwgZGVhY3RpdmF0ZSBzdGFrZSB0cmFuc2FjdGlvbiwgbWlzc2luZyBhc3NpZ24gdW5zdGFrZSBhY2NvdW50IGluc3RydWN0aW9uJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdTaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIFNwbGl0IGluc3RydWN0aW9uIGlzIG1pc3NpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICBjb25zdCBzcGxpdFN0YWtlQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBtZW1vID0gJ3Rlc3QgbWVtbyc7XG5cbiAgICAgICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgICAgIG5vbmNlUHVia2V5OiBuZXcgUHVibGljS2V5KG5vbmNlQWNjb3VudCksXG4gICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGFsbG9jYXRlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLmFsbG9jYXRlKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgc3BhY2U6IFN0YWtlUHJvZ3JhbS5zcGFjZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGFzc2lnbkluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5hc3NpZ24oe1xuICAgICAgICAgICAgYWNjb3VudFB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgICBwcm9ncmFtSWQ6IFN0YWtlUHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgc3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAgICAgIGtleXM6IFtdLFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtcbiAgICAgICAgICAgIG5vbmNlQWR2YW5jZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgYWxsb2NhdGVJbnN0cnVjdGlvbixcbiAgICAgICAgICAgIGFzc2lnbkluc3RydWN0aW9uLFxuICAgICAgICAgICAgLi4uc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICBtZW1vSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgXTtcbiAgICAgICAgICBzaG91bGQoKCkgPT4gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKSkudGhyb3coXG4gICAgICAgICAgICAnSW52YWxpZCBwYXJ0aWFsIGRlYWN0aXZhdGUgc3Rha2UgdHJhbnNhY3Rpb24sIG1pc3Npbmcgc3BsaXQgc3Rha2UgYWNjb3VudCBpbnN0cnVjdGlvbidcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ1Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgdHJhbnNmZXIgaW5zdHJ1Y3Rpb24gaXMgbWlzc2luZyBmb3IgcGFydGlhbCcsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBub25jZUFjY291bnQgPSB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViO1xuICAgICAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBzcGxpdFN0YWtlQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBtZW1vID0gJ3Rlc3QgbWVtbyc7XG5cbiAgICAgICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgICAgIG5vbmNlUHVia2V5OiBuZXcgUHVibGljS2V5KG5vbmNlQWNjb3VudCksXG4gICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGFsbG9jYXRlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLmFsbG9jYXRlKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgc3BhY2U6IFN0YWtlUHJvZ3JhbS5zcGFjZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHNwbGl0SW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLnNwbGl0KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgICBzcGxpdFN0YWtlUHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICAgICAgbGFtcG9ydHM6IDEwMDAwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAwXG4gICAgICAgICAgKS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBTdGFrZVByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVhY3RpdmF0ZSh7XG4gICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBtZW1vSW5zdHJ1Y3Rpb24gPSBuZXcgVHJhbnNhY3Rpb25JbnN0cnVjdGlvbih7XG4gICAgICAgICAgICBrZXlzOiBbXSxcbiAgICAgICAgICAgIHByb2dyYW1JZDogbmV3IFB1YmxpY0tleShNRU1PX1BST0dSQU1fUEspLFxuICAgICAgICAgICAgZGF0YTogQnVmZmVyLmZyb20obWVtbyksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbXG4gICAgICAgICAgICBub25jZUFkdmFuY2VJbnN0cnVjdGlvbixcbiAgICAgICAgICAgIGFsbG9jYXRlSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBhc3NpZ25JbnN0cnVjdGlvbixcbiAgICAgICAgICAgIC4uLnNwbGl0SW5zdHJ1Y3Rpb25zLFxuICAgICAgICAgICAgLi4uc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICBtZW1vSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgXTtcbiAgICAgICAgICBzaG91bGQoKCkgPT4gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSwgaW5zdHJ1Y3Rpb25zKSkudGhyb3coXG4gICAgICAgICAgICAnSW52YWxpZCBwYXJ0aWFsIGRlYWN0aXZhdGUgc3Rha2UgdHJhbnNhY3Rpb24sIG1pc3NpbmcgZnVuZGluZyBvZiB1bnN0YWtlIGFkZHJlc3MgaW5zdHJ1Y3Rpb24nXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ1Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYWxsb2NhdGVkIGFjY291bnQgZG9lcyBub3QgbWF0Y2ggdGhlIGFzc2lnbmVkIGFjY291bnQnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgc3BsaXRTdGFrZUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnNwbGl0U3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLm5vbmNlQWR2YW5jZSh7XG4gICAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhbGxvY2F0ZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5hbGxvY2F0ZSh7XG4gICAgICAgICAgICBhY2NvdW50UHVia2V5OiBuZXcgU29sS2V5cGFpcigpLnB1YmxpY0tleSxcbiAgICAgICAgICAgIHNwYWNlOiBTdGFrZVByb2dyYW0uc3BhY2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBTdGFrZVByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3BsaXRJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uc3BsaXQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICAgIHNwbGl0U3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IHN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmRlYWN0aXZhdGUoe1xuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgICBwcm9ncmFtSWQ6IG5ldyBQdWJsaWNLZXkoTUVNT19QUk9HUkFNX1BLKSxcbiAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICAgICAgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBhbGxvY2F0ZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgYXNzaWduSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICAuLi5zcGxpdEluc3RydWN0aW9ucyxcbiAgICAgICAgICAgIC4uLnN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAgICAgbWVtb0luc3RydWN0aW9uLFxuICAgICAgICAgIF07XG4gICAgICAgICAgc2hvdWxkKCgpID0+IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucykpLnRocm93KFxuICAgICAgICAgICAgJ0ludmFsaWQgcGFydGlhbCBkZWFjdGl2YXRlIHN0YWtlIHRyYW5zYWN0aW9uLCBtdXN0IGFsbG9jYXRlIGFuZCBhc3NpZ24gdGhlIHNhbWUgcHVibGljIGtleSdcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBbMTk5LCAyMDFdLmZvckVhY2goKHNwYWNlKSA9PiB7XG4gICAgICAgICAgaXQoYFNob3VsZCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgY29ycmVjdCBhbW91bnQgb2Ygc3BhY2UgaXMgbm90IGFsbG9jYXRlZCBmb3IgdGhlIHNwbGl0IGFjY291bnQgLSAke3NwYWNlfWAsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICAgIGNvbnN0IHNwbGl0U3Rha2VBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zcGxpdFN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgICAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5ub25jZUFkdmFuY2Uoe1xuICAgICAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBhbGxvY2F0ZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5hbGxvY2F0ZSh7XG4gICAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgICBzcGFjZSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgICAgYWNjb3VudFB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgICAgIHByb2dyYW1JZDogU3Rha2VQcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBzcGxpdEluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5zcGxpdChcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICAgICAgICBzcGxpdFN0YWtlUHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uZGVhY3RpdmF0ZSh7XG4gICAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgICAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgICAgIHByb2dyYW1JZDogbmV3IFB1YmxpY0tleShNRU1PX1BST0dSQU1fUEspLFxuICAgICAgICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbXG4gICAgICAgICAgICAgIG5vbmNlQWR2YW5jZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgICBhbGxvY2F0ZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgICBhc3NpZ25JbnN0cnVjdGlvbixcbiAgICAgICAgICAgICAgLi4uc3BsaXRJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICAgIC4uLnN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAgICAgICBtZW1vSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgc2hvdWxkKCgpID0+IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucykpLnRocm93KFxuICAgICAgICAgICAgICBgSW52YWxpZCBwYXJ0aWFsIGRlYWN0aXZhdGUgc3Rha2UgdHJhbnNhY3Rpb24sIHVuc3Rha2luZyBhY2NvdW50IG11c3QgYWxsb2NhdGUgJHtTdGFrZVByb2dyYW0uc3BhY2V9IGJ5dGVzYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ1Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYWxsb2NhdGVkIGFjY291bnQgaXMgbm90IGFzc2lnbmVkIHRvIHRoZSBTdGFrZVByb2dyYW0nLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgc3BsaXRTdGFrZUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnNwbGl0U3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLm5vbmNlQWR2YW5jZSh7XG4gICAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhbGxvY2F0ZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5hbGxvY2F0ZSh7XG4gICAgICAgICAgICBhY2NvdW50UHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICAgIHNwYWNlOiBTdGFrZVByb2dyYW0uc3BhY2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBTeXN0ZW1Qcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHNwbGl0SW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLnNwbGl0KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgICBzcGxpdFN0YWtlUHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICAgICAgbGFtcG9ydHM6IDEwMDAwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAwXG4gICAgICAgICAgKS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgc3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAgICAgIGtleXM6IFtdLFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtcbiAgICAgICAgICAgIG5vbmNlQWR2YW5jZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgYWxsb2NhdGVJbnN0cnVjdGlvbixcbiAgICAgICAgICAgIGFzc2lnbkluc3RydWN0aW9uLFxuICAgICAgICAgICAgLi4uc3BsaXRJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgICAgIG1lbW9JbnN0cnVjdGlvbixcbiAgICAgICAgICBdO1xuICAgICAgICAgIHNob3VsZCgoKSA9PiBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlLCBpbnN0cnVjdGlvbnMpKS50aHJvdyhcbiAgICAgICAgICAgICdJbnZhbGlkIHBhcnRpYWwgZGVhY3RpdmF0ZSBzdGFrZSB0cmFuc2FjdGlvbiwgdGhlIHVuc3Rha2UgYWNjb3VudCBtdXN0IGJlIGFzc2lnbmVkIHRvIHRoZSBTdGFrZSBQcm9ncmFtJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdTaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHNwbGl0IGFjY291bnQgaXMgbm90IGFsbG9jYXRlZCcsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBub25jZUFjY291bnQgPSB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViO1xuICAgICAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBzcGxpdFN0YWtlQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgICBjb25zdCBtZW1vID0gJ3Rlc3QgbWVtbyc7XG5cbiAgICAgICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgICAgIG5vbmNlUHVia2V5OiBuZXcgUHVibGljS2V5KG5vbmNlQWNjb3VudCksXG4gICAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGtleSA9IG5ldyBTb2xLZXlwYWlyKCkucHVibGljS2V5O1xuICAgICAgICAgIGNvbnN0IGFsbG9jYXRlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLmFsbG9jYXRlKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IGtleSxcbiAgICAgICAgICAgIHNwYWNlOiBTdGFrZVByb2dyYW0uc3BhY2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IGtleSxcbiAgICAgICAgICAgIHByb2dyYW1JZDogU3Rha2VQcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHNwbGl0SW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLnNwbGl0KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgICBzcGxpdFN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgbGFtcG9ydHM6IDEwMDAwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAwXG4gICAgICAgICAgKS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgc3Rha2VQdWJrZXk6IHNwbGl0U3Rha2VBY2NvdW50LFxuICAgICAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAgICAgIGtleXM6IFtdLFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtcbiAgICAgICAgICAgIG5vbmNlQWR2YW5jZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgYWxsb2NhdGVJbnN0cnVjdGlvbixcbiAgICAgICAgICAgIGFzc2lnbkluc3RydWN0aW9uLFxuICAgICAgICAgICAgLi4uc3BsaXRJbnN0cnVjdGlvbnMsXG4gICAgICAgICAgICAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgICAgIG1lbW9JbnN0cnVjdGlvbixcbiAgICAgICAgICBdO1xuICAgICAgICAgIHNob3VsZCgoKSA9PiBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlLCBpbnN0cnVjdGlvbnMpKS50aHJvdyhcbiAgICAgICAgICAgICdJbnZhbGlkIHBhcnRpYWwgZGVhY3RpdmF0ZSBzdGFrZSB0cmFuc2FjdGlvbiwgbXVzdCBhbGxvY2F0ZSB0aGUgdW5zdGFraW5nIGFjY291bnQnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ1Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgc3Rha2UgYWNjb3VudCBhbmQgdGhlIHNwbGl0IGFjY291bnQgYXJlIHRoZSBzYW1lIGFjY291bnQnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZnJvbUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3Qgc3BsaXRTdGFrZUFjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnNwbGl0U3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICAgICAgY29uc3Qgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLm5vbmNlQWR2YW5jZSh7XG4gICAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhbGxvY2F0ZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5hbGxvY2F0ZSh7XG4gICAgICAgICAgICBhY2NvdW50UHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgIHNwYWNlOiBTdGFrZVByb2dyYW0uc3BhY2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICAgIGFjY291bnRQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICAgICAgcHJvZ3JhbUlkOiBTdGFrZVByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc3BsaXRJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uc3BsaXQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICAgIHNwbGl0U3Rha2VQdWJrZXk6IHN0YWtpbmdBY2NvdW50LFxuICAgICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICAgIGNvbnN0IHN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLmRlYWN0aXZhdGUoe1xuICAgICAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAgICAgY29uc3QgbWVtb0luc3RydWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24oe1xuICAgICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgICBwcm9ncmFtSWQ6IG5ldyBQdWJsaWNLZXkoTUVNT19QUk9HUkFNX1BLKSxcbiAgICAgICAgICAgIGRhdGE6IEJ1ZmZlci5mcm9tKG1lbW8pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICAgICAgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICBhbGxvY2F0ZUluc3RydWN0aW9uLFxuICAgICAgICAgICAgYXNzaWduSW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgICAuLi5zcGxpdEluc3RydWN0aW9ucyxcbiAgICAgICAgICAgIC4uLnN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAgICAgbWVtb0luc3RydWN0aW9uLFxuICAgICAgICAgIF07XG4gICAgICAgICAgc2hvdWxkKCgpID0+IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucykpLnRocm93KFxuICAgICAgICAgICAgJ0ludmFsaWQgcGFydGlhbCBkZWFjdGl2YXRlIHN0YWtlIHRyYW5zYWN0aW9uLCB0aGUgdW5zdGFraW5nIGFjY291bnQgbXVzdCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgU3Rha2UgQWNjb3VudCdcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnU2hvdWxkIHBhcnNlIHBhcnRpYWwgZGVhY3RpdmF0ZSBzdGFrZSB0eCBpbnN0cnVjdGlvbnMgd2l0aCBtZW1vIGFuZCBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgICBjb25zdCBzcGxpdFN0YWtlQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3BsaXRTdGFrZUFjY291bnQucHViKTtcbiAgICAgICAgY29uc3QgbWVtbyA9ICd0ZXN0IG1lbW8nO1xuXG4gICAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyB0cmFuc2ZlclxuICAgICAgICBjb25zdCB0cmFuc2Zlckluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS50cmFuc2Zlcih7XG4gICAgICAgICAgZnJvbVB1YmtleTogbmV3IFB1YmxpY0tleShmcm9tQWNjb3VudCksXG4gICAgICAgICAgdG9QdWJrZXk6IG5ldyBQdWJsaWNLZXkoc3BsaXRTdGFrZUFjY291bnQpLFxuICAgICAgICAgIGxhbXBvcnRzOiBwYXJzZUludChTVEFLRV9BQ0NPVU5UX1JFTlRfRVhFTVBUX0FNT1VOVC50b1N0cmluZygpLCAxMCksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFsbG9jYXRlSW5zdHJ1Y3Rpb24gPSBTeXN0ZW1Qcm9ncmFtLmFsbG9jYXRlKHtcbiAgICAgICAgICBhY2NvdW50UHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICBzcGFjZTogU3Rha2VQcm9ncmFtLnNwYWNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhc3NpZ25JbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0uYXNzaWduKHtcbiAgICAgICAgICBhY2NvdW50UHVia2V5OiBzcGxpdFN0YWtlQWNjb3VudCxcbiAgICAgICAgICBwcm9ncmFtSWQ6IFN0YWtlUHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHNwbGl0SW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLnNwbGl0KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICAgICAgc3BsaXRTdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgICAgICBsYW1wb3J0czogMTAwMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgMFxuICAgICAgICApLmluc3RydWN0aW9ucztcblxuICAgICAgICBjb25zdCBzdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWFjdGl2YXRlKHtcbiAgICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgICBzdGFrZVB1YmtleTogc3BsaXRTdGFrZUFjY291bnQsXG4gICAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgICBjb25zdCBtZW1vSW5zdHJ1Y3Rpb24gPSBuZXcgVHJhbnNhY3Rpb25JbnN0cnVjdGlvbih7XG4gICAgICAgICAga2V5czogW10sXG4gICAgICAgICAgcHJvZ3JhbUlkOiBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSyksXG4gICAgICAgICAgZGF0YTogQnVmZmVyLmZyb20obWVtbyksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFBhcmFtc1xuICAgICAgICBjb25zdCBub25jZUFkdmFuY2VQYXJhbXM6IE5vbmNlID0ge1xuICAgICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLk5vbmNlQWR2YW5jZSxcbiAgICAgICAgICBwYXJhbXM6IHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQsIGF1dGhXYWxsZXRBZGRyZXNzOiBmcm9tQWNjb3VudC50b1N0cmluZygpIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgc3Rha2luZ0RlYWN0aXZhdGVQYXJhbXM6IFN0YWtpbmdEZWFjdGl2YXRlID0ge1xuICAgICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLlN0YWtpbmdEZWFjdGl2YXRlLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgZnJvbUFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMCcsXG4gICAgICAgICAgICB1bnN0YWtpbmdBZGRyZXNzOiBzcGxpdFN0YWtlQWNjb3VudC50b1N0cmluZygpLFxuICAgICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgICAgICByZWNpcGllbnRzOiB1bmRlZmluZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBtZW1vUGFyYW1zOiBJbnN0cnVjdGlvblBhcmFtcyA9IHtcbiAgICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5NZW1vLFxuICAgICAgICAgIHBhcmFtczogeyBtZW1vIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW1xuICAgICAgICAgIG5vbmNlQWR2YW5jZUluc3RydWN0aW9uLFxuICAgICAgICAgIHRyYW5zZmVySW5zdHJ1Y3Rpb24sXG4gICAgICAgICAgYWxsb2NhdGVJbnN0cnVjdGlvbixcbiAgICAgICAgICBhc3NpZ25JbnN0cnVjdGlvbixcbiAgICAgICAgICAuLi5zcGxpdEluc3RydWN0aW9ucyxcbiAgICAgICAgICAuLi5zdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgICBtZW1vSW5zdHJ1Y3Rpb24sXG4gICAgICAgIF07XG4gICAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSBbbm9uY2VBZHZhbmNlUGFyYW1zLCBtZW1vUGFyYW1zLCBzdGFraW5nRGVhY3RpdmF0ZVBhcmFtc107XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGUsIGluc3RydWN0aW9ucyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LCBpbnN0cnVjdGlvbnNEYXRhKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2l0aGRyYXcgc3Rha2UgaW5zdHJ1Y3Rpb25zICcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnU2hvdWxkIHBhcnNlIHdpdGhkcmF3IHN0YWtlIHR4IGluc3RydWN0aW9ucyB3aXRoIG1lbW8gYW5kIGR1cmFibGUgbm9uY2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IG5vbmNlQWNjb3VudCA9IHRlc3REYXRhLm5vbmNlQWNjb3VudC5wdWI7XG4gICAgICBjb25zdCBzdGFraW5nQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuc3Rha2VBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBtZW1vID0gJ3Rlc3QgbWVtbyc7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwJztcblxuICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICBjb25zdCBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiA9IFN5c3RlbVByb2dyYW0ubm9uY2VBZHZhbmNlKHtcbiAgICAgICAgbm9uY2VQdWJrZXk6IG5ldyBQdWJsaWNLZXkobm9uY2VBY2NvdW50KSxcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgd2l0aGRyYXdTdGFrZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS53aXRoZHJhdyh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHRvUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICBjb25zdCBtZW1vSW5zdHJ1Y3Rpb24gPSBuZXcgVHJhbnNhY3Rpb25JbnN0cnVjdGlvbih7XG4gICAgICAgIGtleXM6IFtdLFxuICAgICAgICBwcm9ncmFtSWQ6IG5ldyBQdWJsaWNLZXkoTUVNT19QUk9HUkFNX1BLKSxcbiAgICAgICAgZGF0YTogQnVmZmVyLmZyb20obWVtbyksXG4gICAgICB9KTtcblxuICAgICAgLy8gUGFyYW1zXG4gICAgICBjb25zdCBub25jZUFkdmFuY2VQYXJhbXM6IE5vbmNlID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5Ob25jZUFkdmFuY2UsXG4gICAgICAgIHBhcmFtczogeyB3YWxsZXROb25jZUFkZHJlc3M6IG5vbmNlQWNjb3VudCwgYXV0aFdhbGxldEFkZHJlc3M6IGZyb21BY2NvdW50LnRvU3RyaW5nKCkgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdpdGhkcmF3U3Rha2VQYXJhbXM6IFN0YWtpbmdXaXRoZHJhdyA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuU3Rha2luZ1dpdGhkcmF3LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtZW1vUGFyYW1zOiBJbnN0cnVjdGlvblBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuTWVtbyxcbiAgICAgICAgcGFyYW1zOiB7IG1lbW8gfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IFtub25jZUFkdmFuY2VJbnN0cnVjdGlvbiwgLi4ud2l0aGRyYXdTdGFrZUluc3RydWN0aW9ucywgbWVtb0luc3RydWN0aW9uXTtcbiAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSBbbm9uY2VBZHZhbmNlUGFyYW1zLCB3aXRoZHJhd1N0YWtlUGFyYW1zLCBtZW1vUGFyYW1zXTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGluc3RydWN0aW9uUGFyYW1zRmFjdG9yeShUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1dpdGhkcmF3LCBpbnN0cnVjdGlvbnMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQsIGluc3RydWN0aW9uc0RhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBwYXJzZSB3aXRoZHJhdyBzdGFrZSB0eCBpbnN0cnVjdGlvbnMgd2l0aCBtZW1vIGFuZCBkdXJhYmxlIG5vbmNlIHdpdGggaW5zdHJ1Y3Rpb25zIGluIGFueSBvcmRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3Qgbm9uY2VBY2NvdW50ID0gdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YjtcbiAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IG1lbW8gPSAndGVzdCBtZW1vJztcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMDAnO1xuXG4gICAgICAvLyBJbnN0cnVjdGlvbnNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uID0gU3lzdGVtUHJvZ3JhbS5ub25jZUFkdmFuY2Uoe1xuICAgICAgICBub25jZVB1YmtleTogbmV3IFB1YmxpY0tleShub25jZUFjY291bnQpLFxuICAgICAgICBhdXRob3JpemVkUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB3aXRoZHJhd1N0YWtlSW5zdHJ1Y3Rpb25zID0gU3Rha2VQcm9ncmFtLndpdGhkcmF3KHtcbiAgICAgICAgYXV0aG9yaXplZFB1YmtleTogZnJvbUFjY291bnQsXG4gICAgICAgIHN0YWtlUHVia2V5OiBzdGFraW5nQWNjb3VudCxcbiAgICAgICAgdG9QdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBsYW1wb3J0czogbmV3IEJpZ051bWJlcihhbW91bnQpLnRvTnVtYmVyKCksXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IG1lbW9JbnN0cnVjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbkluc3RydWN0aW9uKHtcbiAgICAgICAga2V5czogW10sXG4gICAgICAgIHByb2dyYW1JZDogbmV3IFB1YmxpY0tleShNRU1PX1BST0dSQU1fUEspLFxuICAgICAgICBkYXRhOiBCdWZmZXIuZnJvbShtZW1vKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQYXJhbXNcbiAgICAgIGNvbnN0IG5vbmNlQWR2YW5jZVBhcmFtczogTm9uY2UgPSB7XG4gICAgICAgIHR5cGU6IEluc3RydWN0aW9uQnVpbGRlclR5cGVzLk5vbmNlQWR2YW5jZSxcbiAgICAgICAgcGFyYW1zOiB7IHdhbGxldE5vbmNlQWRkcmVzczogbm9uY2VBY2NvdW50LCBhdXRoV2FsbGV0QWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2l0aGRyYXdTdGFrZVBhcmFtczogU3Rha2luZ1dpdGhkcmF3ID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5TdGFraW5nV2l0aGRyYXcsXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGZyb21BZGRyZXNzOiBmcm9tQWNjb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIHN0YWtpbmdBZGRyZXNzOiBzdGFraW5nQWNjb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIGFtb3VudCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1lbW9QYXJhbXM6IEluc3RydWN0aW9uUGFyYW1zID0ge1xuICAgICAgICB0eXBlOiBJbnN0cnVjdGlvbkJ1aWxkZXJUeXBlcy5NZW1vLFxuICAgICAgICBwYXJhbXM6IHsgbWVtbyB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW21lbW9JbnN0cnVjdGlvbiwgLi4ud2l0aGRyYXdTdGFrZUluc3RydWN0aW9ucywgbm9uY2VBZHZhbmNlSW5zdHJ1Y3Rpb25dO1xuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IFttZW1vUGFyYW1zLCB3aXRoZHJhd1N0YWtlUGFyYW1zLCBub25jZUFkdmFuY2VQYXJhbXNdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHBhcnNlIHdpdGhkcmF3IHN0YWtlIHR4IGluc3RydWN0aW9ucyB3aXRob3V0IG1lbW8gb3IgZHVyYWJsZSBub25jZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGZyb21BY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5hdXRoQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3Qgc3Rha2luZ0FjY291bnQgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLnN0YWtlQWNjb3VudC5wdWIpO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMCc7XG5cbiAgICAgIC8vIEluc3RydWN0aW9uc1xuICAgICAgY29uc3Qgd2l0aGRyYXdTdGFrZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS53aXRoZHJhdyh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHRvUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAvLyBQYXJhbXNcbiAgICAgIGNvbnN0IHdpdGhkcmF3U3Rha2VQYXJhbXM6IFN0YWtpbmdXaXRoZHJhdyA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuU3Rha2luZ1dpdGhkcmF3LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbLi4ud2l0aGRyYXdTdGFrZUluc3RydWN0aW9uc107XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gW3dpdGhkcmF3U3Rha2VQYXJhbXNdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gaW5zdHJ1Y3Rpb25QYXJhbXNGYWN0b3J5KFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcsIGluc3RydWN0aW9ucyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJlc3VsdCwgaW5zdHJ1Y3Rpb25zRGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHBhcnNlIHdpdGhkcmF3IHN0YWtlIHR4IGluc3RydWN0aW9ucyBpZiB0aGVyZSBhcmUgdW5leHBlY3RlZCBpbnN0cnVjdGlvbnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBmcm9tQWNjb3VudCA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEuYXV0aEFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IHN0YWtpbmdBY2NvdW50ID0gbmV3IFB1YmxpY0tleSh0ZXN0RGF0YS5zdGFrZUFjY291bnQucHViKTtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG5ldyBQdWJsaWNLZXkodGVzdERhdGEudmFsaWRhdG9yLnB1Yik7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwJztcblxuICAgICAgLy8gSW5zdHJ1Y3Rpb25zXG4gICAgICBjb25zdCBzdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnMgPSBTdGFrZVByb2dyYW0uY3JlYXRlQWNjb3VudCh7XG4gICAgICAgIGZyb21QdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIGF1dGhvcml6ZWQ6IHtcbiAgICAgICAgICBzdGFrZXI6IGZyb21BY2NvdW50LFxuICAgICAgICAgIHdpdGhkcmF3ZXI6IGZyb21BY2NvdW50LFxuICAgICAgICB9LFxuICAgICAgICBsb2NrdXA6IG5ldyBMb2NrdXAoMCwgMCwgZnJvbUFjY291bnQpLFxuICAgICAgICBsYW1wb3J0czogbmV3IEJpZ051bWJlcihhbW91bnQpLnRvTnVtYmVyKCksXG4gICAgICB9KS5pbnN0cnVjdGlvbnM7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdEZWxlZ2F0ZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS5kZWxlZ2F0ZSh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHZvdGVQdWJrZXk6IHZhbGlkYXRvcixcbiAgICAgIH0pLmluc3RydWN0aW9ucztcblxuICAgICAgY29uc3Qgd2l0aGRyYXdTdGFrZUluc3RydWN0aW9ucyA9IFN0YWtlUHJvZ3JhbS53aXRoZHJhdyh7XG4gICAgICAgIGF1dGhvcml6ZWRQdWJrZXk6IGZyb21BY2NvdW50LFxuICAgICAgICBzdGFrZVB1YmtleTogc3Rha2luZ0FjY291bnQsXG4gICAgICAgIHRvUHVia2V5OiBmcm9tQWNjb3VudCxcbiAgICAgICAgbGFtcG9ydHM6IG5ldyBCaWdOdW1iZXIoYW1vdW50KS50b051bWJlcigpLFxuICAgICAgfSkuaW5zdHJ1Y3Rpb25zO1xuXG4gICAgICAvLyBQYXJhbXNcbiAgICAgIGNvbnN0IHdpdGhkcmF3U3Rha2VQYXJhbXM6IFN0YWtpbmdXaXRoZHJhdyA9IHtcbiAgICAgICAgdHlwZTogSW5zdHJ1Y3Rpb25CdWlsZGVyVHlwZXMuU3Rha2luZ1dpdGhkcmF3LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogZnJvbUFjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBzdGFraW5nQWRkcmVzczogc3Rha2luZ0FjY291bnQudG9TdHJpbmcoKSxcbiAgICAgICAgICBhbW91bnQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBbXG4gICAgICAgIC4uLnN0YWtpbmdBY3RpdmF0ZUluc3RydWN0aW9ucyxcbiAgICAgICAgLi4uc3Rha2luZ0RlbGVnYXRlSW5zdHJ1Y3Rpb25zLFxuICAgICAgICAuLi53aXRoZHJhd1N0YWtlSW5zdHJ1Y3Rpb25zLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSBbd2l0aGRyYXdTdGFrZVBhcmFtc107XG4gICAgICBjb25zdCByZXN1bHQgPSBpbnN0cnVjdGlvblBhcmFtc0ZhY3RvcnkoVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdywgaW5zdHJ1Y3Rpb25zKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LCBpbnN0cnVjdGlvbnNEYXRhKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!