PHP WebShell
Текущая директория: /opt/BitGoJS/modules/express/dist/test/integration
Просмотр файла: bitgoExpressV1.js
"use strict";
// eslint-disable-next-line
/// <reference types="mocha" />
Object.defineProperty(exports, "__esModule", { value: true });
require("should");
const nock = require("nock");
require('should-http');
const request = require('supertest-as-promised');
const _ = require('lodash');
const expressApp = require('../../src/expressApp');
const TestBitGo = require('../lib/test_bitgo');
const testUtil = require('../lib/testutil');
describe('Bitgo Express V1', function () {
let agent;
let bitgo;
before(function () {
nock.restore();
const args = {
debug: false,
env: 'test',
logfile: '/dev/null',
};
bitgo = new TestBitGo();
bitgo.initializeTestVars();
const app = expressApp.app(args);
agent = request.agent(app);
});
describe('proxied calls', function () {
it('error - not authed', function () {
return agent
.get('/api/v1/wallet')
.send()
.then(function (res) {
res.should.have.status(401);
});
});
it('error - proxied calls disabled', function () {
const app = expressApp.app(_.extend({}, {
debug: false,
env: 'test',
logfile: '/dev/null',
}, { disableproxy: true }));
const disabledProxyAgent = request.agent(app);
return disabledProxyAgent
.get('/')
.send()
.then(function (res) {
res.should.have.status(404);
});
});
it('market data', function () {
return agent
.get('/api/v1/market/latest')
.send()
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('latest');
res.body.latest.should.have.property('currencies');
res.body.latest.currencies.should.have.property('USD');
const usdMarketData = res.body.latest.currencies.USD;
usdMarketData.should.have.property('last');
usdMarketData.should.have.property('bid');
usdMarketData.should.have.property('ask');
});
});
it('get wallet list (authed)', function () {
return agent
.get('/api/v1/wallet')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send()
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('wallets');
res.body.wallets.length.should.not.equal(0);
res.body.wallets[0].should.have.property('label');
});
});
it('post unlock (authed)', function () {
return agent
.post('/api/v1/user/unlock')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({ otp: bitgo.testUserOTP(), duration: 3 })
.then(function (res) {
res.body.should.have.property('session');
res.body.session.should.have.property('client');
res.body.session.client.should.equal('test');
});
});
it('put label set (authed)', function () {
const walletId = '2MvfC3e6njdTXqWDfGvNUqDs5kwimfaTGjK';
return agent
.put('/api/v1/labels/' + walletId + '/msj42CCGruhRsFrGATiUuh25dtxYtnpbTx')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({ label: 'testLabel_bitgoExpressSDK' })
.then(function (res) {
res.body.should.have.property('walletId');
res.body.should.have.property('address');
res.body.should.have.property('label');
res.body.label.should.equal('testLabel_bitgoExpressSDK');
res.body.walletId.should.equal(walletId);
});
});
});
describe('handled calls', function () {
it('error - not authed', function () {
return agent
.post('/api/v1/wallets/simplecreate')
.send({ passphrase: 'abc', label: 'helloworld' })
.then(function (res) {
res.should.have.status(401);
});
});
it('new keychain', function () {
return agent
.post('/api/v1/keychain/local')
.send()
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('xpub');
res.body.should.have.property('xprv');
});
});
it('derive BIP32 private keychain', function () {
return agent
.post('/api/v1/keychain/derive')
.send({
path: 'm/1/2/3/4',
xprv: 'xprv9s21ZrQH143K3o5A54b28GYVnDAa7gdPSxjWGz9ARzbxqYax8gbds5yGiU4D56GgSRwp7t9T8p54xh6MN19h8n6HJyR5FCkQopoUxC34EV3',
})
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('xpub');
res.body.should.have.property('xprv');
res.body.xprv.should.eql('xprvA1yY6N1A6aT3B9VUb2mhnLpNyPwAguPY3sibAXYXiEUVjT62TZNHTy13LhrdJ4BcGmt2hnRdgGQFLDowBqANkysSRw6KXri2MpGjkPAbGrS');
res.body.xpub.should.eql('xpub6ExtVsY3vx1LPdZwh4Ji9Um7XRmf6N7PR6eBxux9Ga1UcFRB16gY1mKXBzVPcGZVpnDPYboEPYdPxfsrnq1Yec49RN4usyB5ba8NNtVbHeG');
res.body.path.should.eql('m/1/2/3/4');
});
});
it('derive BIP32 public keychain', function () {
return agent
.post('/api/v1/keychain/derive')
.send({
path: 'm/3/4/5/6',
xpub: 'xpub6ExtVsY3vx1LPdZwh4Ji9Um7XRmf6N7PR6eBxux9Ga1UcFRB16gY1mKXBzVPcGZVpnDPYboEPYdPxfsrnq1Yec49RN4usyB5ba8NNtVbHeG',
})
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('xpub');
res.body.should.not.have.property('xprv');
res.body.xpub.should.eql('xpub6N5Svn29v8op8f6VgHeM9FXvmpoFx7535qW4HKFHeM7HqJDD2dWQq92MKduYZjuWi4FWZQsGDtHwRtLpmCRWMxy3d3r77jcsxDpYNAGpbuY');
res.body.path.should.eql('m/3/4/5/6');
});
});
it('decrypt', function () {
const encryptedString = '{"iv":"n4zHXVTi/Go/riCP8fNs/A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"zvLyve+4AJU=","ct":"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l"}';
return agent
.post('/api/v1/decrypt')
.send({ input: encryptedString, password: 'password' })
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('decrypted');
res.body.decrypted.should.equal('this is a secret');
});
});
it('create wallet', function () {
const backupXpub = 'xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU';
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallets/simplecreate')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({ passphrase: 'chamchatka', label: 'kokoko', backupXpub: backupXpub });
})
.then(function (res) {
res.should.have.status(200);
res.body.should.have.property('wallet');
res.body.should.have.property('backupKeychain');
res.body.backupKeychain.should.have.property('xpub');
res.body.backupKeychain.xpub.should.equal(backupXpub);
});
});
it('create transaction - wallet1 to wallet3', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_WALLET1_ADDRESS + '/createtransaction')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
recipients: [{ address: TestBitGo.TEST_WALLET3_ADDRESS, amount: 2 * 1e8 }],
walletPassphrase: TestBitGo.TEST_WALLET3_PASSCODE,
});
})
.then(function (res) {
res.status.should.eql(200);
const { nP2shInputs = 0, nP2shP2wshInputs = 0, nP2pkhInputs, nOutputs } = res.body.txInfo;
(nP2shInputs + nP2shP2wshInputs).should.be.greaterThan(0);
nP2pkhInputs.should.eql(0);
nOutputs.should.be.greaterThan(2); // change + bitgo fee + destination
});
});
it('send coins - wallet1 to wallet3', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_WALLET1_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET3_ADDRESS,
amount: 0.002 * 1e8,
walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
});
})
.then(function (res) {
res.status.should.equal(200);
res.body.should.have.property('tx');
res.body.should.have.property('hash');
res.body.should.have.property('fee');
res.body.should.have.property('feeRate');
});
});
it('create transaction - wallet3 to wallet1 with insufficient amount', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_WALLET3_ADDRESS + '/createtransaction')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
recipients: [{ address: TestBitGo.TEST_WALLET1_ADDRESS, amount: 10000 * 1e8 }],
walletPassphrase: TestBitGo.TEST_WALLET3_PASSCODE,
});
})
.then(function (res) {
res.status.should.eql(400);
res.body.should.have.property('message');
res.body.should.have.property('fee');
res.body.should.have.property('available');
res.body.message.should.equal('Insufficient funds');
res.body.fee.should.be.greaterThan(546);
res.body.available.should.be.greaterThan(546);
const { nP2shInputs = 0, nP2shP2wshInputs = 0, nP2pkhInputs = 0, nOutputs } = res.body.txInfo;
(nP2shInputs + nP2shP2wshInputs).should.be.greaterThan(0);
nP2pkhInputs.should.eql(0);
nOutputs.should.be.greaterThan(2); // change + bitgo fee + destination
});
});
it('send coins - wallet3 to wallet1 with insufficient amount', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_WALLET3_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 10000 * 1e8,
walletPassphrase: TestBitGo.TEST_WALLET3_PASSCODE,
fee: 0.0003 * 1e8,
});
})
.then(function (res) {
res.status.should.equal(400);
res.body.should.have.property('fee');
res.body.should.have.property('available');
res.body.message.should.equal('Insufficient funds');
res.body.should.have.property('fee');
res.body.fee.should.equal(0.0003 * 1e8);
const { nP2shInputs = 0, nP2shP2wshInputs = 0, nP2pkhInputs = 0, nOutputs } = res.body.txInfo;
(nP2shInputs + nP2shP2wshInputs).should.be.greaterThan(0);
nP2pkhInputs.should.eql(0);
nOutputs.should.be.greaterThan(2); // change + bitgo fee + destination
});
});
it('send coins - wallet3 to wallet1 with fee', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_WALLET3_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_WALLET3_PASSCODE,
fee: 0.0003 * 1e8,
});
})
.then(function (res) {
res.status.should.equal(200);
res.body.should.have.property('tx');
res.body.should.have.property('hash');
res.body.should.have.property('fee');
res.body.fee.should.equal(Math.round(0.0003 * 1e8));
});
});
xit('create and reject a pending approval', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return testUtil.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER, 15);
})
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_SHARED_WALLET_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_PASSWORD,
otp: bitgo.testUserOTP(),
});
})
.then(function (res) {
res.should.have.status(202);
res.body.should.have.property('pendingApproval');
res.body.status.should.eql('pendingApproval');
const pendingApprovalId = res.body.pendingApproval;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId + '/express')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER)
.send({ walletPassphrase: TestBitGo.TEST_PASSWORD, state: 'rejected' });
})
.then(function (res) {
res.body.state.should.eql('rejected');
});
});
xit('create a transaction and then reconstruct a tx to approve (with original fee)', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER, 15)
.then(function () {
return testUtil.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15);
})
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_SHARED_WALLET_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_PASSWORD,
fee: 12345,
});
})
.then(function (res) {
res.should.have.status(202);
res.body.should.have.property('pendingApproval');
res.body.status.should.eql('pendingApproval');
const pendingApprovalId = res.body.pendingApproval;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId + '/constructTx')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({ walletPassphrase: TestBitGo.TEST_PASSWORD, useOriginalFee: true });
})
.then(function (res) {
res.body.should.have.property('tx');
res.body.tx.should.not.eql('');
res.body.fee.should.eql(12345);
});
});
it('calculate tx size from parameters', function () {
return agent
.post('/api/v1/calculateminerfeeinfo')
.send({
feeRate: 20000,
nP2shInputs: 2,
nP2pkhInputs: 1,
nP2shP2wshInputs: 0,
nOutputs: 4,
})
.then(function (res) {
res.should.have.status(200);
res.body.size.should.eql(920);
res.body.fee.should.eql(18400);
});
});
xit('create and accept a pending approval', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function () {
return testUtil.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER, 15);
})
.then(function () {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_SHARED_WALLET_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_PASSWORD,
otp: bitgo.testUserOTP(),
});
})
.then(function (res) {
res.should.have.status(202);
res.body.should.have.property('pendingApproval');
res.body.status.should.eql('pendingApproval');
const pendingApprovalId = res.body.pendingApproval;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId + '/express')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER)
.send({ walletPassphrase: TestBitGo.TEST_PASSWORD, state: 'approved', otp: bitgo.testUserOTP() });
})
.then(function (res) {
res.body.state.should.eql('approved');
});
});
xit('create and accept a pending approval using the xprv', function () {
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function (res) {
return testUtil.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER, 15);
})
.then(function (res) {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_SHARED_WALLET_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_PASSWORD,
otp: bitgo.testUserOTP(),
});
})
.then(function (res) {
res.should.have.status(202);
res.body.should.have.property('pendingApproval');
res.body.status.should.eql('pendingApproval');
const pendingApprovalId = res.body.pendingApproval;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId + '/express')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER)
.send({
xprv: 'xprv9s21ZrQH143K3GisDvcsLyQZ88CrgtHziPuQ4ZZU6x3v8AZxEYEBZ7ANwfAPVz9mqraSjREVaCdFgv1u7mHvjuDRZ25J4wGJ73yooYhDoJ4',
state: 'approved',
otp: bitgo.testUserOTP(),
});
})
.then(function (res) {
res.body.state.should.eql('approved');
});
});
xit('create and accept a pending approval (2 step accept by constructing tx with original user)', function () {
let pendingApprovalId;
return testUtil
.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN, 15)
.then(function (res) {
return testUtil.unlockToken(agent, TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER, 15);
})
.then(function (res) {
return agent
.post('/api/v1/wallet/' + TestBitGo.TEST_SHARED_WALLET_ADDRESS + '/sendcoins')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({
address: TestBitGo.TEST_WALLET1_ADDRESS,
amount: 0.001 * 1e8,
walletPassphrase: TestBitGo.TEST_PASSWORD,
fee: 12345,
otp: bitgo.testUserOTP(),
});
})
.then(function (res) {
res.should.have.status(202);
res.body.should.have.property('pendingApproval');
res.body.status.should.eql('pendingApproval');
pendingApprovalId = res.body.pendingApproval;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId + '/constructTx')
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN)
.send({ walletPassphrase: TestBitGo.TEST_PASSWORD });
})
.then(function (res) {
res.body.should.have.property('tx');
res.body.tx.should.not.eql('');
res.body.fee.should.not.eql(12345); // fee should be recalculated dynamically
const txHex = res.body.tx;
return agent
.put('/api/v1/pendingapprovals/' + pendingApprovalId)
.set('Authorization', 'Bearer ' + TestBitGo.TEST_ACCESSTOKEN_SHAREDUSER)
.send({ tx: txHex, state: 'approved', otp: bitgo.testUserOTP() });
})
.then(function (res) {
res.body.state.should.eql('approved');
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0Z29FeHByZXNzVjEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2ludGVncmF0aW9uL2JpdGdvRXhwcmVzc1YxLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwyQkFBMkI7QUFDM0IsK0JBQStCOztBQUUvQixrQkFBZ0I7QUFDaEIsNkJBQTZCO0FBQzdCLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUN2QixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUNqRCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFNUIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDbkQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFDL0MsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFNUMsUUFBUSxDQUFDLGtCQUFrQixFQUFFO0lBQzNCLElBQUksS0FBSyxDQUFDO0lBQ1YsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFZixNQUFNLElBQUksR0FBRztZQUNYLEtBQUssRUFBRSxLQUFLO1lBQ1osR0FBRyxFQUFFLE1BQU07WUFDWCxPQUFPLEVBQUUsV0FBVztTQUNyQixDQUFDO1FBQ0YsS0FBSyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7UUFDeEIsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFD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QyxFQUFFLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELENBQUMsQ0FBQztpQkFDRCxJQUFJLENBQUMsVUFBVSxHQUFHO2dCQUNqQixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDL0IsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7Z0JBQzdFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUMxQixPQUFPLEtBQUs7cUJBQ1QsR0FBRyxDQUFDLDJCQUEyQixHQUFHLGlCQUFpQixDQUFDO3FCQUNwRCxHQUFHLENBQUMsZUFBZSxFQUFFLFNBQVMsR0FBRyxTQUFTLENBQUMsMkJBQTJCLENBQUM7cUJBQ3ZFLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0RSxDQUFDLENBQUM7aUJBQ0QsSUFBSSxDQUFDLFVBQVUsR0FBRztnQkFDakIsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCJtb2NoYVwiIC8+XG5cbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCAqIGFzIG5vY2sgZnJvbSAnbm9jayc7XG5yZXF1aXJlKCdzaG91bGQtaHR0cCcpO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJ3N1cGVydGVzdC1hcy1wcm9taXNlZCcpO1xuY29uc3QgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpO1xuXG5jb25zdCBleHByZXNzQXBwID0gcmVxdWlyZSgnLi4vLi4vc3JjL2V4cHJlc3NBcHAnKTtcbmNvbnN0IFRlc3RCaXRHbyA9IHJlcXVpcmUoJy4uL2xpYi90ZXN0X2JpdGdvJyk7XG5jb25zdCB0ZXN0VXRpbCA9IHJlcXVpcmUoJy4uL2xpYi90ZXN0dXRpbCcpO1xuXG5kZXNjcmliZSgnQml0Z28gRXhwcmVzcyBWMScsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGFnZW50O1xuICBsZXQgYml0Z287XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLnJlc3RvcmUoKTtcblxuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBkZWJ1ZzogZmFsc2UsXG4gICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgIGxvZ2ZpbGU6ICcvZGV2L251bGwnLFxuICAgIH07XG4gICAgYml0Z28gPSBuZXcgVGVzdEJpdEdvKCk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgY29uc3QgYXBwID0gZXhwcmVzc0FwcC5hcHAoYXJncyk7XG4gICAgYWdlbnQgPSByZXF1ZXN0LmFnZW50KGFwcCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwcm94aWVkIGNhbGxzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdlcnJvciAtIG5vdCBhdXRoZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLmdldCgnL2FwaS92MS93YWxsZXQnKVxuICAgICAgICAuc2VuZCgpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc2hvdWxkLmhhdmUuc3RhdHVzKDQwMSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Vycm9yIC0gcHJveGllZCBjYWxscyBkaXNhYmxlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFwcCA9IGV4cHJlc3NBcHAuYXBwKFxuICAgICAgICBfLmV4dGVuZChcbiAgICAgICAgICB7fSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkZWJ1ZzogZmFsc2UsXG4gICAgICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgICAgIGxvZ2ZpbGU6ICcvZGV2L251bGwnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBkaXNhYmxlcHJveHk6IHRydWUgfVxuICAgICAgICApXG4gICAgICApO1xuICAgICAgY29uc3QgZGlzYWJsZWRQcm94eUFnZW50ID0gcmVxdWVzdC5hZ2VudChhcHApO1xuICAgICAgcmV0dXJuIGRpc2FibGVkUHJveHlBZ2VudFxuICAgICAgICAuZ2V0KCcvJylcbiAgICAgICAgLnNlbmQoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cyg0MDQpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdtYXJrZXQgZGF0YScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAuZ2V0KCcvYXBpL3YxL21hcmtldC9sYXRlc3QnKVxuICAgICAgICAuc2VuZCgpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc2hvdWxkLmhhdmUuc3RhdHVzKDIwMCk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2xhdGVzdCcpO1xuICAgICAgICAgIHJlcy5ib2R5LmxhdGVzdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY3VycmVuY2llcycpO1xuICAgICAgICAgIHJlcy5ib2R5LmxhdGVzdC5jdXJyZW5jaWVzLnNob3VsZC5oYXZlLnByb3BlcnR5KCdVU0QnKTtcblxuICAgICAgICAgIGNvbnN0IHVzZE1hcmtldERhdGEgPSByZXMuYm9keS5sYXRlc3QuY3VycmVuY2llcy5VU0Q7XG4gICAgICAgICAgdXNkTWFya2V0RGF0YS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbGFzdCcpO1xuICAgICAgICAgIHVzZE1hcmtldERhdGEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2JpZCcpO1xuICAgICAgICAgIHVzZE1hcmtldERhdGEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FzaycpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdnZXQgd2FsbGV0IGxpc3QgKGF1dGhlZCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLmdldCgnL2FwaS92MS93YWxsZXQnKVxuICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgIC5zZW5kKClcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zaG91bGQuaGF2ZS5zdGF0dXMoMjAwKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0cycpO1xuICAgICAgICAgIHJlcy5ib2R5LndhbGxldHMubGVuZ3RoLnNob3VsZC5ub3QuZXF1YWwoMCk7XG4gICAgICAgICAgcmVzLmJvZHkud2FsbGV0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbGFiZWwnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncG9zdCB1bmxvY2sgKGF1dGhlZCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEvdXNlci91bmxvY2snKVxuICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgIC5zZW5kKHsgb3RwOiBiaXRnby50ZXN0VXNlck9UUCgpLCBkdXJhdGlvbjogMyB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Nlc3Npb24nKTtcbiAgICAgICAgICByZXMuYm9keS5zZXNzaW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjbGllbnQnKTtcbiAgICAgICAgICByZXMuYm9keS5zZXNzaW9uLmNsaWVudC5zaG91bGQuZXF1YWwoJ3Rlc3QnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgncHV0IGxhYmVsIHNldCAoYXV0aGVkKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldElkID0gJzJNdmZDM2U2bmpkVFhxV0RmR3ZOVXFEczVrd2ltZmFUR2pLJztcbiAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAucHV0KCcvYXBpL3YxL2xhYmVscy8nICsgd2FsbGV0SWQgKyAnL21zajQyQ0NHcnVoUnNGckdBVGlVdWgyNWR0eFl0bnBiVHgnKVxuICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgIC5zZW5kKHsgbGFiZWw6ICd0ZXN0TGFiZWxfYml0Z29FeHByZXNzU0RLJyB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldElkJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbGFiZWwnKTtcbiAgICAgICAgICByZXMuYm9keS5sYWJlbC5zaG91bGQuZXF1YWwoJ3Rlc3RMYWJlbF9iaXRnb0V4cHJlc3NTREsnKTtcbiAgICAgICAgICByZXMuYm9keS53YWxsZXRJZC5zaG91bGQuZXF1YWwod2FsbGV0SWQpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2hhbmRsZWQgY2FsbHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2Vycm9yIC0gbm90IGF1dGhlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAucG9zdCgnL2FwaS92MS93YWxsZXRzL3NpbXBsZWNyZWF0ZScpXG4gICAgICAgIC5zZW5kKHsgcGFzc3BocmFzZTogJ2FiYycsIGxhYmVsOiAnaGVsbG93b3JsZCcgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zaG91bGQuaGF2ZS5zdGF0dXMoNDAxKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnbmV3IGtleWNoYWluJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL2tleWNoYWluL2xvY2FsJylcbiAgICAgICAgLnNlbmQoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDApO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd4cHViJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3hwcnYnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGVyaXZlIEJJUDMyIHByaXZhdGUga2V5Y2hhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEva2V5Y2hhaW4vZGVyaXZlJylcbiAgICAgICAgLnNlbmQoe1xuICAgICAgICAgIHBhdGg6ICdtLzEvMi8zLzQnLFxuICAgICAgICAgIHhwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLM281QTU0YjI4R1lWbkRBYTdnZFBTeGpXR3o5QVJ6YnhxWWF4OGdiZHM1eUdpVTRENTZHZ1NSd3A3dDlUOHA1NHhoNk1OMTloOG42SEp5UjVGQ2tRb3BvVXhDMzRFVjMnLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDApO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd4cHViJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3hwcnYnKTtcbiAgICAgICAgICByZXMuYm9keS54cHJ2LnNob3VsZC5lcWwoXG4gICAgICAgICAgICAneHBydkExeVk2TjFBNmFUM0I5VlViMm1obkxwTnlQd0FndVBZM3NpYkFYWVhpRVVWalQ2MlRaTkhUeTEzTGhyZEo0QmNHbXQyaG5SZGdHUUZMRG93QnFBTmt5c1NSdzZLWHJpMk1wR2prUEFiR3JTJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgcmVzLmJvZHkueHB1Yi5zaG91bGQuZXFsKFxuICAgICAgICAgICAgJ3hwdWI2RXh0VnNZM3Z4MUxQZFp3aDRKaTlVbTdYUm1mNk43UFI2ZUJ4dXg5R2ExVWNGUkIxNmdZMW1LWEJ6VlBjR1pWcG5EUFlib0VQWWRQeGZzcm5xMVllYzQ5Uk40dXN5QjViYThOTnRWYkhlRydcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlcy5ib2R5LnBhdGguc2hvdWxkLmVxbCgnbS8xLzIvMy80Jyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Rlcml2ZSBCSVAzMiBwdWJsaWMga2V5Y2hhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEva2V5Y2hhaW4vZGVyaXZlJylcbiAgICAgICAgLnNlbmQoe1xuICAgICAgICAgIHBhdGg6ICdtLzMvNC81LzYnLFxuICAgICAgICAgIHhwdWI6ICd4cHViNkV4dFZzWTN2eDFMUGRad2g0Smk5VW03WFJtZjZON1BSNmVCeHV4OUdhMVVjRlJCMTZnWTFtS1hCelZQY0daVnBuRFBZYm9FUFlkUHhmc3JucTFZZWM0OVJONHVzeUI1YmE4Tk50VmJIZUcnLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDApO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd4cHViJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd4cHJ2Jyk7XG4gICAgICAgICAgcmVzLmJvZHkueHB1Yi5zaG91bGQuZXFsKFxuICAgICAgICAgICAgJ3hwdWI2TjVTdm4yOXY4b3A4ZjZWZ0hlTTlGWHZtcG9GeDc1MzVxVzRIS0ZIZU03SHFKREQyZFdRcTkyTUtkdVlaanVXaTRGV1pRc0dEdEh3UnRMcG1DUldNeHkzZDNyNzdqY3N4RHBZTkFHcGJ1WSdcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlcy5ib2R5LnBhdGguc2hvdWxkLmVxbCgnbS8zLzQvNS82Jyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlY3J5cHQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNyeXB0ZWRTdHJpbmcgPVxuICAgICAgICAne1wiaXZcIjpcIm40ekhYVlRpL0dvL3JpQ1A4Zk5zL0E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJ6dkx5dmUrNEFKVT1cIixcImN0XCI6XCJnTk1xaGVpY01vRDhabU56Und1UWZXR0FoK0hBOTMzbFwifSc7XG4gICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEvZGVjcnlwdCcpXG4gICAgICAgIC5zZW5kKHsgaW5wdXQ6IGVuY3J5cHRlZFN0cmluZywgcGFzc3dvcmQ6ICdwYXNzd29yZCcgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zaG91bGQuaGF2ZS5zdGF0dXMoMjAwKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVjcnlwdGVkJyk7XG4gICAgICAgICAgcmVzLmJvZHkuZGVjcnlwdGVkLnNob3VsZC5lcXVhbCgndGhpcyBpcyBhIHNlY3JldCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGUgd2FsbGV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFja3VwWHB1YiA9XG4gICAgICAgICd4cHViNkFIQTloWkROMTFrMmlqSE1lUzVRcUh4MktQOWFNQlJoVERxQU5NbndWdGR5dzJURFlSbUY4UGpwdndVRmNMMUV0OEhqNTlTM2dUU01jVVE1Z0FxVHozV2Q4RXNNVG1GM0RDaGhxUFFCblUnO1xuICAgICAgcmV0dXJuIHRlc3RVdGlsXG4gICAgICAgIC51bmxvY2tUb2tlbihhZ2VudCwgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4sIDE1KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS93YWxsZXRzL3NpbXBsZWNyZWF0ZScpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7IHBhc3NwaHJhc2U6ICdjaGFtY2hhdGthJywgbGFiZWw6ICdrb2tva28nLCBiYWNrdXBYcHViOiBiYWNrdXBYcHViIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDApO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXQnKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYmFja3VwS2V5Y2hhaW4nKTtcbiAgICAgICAgICByZXMuYm9keS5iYWNrdXBLZXljaGFpbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgneHB1YicpO1xuICAgICAgICAgIHJlcy5ib2R5LmJhY2t1cEtleWNoYWluLnhwdWIuc2hvdWxkLmVxdWFsKGJhY2t1cFhwdWIpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGUgdHJhbnNhY3Rpb24gLSB3YWxsZXQxIHRvIHdhbGxldDMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGVzdFV0aWxcbiAgICAgICAgLnVubG9ja1Rva2VuKGFnZW50LCBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTiwgMTUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3dhbGxldC8nICsgVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9BRERSRVNTICsgJy9jcmVhdGV0cmFuc2FjdGlvbicpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDNfQUREUkVTUywgYW1vdW50OiAyICogMWU4IH1dLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQzX1BBU1NDT0RFLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc3RhdHVzLnNob3VsZC5lcWwoMjAwKTtcbiAgICAgICAgICBjb25zdCB7IG5QMnNoSW5wdXRzID0gMCwgblAyc2hQMndzaElucHV0cyA9IDAsIG5QMnBraElucHV0cywgbk91dHB1dHMgfSA9IHJlcy5ib2R5LnR4SW5mbztcbiAgICAgICAgICAoblAyc2hJbnB1dHMgKyBuUDJzaFAyd3NoSW5wdXRzKS5zaG91bGQuYmUuZ3JlYXRlclRoYW4oMCk7XG4gICAgICAgICAgblAycGtoSW5wdXRzLnNob3VsZC5lcWwoMCk7XG4gICAgICAgICAgbk91dHB1dHMuc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDIpOyAvLyBjaGFuZ2UgKyBiaXRnbyBmZWUgKyBkZXN0aW5hdGlvblxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzZW5kIGNvaW5zIC0gd2FsbGV0MSB0byB3YWxsZXQzJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRlc3RVdGlsXG4gICAgICAgIC51bmxvY2tUb2tlbihhZ2VudCwgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4sIDE1KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS93YWxsZXQvJyArIFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUyArICcvc2VuZGNvaW5zJylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTilcbiAgICAgICAgICAgIC5zZW5kKHtcbiAgICAgICAgICAgICAgYWRkcmVzczogVGVzdEJpdEdvLlRFU1RfV0FMTEVUM19BRERSRVNTLFxuICAgICAgICAgICAgICBhbW91bnQ6IDAuMDAyICogMWU4LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYXNoJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZScpO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVSYXRlJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZSB0cmFuc2FjdGlvbiAtIHdhbGxldDMgdG8gd2FsbGV0MSB3aXRoIGluc3VmZmljaWVudCBhbW91bnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGVzdFV0aWxcbiAgICAgICAgLnVubG9ja1Rva2VuKGFnZW50LCBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTiwgMTUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3dhbGxldC8nICsgVGVzdEJpdEdvLlRFU1RfV0FMTEVUM19BRERSRVNTICsgJy9jcmVhdGV0cmFuc2FjdGlvbicpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUywgYW1vdW50OiAxMDAwMCAqIDFlOCB9XSxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUM19QQVNTQ09ERSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnN0YXR1cy5zaG91bGQuZXFsKDQwMCk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21lc3NhZ2UnKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2F2YWlsYWJsZScpO1xuICAgICAgICAgIHJlcy5ib2R5Lm1lc3NhZ2Uuc2hvdWxkLmVxdWFsKCdJbnN1ZmZpY2llbnQgZnVuZHMnKTtcbiAgICAgICAgICByZXMuYm9keS5mZWUuc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDU0Nik7XG4gICAgICAgICAgcmVzLmJvZHkuYXZhaWxhYmxlLnNob3VsZC5iZS5ncmVhdGVyVGhhbig1NDYpO1xuICAgICAgICAgIGNvbnN0IHsgblAyc2hJbnB1dHMgPSAwLCBuUDJzaFAyd3NoSW5wdXRzID0gMCwgblAycGtoSW5wdXRzID0gMCwgbk91dHB1dHMgfSA9IHJlcy5ib2R5LnR4SW5mbztcbiAgICAgICAgICAoblAyc2hJbnB1dHMgKyBuUDJzaFAyd3NoSW5wdXRzKS5zaG91bGQuYmUuZ3JlYXRlclRoYW4oMCk7XG4gICAgICAgICAgblAycGtoSW5wdXRzLnNob3VsZC5lcWwoMCk7XG4gICAgICAgICAgbk91dHB1dHMuc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDIpOyAvLyBjaGFuZ2UgKyBiaXRnbyBmZWUgKyBkZXN0aW5hdGlvblxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzZW5kIGNvaW5zIC0gd2FsbGV0MyB0byB3YWxsZXQxIHdpdGggaW5zdWZmaWNpZW50IGFtb3VudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0ZXN0VXRpbFxuICAgICAgICAudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOLCAxNSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEvd2FsbGV0LycgKyBUZXN0Qml0R28uVEVTVF9XQUxMRVQzX0FERFJFU1MgKyAnL3NlbmRjb2lucycpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUyxcbiAgICAgICAgICAgICAgYW1vdW50OiAxMDAwMCAqIDFlOCxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUM19QQVNTQ09ERSxcbiAgICAgICAgICAgICAgZmVlOiAwLjAwMDMgKiAxZTgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zdGF0dXMuc2hvdWxkLmVxdWFsKDQwMCk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZScpO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhdmFpbGFibGUnKTtcbiAgICAgICAgICByZXMuYm9keS5tZXNzYWdlLnNob3VsZC5lcXVhbCgnSW5zdWZmaWNpZW50IGZ1bmRzJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZScpO1xuICAgICAgICAgIHJlcy5ib2R5LmZlZS5zaG91bGQuZXF1YWwoMC4wMDAzICogMWU4KTtcbiAgICAgICAgICBjb25zdCB7IG5QMnNoSW5wdXRzID0gMCwgblAyc2hQMndzaElucHV0cyA9IDAsIG5QMnBraElucHV0cyA9IDAsIG5PdXRwdXRzIH0gPSByZXMuYm9keS50eEluZm87XG4gICAgICAgICAgKG5QMnNoSW5wdXRzICsgblAyc2hQMndzaElucHV0cykuc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDApO1xuICAgICAgICAgIG5QMnBraElucHV0cy5zaG91bGQuZXFsKDApO1xuICAgICAgICAgIG5PdXRwdXRzLnNob3VsZC5iZS5ncmVhdGVyVGhhbigyKTsgLy8gY2hhbmdlICsgYml0Z28gZmVlICsgZGVzdGluYXRpb25cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2VuZCBjb2lucyAtIHdhbGxldDMgdG8gd2FsbGV0MSB3aXRoIGZlZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0ZXN0VXRpbFxuICAgICAgICAudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOLCAxNSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEvd2FsbGV0LycgKyBUZXN0Qml0R28uVEVTVF9XQUxMRVQzX0FERFJFU1MgKyAnL3NlbmRjb2lucycpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUyxcbiAgICAgICAgICAgICAgYW1vdW50OiAwLjAwMSAqIDFlOCxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUM19QQVNTQ09ERSxcbiAgICAgICAgICAgICAgZmVlOiAwLjAwMDMgKiAxZTgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhc2gnKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgICAgcmVzLmJvZHkuZmVlLnNob3VsZC5lcXVhbChNYXRoLnJvdW5kKDAuMDAwMyAqIDFlOCkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHhpdCgnY3JlYXRlIGFuZCByZWplY3QgYSBwZW5kaW5nIGFwcHJvdmFsJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRlc3RVdGlsXG4gICAgICAgIC51bmxvY2tUb2tlbihhZ2VudCwgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4sIDE1KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHRlc3RVdGlsLnVubG9ja1Rva2VuKGFnZW50LCBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTl9TSEFSRURVU0VSLCAxNSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3dhbGxldC8nICsgVGVzdEJpdEdvLlRFU1RfU0hBUkVEX1dBTExFVF9BRERSRVNTICsgJy9zZW5kY29pbnMnKVxuICAgICAgICAgICAgLnNldCgnQXV0aG9yaXphdGlvbicsICdCZWFyZXIgJyArIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOKVxuICAgICAgICAgICAgLnNlbmQoe1xuICAgICAgICAgICAgICBhZGRyZXNzOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX0FERFJFU1MsXG4gICAgICAgICAgICAgIGFtb3VudDogMC4wMDEgKiAxZTgsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5URVNUX1BBU1NXT1JELFxuICAgICAgICAgICAgICBvdHA6IGJpdGdvLnRlc3RVc2VyT1RQKCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zaG91bGQuaGF2ZS5zdGF0dXMoMjAyKTtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGVuZGluZ0FwcHJvdmFsJyk7XG4gICAgICAgICAgcmVzLmJvZHkuc3RhdHVzLnNob3VsZC5lcWwoJ3BlbmRpbmdBcHByb3ZhbCcpO1xuICAgICAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbElkID0gcmVzLmJvZHkucGVuZGluZ0FwcHJvdmFsO1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnB1dCgnL2FwaS92MS9wZW5kaW5nYXBwcm92YWxzLycgKyBwZW5kaW5nQXBwcm92YWxJZCArICcvZXhwcmVzcycpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU5fU0hBUkVEVVNFUilcbiAgICAgICAgICAgIC5zZW5kKHsgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfUEFTU1dPUkQsIHN0YXRlOiAncmVqZWN0ZWQnIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLmJvZHkuc3RhdGUuc2hvdWxkLmVxbCgncmVqZWN0ZWQnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB4aXQoJ2NyZWF0ZSBhIHRyYW5zYWN0aW9uIGFuZCB0aGVuIHJlY29uc3RydWN0IGEgdHggdG8gYXBwcm92ZSAod2l0aCBvcmlnaW5hbCBmZWUpJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRlc3RVdGlsXG4gICAgICAgIC51bmxvY2tUb2tlbihhZ2VudCwgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU5fU0hBUkVEVVNFUiwgMTUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gdGVzdFV0aWwudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOLCAxNSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3dhbGxldC8nICsgVGVzdEJpdEdvLlRFU1RfU0hBUkVEX1dBTExFVF9BRERSRVNTICsgJy9zZW5kY29pbnMnKVxuICAgICAgICAgICAgLnNldCgnQXV0aG9yaXphdGlvbicsICdCZWFyZXIgJyArIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOKVxuICAgICAgICAgICAgLnNlbmQoe1xuICAgICAgICAgICAgICBhZGRyZXNzOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX0FERFJFU1MsXG4gICAgICAgICAgICAgIGFtb3VudDogMC4wMDEgKiAxZTgsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5URVNUX1BBU1NXT1JELFxuICAgICAgICAgICAgICBmZWU6IDEyMzQ1LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc2hvdWxkLmhhdmUuc3RhdHVzKDIwMik7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BlbmRpbmdBcHByb3ZhbCcpO1xuICAgICAgICAgIHJlcy5ib2R5LnN0YXR1cy5zaG91bGQuZXFsKCdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWxJZCA9IHJlcy5ib2R5LnBlbmRpbmdBcHByb3ZhbDtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wdXQoJy9hcGkvdjEvcGVuZGluZ2FwcHJvdmFscy8nICsgcGVuZGluZ0FwcHJvdmFsSWQgKyAnL2NvbnN0cnVjdFR4JylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTilcbiAgICAgICAgICAgIC5zZW5kKHsgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfUEFTU1dPUkQsIHVzZU9yaWdpbmFsRmVlOiB0cnVlIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgICAgICAgcmVzLmJvZHkudHguc2hvdWxkLm5vdC5lcWwoJycpO1xuICAgICAgICAgIHJlcy5ib2R5LmZlZS5zaG91bGQuZXFsKDEyMzQ1KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY2FsY3VsYXRlIHR4IHNpemUgZnJvbSBwYXJhbWV0ZXJzJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL2NhbGN1bGF0ZW1pbmVyZmVlaW5mbycpXG4gICAgICAgIC5zZW5kKHtcbiAgICAgICAgICBmZWVSYXRlOiAyMDAwMCxcbiAgICAgICAgICBuUDJzaElucHV0czogMixcbiAgICAgICAgICBuUDJwa2hJbnB1dHM6IDEsXG4gICAgICAgICAgblAyc2hQMndzaElucHV0czogMCxcbiAgICAgICAgICBuT3V0cHV0czogNCxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5zaG91bGQuaGF2ZS5zdGF0dXMoMjAwKTtcbiAgICAgICAgICByZXMuYm9keS5zaXplLnNob3VsZC5lcWwoOTIwKTtcbiAgICAgICAgICByZXMuYm9keS5mZWUuc2hvdWxkLmVxbCgxODQwMCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgeGl0KCdjcmVhdGUgYW5kIGFjY2VwdCBhIHBlbmRpbmcgYXBwcm92YWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGVzdFV0aWxcbiAgICAgICAgLnVubG9ja1Rva2VuKGFnZW50LCBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTiwgMTUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gdGVzdFV0aWwudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOX1NIQVJFRFVTRVIsIDE1KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEvd2FsbGV0LycgKyBUZXN0Qml0R28uVEVTVF9TSEFSRURfV0FMTEVUX0FERFJFU1MgKyAnL3NlbmRjb2lucycpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUyxcbiAgICAgICAgICAgICAgYW1vdW50OiAwLjAwMSAqIDFlOCxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfUEFTU1dPUkQsXG4gICAgICAgICAgICAgIG90cDogYml0Z28udGVzdFVzZXJPVFAoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDIpO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgICAgICByZXMuYm9keS5zdGF0dXMuc2hvdWxkLmVxbCgncGVuZGluZ0FwcHJvdmFsJyk7XG4gICAgICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsSWQgPSByZXMuYm9keS5wZW5kaW5nQXBwcm92YWw7XG4gICAgICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgICAgICAucHV0KCcvYXBpL3YxL3BlbmRpbmdhcHByb3ZhbHMvJyArIHBlbmRpbmdBcHByb3ZhbElkICsgJy9leHByZXNzJylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTl9TSEFSRURVU0VSKVxuICAgICAgICAgICAgLnNlbmQoeyB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9QQVNTV09SRCwgc3RhdGU6ICdhcHByb3ZlZCcsIG90cDogYml0Z28udGVzdFVzZXJPVFAoKSB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJlcy5ib2R5LnN0YXRlLnNob3VsZC5lcWwoJ2FwcHJvdmVkJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgeGl0KCdjcmVhdGUgYW5kIGFjY2VwdCBhIHBlbmRpbmcgYXBwcm92YWwgdXNpbmcgdGhlIHhwcnYnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdGVzdFV0aWxcbiAgICAgICAgLnVubG9ja1Rva2VuKGFnZW50LCBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTiwgMTUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXR1cm4gdGVzdFV0aWwudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOX1NIQVJFRFVTRVIsIDE1KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEvd2FsbGV0LycgKyBUZXN0Qml0R28uVEVTVF9TSEFSRURfV0FMTEVUX0FERFJFU1MgKyAnL3NlbmRjb2lucycpXG4gICAgICAgICAgICAuc2V0KCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnICsgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU4pXG4gICAgICAgICAgICAuc2VuZCh7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfQUREUkVTUyxcbiAgICAgICAgICAgICAgYW1vdW50OiAwLjAwMSAqIDFlOCxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfUEFTU1dPUkQsXG4gICAgICAgICAgICAgIG90cDogYml0Z28udGVzdFVzZXJPVFAoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLnNob3VsZC5oYXZlLnN0YXR1cygyMDIpO1xuICAgICAgICAgIHJlcy5ib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgICAgICByZXMuYm9keS5zdGF0dXMuc2hvdWxkLmVxbCgncGVuZGluZ0FwcHJvdmFsJyk7XG4gICAgICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsSWQgPSByZXMuYm9keS5wZW5kaW5nQXBwcm92YWw7XG4gICAgICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgICAgICAucHV0KCcvYXBpL3YxL3BlbmRpbmdhcHByb3ZhbHMvJyArIHBlbmRpbmdBcHByb3ZhbElkICsgJy9leHByZXNzJylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTl9TSEFSRURVU0VSKVxuICAgICAgICAgICAgLnNlbmQoe1xuICAgICAgICAgICAgICB4cHJ2OiAneHBydjlzMjFaclFIMTQzSzNHaXNEdmNzTHlRWjg4Q3JndEh6aVB1UTRaWlU2eDN2OEFaeEVZRUJaN0FOd2ZBUFZ6OW1xcmFTalJFVmFDZEZndjF1N21Idmp1RFJaMjVKNHdHSjczeW9vWWhEb0o0JyxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhcHByb3ZlZCcsXG4gICAgICAgICAgICAgIG90cDogYml0Z28udGVzdFVzZXJPVFAoKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmVzLmJvZHkuc3RhdGUuc2hvdWxkLmVxbCgnYXBwcm92ZWQnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB4aXQoJ2NyZWF0ZSBhbmQgYWNjZXB0IGEgcGVuZGluZyBhcHByb3ZhbCAoMiBzdGVwIGFjY2VwdCBieSBjb25zdHJ1Y3RpbmcgdHggd2l0aCBvcmlnaW5hbCB1c2VyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBwZW5kaW5nQXBwcm92YWxJZDtcbiAgICAgIHJldHVybiB0ZXN0VXRpbFxuICAgICAgICAudW5sb2NrVG9rZW4oYWdlbnQsIFRlc3RCaXRHby5URVNUX0FDQ0VTU1RPS0VOLCAxNSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgIHJldHVybiB0ZXN0VXRpbC51bmxvY2tUb2tlbihhZ2VudCwgVGVzdEJpdEdvLlRFU1RfQUNDRVNTVE9LRU5fU0hBUkVEVVNFUiwgMTUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgcmV0dXJuIGFnZW50XG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS93YWxsZXQvJyArIFRlc3RCaXRHby5URVNUX1NIQVJFRF9XQUxMRVRfQUREUkVTUyArICcvc2VuZGNvaW5zJylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTilcbiAgICAgICAgICAgIC5zZW5kKHtcbiAgICAgICAgICAgICAgYWRkcmVzczogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9BRERSRVNTLFxuICAgICAgICAgICAgICBhbW91bnQ6IDAuMDAxICogMWU4LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9QQVNTV09SRCxcbiAgICAgICAgICAgICAgZmVlOiAxMjM0NSxcbiAgICAgICAgICAgICAgb3RwOiBiaXRnby50ZXN0VXNlck9UUCgpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuc2hvdWxkLmhhdmUuc3RhdHVzKDIwMik7XG4gICAgICAgICAgcmVzLmJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BlbmRpbmdBcHByb3ZhbCcpO1xuICAgICAgICAgIHJlcy5ib2R5LnN0YXR1cy5zaG91bGQuZXFsKCdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgICAgICBwZW5kaW5nQXBwcm92YWxJZCA9IHJlcy5ib2R5LnBlbmRpbmdBcHByb3ZhbDtcbiAgICAgICAgICByZXR1cm4gYWdlbnRcbiAgICAgICAgICAgIC5wdXQoJy9hcGkvdjEvcGVuZGluZ2FwcHJvdmFscy8nICsgcGVuZGluZ0FwcHJvdmFsSWQgKyAnL2NvbnN0cnVjdFR4JylcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTilcbiAgICAgICAgICAgIC5zZW5kKHsgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfUEFTU1dPUkQgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcbiAgICAgICAgICByZXMuYm9keS50eC5zaG91bGQubm90LmVxbCgnJyk7XG4gICAgICAgICAgcmVzLmJvZHkuZmVlLnNob3VsZC5ub3QuZXFsKDEyMzQ1KTsgLy8gZmVlIHNob3VsZCBiZSByZWNhbGN1bGF0ZWQgZHluYW1pY2FsbHlcbiAgICAgICAgICBjb25zdCB0eEhleCA9IHJlcy5ib2R5LnR4O1xuICAgICAgICAgIHJldHVybiBhZ2VudFxuICAgICAgICAgICAgLnB1dCgnL2FwaS92MS9wZW5kaW5nYXBwcm92YWxzLycgKyBwZW5kaW5nQXBwcm92YWxJZClcbiAgICAgICAgICAgIC5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBUZXN0Qml0R28uVEVTVF9BQ0NFU1NUT0tFTl9TSEFSRURVU0VSKVxuICAgICAgICAgICAgLnNlbmQoeyB0eDogdHhIZXgsIHN0YXRlOiAnYXBwcm92ZWQnLCBvdHA6IGJpdGdvLnRlc3RVc2VyT1RQKCkgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICByZXMuYm9keS5zdGF0ZS5zaG91bGQuZXFsKCdhcHByb3ZlZCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!