@bitgo-beta/sdk-coin-trx 1.2.3-alpha.397 → 1.2.3-alpha.399
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +7 -7
- package/dist/src/index.d.ts +0 -6
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -22
- package/dist/src/lib/address.d.ts +0 -11
- package/dist/src/lib/address.d.ts.map +0 -1
- package/dist/src/lib/address.js +0 -13
- package/dist/src/lib/builder.d.ts +0 -3
- package/dist/src/lib/builder.d.ts.map +0 -1
- package/dist/src/lib/builder.js +0 -10
- package/dist/src/lib/constants.d.ts +0 -3
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -6
- package/dist/src/lib/contractCallBuilder.d.ts +0 -62
- package/dist/src/lib/contractCallBuilder.d.ts.map +0 -1
- package/dist/src/lib/contractCallBuilder.js +0 -218
- package/dist/src/lib/delegateResourceTxBuilder.d.ts +0 -27
- package/dist/src/lib/delegateResourceTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/delegateResourceTxBuilder.js +0 -98
- package/dist/src/lib/enum.d.ts +0 -58
- package/dist/src/lib/enum.d.ts.map +0 -1
- package/dist/src/lib/enum.js +0 -64
- package/dist/src/lib/freezeBalanceTxBuilder.d.ts +0 -71
- package/dist/src/lib/freezeBalanceTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/freezeBalanceTxBuilder.js +0 -211
- package/dist/src/lib/iface.d.ts +0 -321
- package/dist/src/lib/iface.d.ts.map +0 -1
- package/dist/src/lib/iface.js +0 -3
- package/dist/src/lib/index.d.ts +0 -12
- package/dist/src/lib/index.d.ts.map +0 -1
- package/dist/src/lib/index.js +0 -53
- package/dist/src/lib/keyPair.d.ts +0 -43
- package/dist/src/lib/keyPair.d.ts.map +0 -1
- package/dist/src/lib/keyPair.js +0 -134
- package/dist/src/lib/resourceManagementTxBuilder.d.ts +0 -72
- package/dist/src/lib/resourceManagementTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/resourceManagementTxBuilder.js +0 -150
- package/dist/src/lib/tokenTransferBuilder.d.ts +0 -23
- package/dist/src/lib/tokenTransferBuilder.d.ts.map +0 -1
- package/dist/src/lib/tokenTransferBuilder.js +0 -42
- package/dist/src/lib/transaction.d.ts +0 -74
- package/dist/src/lib/transaction.d.ts.map +0 -1
- package/dist/src/lib/transaction.js +0 -312
- package/dist/src/lib/transactionBuilder.d.ts +0 -110
- package/dist/src/lib/transactionBuilder.d.ts.map +0 -1
- package/dist/src/lib/transactionBuilder.js +0 -304
- package/dist/src/lib/undelegateResourceTxBuilder.d.ts +0 -27
- package/dist/src/lib/undelegateResourceTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/undelegateResourceTxBuilder.js +0 -98
- package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts +0 -65
- package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/unfreezeBalanceTxBuilder.js +0 -204
- package/dist/src/lib/utils.d.ts +0 -197
- package/dist/src/lib/utils.d.ts.map +0 -1
- package/dist/src/lib/utils.js +0 -745
- package/dist/src/lib/voteWitnessTxBuilder.d.ts +0 -62
- package/dist/src/lib/voteWitnessTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/voteWitnessTxBuilder.js +0 -219
- package/dist/src/lib/withdrawBuilder.d.ts +0 -49
- package/dist/src/lib/withdrawBuilder.d.ts.map +0 -1
- package/dist/src/lib/withdrawBuilder.js +0 -167
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts +0 -49
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.js +0 -167
- package/dist/src/lib/wrappedBuilder.d.ts +0 -110
- package/dist/src/lib/wrappedBuilder.d.ts.map +0 -1
- package/dist/src/lib/wrappedBuilder.js +0 -192
- package/dist/src/register.d.ts +0 -3
- package/dist/src/register.d.ts.map +0 -1
- package/dist/src/register.js +0 -15
- package/dist/src/trx.d.ts +0 -262
- package/dist/src/trx.d.ts.map +0 -1
- package/dist/src/trx.js +0 -737
- package/dist/src/trxToken.d.ts +0 -38
- package/dist/src/trxToken.d.ts.map +0 -1
- package/dist/src/trxToken.js +0 -91
- package/dist/src/ttrx.d.ts +0 -13
- package/dist/src/ttrx.d.ts.map +0 -1
- package/dist/src/ttrx.js +0 -14
package/dist/src/lib/utils.js
DELETED
|
@@ -1,745 +0,0 @@
|
|
|
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
|
-
exports.VALID_RESOURCE_TYPES = exports.tokenTestnetContractAddresses = exports.tokenMainnetContractAddresses = exports.TRANSACTION_DEFAULT_EXPIRATION = exports.TRANSACTION_MAX_EXPIRATION = void 0;
|
|
40
|
-
exports.isBase58Address = isBase58Address;
|
|
41
|
-
exports.getByteArrayFromHexAddress = getByteArrayFromHexAddress;
|
|
42
|
-
exports.getHexAddressFromByteArray = getHexAddressFromByteArray;
|
|
43
|
-
exports.verifySignature = verifySignature;
|
|
44
|
-
exports.getHexAddressFromBase58Address = getHexAddressFromBase58Address;
|
|
45
|
-
exports.getPubKeyFromPriKey = getPubKeyFromPriKey;
|
|
46
|
-
exports.getAddressFromPriKey = getAddressFromPriKey;
|
|
47
|
-
exports.getBase58AddressFromByteArray = getBase58AddressFromByteArray;
|
|
48
|
-
exports.getBase58AddressFromHex = getBase58AddressFromHex;
|
|
49
|
-
exports.signTransaction = signTransaction;
|
|
50
|
-
exports.signString = signString;
|
|
51
|
-
exports.getRawAddressFromPubKey = getRawAddressFromPubKey;
|
|
52
|
-
exports.decodeTransaction = decodeTransaction;
|
|
53
|
-
exports.decodeRawTransaction = decodeRawTransaction;
|
|
54
|
-
exports.isValidHex = isValidHex;
|
|
55
|
-
exports.decodeTransferContract = decodeTransferContract;
|
|
56
|
-
exports.decodeTriggerSmartContract = decodeTriggerSmartContract;
|
|
57
|
-
exports.decodeAccountPermissionUpdateContract = decodeAccountPermissionUpdateContract;
|
|
58
|
-
exports.decodeFreezeBalanceV2Contract = decodeFreezeBalanceV2Contract;
|
|
59
|
-
exports.decodeVoteWitnessContract = decodeVoteWitnessContract;
|
|
60
|
-
exports.decodeUnfreezeBalanceV2Contract = decodeUnfreezeBalanceV2Contract;
|
|
61
|
-
exports.decodeWithdrawBalanceContract = decodeWithdrawBalanceContract;
|
|
62
|
-
exports.decodeWithdrawExpireUnfreezeContract = decodeWithdrawExpireUnfreezeContract;
|
|
63
|
-
exports.decodeDelegateResourceContract = decodeDelegateResourceContract;
|
|
64
|
-
exports.decodeUnDelegateResourceContract = decodeUnDelegateResourceContract;
|
|
65
|
-
exports.isValidTxJsonString = isValidTxJsonString;
|
|
66
|
-
exports.isValidRawTransactionFormat = isValidRawTransactionFormat;
|
|
67
|
-
exports.toHex = toHex;
|
|
68
|
-
exports.encodeDataParams = encodeDataParams;
|
|
69
|
-
exports.decodeDataParams = decodeDataParams;
|
|
70
|
-
const assert_1 = __importDefault(require("assert"));
|
|
71
|
-
const hex = __importStar(require("@stablelib/hex"));
|
|
72
|
-
const tronweb = __importStar(require("tronweb"));
|
|
73
|
-
const tron_1 = require("../../resources/protobuf/tron");
|
|
74
|
-
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
75
|
-
const statics_1 = require("@bitgo-beta/statics");
|
|
76
|
-
const enum_1 = require("./enum");
|
|
77
|
-
const utils_1 = require("ethers/lib/utils");
|
|
78
|
-
const constants_1 = require("./constants");
|
|
79
|
-
exports.TRANSACTION_MAX_EXPIRATION = 86400000; // one day
|
|
80
|
-
exports.TRANSACTION_DEFAULT_EXPIRATION = 3600000; // one hour
|
|
81
|
-
const ADDRESS_PREFIX_REGEX = /^(41)/;
|
|
82
|
-
const ADDRESS_PREFIX = '41';
|
|
83
|
-
const getTronTokens = (network = 'mainnet') => {
|
|
84
|
-
return statics_1.coins
|
|
85
|
-
.filter((coin) => coin.family === 'trx')
|
|
86
|
-
.filter((trx) => trx.network.type === network && trx.isToken).map((coins) => coins.contractAddress.toString());
|
|
87
|
-
};
|
|
88
|
-
exports.tokenMainnetContractAddresses = getTronTokens('mainnet');
|
|
89
|
-
exports.tokenTestnetContractAddresses = getTronTokens('testnet');
|
|
90
|
-
exports.VALID_RESOURCE_TYPES = ['ENERGY', 'BANDWIDTH'];
|
|
91
|
-
/**
|
|
92
|
-
* @param address
|
|
93
|
-
*/
|
|
94
|
-
function isBase58Address(address) {
|
|
95
|
-
return tronweb.utils.crypto.isAddressValid(address);
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* @param str
|
|
99
|
-
*/
|
|
100
|
-
function getByteArrayFromHexAddress(str) {
|
|
101
|
-
return tronweb.utils.code.hexStr2byteArray(str.replace('0x', ''));
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* @param arr
|
|
105
|
-
*/
|
|
106
|
-
function getHexAddressFromByteArray(arr) {
|
|
107
|
-
return tronweb.utils.code.byteArray2hexStr(arr);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* @param messageToVerify
|
|
111
|
-
* @param base58Address
|
|
112
|
-
* @param sigHex
|
|
113
|
-
* @param useTronHeader
|
|
114
|
-
*/
|
|
115
|
-
function verifySignature(messageToVerify, base58Address, sigHex, useTronHeader = true) {
|
|
116
|
-
if (!isValidHex(sigHex)) {
|
|
117
|
-
throw new sdk_core_1.UtilsError('signature is not in a valid format, needs to be hexadecimal');
|
|
118
|
-
}
|
|
119
|
-
if (!isValidHex(messageToVerify)) {
|
|
120
|
-
throw new sdk_core_1.UtilsError('message is not in a valid format, needs to be hexadecimal');
|
|
121
|
-
}
|
|
122
|
-
if (!isBase58Address(base58Address)) {
|
|
123
|
-
throw new sdk_core_1.UtilsError('address needs to be base58 encoded');
|
|
124
|
-
}
|
|
125
|
-
return tronweb.Trx.verifySignature(messageToVerify, base58Address, sigHex, useTronHeader);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* @param base58
|
|
129
|
-
*/
|
|
130
|
-
function getHexAddressFromBase58Address(base58) {
|
|
131
|
-
// pulled from: https://github.com/TRON-US/tronweb/blob/dcb8efa36a5ebb65c4dab3626e90256a453f3b0d/src/utils/help.js#L17
|
|
132
|
-
// but they don't surface this call in index.js
|
|
133
|
-
const bytes = tronweb.utils.crypto.decodeBase58Address(base58);
|
|
134
|
-
// Ensure bytes is a ByteArray (number[])
|
|
135
|
-
if (Array.isArray(bytes)) {
|
|
136
|
-
return getHexAddressFromByteArray(bytes);
|
|
137
|
-
}
|
|
138
|
-
throw new sdk_core_1.UtilsError('Failed to decode base58 address to byte array');
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* @param privateKey
|
|
142
|
-
*/
|
|
143
|
-
function getPubKeyFromPriKey(privateKey) {
|
|
144
|
-
return tronweb.utils.crypto.getPubKeyFromPriKey(privateKey);
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* @param privateKey
|
|
148
|
-
*/
|
|
149
|
-
function getAddressFromPriKey(privateKey) {
|
|
150
|
-
return tronweb.utils.crypto.getAddressFromPriKey(privateKey);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* @param address
|
|
154
|
-
*/
|
|
155
|
-
function getBase58AddressFromByteArray(address) {
|
|
156
|
-
return tronweb.utils.crypto.getBase58CheckAddress(address);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* @param hex
|
|
160
|
-
*/
|
|
161
|
-
function getBase58AddressFromHex(hex) {
|
|
162
|
-
const arr = getByteArrayFromHexAddress(hex);
|
|
163
|
-
return getBase58AddressFromByteArray(arr);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* @param privateKey
|
|
167
|
-
* @param transaction
|
|
168
|
-
*/
|
|
169
|
-
function signTransaction(privateKey, transaction) {
|
|
170
|
-
return tronweb.utils.crypto.signTransaction(privateKey, transaction);
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* @param message
|
|
174
|
-
* @param privateKey
|
|
175
|
-
* @param useTronHeader
|
|
176
|
-
*/
|
|
177
|
-
function signString(message, privateKey, useTronHeader = true) {
|
|
178
|
-
return tronweb.Trx.signString(message, privateKey, useTronHeader);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* @param pubBytes
|
|
182
|
-
*/
|
|
183
|
-
function getRawAddressFromPubKey(pubBytes) {
|
|
184
|
-
return tronweb.utils.crypto.computeAddress(pubBytes);
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Decodes a hex encoded transaction in its protobuf representation.
|
|
188
|
-
*
|
|
189
|
-
* @param hexString raw_data_hex field from tron transactions
|
|
190
|
-
*/
|
|
191
|
-
function decodeTransaction(hexString) {
|
|
192
|
-
const rawTransaction = decodeRawTransaction(hexString);
|
|
193
|
-
// there should not be multiple contracts in this data
|
|
194
|
-
if (rawTransaction.contracts.length !== 1) {
|
|
195
|
-
throw new sdk_core_1.UtilsError('Number of contracts is greater than 1.');
|
|
196
|
-
}
|
|
197
|
-
let contract;
|
|
198
|
-
let contractType;
|
|
199
|
-
// ensure the contract type is supported
|
|
200
|
-
switch (rawTransaction.contracts[0].parameter.type_url) {
|
|
201
|
-
case 'type.googleapis.com/protocol.TransferContract':
|
|
202
|
-
contractType = enum_1.ContractType.Transfer;
|
|
203
|
-
contract = exports.decodeTransferContract(rawTransaction.contracts[0].parameter.value);
|
|
204
|
-
break;
|
|
205
|
-
case 'type.googleapis.com/protocol.AccountPermissionUpdateContract':
|
|
206
|
-
contractType = enum_1.ContractType.AccountPermissionUpdate;
|
|
207
|
-
contract = exports.decodeAccountPermissionUpdateContract(rawTransaction.contracts[0].parameter.value);
|
|
208
|
-
break;
|
|
209
|
-
case 'type.googleapis.com/protocol.TriggerSmartContract':
|
|
210
|
-
contractType = enum_1.ContractType.TriggerSmartContract;
|
|
211
|
-
contract = exports.decodeTriggerSmartContract(rawTransaction.contracts[0].parameter.value);
|
|
212
|
-
break;
|
|
213
|
-
case 'type.googleapis.com/protocol.FreezeBalanceV2Contract':
|
|
214
|
-
contractType = enum_1.ContractType.FreezeBalanceV2;
|
|
215
|
-
contract = decodeFreezeBalanceV2Contract(rawTransaction.contracts[0].parameter.value);
|
|
216
|
-
break;
|
|
217
|
-
case 'type.googleapis.com/protocol.VoteWitnessContract':
|
|
218
|
-
contractType = enum_1.ContractType.VoteWitness;
|
|
219
|
-
contract = decodeVoteWitnessContract(rawTransaction.contracts[0].parameter.value);
|
|
220
|
-
break;
|
|
221
|
-
case 'type.googleapis.com/protocol.WithdrawExpireUnfreezeContract':
|
|
222
|
-
contract = decodeWithdrawExpireUnfreezeContract(rawTransaction.contracts[0].parameter.value);
|
|
223
|
-
contractType = enum_1.ContractType.WithdrawExpireUnfreeze;
|
|
224
|
-
break;
|
|
225
|
-
case 'type.googleapis.com/protocol.WithdrawBalanceContract':
|
|
226
|
-
contract = decodeWithdrawBalanceContract(rawTransaction.contracts[0].parameter.value);
|
|
227
|
-
contractType = enum_1.ContractType.WithdrawBalance;
|
|
228
|
-
break;
|
|
229
|
-
case 'type.googleapis.com/protocol.UnfreezeBalanceV2Contract':
|
|
230
|
-
contract = decodeUnfreezeBalanceV2Contract(rawTransaction.contracts[0].parameter.value);
|
|
231
|
-
contractType = enum_1.ContractType.UnfreezeBalanceV2;
|
|
232
|
-
break;
|
|
233
|
-
case constants_1.DELEGATION_TYPE_URL:
|
|
234
|
-
contractType = enum_1.ContractType.DelegateResourceContract;
|
|
235
|
-
contract = decodeDelegateResourceContract(rawTransaction.contracts[0].parameter.value);
|
|
236
|
-
break;
|
|
237
|
-
case 'type.googleapis.com/protocol.UnDelegateResourceContract':
|
|
238
|
-
contractType = enum_1.ContractType.UnDelegateResourceContract;
|
|
239
|
-
contract = decodeUnDelegateResourceContract(rawTransaction.contracts[0].parameter.value);
|
|
240
|
-
break;
|
|
241
|
-
default:
|
|
242
|
-
throw new sdk_core_1.UtilsError('Unsupported contract type');
|
|
243
|
-
}
|
|
244
|
-
return {
|
|
245
|
-
contractType,
|
|
246
|
-
contract,
|
|
247
|
-
expiration: rawTransaction.expiration,
|
|
248
|
-
timestamp: rawTransaction.timestamp,
|
|
249
|
-
ref_block_bytes: rawTransaction.blockBytes,
|
|
250
|
-
ref_block_hash: rawTransaction.blockHash,
|
|
251
|
-
fee_limit: +rawTransaction.feeLimit,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Decodes a transaction's raw field from a base64 encoded string. This is a protobuf representation.
|
|
256
|
-
*
|
|
257
|
-
* @param hexString this is the raw hexadecimal encoded string. Doc found in the following link.
|
|
258
|
-
* @example
|
|
259
|
-
* @see {@link https://github.com/BitGo/bitgo-account-lib/blob/5f282588701778a4421c75fa61f42713f56e95b9/resources/protobuf/tron.proto#L319}
|
|
260
|
-
*/
|
|
261
|
-
function decodeRawTransaction(hexString) {
|
|
262
|
-
const bytes = Buffer.from(hexString, 'hex');
|
|
263
|
-
let raw;
|
|
264
|
-
try {
|
|
265
|
-
// we need to decode our raw_data_hex field first
|
|
266
|
-
raw = tron_1.protocol.Transaction.raw.decode(bytes);
|
|
267
|
-
}
|
|
268
|
-
catch (e) {
|
|
269
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the initial raw_data_hex from the serialized tx.');
|
|
270
|
-
}
|
|
271
|
-
return {
|
|
272
|
-
expiration: Number(raw.expiration),
|
|
273
|
-
timestamp: Number(raw.timestamp),
|
|
274
|
-
contracts: raw.contract,
|
|
275
|
-
blockBytes: toHex(raw.refBlockBytes),
|
|
276
|
-
feeLimit: raw.feeLimit,
|
|
277
|
-
blockHash: toHex(raw.refBlockHash),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Indicates whether the passed string is a safe hex string for tron's purposes.
|
|
282
|
-
*
|
|
283
|
-
* @param hex A valid hex string must be a string made of numbers and characters and has an even length.
|
|
284
|
-
*/
|
|
285
|
-
function isValidHex(hex) {
|
|
286
|
-
return /^(0x)?([0-9a-f]{2})+$/i.test(hex);
|
|
287
|
-
}
|
|
288
|
-
/** Deserialize the segment of the txHex which corresponds with the details of the transfer
|
|
289
|
-
*
|
|
290
|
-
* @param transferHex is the value property of the "parameter" field of contractList[0]
|
|
291
|
-
* */
|
|
292
|
-
function decodeTransferContract(transferHex) {
|
|
293
|
-
const contractBytes = Buffer.from(transferHex, 'base64');
|
|
294
|
-
let transferContract;
|
|
295
|
-
try {
|
|
296
|
-
transferContract = tron_1.protocol.TransferContract.decode(contractBytes);
|
|
297
|
-
}
|
|
298
|
-
catch (e) {
|
|
299
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the transfer contract in the transaction.');
|
|
300
|
-
}
|
|
301
|
-
if (!transferContract.ownerAddress) {
|
|
302
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this transfer contract.');
|
|
303
|
-
}
|
|
304
|
-
if (!transferContract.toAddress) {
|
|
305
|
-
throw new sdk_core_1.UtilsError('Destination address does not exist in this transfer contract.');
|
|
306
|
-
}
|
|
307
|
-
if (!transferContract.hasOwnProperty('amount')) {
|
|
308
|
-
throw new sdk_core_1.UtilsError('Amount does not exist in this transfer contract.');
|
|
309
|
-
}
|
|
310
|
-
// deserialize attributes
|
|
311
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(transferContract.ownerAddress, 'base64').toString('hex')));
|
|
312
|
-
const to_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(transferContract.toAddress, 'base64').toString('hex')));
|
|
313
|
-
const amount = transferContract.amount;
|
|
314
|
-
return [
|
|
315
|
-
{
|
|
316
|
-
parameter: {
|
|
317
|
-
value: {
|
|
318
|
-
amount: Number(amount),
|
|
319
|
-
owner_address,
|
|
320
|
-
to_address,
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
];
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Deserialize the segment of the txHex corresponding with trigger smart contract
|
|
328
|
-
*
|
|
329
|
-
* @param {string} base64
|
|
330
|
-
* @returns {AccountPermissionUpdateContract}
|
|
331
|
-
*/
|
|
332
|
-
function decodeTriggerSmartContract(base64) {
|
|
333
|
-
let contractCallDecoded;
|
|
334
|
-
try {
|
|
335
|
-
contractCallDecoded = tron_1.protocol.TriggerSmartContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
336
|
-
}
|
|
337
|
-
catch (e) {
|
|
338
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the contract call in the transaction.');
|
|
339
|
-
}
|
|
340
|
-
if (!contractCallDecoded.ownerAddress) {
|
|
341
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this contract call.');
|
|
342
|
-
}
|
|
343
|
-
if (!contractCallDecoded.contractAddress) {
|
|
344
|
-
throw new sdk_core_1.UtilsError('Destination contract address does not exist in this contract call.');
|
|
345
|
-
}
|
|
346
|
-
if (!contractCallDecoded.data) {
|
|
347
|
-
throw new sdk_core_1.UtilsError('Data does not exist in this contract call.');
|
|
348
|
-
}
|
|
349
|
-
// deserialize attributes
|
|
350
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(contractCallDecoded.ownerAddress, 'base64').toString('hex')));
|
|
351
|
-
const contract_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(contractCallDecoded.contractAddress, 'base64').toString('hex')));
|
|
352
|
-
const data = contractCallDecoded.data;
|
|
353
|
-
return [
|
|
354
|
-
{
|
|
355
|
-
parameter: {
|
|
356
|
-
value: {
|
|
357
|
-
data: data,
|
|
358
|
-
owner_address,
|
|
359
|
-
contract_address,
|
|
360
|
-
},
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
];
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Deserialize the segment of the txHex corresponding with the details of the contract which updates
|
|
367
|
-
* account permission
|
|
368
|
-
*
|
|
369
|
-
* @param {string} base64
|
|
370
|
-
* @returns {AccountPermissionUpdateContract}
|
|
371
|
-
*/
|
|
372
|
-
function decodeAccountPermissionUpdateContract(base64) {
|
|
373
|
-
const accountUpdateContract = tron_1.protocol.AccountPermissionUpdateContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
374
|
-
(0, assert_1.default)(accountUpdateContract.ownerAddress);
|
|
375
|
-
(0, assert_1.default)(accountUpdateContract.owner);
|
|
376
|
-
(0, assert_1.default)(accountUpdateContract.hasOwnProperty('actives'));
|
|
377
|
-
const ownerAddress = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(accountUpdateContract.ownerAddress, 'base64').toString('hex')));
|
|
378
|
-
const owner = createPermission(accountUpdateContract.owner);
|
|
379
|
-
let witness = undefined;
|
|
380
|
-
if (accountUpdateContract.witness) {
|
|
381
|
-
witness = createPermission(accountUpdateContract.witness);
|
|
382
|
-
}
|
|
383
|
-
const activeList = accountUpdateContract.actives.map((active) => createPermission(active));
|
|
384
|
-
return {
|
|
385
|
-
ownerAddress,
|
|
386
|
-
owner,
|
|
387
|
-
witness,
|
|
388
|
-
actives: activeList,
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Deserialize the segment of the txHex corresponding with freeze balance contract
|
|
393
|
-
*
|
|
394
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
395
|
-
* @returns {FreezeBalanceContractParameter[]} - Array containing the decoded freeze contract
|
|
396
|
-
*/
|
|
397
|
-
function decodeFreezeBalanceV2Contract(base64) {
|
|
398
|
-
let freezeContract;
|
|
399
|
-
try {
|
|
400
|
-
freezeContract = tron_1.protocol.FreezeBalanceV2Contract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
401
|
-
}
|
|
402
|
-
catch (e) {
|
|
403
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the freeze contract in the transaction.');
|
|
404
|
-
}
|
|
405
|
-
if (!freezeContract.ownerAddress) {
|
|
406
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this freeze contract.');
|
|
407
|
-
}
|
|
408
|
-
if (freezeContract.resource === undefined) {
|
|
409
|
-
throw new sdk_core_1.UtilsError('Resource type does not exist in this freeze contract.');
|
|
410
|
-
}
|
|
411
|
-
if (freezeContract.frozenBalance === undefined) {
|
|
412
|
-
throw new sdk_core_1.UtilsError('Frozen balance does not exist in this freeze contract.');
|
|
413
|
-
}
|
|
414
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(freezeContract.ownerAddress, 'base64').toString('hex')));
|
|
415
|
-
const resourceValue = freezeContract.resource === 0 ? enum_1.TronResource.BANDWIDTH : enum_1.TronResource.ENERGY;
|
|
416
|
-
return [
|
|
417
|
-
{
|
|
418
|
-
parameter: {
|
|
419
|
-
value: {
|
|
420
|
-
resource: resourceValue,
|
|
421
|
-
frozen_balance: Number(freezeContract.frozenBalance),
|
|
422
|
-
owner_address,
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
},
|
|
426
|
-
];
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Deserialize the segment of the txHex corresponding with vote witness contract
|
|
430
|
-
*
|
|
431
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
432
|
-
* @returns {VoteWitnessContractParameter[]} - Array containing the decoded vote witness contract
|
|
433
|
-
*/
|
|
434
|
-
function decodeVoteWitnessContract(base64) {
|
|
435
|
-
let voteContract;
|
|
436
|
-
try {
|
|
437
|
-
voteContract = tron_1.protocol.VoteWitnessContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
438
|
-
}
|
|
439
|
-
catch (e) {
|
|
440
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the vote contract in the transaction.');
|
|
441
|
-
}
|
|
442
|
-
if (!voteContract.ownerAddress) {
|
|
443
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this vote contract.');
|
|
444
|
-
}
|
|
445
|
-
if (!Array.isArray(voteContract.votes) || voteContract.votes.length === 0) {
|
|
446
|
-
throw new sdk_core_1.UtilsError('Votes do not exist or are empty in this vote contract.');
|
|
447
|
-
}
|
|
448
|
-
// deserialize attributes
|
|
449
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(voteContract.ownerAddress, 'base64').toString('hex')));
|
|
450
|
-
const votes = voteContract.votes.map((vote) => {
|
|
451
|
-
if (!vote.voteAddress) {
|
|
452
|
-
throw new sdk_core_1.UtilsError('Vote address is missing in one of the votes.');
|
|
453
|
-
}
|
|
454
|
-
return {
|
|
455
|
-
vote_address: getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(vote.voteAddress, 'base64').toString('hex'))),
|
|
456
|
-
vote_count: Number(vote.voteCount || 0),
|
|
457
|
-
};
|
|
458
|
-
});
|
|
459
|
-
return [
|
|
460
|
-
{
|
|
461
|
-
parameter: {
|
|
462
|
-
value: {
|
|
463
|
-
owner_address,
|
|
464
|
-
votes,
|
|
465
|
-
},
|
|
466
|
-
},
|
|
467
|
-
},
|
|
468
|
-
];
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Deserialize the segment of the txHex corresponding with unfreeze balance contract
|
|
472
|
-
*
|
|
473
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
474
|
-
* @returns {UnfreezeBalanceContractParameter[]} - Array containing the decoded unfreeze contract
|
|
475
|
-
*/
|
|
476
|
-
function decodeUnfreezeBalanceV2Contract(base64) {
|
|
477
|
-
let unfreezeContract;
|
|
478
|
-
try {
|
|
479
|
-
unfreezeContract = tron_1.protocol.UnfreezeBalanceV2Contract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
480
|
-
}
|
|
481
|
-
catch (e) {
|
|
482
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the unfreeze contract in the transaction.');
|
|
483
|
-
}
|
|
484
|
-
if (!unfreezeContract.ownerAddress) {
|
|
485
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this unfreeze contract.');
|
|
486
|
-
}
|
|
487
|
-
if (unfreezeContract.resource === undefined) {
|
|
488
|
-
throw new sdk_core_1.UtilsError('Resource type does not exist in this unfreeze contract.');
|
|
489
|
-
}
|
|
490
|
-
if (unfreezeContract.unfreezeBalance === undefined) {
|
|
491
|
-
throw new sdk_core_1.UtilsError('Unfreeze balance does not exist in this unfreeze contract.');
|
|
492
|
-
}
|
|
493
|
-
// deserialize attributes
|
|
494
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(unfreezeContract.ownerAddress, 'base64').toString('hex')));
|
|
495
|
-
// Convert ResourceCode enum value to string resource name
|
|
496
|
-
const resourceValue = unfreezeContract.resource;
|
|
497
|
-
const resourceEnum = resourceValue === tron_1.protocol.ResourceCode.BANDWIDTH ? enum_1.TronResource.BANDWIDTH : enum_1.TronResource.ENERGY;
|
|
498
|
-
return [
|
|
499
|
-
{
|
|
500
|
-
parameter: {
|
|
501
|
-
value: {
|
|
502
|
-
resource: resourceEnum,
|
|
503
|
-
unfreeze_balance: Number(unfreezeContract.unfreezeBalance),
|
|
504
|
-
owner_address,
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
},
|
|
508
|
-
];
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Deserialize the segment of the txHex corresponding with withdraw balance contract
|
|
512
|
-
* Decoded contract is the same as withdraw expire unfreeze
|
|
513
|
-
*
|
|
514
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
515
|
-
* @returns {WithdrawExpireUnfreezeContractParameter[]} - Array containing the decoded withdraw contract
|
|
516
|
-
*/
|
|
517
|
-
function decodeWithdrawBalanceContract(base64) {
|
|
518
|
-
let withdrawContract;
|
|
519
|
-
try {
|
|
520
|
-
withdrawContract = tron_1.protocol.WithdrawBalanceContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
521
|
-
}
|
|
522
|
-
catch (e) {
|
|
523
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the withdraw contract in the transaction.');
|
|
524
|
-
}
|
|
525
|
-
if (!withdrawContract.ownerAddress) {
|
|
526
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this withdraw contract.');
|
|
527
|
-
}
|
|
528
|
-
// deserialize attributes
|
|
529
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(withdrawContract.ownerAddress, 'base64').toString('hex')));
|
|
530
|
-
return [
|
|
531
|
-
{
|
|
532
|
-
parameter: {
|
|
533
|
-
value: {
|
|
534
|
-
owner_address,
|
|
535
|
-
},
|
|
536
|
-
},
|
|
537
|
-
},
|
|
538
|
-
];
|
|
539
|
-
}
|
|
540
|
-
/**
|
|
541
|
-
* Deserialize the segment of the txHex corresponding with withdraw expire unfreeze contract
|
|
542
|
-
*
|
|
543
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
544
|
-
* @returns {WithdrawExpireUnfreezeContractParameter[]} - Array containing the decoded withdraw contract
|
|
545
|
-
*/
|
|
546
|
-
function decodeWithdrawExpireUnfreezeContract(base64) {
|
|
547
|
-
let withdrawContract;
|
|
548
|
-
try {
|
|
549
|
-
withdrawContract = tron_1.protocol.WithdrawBalanceContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
550
|
-
}
|
|
551
|
-
catch (e) {
|
|
552
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the withdraw contract in the transaction.');
|
|
553
|
-
}
|
|
554
|
-
if (!withdrawContract.ownerAddress) {
|
|
555
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this withdraw contract.');
|
|
556
|
-
}
|
|
557
|
-
// deserialize attributes
|
|
558
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(withdrawContract.ownerAddress, 'base64').toString('hex')));
|
|
559
|
-
return [
|
|
560
|
-
{
|
|
561
|
-
parameter: {
|
|
562
|
-
value: {
|
|
563
|
-
owner_address,
|
|
564
|
-
},
|
|
565
|
-
},
|
|
566
|
-
},
|
|
567
|
-
];
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Deserialize the segment of the txHex corresponding with delegate resource contract
|
|
571
|
-
*
|
|
572
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
573
|
-
* @returns {ResourceManagementContractParameter[]} - Array containing the decoded delegate resource contract
|
|
574
|
-
*/
|
|
575
|
-
function decodeDelegateResourceContract(base64) {
|
|
576
|
-
let delegateResourceContract;
|
|
577
|
-
try {
|
|
578
|
-
delegateResourceContract = tron_1.protocol.DelegateResourceContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
579
|
-
}
|
|
580
|
-
catch (e) {
|
|
581
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the delegate resource contract in the transaction.');
|
|
582
|
-
}
|
|
583
|
-
if (!delegateResourceContract.ownerAddress) {
|
|
584
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this delegate resource contract.');
|
|
585
|
-
}
|
|
586
|
-
if (!delegateResourceContract.receiverAddress) {
|
|
587
|
-
throw new sdk_core_1.UtilsError('Receiver address does not exist in this delegate resource contract.');
|
|
588
|
-
}
|
|
589
|
-
if (delegateResourceContract.resource === undefined) {
|
|
590
|
-
throw new sdk_core_1.UtilsError('Resource type does not exist in this delegate resource contract.');
|
|
591
|
-
}
|
|
592
|
-
if (delegateResourceContract.balance === undefined) {
|
|
593
|
-
throw new sdk_core_1.UtilsError('Balance does not exist in this delegate resource contract.');
|
|
594
|
-
}
|
|
595
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(delegateResourceContract.ownerAddress, 'base64').toString('hex')));
|
|
596
|
-
const receiver_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(delegateResourceContract.receiverAddress, 'base64').toString('hex')));
|
|
597
|
-
const resourceValue = !delegateResourceContract.resource ? enum_1.TronResource.BANDWIDTH : enum_1.TronResource.ENERGY;
|
|
598
|
-
return [
|
|
599
|
-
{
|
|
600
|
-
parameter: {
|
|
601
|
-
value: {
|
|
602
|
-
resource: resourceValue,
|
|
603
|
-
balance: Number(delegateResourceContract.balance),
|
|
604
|
-
owner_address,
|
|
605
|
-
receiver_address,
|
|
606
|
-
},
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
];
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Deserialize the segment of the txHex corresponding with undelegate resource contract
|
|
613
|
-
*
|
|
614
|
-
* @param {string} base64 - The base64 encoded contract data
|
|
615
|
-
* @returns {ResourceManagementContractParameter[]} - Array containing the decoded undelegate resource contract
|
|
616
|
-
*/
|
|
617
|
-
function decodeUnDelegateResourceContract(base64) {
|
|
618
|
-
let undelegateResourceContract;
|
|
619
|
-
try {
|
|
620
|
-
undelegateResourceContract = tron_1.protocol.UnDelegateResourceContract.decode(Buffer.from(base64, 'base64')).toJSON();
|
|
621
|
-
}
|
|
622
|
-
catch (e) {
|
|
623
|
-
throw new sdk_core_1.UtilsError('There was an error decoding the delegate resource contract in the transaction.');
|
|
624
|
-
}
|
|
625
|
-
if (!undelegateResourceContract.ownerAddress) {
|
|
626
|
-
throw new sdk_core_1.UtilsError('Owner address does not exist in this delegate resource contract.');
|
|
627
|
-
}
|
|
628
|
-
if (!undelegateResourceContract.receiverAddress) {
|
|
629
|
-
throw new sdk_core_1.UtilsError('Receiver address does not exist in this delegate resource contract.');
|
|
630
|
-
}
|
|
631
|
-
if (undelegateResourceContract.resource === undefined) {
|
|
632
|
-
throw new sdk_core_1.UtilsError('Resource type does not exist in this delegate resource contract.');
|
|
633
|
-
}
|
|
634
|
-
if (undelegateResourceContract.balance === undefined) {
|
|
635
|
-
throw new sdk_core_1.UtilsError('Balance does not exist in this delegate resource contract.');
|
|
636
|
-
}
|
|
637
|
-
const owner_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(undelegateResourceContract.ownerAddress, 'base64').toString('hex')));
|
|
638
|
-
const receiver_address = getBase58AddressFromByteArray(getByteArrayFromHexAddress(Buffer.from(undelegateResourceContract.receiverAddress, 'base64').toString('hex')));
|
|
639
|
-
const resourceValue = !undelegateResourceContract.resource ? enum_1.TronResource.BANDWIDTH : enum_1.TronResource.ENERGY;
|
|
640
|
-
return [
|
|
641
|
-
{
|
|
642
|
-
parameter: {
|
|
643
|
-
value: {
|
|
644
|
-
resource: resourceValue,
|
|
645
|
-
balance: Number(undelegateResourceContract.balance),
|
|
646
|
-
owner_address,
|
|
647
|
-
receiver_address,
|
|
648
|
-
},
|
|
649
|
-
},
|
|
650
|
-
},
|
|
651
|
-
];
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* @param raw
|
|
655
|
-
*/
|
|
656
|
-
function createPermission(raw) {
|
|
657
|
-
let permissionType;
|
|
658
|
-
const permission = raw.permissionName.toLowerCase().trim();
|
|
659
|
-
if (permission === 'owner') {
|
|
660
|
-
permissionType = enum_1.PermissionType.Owner;
|
|
661
|
-
}
|
|
662
|
-
else if (permission === 'witness') {
|
|
663
|
-
permissionType = enum_1.PermissionType.Witness;
|
|
664
|
-
}
|
|
665
|
-
else if (permission.substr(0, 6) === 'active') {
|
|
666
|
-
permissionType = enum_1.PermissionType.Active;
|
|
667
|
-
}
|
|
668
|
-
else {
|
|
669
|
-
throw new sdk_core_1.UtilsError('Permission type not parseable.');
|
|
670
|
-
}
|
|
671
|
-
return { type: permissionType, threshold: raw.threshold };
|
|
672
|
-
}
|
|
673
|
-
/**
|
|
674
|
-
* @param rawTransaction
|
|
675
|
-
*/
|
|
676
|
-
function isValidTxJsonString(rawTransaction) {
|
|
677
|
-
const transaction = JSON.parse(rawTransaction);
|
|
678
|
-
return transaction.hasOwnProperty('txID');
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Returns whether the provided raw transaction accommodates to bitgo's preferred format
|
|
682
|
-
*
|
|
683
|
-
* @param {any} rawTransaction - The raw transaction to be checked
|
|
684
|
-
* @returns {boolean} the validation result
|
|
685
|
-
*/
|
|
686
|
-
function isValidRawTransactionFormat(rawTransaction) {
|
|
687
|
-
if (typeof rawTransaction === 'string' && (isValidHex(rawTransaction) || isValidTxJsonString(rawTransaction))) {
|
|
688
|
-
return true;
|
|
689
|
-
}
|
|
690
|
-
return false;
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Returns an hex string of the given buffer
|
|
694
|
-
*
|
|
695
|
-
* @param {Buffer | Uint8Array} buffer - the buffer to be converted to hex
|
|
696
|
-
* @returns {string} - the hex value
|
|
697
|
-
*/
|
|
698
|
-
function toHex(buffer) {
|
|
699
|
-
return hex.encode(buffer, true);
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Returns a Keccak-256 encoded string of the parameters
|
|
703
|
-
*
|
|
704
|
-
* @param types - strings describing the types of the values
|
|
705
|
-
* @param values - value to encode
|
|
706
|
-
* @param methodId - the first 4 bytes of the function selector
|
|
707
|
-
*/
|
|
708
|
-
function encodeDataParams(types, values, methodId) {
|
|
709
|
-
types.forEach((type, index) => {
|
|
710
|
-
if (type == 'address') {
|
|
711
|
-
values[index] = values[index].replace(ADDRESS_PREFIX_REGEX, '0x');
|
|
712
|
-
}
|
|
713
|
-
});
|
|
714
|
-
const abiCoder = new utils_1.AbiCoder();
|
|
715
|
-
let data;
|
|
716
|
-
try {
|
|
717
|
-
data = abiCoder.encode(types, values);
|
|
718
|
-
}
|
|
719
|
-
catch (e) {
|
|
720
|
-
throw new sdk_core_1.UtilsError(`There was an error encoding the data params. Error = ${JSON.stringify(e)}`);
|
|
721
|
-
}
|
|
722
|
-
if (methodId) {
|
|
723
|
-
return (0, utils_1.hexConcat)([methodId, data]).replace(/^(0x)/, '');
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
return data.replace(/^(0x)/, '');
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* Returns the decoded values according to the array of types
|
|
731
|
-
*
|
|
732
|
-
* @param types - strings describing the types of the values
|
|
733
|
-
* @param data - encoded string
|
|
734
|
-
*/
|
|
735
|
-
function decodeDataParams(types, data) {
|
|
736
|
-
const abiCoder = new utils_1.AbiCoder();
|
|
737
|
-
data = '0x' + data.substring(8);
|
|
738
|
-
return abiCoder.decode(types, data).reduce((obj, arg, index) => {
|
|
739
|
-
if (types[index] == 'address')
|
|
740
|
-
arg = ADDRESS_PREFIX + arg.substr(2).toLowerCase();
|
|
741
|
-
obj.push(arg);
|
|
742
|
-
return obj;
|
|
743
|
-
}, []);
|
|
744
|
-
}
|
|
745
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXlEQSwwQ0FFQztBQUtELGdFQUVDO0FBS0QsZ0VBRUM7QUFRRCwwQ0FtQkM7QUFLRCx3RUFTQztBQUlELGtEQUVDO0FBS0Qsb0RBRUM7QUFLRCxzRUFFQztBQUtELDBEQUdDO0FBTUQsMENBRUM7QUFPRCxnQ0FFQztBQUtELDBEQUVDO0FBT0QsOENBMkVDO0FBU0Qsb0RBMEJDO0FBT0QsZ0NBRUM7QUFNRCx3REEwQ0M7QUFRRCxnRUF1Q0M7QUFTRCxzRkFzQkM7QUFRRCxzRUFxQ0M7QUFRRCw4REFpREM7QUFRRCwwRUF3Q0M7QUFTRCxzRUEwQkM7QUFRRCxvRkEwQkM7QUFRRCx3RUE4Q0M7QUFRRCw0RUE4Q0M7QUF1QkQsa0RBR0M7QUFRRCxrRUFLQztBQVFELHNCQUVDO0FBU0QsNENBbUJDO0FBUUQsNENBUUM7QUF0MEJELG9EQUE0QjtBQUM1QixvREFBc0M7QUFDdEMsaURBQW1DO0FBQ25DLHdEQUF5RDtBQUV6RCxtREFBa0Q7QUFDbEQsaURBQTJEO0FBbUIzRCxpQ0FBb0U7QUFDcEUsNENBQXVEO0FBQ3ZELDJDQUFrRDtBQUVyQyxRQUFBLDBCQUEwQixHQUFHLFFBQVEsQ0FBQyxDQUFDLFVBQVU7QUFDakQsUUFBQSw4QkFBOEIsR0FBRyxPQUFPLENBQUMsQ0FBQyxXQUFXO0FBQ2xFLE1BQU0sb0JBQW9CLEdBQUcsT0FBTyxDQUFDO0FBQ3JDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQztBQUk1QixNQUFNLGFBQWEsR0FBRyxDQUFDLE9BQU8sR0FBRyxTQUFTLEVBQUUsRUFBRTtJQUM1QyxPQUNFLGVBQUs7U0FDRixNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFD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QUMsS0FBZSxFQUFFLElBQVk7SUFDNUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxnQkFBUSxFQUFFLENBQUM7SUFDaEMsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hDLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRTtRQUM3RCxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTO1lBQUUsR0FBRyxHQUFHLGNBQWMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2xGLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDZCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNULENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBoZXggZnJvbSAnQHN0YWJsZWxpYi9oZXgnO1xuaW1wb3J0ICogYXMgdHJvbndlYiBmcm9tICd0cm9ud2ViJztcbmltcG9ydCB7IHByb3RvY29sIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3Byb3RvYnVmL3Ryb24nO1xuXG5pbXBvcnQgeyBVdGlsc0Vycm9yIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgVHJvbkVyYzIwQ29pbiwgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7XG4gIFRyYW5zZmVyQ29udHJhY3QsXG4gIFJhd0RhdGEsXG4gIEFjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3QsXG4gIFRyYW5zYWN0aW9uUmVjZWlwdCxcbiAgUGVybWlzc2lvbixcbiAgVHJpZ2dlclNtYXJ0Q29udHJhY3QsXG4gIEZyZWV6ZUJhbGFuY2VDb250cmFjdFBhcmFtZXRlcixcbiAgVm90ZVdpdG5lc3NDb250cmFjdFBhcmFtZXRlcixcbiAgRnJlZXplQ29udHJhY3REZWNvZGVkLFxuICBWb3RlQ29udHJhY3REZWNvZGVkLFxuICBVbmZyZWV6ZUJhbGFuY2VDb250cmFjdFBhcmFtZXRlcixcbiAgV2l0aGRyYXdFeHBpcmVVbmZyZWV6ZUNvbnRyYWN0UGFyYW1ldGVyLFxuICBVbmZyZWV6ZUNvbnRyYWN0RGVjb2RlZCxcbiAgV2l0aGRyYXdDb250cmFjdERlY29kZWQsXG4gIFJlc291cmNlTWFuYWdlbWVudENvbnRyYWN0UGFyYW1ldGVyLFxuICBSZXNvdXJjZU1hbmFnZW1lbnRDb250cmFjdERlY29kZWQsXG59IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHsgQ29udHJhY3RUeXBlLCBQZXJtaXNzaW9uVHlwZSwgVHJvblJlc291cmNlIH0gZnJvbSAnLi9lbnVtJztcbmltcG9ydCB7IEFiaUNvZGVyLCBoZXhDb25jYXQgfSBmcm9tICdldGhlcnMvbGliL3V0aWxzJztcbmltcG9ydCB7IERFTEVHQVRJT05fVFlQRV9VUkwgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBjb25zdCBUUkFOU0FDVElPTl9NQVhfRVhQSVJBVElPTiA9IDg2NDAwMDAwOyAvLyBvbmUgZGF5XG5leHBvcnQgY29uc3QgVFJBTlNBQ1RJT05fREVGQVVMVF9FWFBJUkFUSU9OID0gMzYwMDAwMDsgLy8gb25lIGhvdXJcbmNvbnN0IEFERFJFU1NfUFJFRklYX1JFR0VYID0gL14oNDEpLztcbmNvbnN0IEFERFJFU1NfUFJFRklYID0gJzQxJztcblxuZXhwb3J0IHR5cGUgQnl0ZXNMaWtlID0gbnVtYmVyW10gfCBVaW50OEFycmF5O1xuXG5jb25zdCBnZXRUcm9uVG9rZW5zID0gKG5ldHdvcmsgPSAnbWFpbm5ldCcpID0+IHtcbiAgcmV0dXJuIChcbiAgICBjb2luc1xuICAgICAgLmZpbHRlcigoY29pbikgPT4gY29pbi5mYW1pbHkgPT09ICd0cngnKVxuICAgICAgLmZpbHRlcigodHJ4KSA9PiB0cngubmV0d29yay50eXBlID09PSBuZXR3b3JrICYmIHRyeC5pc1Rva2VuKSBhcyB1bmtub3duIGFzIFRyb25FcmMyMENvaW5bXVxuICApLm1hcCgoY29pbnMpID0+IGNvaW5zLmNvbnRyYWN0QWRkcmVzcy50b1N0cmluZygpKTtcbn07XG5cbmV4cG9ydCBjb25zdCB0b2tlbk1haW5uZXRDb250cmFjdEFkZHJlc3NlcyA9IGdldFRyb25Ub2tlbnMoJ21haW5uZXQnKTtcbmV4cG9ydCBjb25zdCB0b2tlblRlc3RuZXRDb250cmFjdEFkZHJlc3NlcyA9IGdldFRyb25Ub2tlbnMoJ3Rlc3RuZXQnKTtcbi8qKlxuICogVHJvbi1zcGVjaWZpYyBoZWxwZXIgZnVuY3Rpb25zXG4gKi9cbmV4cG9ydCB0eXBlIEJ5dGVBcnJheSA9IG51bWJlcltdO1xuZXhwb3J0IHR5cGUgVHJvbkJpbmFyeUxpa2UgPSBCeXRlQXJyYXkgfCBCdWZmZXIgfCBVaW50OEFycmF5IHwgc3RyaW5nO1xuXG5leHBvcnQgY29uc3QgVkFMSURfUkVTT1VSQ0VfVFlQRVMgPSBbJ0VORVJHWScsICdCQU5EV0lEVEgnXTtcblxuLyoqXG4gKiBAcGFyYW0gYWRkcmVzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCYXNlNThBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHJvbndlYi51dGlscy5jcnlwdG8uaXNBZGRyZXNzVmFsaWQoYWRkcmVzcyk7XG59XG5cbi8qKlxuICogQHBhcmFtIHN0clxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3Moc3RyOiBzdHJpbmcpOiBCeXRlQXJyYXkge1xuICByZXR1cm4gdHJvbndlYi51dGlscy5jb2RlLmhleFN0cjJieXRlQXJyYXkoc3RyLnJlcGxhY2UoJzB4JywgJycpKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gYXJyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZXhBZGRyZXNzRnJvbUJ5dGVBcnJheShhcnI6IEJ5dGVBcnJheSk6IHN0cmluZyB7XG4gIHJldHVybiB0cm9ud2ViLnV0aWxzLmNvZGUuYnl0ZUFycmF5MmhleFN0cihhcnIpO1xufVxuXG4vKipcbiAqIEBwYXJhbSBtZXNzYWdlVG9WZXJpZnlcbiAqIEBwYXJhbSBiYXNlNThBZGRyZXNzXG4gKiBAcGFyYW0gc2lnSGV4XG4gKiBAcGFyYW0gdXNlVHJvbkhlYWRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5U2lnbmF0dXJlKFxuICBtZXNzYWdlVG9WZXJpZnk6IHN0cmluZyxcbiAgYmFzZTU4QWRkcmVzczogc3RyaW5nLFxuICBzaWdIZXg6IHN0cmluZyxcbiAgdXNlVHJvbkhlYWRlciA9IHRydWVcbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzVmFsaWRIZXgoc2lnSGV4KSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdzaWduYXR1cmUgaXMgbm90IGluIGEgdmFsaWQgZm9ybWF0LCBuZWVkcyB0byBiZSBoZXhhZGVjaW1hbCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkSGV4KG1lc3NhZ2VUb1ZlcmlmeSkpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignbWVzc2FnZSBpcyBub3QgaW4gYSB2YWxpZCBmb3JtYXQsIG5lZWRzIHRvIGJlIGhleGFkZWNpbWFsJyk7XG4gIH1cblxuICBpZiAoIWlzQmFzZTU4QWRkcmVzcyhiYXNlNThBZGRyZXNzKSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdhZGRyZXNzIG5lZWRzIHRvIGJlIGJhc2U1OCBlbmNvZGVkJyk7XG4gIH1cblxuICByZXR1cm4gdHJvbndlYi5UcngudmVyaWZ5U2lnbmF0dXJlKG1lc3NhZ2VUb1ZlcmlmeSwgYmFzZTU4QWRkcmVzcywgc2lnSGV4LCB1c2VUcm9uSGVhZGVyKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gYmFzZTU4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoYmFzZTU4OiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBwdWxsZWQgZnJvbTogaHR0cHM6Ly9naXRodWIuY29tL1RST04tVVMvdHJvbndlYi9ibG9iL2RjYjhlZmEzNmE1ZWJiNjVjNGRhYjM2MjZlOTAyNTZhNDUzZjNiMGQvc3JjL3V0aWxzL2hlbHAuanMjTDE3XG4gIC8vIGJ1dCB0aGV5IGRvbid0IHN1cmZhY2UgdGhpcyBjYWxsIGluIGluZGV4LmpzXG4gIGNvbnN0IGJ5dGVzID0gdHJvbndlYi51dGlscy5jcnlwdG8uZGVjb2RlQmFzZTU4QWRkcmVzcyhiYXNlNTgpO1xuICAvLyBFbnN1cmUgYnl0ZXMgaXMgYSBCeXRlQXJyYXkgKG51bWJlcltdKVxuICBpZiAoQXJyYXkuaXNBcnJheShieXRlcykpIHtcbiAgICByZXR1cm4gZ2V0SGV4QWRkcmVzc0Zyb21CeXRlQXJyYXkoYnl0ZXMpO1xuICB9XG4gIHRocm93IG5ldyBVdGlsc0Vycm9yKCdGYWlsZWQgdG8gZGVjb2RlIGJhc2U1OCBhZGRyZXNzIHRvIGJ5dGUgYXJyYXknKTtcbn1cbi8qKlxuICogQHBhcmFtIHByaXZhdGVLZXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFB1YktleUZyb21QcmlLZXkocHJpdmF0ZUtleTogVHJvbkJpbmFyeUxpa2UpOiBCeXRlQXJyYXkge1xuICByZXR1cm4gdHJvbndlYi51dGlscy5jcnlwdG8uZ2V0UHViS2V5RnJvbVByaUtleShwcml2YXRlS2V5IGFzIEJ5dGVzTGlrZSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHByaXZhdGVLZXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFkZHJlc3NGcm9tUHJpS2V5KHByaXZhdGVLZXk6IFRyb25CaW5hcnlMaWtlKTogQnl0ZUFycmF5IHtcbiAgcmV0dXJuIHRyb253ZWIudXRpbHMuY3J5cHRvLmdldEFkZHJlc3NGcm9tUHJpS2V5KHByaXZhdGVLZXkgYXMgQnl0ZXNMaWtlKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gYWRkcmVzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoYWRkcmVzczogQnl0ZUFycmF5KTogc3RyaW5nIHtcbiAgcmV0dXJuIHRyb253ZWIudXRpbHMuY3J5cHRvLmdldEJhc2U1OENoZWNrQWRkcmVzcyhhZGRyZXNzKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gaGV4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXNlNThBZGRyZXNzRnJvbUhleChoZXg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGFyciA9IGdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKGhleCk7XG4gIHJldHVybiBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShhcnIpO1xufVxuXG4vKipcbiAqIEBwYXJhbSBwcml2YXRlS2V5XG4gKiBAcGFyYW0gdHJhbnNhY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25UcmFuc2FjdGlvbihwcml2YXRlS2V5OiBzdHJpbmcgfCBCeXRlQXJyYXksIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvblJlY2VpcHQpOiBUcmFuc2FjdGlvblJlY2VpcHQge1xuICByZXR1cm4gdHJvbndlYi51dGlscy5jcnlwdG8uc2lnblRyYW5zYWN0aW9uKHByaXZhdGVLZXksIHRyYW5zYWN0aW9uKSBhcyBUcmFuc2FjdGlvblJlY2VpcHQ7XG59XG5cbi8qKlxuICogQHBhcmFtIG1lc3NhZ2VcbiAqIEBwYXJhbSBwcml2YXRlS2V5XG4gKiBAcGFyYW0gdXNlVHJvbkhlYWRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gc2lnblN0cmluZyhtZXNzYWdlOiBzdHJpbmcsIHByaXZhdGVLZXk6IHN0cmluZyB8IEJ5dGVBcnJheSwgdXNlVHJvbkhlYWRlciA9IHRydWUpOiBzdHJpbmcge1xuICByZXR1cm4gdHJvbndlYi5Ucnguc2lnblN0cmluZyhtZXNzYWdlLCBwcml2YXRlS2V5IGFzIHN0cmluZywgdXNlVHJvbkhlYWRlcik7XG59XG5cbi8qKlxuICogQHBhcmFtIHB1YkJ5dGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSYXdBZGRyZXNzRnJvbVB1YktleShwdWJCeXRlczogVHJvbkJpbmFyeUxpa2UpOiBCeXRlQXJyYXkge1xuICByZXR1cm4gdHJvbndlYi51dGlscy5jcnlwdG8uY29tcHV0ZUFkZHJlc3MocHViQnl0ZXMgYXMgQnl0ZXNMaWtlKTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGEgaGV4IGVuY29kZWQgdHJhbnNhY3Rpb24gaW4gaXRzIHByb3RvYnVmIHJlcHJlc2VudGF0aW9uLlxuICpcbiAqIEBwYXJhbSBoZXhTdHJpbmcgcmF3X2RhdGFfaGV4IGZpZWxkIGZyb20gdHJvbiB0cmFuc2FjdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVRyYW5zYWN0aW9uKGhleFN0cmluZzogc3RyaW5nKTogUmF3RGF0YSB7XG4gIGNvbnN0IHJhd1RyYW5zYWN0aW9uID0gZGVjb2RlUmF3VHJhbnNhY3Rpb24oaGV4U3RyaW5nKTtcblxuICAvLyB0aGVyZSBzaG91bGQgbm90IGJlIG11bHRpcGxlIGNvbnRyYWN0cyBpbiB0aGlzIGRhdGFcbiAgaWYgKHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignTnVtYmVyIG9mIGNvbnRyYWN0cyBpcyBncmVhdGVyIHRoYW4gMS4nKTtcbiAgfVxuXG4gIGxldCBjb250cmFjdDpcbiAgICB8IFRyYW5zZmVyQ29udHJhY3RbXVxuICAgIHwgQWNjb3VudFBlcm1pc3Npb25VcGRhdGVDb250cmFjdFtdXG4gICAgfCBUcmlnZ2VyU21hcnRDb250cmFjdFtdXG4gICAgfCBGcmVlemVCYWxhbmNlQ29udHJhY3RQYXJhbWV0ZXJbXVxuICAgIHwgVm90ZVdpdG5lc3NDb250cmFjdFBhcmFtZXRlcltdXG4gICAgfCBVbmZyZWV6ZUJhbGFuY2VDb250cmFjdFBhcmFtZXRlcltdXG4gICAgfCBXaXRoZHJhd0V4cGlyZVVuZnJlZXplQ29udHJhY3RQYXJhbWV0ZXJbXVxuICAgIHwgUmVzb3VyY2VNYW5hZ2VtZW50Q29udHJhY3RQYXJhbWV0ZXJbXTtcblxuICBsZXQgY29udHJhY3RUeXBlOiBDb250cmFjdFR5cGU7XG5cbiAgLy8gZW5zdXJlIHRoZSBjb250cmFjdCB0eXBlIGlzIHN1cHBvcnRlZFxuICBzd2l0Y2ggKHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0c1swXS5wYXJhbWV0ZXIudHlwZV91cmwpIHtcbiAgICBjYXNlICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3QnOlxuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLlRyYW5zZmVyO1xuICAgICAgY29udHJhY3QgPSBleHBvcnRzLmRlY29kZVRyYW5zZmVyQ29udHJhY3QocmF3VHJhbnNhY3Rpb24uY29udHJhY3RzWzBdLnBhcmFtZXRlci52YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLkFjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3QnOlxuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLkFjY291bnRQZXJtaXNzaW9uVXBkYXRlO1xuICAgICAgY29udHJhY3QgPSBleHBvcnRzLmRlY29kZUFjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3QocmF3VHJhbnNhY3Rpb24uY29udHJhY3RzWzBdLnBhcmFtZXRlci52YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyaWdnZXJTbWFydENvbnRyYWN0JzpcbiAgICAgIGNvbnRyYWN0VHlwZSA9IENvbnRyYWN0VHlwZS5UcmlnZ2VyU21hcnRDb250cmFjdDtcbiAgICAgIGNvbnRyYWN0ID0gZXhwb3J0cy5kZWNvZGVUcmlnZ2VyU21hcnRDb250cmFjdChyYXdUcmFuc2FjdGlvbi5jb250cmFjdHNbMF0ucGFyYW1ldGVyLnZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3R5cGUuZ29vZ2xlYXBpcy5jb20vcHJvdG9jb2wuRnJlZXplQmFsYW5jZVYyQ29udHJhY3QnOlxuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLkZyZWV6ZUJhbGFuY2VWMjtcbiAgICAgIGNvbnRyYWN0ID0gZGVjb2RlRnJlZXplQmFsYW5jZVYyQ29udHJhY3QocmF3VHJhbnNhY3Rpb24uY29udHJhY3RzWzBdLnBhcmFtZXRlci52YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlZvdGVXaXRuZXNzQ29udHJhY3QnOlxuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLlZvdGVXaXRuZXNzO1xuICAgICAgY29udHJhY3QgPSBkZWNvZGVWb3RlV2l0bmVzc0NvbnRyYWN0KHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0c1swXS5wYXJhbWV0ZXIudmFsdWUpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5XaXRoZHJhd0V4cGlyZVVuZnJlZXplQ29udHJhY3QnOlxuICAgICAgY29udHJhY3QgPSBkZWNvZGVXaXRoZHJhd0V4cGlyZVVuZnJlZXplQ29udHJhY3QocmF3VHJhbnNhY3Rpb24uY29udHJhY3RzWzBdLnBhcmFtZXRlci52YWx1ZSk7XG4gICAgICBjb250cmFjdFR5cGUgPSBDb250cmFjdFR5cGUuV2l0aGRyYXdFeHBpcmVVbmZyZWV6ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3R5cGUuZ29vZ2xlYXBpcy5jb20vcHJvdG9jb2wuV2l0aGRyYXdCYWxhbmNlQ29udHJhY3QnOlxuICAgICAgY29udHJhY3QgPSBkZWNvZGVXaXRoZHJhd0JhbGFuY2VDb250cmFjdChyYXdUcmFuc2FjdGlvbi5jb250cmFjdHNbMF0ucGFyYW1ldGVyLnZhbHVlKTtcbiAgICAgIGNvbnRyYWN0VHlwZSA9IENvbnRyYWN0VHlwZS5XaXRoZHJhd0JhbGFuY2U7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlVuZnJlZXplQmFsYW5jZVYyQ29udHJhY3QnOlxuICAgICAgY29udHJhY3QgPSBkZWNvZGVVbmZyZWV6ZUJhbGFuY2VWMkNvbnRyYWN0KHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0c1swXS5wYXJhbWV0ZXIudmFsdWUpO1xuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLlVuZnJlZXplQmFsYW5jZVYyO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBERUxFR0FUSU9OX1RZUEVfVVJMOlxuICAgICAgY29udHJhY3RUeXBlID0gQ29udHJhY3RUeXBlLkRlbGVnYXRlUmVzb3VyY2VDb250cmFjdDtcbiAgICAgIGNvbnRyYWN0ID0gZGVjb2RlRGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0KHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0c1swXS5wYXJhbWV0ZXIudmFsdWUpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5VbkRlbGVnYXRlUmVzb3VyY2VDb250cmFjdCc6XG4gICAgICBjb250cmFjdFR5cGUgPSBDb250cmFjdFR5cGUuVW5EZWxlZ2F0ZVJlc291cmNlQ29udHJhY3Q7XG4gICAgICBjb250cmFjdCA9IGRlY29kZVVuRGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0KHJhd1RyYW5zYWN0aW9uLmNvbnRyYWN0c1swXS5wYXJhbWV0ZXIudmFsdWUpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdVbnN1cHBvcnRlZCBjb250cmFjdCB0eXBlJyk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbnRyYWN0VHlwZSxcbiAgICBjb250cmFjdCxcbiAgICBleHBpcmF0aW9uOiByYXdUcmFuc2FjdGlvbi5leHBpcmF0aW9uLFxuICAgIHRpbWVzdGFtcDogcmF3VHJhbnNhY3Rpb24udGltZXN0YW1wLFxuICAgIHJlZl9ibG9ja19ieXRlczogcmF3VHJhbnNhY3Rpb24uYmxvY2tCeXRlcyxcbiAgICByZWZfYmxvY2tfaGFzaDogcmF3VHJhbnNhY3Rpb24uYmxvY2tIYXNoLFxuICAgIGZlZV9saW1pdDogK3Jhd1RyYW5zYWN0aW9uLmZlZUxpbWl0LFxuICB9O1xufVxuXG4vKipcbiAqIERlY29kZXMgYSB0cmFuc2FjdGlvbidzIHJhdyBmaWVsZCBmcm9tIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLiBUaGlzIGlzIGEgcHJvdG9idWYgcmVwcmVzZW50YXRpb24uXG4gKlxuICogQHBhcmFtIGhleFN0cmluZyB0aGlzIGlzIHRoZSByYXcgaGV4YWRlY2ltYWwgZW5jb2RlZCBzdHJpbmcuIERvYyBmb3VuZCBpbiB0aGUgZm9sbG93aW5nIGxpbmsuXG4gKiBAZXhhbXBsZVxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL0JpdEdvL2JpdGdvLWFjY291bnQtbGliL2Jsb2IvNWYyODI1ODg3MDE3NzhhNDQyMWM3NWZhNjFmNDI3MTNmNTZlOTViOS9yZXNvdXJjZXMvcHJvdG9idWYvdHJvbi5wcm90byNMMzE5fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlUmF3VHJhbnNhY3Rpb24oaGV4U3RyaW5nOiBzdHJpbmcpOiB7XG4gIGV4cGlyYXRpb246IG51bWJlcjtcbiAgdGltZXN0YW1wOiBudW1iZXI7XG4gIGNvbnRyYWN0czogQXJyYXk8YW55PjtcbiAgYmxvY2tCeXRlczogc3RyaW5nO1xuICBibG9ja0hhc2g6IHN0cmluZztcbiAgZmVlTGltaXQ6IHN0cmluZztcbn0ge1xuICBjb25zdCBieXRlcyA9IEJ1ZmZlci5mcm9tKGhleFN0cmluZywgJ2hleCcpO1xuXG4gIGxldCByYXc7XG4gIHRyeSB7XG4gICAgLy8gd2UgbmVlZCB0byBkZWNvZGUgb3VyIHJhd19kYXRhX2hleCBmaWVsZCBmaXJzdFxuICAgIHJhdyA9IHByb3RvY29sLlRyYW5zYWN0aW9uLnJhdy5kZWNvZGUoYnl0ZXMpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciBkZWNvZGluZyB0aGUgaW5pdGlhbCByYXdfZGF0YV9oZXggZnJvbSB0aGUgc2VyaWFsaXplZCB0eC4nKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZXhwaXJhdGlvbjogTnVtYmVyKHJhdy5leHBpcmF0aW9uKSxcbiAgICB0aW1lc3RhbXA6IE51bWJlcihyYXcudGltZXN0YW1wKSxcbiAgICBjb250cmFjdHM6IHJhdy5jb250cmFjdCxcbiAgICBibG9ja0J5dGVzOiB0b0hleChyYXcucmVmQmxvY2tCeXRlcyksXG4gICAgZmVlTGltaXQ6IHJhdy5mZWVMaW1pdCxcbiAgICBibG9ja0hhc2g6IHRvSGV4KHJhdy5yZWZCbG9ja0hhc2gpLFxuICB9O1xufVxuXG4vKipcbiAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBwYXNzZWQgc3RyaW5nIGlzIGEgc2FmZSBoZXggc3RyaW5nIGZvciB0cm9uJ3MgcHVycG9zZXMuXG4gKlxuICogQHBhcmFtIGhleCBBIHZhbGlkIGhleCBzdHJpbmcgbXVzdCBiZSBhIHN0cmluZyBtYWRlIG9mIG51bWJlcnMgYW5kIGNoYXJhY3RlcnMgYW5kIGhhcyBhbiBldmVuIGxlbmd0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRIZXgoaGV4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eKDB4KT8oWzAtOWEtZl17Mn0pKyQvaS50ZXN0KGhleCk7XG59XG5cbi8qKiBEZXNlcmlhbGl6ZSB0aGUgc2VnbWVudCBvZiB0aGUgdHhIZXggd2hpY2ggY29ycmVzcG9uZHMgd2l0aCB0aGUgZGV0YWlscyBvZiB0aGUgdHJhbnNmZXJcbiAqXG4gKiBAcGFyYW0gdHJhbnNmZXJIZXggaXMgdGhlIHZhbHVlIHByb3BlcnR5IG9mIHRoZSBcInBhcmFtZXRlclwiIGZpZWxkIG9mIGNvbnRyYWN0TGlzdFswXVxuICogKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVUcmFuc2ZlckNvbnRyYWN0KHRyYW5zZmVySGV4OiBzdHJpbmcpOiBUcmFuc2ZlckNvbnRyYWN0W10ge1xuICBjb25zdCBjb250cmFjdEJ5dGVzID0gQnVmZmVyLmZyb20odHJhbnNmZXJIZXgsICdiYXNlNjQnKTtcbiAgbGV0IHRyYW5zZmVyQ29udHJhY3Q7XG5cbiAgdHJ5IHtcbiAgICB0cmFuc2ZlckNvbnRyYWN0ID0gcHJvdG9jb2wuVHJhbnNmZXJDb250cmFjdC5kZWNvZGUoY29udHJhY3RCeXRlcyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVGhlcmUgd2FzIGFuIGVycm9yIGRlY29kaW5nIHRoZSB0cmFuc2ZlciBjb250cmFjdCBpbiB0aGUgdHJhbnNhY3Rpb24uJyk7XG4gIH1cblxuICBpZiAoIXRyYW5zZmVyQ29udHJhY3Qub3duZXJBZGRyZXNzKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ093bmVyIGFkZHJlc3MgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyB0cmFuc2ZlciBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGlmICghdHJhbnNmZXJDb250cmFjdC50b0FkZHJlc3MpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignRGVzdGluYXRpb24gYWRkcmVzcyBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHRyYW5zZmVyIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKCF0cmFuc2ZlckNvbnRyYWN0Lmhhc093blByb3BlcnR5KCdhbW91bnQnKSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdBbW91bnQgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyB0cmFuc2ZlciBjb250cmFjdC4nKTtcbiAgfVxuXG4gIC8vIGRlc2VyaWFsaXplIGF0dHJpYnV0ZXNcbiAgY29uc3Qgb3duZXJfYWRkcmVzcyA9IGdldEJhc2U1OEFkZHJlc3NGcm9tQnl0ZUFycmF5KFxuICAgIGdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKEJ1ZmZlci5mcm9tKHRyYW5zZmVyQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuICBjb25zdCB0b19hZGRyZXNzID0gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MoQnVmZmVyLmZyb20odHJhbnNmZXJDb250cmFjdC50b0FkZHJlc3MsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JykpXG4gICk7XG4gIGNvbnN0IGFtb3VudCA9IHRyYW5zZmVyQ29udHJhY3QuYW1vdW50O1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgYW1vdW50OiBOdW1iZXIoYW1vdW50KSxcbiAgICAgICAgICBvd25lcl9hZGRyZXNzLFxuICAgICAgICAgIHRvX2FkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogRGVzZXJpYWxpemUgdGhlIHNlZ21lbnQgb2YgdGhlIHR4SGV4IGNvcnJlc3BvbmRpbmcgd2l0aCB0cmlnZ2VyIHNtYXJ0IGNvbnRyYWN0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFxuICogQHJldHVybnMge0FjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVUcmlnZ2VyU21hcnRDb250cmFjdChiYXNlNjQ6IHN0cmluZyk6IFRyaWdnZXJTbWFydENvbnRyYWN0W10ge1xuICBsZXQgY29udHJhY3RDYWxsRGVjb2RlZDtcbiAgdHJ5IHtcbiAgICBjb250cmFjdENhbGxEZWNvZGVkID0gcHJvdG9jb2wuVHJpZ2dlclNtYXJ0Q29udHJhY3QuZGVjb2RlKEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2Jhc2U2NCcpKS50b0pTT04oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdUaGVyZSB3YXMgYW4gZXJyb3IgZGVjb2RpbmcgdGhlIGNvbnRyYWN0IGNhbGwgaW4gdGhlIHRyYW5zYWN0aW9uLicpO1xuICB9XG5cbiAgaWYgKCFjb250cmFjdENhbGxEZWNvZGVkLm93bmVyQWRkcmVzcykge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdPd25lciBhZGRyZXNzIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgY29udHJhY3QgY2FsbC4nKTtcbiAgfVxuXG4gIGlmICghY29udHJhY3RDYWxsRGVjb2RlZC5jb250cmFjdEFkZHJlc3MpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignRGVzdGluYXRpb24gY29udHJhY3QgYWRkcmVzcyBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGNvbnRyYWN0IGNhbGwuJyk7XG4gIH1cblxuICBpZiAoIWNvbnRyYWN0Q2FsbERlY29kZWQuZGF0YSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdEYXRhIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgY29udHJhY3QgY2FsbC4nKTtcbiAgfVxuXG4gIC8vIGRlc2VyaWFsaXplIGF0dHJpYnV0ZXNcbiAgY29uc3Qgb3duZXJfYWRkcmVzcyA9IGdldEJhc2U1OEFkZHJlc3NGcm9tQnl0ZUFycmF5KFxuICAgIGdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKEJ1ZmZlci5mcm9tKGNvbnRyYWN0Q2FsbERlY29kZWQub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuICBjb25zdCBjb250cmFjdF9hZGRyZXNzID0gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MoQnVmZmVyLmZyb20oY29udHJhY3RDYWxsRGVjb2RlZC5jb250cmFjdEFkZHJlc3MsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JykpXG4gICk7XG4gIGNvbnN0IGRhdGEgPSBjb250cmFjdENhbGxEZWNvZGVkLmRhdGE7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICBvd25lcl9hZGRyZXNzLFxuICAgICAgICAgIGNvbnRyYWN0X2FkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogRGVzZXJpYWxpemUgdGhlIHNlZ21lbnQgb2YgdGhlIHR4SGV4IGNvcnJlc3BvbmRpbmcgd2l0aCB0aGUgZGV0YWlscyBvZiB0aGUgY29udHJhY3Qgd2hpY2ggdXBkYXRlc1xuICogYWNjb3VudCBwZXJtaXNzaW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFxuICogQHJldHVybnMge0FjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVBY2NvdW50UGVybWlzc2lvblVwZGF0ZUNvbnRyYWN0KGJhc2U2NDogc3RyaW5nKTogQWNjb3VudFBlcm1pc3Npb25VcGRhdGVDb250cmFjdCB7XG4gIGNvbnN0IGFjY291bnRVcGRhdGVDb250cmFjdCA9IHByb3RvY29sLkFjY291bnRQZXJtaXNzaW9uVXBkYXRlQ29udHJhY3QuZGVjb2RlKEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2Jhc2U2NCcpKS50b0pTT04oKTtcbiAgYXNzZXJ0KGFjY291bnRVcGRhdGVDb250cmFjdC5vd25lckFkZHJlc3MpO1xuICBhc3NlcnQoYWNjb3VudFVwZGF0ZUNvbnRyYWN0Lm93bmVyKTtcbiAgYXNzZXJ0KGFjY291bnRVcGRhdGVDb250cmFjdC5oYXNPd25Qcm9wZXJ0eSgnYWN0aXZlcycpKTtcblxuICBjb25zdCBvd25lckFkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbShhY2NvdW50VXBkYXRlQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuICBjb25zdCBvd25lcjogUGVybWlzc2lvbiA9IGNyZWF0ZVBlcm1pc3Npb24oYWNjb3VudFVwZGF0ZUNvbnRyYWN0Lm93bmVyKTtcbiAgbGV0IHdpdG5lc3M6IFBlcm1pc3Npb24gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIGlmIChhY2NvdW50VXBkYXRlQ29udHJhY3Qud2l0bmVzcykge1xuICAgIHdpdG5lc3MgPSBjcmVhdGVQZXJtaXNzaW9uKGFjY291bnRVcGRhdGVDb250cmFjdC53aXRuZXNzKTtcbiAgfVxuICBjb25zdCBhY3RpdmVMaXN0ID0gYWNjb3VudFVwZGF0ZUNvbnRyYWN0LmFjdGl2ZXMubWFwKChhY3RpdmUpID0+IGNyZWF0ZVBlcm1pc3Npb24oYWN0aXZlKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBvd25lckFkZHJlc3MsXG4gICAgb3duZXIsXG4gICAgd2l0bmVzcyxcbiAgICBhY3RpdmVzOiBhY3RpdmVMaXN0LFxuICB9O1xufVxuXG4vKipcbiAqIERlc2VyaWFsaXplIHRoZSBzZWdtZW50IG9mIHRoZSB0eEhleCBjb3JyZXNwb25kaW5nIHdpdGggZnJlZXplIGJhbGFuY2UgY29udHJhY3RcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZTY0IC0gVGhlIGJhc2U2NCBlbmNvZGVkIGNvbnRyYWN0IGRhdGFcbiAqIEByZXR1cm5zIHtGcmVlemVCYWxhbmNlQ29udHJhY3RQYXJhbWV0ZXJbXX0gLSBBcnJheSBjb250YWluaW5nIHRoZSBkZWNvZGVkIGZyZWV6ZSBjb250cmFjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlRnJlZXplQmFsYW5jZVYyQ29udHJhY3QoYmFzZTY0OiBzdHJpbmcpOiBGcmVlemVCYWxhbmNlQ29udHJhY3RQYXJhbWV0ZXJbXSB7XG4gIGxldCBmcmVlemVDb250cmFjdDogRnJlZXplQ29udHJhY3REZWNvZGVkO1xuICB0cnkge1xuICAgIGZyZWV6ZUNvbnRyYWN0ID0gcHJvdG9jb2wuRnJlZXplQmFsYW5jZVYyQ29udHJhY3QuZGVjb2RlKEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2Jhc2U2NCcpKS50b0pTT04oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdUaGVyZSB3YXMgYW4gZXJyb3IgZGVjb2RpbmcgdGhlIGZyZWV6ZSBjb250cmFjdCBpbiB0aGUgdHJhbnNhY3Rpb24uJyk7XG4gIH1cblxuICBpZiAoIWZyZWV6ZUNvbnRyYWN0Lm93bmVyQWRkcmVzcykge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdPd25lciBhZGRyZXNzIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgZnJlZXplIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKGZyZWV6ZUNvbnRyYWN0LnJlc291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUmVzb3VyY2UgdHlwZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGZyZWV6ZSBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGlmIChmcmVlemVDb250cmFjdC5mcm96ZW5CYWxhbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignRnJvemVuIGJhbGFuY2UgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyBmcmVlemUgY29udHJhY3QuJyk7XG4gIH1cblxuICBjb25zdCBvd25lcl9hZGRyZXNzID0gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MoQnVmZmVyLmZyb20oZnJlZXplQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIGNvbnN0IHJlc291cmNlVmFsdWUgPSBmcmVlemVDb250cmFjdC5yZXNvdXJjZSA9PT0gMCA/IFRyb25SZXNvdXJjZS5CQU5EV0lEVEggOiBUcm9uUmVzb3VyY2UuRU5FUkdZO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcmVzb3VyY2U6IHJlc291cmNlVmFsdWUsXG4gICAgICAgICAgZnJvemVuX2JhbGFuY2U6IE51bWJlcihmcmVlemVDb250cmFjdC5mcm96ZW5CYWxhbmNlKSxcbiAgICAgICAgICBvd25lcl9hZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIERlc2VyaWFsaXplIHRoZSBzZWdtZW50IG9mIHRoZSB0eEhleCBjb3JyZXNwb25kaW5nIHdpdGggdm90ZSB3aXRuZXNzIGNvbnRyYWN0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NCAtIFRoZSBiYXNlNjQgZW5jb2RlZCBjb250cmFjdCBkYXRhXG4gKiBAcmV0dXJucyB7Vm90ZVdpdG5lc3NDb250cmFjdFBhcmFtZXRlcltdfSAtIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRlY29kZWQgdm90ZSB3aXRuZXNzIGNvbnRyYWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVWb3RlV2l0bmVzc0NvbnRyYWN0KGJhc2U2NDogc3RyaW5nKTogVm90ZVdpdG5lc3NDb250cmFjdFBhcmFtZXRlcltdIHtcbiAgbGV0IHZvdGVDb250cmFjdDogVm90ZUNvbnRyYWN0RGVjb2RlZDtcbiAgdHJ5IHtcbiAgICB2b3RlQ29udHJhY3QgPSBwcm90b2NvbC5Wb3RlV2l0bmVzc0NvbnRyYWN0LmRlY29kZShCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKSkudG9KU09OKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVGhlcmUgd2FzIGFuIGVycm9yIGRlY29kaW5nIHRoZSB2b3RlIGNvbnRyYWN0IGluIHRoZSB0cmFuc2FjdGlvbi4nKTtcbiAgfVxuXG4gIGlmICghdm90ZUNvbnRyYWN0Lm93bmVyQWRkcmVzcykge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdPd25lciBhZGRyZXNzIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgdm90ZSBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGlmICghQXJyYXkuaXNBcnJheSh2b3RlQ29udHJhY3Qudm90ZXMpIHx8IHZvdGVDb250cmFjdC52b3Rlcy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVm90ZXMgZG8gbm90IGV4aXN0IG9yIGFyZSBlbXB0eSBpbiB0aGlzIHZvdGUgY29udHJhY3QuJyk7XG4gIH1cblxuICAvLyBkZXNlcmlhbGl6ZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IG93bmVyX2FkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbSh2b3RlQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIGludGVyZmFjZSBWb3RlSXRlbSB7XG4gICAgdm90ZUFkZHJlc3M/OiBzdHJpbmc7XG4gICAgdm90ZUNvdW50Pzogc3RyaW5nIHwgbnVtYmVyO1xuICB9XG5cbiAgY29uc3Qgdm90ZXMgPSB2b3RlQ29udHJhY3Qudm90ZXMubWFwKCh2b3RlOiBWb3RlSXRlbSkgPT4ge1xuICAgIGlmICghdm90ZS52b3RlQWRkcmVzcykge1xuICAgICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ1ZvdGUgYWRkcmVzcyBpcyBtaXNzaW5nIGluIG9uZSBvZiB0aGUgdm90ZXMuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHZvdGVfYWRkcmVzczogZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgICAgIGdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKEJ1ZmZlci5mcm9tKHZvdGUudm90ZUFkZHJlc3MsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JykpXG4gICAgICApLFxuICAgICAgdm90ZV9jb3VudDogTnVtYmVyKHZvdGUudm90ZUNvdW50IHx8IDApLFxuICAgIH07XG4gIH0pO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgb3duZXJfYWRkcmVzcyxcbiAgICAgICAgICB2b3RlcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiBEZXNlcmlhbGl6ZSB0aGUgc2VnbWVudCBvZiB0aGUgdHhIZXggY29ycmVzcG9uZGluZyB3aXRoIHVuZnJlZXplIGJhbGFuY2UgY29udHJhY3RcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZTY0IC0gVGhlIGJhc2U2NCBlbmNvZGVkIGNvbnRyYWN0IGRhdGFcbiAqIEByZXR1cm5zIHtVbmZyZWV6ZUJhbGFuY2VDb250cmFjdFBhcmFtZXRlcltdfSAtIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRlY29kZWQgdW5mcmVlemUgY29udHJhY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVVuZnJlZXplQmFsYW5jZVYyQ29udHJhY3QoYmFzZTY0OiBzdHJpbmcpOiBVbmZyZWV6ZUJhbGFuY2VDb250cmFjdFBhcmFtZXRlcltdIHtcbiAgbGV0IHVuZnJlZXplQ29udHJhY3Q6IFVuZnJlZXplQ29udHJhY3REZWNvZGVkO1xuICB0cnkge1xuICAgIHVuZnJlZXplQ29udHJhY3QgPSBwcm90b2NvbC5VbmZyZWV6ZUJhbGFuY2VWMkNvbnRyYWN0LmRlY29kZShCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKSkudG9KU09OKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVGhlcmUgd2FzIGFuIGVycm9yIGRlY29kaW5nIHRoZSB1bmZyZWV6ZSBjb250cmFjdCBpbiB0aGUgdHJhbnNhY3Rpb24uJyk7XG4gIH1cblxuICBpZiAoIXVuZnJlZXplQ29udHJhY3Qub3duZXJBZGRyZXNzKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ093bmVyIGFkZHJlc3MgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyB1bmZyZWV6ZSBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGlmICh1bmZyZWV6ZUNvbnRyYWN0LnJlc291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUmVzb3VyY2UgdHlwZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHVuZnJlZXplIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKHVuZnJlZXplQ29udHJhY3QudW5mcmVlemVCYWxhbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVW5mcmVlemUgYmFsYW5jZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHVuZnJlZXplIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgLy8gZGVzZXJpYWxpemUgYXR0cmlidXRlc1xuICBjb25zdCBvd25lcl9hZGRyZXNzID0gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MoQnVmZmVyLmZyb20odW5mcmVlemVDb250cmFjdC5vd25lckFkZHJlc3MsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JykpXG4gICk7XG5cbiAgLy8gQ29udmVydCBSZXNvdXJjZUNvZGUgZW51bSB2YWx1ZSB0byBzdHJpbmcgcmVzb3VyY2UgbmFtZVxuICBjb25zdCByZXNvdXJjZVZhbHVlID0gdW5mcmVlemVDb250cmFjdC5yZXNvdXJjZTtcbiAgY29uc3QgcmVzb3VyY2VFbnVtID0gcmVzb3VyY2VWYWx1ZSA9PT0gcHJvdG9jb2wuUmVzb3VyY2VDb2RlLkJBTkRXSURUSCA/IFRyb25SZXNvdXJjZS5CQU5EV0lEVEggOiBUcm9uUmVzb3VyY2UuRU5FUkdZO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcmVzb3VyY2U6IHJlc291cmNlRW51bSxcbiAgICAgICAgICB1bmZyZWV6ZV9iYWxhbmNlOiBOdW1iZXIodW5mcmVlemVDb250cmFjdC51bmZyZWV6ZUJhbGFuY2UpLFxuICAgICAgICAgIG93bmVyX2FkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogRGVzZXJpYWxpemUgdGhlIHNlZ21lbnQgb2YgdGhlIHR4SGV4IGNvcnJlc3BvbmRpbmcgd2l0aCB3aXRoZHJhdyBiYWxhbmNlIGNvbnRyYWN0XG4gKiBEZWNvZGVkIGNvbnRyYWN0IGlzIHRoZSBzYW1lIGFzIHdpdGhkcmF3IGV4cGlyZSB1bmZyZWV6ZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjQgLSBUaGUgYmFzZTY0IGVuY29kZWQgY29udHJhY3QgZGF0YVxuICogQHJldHVybnMge1dpdGhkcmF3RXhwaXJlVW5mcmVlemVDb250cmFjdFBhcmFtZXRlcltdfSAtIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRlY29kZWQgd2l0aGRyYXcgY29udHJhY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVdpdGhkcmF3QmFsYW5jZUNvbnRyYWN0KGJhc2U2NDogc3RyaW5nKTogV2l0aGRyYXdFeHBpcmVVbmZyZWV6ZUNvbnRyYWN0UGFyYW1ldGVyW10ge1xuICBsZXQgd2l0aGRyYXdDb250cmFjdDogV2l0aGRyYXdDb250cmFjdERlY29kZWQ7XG4gIHRyeSB7XG4gICAgd2l0aGRyYXdDb250cmFjdCA9IHByb3RvY29sLldpdGhkcmF3QmFsYW5jZUNvbnRyYWN0LmRlY29kZShCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKSkudG9KU09OKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignVGhlcmUgd2FzIGFuIGVycm9yIGRlY29kaW5nIHRoZSB3aXRoZHJhdyBjb250cmFjdCBpbiB0aGUgdHJhbnNhY3Rpb24uJyk7XG4gIH1cblxuICBpZiAoIXdpdGhkcmF3Q29udHJhY3Qub3duZXJBZGRyZXNzKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ093bmVyIGFkZHJlc3MgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyB3aXRoZHJhdyBjb250cmFjdC4nKTtcbiAgfVxuXG4gIC8vIGRlc2VyaWFsaXplIGF0dHJpYnV0ZXNcbiAgY29uc3Qgb3duZXJfYWRkcmVzcyA9IGdldEJhc2U1OEFkZHJlc3NGcm9tQnl0ZUFycmF5KFxuICAgIGdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKEJ1ZmZlci5mcm9tKHdpdGhkcmF3Q29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgb3duZXJfYWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiBEZXNlcmlhbGl6ZSB0aGUgc2VnbWVudCBvZiB0aGUgdHhIZXggY29ycmVzcG9uZGluZyB3aXRoIHdpdGhkcmF3IGV4cGlyZSB1bmZyZWV6ZSBjb250cmFjdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjQgLSBUaGUgYmFzZTY0IGVuY29kZWQgY29udHJhY3QgZGF0YVxuICogQHJldHVybnMge1dpdGhkcmF3RXhwaXJlVW5mcmVlemVDb250cmFjdFBhcmFtZXRlcltdfSAtIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRlY29kZWQgd2l0aGRyYXcgY29udHJhY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVdpdGhkcmF3RXhwaXJlVW5mcmVlemVDb250cmFjdChiYXNlNjQ6IHN0cmluZyk6IFdpdGhkcmF3RXhwaXJlVW5mcmVlemVDb250cmFjdFBhcmFtZXRlcltdIHtcbiAgbGV0IHdpdGhkcmF3Q29udHJhY3Q6IFdpdGhkcmF3Q29udHJhY3REZWNvZGVkO1xuICB0cnkge1xuICAgIHdpdGhkcmF3Q29udHJhY3QgPSBwcm90b2NvbC5XaXRoZHJhd0JhbGFuY2VDb250cmFjdC5kZWNvZGUoQnVmZmVyLmZyb20oYmFzZTY0LCAnYmFzZTY0JykpLnRvSlNPTigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciBkZWNvZGluZyB0aGUgd2l0aGRyYXcgY29udHJhY3QgaW4gdGhlIHRyYW5zYWN0aW9uLicpO1xuICB9XG5cbiAgaWYgKCF3aXRoZHJhd0NvbnRyYWN0Lm93bmVyQWRkcmVzcykge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdPd25lciBhZGRyZXNzIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgd2l0aGRyYXcgY29udHJhY3QuJyk7XG4gIH1cblxuICAvLyBkZXNlcmlhbGl6ZSBhdHRyaWJ1dGVzXG4gIGNvbnN0IG93bmVyX2FkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbSh3aXRoZHJhd0NvbnRyYWN0Lm93bmVyQWRkcmVzcywgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSlcbiAgKTtcblxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHBhcmFtZXRlcjoge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIG93bmVyX2FkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogRGVzZXJpYWxpemUgdGhlIHNlZ21lbnQgb2YgdGhlIHR4SGV4IGNvcnJlc3BvbmRpbmcgd2l0aCBkZWxlZ2F0ZSByZXNvdXJjZSBjb250cmFjdFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjQgLSBUaGUgYmFzZTY0IGVuY29kZWQgY29udHJhY3QgZGF0YVxuICogQHJldHVybnMge1Jlc291cmNlTWFuYWdlbWVudENvbnRyYWN0UGFyYW1ldGVyW119IC0gQXJyYXkgY29udGFpbmluZyB0aGUgZGVjb2RlZCBkZWxlZ2F0ZSByZXNvdXJjZSBjb250cmFjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlRGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0KGJhc2U2NDogc3RyaW5nKTogUmVzb3VyY2VNYW5hZ2VtZW50Q29udHJhY3RQYXJhbWV0ZXJbXSB7XG4gIGxldCBkZWxlZ2F0ZVJlc291cmNlQ29udHJhY3Q6IFJlc291cmNlTWFuYWdlbWVudENvbnRyYWN0RGVjb2RlZDtcbiAgdHJ5IHtcbiAgICBkZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QgPSBwcm90b2NvbC5EZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QuZGVjb2RlKEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2Jhc2U2NCcpKS50b0pTT04oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdUaGVyZSB3YXMgYW4gZXJyb3IgZGVjb2RpbmcgdGhlIGRlbGVnYXRlIHJlc291cmNlIGNvbnRyYWN0IGluIHRoZSB0cmFuc2FjdGlvbi4nKTtcbiAgfVxuXG4gIGlmICghZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0Lm93bmVyQWRkcmVzcykge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdPd25lciBhZGRyZXNzIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgZGVsZWdhdGUgcmVzb3VyY2UgY29udHJhY3QuJyk7XG4gIH1cblxuICBpZiAoIWRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5yZWNlaXZlckFkZHJlc3MpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUmVjZWl2ZXIgYWRkcmVzcyBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGRlbGVnYXRlIHJlc291cmNlIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKGRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5yZXNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ1Jlc291cmNlIHR5cGUgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyBkZWxlZ2F0ZSByZXNvdXJjZSBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGlmIChkZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QuYmFsYW5jZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ0JhbGFuY2UgZG9lcyBub3QgZXhpc3QgaW4gdGhpcyBkZWxlZ2F0ZSByZXNvdXJjZSBjb250cmFjdC4nKTtcbiAgfVxuXG4gIGNvbnN0IG93bmVyX2FkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbShkZWxlZ2F0ZVJlc291cmNlQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIGNvbnN0IHJlY2VpdmVyX2FkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbShkZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QucmVjZWl2ZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIGNvbnN0IHJlc291cmNlVmFsdWUgPSAhZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0LnJlc291cmNlID8gVHJvblJlc291cmNlLkJBTkRXSURUSCA6IFRyb25SZXNvdXJjZS5FTkVSR1k7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBwYXJhbWV0ZXI6IHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICByZXNvdXJjZTogcmVzb3VyY2VWYWx1ZSxcbiAgICAgICAgICBiYWxhbmNlOiBOdW1iZXIoZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0LmJhbGFuY2UpLFxuICAgICAgICAgIG93bmVyX2FkZHJlc3MsXG4gICAgICAgICAgcmVjZWl2ZXJfYWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiBEZXNlcmlhbGl6ZSB0aGUgc2VnbWVudCBvZiB0aGUgdHhIZXggY29ycmVzcG9uZGluZyB3aXRoIHVuZGVsZWdhdGUgcmVzb3VyY2UgY29udHJhY3RcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZTY0IC0gVGhlIGJhc2U2NCBlbmNvZGVkIGNvbnRyYWN0IGRhdGFcbiAqIEByZXR1cm5zIHtSZXNvdXJjZU1hbmFnZW1lbnRDb250cmFjdFBhcmFtZXRlcltdfSAtIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRlY29kZWQgdW5kZWxlZ2F0ZSByZXNvdXJjZSBjb250cmFjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlVW5EZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QoYmFzZTY0OiBzdHJpbmcpOiBSZXNvdXJjZU1hbmFnZW1lbnRDb250cmFjdFBhcmFtZXRlcltdIHtcbiAgbGV0IHVuZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0OiBSZXNvdXJjZU1hbmFnZW1lbnRDb250cmFjdERlY29kZWQ7XG4gIHRyeSB7XG4gICAgdW5kZWxlZ2F0ZVJlc291cmNlQ29udHJhY3QgPSBwcm90b2NvbC5VbkRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5kZWNvZGUoQnVmZmVyLmZyb20oYmFzZTY0LCAnYmFzZTY0JykpLnRvSlNPTigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciBkZWNvZGluZyB0aGUgZGVsZWdhdGUgcmVzb3VyY2UgY29udHJhY3QgaW4gdGhlIHRyYW5zYWN0aW9uLicpO1xuICB9XG5cbiAgaWYgKCF1bmRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5vd25lckFkZHJlc3MpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignT3duZXIgYWRkcmVzcyBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGRlbGVnYXRlIHJlc291cmNlIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKCF1bmRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5yZWNlaXZlckFkZHJlc3MpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUmVjZWl2ZXIgYWRkcmVzcyBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGRlbGVnYXRlIHJlc291cmNlIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKHVuZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0LnJlc291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUmVzb3VyY2UgdHlwZSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGRlbGVnYXRlIHJlc291cmNlIGNvbnRyYWN0LicpO1xuICB9XG5cbiAgaWYgKHVuZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0LmJhbGFuY2UgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdCYWxhbmNlIGRvZXMgbm90IGV4aXN0IGluIHRoaXMgZGVsZWdhdGUgcmVzb3VyY2UgY29udHJhY3QuJyk7XG4gIH1cblxuICBjb25zdCBvd25lcl9hZGRyZXNzID0gZ2V0QmFzZTU4QWRkcmVzc0Zyb21CeXRlQXJyYXkoXG4gICAgZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MoQnVmZmVyLmZyb20odW5kZWxlZ2F0ZVJlc291cmNlQ29udHJhY3Qub3duZXJBZGRyZXNzLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpKVxuICApO1xuXG4gIGNvbnN0IHJlY2VpdmVyX2FkZHJlc3MgPSBnZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShcbiAgICBnZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhCdWZmZXIuZnJvbSh1bmRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5yZWNlaXZlckFkZHJlc3MsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JykpXG4gICk7XG5cbiAgY29uc3QgcmVzb3VyY2VWYWx1ZSA9ICF1bmRlbGVnYXRlUmVzb3VyY2VDb250cmFjdC5yZXNvdXJjZSA/IFRyb25SZXNvdXJjZS5CQU5EV0lEVEggOiBUcm9uUmVzb3VyY2UuRU5FUkdZO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgcmVzb3VyY2U6IHJlc291cmNlVmFsdWUsXG4gICAgICAgICAgYmFsYW5jZTogTnVtYmVyKHVuZGVsZWdhdGVSZXNvdXJjZUNvbnRyYWN0LmJhbGFuY2UpLFxuICAgICAgICAgIG93bmVyX2FkZHJlc3MsXG4gICAgICAgICAgcmVjZWl2ZXJfYWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gcmF3XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBlcm1pc3Npb24ocmF3OiB7IHBlcm1pc3Npb25OYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0pOiBQZXJtaXNzaW9uIHtcbiAgbGV0IHBlcm1pc3Npb25UeXBlOiBQZXJtaXNzaW9uVHlwZTtcbiAgY29uc3QgcGVybWlzc2lvbiA9IHJhdy5wZXJtaXNzaW9uTmFtZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgaWYgKHBlcm1pc3Npb24gPT09ICdvd25lcicpIHtcbiAgICBwZXJtaXNzaW9uVHlwZSA9IFBlcm1pc3Npb25UeXBlLk93bmVyO1xuICB9IGVsc2UgaWYgKHBlcm1pc3Npb24gPT09ICd3aXRuZXNzJykge1xuICAgIHBlcm1pc3Npb25UeXBlID0gUGVybWlzc2lvblR5cGUuV2l0bmVzcztcbiAgfSBlbHNlIGlmIChwZXJtaXNzaW9uLnN1YnN0cigwLCA2KSA9PT0gJ2FjdGl2ZScpIHtcbiAgICBwZXJtaXNzaW9uVHlwZSA9IFBlcm1pc3Npb25UeXBlLkFjdGl2ZTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignUGVybWlzc2lvbiB0eXBlIG5vdCBwYXJzZWFibGUuJyk7XG4gIH1cbiAgcmV0dXJuIHsgdHlwZTogcGVybWlzc2lvblR5cGUsIHRocmVzaG9sZDogcmF3LnRocmVzaG9sZCB9O1xufVxuXG4vKipcbiAqIEBwYXJhbSByYXdUcmFuc2FjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFR4SnNvblN0cmluZyhyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHRyYW5zYWN0aW9uID0gSlNPTi5wYXJzZShyYXdUcmFuc2FjdGlvbik7XG4gIHJldHVybiB0cmFuc2FjdGlvbi5oYXNPd25Qcm9wZXJ0eSgndHhJRCcpO1xufVxuXG4vKipcbiAqIFJldHVybnMgd2hldGhlciB0aGUgcHJvdmlkZWQgcmF3IHRyYW5zYWN0aW9uIGFjY29tbW9kYXRlcyB0byBiaXRnbydzIHByZWZlcnJlZCBmb3JtYXRcbiAqXG4gKiBAcGFyYW0ge2FueX0gcmF3VHJhbnNhY3Rpb24gLSBUaGUgcmF3IHRyYW5zYWN0aW9uIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIHtib29sZWFufSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRSYXdUcmFuc2FjdGlvbkZvcm1hdChyYXdUcmFuc2FjdGlvbjogYW55KTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgcmF3VHJhbnNhY3Rpb24gPT09ICdzdHJpbmcnICYmIChpc1ZhbGlkSGV4KHJhd1RyYW5zYWN0aW9uKSB8fCBpc1ZhbGlkVHhKc29uU3RyaW5nKHJhd1RyYW5zYWN0aW9uKSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBoZXggc3RyaW5nIG9mIHRoZSBnaXZlbiBidWZmZXJcbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IFVpbnQ4QXJyYXl9IGJ1ZmZlciAtIHRoZSBidWZmZXIgdG8gYmUgY29udmVydGVkIHRvIGhleFxuICogQHJldHVybnMge3N0cmluZ30gLSB0aGUgaGV4IHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0hleChidWZmZXI6IEJ1ZmZlciB8IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gaGV4LmVuY29kZShidWZmZXIsIHRydWUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBLZWNjYWstMjU2IGVuY29kZWQgc3RyaW5nIG9mIHRoZSBwYXJhbWV0ZXJzXG4gKlxuICogQHBhcmFtIHR5cGVzIC0gc3RyaW5ncyBkZXNjcmliaW5nIHRoZSB0eXBlcyBvZiB0aGUgdmFsdWVzXG4gKiBAcGFyYW0gdmFsdWVzIC0gdmFsdWUgdG8gZW5jb2RlXG4gKiBAcGFyYW0gbWV0aG9kSWQgLSB0aGUgZmlyc3QgNCBieXRlcyBvZiB0aGUgZnVuY3Rpb24gc2VsZWN0b3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZURhdGFQYXJhbXModHlwZXM6IHN0cmluZ1tdLCB2YWx1ZXM6IGFueVtdLCBtZXRob2RJZD86IHN0cmluZyk6IHN0cmluZyB7XG4gIHR5cGVzLmZvckVhY2goKHR5cGUsIGluZGV4KSA9PiB7XG4gICAgaWYgKHR5cGUgPT0gJ2FkZHJlc3MnKSB7XG4gICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWVzW2luZGV4XS5yZXBsYWNlKEFERFJFU1NfUFJFRklYX1JFR0VYLCAnMHgnKTtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGFiaUNvZGVyID0gbmV3IEFiaUNvZGVyKCk7XG4gIGxldCBkYXRhO1xuICB0cnkge1xuICAgIGRhdGEgPSBhYmlDb2Rlci5lbmNvZGUodHlwZXMsIHZhbHVlcyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcihgVGhlcmUgd2FzIGFuIGVycm9yIGVuY29kaW5nIHRoZSBkYXRhIHBhcmFtcy4gRXJyb3IgPSAke0pTT04uc3RyaW5naWZ5KGUpfWApO1xuICB9XG4gIGlmIChtZXRob2RJZCkge1xuICAgIHJldHVybiBoZXhDb25jYXQoW21ldGhvZElkLCBkYXRhXSkucmVwbGFjZSgvXigweCkvLCAnJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRhdGEucmVwbGFjZSgvXigweCkvLCAnJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkZWNvZGVkIHZhbHVlcyBhY2NvcmRpbmcgdG8gdGhlIGFycmF5IG9mIHR5cGVzXG4gKlxuICogQHBhcmFtIHR5cGVzIC0gc3RyaW5ncyBkZXNjcmliaW5nIHRoZSB0eXBlcyBvZiB0aGUgdmFsdWVzXG4gKiBAcGFyYW0gZGF0YSAtIGVuY29kZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVEYXRhUGFyYW1zKHR5cGVzOiBzdHJpbmdbXSwgZGF0YTogc3RyaW5nKTogYW55W10ge1xuICBjb25zdCBhYmlDb2RlciA9IG5ldyBBYmlDb2RlcigpO1xuICBkYXRhID0gJzB4JyArIGRhdGEuc3Vic3RyaW5nKDgpO1xuICByZXR1cm4gYWJpQ29kZXIuZGVjb2RlKHR5cGVzLCBkYXRhKS5yZWR1Y2UoKG9iaiwgYXJnLCBpbmRleCkgPT4ge1xuICAgIGlmICh0eXBlc1tpbmRleF0gPT0gJ2FkZHJlc3MnKSBhcmcgPSBBRERSRVNTX1BSRUZJWCArIGFyZy5zdWJzdHIoMikudG9Mb3dlckNhc2UoKTtcbiAgICBvYmoucHVzaChhcmcpO1xuICAgIHJldHVybiBvYmo7XG4gIH0sIFtdKTtcbn1cbiJdfQ==
|