@bitgo-beta/sdk-core 8.2.1-beta.1770 → 8.2.1-beta.1772

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,10 +36,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const assert = __importStar(require("assert"));
37
37
  require("should");
38
38
  const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
39
+ const mpc_1 = require("../../../../../src/account-lib/mpc");
39
40
  function getAddressVerificationModule() {
40
41
  return require('../../../../../src/bitgo/utils/tss/addressVerification');
41
42
  }
42
43
  const getExtractCommonKeychain = () => getAddressVerificationModule().extractCommonKeychain;
44
+ const getVerifyEddsaTssWalletAddress = () => getAddressVerificationModule().verifyEddsaTssWalletAddress;
45
+ const getVerifyMPCWalletAddress = () => getAddressVerificationModule().verifyMPCWalletAddress;
46
+ // RFC 8032 test vector: known valid Ed25519 public key + arbitrary chaincode = 128 hex chars.
47
+ const TEST_PK = 'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a';
48
+ const TEST_CHAINCODE = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
49
+ const TEST_KEYCHAIN = TEST_PK + TEST_CHAINCODE;
50
+ // secp256k1 generator point G (compressed, 33 bytes = 66 hex) + same chaincode = 130 hex chars.
51
+ const ECDSA_PK = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
52
+ const ECDSA_KEYCHAIN = ECDSA_PK + TEST_CHAINCODE;
43
53
  describe('TSS Address Verification - Derivation Path with Prefix', function () {
44
54
  const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
45
55
  describe('extractCommonKeychain', function () {
@@ -82,4 +92,112 @@ describe('TSS Address Verification - Derivation Path with Prefix', function () {
82
92
  });
83
93
  });
84
94
  });
85
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzc1ZlcmlmaWNhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvYWRkcmVzc1ZlcmlmaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyxrQkFBZ0I7QUFDaEIseURBQTREO0FBRTVELFNBQVMsNEJBQTRCO0lBQ25DLE9BQU8sT0FBTyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVELE1BQU0sd0JBQXdCLEdBQUcsR0FBRyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztBQUU1RixRQUFRLENBQUMsd0RBQXdELEVBQUU7SUFDakUsTUFBTSxjQUFjLEdBQ2xCLGtJQUFrSSxDQUFDO0lBRXJJLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtRQUNoQyxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsTUFBTSxxQkFBcUIsR0FBRyx3QkFBd0IsRUFBRSxDQUFDO1lBQ3pELE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUUvRSxNQUFNLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxNQUFNLHFCQUFxQixHQUFHLHdCQUF3QixFQUFFLENBQUM7WUFDekQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUMsRUFBRSxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsU0FBZ0IsQ0FBQyxFQUFFLGtDQUFrQyxDQUFDLENBQUM7UUFDbkcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsTUFBTSxxQkFBcUIsR0FBRyx3QkFBd0IsRUFBRSxDQUFDO1lBQ3pELE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLFNBQWdCLENBQUMsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1FBQ3hHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFO1lBQ3BFLE1BQU0scUJBQXFCLEdBQUcsd0JBQXdCLEVBQUUsQ0FBQztZQUN6RCxNQUFNLFNBQVMsR0FBRyxDQUFDLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDLEVBQUUsaURBQWlELENBQUMsQ0FBQztRQUMzRyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1DQUFtQyxFQUFFO1FBQzVDLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtZQUNsRCxNQUFNLFNBQVMsR0FBRyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBRWhFLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDekIsTUFBTSxJQUFJLEdBQUcsSUFBQSwrQkFBaUIsRUFBQyxJQUFJLENBQUMsQ0FBQztnQkFFckMsOENBQThDO2dCQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUUzQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFNUIsOEJBQThCO2dCQUM5QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QixLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IHsgZ2V0RGVyaXZhdGlvblBhdGggfSBmcm9tICdAYml0Z28tYmV0YS9zZGstbGliLW1wYyc7XG5cbmZ1bmN0aW9uIGdldEFkZHJlc3NWZXJpZmljYXRpb25Nb2R1bGUoKSB7XG4gIHJldHVybiByZXF1aXJlKCcuLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2FkZHJlc3NWZXJpZmljYXRpb24nKTtcbn1cblxuY29uc3QgZ2V0RXh0cmFjdENvbW1vbktleWNoYWluID0gKCkgPT4gZ2V0QWRkcmVzc1ZlcmlmaWNhdGlvbk1vZHVsZSgpLmV4dHJhY3RDb21tb25LZXljaGFpbjtcblxuZGVzY3JpYmUoJ1RTUyBBZGRyZXNzIFZlcmlmaWNhdGlvbiAtIERlcml2YXRpb24gUGF0aCB3aXRoIFByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICc4ZWEzMmVjYWNmYzgzZWZmYmQyZTI3OTBlZTQ0ZmE3YzU5YjRkODZjMjlhMTJmMDlmYjYxM2Q4MTk1ZjkzZjRlMjE4NzVjYWQzYjk4YWRhZGE0MGMwNDBjNTRjMzU2OTQ2N2RmNDFhMDIwODgxYTYxODQwOTYzNzg3MDE4NjJiZCc7XG5cbiAgZGVzY3JpYmUoJ2V4dHJhY3RDb21tb25LZXljaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGV4dHJhY3QgY29tbW9uS2V5Y2hhaW4gZnJvbSBrZXljaGFpbnMgYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHRyYWN0Q29tbW9uS2V5Y2hhaW4gPSBnZXRFeHRyYWN0Q29tbW9uS2V5Y2hhaW4oKTtcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGNvbW1vbktleWNoYWluIH0sIHsgY29tbW9uS2V5Y2hhaW4gfSwgeyBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdENvbW1vbktleWNoYWluKGtleWNoYWlucyk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKGNvbW1vbktleWNoYWluKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYga2V5Y2hhaW5zIGFyZSBtaXNzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IGV4dHJhY3RDb21tb25LZXljaGFpbihbXSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucy8pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBleHRyYWN0Q29tbW9uS2V5Y2hhaW4odW5kZWZpbmVkIGFzIGFueSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnIH1dO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBleHRyYWN0Q29tbW9uS2V5Y2hhaW4oa2V5Y2hhaW5zIGFzIGFueSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGNvbW1vbktleWNoYWluLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIGtleWNoYWlucyBoYXZlIG1pc21hdGNoZWQgY29tbW9uS2V5Y2hhaW5zJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBjb21tb25LZXljaGFpbiB9LCB7IGNvbW1vbktleWNoYWluOiAnZGlmZmVyZW50LWtleWNoYWluJyB9XTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gZXh0cmFjdENvbW1vbktleWNoYWluKGtleWNoYWlucyksIC9hbGwga2V5Y2hhaW5zIG11c3QgaGF2ZSB0aGUgc2FtZSBjb21tb25LZXljaGFpbi8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRGVyaXZhdGlvbiBQYXRoIEZvcm1hdCBWYWxpZGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGRlcml2YXRpb24gcGF0aCBmb3JtYXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0U2VlZHMgPSBbJ3NlZWQxJywgJ3NlZWQtMicsICcxMjM0NScsICd0ZXN0X3NlZWRfMTIzJ107XG5cbiAgICAgIHRlc3RTZWVkcy5mb3JFYWNoKChzZWVkKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBnZXREZXJpdmF0aW9uUGF0aChzZWVkKTtcblxuICAgICAgICAvLyBFeHBlY3RlZCBmb3JtYXQ6IFwibS85OTk5OTkve3BhcnQxfS97cGFydDJ9XCJcbiAgICAgICAgcGF0aC5zaG91bGQubWF0Y2goL15tXFwvOTk5OTk5XFwvXFxkK1xcL1xcZCskLyk7XG5cbiAgICAgICAgcGF0aC5zaG91bGQuc3RhcnRXaXRoKCdtLycpO1xuXG4gICAgICAgIC8vIFNob3VsZCBoYXZlIGV4YWN0bHkgMyBwYXJ0c1xuICAgICAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoJy8nKTtcbiAgICAgICAgcGFydHMubGVuZ3RoLnNob3VsZC5lcXVhbCg0KTtcbiAgICAgICAgcGFydHNbMF0uc2hvdWxkLmVxdWFsKCdtJyk7XG4gICAgICAgIHBhcnRzWzFdLnNob3VsZC5lcXVhbCgnOTk5OTk5Jyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
95
+ describe('verifyEddsaTssWalletAddress', function () {
96
+ const keychains = [
97
+ { commonKeychain: TEST_KEYCHAIN },
98
+ { commonKeychain: TEST_KEYCHAIN },
99
+ { commonKeychain: TEST_KEYCHAIN },
100
+ ];
101
+ const isValidAddress = (addr) => addr.length === 64;
102
+ const getAddressFromPublicKey = (pk) => pk;
103
+ describe('MPCv2 wallets (Silence Labs / MPS formula)', function () {
104
+ it('verifies a correct address derived with deriveUnhardenedMps at index 0', async function () {
105
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
106
+ const expectedAddress = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, 'm/0').slice(0, 64);
107
+ const result = await verifyEddsaTssWalletAddress({ address: expectedAddress, keychains, index: 0, multisigTypeVersion: 'MPCv2' }, isValidAddress, getAddressFromPublicKey);
108
+ result.should.be.true();
109
+ });
110
+ it('verifies a correct address derived with deriveUnhardenedMps at index 1', async function () {
111
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
112
+ const expectedAddress = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, 'm/1').slice(0, 64);
113
+ const result = await verifyEddsaTssWalletAddress({ address: expectedAddress, keychains, index: 1, multisigTypeVersion: 'MPCv2' }, isValidAddress, getAddressFromPublicKey);
114
+ result.should.be.true();
115
+ });
116
+ it('rejects an address derived at a different index', async function () {
117
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
118
+ const addressFromIndex0 = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, 'm/0').slice(0, 64);
119
+ const result = await verifyEddsaTssWalletAddress({ address: addressFromIndex0, keychains, index: 1, multisigTypeVersion: 'MPCv2' }, isValidAddress, getAddressFromPublicKey);
120
+ result.should.be.false();
121
+ });
122
+ it('rejects a random address that was not derived from the keychain', async function () {
123
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
124
+ const randomAddress = 'ab'.repeat(32); // 64 hex chars, wrong address
125
+ const result = await verifyEddsaTssWalletAddress({ address: randomAddress, keychains, index: 0, multisigTypeVersion: 'MPCv2' }, isValidAddress, getAddressFromPublicKey);
126
+ result.should.be.false();
127
+ });
128
+ it('verifies a correct MPCv2 address for SMC wallet using derivedFromParentWithSeed', async function () {
129
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
130
+ const seed = 'smc-seed-123';
131
+ const prefix = (0, sdk_lib_mpc_1.getDerivationPath)(seed);
132
+ const expectedAddress = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, `${prefix}/0`).slice(0, 64);
133
+ const result = await verifyEddsaTssWalletAddress({
134
+ address: expectedAddress,
135
+ keychains,
136
+ index: 0,
137
+ multisigTypeVersion: 'MPCv2',
138
+ derivedFromParentWithSeed: seed,
139
+ }, isValidAddress, getAddressFromPublicKey);
140
+ result.should.be.true();
141
+ });
142
+ it('rejects an MPCv2 address derived at the wrong index when derivedFromParentWithSeed is set', async function () {
143
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
144
+ const seed = 'smc-seed-123';
145
+ const prefix = (0, sdk_lib_mpc_1.getDerivationPath)(seed);
146
+ const addressAtIndex1 = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, `${prefix}/1`).slice(0, 64);
147
+ const result = await verifyEddsaTssWalletAddress({
148
+ address: addressAtIndex1,
149
+ keychains,
150
+ index: 0,
151
+ multisigTypeVersion: 'MPCv2',
152
+ derivedFromParentWithSeed: seed,
153
+ }, isValidAddress, getAddressFromPublicKey);
154
+ result.should.be.false();
155
+ });
156
+ });
157
+ describe('non-MPCv2 wallets (MPCv1 formula)', function () {
158
+ it('rejects an MPCv2-derived address when multisigTypeVersion is not set', async function () {
159
+ const verifyEddsaTssWalletAddress = getVerifyEddsaTssWalletAddress();
160
+ // MPCv2 (Silence Labs) and MPCv1 formulas produce different addresses for the same keychain.
161
+ // Without multisigTypeVersion: 'MPCv2', the MPCv1 formula is used, so the MPCv2-derived
162
+ // address should not match.
163
+ const mpcv2Address = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(TEST_KEYCHAIN, 'm/0').slice(0, 64);
164
+ const result = await verifyEddsaTssWalletAddress({ address: mpcv2Address, keychains, index: 0 }, isValidAddress, getAddressFromPublicKey);
165
+ result.should.be.false();
166
+ });
167
+ });
168
+ });
169
+ describe('verifyMPCWalletAddress - ECDSA (secp256k1)', function () {
170
+ const ecdsaKeychains = [
171
+ { commonKeychain: ECDSA_KEYCHAIN },
172
+ { commonKeychain: ECDSA_KEYCHAIN },
173
+ { commonKeychain: ECDSA_KEYCHAIN },
174
+ ];
175
+ // secp256k1 compressed public key is 33 bytes = 66 hex chars
176
+ const isValidEcdsaAddress = (addr) => addr.length === 66;
177
+ const getAddressFromPublicKey = (pk) => pk;
178
+ it('ignores multisigTypeVersion MPCv2 and uses Ecdsa derivation for secp256k1 wallets', async function () {
179
+ const verifyMPCWalletAddress = getVerifyMPCWalletAddress();
180
+ const expectedAddress = new mpc_1.Ecdsa().deriveUnhardened(ECDSA_KEYCHAIN, 'm/0').slice(0, 66);
181
+ const result = await verifyMPCWalletAddress({
182
+ address: expectedAddress,
183
+ keychains: ecdsaKeychains,
184
+ index: 0,
185
+ multisigTypeVersion: 'MPCv2',
186
+ keyCurve: 'secp256k1',
187
+ }, isValidEcdsaAddress, getAddressFromPublicKey);
188
+ result.should.be.true();
189
+ });
190
+ it('verifies a correct secp256k1 address at index 1', async function () {
191
+ const verifyMPCWalletAddress = getVerifyMPCWalletAddress();
192
+ const expectedAddress = new mpc_1.Ecdsa().deriveUnhardened(ECDSA_KEYCHAIN, 'm/1').slice(0, 66);
193
+ const result = await verifyMPCWalletAddress({ address: expectedAddress, keychains: ecdsaKeychains, index: 1, keyCurve: 'secp256k1' }, isValidEcdsaAddress, getAddressFromPublicKey);
194
+ result.should.be.true();
195
+ });
196
+ it('rejects an address derived at a different index', async function () {
197
+ const verifyMPCWalletAddress = getVerifyMPCWalletAddress();
198
+ const addressAtIndex0 = new mpc_1.Ecdsa().deriveUnhardened(ECDSA_KEYCHAIN, 'm/0').slice(0, 66);
199
+ const result = await verifyMPCWalletAddress({ address: addressAtIndex0, keychains: ecdsaKeychains, index: 1, keyCurve: 'secp256k1' }, isValidEcdsaAddress, getAddressFromPublicKey);
200
+ result.should.be.false();
201
+ });
202
+ });
203
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzc1ZlcmlmaWNhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvYWRkcmVzc1ZlcmlmaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyxrQkFBZ0I7QUFDaEIseURBQWlGO0FBQ2pGLDREQUEyRDtBQUUzRCxTQUFTLDRCQUE0QjtJQUNuQyxPQUFPLE9BQU8sQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO0FBQzNFLENBQUM7QUFFRCxNQUFNLHdCQUF3QixHQUFHLEdBQUcsRUFBRSxDQUFDLDRCQUE0QixFQUFFLENBQUMscUJBQXFCLENBQUM7QUFDNUYsTUFBTSw4QkFBOEIsR0FBRyxHQUFHLEVBQUUsQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLDJCQUEyQixDQUFDO0FBQ3hHLE1BQU0seUJBQXlCLEdBQUcsR0FBRyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQztBQUU5Riw4RkFBOEY7QUFDOUYsTUFBTSxPQUFPLEdBQUcsa0VBQWtFLENBQUM7QUFDbkYsTUFBTSxjQUFjLEdBQUcsa0VBQWtFLENBQUM7QUFDMUYsTUFBTSxhQUFhLEdBQUcsT0FBTyxHQUFHLGNBQWMsQ0FBQztBQUUvQyxnR0FBZ0c7QUFDaEcsTUFBTSxRQUFRLEdBQUcsb0VBQW9FLENBQUM7QUFDdEYsTUFBTSxjQUFjLEdBQUcsUUFBUSxHQUFHLGNBQWMsQ0FBQztBQUVqRCxRQUFRLENBQUMsd0RBQXdELEVBQUU7SUFDakUsTUFBTSxjQUFjLEdBQ2xCLGtJQUFrSSxDQUFDO0lBRXJJLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtRQUNoQyxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsTUFBTSxxQkFBcUIsR0FBRyx3QkFBd0IsRUFBRSxDQUFDO1lBQ3pELE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUUvRSxNQUFNLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxNQUFNLHFCQUFxQixHQUFHLHdCQUF3QixFQUFFLENBQUM7WUFDekQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUMsRUFBRSxrQ0FBa0MsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsU0FBZ0IsQ0FBQyxFQUFFLGtDQUFrQyxDQUFDLENBQUM7UUFDbkcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsTUFBTSxxQkFBcUIsR0FBRyx3QkFBd0IsRUFBRSxDQUFDO1lBQ3pELE1BQU0sU0FBUyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLFNBQWdCLENBQUMsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1FBQ3hHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFO1lBQ3BFLE1BQU0scUJBQXFCLEdBQUcsd0JBQXdCLEVBQUUsQ0FBQztZQUN6RCxNQUFNLFNBQVMsR0FBRyxDQUFDLEVBQUUsY0FBYyxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDLEVBQUUsaURBQWlELENBQUMsQ0FBQztRQUMzRyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1DQUFtQyxFQUFFO1FBQzVDLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRTtZQUNsRCxNQUFNLFNBQVMsR0FBRyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBRWhFLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDekIsTUFBTSxJQUFJLEdBQUcsSUFBQSwrQkFBaUIsRUFBQyxJQUFJLENBQUMsQ0FBQztnQkFFckMsOENBQThDO2dCQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUUzQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFNUIsOEJBQThCO2dCQUM5QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QixLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILFFBQVEsQ0FBQyw2QkFBNkIsRUFBRTtJQUN0QyxNQUFNLFNBQVMsR0FBRztRQUNoQixFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUU7UUFDakMsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFO1FBQ2pDLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRTtLQUNsQyxDQUFDO0lBQ0YsTUFBTSxjQUFjLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssRUFBRSxDQUFDO0lBQzVELE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxFQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUVuRCxRQUFRLENBQUMsNENBQTRDLEVBQUU7UUFDckQsRUFBRSxDQUFDLHdFQUF3RSxFQUFFLEtBQUs7WUFDaEYsTUFBTSwyQkFBMkIsR0FBRyw4QkFBOEIsRUFBRSxDQUFDO1lBQ3JFLE1BQU0sZUFBZSxHQUFHLElBQUEsaUNBQW1CLEVBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFL0UsTUFBTSxNQUFNLEdBQUcsTUFBTSwyQkFBMkIsQ0FDOUMsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxFQUMvRSxjQUFjLEVBQ2QsdUJBQXVCLENBQ3hCLENBQUM7WUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx3RUFBd0UsRUFBRSxLQUFLO1lBQ2hGLE1BQU0sMkJBQTJCLEdBQUcsOEJBQThCLEVBQUUsQ0FBQztZQUNyRSxNQUFNLGVBQWUsR0FBRyxJQUFBLGlDQUFtQixFQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRS9FLE1BQU0sTUFBTSxHQUFHLE1BQU0sMkJBQTJCLENBQzlDLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsRUFDL0UsY0FBYyxFQUNkLHVCQUF1QixDQUN4QixDQUFDO1lBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsS0FBSztZQUN6RCxNQUFNLDJCQUEyQixHQUFHLDhCQUE4QixFQUFFLENBQUM7WUFDckUsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLGlDQUFtQixFQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRWpGLE1BQU0sTUFBTSxHQUFHLE1BQU0sMkJBQTJCLENBQzlDLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxFQUNqRixjQUFjLEVBQ2QsdUJBQXVCLENBQ3hCLENBQUM7WUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpRUFBaUUsRUFBRSxLQUFLO1lBQ3pFLE1BQU0sMkJBQTJCLEdBQUcsOEJBQThCLEVBQUUsQ0FBQztZQUNyRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsOEJBQThCO1lBRXJFLE1BQU0sTUFBTSxHQUFHLE1BQU0sMkJBQTJCLENBQzlDLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsRUFDN0UsY0FBYyxFQUNkLHVCQUF1QixDQUN4QixDQUFDO1lBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUZBQWlGLEVBQUUsS0FBSztZQUN6RixNQUFNLDJCQUEyQixHQUFHLDhCQUE4QixFQUFFLENBQUM7WUFDckUsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDO1lBQzVCLE1BQU0sTUFBTSxHQUFHLElBQUEsK0JBQWlCLEVBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsTUFBTSxlQUFlLEdBQUcsSUFBQSxpQ0FBbUIsRUFBQyxhQUFhLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFdkYsTUFBTSxNQUFNLEdBQUcsTUFBTSwyQkFBMkIsQ0FDOUM7Z0JBQ0UsT0FBTyxFQUFFLGVBQWU7Z0JBQ3hCLFNBQVM7Z0JBQ1QsS0FBSyxFQUFFLENBQUM7Z0JBQ1IsbUJBQW1CLEVBQUUsT0FBTztnQkFDNUIseUJBQXlCLEVBQUUsSUFBSTthQUNoQyxFQUNELGNBQWMsRUFDZCx1QkFBdUIsQ0FDeEIsQ0FBQztZQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJGQUEyRixFQUFFLEtBQUs7WUFDbkcsTUFBTSwyQkFBMkIsR0FBRyw4QkFBOEIsRUFBRSxDQUFDO1lBQ3JFLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQztZQUM1QixNQUFNLE1BQU0sR0FBRyxJQUFBLCtCQUFpQixFQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sZUFBZSxHQUFHLElBQUEsaUNBQW1CLEVBQUMsYUFBYSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRXZGLE1BQU0sTUFBTSxHQUFHLE1BQU0sMkJBQTJCLENBQzlDO2dCQUNFLE9BQU8sRUFBRSxlQUFlO2dCQUN4QixTQUFTO2dCQUNULEtBQUssRUFBRSxDQUFDO2dCQUNSLG1CQUFtQixFQUFFLE9BQU87Z0JBQzVCLHlCQUF5QixFQUFFLElBQUk7YUFDaEMsRUFDRCxjQUFjLEVBQ2QsdUJBQXVCLENBQ3hCLENBQUM7WUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG1DQUFtQyxFQUFFO1FBQzVDLEVBQUUsQ0FBQyxzRUFBc0UsRUFBRSxLQUFLO1lBQzlFLE1BQU0sMkJBQTJCLEdBQUcsOEJBQThCLEVBQUUsQ0FBQztZQUNyRSw2RkFBNkY7WUFDN0Ysd0ZBQXdGO1lBQ3hGLDRCQUE0QjtZQUM1QixNQUFNLFlBQVksR0FBRyxJQUFBLGlDQUFtQixFQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRTVFLE1BQU0sTUFBTSxHQUFHLE1BQU0sMkJBQTJCLENBQzlDLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUM5QyxjQUFjLEVBQ2QsdUJBQXVCLENBQ3hCLENBQUM7WUFFRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsNENBQTRDLEVBQUU7SUFDckQsTUFBTSxjQUFjLEdBQUc7UUFDckIsRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFO1FBQ2xDLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRTtRQUNsQyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUU7S0FDbkMsQ0FBQztJQUNGLDZEQUE2RDtJQUM3RCxNQUFNLG1CQUFtQixHQUFHLENBQUMsSUFBWSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLEVBQUUsQ0FBQztJQUNqRSxNQUFNLHVCQUF1QixHQUFHLENBQUMsRUFBVSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFFbkQsRUFBRSxDQUFDLG1GQUFtRixFQUFFLEtBQUs7UUFDM0YsTUFBTSxzQkFBc0IsR0FBRyx5QkFBeUIsRUFBRSxDQUFDO1FBQzNELE1BQU0sZUFBZSxHQUFHLElBQUksV0FBSyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFekYsTUFBTSxNQUFNLEdBQUcsTUFBTSxzQkFBc0IsQ0FDekM7WUFDRSxPQUFPLEVBQUUsZUFBZTtZQUN4QixTQUFTLEVBQUUsY0FBYztZQUN6QixLQUFLLEVBQUUsQ0FBQztZQUNSLG1CQUFtQixFQUFFLE9BQU87WUFDNUIsUUFBUSxFQUFFLFdBQVc7U0FDdEIsRUFDRCxtQkFBbUIsRUFDbkIsdUJBQXVCLENBQ3hCLENBQUM7UUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLO1FBQ3pELE1BQU0sc0JBQXNCLEdBQUcseUJBQXlCLEVBQUUsQ0FBQztRQUMzRCxNQUFNLGVBQWUsR0FBRyxJQUFJLFdBQUssRUFBRSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXpGLE1BQU0sTUFBTSxHQUFHLE1BQU0sc0JBQXNCLENBQ3pDLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxFQUN4RixtQkFBbUIsRUFDbkIsdUJBQXVCLENBQ3hCLENBQUM7UUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxQixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLO1FBQ3pELE1BQU0sc0JBQXNCLEdBQUcseUJBQXlCLEVBQUUsQ0FBQztRQUMzRCxNQUFNLGVBQWUsR0FBRyxJQUFJLFdBQUssRUFBRSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXpGLE1BQU0sTUFBTSxHQUFHLE1BQU0sc0JBQXNCLENBQ3pDLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxFQUN4RixtQkFBbUIsRUFDbkIsdUJBQXVCLENBQ3hCLENBQUM7UUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMzQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgJ3Nob3VsZCc7XG5pbXBvcnQgeyBkZXJpdmVVbmhhcmRlbmVkTXBzLCBnZXREZXJpdmF0aW9uUGF0aCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCB7IEVjZHNhIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc3JjL2FjY291bnQtbGliL21wYyc7XG5cbmZ1bmN0aW9uIGdldEFkZHJlc3NWZXJpZmljYXRpb25Nb2R1bGUoKSB7XG4gIHJldHVybiByZXF1aXJlKCcuLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2FkZHJlc3NWZXJpZmljYXRpb24nKTtcbn1cblxuY29uc3QgZ2V0RXh0cmFjdENvbW1vbktleWNoYWluID0gKCkgPT4gZ2V0QWRkcmVzc1ZlcmlmaWNhdGlvbk1vZHVsZSgpLmV4dHJhY3RDb21tb25LZXljaGFpbjtcbmNvbnN0IGdldFZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyA9ICgpID0+IGdldEFkZHJlc3NWZXJpZmljYXRpb25Nb2R1bGUoKS52ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3M7XG5jb25zdCBnZXRWZXJpZnlNUENXYWxsZXRBZGRyZXNzID0gKCkgPT4gZ2V0QWRkcmVzc1ZlcmlmaWNhdGlvbk1vZHVsZSgpLnZlcmlmeU1QQ1dhbGxldEFkZHJlc3M7XG5cbi8vIFJGQyA4MDMyIHRlc3QgdmVjdG9yOiBrbm93biB2YWxpZCBFZDI1NTE5IHB1YmxpYyBrZXkgKyBhcmJpdHJhcnkgY2hhaW5jb2RlID0gMTI4IGhleCBjaGFycy5cbmNvbnN0IFRFU1RfUEsgPSAnZDc1YTk4MDE4MmIxMGFiN2Q1NGJmZWQzYzk2NDA3M2EwZWUxNzJmM2RhYTYyMzI1YWYwMjFhNjhmNzA3NTExYSc7XG5jb25zdCBURVNUX0NIQUlOQ09ERSA9ICdkZWFkYmVlZmRlYWRiZWVmZGVhZGJlZWZkZWFkYmVlZmRlYWRiZWVmZGVhZGJlZWZkZWFkYmVlZmRlYWRiZWVmJztcbmNvbnN0IFRFU1RfS0VZQ0hBSU4gPSBURVNUX1BLICsgVEVTVF9DSEFJTkNPREU7XG5cbi8vIHNlY3AyNTZrMSBnZW5lcmF0b3IgcG9pbnQgRyAoY29tcHJlc3NlZCwgMzMgYnl0ZXMgPSA2NiBoZXgpICsgc2FtZSBjaGFpbmNvZGUgPSAxMzAgaGV4IGNoYXJzLlxuY29uc3QgRUNEU0FfUEsgPSAnMDI3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4JztcbmNvbnN0IEVDRFNBX0tFWUNIQUlOID0gRUNEU0FfUEsgKyBURVNUX0NIQUlOQ09ERTtcblxuZGVzY3JpYmUoJ1RTUyBBZGRyZXNzIFZlcmlmaWNhdGlvbiAtIERlcml2YXRpb24gUGF0aCB3aXRoIFByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICc4ZWEzMmVjYWNmYzgzZWZmYmQyZTI3OTBlZTQ0ZmE3YzU5YjRkODZjMjlhMTJmMDlmYjYxM2Q4MTk1ZjkzZjRlMjE4NzVjYWQzYjk4YWRhZGE0MGMwNDBjNTRjMzU2OTQ2N2RmNDFhMDIwODgxYTYxODQwOTYzNzg3MDE4NjJiZCc7XG5cbiAgZGVzY3JpYmUoJ2V4dHJhY3RDb21tb25LZXljaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGV4dHJhY3QgY29tbW9uS2V5Y2hhaW4gZnJvbSBrZXljaGFpbnMgYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHRyYWN0Q29tbW9uS2V5Y2hhaW4gPSBnZXRFeHRyYWN0Q29tbW9uS2V5Y2hhaW4oKTtcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGNvbW1vbktleWNoYWluIH0sIHsgY29tbW9uS2V5Y2hhaW4gfSwgeyBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdENvbW1vbktleWNoYWluKGtleWNoYWlucyk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKGNvbW1vbktleWNoYWluKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYga2V5Y2hhaW5zIGFyZSBtaXNzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IGV4dHJhY3RDb21tb25LZXljaGFpbihbXSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucy8pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBleHRyYWN0Q29tbW9uS2V5Y2hhaW4odW5kZWZpbmVkIGFzIGFueSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnIH1dO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBleHRyYWN0Q29tbW9uS2V5Y2hhaW4oa2V5Y2hhaW5zIGFzIGFueSksIC9taXNzaW5nIHJlcXVpcmVkIHBhcmFtIGNvbW1vbktleWNoYWluLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIGtleWNoYWlucyBoYXZlIG1pc21hdGNoZWQgY29tbW9uS2V5Y2hhaW5zJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0cmFjdENvbW1vbktleWNoYWluID0gZ2V0RXh0cmFjdENvbW1vbktleWNoYWluKCk7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBjb21tb25LZXljaGFpbiB9LCB7IGNvbW1vbktleWNoYWluOiAnZGlmZmVyZW50LWtleWNoYWluJyB9XTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gZXh0cmFjdENvbW1vbktleWNoYWluKGtleWNoYWlucyksIC9hbGwga2V5Y2hhaW5zIG11c3QgaGF2ZSB0aGUgc2FtZSBjb21tb25LZXljaGFpbi8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRGVyaXZhdGlvbiBQYXRoIEZvcm1hdCBWYWxpZGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBjb3JyZWN0IGRlcml2YXRpb24gcGF0aCBmb3JtYXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0U2VlZHMgPSBbJ3NlZWQxJywgJ3NlZWQtMicsICcxMjM0NScsICd0ZXN0X3NlZWRfMTIzJ107XG5cbiAgICAgIHRlc3RTZWVkcy5mb3JFYWNoKChzZWVkKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBnZXREZXJpdmF0aW9uUGF0aChzZWVkKTtcblxuICAgICAgICAvLyBFeHBlY3RlZCBmb3JtYXQ6IFwibS85OTk5OTkve3BhcnQxfS97cGFydDJ9XCJcbiAgICAgICAgcGF0aC5zaG91bGQubWF0Y2goL15tXFwvOTk5OTk5XFwvXFxkK1xcL1xcZCskLyk7XG5cbiAgICAgICAgcGF0aC5zaG91bGQuc3RhcnRXaXRoKCdtLycpO1xuXG4gICAgICAgIC8vIFNob3VsZCBoYXZlIGV4YWN0bHkgMyBwYXJ0c1xuICAgICAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoJy8nKTtcbiAgICAgICAgcGFydHMubGVuZ3RoLnNob3VsZC5lcXVhbCg0KTtcbiAgICAgICAgcGFydHNbMF0uc2hvdWxkLmVxdWFsKCdtJyk7XG4gICAgICAgIHBhcnRzWzFdLnNob3VsZC5lcXVhbCgnOTk5OTk5Jyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3ZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgIHsgY29tbW9uS2V5Y2hhaW46IFRFU1RfS0VZQ0hBSU4gfSxcbiAgICB7IGNvbW1vbktleWNoYWluOiBURVNUX0tFWUNIQUlOIH0sXG4gICAgeyBjb21tb25LZXljaGFpbjogVEVTVF9LRVlDSEFJTiB9LFxuICBdO1xuICBjb25zdCBpc1ZhbGlkQWRkcmVzcyA9IChhZGRyOiBzdHJpbmcpID0+IGFkZHIubGVuZ3RoID09PSA2NDtcbiAgY29uc3QgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkgPSAocGs6IHN0cmluZykgPT4gcGs7XG5cbiAgZGVzY3JpYmUoJ01QQ3YyIHdhbGxldHMgKFNpbGVuY2UgTGFicyAvIE1QUyBmb3JtdWxhKScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgndmVyaWZpZXMgYSBjb3JyZWN0IGFkZHJlc3MgZGVyaXZlZCB3aXRoIGRlcml2ZVVuaGFyZGVuZWRNcHMgYXQgaW5kZXggMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyA9IGdldFZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcygpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBZGRyZXNzID0gZGVyaXZlVW5oYXJkZW5lZE1wcyhURVNUX0tFWUNIQUlOLCAnbS8wJykuc2xpY2UoMCwgNjQpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoXG4gICAgICAgIHsgYWRkcmVzczogZXhwZWN0ZWRBZGRyZXNzLCBrZXljaGFpbnMsIGluZGV4OiAwLCBtdWx0aXNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInIH0sXG4gICAgICAgIGlzVmFsaWRBZGRyZXNzLFxuICAgICAgICBnZXRBZGRyZXNzRnJvbVB1YmxpY0tleVxuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZlcmlmaWVzIGEgY29ycmVjdCBhZGRyZXNzIGRlcml2ZWQgd2l0aCBkZXJpdmVVbmhhcmRlbmVkTXBzIGF0IGluZGV4IDEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MgPSBnZXRWZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkQWRkcmVzcyA9IGRlcml2ZVVuaGFyZGVuZWRNcHMoVEVTVF9LRVlDSEFJTiwgJ20vMScpLnNsaWNlKDAsIDY0KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5RWRkc2FUc3NXYWxsZXRBZGRyZXNzKFxuICAgICAgICB7IGFkZHJlc3M6IGV4cGVjdGVkQWRkcmVzcywga2V5Y2hhaW5zLCBpbmRleDogMSwgbXVsdGlzaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyB9LFxuICAgICAgICBpc1ZhbGlkQWRkcmVzcyxcbiAgICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICAgICk7XG4gICAgICByZXN1bHQuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIGFuIGFkZHJlc3MgZGVyaXZlZCBhdCBhIGRpZmZlcmVudCBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyA9IGdldFZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcygpO1xuICAgICAgY29uc3QgYWRkcmVzc0Zyb21JbmRleDAgPSBkZXJpdmVVbmhhcmRlbmVkTXBzKFRFU1RfS0VZQ0hBSU4sICdtLzAnKS5zbGljZSgwLCA2NCk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyhcbiAgICAgICAgeyBhZGRyZXNzOiBhZGRyZXNzRnJvbUluZGV4MCwga2V5Y2hhaW5zLCBpbmRleDogMSwgbXVsdGlzaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyB9LFxuICAgICAgICBpc1ZhbGlkQWRkcmVzcyxcbiAgICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICAgICk7XG4gICAgICByZXN1bHQuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVqZWN0cyBhIHJhbmRvbSBhZGRyZXNzIHRoYXQgd2FzIG5vdCBkZXJpdmVkIGZyb20gdGhlIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmVyaWZ5RWRkc2FUc3NXYWxsZXRBZGRyZXNzID0gZ2V0VmVyaWZ5RWRkc2FUc3NXYWxsZXRBZGRyZXNzKCk7XG4gICAgICBjb25zdCByYW5kb21BZGRyZXNzID0gJ2FiJy5yZXBlYXQoMzIpOyAvLyA2NCBoZXggY2hhcnMsIHdyb25nIGFkZHJlc3NcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5RWRkc2FUc3NXYWxsZXRBZGRyZXNzKFxuICAgICAgICB7IGFkZHJlc3M6IHJhbmRvbUFkZHJlc3MsIGtleWNoYWlucywgaW5kZXg6IDAsIG11bHRpc2lnVHlwZVZlcnNpb246ICdNUEN2MicgfSxcbiAgICAgICAgaXNWYWxpZEFkZHJlc3MsXG4gICAgICAgIGdldEFkZHJlc3NGcm9tUHVibGljS2V5XG4gICAgICApO1xuICAgICAgcmVzdWx0LnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZlcmlmaWVzIGEgY29ycmVjdCBNUEN2MiBhZGRyZXNzIGZvciBTTUMgd2FsbGV0IHVzaW5nIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MgPSBnZXRWZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoKTtcbiAgICAgIGNvbnN0IHNlZWQgPSAnc21jLXNlZWQtMTIzJztcbiAgICAgIGNvbnN0IHByZWZpeCA9IGdldERlcml2YXRpb25QYXRoKHNlZWQpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBZGRyZXNzID0gZGVyaXZlVW5oYXJkZW5lZE1wcyhURVNUX0tFWUNIQUlOLCBgJHtwcmVmaXh9LzBgKS5zbGljZSgwLCA2NCk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyhcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6IGV4cGVjdGVkQWRkcmVzcyxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICB9LFxuICAgICAgICBpc1ZhbGlkQWRkcmVzcyxcbiAgICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICAgICk7XG4gICAgICByZXN1bHQuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZWplY3RzIGFuIE1QQ3YyIGFkZHJlc3MgZGVyaXZlZCBhdCB0aGUgd3JvbmcgaW5kZXggd2hlbiBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkIGlzIHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyA9IGdldFZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcygpO1xuICAgICAgY29uc3Qgc2VlZCA9ICdzbWMtc2VlZC0xMjMnO1xuICAgICAgY29uc3QgcHJlZml4ID0gZ2V0RGVyaXZhdGlvblBhdGgoc2VlZCk7XG4gICAgICBjb25zdCBhZGRyZXNzQXRJbmRleDEgPSBkZXJpdmVVbmhhcmRlbmVkTXBzKFRFU1RfS0VZQ0hBSU4sIGAke3ByZWZpeH0vMWApLnNsaWNlKDAsIDY0KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5RWRkc2FUc3NXYWxsZXRBZGRyZXNzKFxuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogYWRkcmVzc0F0SW5kZXgxLFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgIH0sXG4gICAgICAgIGlzVmFsaWRBZGRyZXNzLFxuICAgICAgICBnZXRBZGRyZXNzRnJvbVB1YmxpY0tleVxuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ25vbi1NUEN2MiB3YWxsZXRzIChNUEN2MSBmb3JtdWxhKScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncmVqZWN0cyBhbiBNUEN2Mi1kZXJpdmVkIGFkZHJlc3Mgd2hlbiBtdWx0aXNpZ1R5cGVWZXJzaW9uIGlzIG5vdCBzZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MgPSBnZXRWZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoKTtcbiAgICAgIC8vIE1QQ3YyIChTaWxlbmNlIExhYnMpIGFuZCBNUEN2MSBmb3JtdWxhcyBwcm9kdWNlIGRpZmZlcmVudCBhZGRyZXNzZXMgZm9yIHRoZSBzYW1lIGtleWNoYWluLlxuICAgICAgLy8gV2l0aG91dCBtdWx0aXNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLCB0aGUgTVBDdjEgZm9ybXVsYSBpcyB1c2VkLCBzbyB0aGUgTVBDdjItZGVyaXZlZFxuICAgICAgLy8gYWRkcmVzcyBzaG91bGQgbm90IG1hdGNoLlxuICAgICAgY29uc3QgbXBjdjJBZGRyZXNzID0gZGVyaXZlVW5oYXJkZW5lZE1wcyhURVNUX0tFWUNIQUlOLCAnbS8wJykuc2xpY2UoMCwgNjQpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoXG4gICAgICAgIHsgYWRkcmVzczogbXBjdjJBZGRyZXNzLCBrZXljaGFpbnMsIGluZGV4OiAwIH0sXG4gICAgICAgIGlzVmFsaWRBZGRyZXNzLFxuICAgICAgICBnZXRBZGRyZXNzRnJvbVB1YmxpY0tleVxuICAgICAgKTtcblxuICAgICAgcmVzdWx0LnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgndmVyaWZ5TVBDV2FsbGV0QWRkcmVzcyAtIEVDRFNBIChzZWNwMjU2azEpJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBlY2RzYUtleWNoYWlucyA9IFtcbiAgICB7IGNvbW1vbktleWNoYWluOiBFQ0RTQV9LRVlDSEFJTiB9LFxuICAgIHsgY29tbW9uS2V5Y2hhaW46IEVDRFNBX0tFWUNIQUlOIH0sXG4gICAgeyBjb21tb25LZXljaGFpbjogRUNEU0FfS0VZQ0hBSU4gfSxcbiAgXTtcbiAgLy8gc2VjcDI1NmsxIGNvbXByZXNzZWQgcHVibGljIGtleSBpcyAzMyBieXRlcyA9IDY2IGhleCBjaGFyc1xuICBjb25zdCBpc1ZhbGlkRWNkc2FBZGRyZXNzID0gKGFkZHI6IHN0cmluZykgPT4gYWRkci5sZW5ndGggPT09IDY2O1xuICBjb25zdCBnZXRBZGRyZXNzRnJvbVB1YmxpY0tleSA9IChwazogc3RyaW5nKSA9PiBwaztcblxuICBpdCgnaWdub3JlcyBtdWx0aXNpZ1R5cGVWZXJzaW9uIE1QQ3YyIGFuZCB1c2VzIEVjZHNhIGRlcml2YXRpb24gZm9yIHNlY3AyNTZrMSB3YWxsZXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHZlcmlmeU1QQ1dhbGxldEFkZHJlc3MgPSBnZXRWZXJpZnlNUENXYWxsZXRBZGRyZXNzKCk7XG4gICAgY29uc3QgZXhwZWN0ZWRBZGRyZXNzID0gbmV3IEVjZHNhKCkuZGVyaXZlVW5oYXJkZW5lZChFQ0RTQV9LRVlDSEFJTiwgJ20vMCcpLnNsaWNlKDAsIDY2KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeU1QQ1dhbGxldEFkZHJlc3MoXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6IGV4cGVjdGVkQWRkcmVzcyxcbiAgICAgICAga2V5Y2hhaW5zOiBlY2RzYUtleWNoYWlucyxcbiAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgIG11bHRpc2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgIGtleUN1cnZlOiAnc2VjcDI1NmsxJyxcbiAgICAgIH0sXG4gICAgICBpc1ZhbGlkRWNkc2FBZGRyZXNzLFxuICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICApO1xuICAgIHJlc3VsdC5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgndmVyaWZpZXMgYSBjb3JyZWN0IHNlY3AyNTZrMSBhZGRyZXNzIGF0IGluZGV4IDEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdmVyaWZ5TVBDV2FsbGV0QWRkcmVzcyA9IGdldFZlcmlmeU1QQ1dhbGxldEFkZHJlc3MoKTtcbiAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSBuZXcgRWNkc2EoKS5kZXJpdmVVbmhhcmRlbmVkKEVDRFNBX0tFWUNIQUlOLCAnbS8xJykuc2xpY2UoMCwgNjYpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5TVBDV2FsbGV0QWRkcmVzcyhcbiAgICAgIHsgYWRkcmVzczogZXhwZWN0ZWRBZGRyZXNzLCBrZXljaGFpbnM6IGVjZHNhS2V5Y2hhaW5zLCBpbmRleDogMSwga2V5Q3VydmU6ICdzZWNwMjU2azEnIH0sXG4gICAgICBpc1ZhbGlkRWNkc2FBZGRyZXNzLFxuICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICApO1xuICAgIHJlc3VsdC5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgncmVqZWN0cyBhbiBhZGRyZXNzIGRlcml2ZWQgYXQgYSBkaWZmZXJlbnQgaW5kZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdmVyaWZ5TVBDV2FsbGV0QWRkcmVzcyA9IGdldFZlcmlmeU1QQ1dhbGxldEFkZHJlc3MoKTtcbiAgICBjb25zdCBhZGRyZXNzQXRJbmRleDAgPSBuZXcgRWNkc2EoKS5kZXJpdmVVbmhhcmRlbmVkKEVDRFNBX0tFWUNIQUlOLCAnbS8wJykuc2xpY2UoMCwgNjYpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5TVBDV2FsbGV0QWRkcmVzcyhcbiAgICAgIHsgYWRkcmVzczogYWRkcmVzc0F0SW5kZXgwLCBrZXljaGFpbnM6IGVjZHNhS2V5Y2hhaW5zLCBpbmRleDogMSwga2V5Q3VydmU6ICdzZWNwMjU2azEnIH0sXG4gICAgICBpc1ZhbGlkRWNkc2FBZGRyZXNzLFxuICAgICAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXlcbiAgICApO1xuICAgIHJlc3VsdC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=baseTSSUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseTSSUtils.d.ts","sourceRoot":"","sources":["../../../../../../test/unit/bitgo/utils/tss/baseTSSUtils.ts"],"names":[],"mappings":""}
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert = __importStar(require("assert"));
40
+ const crypto_1 = require("crypto");
41
+ const keccak_1 = __importDefault(require("keccak"));
42
+ const openpgp = __importStar(require("openpgp"));
43
+ const sinon = __importStar(require("sinon"));
44
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
45
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
46
+ const src_1 = require("../../../../../src");
47
+ const baseTSSUtils_1 = __importDefault(require("../../../../../src/bitgo/utils/tss/baseTSSUtils"));
48
+ class TestBaseTssUtils extends baseTSSUtils_1.default {
49
+ getSignableHexAndDerivationPathForTest(txRequest, missingTransactionsMessage) {
50
+ return this.getSignableHexAndDerivationPath(txRequest, missingTransactionsMessage);
51
+ }
52
+ validateAdataForTest(adata, cyphertext, roundDomainSeparator) {
53
+ this.validateAdata(adata, cyphertext, roundDomainSeparator);
54
+ }
55
+ getBitgoAndUserGpgKeysForTest(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase, adata, userGpgKeyDomainSeparator) {
56
+ return this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase, adata, userGpgKeyDomainSeparator);
57
+ }
58
+ }
59
+ describe('Base TSS Utils', function () {
60
+ const walletPassphrase = 'test-password';
61
+ const signingUserGpgKeyDomainSeparator = 'MPS_DSG_SIGNING_USER_GPG_KEY';
62
+ const roundOneDomainSeparator = 'MPS_DSG_SIGNING_ROUND1_STATE';
63
+ let baseTssUtils;
64
+ let ecdsaMPCv2Utils;
65
+ let mockBitgo;
66
+ let decryptAsyncStub;
67
+ let bitgoGpgKeyPair;
68
+ let userGpgKeyPair;
69
+ let userShare;
70
+ before(async function () {
71
+ openpgp.config.rejectCurves = new Set();
72
+ bitgoGpgKeyPair = await openpgp.generateKey({
73
+ userIDs: [{ name: 'bitgo', email: 'bitgo@test.com' }],
74
+ curve: 'ed25519',
75
+ format: 'armored',
76
+ });
77
+ userGpgKeyPair = await openpgp.generateKey({
78
+ userIDs: [{ name: 'user', email: 'user@test.com' }],
79
+ curve: 'ed25519',
80
+ format: 'armored',
81
+ });
82
+ const [userDkgSession] = await sdk_lib_mpc_1.DklsUtils.generateDKGKeyShares();
83
+ userShare = userDkgSession.getKeyShare();
84
+ });
85
+ beforeEach(function () {
86
+ decryptAsyncStub = sinon.stub().callsFake(({ input }) =>
87
+ // Fake v2 envelope: resolve the plaintext embedded in the JSON.
88
+ Promise.resolve(JSON.parse(input).plaintext));
89
+ const mockBg = {};
90
+ mockBg.getEnv = sinon.stub().returns('test');
91
+ mockBg.encrypt = sinon
92
+ .stub()
93
+ .callsFake((params) => encryptWithSjcl(params.password ?? '', params.input, params.adata));
94
+ mockBg.decrypt = sinon.stub().callsFake((params) => sjcl.decrypt(params.password ?? '', params.input));
95
+ mockBg.decryptAsync = decryptAsyncStub;
96
+ mockBitgo = mockBg;
97
+ const mockCoin = {};
98
+ mockCoin.getHashFunction = sinon.stub().callsFake(() => (0, keccak_1.default)('keccak256'));
99
+ baseTssUtils = new TestBaseTssUtils(mockBitgo, mockCoin);
100
+ ecdsaMPCv2Utils = new src_1.EcdsaMPCv2Utils(mockBitgo, mockCoin);
101
+ });
102
+ describe('getSignableHexAndDerivationPath', function () {
103
+ it('extracts signableHex and derivationPath from a valid txRequest', function () {
104
+ const txRequest = buildTxRequest({
105
+ transactions: [
106
+ buildTransaction({
107
+ unsignedTx: buildUnsignedTransaction({ signableHex: 'deadbeef', derivationPath: 'm/0/0' }),
108
+ }),
109
+ ],
110
+ });
111
+ const result = baseTssUtils.getSignableHexAndDerivationPathForTest(txRequest);
112
+ assert.equal(result.signableHex, 'deadbeef');
113
+ assert.equal(result.derivationPath, 'm/0/0');
114
+ });
115
+ it('throws when transactions field is missing', function () {
116
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequestWithoutTransactions()), /createOfflineShare requires exactly one transaction in txRequest/);
117
+ });
118
+ it('throws when transactions array is empty', function () {
119
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequest({ transactions: [] })), /createOfflineShare requires exactly one transaction in txRequest/);
120
+ });
121
+ it('throws when transactions array has more than one element', function () {
122
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequest({
123
+ transactions: [
124
+ buildTransaction({
125
+ unsignedTx: buildUnsignedTransaction({ signableHex: 'aaa', derivationPath: 'm/0' }),
126
+ }),
127
+ buildTransaction({
128
+ unsignedTx: buildUnsignedTransaction({ signableHex: 'bbb', derivationPath: 'm/1' }),
129
+ }),
130
+ ],
131
+ })), /createOfflineShare requires exactly one transaction in txRequest/);
132
+ });
133
+ it('throws when unsignedTx is missing', function () {
134
+ // @ts-expect-error Intentionally malformed to exercise the runtime guard.
135
+ const noUnsignedTx = { state: 'pendingSignature', signatureShares: [] };
136
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequest({ transactions: [noUnsignedTx] })), /Missing unsignedTx in transactions/);
137
+ });
138
+ it('throws when signableHex is missing', function () {
139
+ // @ts-expect-error Intentionally malformed to exercise the runtime guard.
140
+ const noSignableHex = { serializedTxHex: 'aabbccdd', derivationPath: 'm/0' };
141
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequest({ transactions: [buildTransaction({ unsignedTx: noSignableHex })] })), /Missing signableHex in unsignedTx/);
142
+ });
143
+ it('throws when derivationPath is missing', function () {
144
+ // @ts-expect-error Intentionally malformed to exercise the runtime guard.
145
+ const noDerivationPath = { serializedTxHex: 'aabbccdd', signableHex: 'deadbeef' };
146
+ assert.throws(() => baseTssUtils.getSignableHexAndDerivationPathForTest(buildTxRequest({ transactions: [buildTransaction({ unsignedTx: noDerivationPath })] })), /Missing derivationPath in unsignedTx/);
147
+ });
148
+ });
149
+ describe('validateAdata', function () {
150
+ it('passes when adata matches with domain separator', function () {
151
+ const adata = 'test-value';
152
+ const cyphertext = mockBitgo.encrypt({
153
+ input: 'secret',
154
+ password: walletPassphrase,
155
+ adata: `${roundOneDomainSeparator}:${adata}`,
156
+ });
157
+ assert.doesNotThrow(() => baseTssUtils.validateAdataForTest(adata, cyphertext, roundOneDomainSeparator));
158
+ });
159
+ it('passes when adata matches without domain separator', function () {
160
+ const adata = 'test-value';
161
+ const cyphertext = mockBitgo.encrypt({ input: 'secret', password: walletPassphrase, adata });
162
+ assert.doesNotThrow(() => baseTssUtils.validateAdataForTest(adata, cyphertext, roundOneDomainSeparator));
163
+ });
164
+ it('throws when adata does not match', function () {
165
+ const cyphertext = mockBitgo.encrypt({
166
+ input: 'secret',
167
+ password: walletPassphrase,
168
+ adata: `${roundOneDomainSeparator}:correct`,
169
+ });
170
+ assert.throws(() => baseTssUtils.validateAdataForTest('wrong', cyphertext, roundOneDomainSeparator), /Adata does not match cyphertext adata/);
171
+ });
172
+ it('throws when cyphertext is not valid JSON', function () {
173
+ assert.throws(() => baseTssUtils.validateAdataForTest('adata', 'not-json', roundOneDomainSeparator), /Failed to parse cyphertext to JSON/);
174
+ });
175
+ });
176
+ describe('getBitgoAndUserGpgKeys', function () {
177
+ it('decrypts v1 SJCL envelope without adata and skips validation', async function () {
178
+ const encryptedUserGpgPrvKey = mockBitgo.encrypt({
179
+ input: userGpgKeyPair.privateKey,
180
+ password: walletPassphrase,
181
+ });
182
+ const result = await baseTssUtils.getBitgoAndUserGpgKeysForTest(bitgoGpgKeyPair.publicKey, encryptedUserGpgPrvKey, walletPassphrase, '', signingUserGpgKeyDomainSeparator);
183
+ assert.ok(result.bitgoGpgKey);
184
+ assert.equal(result.userGpgPrvKey.isPrivate(), true);
185
+ });
186
+ it('decrypts v1 SJCL envelope with matching adata', async function () {
187
+ const adata = 'test-adata';
188
+ const encryptedUserGpgPrvKey = mockBitgo.encrypt({
189
+ input: userGpgKeyPair.privateKey,
190
+ password: walletPassphrase,
191
+ adata: `${signingUserGpgKeyDomainSeparator}:${adata}`,
192
+ });
193
+ const result = await baseTssUtils.getBitgoAndUserGpgKeysForTest(bitgoGpgKeyPair.publicKey, encryptedUserGpgPrvKey, walletPassphrase, adata, signingUserGpgKeyDomainSeparator);
194
+ assert.ok(result.bitgoGpgKey);
195
+ assert.equal(result.userGpgPrvKey.isPrivate(), true);
196
+ });
197
+ it('decrypts v2 envelope and returns GPG keys', async function () {
198
+ const adata = 'test-adata';
199
+ // Fake v2 envelope: JSON with v:2 triggers isV2Envelope; decryptAsync stub returns plaintext directly.
200
+ const encryptedUserGpgPrvKey = JSON.stringify({
201
+ v: 2,
202
+ adata: `${signingUserGpgKeyDomainSeparator}:${adata}`,
203
+ plaintext: userGpgKeyPair.privateKey,
204
+ });
205
+ const result = await baseTssUtils.getBitgoAndUserGpgKeysForTest(bitgoGpgKeyPair.publicKey, encryptedUserGpgPrvKey, walletPassphrase, adata, signingUserGpgKeyDomainSeparator);
206
+ sinon.assert.calledOnce(decryptAsyncStub);
207
+ assert.ok(result.bitgoGpgKey);
208
+ assert.equal(result.userGpgPrvKey.isPrivate(), true);
209
+ });
210
+ it('throws when adata does not match', async function () {
211
+ const encryptedUserGpgPrvKey = mockBitgo.encrypt({
212
+ input: userGpgKeyPair.privateKey,
213
+ password: walletPassphrase,
214
+ adata: `${signingUserGpgKeyDomainSeparator}:correct-adata`,
215
+ });
216
+ await assert.rejects(baseTssUtils.getBitgoAndUserGpgKeysForTest(bitgoGpgKeyPair.publicKey, encryptedUserGpgPrvKey, walletPassphrase, 'wrong-adata', signingUserGpgKeyDomainSeparator), /Adata does not match cyphertext adata/);
217
+ });
218
+ it('throws when cyphertext is not valid JSON', async function () {
219
+ await assert.rejects(baseTssUtils.getBitgoAndUserGpgKeysForTest(bitgoGpgKeyPair.publicKey, 'not-valid-json', walletPassphrase, 'test-adata', signingUserGpgKeyDomainSeparator), /json decode|Failed to parse cyphertext to JSON/);
220
+ });
221
+ });
222
+ describe('ECDSA MPC v2 delegated txRequest parsing', function () {
223
+ it('getHashStringAndDerivationPath produces the correct hashBuffer and derivationPath', async function () {
224
+ const signableHex = 'deadbeef';
225
+ const derivationPath = 'm/0';
226
+ const txRequest = buildTxRequest({
227
+ transactions: [buildTransaction({ unsignedTx: buildUnsignedTransaction({ signableHex, derivationPath }) })],
228
+ });
229
+ const expectedHashBuffer = (0, keccak_1.default)('keccak256').update(Buffer.from(signableHex, 'hex')).digest();
230
+ const { encryptedRound1Session } = await ecdsaMPCv2Utils.createOfflineRound1Share({
231
+ txRequest,
232
+ prv: userShare.toString('base64'),
233
+ walletPassphrase,
234
+ });
235
+ // The round-1 session is encrypted with adata = "DKLS23_SIGNING_ROUND1_STATE:<hash>:<derivationPath>",
236
+ // which proves getHashStringAndDerivationPath produced the right values after the delegation refactor.
237
+ const { adata } = JSON.parse(encryptedRound1Session);
238
+ assert.equal(adata === undefined ? adata : decodeURIComponent(adata), `DKLS23_SIGNING_ROUND1_STATE:${expectedHashBuffer.toString('hex')}:${derivationPath}`);
239
+ });
240
+ it('propagates the base unsignedTx guard through the ECDSA route', async function () {
241
+ // @ts-expect-error Intentionally malformed to exercise the runtime guard.
242
+ const noUnsignedTx = { state: 'pendingSignature', signatureShares: [] };
243
+ await assert.rejects(ecdsaMPCv2Utils.createOfflineRound1Share({
244
+ txRequest: buildTxRequest({ transactions: [noUnsignedTx] }),
245
+ prv: 'unused',
246
+ walletPassphrase,
247
+ }), /Missing unsignedTx in transactions/);
248
+ });
249
+ });
250
+ });
251
+ // ---------------------------------------------------------------------------
252
+ // Fixture builders
253
+ // ---------------------------------------------------------------------------
254
+ function buildTxRequest(overrides = {}) {
255
+ return {
256
+ txRequestId: 'tx-request-id',
257
+ walletId: 'wallet-id',
258
+ walletType: 'hot',
259
+ version: 1,
260
+ state: 'initialized',
261
+ date: new Date(0).toISOString(),
262
+ userId: 'user-id',
263
+ intent: {},
264
+ policiesChecked: true,
265
+ unsignedTxs: [],
266
+ transactions: [buildTransaction()],
267
+ latest: true,
268
+ ...overrides,
269
+ };
270
+ }
271
+ function buildTxRequestWithoutTransactions() {
272
+ const txRequest = buildTxRequest();
273
+ delete txRequest.transactions;
274
+ return txRequest;
275
+ }
276
+ function buildTransaction(overrides = {}) {
277
+ return { state: 'pendingSignature', unsignedTx: buildUnsignedTransaction(), signatureShares: [], ...overrides };
278
+ }
279
+ function buildUnsignedTransaction(overrides = {}) {
280
+ return { serializedTxHex: 'aabbccdd', signableHex: 'deadbeef', derivationPath: 'm/0', ...overrides };
281
+ }
282
+ // ---------------------------------------------------------------------------
283
+ // Encryption helpers (mirrors the ecdsaMPCv2 test pattern)
284
+ // ---------------------------------------------------------------------------
285
+ function encryptWithSjcl(password, input, adata) {
286
+ const salt = (0, crypto_1.randomBytes)(8);
287
+ const iv = (0, crypto_1.randomBytes)(16);
288
+ return sjcl.encrypt(password, input, {
289
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
290
+ iv: [
291
+ bytesToWord(iv.subarray(0, 4)),
292
+ bytesToWord(iv.subarray(4, 8)),
293
+ bytesToWord(iv.subarray(8, 12)),
294
+ bytesToWord(iv.subarray(12, 16)),
295
+ ],
296
+ ...(adata !== undefined ? { adata } : {}),
297
+ });
298
+ }
299
+ function bytesToWord(bytes) {
300
+ if (bytes.length !== 4) {
301
+ throw new Error('bytes must have length 4');
302
+ }
303
+ return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
304
+ }
305
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZVRTU1V0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvL3V0aWxzL3Rzcy9iYXNlVFNTVXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsbUNBQTJDO0FBQzNDLG9EQUFzQztBQUN0QyxpREFBbUM7QUFDbkMsNkNBQStCO0FBQy9CLHVEQUF5QztBQUN6Qyx5REFBb0Q7QUFFcEQsNENBQXNGO0FBQ3RGLG1HQUEyRTtBQVkzRSxNQUFNLGdCQUFpQixTQUFRLHNCQUFvQjtJQUNqRCxzQ0FBc0MsQ0FDcEMsU0FBb0IsRUFDcEIsMEJBQW1DO1FBRW5DLE9BQU8sSUFBSSxDQUFDLCtCQUErQixDQUFDLFNBQVMsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxLQUFhLEVBQUUsVUFBa0IsRUFBRSxvQkFBNEI7UUFDbEYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELDZCQUE2QixDQUMzQixpQkFBeUIsRUFDekIsc0JBQThCLEVBQzlCLGdCQUF3QixFQUN4QixLQUFhLEVBQ2IseUJBQWlDO1FBRWpDLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUNoQyxpQkFBaUIsRUFDakIsc0JBQXNCLEVBQ3RCLGdCQUFnQixFQUNoQixLQUFLLEVBQ0wseUJBQXlCLENBQzFCLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUFFRCxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7SUFDekIsTUFBTSxnQkFBZ0IsR0FBRyxlQUFlLENBQUM7SUFDekMsTUFBTSxnQ0FBZ0MsR0FBRyw4QkFBOEIsQ0FBQztJQUN4RSxNQUFNLHVCQUF1QixHQUFHLDhCQUE4QixDQUFDO0lBRS9ELElBQUksWUFBOEIs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QUFFLENBQUMsR0FBRyxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IGNyZWF0ZUtlY2Nha0hhc2ggZnJvbSAna2VjY2FrJztcbmltcG9ydCAqIGFzIG9wZW5wZ3AgZnJvbSAnb3BlbnBncCc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgKiBhcyBzamNsIGZyb20gJ0BiaXRnby1iZXRhL3NqY2wnO1xuaW1wb3J0IHsgRGtsc1V0aWxzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuXG5pbXBvcnQgeyBCaXRHb0Jhc2UsIEVjZHNhTVBDdjJVdGlscywgSUJhc2VDb2luLCBUeFJlcXVlc3QgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9zcmMnO1xuaW1wb3J0IEJhc2VUc3NVdGlscyBmcm9tICcuLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2Jhc2VUU1NVdGlscyc7XG5cbnR5cGUgQml0Z29HcGdLZXlQYWlyID0gb3BlbnBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+ICYgeyByZXZvY2F0aW9uQ2VydGlmaWNhdGU6IHN0cmluZyB9O1xudHlwZSBUeFJlcXVlc3RUcmFuc2FjdGlvbiA9IE5vbk51bGxhYmxlPFR4UmVxdWVzdFsndHJhbnNhY3Rpb25zJ10+W251bWJlcl07XG50eXBlIFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBUeFJlcXVlc3RUcmFuc2FjdGlvblsndW5zaWduZWRUeCddO1xudHlwZSBTaWduYWJsZUhleEFuZERlcml2YXRpb25QYXRoID0ge1xuICBzaWduYWJsZUhleDogc3RyaW5nO1xuICBkZXJpdmF0aW9uUGF0aDogc3RyaW5nO1xuICBzZXJpYWxpemVkVHhIZXg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn07XG50eXBlIERlY3J5cHRlZEdwZ0tleXMgPSB7IGJpdGdvR3BnS2V5OiBvcGVucGdwLktleTsgdXNlckdwZ1BydktleTogb3BlbnBncC5Qcml2YXRlS2V5IH07XG5cbmNsYXNzIFRlc3RCYXNlVHNzVXRpbHMgZXh0ZW5kcyBCYXNlVHNzVXRpbHM8QnVmZmVyPiB7XG4gIGdldFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGhGb3JUZXN0KFxuICAgIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICAgIG1pc3NpbmdUcmFuc2FjdGlvbnNNZXNzYWdlPzogc3RyaW5nXG4gICk6IFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGgge1xuICAgIHJldHVybiB0aGlzLmdldFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGgodHhSZXF1ZXN0LCBtaXNzaW5nVHJhbnNhY3Rpb25zTWVzc2FnZSk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXRhRm9yVGVzdChhZGF0YTogc3RyaW5nLCBjeXBoZXJ0ZXh0OiBzdHJpbmcsIHJvdW5kRG9tYWluU2VwYXJhdG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlQWRhdGEoYWRhdGEsIGN5cGhlcnRleHQsIHJvdW5kRG9tYWluU2VwYXJhdG9yKTtcbiAgfVxuXG4gIGdldEJpdGdvQW5kVXNlckdwZ0tleXNGb3JUZXN0KFxuICAgIGJpdGdvUHVibGljR3BnS2V5OiBzdHJpbmcsXG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nLFxuICAgIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZyxcbiAgICBhZGF0YTogc3RyaW5nLFxuICAgIHVzZXJHcGdLZXlEb21haW5TZXBhcmF0b3I6IHN0cmluZ1xuICApOiBQcm9taXNlPERlY3J5cHRlZEdwZ0tleXM+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRCaXRnb0FuZFVzZXJHcGdLZXlzKFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGFkYXRhLFxuICAgICAgdXNlckdwZ0tleURvbWFpblNlcGFyYXRvclxuICAgICk7XG4gIH1cbn1cblxuZGVzY3JpYmUoJ0Jhc2UgVFNTIFV0aWxzJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3QtcGFzc3dvcmQnO1xuICBjb25zdCBzaWduaW5nVXNlckdwZ0tleURvbWFpblNlcGFyYXRvciA9ICdNUFNfRFNHX1NJR05JTkdfVVNFUl9HUEdfS0VZJztcbiAgY29uc3Qgcm91bmRPbmVEb21haW5TZXBhcmF0b3IgPSAnTVBTX0RTR19TSUdOSU5HX1JPVU5EMV9TVEFURSc7XG5cbiAgbGV0IGJhc2VUc3NVdGlsczogVGVzdEJhc2VUc3NVdGlscztcbiAgbGV0IGVjZHNhTVBDdjJVdGlsczogRWNkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCBkZWNyeXB0QXN5bmNTdHViOiBzaW5vbi5TaW5vblN0dWI7XG4gIGxldCBiaXRnb0dwZ0tleVBhaXI6IEJpdGdvR3BnS2V5UGFpcjtcbiAgbGV0IHVzZXJHcGdLZXlQYWlyOiBCaXRnb0dwZ0tleVBhaXI7XG4gIGxldCB1c2VyU2hhcmU6IEJ1ZmZlcjtcblxuICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG9wZW5wZ3AuY29uZmlnLnJlamVjdEN1cnZlcyA9IG5ldyBTZXQoKTtcbiAgICBiaXRnb0dwZ0tleVBhaXIgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgIHVzZXJJRHM6IFt7IG5hbWU6ICdiaXRnbycsIGVtYWlsOiAnYml0Z29AdGVzdC5jb20nIH1dLFxuICAgICAgY3VydmU6ICdlZDI1NTE5JyxcbiAgICAgIGZvcm1hdDogJ2FybW9yZWQnLFxuICAgIH0pO1xuICAgIHVzZXJHcGdLZXlQYWlyID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbeyBuYW1lOiAndXNlcicsIGVtYWlsOiAndXNlckB0ZXN0LmNvbScgfV0sXG4gICAgICBjdXJ2ZTogJ2VkMjU1MTknLFxuICAgICAgZm9ybWF0OiAnYXJtb3JlZCcsXG4gICAgfSk7XG5cbiAgICBjb25zdCBbdXNlckRrZ1Nlc3Npb25dID0gYXdhaXQgRGtsc1V0aWxzLmdlbmVyYXRlREtHS2V5U2hhcmVzKCk7XG4gICAgdXNlclNoYXJlID0gdXNlckRrZ1Nlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgfSk7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgZGVjcnlwdEFzeW5jU3R1YiA9IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHsgaW5wdXQgfTogUGFyYW1ldGVyczxCaXRHb0Jhc2VbJ2RlY3J5cHRBc3luYyddPlswXSkgPT5cbiAgICAgIC8vIEZha2UgdjIgZW52ZWxvcGU6IHJlc29sdmUgdGhlIHBsYWludGV4dCBlbWJlZGRlZCBpbiB0aGUgSlNPTi5cbiAgICAgIFByb21pc2UucmVzb2x2ZSgoSlNPTi5wYXJzZShpbnB1dCkgYXMgeyBwbGFpbnRleHQ6IHN0cmluZyB9KS5wbGFpbnRleHQpXG4gICAgKTtcblxuICAgIGNvbnN0IG1vY2tCZyA9IHt9IGFzIEJpdEdvQmFzZTtcbiAgICBtb2NrQmcuZ2V0RW52ID0gc2lub24uc3R1YigpLnJldHVybnMoJ3Rlc3QnKTtcbiAgICBtb2NrQmcuZW5jcnlwdCA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAuY2FsbHNGYWtlKChwYXJhbXMpID0+IGVuY3J5cHRXaXRoU2pjbChwYXJhbXMucGFzc3dvcmQgPz8gJycsIHBhcmFtcy5pbnB1dCwgcGFyYW1zLmFkYXRhKSk7XG4gICAgbW9ja0JnLmRlY3J5cHQgPSBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChwYXJhbXMpID0+IHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQgPz8gJycsIHBhcmFtcy5pbnB1dCkpO1xuICAgIG1vY2tCZy5kZWNyeXB0QXN5bmMgPSBkZWNyeXB0QXN5bmNTdHViO1xuICAgIG1vY2tCaXRnbyA9IG1vY2tCZztcblxuICAgIGNvbnN0IG1vY2tDb2luID0ge30gYXMgSUJhc2VDb2luO1xuICAgIG1vY2tDb2luLmdldEhhc2hGdW5jdGlvbiA9IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKCkgPT4gY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykgYXMgSGFzaCk7XG5cbiAgICBiYXNlVHNzVXRpbHMgPSBuZXcgVGVzdEJhc2VUc3NVdGlscyhtb2NrQml0Z28sIG1vY2tDb2luKTtcbiAgICBlY2RzYU1QQ3YyVXRpbHMgPSBuZXcgRWNkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0U2lnbmFibGVIZXhBbmREZXJpdmF0aW9uUGF0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnZXh0cmFjdHMgc2lnbmFibGVIZXggYW5kIGRlcml2YXRpb25QYXRoIGZyb20gYSB2YWxpZCB0eFJlcXVlc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFJlcXVlc3QgPSBidWlsZFR4UmVxdWVzdCh7XG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIGJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdW5zaWduZWRUeDogYnVpbGRVbnNpZ25lZFRyYW5zYWN0aW9uKHsgc2lnbmFibGVIZXg6ICdkZWFkYmVlZicsIGRlcml2YXRpb25QYXRoOiAnbS8wLzAnIH0pLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGJhc2VUc3NVdGlscy5nZXRTaWduYWJsZUhleEFuZERlcml2YXRpb25QYXRoRm9yVGVzdCh0eFJlcXVlc3QpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHJlc3VsdC5zaWduYWJsZUhleCwgJ2RlYWRiZWVmJyk7XG4gICAgICBhc3NlcnQuZXF1YWwocmVzdWx0LmRlcml2YXRpb25QYXRoLCAnbS8wLzAnKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiB0cmFuc2FjdGlvbnMgZmllbGQgaXMgbWlzc2luZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IGJhc2VUc3NVdGlscy5nZXRTaWduYWJsZUhleEFuZERlcml2YXRpb25QYXRoRm9yVGVzdChidWlsZFR4UmVxdWVzdFdpdGhvdXRUcmFuc2FjdGlvbnMoKSksXG4gICAgICAgIC9jcmVhdGVPZmZsaW5lU2hhcmUgcmVxdWlyZXMgZXhhY3RseSBvbmUgdHJhbnNhY3Rpb24gaW4gdHhSZXF1ZXN0L1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiB0cmFuc2FjdGlvbnMgYXJyYXkgaXMgZW1wdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBiYXNlVHNzVXRpbHMuZ2V0U2lnbmFibGVIZXhBbmREZXJpdmF0aW9uUGF0aEZvclRlc3QoYnVpbGRUeFJlcXVlc3QoeyB0cmFuc2FjdGlvbnM6IFtdIH0pKSxcbiAgICAgICAgL2NyZWF0ZU9mZmxpbmVTaGFyZSByZXF1aXJlcyBleGFjdGx5IG9uZSB0cmFuc2FjdGlvbiBpbiB0eFJlcXVlc3QvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHRyYW5zYWN0aW9ucyBhcnJheSBoYXMgbW9yZSB0aGFuIG9uZSBlbGVtZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBiYXNlVHNzVXRpbHMuZ2V0U2lnbmFibGVIZXhBbmREZXJpdmF0aW9uUGF0aEZvclRlc3QoXG4gICAgICAgICAgICBidWlsZFR4UmVxdWVzdCh7XG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAgICAgIGJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgICAgICAgdW5zaWduZWRUeDogYnVpbGRVbnNpZ25lZFRyYW5zYWN0aW9uKHsgc2lnbmFibGVIZXg6ICdhYWEnLCBkZXJpdmF0aW9uUGF0aDogJ20vMCcgfSksXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICAgICAgICB1bnNpZ25lZFR4OiBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24oeyBzaWduYWJsZUhleDogJ2JiYicsIGRlcml2YXRpb25QYXRoOiAnbS8xJyB9KSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKSxcbiAgICAgICAgL2NyZWF0ZU9mZmxpbmVTaGFyZSByZXF1aXJlcyBleGFjdGx5IG9uZSB0cmFuc2FjdGlvbiBpbiB0eFJlcXVlc3QvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHVuc2lnbmVkVHggaXMgbWlzc2luZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgSW50ZW50aW9uYWxseSBtYWxmb3JtZWQgdG8gZXhlcmNpc2UgdGhlIHJ1bnRpbWUgZ3VhcmQuXG4gICAgICBjb25zdCBub1Vuc2lnbmVkVHg6IFR4UmVxdWVzdFRyYW5zYWN0aW9uID0geyBzdGF0ZTogJ3BlbmRpbmdTaWduYXR1cmUnLCBzaWduYXR1cmVTaGFyZXM6IFtdIH07XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBiYXNlVHNzVXRpbHMuZ2V0U2lnbmFibGVIZXhBbmREZXJpdmF0aW9uUGF0aEZvclRlc3QoYnVpbGRUeFJlcXVlc3QoeyB0cmFuc2FjdGlvbnM6IFtub1Vuc2lnbmVkVHhdIH0pKSxcbiAgICAgICAgL01pc3NpbmcgdW5zaWduZWRUeCBpbiB0cmFuc2FjdGlvbnMvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHNpZ25hYmxlSGV4IGlzIG1pc3NpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIEludGVudGlvbmFsbHkgbWFsZm9ybWVkIHRvIGV4ZXJjaXNlIHRoZSBydW50aW1lIGd1YXJkLlxuICAgICAgY29uc3Qgbm9TaWduYWJsZUhleDogVW5zaWduZWRUcmFuc2FjdGlvbiA9IHsgc2VyaWFsaXplZFR4SGV4OiAnYWFiYmNjZGQnLCBkZXJpdmF0aW9uUGF0aDogJ20vMCcgfTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+XG4gICAgICAgICAgYmFzZVRzc1V0aWxzLmdldFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGhGb3JUZXN0KFxuICAgICAgICAgICAgYnVpbGRUeFJlcXVlc3QoeyB0cmFuc2FjdGlvbnM6IFtidWlsZFRyYW5zYWN0aW9uKHsgdW5zaWduZWRUeDogbm9TaWduYWJsZUhleCB9KV0gfSlcbiAgICAgICAgICApLFxuICAgICAgICAvTWlzc2luZyBzaWduYWJsZUhleCBpbiB1bnNpZ25lZFR4L1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiBkZXJpdmF0aW9uUGF0aCBpcyBtaXNzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBJbnRlbnRpb25hbGx5IG1hbGZvcm1lZCB0byBleGVyY2lzZSB0aGUgcnVudGltZSBndWFyZC5cbiAgICAgIGNvbnN0IG5vRGVyaXZhdGlvblBhdGg6IFVuc2lnbmVkVHJhbnNhY3Rpb24gPSB7IHNlcmlhbGl6ZWRUeEhleDogJ2FhYmJjY2RkJywgc2lnbmFibGVIZXg6ICdkZWFkYmVlZicgfTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+XG4gICAgICAgICAgYmFzZVRzc1V0aWxzLmdldFNpZ25hYmxlSGV4QW5kRGVyaXZhdGlvblBhdGhGb3JUZXN0KFxuICAgICAgICAgICAgYnVpbGRUeFJlcXVlc3QoeyB0cmFuc2FjdGlvbnM6IFtidWlsZFRyYW5zYWN0aW9uKHsgdW5zaWduZWRUeDogbm9EZXJpdmF0aW9uUGF0aCB9KV0gfSlcbiAgICAgICAgICApLFxuICAgICAgICAvTWlzc2luZyBkZXJpdmF0aW9uUGF0aCBpbiB1bnNpZ25lZFR4L1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbGlkYXRlQWRhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Bhc3NlcyB3aGVuIGFkYXRhIG1hdGNoZXMgd2l0aCBkb21haW4gc2VwYXJhdG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRhdGEgPSAndGVzdC12YWx1ZSc7XG4gICAgICBjb25zdCBjeXBoZXJ0ZXh0ID0gbW9ja0JpdGdvLmVuY3J5cHQoe1xuICAgICAgICBpbnB1dDogJ3NlY3JldCcsXG4gICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBhZGF0YTogYCR7cm91bmRPbmVEb21haW5TZXBhcmF0b3J9OiR7YWRhdGF9YCxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiBiYXNlVHNzVXRpbHMudmFsaWRhdGVBZGF0YUZvclRlc3QoYWRhdGEsIGN5cGhlcnRleHQsIHJvdW5kT25lRG9tYWluU2VwYXJhdG9yKSk7XG4gICAgfSk7XG5cbiAgICBpdCgncGFzc2VzIHdoZW4gYWRhdGEgbWF0Y2hlcyB3aXRob3V0IGRvbWFpbiBzZXBhcmF0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGF0YSA9ICd0ZXN0LXZhbHVlJztcbiAgICAgIGNvbnN0IGN5cGhlcnRleHQgPSBtb2NrQml0Z28uZW5jcnlwdCh7IGlucHV0OiAnc2VjcmV0JywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsIGFkYXRhIH0pO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiBiYXNlVHNzVXRpbHMudmFsaWRhdGVBZGF0YUZvclRlc3QoYWRhdGEsIGN5cGhlcnRleHQsIHJvdW5kT25lRG9tYWluU2VwYXJhdG9yKSk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIHdoZW4gYWRhdGEgZG9lcyBub3QgbWF0Y2gnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjeXBoZXJ0ZXh0ID0gbW9ja0JpdGdvLmVuY3J5cHQoe1xuICAgICAgICBpbnB1dDogJ3NlY3JldCcsXG4gICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBhZGF0YTogYCR7cm91bmRPbmVEb21haW5TZXBhcmF0b3J9OmNvcnJlY3RgLFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBiYXNlVHNzVXRpbHMudmFsaWRhdGVBZGF0YUZvclRlc3QoJ3dyb25nJywgY3lwaGVydGV4dCwgcm91bmRPbmVEb21haW5TZXBhcmF0b3IpLFxuICAgICAgICAvQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YS9cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIHdoZW4gY3lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IGJhc2VUc3NVdGlscy52YWxpZGF0ZUFkYXRhRm9yVGVzdCgnYWRhdGEnLCAnbm90LWpzb24nLCByb3VuZE9uZURvbWFpblNlcGFyYXRvciksXG4gICAgICAgIC9GYWlsZWQgdG8gcGFyc2UgY3lwaGVydGV4dCB0byBKU09OL1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEJpdGdvQW5kVXNlckdwZ0tleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2RlY3J5cHRzIHYxIFNKQ0wgZW52ZWxvcGUgd2l0aG91dCBhZGF0YSBhbmQgc2tpcHMgdmFsaWRhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBtb2NrQml0Z28uZW5jcnlwdCh7XG4gICAgICAgIGlucHV0OiB1c2VyR3BnS2V5UGFpci5wcml2YXRlS2V5LFxuICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlVHNzVXRpbHMuZ2V0Qml0Z29BbmRVc2VyR3BnS2V5c0ZvclRlc3QoXG4gICAgICAgIGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICcnLFxuICAgICAgICBzaWduaW5nVXNlckdwZ0tleURvbWFpblNlcGFyYXRvclxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5iaXRnb0dwZ0tleSk7XG4gICAgICBhc3NlcnQuZXF1YWwocmVzdWx0LnVzZXJHcGdQcnZLZXkuaXNQcml2YXRlKCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlY3J5cHRzIHYxIFNKQ0wgZW52ZWxvcGUgd2l0aCBtYXRjaGluZyBhZGF0YScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkYXRhID0gJ3Rlc3QtYWRhdGEnO1xuICAgICAgY29uc3QgZW5jcnlwdGVkVXNlckdwZ1BydktleSA9IG1vY2tCaXRnby5lbmNyeXB0KHtcbiAgICAgICAgaW5wdXQ6IHVzZXJHcGdLZXlQYWlyLnByaXZhdGVLZXksXG4gICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBhZGF0YTogYCR7c2lnbmluZ1VzZXJHcGdLZXlEb21haW5TZXBhcmF0b3J9OiR7YWRhdGF9YCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlVHNzVXRpbHMuZ2V0Qml0Z29BbmRVc2VyR3BnS2V5c0ZvclRlc3QoXG4gICAgICAgIGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGFkYXRhLFxuICAgICAgICBzaWduaW5nVXNlckdwZ0tleURvbWFpblNlcGFyYXRvclxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5iaXRnb0dwZ0tleSk7XG4gICAgICBhc3NlcnQuZXF1YWwocmVzdWx0LnVzZXJHcGdQcnZLZXkuaXNQcml2YXRlKCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlY3J5cHRzIHYyIGVudmVsb3BlIGFuZCByZXR1cm5zIEdQRyBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRhdGEgPSAndGVzdC1hZGF0YSc7XG4gICAgICAvLyBGYWtlIHYyIGVudmVsb3BlOiBKU09OIHdpdGggdjoyIHRyaWdnZXJzIGlzVjJFbnZlbG9wZTsgZGVjcnlwdEFzeW5jIHN0dWIgcmV0dXJucyBwbGFpbnRleHQgZGlyZWN0bHkuXG4gICAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB2OiAyLFxuICAgICAgICBhZGF0YTogYCR7c2lnbmluZ1VzZXJHcGdLZXlEb21haW5TZXBhcmF0b3J9OiR7YWRhdGF9YCxcbiAgICAgICAgcGxhaW50ZXh0OiB1c2VyR3BnS2V5UGFpci5wcml2YXRlS2V5LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2VUc3NVdGlscy5nZXRCaXRnb0FuZFVzZXJHcGdLZXlzRm9yVGVzdChcbiAgICAgICAgYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgYWRhdGEsXG4gICAgICAgIHNpZ25pbmdVc2VyR3BnS2V5RG9tYWluU2VwYXJhdG9yXG4gICAgICApO1xuXG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShkZWNyeXB0QXN5bmNTdHViKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuYml0Z29HcGdLZXkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHJlc3VsdC51c2VyR3BnUHJ2S2V5LmlzUHJpdmF0ZSgpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiBhZGF0YSBkb2VzIG5vdCBtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBtb2NrQml0Z28uZW5jcnlwdCh7XG4gICAgICAgIGlucHV0OiB1c2VyR3BnS2V5UGFpci5wcml2YXRlS2V5LFxuICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgYWRhdGE6IGAke3NpZ25pbmdVc2VyR3BnS2V5RG9tYWluU2VwYXJhdG9yfTpjb3JyZWN0LWFkYXRhYCxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYmFzZVRzc1V0aWxzLmdldEJpdGdvQW5kVXNlckdwZ0tleXNGb3JUZXN0KFxuICAgICAgICAgIGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICd3cm9uZy1hZGF0YScsXG4gICAgICAgICAgc2lnbmluZ1VzZXJHcGdLZXlEb21haW5TZXBhcmF0b3JcbiAgICAgICAgKSxcbiAgICAgICAgL0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIGN5cGhlcnRleHQgaXMgbm90IHZhbGlkIEpTT04nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYmFzZVRzc1V0aWxzLmdldEJpdGdvQW5kVXNlckdwZ0tleXNGb3JUZXN0KFxuICAgICAgICAgIGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgJ25vdC12YWxpZC1qc29uJyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICd0ZXN0LWFkYXRhJyxcbiAgICAgICAgICBzaWduaW5nVXNlckdwZ0tleURvbWFpblNlcGFyYXRvclxuICAgICAgICApLFxuICAgICAgICAvanNvbiBkZWNvZGV8RmFpbGVkIHRvIHBhcnNlIGN5cGhlcnRleHQgdG8gSlNPTi9cbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFQ0RTQSBNUEMgdjIgZGVsZWdhdGVkIHR4UmVxdWVzdCBwYXJzaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdnZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGggcHJvZHVjZXMgdGhlIGNvcnJlY3QgaGFzaEJ1ZmZlciBhbmQgZGVyaXZhdGlvblBhdGgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduYWJsZUhleCA9ICdkZWFkYmVlZic7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAnO1xuICAgICAgY29uc3QgdHhSZXF1ZXN0ID0gYnVpbGRUeFJlcXVlc3Qoe1xuICAgICAgICB0cmFuc2FjdGlvbnM6IFtidWlsZFRyYW5zYWN0aW9uKHsgdW5zaWduZWRUeDogYnVpbGRVbnNpZ25lZFRyYW5zYWN0aW9uKHsgc2lnbmFibGVIZXgsIGRlcml2YXRpb25QYXRoIH0pIH0pXSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZXhwZWN0ZWRIYXNoQnVmZmVyID0gY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4JykpLmRpZ2VzdCgpO1xuXG4gICAgICBjb25zdCB7IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gfSA9IGF3YWl0IGVjZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgIHBydjogdXNlclNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBUaGUgcm91bmQtMSBzZXNzaW9uIGlzIGVuY3J5cHRlZCB3aXRoIGFkYXRhID0gXCJES0xTMjNfU0lHTklOR19ST1VORDFfU1RBVEU6PGhhc2g+OjxkZXJpdmF0aW9uUGF0aD5cIixcbiAgICAgIC8vIHdoaWNoIHByb3ZlcyBnZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGggcHJvZHVjZWQgdGhlIHJpZ2h0IHZhbHVlcyBhZnRlciB0aGUgZGVsZWdhdGlvbiByZWZhY3Rvci5cbiAgICAgIGNvbnN0IHsgYWRhdGEgfSA9IEpTT04ucGFyc2UoZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikgYXMgeyBhZGF0YT86IHN0cmluZyB9O1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhZGF0YSA9PT0gdW5kZWZpbmVkID8gYWRhdGEgOiBkZWNvZGVVUklDb21wb25lbnQoYWRhdGEpLFxuICAgICAgICBgREtMUzIzX1NJR05JTkdfUk9VTkQxX1NUQVRFOiR7ZXhwZWN0ZWRIYXNoQnVmZmVyLnRvU3RyaW5nKCdoZXgnKX06JHtkZXJpdmF0aW9uUGF0aH1gXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Byb3BhZ2F0ZXMgdGhlIGJhc2UgdW5zaWduZWRUeCBndWFyZCB0aHJvdWdoIHRoZSBFQ0RTQSByb3V0ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgSW50ZW50aW9uYWxseSBtYWxmb3JtZWQgdG8gZXhlcmNpc2UgdGhlIHJ1bnRpbWUgZ3VhcmQuXG4gICAgICBjb25zdCBub1Vuc2lnbmVkVHg6IFR4UmVxdWVzdFRyYW5zYWN0aW9uID0geyBzdGF0ZTogJ3BlbmRpbmdTaWduYXR1cmUnLCBzaWduYXR1cmVTaGFyZXM6IFtdIH07XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgZWNkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiBidWlsZFR4UmVxdWVzdCh7IHRyYW5zYWN0aW9uczogW25vVW5zaWduZWRUeF0gfSksXG4gICAgICAgICAgcHJ2OiAndW51c2VkJyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KSxcbiAgICAgICAgL01pc3NpbmcgdW5zaWduZWRUeCBpbiB0cmFuc2FjdGlvbnMvXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEZpeHR1cmUgYnVpbGRlcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5mdW5jdGlvbiBidWlsZFR4UmVxdWVzdChvdmVycmlkZXM6IFBhcnRpYWw8VHhSZXF1ZXN0PiA9IHt9KTogVHhSZXF1ZXN0IHtcbiAgcmV0dXJuIHtcbiAgICB0eFJlcXVlc3RJZDogJ3R4LXJlcXVlc3QtaWQnLFxuICAgIHdhbGxldElkOiAnd2FsbGV0LWlkJyxcbiAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICB2ZXJzaW9uOiAxLFxuICAgIHN0YXRlOiAnaW5pdGlhbGl6ZWQnLFxuICAgIGRhdGU6IG5ldyBEYXRlKDApLnRvSVNPU3RyaW5nKCksXG4gICAgdXNlcklkOiAndXNlci1pZCcsXG4gICAgaW50ZW50OiB7fSxcbiAgICBwb2xpY2llc0NoZWNrZWQ6IHRydWUsXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICAgIHRyYW5zYWN0aW9uczogW2J1aWxkVHJhbnNhY3Rpb24oKV0sXG4gICAgbGF0ZXN0OiB0cnVlLFxuICAgIC4uLm92ZXJyaWRlcyxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGRUeFJlcXVlc3RXaXRob3V0VHJhbnNhY3Rpb25zKCk6IFR4UmVxdWVzdCB7XG4gIGNvbnN0IHR4UmVxdWVzdCA9IGJ1aWxkVHhSZXF1ZXN0KCk7XG4gIGRlbGV0ZSB0eFJlcXVlc3QudHJhbnNhY3Rpb25zO1xuICByZXR1cm4gdHhSZXF1ZXN0O1xufVxuXG5mdW5jdGlvbiBidWlsZFRyYW5zYWN0aW9uKG92ZXJyaWRlczogUGFydGlhbDxUeFJlcXVlc3RUcmFuc2FjdGlvbj4gPSB7fSk6IFR4UmVxdWVzdFRyYW5zYWN0aW9uIHtcbiAgcmV0dXJuIHsgc3RhdGU6ICdwZW5kaW5nU2lnbmF0dXJlJywgdW5zaWduZWRUeDogYnVpbGRVbnNpZ25lZFRyYW5zYWN0aW9uKCksIHNpZ25hdHVyZVNoYXJlczogW10sIC4uLm92ZXJyaWRlcyB9O1xufVxuXG5mdW5jdGlvbiBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24ob3ZlcnJpZGVzOiBQYXJ0aWFsPFVuc2lnbmVkVHJhbnNhY3Rpb24+ID0ge30pOiBVbnNpZ25lZFRyYW5zYWN0aW9uIHtcbiAgcmV0dXJuIHsgc2VyaWFsaXplZFR4SGV4OiAnYWFiYmNjZGQnLCBzaWduYWJsZUhleDogJ2RlYWRiZWVmJywgZGVyaXZhdGlvblBhdGg6ICdtLzAnLCAuLi5vdmVycmlkZXMgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBFbmNyeXB0aW9uIGhlbHBlcnMgKG1pcnJvcnMgdGhlIGVjZHNhTVBDdjIgdGVzdCBwYXR0ZXJuKVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIGVuY3J5cHRXaXRoU2pjbChwYXNzd29yZDogc3RyaW5nLCBpbnB1dDogc3RyaW5nLCBhZGF0YT86IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNhbHQgPSByYW5kb21CeXRlcyg4KTtcbiAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxNik7XG4gIHJldHVybiBzamNsLmVuY3J5cHQocGFzc3dvcmQsIGlucHV0LCB7XG4gICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgaXY6IFtcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDgsIDEyKSksXG4gICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICBdLFxuICAgIC4uLihhZGF0YSAhPT0gdW5kZWZpbmVkID8geyBhZGF0YSB9IDoge30pLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmQoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBudW1iZXIge1xuICBpZiAoYnl0ZXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdieXRlcyBtdXN0IGhhdmUgbGVuZ3RoIDQnKTtcbiAgfVxuICByZXR1cm4gYnl0ZXMucmVkdWNlKChudW0sIGJ5dGUpID0+IG51bSAqIDB4MTAwICsgYnl0ZSwgMCk7XG59XG4iXX0=