@bitgo-beta/sdk-coin-flrp 1.0.1-beta.32 → 1.0.1-beta.320
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/dist/src/flrp.d.ts +9 -16
- package/dist/src/flrp.d.ts.map +1 -1
- package/dist/src/flrp.js +49 -75
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -2
- package/dist/src/lib/ExportInCTxBuilder.d.ts +51 -0
- package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ExportInCTxBuilder.js +188 -0
- package/dist/src/lib/ExportInPTxBuilder.d.ts +47 -0
- package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ExportInPTxBuilder.js +273 -0
- package/dist/src/lib/ImportInCTxBuilder.d.ts +48 -0
- package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ImportInCTxBuilder.js +215 -0
- package/dist/src/lib/ImportInPTxBuilder.d.ts +33 -0
- package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/ImportInPTxBuilder.js +180 -0
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts +18 -16
- package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/atomicInCTransactionBuilder.js +38 -36
- package/dist/src/lib/atomicTransactionBuilder.d.ts +42 -76
- package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/atomicTransactionBuilder.js +141 -218
- package/dist/src/lib/iface.d.ts +38 -61
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +13 -14
- package/dist/src/lib/index.d.ts +5 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +12 -2
- package/dist/src/lib/keyPair.d.ts +5 -5
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +17 -9
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +43 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/permissionlessValidatorTxBuilder.js +132 -0
- package/dist/src/lib/transaction.d.ts +14 -69
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +258 -199
- package/dist/src/lib/transactionBuilder.d.ts +107 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilder.js +210 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts +50 -30
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +129 -72
- package/dist/src/lib/utils.d.ts +74 -147
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +235 -324
- package/dist/test/resources/account.d.ts +51 -0
- package/dist/test/resources/account.d.ts.map +1 -0
- package/dist/test/resources/account.js +54 -0
- package/dist/test/resources/transactionData/exportInC.d.ts +20 -0
- package/dist/test/resources/transactionData/exportInC.d.ts.map +1 -0
- package/dist/test/resources/transactionData/exportInC.js +34 -0
- package/dist/test/resources/transactionData/exportInP.d.ts +69 -0
- package/dist/test/resources/transactionData/exportInP.d.ts.map +1 -0
- package/dist/test/resources/transactionData/exportInP.js +140 -0
- package/dist/test/resources/transactionData/importInC.d.ts +27 -0
- package/dist/test/resources/transactionData/importInC.d.ts.map +1 -0
- package/dist/test/resources/transactionData/importInC.js +44 -0
- package/dist/test/resources/transactionData/importInP.d.ts +35 -0
- package/dist/test/resources/transactionData/importInP.d.ts.map +1 -0
- package/dist/test/resources/transactionData/importInP.js +58 -0
- package/dist/test/unit/flrp.js +449 -68
- package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportInCTxBuilder.js +166 -0
- package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/exportInPTxBuilder.js +121 -0
- package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importInCTxBuilder.js +47 -0
- package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
- package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/lib/importInPTxBuilder.js +73 -0
- package/dist/test/unit/lib/keyPair.d.ts +2 -0
- package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
- package/dist/test/unit/lib/keyPair.js +158 -0
- package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
- package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
- package/dist/test/unit/lib/signFlowTestSuit.js +89 -0
- package/dist/test/unit/lib/utils.js +507 -207
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -10
- package/.eslintignore +0 -5
- package/.eslintrc.json +0 -7
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -0
- package/dist/src/iface.d.ts +0 -25
- package/dist/src/iface.d.ts.map +0 -1
- package/dist/src/iface.js +0 -3
- package/dist/src/lib/constants.d.ts +0 -11
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -17
- package/dist/src/lib/errors.d.ts +0 -8
- package/dist/src/lib/errors.d.ts.map +0 -1
- package/dist/src/lib/errors.js +0 -19
- package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
- package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/exportInCTxBuilder.js +0 -170
- package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
- package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
- package/dist/src/lib/exportInPTxBuilder.js +0 -56
- package/dist/test/unit/lib/atomicTransactionBuilder.d.ts +0 -2
- package/dist/test/unit/lib/atomicTransactionBuilder.d.ts.map +0 -1
- package/dist/test/unit/lib/atomicTransactionBuilder.js +0 -222
- package/dist/test/unit/lib/exportTxBuilder.d.ts +0 -2
- package/dist/test/unit/lib/exportTxBuilder.d.ts.map +0 -1
- package/dist/test/unit/lib/exportTxBuilder.js +0 -45
- package/dist/test/unit/lib/transaction.d.ts +0 -2
- package/dist/test/unit/lib/transaction.d.ts.map +0 -1
- package/dist/test/unit/lib/transaction.js +0 -460
- package/dist/test/unit/smoke.d.ts +0 -2
- package/dist/test/unit/smoke.d.ts.map +0 -1
- package/dist/test/unit/smoke.js +0 -23
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ExportInCTxBuilder = void 0;
|
|
7
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
+
const atomicInCTransactionBuilder_1 = require("./atomicInCTransactionBuilder");
|
|
9
|
+
const flarejs_1 = require("@flarenetwork/flarejs");
|
|
10
|
+
const utils_1 = __importDefault(require("./utils"));
|
|
11
|
+
const iface_1 = require("./iface");
|
|
12
|
+
class ExportInCTxBuilder extends atomicInCTransactionBuilder_1.AtomicInCTransactionBuilder {
|
|
13
|
+
constructor(_coinConfig) {
|
|
14
|
+
super(_coinConfig);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Utxos are not required in Export Tx in C-Chain.
|
|
18
|
+
* Override utxos to prevent used by throwing a error.
|
|
19
|
+
*
|
|
20
|
+
* @param {DecodedUtxoObj[]} value ignored
|
|
21
|
+
*/
|
|
22
|
+
utxos(value) {
|
|
23
|
+
throw new sdk_core_1.BuildTransactionError('utxos are not required in Export Tx in C-Chain');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Amount is a bigint that specifies the quantity of the asset that this output owns. Must be positive.
|
|
27
|
+
* The transaction output amount add a fixed fee that will be paid upon import.
|
|
28
|
+
*
|
|
29
|
+
* @param {bigint | string} amount The withdrawal amount
|
|
30
|
+
*/
|
|
31
|
+
amount(amount) {
|
|
32
|
+
const amountBigInt = typeof amount === 'string' ? BigInt(amount) : amount;
|
|
33
|
+
this.validateAmount(amountBigInt);
|
|
34
|
+
this._amount = amountBigInt;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Set the nonce of C-Chain sender address
|
|
39
|
+
*
|
|
40
|
+
* @param {number | string} nonce - number that can be only used once
|
|
41
|
+
*/
|
|
42
|
+
nonce(nonce) {
|
|
43
|
+
const nonceBigInt = BigInt(nonce);
|
|
44
|
+
this.validateNonce(nonceBigInt);
|
|
45
|
+
this._nonce = nonceBigInt;
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Export tx target P wallet.
|
|
50
|
+
*
|
|
51
|
+
* @param pAddresses
|
|
52
|
+
*/
|
|
53
|
+
to(pAddresses) {
|
|
54
|
+
const pubKeys = Array.isArray(pAddresses) ? pAddresses : pAddresses.split('~');
|
|
55
|
+
this.transaction._to = pubKeys.map((addr) => utils_1.default.parseAddress(addr));
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
get transactionType() {
|
|
59
|
+
return sdk_core_1.TransactionType.Export;
|
|
60
|
+
}
|
|
61
|
+
initBuilder(tx, rawBytes, parsedCredentials) {
|
|
62
|
+
const baseTx = tx;
|
|
63
|
+
if (!this.verifyTxType(baseTx._type)) {
|
|
64
|
+
throw new sdk_core_1.NotSupported('Transaction cannot be parsed or has an unsupported transaction type');
|
|
65
|
+
}
|
|
66
|
+
// The outputs is a multisign P-Chain address result.
|
|
67
|
+
// It's expected to have only one output to the destination P-Chain address.
|
|
68
|
+
const outputs = baseTx.exportedOutputs;
|
|
69
|
+
if (outputs.length !== 1) {
|
|
70
|
+
throw new sdk_core_1.BuildTransactionError('Transaction can have one output');
|
|
71
|
+
}
|
|
72
|
+
const output = outputs[0];
|
|
73
|
+
if (Buffer.from(output.assetId.toBytes()).toString('hex') !== this.transaction._assetId) {
|
|
74
|
+
throw new sdk_core_1.BuildTransactionError('AssetID mismatch');
|
|
75
|
+
}
|
|
76
|
+
// The inputs is not an utxo.
|
|
77
|
+
// It's expected to have only one input from C-Chain address.
|
|
78
|
+
const inputs = baseTx.ins;
|
|
79
|
+
if (inputs.length !== 1) {
|
|
80
|
+
throw new sdk_core_1.BuildTransactionError('Transaction can have one input');
|
|
81
|
+
}
|
|
82
|
+
const input = inputs[0];
|
|
83
|
+
const transferOutput = output.output;
|
|
84
|
+
const owners = transferOutput.getOwners();
|
|
85
|
+
this.transaction._to = owners;
|
|
86
|
+
const inputAmount = input.amount.value();
|
|
87
|
+
const outputAmount = transferOutput.amount();
|
|
88
|
+
const fee = inputAmount - outputAmount;
|
|
89
|
+
this._amount = outputAmount;
|
|
90
|
+
// Store the actual fee directly (don't subtract fixedFee since buildFlareTransaction doesn't add it back)
|
|
91
|
+
this.transaction._fee.feeRate = Number(fee);
|
|
92
|
+
this.transaction._fee.fee = fee.toString();
|
|
93
|
+
this.transaction._fee.size = 1;
|
|
94
|
+
this.transaction._fromAddresses = [Buffer.from(input.address.toBytes())];
|
|
95
|
+
this.transaction._locktime = transferOutput.getLocktime();
|
|
96
|
+
this._nonce = input.nonce.value();
|
|
97
|
+
// Use credentials passed from TransactionBuilderFactory (properly extracted using codec)
|
|
98
|
+
const credentials = parsedCredentials || [];
|
|
99
|
+
const hasCredentials = credentials.length > 0;
|
|
100
|
+
// If it's a signed transaction, store the original raw bytes to preserve exact format
|
|
101
|
+
if (hasCredentials && rawBytes) {
|
|
102
|
+
this.transaction._rawSignedBytes = rawBytes;
|
|
103
|
+
}
|
|
104
|
+
// Create proper UnsignedTx wrapper with credentials
|
|
105
|
+
const fromAddress = new flarejs_1.Address(this.transaction._fromAddresses[0]);
|
|
106
|
+
const addressMap = new flarejs_1.utils.AddressMap([
|
|
107
|
+
[fromAddress, 0],
|
|
108
|
+
[fromAddress, 1],
|
|
109
|
+
]);
|
|
110
|
+
const addressMaps = new flarejs_1.utils.AddressMaps([addressMap]);
|
|
111
|
+
const unsignedTx = new flarejs_1.UnsignedTx(baseTx, [], addressMaps, credentials.length > 0 ? credentials : [new flarejs_1.Credential([utils_1.default.createNewSig('')])]);
|
|
112
|
+
this.transaction.setTransaction(unsignedTx);
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
static verifyTxType(txnType) {
|
|
116
|
+
return txnType === iface_1.FlareTransactionType.EvmExportTx;
|
|
117
|
+
}
|
|
118
|
+
verifyTxType(txnType) {
|
|
119
|
+
return ExportInCTxBuilder.verifyTxType(txnType);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Build the export in C-chain transaction
|
|
123
|
+
* @protected
|
|
124
|
+
*/
|
|
125
|
+
buildFlareTransaction() {
|
|
126
|
+
if (this.transaction.hasCredentials)
|
|
127
|
+
return;
|
|
128
|
+
if (this._amount === undefined) {
|
|
129
|
+
throw new Error('amount is required');
|
|
130
|
+
}
|
|
131
|
+
if (this.transaction._fromAddresses.length !== 1) {
|
|
132
|
+
throw new Error('sender is one and required');
|
|
133
|
+
}
|
|
134
|
+
if (this.transaction._to.length === 0) {
|
|
135
|
+
throw new Error('to is required');
|
|
136
|
+
}
|
|
137
|
+
if (!this.transaction._fee.feeRate) {
|
|
138
|
+
throw new Error('fee rate is required');
|
|
139
|
+
}
|
|
140
|
+
if (this._nonce === undefined) {
|
|
141
|
+
throw new Error('nonce is required');
|
|
142
|
+
}
|
|
143
|
+
// For EVM exports, feeRate represents the total fee (baseFee * gasUnits)
|
|
144
|
+
// Don't add fixedFee as it's already accounted for in the EVM gas model
|
|
145
|
+
const fee = BigInt(this.transaction._fee.feeRate);
|
|
146
|
+
this.transaction._fee.fee = fee.toString();
|
|
147
|
+
this.transaction._fee.size = 1;
|
|
148
|
+
const fromAddressBytes = this.transaction._fromAddresses[0];
|
|
149
|
+
const fromAddress = new flarejs_1.Address(fromAddressBytes);
|
|
150
|
+
const assetId = utils_1.default.flareIdString(this.transaction._assetId);
|
|
151
|
+
const amount = new flarejs_1.BigIntPr(this._amount + fee);
|
|
152
|
+
const nonce = new flarejs_1.BigIntPr(this._nonce);
|
|
153
|
+
const input = new flarejs_1.evmSerial.Input(fromAddress, amount, assetId, nonce);
|
|
154
|
+
// Map all destination P-chain addresses for multisig support
|
|
155
|
+
// Sort addresses alphabetically by hex representation (required by Avalanche/Flare protocol)
|
|
156
|
+
const sortedToAddresses = [...this.transaction._to].sort((a, b) => {
|
|
157
|
+
const aHex = Buffer.from(a).toString('hex');
|
|
158
|
+
const bHex = Buffer.from(b).toString('hex');
|
|
159
|
+
return aHex.localeCompare(bHex);
|
|
160
|
+
});
|
|
161
|
+
const toAddresses = sortedToAddresses.map((addr) => new flarejs_1.Address(addr));
|
|
162
|
+
const exportTx = new flarejs_1.evmSerial.ExportTx(new flarejs_1.Int(this.transaction._networkID), utils_1.default.flareIdString(this.transaction._blockchainID), new flarejs_1.Id(new Uint8Array(this._externalChainId)), [input], [
|
|
163
|
+
new flarejs_1.TransferableOutput(assetId, new flarejs_1.TransferOutput(new flarejs_1.BigIntPr(this._amount), new flarejs_1.OutputOwners(new flarejs_1.BigIntPr(this.transaction._locktime), new flarejs_1.Int(this.transaction._threshold), toAddresses))),
|
|
164
|
+
]);
|
|
165
|
+
// Create address maps with proper EVM address format
|
|
166
|
+
const addressMap = new flarejs_1.utils.AddressMap([
|
|
167
|
+
[fromAddress, 0],
|
|
168
|
+
[fromAddress, 1], // Map the same address to both indices since it's used in both places
|
|
169
|
+
]);
|
|
170
|
+
const addressMaps = new flarejs_1.utils.AddressMaps([addressMap]); // Single map is sufficient
|
|
171
|
+
// Create unsigned transaction with proper address mapping
|
|
172
|
+
const unsignedTx = new flarejs_1.UnsignedTx(exportTx, [], // Empty UTXOs array, will be filled during processing
|
|
173
|
+
addressMaps, [new flarejs_1.Credential([utils_1.default.createNewSig('')])] // Empty credential for signing
|
|
174
|
+
);
|
|
175
|
+
this.transaction.setTransaction(unsignedTx);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check the nonce is non-negative.
|
|
179
|
+
* @param nonce
|
|
180
|
+
*/
|
|
181
|
+
validateNonce(nonce) {
|
|
182
|
+
if (nonce < BigInt(0)) {
|
|
183
|
+
throw new sdk_core_1.BuildTransactionError('Nonce must be greater or equal than 0');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.ExportInCTxBuilder = ExportInCTxBuilder;
|
|
188
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXhwb3J0SW5DVHhCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9FeHBvcnRJbkNUeEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsbURBQTRGO0FBRTVGLCtFQUE0RTtBQUM1RSxtREFZK0I7QUFDL0Isb0RBQTRCO0FBQzVCLG1DQUFtRTtBQUVuRSxNQUFhLGtCQUFtQixTQUFRLHlEQUEyQjtJQUlqRSxZQUFZLFdBQWlDO1FBQzNDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsS0FBdUI7UUFDM0IsTUFBTSxJQUFJLGdDQUFxQixDQUFDLGdEQUFnRCxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLE1BQXVCO1FBQzVCLE1BQU0sWUFBWSxHQUFHLE9BQU8sTUFBTSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDMUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQztRQUM1QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLEtBQXNCO1FBQzFCLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO1FBQzFCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxFQUFFLENBQUMsVUFBNkI7UUFDOUIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLGVBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN2RSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFjLGVBQWU7UUFDM0IsT0FBTywwQkFBZSxDQUFDLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRUQsV0FBVyxDQUFDLEVBQU0sRUFBRSxRQUFpQixFQUFFLGlCQUFnQztRQUNyRSxNQUFNLE1BQU0sR0FBRyxFQUF3QixDQUFDO1FBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSx1QkFBWSxDQUFDLHFFQUFxRSxDQUFDLENBQUM7UUFDaEcsQ0FBQztRQUVELHFEQUFxRDtRQUNyRCw0RUFBNEU7UUFDNUUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQztRQUN2QyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLGdDQUFxQixDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUxQixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3hGLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3RELENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsNkRBQTZEO1FBQzdELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDMUIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFeEIsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLE1BQXdCLENBQUM7UUFDdkQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUM5QixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pDLE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3QyxNQUFNLEdBQUcsR0FBRyxXQUFXLEdBQUcsWUFBWSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBWSxDQUFDO1FBQzVCLDBHQUEwRztRQUMxRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEdBQUcsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRTFELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVsQyx5RkFBeUY7UUFDekYsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLElBQUksRUFBRSxDQUFDO1FBQzVDLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBRTlDLHNGQUFzRjtRQUN0RixJQUFJLGNBQWMsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUM7UUFDOUMsQ0FBQztRQUVELG9EQUFvRDtRQUNwRCxNQUFNLFdBQVcsR0FBRyxJQUFJLGlCQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRSxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQVUsQ0FBQyxVQUFVLENBQUM7WUFDM0MsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztTQUNqQixDQUFDLENBQUM7UUFDSCxNQUFNLFdBQVcsR0FBRyxJQUFJLGVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBRTdELE1BQU0sVUFBVSxHQUFHLElBQUksb0JBQVUsQ0FDL0IsTUFBTSxFQUNOLEVBQUUsRUFDRixXQUFXLEVBQ1gsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLG9CQUFVLENBQUMsQ0FBQyxlQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNsRixDQUFDO1FBRUYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFlO1FBQ2pDLE9BQU8sT0FBTyxLQUFLLDRCQUFvQixDQUFDLFdBQVcsQ0FBQztJQUN0RCxDQUFDO0lBRUQsWUFBWSxDQUFDLE9BQWU7UUFDMUIsT0FBTyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVEOzs7T0FHRztJQUNPLHFCQUFxQjtRQUM3QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYztZQUFFLE9BQU87UUFDNUMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDakQsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxNQUFNLElBQUksS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUVELHlFQUF5RTtRQUN6RSx3RUFBd0U7UUFDeEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUUvQixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVELE1BQU0sV0FBVyxHQUFHLElBQUksaUJBQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sT0FBTyxHQUFHLGVBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvRCxNQUFNLE1BQU0sR0FBRyxJQUFJLGtCQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNoRCxNQUFNLEtBQUssR0FBRyxJQUFJLGtCQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkUsNkRBQTZEO1FBQzdELDZGQUE2RjtRQUM3RixNQUFNLGlCQUFpQixHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNoRSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksaUJBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXZFLE1BQU0sUUFBUSxHQUFHLElBQUksbUJBQVMsQ0FBQyxRQUFRLENBQ3JDLElBQUksYUFBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEVBQ3BDLGVBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsRUFDbkQsSUFBSSxZQUFFLENBQUMsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFDN0MsQ0FBQyxLQUFLLENBQUMsRUFDUDtZQUNFLElBQUksNEJBQWtCLENBQ3BCLE9BQU8sRUFDUCxJQUFJLHdCQUFjLENBQ2hCLElBQUksa0JBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQzFCLElBQUksc0JBQVksQ0FDZCxJQUFJLGtCQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsRUFDeEMsSUFBSSxhQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsRUFDcEMsV0FBVyxDQUNaLENBQ0YsQ0FDRjtTQUNGLENBQ0YsQ0FBQztRQUVGLHFEQUFxRDtRQUNyRCxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQVUsQ0FBQyxVQUFVLENBQUM7WUFDM0MsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxFQUFFLHNFQUFzRTtTQUN6RixDQUFDLENBQUM7UUFDSCxNQUFNLFdBQVcsR0FBRyxJQUFJLGVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO1FBRXpGLDBEQUEwRDtRQUMxRCxNQUFNLFVBQVUsR0FBRyxJQUFJLG9CQUFVLENBQy9CLFFBQVEsRUFDUixFQUFFLEVBQUUsc0RBQXNEO1FBQzFELFdBQVcsRUFDWCxDQUFDLElBQUksb0JBQVUsQ0FBQyxDQUFDLGVBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsK0JBQStCO1NBQzNFLENBQUM7UUFFRixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLEtBQWE7UUFDekIsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLGdDQUFxQixDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDM0UsQ0FBQztJQUNILENBQUM7Q0FDRjtBQWxPRCxnREFrT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IsIE5vdFN1cHBvcnRlZCwgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQmFzZUNvaW4gYXMgQ29pbkNvbmZpZyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgQXRvbWljSW5DVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi9hdG9taWNJbkNUcmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHtcbiAgZXZtU2VyaWFsLFxuICBVbnNpZ25lZFR4LFxuICBDcmVkZW50aWFsLFxuICBCaWdJbnRQcixcbiAgSW50LFxuICBJZCxcbiAgVHJhbnNmZXJhYmxlT3V0cHV0LFxuICBBZGRyZXNzLFxuICBUcmFuc2Zlck91dHB1dCxcbiAgT3V0cHV0T3duZXJzLFxuICB1dGlscyBhcyBGbGFyZVV0aWxzLFxufSBmcm9tICdAZmxhcmVuZXR3b3JrL2ZsYXJlanMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgRGVjb2RlZFV0eG9PYmosIFR4LCBGbGFyZVRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJy4vaWZhY2UnO1xuXG5leHBvcnQgY2xhc3MgRXhwb3J0SW5DVHhCdWlsZGVyIGV4dGVuZHMgQXRvbWljSW5DVHJhbnNhY3Rpb25CdWlsZGVyIHtcbiAgcHJpdmF0ZSBfYW1vdW50OiBiaWdpbnQ7XG4gIHByaXZhdGUgX25vbmNlOiBiaWdpbnQ7XG5cbiAgY29uc3RydWN0b3IoX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoX2NvaW5Db25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFV0eG9zIGFyZSBub3QgcmVxdWlyZWQgaW4gRXhwb3J0IFR4IGluIEMtQ2hhaW4uXG4gICAqIE92ZXJyaWRlIHV0eG9zIHRvIHByZXZlbnQgdXNlZCBieSB0aHJvd2luZyBhIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0ge0RlY29kZWRVdHhvT2JqW119IHZhbHVlIGlnbm9yZWRcbiAgICovXG4gIHV0eG9zKHZhbHVlOiBEZWNvZGVkVXR4b09ialtdKTogdGhpcyB7XG4gICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcigndXR4b3MgYXJlIG5vdCByZXF1aXJlZCBpbiBFeHBvcnQgVHggaW4gQy1DaGFpbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFtb3VudCBpcyBhIGJpZ2ludCB0aGF0IHNwZWNpZmllcyB0aGUgcXVhbnRpdHkgb2YgdGhlIGFzc2V0IHRoYXQgdGhpcyBvdXRwdXQgb3ducy4gTXVzdCBiZSBwb3NpdGl2ZS5cbiAgICogVGhlIHRyYW5zYWN0aW9uIG91dHB1dCBhbW91bnQgYWRkIGEgZml4ZWQgZmVlIHRoYXQgd2lsbCBiZSBwYWlkIHVwb24gaW1wb3J0LlxuICAgKlxuICAgKiBAcGFyYW0ge2JpZ2ludCB8IHN0cmluZ30gYW1vdW50IFRoZSB3aXRoZHJhd2FsIGFtb3VudFxuICAgKi9cbiAgYW1vdW50KGFtb3VudDogYmlnaW50IHwgc3RyaW5nKTogdGhpcyB7XG4gICAgY29uc3QgYW1vdW50QmlnSW50ID0gdHlwZW9mIGFtb3VudCA9PT0gJ3N0cmluZycgPyBCaWdJbnQoYW1vdW50KSA6IGFtb3VudDtcbiAgICB0aGlzLnZhbGlkYXRlQW1vdW50KGFtb3VudEJpZ0ludCk7XG4gICAgdGhpcy5fYW1vdW50ID0gYW1vdW50QmlnSW50O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbm9uY2Ugb2YgQy1DaGFpbiBzZW5kZXIgYWRkcmVzc1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlciB8IHN0cmluZ30gbm9uY2UgLSBudW1iZXIgdGhhdCBjYW4gYmUgb25seSB1c2VkIG9uY2VcbiAgICovXG4gIG5vbmNlKG5vbmNlOiBudW1iZXIgfCBzdHJpbmcpOiB0aGlzIHtcbiAgICBjb25zdCBub25jZUJpZ0ludCA9IEJpZ0ludChub25jZSk7XG4gICAgdGhpcy52YWxpZGF0ZU5vbmNlKG5vbmNlQmlnSW50KTtcbiAgICB0aGlzLl9ub25jZSA9IG5vbmNlQmlnSW50O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCB0eCB0YXJnZXQgUCB3YWxsZXQuXG4gICAqXG4gICAqIEBwYXJhbSBwQWRkcmVzc2VzXG4gICAqL1xuICB0byhwQWRkcmVzc2VzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHRoaXMge1xuICAgIGNvbnN0IHB1YktleXMgPSBBcnJheS5pc0FycmF5KHBBZGRyZXNzZXMpID8gcEFkZHJlc3NlcyA6IHBBZGRyZXNzZXMuc3BsaXQoJ34nKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl90byA9IHB1YktleXMubWFwKChhZGRyKSA9PiB1dGlscy5wYXJzZUFkZHJlc3MoYWRkcikpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCB0cmFuc2FjdGlvblR5cGUoKTogVHJhbnNhY3Rpb25UeXBlIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLkV4cG9ydDtcbiAgfVxuXG4gIGluaXRCdWlsZGVyKHR4OiBUeCwgcmF3Qnl0ZXM/OiBCdWZmZXIsIHBhcnNlZENyZWRlbnRpYWxzPzogQ3JlZGVudGlhbFtdKTogdGhpcyB7XG4gICAgY29uc3QgYmFzZVR4ID0gdHggYXMgZXZtU2VyaWFsLkV4cG9ydFR4O1xuICAgIGlmICghdGhpcy52ZXJpZnlUeFR5cGUoYmFzZVR4Ll90eXBlKSkge1xuICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZCgnVHJhbnNhY3Rpb24gY2Fubm90IGJlIHBhcnNlZCBvciBoYXMgYW4gdW5zdXBwb3J0ZWQgdHJhbnNhY3Rpb24gdHlwZScpO1xuICAgIH1cblxuICAgIC8vIFRoZSBvdXRwdXRzIGlzIGEgbXVsdGlzaWduIFAtQ2hhaW4gYWRkcmVzcyByZXN1bHQuXG4gICAgLy8gSXQncyBleHBlY3RlZCB0byBoYXZlIG9ubHkgb25lIG91dHB1dCB0byB0aGUgZGVzdGluYXRpb24gUC1DaGFpbiBhZGRyZXNzLlxuICAgIGNvbnN0IG91dHB1dHMgPSBiYXNlVHguZXhwb3J0ZWRPdXRwdXRzO1xuICAgIGlmIChvdXRwdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVHJhbnNhY3Rpb24gY2FuIGhhdmUgb25lIG91dHB1dCcpO1xuICAgIH1cbiAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdO1xuXG4gICAgaWYgKEJ1ZmZlci5mcm9tKG91dHB1dC5hc3NldElkLnRvQnl0ZXMoKSkudG9TdHJpbmcoJ2hleCcpICE9PSB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdBc3NldElEIG1pc21hdGNoJyk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGlucHV0cyBpcyBub3QgYW4gdXR4by5cbiAgICAvLyBJdCdzIGV4cGVjdGVkIHRvIGhhdmUgb25seSBvbmUgaW5wdXQgZnJvbSBDLUNoYWluIGFkZHJlc3MuXG4gICAgY29uc3QgaW5wdXRzID0gYmFzZVR4LmlucztcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVHJhbnNhY3Rpb24gY2FuIGhhdmUgb25lIGlucHV0Jyk7XG4gICAgfVxuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdO1xuXG4gICAgY29uc3QgdHJhbnNmZXJPdXRwdXQgPSBvdXRwdXQub3V0cHV0IGFzIFRyYW5zZmVyT3V0cHV0O1xuICAgIGNvbnN0IG93bmVycyA9IHRyYW5zZmVyT3V0cHV0LmdldE93bmVycygpO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX3RvID0gb3duZXJzO1xuICAgIGNvbnN0IGlucHV0QW1vdW50ID0gaW5wdXQuYW1vdW50LnZhbHVlKCk7XG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gdHJhbnNmZXJPdXRwdXQuYW1vdW50KCk7XG4gICAgY29uc3QgZmVlID0gaW5wdXRBbW91bnQgLSBvdXRwdXRBbW91bnQ7XG4gICAgdGhpcy5fYW1vdW50ID0gb3V0cHV0QW1vdW50O1xuICAgIC8vIFN0b3JlIHRoZSBhY3R1YWwgZmVlIGRpcmVjdGx5IChkb24ndCBzdWJ0cmFjdCBmaXhlZEZlZSBzaW5jZSBidWlsZEZsYXJlVHJhbnNhY3Rpb24gZG9lc24ndCBhZGQgaXQgYmFjaylcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl9mZWUuZmVlUmF0ZSA9IE51bWJlcihmZWUpO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX2ZlZS5mZWUgPSBmZWUudG9TdHJpbmcoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl9mZWUuc2l6ZSA9IDE7XG4gICAgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3NlcyA9IFtCdWZmZXIuZnJvbShpbnB1dC5hZGRyZXNzLnRvQnl0ZXMoKSldO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lID0gdHJhbnNmZXJPdXRwdXQuZ2V0TG9ja3RpbWUoKTtcblxuICAgIHRoaXMuX25vbmNlID0gaW5wdXQubm9uY2UudmFsdWUoKTtcblxuICAgIC8vIFVzZSBjcmVkZW50aWFscyBwYXNzZWQgZnJvbSBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IChwcm9wZXJseSBleHRyYWN0ZWQgdXNpbmcgY29kZWMpXG4gICAgY29uc3QgY3JlZGVudGlhbHMgPSBwYXJzZWRDcmVkZW50aWFscyB8fCBbXTtcbiAgICBjb25zdCBoYXNDcmVkZW50aWFscyA9IGNyZWRlbnRpYWxzLmxlbmd0aCA+IDA7XG5cbiAgICAvLyBJZiBpdCdzIGEgc2lnbmVkIHRyYW5zYWN0aW9uLCBzdG9yZSB0aGUgb3JpZ2luYWwgcmF3IGJ5dGVzIHRvIHByZXNlcnZlIGV4YWN0IGZvcm1hdFxuICAgIGlmIChoYXNDcmVkZW50aWFscyAmJiByYXdCeXRlcykge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbi5fcmF3U2lnbmVkQnl0ZXMgPSByYXdCeXRlcztcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgcHJvcGVyIFVuc2lnbmVkVHggd3JhcHBlciB3aXRoIGNyZWRlbnRpYWxzXG4gICAgY29uc3QgZnJvbUFkZHJlc3MgPSBuZXcgQWRkcmVzcyh0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzWzBdKTtcbiAgICBjb25zdCBhZGRyZXNzTWFwID0gbmV3IEZsYXJlVXRpbHMuQWRkcmVzc01hcChbXG4gICAgICBbZnJvbUFkZHJlc3MsIDBdLFxuICAgICAgW2Zyb21BZGRyZXNzLCAxXSxcbiAgICBdKTtcbiAgICBjb25zdCBhZGRyZXNzTWFwcyA9IG5ldyBGbGFyZVV0aWxzLkFkZHJlc3NNYXBzKFthZGRyZXNzTWFwXSk7XG5cbiAgICBjb25zdCB1bnNpZ25lZFR4ID0gbmV3IFVuc2lnbmVkVHgoXG4gICAgICBiYXNlVHgsXG4gICAgICBbXSxcbiAgICAgIGFkZHJlc3NNYXBzLFxuICAgICAgY3JlZGVudGlhbHMubGVuZ3RoID4gMCA/IGNyZWRlbnRpYWxzIDogW25ldyBDcmVkZW50aWFsKFt1dGlscy5jcmVhdGVOZXdTaWcoJycpXSldXG4gICAgKTtcblxuICAgIHRoaXMudHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24odW5zaWduZWRUeCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgdmVyaWZ5VHhUeXBlKHR4blR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eG5UeXBlID09PSBGbGFyZVRyYW5zYWN0aW9uVHlwZS5Fdm1FeHBvcnRUeDtcbiAgfVxuXG4gIHZlcmlmeVR4VHlwZSh0eG5UeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gRXhwb3J0SW5DVHhCdWlsZGVyLnZlcmlmeVR4VHlwZSh0eG5UeXBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgZXhwb3J0IGluIEMtY2hhaW4gdHJhbnNhY3Rpb25cbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkRmxhcmVUcmFuc2FjdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbi5oYXNDcmVkZW50aWFscykgcmV0dXJuO1xuICAgIGlmICh0aGlzLl9hbW91bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbW91bnQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlbmRlciBpcyBvbmUgYW5kIHJlcXVpcmVkJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uLl90by5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndG8gaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnRyYW5zYWN0aW9uLl9mZWUuZmVlUmF0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdmZWUgcmF0ZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fbm9uY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub25jZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8vIEZvciBFVk0gZXhwb3J0cywgZmVlUmF0ZSByZXByZXNlbnRzIHRoZSB0b3RhbCBmZWUgKGJhc2VGZWUgKiBnYXNVbml0cylcbiAgICAvLyBEb24ndCBhZGQgZml4ZWRGZWUgYXMgaXQncyBhbHJlYWR5IGFjY291bnRlZCBmb3IgaW4gdGhlIEVWTSBnYXMgbW9kZWxcbiAgICBjb25zdCBmZWUgPSBCaWdJbnQodGhpcy50cmFuc2FjdGlvbi5fZmVlLmZlZVJhdGUpO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX2ZlZS5mZWUgPSBmZWUudG9TdHJpbmcoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl9mZWUuc2l6ZSA9IDE7XG5cbiAgICBjb25zdCBmcm9tQWRkcmVzc0J5dGVzID0gdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1swXTtcbiAgICBjb25zdCBmcm9tQWRkcmVzcyA9IG5ldyBBZGRyZXNzKGZyb21BZGRyZXNzQnl0ZXMpO1xuICAgIGNvbnN0IGFzc2V0SWQgPSB1dGlscy5mbGFyZUlkU3RyaW5nKHRoaXMudHJhbnNhY3Rpb24uX2Fzc2V0SWQpO1xuICAgIGNvbnN0IGFtb3VudCA9IG5ldyBCaWdJbnRQcih0aGlzLl9hbW91bnQgKyBmZWUpO1xuICAgIGNvbnN0IG5vbmNlID0gbmV3IEJpZ0ludFByKHRoaXMuX25vbmNlKTtcbiAgICBjb25zdCBpbnB1dCA9IG5ldyBldm1TZXJpYWwuSW5wdXQoZnJvbUFkZHJlc3MsIGFtb3VudCwgYXNzZXRJZCwgbm9uY2UpO1xuICAgIC8vIE1hcCBhbGwgZGVzdGluYXRpb24gUC1jaGFpbiBhZGRyZXNzZXMgZm9yIG11bHRpc2lnIHN1cHBvcnRcbiAgICAvLyBTb3J0IGFkZHJlc3NlcyBhbHBoYWJldGljYWxseSBieSBoZXggcmVwcmVzZW50YXRpb24gKHJlcXVpcmVkIGJ5IEF2YWxhbmNoZS9GbGFyZSBwcm90b2NvbClcbiAgICBjb25zdCBzb3J0ZWRUb0FkZHJlc3NlcyA9IFsuLi50aGlzLnRyYW5zYWN0aW9uLl90b10uc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgYUhleCA9IEJ1ZmZlci5mcm9tKGEpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGJIZXggPSBCdWZmZXIuZnJvbShiKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICByZXR1cm4gYUhleC5sb2NhbGVDb21wYXJlKGJIZXgpO1xuICAgIH0pO1xuICAgIGNvbnN0IHRvQWRkcmVzc2VzID0gc29ydGVkVG9BZGRyZXNzZXMubWFwKChhZGRyKSA9PiBuZXcgQWRkcmVzcyhhZGRyKSk7XG5cbiAgICBjb25zdCBleHBvcnRUeCA9IG5ldyBldm1TZXJpYWwuRXhwb3J0VHgoXG4gICAgICBuZXcgSW50KHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmtJRCksXG4gICAgICB1dGlscy5mbGFyZUlkU3RyaW5nKHRoaXMudHJhbnNhY3Rpb24uX2Jsb2NrY2hhaW5JRCksXG4gICAgICBuZXcgSWQobmV3IFVpbnQ4QXJyYXkodGhpcy5fZXh0ZXJuYWxDaGFpbklkKSksXG4gICAgICBbaW5wdXRdLFxuICAgICAgW1xuICAgICAgICBuZXcgVHJhbnNmZXJhYmxlT3V0cHV0KFxuICAgICAgICAgIGFzc2V0SWQsXG4gICAgICAgICAgbmV3IFRyYW5zZmVyT3V0cHV0KFxuICAgICAgICAgICAgbmV3IEJpZ0ludFByKHRoaXMuX2Ftb3VudCksXG4gICAgICAgICAgICBuZXcgT3V0cHV0T3duZXJzKFxuICAgICAgICAgICAgICBuZXcgQmlnSW50UHIodGhpcy50cmFuc2FjdGlvbi5fbG9ja3RpbWUpLFxuICAgICAgICAgICAgICBuZXcgSW50KHRoaXMudHJhbnNhY3Rpb24uX3RocmVzaG9sZCksXG4gICAgICAgICAgICAgIHRvQWRkcmVzc2VzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgXVxuICAgICk7XG5cbiAgICAvLyBDcmVhdGUgYWRkcmVzcyBtYXBzIHdpdGggcHJvcGVyIEVWTSBhZGRyZXNzIGZvcm1hdFxuICAgIGNvbnN0IGFkZHJlc3NNYXAgPSBuZXcgRmxhcmVVdGlscy5BZGRyZXNzTWFwKFtcbiAgICAgIFtmcm9tQWRkcmVzcywgMF0sXG4gICAgICBbZnJvbUFkZHJlc3MsIDFdLCAvLyBNYXAgdGhlIHNhbWUgYWRkcmVzcyB0byBib3RoIGluZGljZXMgc2luY2UgaXQncyB1c2VkIGluIGJvdGggcGxhY2VzXG4gICAgXSk7XG4gICAgY29uc3QgYWRkcmVzc01hcHMgPSBuZXcgRmxhcmVVdGlscy5BZGRyZXNzTWFwcyhbYWRkcmVzc01hcF0pOyAvLyBTaW5nbGUgbWFwIGlzIHN1ZmZpY2llbnRcblxuICAgIC8vIENyZWF0ZSB1bnNpZ25lZCB0cmFuc2FjdGlvbiB3aXRoIHByb3BlciBhZGRyZXNzIG1hcHBpbmdcbiAgICBjb25zdCB1bnNpZ25lZFR4ID0gbmV3IFVuc2lnbmVkVHgoXG4gICAgICBleHBvcnRUeCxcbiAgICAgIFtdLCAvLyBFbXB0eSBVVFhPcyBhcnJheSwgd2lsbCBiZSBmaWxsZWQgZHVyaW5nIHByb2Nlc3NpbmdcbiAgICAgIGFkZHJlc3NNYXBzLFxuICAgICAgW25ldyBDcmVkZW50aWFsKFt1dGlscy5jcmVhdGVOZXdTaWcoJycpXSldIC8vIEVtcHR5IGNyZWRlbnRpYWwgZm9yIHNpZ25pbmdcbiAgICApO1xuXG4gICAgdGhpcy50cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvbih1bnNpZ25lZFR4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB0aGUgbm9uY2UgaXMgbm9uLW5lZ2F0aXZlLlxuICAgKiBAcGFyYW0gbm9uY2VcbiAgICovXG4gIHZhbGlkYXRlTm9uY2Uobm9uY2U6IGJpZ2ludCk6IHZvaWQge1xuICAgIGlmIChub25jZSA8IEJpZ0ludCgwKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignTm9uY2UgbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRoYW4gMCcpO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BaseCoin as CoinConfig } from '@bitgo-beta/statics';
|
|
2
|
+
import { TransactionType } from '@bitgo-beta/sdk-core';
|
|
3
|
+
import { AtomicTransactionBuilder } from './atomicTransactionBuilder';
|
|
4
|
+
import { TransferableInput, TransferableOutput, Credential } from '@flarenetwork/flarejs';
|
|
5
|
+
import { Tx } from './iface';
|
|
6
|
+
export declare class ExportInPTxBuilder extends AtomicTransactionBuilder {
|
|
7
|
+
private _amount;
|
|
8
|
+
constructor(_coinConfig: Readonly<CoinConfig>);
|
|
9
|
+
protected get transactionType(): TransactionType;
|
|
10
|
+
/**
|
|
11
|
+
* Amount is a bigint that specifies the quantity of the asset that this output owns. Must be positive.
|
|
12
|
+
* @param {bigint | string} amount The withdrawal amount
|
|
13
|
+
*/
|
|
14
|
+
amount(value: bigint | string): this;
|
|
15
|
+
initBuilder(tx: Tx, rawBytes?: Buffer, parsedCredentials?: Credential[]): this;
|
|
16
|
+
static verifyTxType(txnType: string): boolean;
|
|
17
|
+
verifyTxType(txnType: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Build the export transaction for P-chain
|
|
20
|
+
* @protected
|
|
21
|
+
*/
|
|
22
|
+
protected buildFlareTransaction(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Create inputs from UTXOs for P-chain export
|
|
25
|
+
* Only selects enough UTXOs to cover the target amount (amount + fee)
|
|
26
|
+
* @returns inputs, change outputs, credentials, and total amount
|
|
27
|
+
*/
|
|
28
|
+
protected createExportInputs(): {
|
|
29
|
+
inputs: TransferableInput[];
|
|
30
|
+
changeOutputs: TransferableOutput[];
|
|
31
|
+
credentials: Credential[];
|
|
32
|
+
totalAmount: bigint;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Create the ExportedOutputs where the recipient address are the sender.
|
|
36
|
+
* Later an importTx should complete the operations signing with the same keys.
|
|
37
|
+
* @protected
|
|
38
|
+
*/
|
|
39
|
+
protected exportedOutputs(): TransferableOutput[];
|
|
40
|
+
/**
|
|
41
|
+
* Recover UTXOs from inputs
|
|
42
|
+
* @param inputs Array of TransferableInput
|
|
43
|
+
* @returns Array of decoded UTXO objects
|
|
44
|
+
*/
|
|
45
|
+
private recoverUtxos;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ExportInPTxBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportInPTxBuilder.d.ts","sourceRoot":"","sources":["../../../src/lib/ExportInPTxBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAuC,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAOL,iBAAiB,EACjB,kBAAkB,EAMlB,UAAU,EAEX,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAmE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE9F,qBAAa,kBAAmB,SAAQ,wBAAwB;IAC9D,OAAO,CAAC,OAAO,CAAS;gBAEZ,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC;IAY7C,SAAS,KAAK,eAAe,IAAI,eAAe,CAE/C;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOpC,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI;IAgG9E,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7C,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAItC;;;OAGG;IACH,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAoDvC;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,IAAI;QAC9B,MAAM,EAAE,iBAAiB,EAAE,CAAC;QAC5B,aAAa,EAAE,kBAAkB,EAAE,CAAC;QACpC,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;KACrB;IAwGD;;;;OAIG;IACH,SAAS,CAAC,eAAe,IAAI,kBAAkB,EAAE;IAgBjD;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAkBrB"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ExportInPTxBuilder = void 0;
|
|
7
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
+
const atomicTransactionBuilder_1 = require("./atomicTransactionBuilder");
|
|
9
|
+
const flarejs_1 = require("@flarenetwork/flarejs");
|
|
10
|
+
const utils_1 = __importDefault(require("./utils"));
|
|
11
|
+
const iface_1 = require("./iface");
|
|
12
|
+
class ExportInPTxBuilder extends atomicTransactionBuilder_1.AtomicTransactionBuilder {
|
|
13
|
+
constructor(_coinConfig) {
|
|
14
|
+
super(_coinConfig);
|
|
15
|
+
// For Export FROM P-chain:
|
|
16
|
+
// - external chain (destination) is C-chain
|
|
17
|
+
// - blockchain ID (source) is P-chain
|
|
18
|
+
this._externalChainId = utils_1.default.cb58Decode(this.transaction._network.cChainBlockchainID);
|
|
19
|
+
// P-chain blockchain ID (from network config - decode from cb58 to hex)
|
|
20
|
+
this.transaction._blockchainID = Buffer.from(utils_1.default.cb58Decode(this.transaction._network.blockchainID)).toString('hex');
|
|
21
|
+
}
|
|
22
|
+
get transactionType() {
|
|
23
|
+
return sdk_core_1.TransactionType.Export;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Amount is a bigint that specifies the quantity of the asset that this output owns. Must be positive.
|
|
27
|
+
* @param {bigint | string} amount The withdrawal amount
|
|
28
|
+
*/
|
|
29
|
+
amount(value) {
|
|
30
|
+
const valueBigInt = typeof value === 'string' ? BigInt(value) : value;
|
|
31
|
+
this.validateAmount(valueBigInt);
|
|
32
|
+
this._amount = valueBigInt;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
initBuilder(tx, rawBytes, parsedCredentials) {
|
|
36
|
+
const exportTx = tx;
|
|
37
|
+
if (!this.verifyTxType(exportTx._type)) {
|
|
38
|
+
throw new sdk_core_1.NotSupported('Transaction cannot be parsed or has an unsupported transaction type');
|
|
39
|
+
}
|
|
40
|
+
// The exportedOutputs is a TransferableOutput array.
|
|
41
|
+
// It's expected to have only one output with the addresses of the sender.
|
|
42
|
+
const outputs = exportTx.outs;
|
|
43
|
+
if (outputs.length !== 1) {
|
|
44
|
+
throw new sdk_core_1.BuildTransactionError('Transaction can have one external output');
|
|
45
|
+
}
|
|
46
|
+
const output = outputs[0];
|
|
47
|
+
const outputTransfer = output.output;
|
|
48
|
+
const assetId = output.assetId.toBytes();
|
|
49
|
+
if (Buffer.compare(Buffer.from(assetId), Buffer.from(this.transaction._assetId, 'hex')) !== 0) {
|
|
50
|
+
throw new Error('The Asset ID of the output does not match the transaction');
|
|
51
|
+
}
|
|
52
|
+
const outputOwners = outputTransfer.outputOwners;
|
|
53
|
+
// Set locktime from output
|
|
54
|
+
this.transaction._locktime = outputOwners.locktime.value();
|
|
55
|
+
// Set threshold from output
|
|
56
|
+
this.transaction._threshold = outputOwners.threshold.value();
|
|
57
|
+
// Convert output addresses to buffers and set as fromAddresses
|
|
58
|
+
this.transaction._fromAddresses = outputOwners.addrs.map((addr) => Buffer.from(addr.toBytes()));
|
|
59
|
+
// Set external chain ID from the destination chain
|
|
60
|
+
this._externalChainId = Buffer.from(exportTx.destination.toBytes());
|
|
61
|
+
// Set amount from exported output
|
|
62
|
+
this._amount = outputTransfer.amount();
|
|
63
|
+
// Recover UTXOs from base tx inputs
|
|
64
|
+
this.transaction._utxos = this.recoverUtxos([...exportTx.baseTx.inputs]);
|
|
65
|
+
// Calculate and set fee from input/output difference
|
|
66
|
+
const totalInputAmount = exportTx.baseTx.inputs.reduce((sum, input) => sum + input.amount(), BigInt(0));
|
|
67
|
+
const changeOutputAmount = exportTx.baseTx.outputs.reduce((sum, out) => {
|
|
68
|
+
const transferOut = out.output;
|
|
69
|
+
return sum + transferOut.amount();
|
|
70
|
+
}, BigInt(0));
|
|
71
|
+
const fee = totalInputAmount - changeOutputAmount - this._amount;
|
|
72
|
+
this.transaction._fee.fee = fee.toString();
|
|
73
|
+
// Use credentials passed from TransactionBuilderFactory (properly extracted using codec)
|
|
74
|
+
const credentials = parsedCredentials || [];
|
|
75
|
+
const hasCredentials = credentials.length > 0;
|
|
76
|
+
// If there are credentials, store the original bytes to preserve exact format
|
|
77
|
+
if (rawBytes && hasCredentials) {
|
|
78
|
+
this.transaction._rawSignedBytes = rawBytes;
|
|
79
|
+
}
|
|
80
|
+
// Create proper UnsignedTx wrapper with credentials
|
|
81
|
+
const sortedAddresses = [...this.transaction._fromAddresses].sort((a, b) => Buffer.compare(a, b));
|
|
82
|
+
// When credentials were extracted, use them directly to preserve existing signatures
|
|
83
|
+
// Otherwise, create empty credentials with embedded addresses for slot identification
|
|
84
|
+
const txCredentials = credentials.length > 0
|
|
85
|
+
? credentials
|
|
86
|
+
: exportTx.baseTx.inputs.map((input) => {
|
|
87
|
+
const transferInput = input.input;
|
|
88
|
+
const inputThreshold = transferInput.sigIndicies().length || this.transaction._threshold;
|
|
89
|
+
// Create empty signatures with embedded addresses for slot identification
|
|
90
|
+
const sigSlots = [];
|
|
91
|
+
for (let i = 0; i < inputThreshold; i++) {
|
|
92
|
+
const addrHex = Buffer.from(sortedAddresses[i]).toString('hex');
|
|
93
|
+
sigSlots.push(utils_1.default.createEmptySigWithAddress(addrHex));
|
|
94
|
+
}
|
|
95
|
+
return new flarejs_1.Credential(sigSlots);
|
|
96
|
+
});
|
|
97
|
+
// Create address maps for signing - one per input/credential
|
|
98
|
+
// Each address map contains all addresses mapped to their indices
|
|
99
|
+
const addressMaps = txCredentials.map(() => {
|
|
100
|
+
const addressMap = new flarejs_1.utils.AddressMap();
|
|
101
|
+
sortedAddresses.forEach((addr, i) => {
|
|
102
|
+
addressMap.set(new flarejs_1.Address(addr), i);
|
|
103
|
+
});
|
|
104
|
+
return addressMap;
|
|
105
|
+
});
|
|
106
|
+
// Always create a new UnsignedTx with properly structured credentials
|
|
107
|
+
const unsignedTx = new flarejs_1.UnsignedTx(exportTx, [], new flarejs_1.utils.AddressMaps(addressMaps), txCredentials);
|
|
108
|
+
this.transaction.setTransaction(unsignedTx);
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
static verifyTxType(txnType) {
|
|
112
|
+
return txnType === iface_1.FlareTransactionType.PvmExportTx;
|
|
113
|
+
}
|
|
114
|
+
verifyTxType(txnType) {
|
|
115
|
+
return ExportInPTxBuilder.verifyTxType(txnType);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build the export transaction for P-chain
|
|
119
|
+
* @protected
|
|
120
|
+
*/
|
|
121
|
+
buildFlareTransaction() {
|
|
122
|
+
// if tx has credentials, tx shouldn't change
|
|
123
|
+
if (this.transaction.hasCredentials)
|
|
124
|
+
return;
|
|
125
|
+
const { inputs, changeOutputs, credentials, totalAmount } = this.createExportInputs();
|
|
126
|
+
// Calculate fee from transaction fee settings
|
|
127
|
+
const fee = BigInt(this.transaction.fee.fee);
|
|
128
|
+
const targetAmount = this._amount + fee;
|
|
129
|
+
// Verify we have enough funds
|
|
130
|
+
if (totalAmount < targetAmount) {
|
|
131
|
+
throw new sdk_core_1.BuildTransactionError(`Insufficient funds: have ${totalAmount}, need ${targetAmount}`);
|
|
132
|
+
}
|
|
133
|
+
// Create the BaseTx for the P-chain export transaction
|
|
134
|
+
const baseTx = new flarejs_1.avaxSerial.BaseTx(new flarejs_1.Int(this.transaction._networkID), new flarejs_1.Id(Buffer.from(this.transaction._blockchainID, 'hex')), changeOutputs, // change outputs
|
|
135
|
+
inputs, // inputs
|
|
136
|
+
new flarejs_1.Bytes(new Uint8Array(0)) // empty memo
|
|
137
|
+
);
|
|
138
|
+
// Create the P-chain export transaction using pvmSerial.ExportTx
|
|
139
|
+
const exportTx = new flarejs_1.pvmSerial.ExportTx(baseTx, new flarejs_1.Id(this._externalChainId), // destinationChain (C-chain)
|
|
140
|
+
this.exportedOutputs() // exportedOutputs
|
|
141
|
+
);
|
|
142
|
+
// Create address maps for signing - one per input/credential
|
|
143
|
+
const sortedAddresses = [...this.transaction._fromAddresses].sort((a, b) => Buffer.compare(a, b));
|
|
144
|
+
const addressMaps = credentials.map(() => {
|
|
145
|
+
const addressMap = new flarejs_1.utils.AddressMap();
|
|
146
|
+
sortedAddresses.forEach((addr, i) => {
|
|
147
|
+
addressMap.set(new flarejs_1.Address(addr), i);
|
|
148
|
+
});
|
|
149
|
+
return addressMap;
|
|
150
|
+
});
|
|
151
|
+
// Create unsigned transaction
|
|
152
|
+
const unsignedTx = new flarejs_1.UnsignedTx(exportTx, [], // Empty UTXOs array
|
|
153
|
+
new flarejs_1.utils.AddressMaps(addressMaps), credentials);
|
|
154
|
+
this.transaction.setTransaction(unsignedTx);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create inputs from UTXOs for P-chain export
|
|
158
|
+
* Only selects enough UTXOs to cover the target amount (amount + fee)
|
|
159
|
+
* @returns inputs, change outputs, credentials, and total amount
|
|
160
|
+
*/
|
|
161
|
+
createExportInputs() {
|
|
162
|
+
const sender = [...this.transaction._fromAddresses];
|
|
163
|
+
if (this.recoverSigner) {
|
|
164
|
+
// switch first and last signer
|
|
165
|
+
const tmp = sender.pop();
|
|
166
|
+
sender.push(sender[0]);
|
|
167
|
+
if (tmp) {
|
|
168
|
+
sender[0] = tmp;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const fee = BigInt(this.transaction.fee.fee);
|
|
172
|
+
const targetAmount = this._amount + fee;
|
|
173
|
+
let totalAmount = BigInt(0);
|
|
174
|
+
const inputs = [];
|
|
175
|
+
const credentials = [];
|
|
176
|
+
// Change output threshold is always 1 (matching Flare protocol behavior)
|
|
177
|
+
// This allows easier spending of change while maintaining security for export outputs
|
|
178
|
+
const changeOutputThreshold = 1;
|
|
179
|
+
// Only consume enough UTXOs to cover the target amount (in array order)
|
|
180
|
+
// Inputs will be sorted after selection
|
|
181
|
+
for (const utxo of this.transaction._utxos) {
|
|
182
|
+
// Stop if we already have enough
|
|
183
|
+
if (totalAmount >= targetAmount) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
const amount = BigInt(utxo.amount);
|
|
187
|
+
totalAmount += amount;
|
|
188
|
+
// Use the UTXO's own threshold for signature indices
|
|
189
|
+
const utxoThreshold = utxo.threshold || this.transaction._threshold;
|
|
190
|
+
// Create signature indices for the UTXO's threshold
|
|
191
|
+
const sigIndices = [];
|
|
192
|
+
for (let i = 0; i < utxoThreshold; i++) {
|
|
193
|
+
sigIndices.push(i);
|
|
194
|
+
}
|
|
195
|
+
// Use fromNative to create TransferableInput
|
|
196
|
+
const txIdCb58 = utxo.txid; // Already cb58 encoded
|
|
197
|
+
const assetIdCb58 = utils_1.default.cb58Encode(Buffer.from(this.transaction._assetId, 'hex'));
|
|
198
|
+
const transferableInput = flarejs_1.TransferableInput.fromNative(txIdCb58, Number(utxo.outputidx), assetIdCb58, amount, sigIndices);
|
|
199
|
+
inputs.push(transferableInput);
|
|
200
|
+
// Create credential with empty signatures that have embedded addresses for slot identification
|
|
201
|
+
// This allows the signing logic to determine which slot belongs to which address
|
|
202
|
+
const sortedAddrs = [...this.transaction._fromAddresses].sort((a, b) => Buffer.compare(a, b));
|
|
203
|
+
const emptySignatures = sigIndices.map((idx) => {
|
|
204
|
+
const addrHex = Buffer.from(sortedAddrs[idx]).toString('hex');
|
|
205
|
+
return utils_1.default.createEmptySigWithAddress(addrHex);
|
|
206
|
+
});
|
|
207
|
+
credentials.push(new flarejs_1.Credential(emptySignatures));
|
|
208
|
+
}
|
|
209
|
+
// Create change output if there is remaining amount after export and fee
|
|
210
|
+
const changeOutputs = [];
|
|
211
|
+
const changeAmount = totalAmount - this._amount - fee;
|
|
212
|
+
if (changeAmount > BigInt(0)) {
|
|
213
|
+
const assetIdBytes = new Uint8Array(Buffer.from(this.transaction._assetId, 'hex'));
|
|
214
|
+
// Create OutputOwners with the P-chain addresses (sorted by byte value as per AVAX protocol)
|
|
215
|
+
// Use threshold=1 for change outputs (matching Flare protocol behavior)
|
|
216
|
+
const sortedAddresses = [...this.transaction._fromAddresses].sort((a, b) => Buffer.compare(a, b));
|
|
217
|
+
const outputOwners = new flarejs_1.OutputOwners(new flarejs_1.BigIntPr(this.transaction._locktime), new flarejs_1.Int(changeOutputThreshold), sortedAddresses.map((addr) => new flarejs_1.Address(addr)));
|
|
218
|
+
const transferOutput = new flarejs_1.TransferOutput(new flarejs_1.BigIntPr(changeAmount), outputOwners);
|
|
219
|
+
const changeOutput = new flarejs_1.TransferableOutput(new flarejs_1.Id(assetIdBytes), transferOutput);
|
|
220
|
+
changeOutputs.push(changeOutput);
|
|
221
|
+
}
|
|
222
|
+
// Sort inputs lexicographically by txid (Avalanche protocol requirement)
|
|
223
|
+
const sortedInputsWithCredentials = inputs
|
|
224
|
+
.map((input, i) => ({ input, credential: credentials[i] }))
|
|
225
|
+
.sort((a, b) => {
|
|
226
|
+
const aTxId = Buffer.from(a.input.utxoID.txID.toBytes());
|
|
227
|
+
const bTxId = Buffer.from(b.input.utxoID.txID.toBytes());
|
|
228
|
+
return Buffer.compare(aTxId, bTxId);
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
inputs: sortedInputsWithCredentials.map((x) => x.input),
|
|
232
|
+
changeOutputs,
|
|
233
|
+
credentials: sortedInputsWithCredentials.map((x) => x.credential),
|
|
234
|
+
totalAmount,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create the ExportedOutputs where the recipient address are the sender.
|
|
239
|
+
* Later an importTx should complete the operations signing with the same keys.
|
|
240
|
+
* @protected
|
|
241
|
+
*/
|
|
242
|
+
exportedOutputs() {
|
|
243
|
+
const assetIdBytes = new Uint8Array(Buffer.from(this.transaction._assetId, 'hex'));
|
|
244
|
+
// Create OutputOwners with sorted addresses
|
|
245
|
+
const sortedAddresses = [...this.transaction._fromAddresses].sort((a, b) => Buffer.compare(a, b));
|
|
246
|
+
const outputOwners = new flarejs_1.OutputOwners(new flarejs_1.BigIntPr(this.transaction._locktime), new flarejs_1.Int(this.transaction._threshold), sortedAddresses.map((addr) => new flarejs_1.Address(addr)));
|
|
247
|
+
const output = new flarejs_1.TransferOutput(new flarejs_1.BigIntPr(this._amount), outputOwners);
|
|
248
|
+
return [new flarejs_1.TransferableOutput(new flarejs_1.Id(assetIdBytes), output)];
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Recover UTXOs from inputs
|
|
252
|
+
* @param inputs Array of TransferableInput
|
|
253
|
+
* @returns Array of decoded UTXO objects
|
|
254
|
+
*/
|
|
255
|
+
recoverUtxos(inputs) {
|
|
256
|
+
return inputs.map((input) => {
|
|
257
|
+
const utxoId = input.utxoID;
|
|
258
|
+
// Get the threshold from the input's sigIndices length
|
|
259
|
+
const transferInput = input.input;
|
|
260
|
+
const inputThreshold = transferInput.sigIndicies().length;
|
|
261
|
+
return {
|
|
262
|
+
outputID: iface_1.SECP256K1_Transfer_Output,
|
|
263
|
+
amount: input.amount().toString(),
|
|
264
|
+
txid: utils_1.default.cb58Encode(Buffer.from(utxoId.txID.toBytes())),
|
|
265
|
+
outputidx: utxoId.outputIdx.value().toString(),
|
|
266
|
+
threshold: inputThreshold || this.transaction._threshold,
|
|
267
|
+
addresses: this.transaction._fromAddresses.map((addr) => utils_1.default.addressToString(this.transaction._network.hrp, this.transaction._network.alias, Buffer.from(addr))),
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
exports.ExportInPTxBuilder = ExportInPTxBuilder;
|
|
273
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXhwb3J0SW5QVHhCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9FeHBvcnRJblBUeEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EsbURBQTRGO0FBQzVGLHlFQUFzRTtBQUN0RSxtREFnQitCO0FBQy9CLG9EQUE0QjtBQUM1QixtQ0FBOEY7QUFFOUYsTUFBYSxrQkFBbUIsU0FBUSxtREFBd0I7SUFHOUQsWUFBWSxXQUFpQztRQUMzQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkIsMkJBQTJCO1FBQzNCLDRDQUE0QztRQUM1QyxzQ0FBc0M7UUFDdEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGVBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN2Rix3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUM3RyxLQUFLLENBQ04sQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFjLGVBQWU7UUFDM0IsT0FBTywwQkFBZSxDQUFDLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLEtBQXNCO1FBQzNCLE1BQU0sV0FBVyxHQUFHLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDdEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsT0FBTyxHQUFHLFdBQVcsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxX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QVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Z0JBQzlDLFNBQVMsRUFBRSxjQUFjLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVO2dCQUN4RCxTQUFTLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDdEQsZUFBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FDekc7YUFDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUE1VkQsZ0RBNFZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzZUNvaW4gYXMgQ29pbkNvbmZpZyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgQnVpbGRUcmFuc2FjdGlvbkVycm9yLCBOb3RTdXBwb3J0ZWQsIFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEF0b21pY1RyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vYXRvbWljVHJhbnNhY3Rpb25CdWlsZGVyJztcbmltcG9ydCB7XG4gIHB2bVNlcmlhbCxcbiAgYXZheFNlcmlhbCxcbiAgVW5zaWduZWRUeCxcbiAgQmlnSW50UHIsXG4gIEludCxcbiAgSWQsXG4gIFRyYW5zZmVyYWJsZUlucHV0LFxuICBUcmFuc2ZlcmFibGVPdXRwdXQsXG4gIFRyYW5zZmVySW5wdXQsXG4gIEFkZHJlc3MsXG4gIHV0aWxzIGFzIEZsYXJlVXRpbHMsXG4gIFRyYW5zZmVyT3V0cHV0LFxuICBPdXRwdXRPd25lcnMsXG4gIENyZWRlbnRpYWwsXG4gIEJ5dGVzLFxufSBmcm9tICdAZmxhcmVuZXR3b3JrL2ZsYXJlanMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgRGVjb2RlZFV0eG9PYmosIFNFQ1AyNTZLMV9UcmFuc2Zlcl9PdXRwdXQsIEZsYXJlVHJhbnNhY3Rpb25UeXBlLCBUeCB9IGZyb20gJy4vaWZhY2UnO1xuXG5leHBvcnQgY2xhc3MgRXhwb3J0SW5QVHhCdWlsZGVyIGV4dGVuZHMgQXRvbWljVHJhbnNhY3Rpb25CdWlsZGVyIHtcbiAgcHJpdmF0ZSBfYW1vdW50OiBiaWdpbnQ7XG5cbiAgY29uc3RydWN0b3IoX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoX2NvaW5Db25maWcpO1xuICAgIC8vIEZvciBFeHBvcnQgRlJPTSBQLWNoYWluOlxuICAgIC8vIC0gZXh0ZXJuYWwgY2hhaW4gKGRlc3RpbmF0aW9uKSBpcyBDLWNoYWluXG4gICAgLy8gLSBibG9ja2NoYWluIElEIChzb3VyY2UpIGlzIFAtY2hhaW5cbiAgICB0aGlzLl9leHRlcm5hbENoYWluSWQgPSB1dGlscy5jYjU4RGVjb2RlKHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmsuY0NoYWluQmxvY2tjaGFpbklEKTtcbiAgICAvLyBQLWNoYWluIGJsb2NrY2hhaW4gSUQgKGZyb20gbmV0d29yayBjb25maWcgLSBkZWNvZGUgZnJvbSBjYjU4IHRvIGhleClcbiAgICB0aGlzLnRyYW5zYWN0aW9uLl9ibG9ja2NoYWluSUQgPSBCdWZmZXIuZnJvbSh1dGlscy5jYjU4RGVjb2RlKHRoaXMudHJhbnNhY3Rpb24uX25ldHdvcmsuYmxvY2tjaGFpbklEKSkudG9TdHJpbmcoXG4gICAgICAnaGV4J1xuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHRyYW5zYWN0aW9uVHlwZSgpOiBUcmFuc2FjdGlvblR5cGUge1xuICAgIHJldHVybiBUcmFuc2FjdGlvblR5cGUuRXhwb3J0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFtb3VudCBpcyBhIGJpZ2ludCB0aGF0IHNwZWNpZmllcyB0aGUgcXVhbnRpdHkgb2YgdGhlIGFzc2V0IHRoYXQgdGhpcyBvdXRwdXQgb3ducy4gTXVzdCBiZSBwb3NpdGl2ZS5cbiAgICogQHBhcmFtIHtiaWdpbnQgfCBzdHJpbmd9IGFtb3VudCBUaGUgd2l0aGRyYXdhbCBhbW91bnRcbiAgICovXG4gIGFtb3VudCh2YWx1ZTogYmlnaW50IHwgc3RyaW5nKTogdGhpcyB7XG4gICAgY29uc3QgdmFsdWVCaWdJbnQgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gQmlnSW50KHZhbHVlKSA6IHZhbHVlO1xuICAgIHRoaXMudmFsaWRhdGVBbW91bnQodmFsdWVCaWdJbnQpO1xuICAgIHRoaXMuX2Ftb3VudCA9IHZhbHVlQmlnSW50O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaW5pdEJ1aWxkZXIodHg6IFR4LCByYXdCeXRlcz86IEJ1ZmZlciwgcGFyc2VkQ3JlZGVudGlhbHM/OiBDcmVkZW50aWFsW10pOiB0aGlzIHtcbiAgICBjb25zdCBleHBvcnRUeCA9IHR4IGFzIHB2bVNlcmlhbC5FeHBvcnRUeDtcblxuICAgIGlmICghdGhpcy52ZXJpZnlUeFR5cGUoZXhwb3J0VHguX3R5cGUpKSB7XG4gICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkKCdUcmFuc2FjdGlvbiBjYW5ub3QgYmUgcGFyc2VkIG9yIGhhcyBhbiB1bnN1cHBvcnRlZCB0cmFuc2FjdGlvbiB0eXBlJyk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGV4cG9ydGVkT3V0cHV0cyBpcyBhIFRyYW5zZmVyYWJsZU91dHB1dCBhcnJheS5cbiAgICAvLyBJdCdzIGV4cGVjdGVkIHRvIGhhdmUgb25seSBvbmUgb3V0cHV0IHdpdGggdGhlIGFkZHJlc3NlcyBvZiB0aGUgc2VuZGVyLlxuICAgIGNvbnN0IG91dHB1dHMgPSBleHBvcnRUeC5vdXRzO1xuICAgIGlmIChvdXRwdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVHJhbnNhY3Rpb24gY2FuIGhhdmUgb25lIGV4dGVybmFsIG91dHB1dCcpO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dHNbMF07XG4gICAgY29uc3Qgb3V0cHV0VHJhbnNmZXIgPSBvdXRwdXQub3V0cHV0IGFzIFRyYW5zZmVyT3V0cHV0O1xuICAgIGNvbnN0IGFzc2V0SWQgPSBvdXRwdXQuYXNzZXRJZC50b0J5dGVzKCk7XG4gICAgaWYgKEJ1ZmZlci5jb21wYXJlKEJ1ZmZlci5mcm9tKGFzc2V0SWQpLCBCdWZmZXIuZnJvbSh0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLCAnaGV4JykpICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBBc3NldCBJRCBvZiB0aGUgb3V0cHV0IGRvZXMgbm90IG1hdGNoIHRoZSB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dE93bmVycyA9IG91dHB1dFRyYW5zZmVyLm91dHB1dE93bmVycztcblxuICAgIC8vIFNldCBsb2NrdGltZSBmcm9tIG91dHB1dFxuICAgIHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lID0gb3V0cHV0T3duZXJzLmxvY2t0aW1lLnZhbHVlKCk7XG5cbiAgICAvLyBTZXQgdGhyZXNob2xkIGZyb20gb3V0cHV0XG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkID0gb3V0cHV0T3duZXJzLnRocmVzaG9sZC52YWx1ZSgpO1xuXG4gICAgLy8gQ29udmVydCBvdXRwdXQgYWRkcmVzc2VzIHRvIGJ1ZmZlcnMgYW5kIHNldCBhcyBmcm9tQWRkcmVzc2VzXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3NlcyA9IG91dHB1dE93bmVycy5hZGRycy5tYXAoKGFkZHIpID0+IEJ1ZmZlci5mcm9tKGFkZHIudG9CeXRlcygpKSk7XG5cbiAgICAvLyBTZXQgZXh0ZXJuYWwgY2hhaW4gSUQgZnJvbSB0aGUgZGVzdGluYXRpb24gY2hhaW5cbiAgICB0aGlzLl9leHRlcm5hbENoYWluSWQgPSBCdWZmZXIuZnJvbShleHBvcnRUeC5kZXN0aW5hdGlvbi50b0J5dGVzKCkpO1xuXG4gICAgLy8gU2V0IGFtb3VudCBmcm9tIGV4cG9ydGVkIG91dHB1dFxuICAgIHRoaXMuX2Ftb3VudCA9IG91dHB1dFRyYW5zZmVyLmFtb3VudCgpO1xuXG4gICAgLy8gUmVjb3ZlciBVVFhPcyBmcm9tIGJhc2UgdHggaW5wdXRzXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdXR4b3MgPSB0aGlzLnJlY292ZXJVdHhvcyhbLi4uZXhwb3J0VHguYmFzZVR4LmlucHV0c10pO1xuXG4gICAgLy8gQ2FsY3VsYXRlIGFuZCBzZXQgZmVlIGZyb20gaW5wdXQvb3V0cHV0IGRpZmZlcmVuY2VcbiAgICBjb25zdCB0b3RhbElucHV0QW1vdW50ID0gZXhwb3J0VHguYmFzZVR4LmlucHV0cy5yZWR1Y2UoKHN1bSwgaW5wdXQpID0+IHN1bSArIGlucHV0LmFtb3VudCgpLCBCaWdJbnQoMCkpO1xuICAgIGNvbnN0IGNoYW5nZU91dHB1dEFtb3VudCA9IGV4cG9ydFR4LmJhc2VUeC5vdXRwdXRzLnJlZHVjZSgoc3VtLCBvdXQpID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zZmVyT3V0ID0gb3V0Lm91dHB1dCBhcyBUcmFuc2Zlck91dHB1dDtcbiAgICAgIHJldHVybiBzdW0gKyB0cmFuc2Zlck91dC5hbW91bnQoKTtcbiAgICB9LCBCaWdJbnQoMCkpO1xuICAgIGNvbnN0IGZlZSA9IHRvdGFsSW5wdXRBbW91bnQgLSBjaGFuZ2VPdXRwdXRBbW91bnQgLSB0aGlzLl9hbW91bnQ7XG4gICAgdGhpcy50cmFuc2FjdGlvbi5fZmVlLmZlZSA9IGZlZS50b1N0cmluZygpO1xuXG4gICAgLy8gVXNlIGNyZWRlbnRpYWxzIHBhc3NlZCBmcm9tIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgKHByb3Blcmx5IGV4dHJhY3RlZCB1c2luZyBjb2RlYylcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IHBhcnNlZENyZWRlbnRpYWxzIHx8IFtdO1xuICAgIGNvbnN0IGhhc0NyZWRlbnRpYWxzID0gY3JlZGVudGlhbHMubGVuZ3RoID4gMDtcblxuICAgIC8vIElmIHRoZXJlIGFyZSBjcmVkZW50aWFscywgc3RvcmUgdGhlIG9yaWdpbmFsIGJ5dGVzIHRvIHByZXNlcnZlIGV4YWN0IGZvcm1hdFxuICAgIGlmIChyYXdCeXRlcyAmJiBoYXNDcmVkZW50aWFscykge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbi5fcmF3U2lnbmVkQnl0ZXMgPSByYXdCeXRlcztcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgcHJvcGVyIFVuc2lnbmVkVHggd3JhcHBlciB3aXRoIGNyZWRlbnRpYWxzXG4gICAgY29uc3Qgc29ydGVkQWRkcmVzc2VzID0gWy4uLnRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNdLnNvcnQoKGEsIGIpID0+IEJ1ZmZlci5jb21wYXJlKGEsIGIpKTtcblxuICAgIC8vIFdoZW4gY3JlZGVudGlhbHMgd2VyZSBleHRyYWN0ZWQsIHVzZSB0aGVtIGRpcmVjdGx5IHRvIHByZXNlcnZlIGV4aXN0aW5nIHNpZ25hdHVyZXNcbiAgICAvLyBPdGhlcndpc2UsIGNyZWF0ZSBlbXB0eSBjcmVkZW50aWFscyB3aXRoIGVtYmVkZGVkIGFkZHJlc3NlcyBmb3Igc2xvdCBpZGVudGlmaWNhdGlvblxuICAgIGNvbnN0IHR4Q3JlZGVudGlhbHMgPVxuICAgICAgY3JlZGVudGlhbHMubGVuZ3RoID4gMFxuICAgICAgICA/IGNyZWRlbnRpYWxzXG4gICAgICAgIDogZXhwb3J0VHguYmFzZVR4LmlucHV0cy5tYXAoKGlucHV0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2ZlcklucHV0ID0gaW5wdXQuaW5wdXQgYXMgVHJhbnNmZXJJbnB1dDtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0VGhyZXNob2xkID0gdHJhbnNmZXJJbnB1dC5zaWdJbmRpY2llcygpLmxlbmd0aCB8fCB0aGlzLnRyYW5zYWN0aW9uLl90aHJlc2hvbGQ7XG4gICAgICAgICAgICAvLyBDcmVhdGUgZW1wdHkgc2lnbmF0dXJlcyB3aXRoIGVtYmVkZGVkIGFkZHJlc3NlcyBmb3Igc2xvdCBpZGVudGlmaWNhdGlvblxuICAgICAgICAgICAgY29uc3Qgc2lnU2xvdHM6IFJldHVyblR5cGU8dHlwZW9mIHV0aWxzLmNyZWF0ZUVtcHR5U2lnV2l0aEFkZHJlc3M+W10gPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRUaHJlc2hvbGQ7IGkrKykge1xuICAgICAgICAgICAgICBjb25zdCBhZGRySGV4ID0gQnVmZmVyLmZyb20oc29ydGVkQWRkcmVzc2VzW2ldKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgICAgIHNpZ1Nsb3RzLnB1c2godXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRySGV4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3IENyZWRlbnRpYWwoc2lnU2xvdHMpO1xuICAgICAgICAgIH0pO1xuXG4gICAgLy8gQ3JlYXRlIGFkZHJlc3MgbWFwcyBmb3Igc2lnbmluZyAtIG9uZSBwZXIgaW5wdXQvY3JlZGVudGlhbFxuICAgIC8vIEVhY2ggYWRkcmVzcyBtYXAgY29udGFpbnMgYWxsIGFkZHJlc3NlcyBtYXBwZWQgdG8gdGhlaXIgaW5kaWNlc1xuICAgIGNvbnN0IGFkZHJlc3NNYXBzID0gdHhDcmVkZW50aWFscy5tYXAoKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzc01hcCA9IG5ldyBGbGFyZVV0aWxzLkFkZHJlc3NNYXAoKTtcbiAgICAgIHNvcnRlZEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyLCBpKSA9PiB7XG4gICAgICAgIGFkZHJlc3NNYXAuc2V0KG5ldyBBZGRyZXNzKGFkZHIpLCBpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFkZHJlc3NNYXA7XG4gICAgfSk7XG5cbiAgICAvLyBBbHdheXMgY3JlYXRlIGEgbmV3IFVuc2lnbmVkVHggd2l0aCBwcm9wZXJseSBzdHJ1Y3R1cmVkIGNyZWRlbnRpYWxzXG4gICAgY29uc3QgdW5zaWduZWRUeCA9IG5ldyBVbnNpZ25lZFR4KGV4cG9ydFR4LCBbXSwgbmV3IEZsYXJlVXRpbHMuQWRkcmVzc01hcHMoYWRkcmVzc01hcHMpLCB0eENyZWRlbnRpYWxzKTtcblxuICAgIHRoaXMudHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24odW5zaWduZWRUeCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdGF0aWMgdmVyaWZ5VHhUeXBlKHR4blR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0eG5UeXBlID09PSBGbGFyZVRyYW5zYWN0aW9uVHlwZS5Qdm1FeHBvcnRUeDtcbiAgfVxuXG4gIHZlcmlmeVR4VHlwZSh0eG5UeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gRXhwb3J0SW5QVHhCdWlsZGVyLnZlcmlmeVR4VHlwZSh0eG5UeXBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgZXhwb3J0IHRyYW5zYWN0aW9uIGZvciBQLWNoYWluXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEZsYXJlVHJhbnNhY3Rpb24oKTogdm9pZCB7XG4gICAgLy8gaWYgdHggaGFzIGNyZWRlbnRpYWxzLCB0eCBzaG91bGRuJ3QgY2hhbmdlXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb24uaGFzQ3JlZGVudGlhbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHsgaW5wdXRzLCBjaGFuZ2VPdXRwdXRzLCBjcmVkZW50aWFscywgdG90YWxBbW91bnQgfSA9IHRoaXMuY3JlYXRlRXhwb3J0SW5wdXRzKCk7XG5cbiAgICAvLyBDYWxjdWxhdGUgZmVlIGZyb20gdHJhbnNhY3Rpb24gZmVlIHNldHRpbmdzXG4gICAgY29uc3QgZmVlID0gQmlnSW50KHRoaXMudHJhbnNhY3Rpb24uZmVlLmZlZSk7XG4gICAgY29uc3QgdGFyZ2V0QW1vdW50ID0gdGhpcy5fYW1vdW50ICsgZmVlO1xuXG4gICAgLy8gVmVyaWZ5IHdlIGhhdmUgZW5vdWdoIGZ1bmRzXG4gICAgaWYgKHRvdGFsQW1vdW50IDwgdGFyZ2V0QW1vdW50KSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKGBJbnN1ZmZpY2llbnQgZnVuZHM6IGhhdmUgJHt0b3RhbEFtb3VudH0sIG5lZWQgJHt0YXJnZXRBbW91bnR9YCk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRoZSBCYXNlVHggZm9yIHRoZSBQLWNoYWluIGV4cG9ydCB0cmFuc2FjdGlvblxuICAgIGNvbnN0IGJhc2VUeCA9IG5ldyBhdmF4U2VyaWFsLkJhc2VUeChcbiAgICAgIG5ldyBJbnQodGhpcy50cmFuc2FjdGlvbi5fbmV0d29ya0lEKSxcbiAgICAgIG5ldyBJZChCdWZmZXIuZnJvbSh0aGlzLnRyYW5zYWN0aW9uLl9ibG9ja2NoYWluSUQsICdoZXgnKSksXG4gICAgICBjaGFuZ2VPdXRwdXRzLCAvLyBjaGFuZ2Ugb3V0cHV0c1xuICAgICAgaW5wdXRzLCAvLyBpbnB1dHNcbiAgICAgIG5ldyBCeXRlcyhuZXcgVWludDhBcnJheSgwKSkgLy8gZW1wdHkgbWVtb1xuICAgICk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIFAtY2hhaW4gZXhwb3J0IHRyYW5zYWN0aW9uIHVzaW5nIHB2bVNlcmlhbC5FeHBvcnRUeFxuICAgIGNvbnN0IGV4cG9ydFR4ID0gbmV3IHB2bVNlcmlhbC5FeHBvcnRUeChcbiAgICAgIGJhc2VUeCxcbiAgICAgIG5ldyBJZCh0aGlzLl9leHRlcm5hbENoYWluSWQpLCAvLyBkZXN0aW5hdGlvbkNoYWluIChDLWNoYWluKVxuICAgICAgdGhpcy5leHBvcnRlZE91dHB1dHMoKSAvLyBleHBvcnRlZE91dHB1dHNcbiAgICApO1xuXG4gICAgLy8gQ3JlYXRlIGFkZHJlc3MgbWFwcyBmb3Igc2lnbmluZyAtIG9uZSBwZXIgaW5wdXQvY3JlZGVudGlhbFxuICAgIGNvbnN0IHNvcnRlZEFkZHJlc3NlcyA9IFsuLi50aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzXS5zb3J0KChhLCBiKSA9PiBCdWZmZXIuY29tcGFyZShhLCBiKSk7XG4gICAgY29uc3QgYWRkcmVzc01hcHMgPSBjcmVkZW50aWFscy5tYXAoKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzc01hcCA9IG5ldyBGbGFyZVV0aWxzLkFkZHJlc3NNYXAoKTtcbiAgICAgIHNvcnRlZEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyLCBpKSA9PiB7XG4gICAgICAgIGFkZHJlc3NNYXAuc2V0KG5ldyBBZGRyZXNzKGFkZHIpLCBpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFkZHJlc3NNYXA7XG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgdW5zaWduZWQgdHJhbnNhY3Rpb25cbiAgICBjb25zdCB1bnNpZ25lZFR4ID0gbmV3IFVuc2lnbmVkVHgoXG4gICAgICBleHBvcnRUeCxcbiAgICAgIFtdLCAvLyBFbXB0eSBVVFhPcyBhcnJheVxuICAgICAgbmV3IEZsYXJlVXRpbHMuQWRkcmVzc01hcHMoYWRkcmVzc01hcHMpLFxuICAgICAgY3JlZGVudGlhbHNcbiAgICApO1xuXG4gICAgdGhpcy50cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvbih1bnNpZ25lZFR4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgaW5wdXRzIGZyb20gVVRYT3MgZm9yIFAtY2hhaW4gZXhwb3J0XG4gICAqIE9ubHkgc2VsZWN0cyBlbm91Z2ggVVRYT3MgdG8gY292ZXIgdGhlIHRhcmdldCBhbW91bnQgKGFtb3VudCArIGZlZSlcbiAgICogQHJldHVybnMgaW5wdXRzLCBjaGFuZ2Ugb3V0cHV0cywgY3JlZGVudGlhbHMsIGFuZCB0b3RhbCBhbW91bnRcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVFeHBvcnRJbnB1dHMoKToge1xuICAgIGlucHV0czogVHJhbnNmZXJhYmxlSW5wdXRbXTtcbiAgICBjaGFuZ2VPdXRwdXRzOiBUcmFuc2ZlcmFibGVPdXRwdXRbXTtcbiAgICBjcmVkZW50aWFsczogQ3JlZGVudGlhbFtdO1xuICAgIHRvdGFsQW1vdW50OiBiaWdpbnQ7XG4gIH0ge1xuICAgIGNvbnN0IHNlbmRlciA9IFsuLi50aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzXTtcbiAgICBpZiAodGhpcy5yZWNvdmVyU2lnbmVyKSB7XG4gICAgICAvLyBzd2l0Y2ggZmlyc3QgYW5kIGxhc3Qgc2lnbmVyXG4gICAgICBjb25zdCB0bXAgPSBzZW5kZXIucG9wKCk7XG4gICAgICBzZW5kZXIucHVzaChzZW5kZXJbMF0pO1xuICAgICAgaWYgKHRtcCkge1xuICAgICAgICBzZW5kZXJbMF0gPSB0bXA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZmVlID0gQmlnSW50KHRoaXMudHJhbnNhY3Rpb24uZmVlLmZlZSk7XG4gICAgY29uc3QgdGFyZ2V0QW1vdW50ID0gdGhpcy5fYW1vdW50ICsgZmVlO1xuXG4gICAgbGV0IHRvdGFsQW1vdW50ID0gQmlnSW50KDApO1xuICAgIGNvbnN0IGlucHV0czogVHJhbnNmZXJhYmxlSW5wdXRbXSA9IFtdO1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzOiBDcmVkZW50aWFsW10gPSBbXTtcblxuICAgIC8vIENoYW5nZSBvdXRwdXQgdGhyZXNob2xkIGlzIGFsd2F5cyAxIChtYXRjaGluZyBGbGFyZSBwcm90b2NvbCBiZWhhdmlvcilcbiAgICAvLyBUaGlzIGFsbG93cyBlYXNpZXIgc3BlbmRpbmcgb2YgY2hhbmdlIHdoaWxlIG1haW50YWluaW5nIHNlY3VyaXR5IGZvciBleHBvcnQgb3V0cHV0c1xuICAgIGNvbnN0IGNoYW5nZU91dHB1dFRocmVzaG9sZCA9IDE7XG5cbiAgICAvLyBPbmx5IGNvbnN1bWUgZW5vdWdoIFVUWE9zIHRvIGNvdmVyIHRoZSB0YXJnZXQgYW1vdW50IChpbiBhcnJheSBvcmRlcilcbiAgICAvLyBJbnB1dHMgd2lsbCBiZSBzb3J0ZWQgYWZ0ZXIgc2VsZWN0aW9uXG4gICAgZm9yIChjb25zdCB1dHhvIG9mIHRoaXMudHJhbnNhY3Rpb24uX3V0eG9zKSB7XG4gICAgICAvLyBTdG9wIGlmIHdlIGFscmVhZHkgaGF2ZSBlbm91Z2hcbiAgICAgIGlmICh0b3RhbEFtb3VudCA+PSB0YXJnZXRBbW91bnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFtb3VudCA9IEJpZ0ludCh1dHhvLmFtb3VudCk7XG4gICAgICB0b3RhbEFtb3VudCArPSBhbW91bnQ7XG5cbiAgICAgIC8vIFVzZSB0aGUgVVRYTydzIG93biB0aHJlc2hvbGQgZm9yIHNpZ25hdHVyZSBpbmRpY2VzXG4gICAgICBjb25zdCB1dHhvVGhyZXNob2xkID0gdXR4by50aHJlc2hvbGQgfHwgdGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkO1xuXG4gICAgICAvLyBDcmVhdGUgc2lnbmF0dXJlIGluZGljZXMgZm9yIHRoZSBVVFhPJ3MgdGhyZXNob2xkXG4gICAgICBjb25zdCBzaWdJbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1dHhvVGhyZXNob2xkOyBpKyspIHtcbiAgICAgICAgc2lnSW5kaWNlcy5wdXNoKGkpO1xuICAgICAgfVxuXG4gICAgICAvLyBVc2UgZnJvbU5hdGl2ZSB0byBjcmVhdGUgVHJhbnNmZXJhYmxlSW5wdXRcbiAgICAgIGNvbnN0IHR4SWRDYjU4ID0gdXR4by50eGlkOyAvLyBBbHJlYWR5IGNiNTggZW5jb2RlZFxuICAgICAgY29uc3QgYXNzZXRJZENiNTggPSB1dGlscy5jYjU4RW5jb2RlKEJ1ZmZlci5mcm9tKHRoaXMudHJhbnNhY3Rpb24uX2Fzc2V0SWQsICdoZXgnKSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zZmVyYWJsZUlucHV0ID0gVHJhbnNmZXJhYmxlSW5wdXQuZnJvbU5hdGl2ZShcbiAgICAgICAgdHhJZENiNTgsXG4gICAgICAgIE51bWJlcih1dHhvLm91dHB1dGlkeCksXG4gICAgICAgIGFzc2V0SWRDYjU4LFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIHNpZ0luZGljZXNcbiAgICAgICk7XG5cbiAgICAgIGlucHV0cy5wdXNoKHRyYW5zZmVyYWJsZUlucHV0KTtcblxuICAgICAgLy8gQ3JlYXRlIGNyZWRlbnRpYWwgd2l0aCBlbXB0eSBzaWduYXR1cmVzIHRoYXQgaGF2ZSBlbWJlZGRlZCBhZGRyZXNzZXMgZm9yIHNsb3QgaWRlbnRpZmljYXRpb25cbiAgICAgIC8vIFRoaXMgYWxsb3dzIHRoZSBzaWduaW5nIGxvZ2ljIHRvIGRldGVybWluZSB3aGljaCBzbG90IGJlbG9uZ3MgdG8gd2hpY2ggYWRkcmVzc1xuICAgICAgY29uc3Qgc29ydGVkQWRkcnMgPSBbLi4udGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc10uc29ydCgoYSwgYikgPT4gQnVmZmVyLmNvbXBhcmUoYSwgYikpO1xuICAgICAgY29uc3QgZW1wdHlTaWduYXR1cmVzID0gc2lnSW5kaWNlcy5tYXAoKGlkeCkgPT4ge1xuICAgICAgICBjb25zdCBhZGRySGV4ID0gQnVmZmVyLmZyb20oc29ydGVkQWRkcnNbaWR4XSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICByZXR1cm4gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRySGV4KTtcbiAgICAgIH0pO1xuICAgICAgY3JlZGVudGlhbHMucHVzaChuZXcgQ3JlZGVudGlhbChlbXB0eVNpZ25hdHVyZXMpKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgY2hhbmdlIG91dHB1dCBpZiB0aGVyZSBpcyByZW1haW5pbmcgYW1vdW50IGFmdGVyIGV4cG9ydCBhbmQgZmVlXG4gICAgY29uc3QgY2hhbmdlT3V0cHV0czogVHJhbnNmZXJhYmxlT3V0cHV0W10gPSBbXTtcbiAgICBjb25zdCBjaGFuZ2VBbW91bnQgPSB0b3RhbEFtb3VudCAtIHRoaXMuX2Ftb3VudCAtIGZlZTtcblxuICAgIGlmIChjaGFuZ2VBbW91bnQgPiBCaWdJbnQoMCkpIHtcbiAgICAgIGNvbnN0IGFzc2V0SWRCeXRlcyA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKHRoaXMudHJhbnNhY3Rpb24uX2Fzc2V0SWQsICdoZXgnKSk7XG5cbiAgICAgIC8vIENyZWF0ZSBPdXRwdXRPd25lcnMgd2l0aCB0aGUgUC1jaGFpbiBhZGRyZXNzZXMgKHNvcnRlZCBieSBieXRlIHZhbHVlIGFzIHBlciBBVkFYIHByb3RvY29sKVxuICAgICAgLy8gVXNlIHRocmVzaG9sZD0xIGZvciBjaGFuZ2Ugb3V0cHV0cyAobWF0Y2hpbmcgRmxhcmUgcHJvdG9jb2wgYmVoYXZpb3IpXG4gICAgICBjb25zdCBzb3J0ZWRBZGRyZXNzZXMgPSBbLi4udGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc10uc29ydCgoYSwgYikgPT4gQnVmZmVyLmNvbXBhcmUoYSwgYikpO1xuICAgICAgY29uc3Qgb3V0cHV0T3duZXJzID0gbmV3IE91dHB1dE93bmVycyhcbiAgICAgICAgbmV3IEJpZ0ludFByKHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lKSxcbiAgICAgICAgbmV3IEludChjaGFuZ2VPdXRwdXRUaHJlc2hvbGQpLFxuICAgICAgICBzb3J0ZWRBZGRyZXNzZXMubWFwKChhZGRyKSA9PiBuZXcgQWRkcmVzcyhhZGRyKSlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHRyYW5zZmVyT3V0cHV0ID0gbmV3IFRyYW5zZmVyT3V0cHV0KG5ldyBCaWdJbnRQcihjaGFuZ2VBbW91bnQpLCBvdXRwdXRPd25lcnMpO1xuICAgICAgY29uc3QgY2hhbmdlT3V0cHV0ID0gbmV3IFRyYW5zZmVyYWJsZU91dHB1dChuZXcgSWQoYXNzZXRJZEJ5dGVzKSwgdHJhbnNmZXJPdXRwdXQpO1xuICAgICAgY2hhbmdlT3V0cHV0cy5wdXNoKGNoYW5nZU91dHB1dCk7XG4gICAgfVxuXG4gICAgLy8gU29ydCBpbnB1dHMgbGV4aWNvZ3JhcGhpY2FsbHkgYnkgdHhpZCAoQXZhbGFuY2hlIHByb3RvY29sIHJlcXVpcmVtZW50KVxuICAgIGNvbnN0IHNvcnRlZElucHV0c1dpdGhDcmVkZW50aWFscyA9IGlucHV0c1xuICAgICAgLm1hcCgoaW5wdXQsIGkpID0+ICh7IGlucHV0LCBjcmVkZW50aWFsOiBjcmVkZW50aWFsc1tpXSB9KSlcbiAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGNvbnN0IGFUeElkID0gQnVmZmVyLmZyb20oYS5pbnB1dC51dHhvSUQudHhJRC50b0J5dGVzKCkpO1xuICAgICAgICBjb25zdCBiVHhJZCA9IEJ1ZmZlci5mcm9tKGIuaW5wdXQudXR4b0lELnR4SUQudG9CeXRlcygpKTtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKGFUeElkLCBiVHhJZCk7XG4gICAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dHM6IHNvcnRlZElucHV0c1dpdGhDcmVkZW50aWFscy5tYXAoKHgpID0+IHguaW5wdXQpLFxuICAgICAgY2hhbmdlT3V0cHV0cyxcbiAgICAgIGNyZWRlbnRpYWxzOiBzb3J0ZWRJbnB1dHNXaXRoQ3JlZGVudGlhbHMubWFwKCh4KSA9PiB4LmNyZWRlbnRpYWwpLFxuICAgICAgdG90YWxBbW91bnQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgdGhlIEV4cG9ydGVkT3V0cHV0cyB3aGVyZSB0aGUgcmVjaXBpZW50IGFkZHJlc3MgYXJlIHRoZSBzZW5kZXIuXG4gICAqIExhdGVyIGFuIGltcG9ydFR4IHNob3VsZCBjb21wbGV0ZSB0aGUgb3BlcmF0aW9ucyBzaWduaW5nIHdpdGggdGhlIHNhbWUga2V5cy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGV4cG9ydGVkT3V0cHV0cygpOiBUcmFuc2ZlcmFibGVPdXRwdXRbXSB7XG4gICAgY29uc3QgYXNzZXRJZEJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20odGhpcy50cmFuc2FjdGlvbi5fYXNzZXRJZCwgJ2hleCcpKTtcblxuICAgIC8vIENyZWF0ZSBPdXRwdXRPd25lcnMgd2l0aCBzb3J0ZWQgYWRkcmVzc2VzXG4gICAgY29uc3Qgc29ydGVkQWRkcmVzc2VzID0gWy4uLnRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNdLnNvcnQoKGEsIGIpID0+IEJ1ZmZlci5jb21wYXJlKGEsIGIpKTtcbiAgICBjb25zdCBvdXRwdXRPd25lcnMgPSBuZXcgT3V0cHV0T3duZXJzKFxuICAgICAgbmV3IEJpZ0ludFByKHRoaXMudHJhbnNhY3Rpb24uX2xvY2t0aW1lKSxcbiAgICAgIG5ldyBJbnQodGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkKSxcbiAgICAgIHNvcnRlZEFkZHJlc3Nlcy5tYXAoKGFkZHIpID0+IG5ldyBBZGRyZXNzKGFkZHIpKVxuICAgICk7XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgVHJhbnNmZXJPdXRwdXQobmV3IEJpZ0ludFByKHRoaXMuX2Ftb3VudCksIG91dHB1dE93bmVycyk7XG5cbiAgICByZXR1cm4gW25ldyBUcmFuc2ZlcmFibGVPdXRwdXQobmV3IElkKGFzc2V0SWRCeXRlcyksIG91dHB1dCldO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY292ZXIgVVRYT3MgZnJvbSBpbnB1dHNcbiAgICogQHBhcmFtIGlucHV0cyBBcnJheSBvZiBUcmFuc2ZlcmFibGVJbnB1dFxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBkZWNvZGVkIFVUWE8gb2JqZWN0c1xuICAgKi9cbiAgcHJpdmF0ZSByZWNvdmVyVXR4b3MoaW5wdXRzOiBUcmFuc2ZlcmFibGVJbnB1dFtdKTogRGVjb2RlZFV0eG9PYmpbXSB7XG4gICAgcmV0dXJuIGlucHV0cy5tYXAoKGlucHV0KSA9PiB7XG4gICAgICBjb25zdCB1dHhvSWQgPSBpbnB1dC51dHhvSUQ7XG4gICAgICAvLyBHZXQgdGhlIHRocmVzaG9sZCBmcm9tIHRoZSBpbnB1dCdzIHNpZ0luZGljZXMgbGVuZ3RoXG4gICAgICBjb25zdCB0cmFuc2ZlcklucHV0ID0gaW5wdXQuaW5wdXQgYXMgVHJhbnNmZXJJbnB1dDtcbiAgICAgIGNvbnN0IGlucHV0VGhyZXNob2xkID0gdHJhbnNmZXJJbnB1dC5zaWdJbmRpY2llcygpLmxlbmd0aDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG91dHB1dElEOiBTRUNQMjU2SzFfVHJhbnNmZXJfT3V0cHV0LFxuICAgICAgICBhbW91bnQ6IGlucHV0LmFtb3VudCgpLnRvU3RyaW5nKCksXG4gICAgICAgIHR4aWQ6IHV0aWxzLmNiNThFbmNvZGUoQnVmZmVyLmZyb20odXR4b0lkLnR4SUQudG9CeXRlcygpKSksXG4gICAgICAgIG91dHB1dGlkeDogdXR4b0lkLm91dHB1dElkeC52YWx1ZSgpLnRvU3RyaW5nKCksXG4gICAgICAgIHRocmVzaG9sZDogaW5wdXRUaHJlc2hvbGQgfHwgdGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkLFxuICAgICAgICBhZGRyZXNzZXM6IHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMubWFwKChhZGRyKSA9PlxuICAgICAgICAgIHV0aWxzLmFkZHJlc3NUb1N0cmluZyh0aGlzLnRyYW5zYWN0aW9uLl9uZXR3b3JrLmhycCwgdGhpcy50cmFuc2FjdGlvbi5fbmV0d29yay5hbGlhcywgQnVmZmVyLmZyb20oYWRkcikpXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|