@bitgo-beta/sdk-coin-iota 1.0.1-beta.44 → 1.0.1-beta.441
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/README.md +1 -1
- package/dist/src/iota.d.ts +134 -23
- package/dist/src/iota.d.ts.map +1 -1
- package/dist/src/iota.js +286 -46
- package/dist/src/lib/constants.d.ts +59 -6
- package/dist/src/lib/constants.d.ts.map +1 -1
- package/dist/src/lib/constants.js +76 -8
- package/dist/src/lib/iface.d.ts +174 -2
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +1 -1
- package/dist/src/lib/index.d.ts +1 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +4 -2
- package/dist/src/lib/keyPair.d.ts +100 -6
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +103 -10
- package/dist/src/lib/transaction.d.ts +175 -5
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +390 -6
- package/dist/src/lib/transactionBuilder.d.ts +109 -9
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +200 -14
- package/dist/src/lib/transactionBuilderFactory.d.ts +98 -2
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +132 -5
- package/dist/src/lib/transferBuilder.d.ts +52 -2
- package/dist/src/lib/transferBuilder.d.ts.map +1 -1
- package/dist/src/lib/transferBuilder.js +86 -3
- package/dist/src/lib/transferTransaction.d.ts +124 -0
- package/dist/src/lib/transferTransaction.d.ts.map +1 -0
- package/dist/src/lib/transferTransaction.js +341 -0
- package/dist/src/lib/utils.d.ts +108 -7
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +146 -11
- package/dist/test/resources/iota.d.ts +35 -0
- package/dist/test/resources/iota.d.ts.map +1 -0
- package/dist/test/resources/iota.js +93 -0
- package/dist/test/unit/helpers/testHelpers.d.ts +57 -0
- package/dist/test/unit/helpers/testHelpers.d.ts.map +1 -0
- package/dist/test/unit/helpers/testHelpers.js +176 -0
- package/dist/test/unit/index.d.ts +2 -0
- package/dist/test/unit/index.d.ts.map +1 -0
- package/dist/test/unit/index.js +16 -0
- package/dist/test/unit/iota.d.ts +2 -0
- package/dist/test/unit/iota.d.ts.map +1 -0
- package/dist/test/unit/iota.js +501 -0
- package/dist/test/unit/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +108 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.js +188 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +178 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.js +438 -0
- package/dist/test/unit/transferTransaction.d.ts +2 -0
- package/dist/test/unit/transferTransaction.d.ts.map +1 -0
- package/dist/test/unit/transferTransaction.js +218 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +252 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +17 -11
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -28
|
@@ -1,8 +1,178 @@
|
|
|
1
|
-
import { BaseKey, BaseTransaction } from '@bitgo-beta/sdk-core';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { BaseKey, BaseTransaction, PublicKey, TransactionType } from '@bitgo-beta/sdk-core';
|
|
2
|
+
import { BaseCoin as CoinConfig } from '@bitgo-beta/statics';
|
|
3
|
+
import { Transaction as IotaTransaction } from '@iota/iota-sdk/transactions';
|
|
4
|
+
import { TxData, TransactionObjectInput, TransactionExplanation } from './iface';
|
|
5
|
+
/**
|
|
6
|
+
* Base class for IOTA transactions.
|
|
7
|
+
* Manages transaction state, gas data, signatures, and building/serialization.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class Transaction extends BaseTransaction {
|
|
10
|
+
protected _rebuildRequired: boolean;
|
|
11
|
+
protected _type: TransactionType;
|
|
12
|
+
protected _iotaTransaction: IotaTransaction;
|
|
13
|
+
private _gasBudget?;
|
|
14
|
+
private _gasPaymentObjects?;
|
|
15
|
+
private _gasPrice?;
|
|
16
|
+
private _gasSponsor?;
|
|
17
|
+
private _sender;
|
|
18
|
+
private _txDataBytes?;
|
|
19
|
+
private _isSimulateTx;
|
|
20
|
+
private _signature?;
|
|
21
|
+
private _serializedSignature?;
|
|
22
|
+
private _gasSponsorSignature?;
|
|
23
|
+
private _serializedGasSponsorSignature?;
|
|
24
|
+
protected constructor(coinConfig: Readonly<CoinConfig>);
|
|
25
|
+
get gasBudget(): number | undefined;
|
|
26
|
+
set gasBudget(value: number | undefined);
|
|
27
|
+
get gasPaymentObjects(): TransactionObjectInput[] | undefined;
|
|
28
|
+
set gasPaymentObjects(value: TransactionObjectInput[] | undefined);
|
|
29
|
+
get gasPrice(): number | undefined;
|
|
30
|
+
set gasPrice(value: number | undefined);
|
|
31
|
+
get gasSponsor(): string | undefined;
|
|
32
|
+
set gasSponsor(value: string | undefined);
|
|
33
|
+
get sender(): string;
|
|
34
|
+
set sender(value: string);
|
|
35
|
+
/**
|
|
36
|
+
* Indicates whether this is a simulate transaction (dry run) or a real transaction.
|
|
37
|
+
* Simulate transactions use maximum gas values for estimation purposes.
|
|
38
|
+
*/
|
|
39
|
+
get isSimulateTx(): boolean;
|
|
40
|
+
set isSimulateTx(value: boolean);
|
|
41
|
+
/**
|
|
42
|
+
* Marks that the transaction needs to be rebuilt before it can be signed or broadcast.
|
|
43
|
+
*/
|
|
44
|
+
private markRebuildRequired;
|
|
45
|
+
/**
|
|
46
|
+
* Validates transaction data when switching from simulate to real transaction mode.
|
|
47
|
+
*/
|
|
48
|
+
private validateTxDataForRealTransaction;
|
|
49
|
+
/**
|
|
50
|
+
* Returns the signable payload for this transaction.
|
|
51
|
+
* This is the Blake2b hash of the transaction data with intent message.
|
|
52
|
+
* @throws Error if transaction is in simulate mode or not built
|
|
53
|
+
*/
|
|
54
|
+
get signablePayload(): Buffer;
|
|
55
|
+
/**
|
|
56
|
+
* Returns the transaction digest (ID).
|
|
57
|
+
* @throws Error if transaction is not built or needs rebuilding
|
|
58
|
+
*/
|
|
59
|
+
get id(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Ensures the transaction is built and doesn't need rebuilding.
|
|
62
|
+
* @throws Error if transaction is not built or rebuild is required
|
|
63
|
+
*/
|
|
64
|
+
private ensureTransactionIsBuilt;
|
|
65
|
+
/**
|
|
66
|
+
* Adds a signature from the transaction sender.
|
|
67
|
+
*/
|
|
68
|
+
addSignature(publicKey: PublicKey, signature: Buffer): void;
|
|
69
|
+
/**
|
|
70
|
+
* Adds a signature from the gas sponsor (if different from sender).
|
|
71
|
+
*/
|
|
72
|
+
addGasSponsorSignature(publicKey: PublicKey, signature: Buffer): void;
|
|
73
|
+
/**
|
|
74
|
+
* Checks if this transaction can be signed.
|
|
75
|
+
* Only real transactions (not simulate) can be signed.
|
|
76
|
+
*/
|
|
77
|
+
canSign(_key: BaseKey): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Returns the transaction fee (gas budget).
|
|
80
|
+
*/
|
|
81
|
+
getFee(): string | undefined;
|
|
82
|
+
get serializedGasSponsorSignature(): string | undefined;
|
|
83
|
+
get serializedSignature(): string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Serializes all signatures for the transaction.
|
|
86
|
+
* Includes both sender signature and gas sponsor signature if present.
|
|
87
|
+
*/
|
|
88
|
+
serializeSignatures(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Converts the transaction to broadcast format (base64 encoded).
|
|
91
|
+
*/
|
|
92
|
+
toBroadcastFormat(): Promise<string>;
|
|
93
|
+
/**
|
|
94
|
+
* Builds the transaction bytes.
|
|
95
|
+
* If in simulate mode, builds a dry run transaction with max gas values.
|
|
96
|
+
* Otherwise, builds a real transaction with actual gas data.
|
|
97
|
+
*/
|
|
98
|
+
build(): Promise<Uint8Array<ArrayBufferLike>>;
|
|
5
99
|
toJson(): TxData;
|
|
6
|
-
|
|
100
|
+
parseFromJSON(txData: TxData): void;
|
|
101
|
+
/**
|
|
102
|
+
* Parses transaction data from its broadcast format (base64 or raw bytes).
|
|
103
|
+
* Extracts sender, gas data, and gas sponsor information.
|
|
104
|
+
*/
|
|
105
|
+
parseFromBroadcastTx(tx: string | Uint8Array): void;
|
|
106
|
+
/**
|
|
107
|
+
* Parses the sender address from transaction data.
|
|
108
|
+
*/
|
|
109
|
+
private parseSender;
|
|
110
|
+
/**
|
|
111
|
+
* Parses gas-related data from transaction data.
|
|
112
|
+
*/
|
|
113
|
+
private parseGasData;
|
|
114
|
+
/**
|
|
115
|
+
* @inheritDoc
|
|
116
|
+
*/
|
|
117
|
+
explainTransaction(): any;
|
|
118
|
+
/**
|
|
119
|
+
* Updates the simulate transaction flag based on gas data availability.
|
|
120
|
+
* If all gas data is present, switches to real transaction mode.
|
|
121
|
+
*/
|
|
122
|
+
protected updateIsSimulateTx(): void;
|
|
123
|
+
protected abstract messageWithIntent(message: Uint8Array): Uint8Array;
|
|
124
|
+
protected abstract populateTxInputsAndCommands(): void;
|
|
125
|
+
protected abstract validateTxDataImplementation(): void;
|
|
126
|
+
abstract addInputsAndOutputs(): void;
|
|
127
|
+
protected abstract explainTransactionImplementation(json: TxData, explanationResult: TransactionExplanation): TransactionExplanation;
|
|
128
|
+
/**
|
|
129
|
+
* Builds a dry run (simulate) transaction with maximum gas values.
|
|
130
|
+
* Used for gas estimation without committing the transaction.
|
|
131
|
+
*/
|
|
132
|
+
private buildDryRunTransaction;
|
|
133
|
+
/**
|
|
134
|
+
* Builds a real transaction with actual gas data.
|
|
135
|
+
* Only builds if necessary (first time or rebuild required).
|
|
136
|
+
*/
|
|
137
|
+
private buildRealTransaction;
|
|
138
|
+
/**
|
|
139
|
+
* Sets gas data on the IOTA transaction object.
|
|
140
|
+
*/
|
|
141
|
+
private setGasDataOnTransaction;
|
|
142
|
+
/**
|
|
143
|
+
* Populates the IOTA transaction with inputs, commands, and gas sponsor if applicable.
|
|
144
|
+
*/
|
|
145
|
+
private populateTxData;
|
|
146
|
+
/**
|
|
147
|
+
* Checks if the transaction has a gas sponsor different from the sender.
|
|
148
|
+
*/
|
|
149
|
+
private hasDifferentGasSponsor;
|
|
150
|
+
/**
|
|
151
|
+
* Sets up a gas-sponsored transaction by building the transaction kind
|
|
152
|
+
* and setting the gas owner.
|
|
153
|
+
*/
|
|
154
|
+
private setupGasSponsoredTransaction;
|
|
155
|
+
/**
|
|
156
|
+
* Serializes a signature into IOTA's expected format.
|
|
157
|
+
* Format: [signature_scheme_flag (1 byte), signature, public_key]
|
|
158
|
+
* Currently hardcoded to EDDSA (0x00) as IOTA only supports this scheme.
|
|
159
|
+
*/
|
|
160
|
+
private serializeSignature;
|
|
161
|
+
/**
|
|
162
|
+
* Validates all transaction data required for a real (non-simulate) transaction.
|
|
163
|
+
*/
|
|
164
|
+
private validateTxData;
|
|
165
|
+
/**
|
|
166
|
+
* Validates common transaction data (sender, gas data).
|
|
167
|
+
*/
|
|
168
|
+
private validateCommonTxData;
|
|
169
|
+
/**
|
|
170
|
+
* Validates sender and gas sponsor signatures if present.
|
|
171
|
+
*/
|
|
172
|
+
private validateSignatures;
|
|
173
|
+
/**
|
|
174
|
+
* Checks if a signature has valid public key and signature data.
|
|
175
|
+
*/
|
|
176
|
+
private isValidSignature;
|
|
7
177
|
}
|
|
8
178
|
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/lib/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/lib/transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,401 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Transaction = void 0;
|
|
4
7
|
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
+
const transactions_1 = require("@iota/iota-sdk/transactions");
|
|
9
|
+
const utils_1 = require("@iota/iota-sdk/utils");
|
|
10
|
+
const blake2b_1 = __importDefault(require("@bitgo-beta/blake2b"));
|
|
11
|
+
const constants_1 = require("./constants");
|
|
12
|
+
const utils_2 = __importDefault(require("./utils"));
|
|
13
|
+
/**
|
|
14
|
+
* Base class for IOTA transactions.
|
|
15
|
+
* Manages transaction state, gas data, signatures, and building/serialization.
|
|
16
|
+
*/
|
|
5
17
|
class Transaction extends sdk_core_1.BaseTransaction {
|
|
6
|
-
|
|
7
|
-
|
|
18
|
+
constructor(coinConfig) {
|
|
19
|
+
super(coinConfig);
|
|
20
|
+
this._sender = '';
|
|
21
|
+
this._rebuildRequired = false;
|
|
22
|
+
this._isSimulateTx = true;
|
|
23
|
+
}
|
|
24
|
+
// Gas budget getter/setter - marks rebuild required when changed
|
|
25
|
+
get gasBudget() {
|
|
26
|
+
return this._gasBudget;
|
|
27
|
+
}
|
|
28
|
+
set gasBudget(value) {
|
|
29
|
+
this._gasBudget = value;
|
|
30
|
+
this.markRebuildRequired();
|
|
31
|
+
}
|
|
32
|
+
// Gas payment objects getter/setter - marks rebuild required when changed
|
|
33
|
+
get gasPaymentObjects() {
|
|
34
|
+
return this._gasPaymentObjects;
|
|
35
|
+
}
|
|
36
|
+
set gasPaymentObjects(value) {
|
|
37
|
+
this._gasPaymentObjects = value;
|
|
38
|
+
this.markRebuildRequired();
|
|
39
|
+
}
|
|
40
|
+
// Gas price getter/setter - marks rebuild required when changed
|
|
41
|
+
get gasPrice() {
|
|
42
|
+
return this._gasPrice;
|
|
43
|
+
}
|
|
44
|
+
set gasPrice(value) {
|
|
45
|
+
this._gasPrice = value;
|
|
46
|
+
this.markRebuildRequired();
|
|
47
|
+
}
|
|
48
|
+
// Gas sponsor getter/setter - marks rebuild required when changed
|
|
49
|
+
get gasSponsor() {
|
|
50
|
+
return this._gasSponsor;
|
|
51
|
+
}
|
|
52
|
+
set gasSponsor(value) {
|
|
53
|
+
this._gasSponsor = value;
|
|
54
|
+
this.markRebuildRequired();
|
|
55
|
+
}
|
|
56
|
+
// Transaction sender getter/setter - marks rebuild required when changed
|
|
57
|
+
get sender() {
|
|
58
|
+
return this._sender;
|
|
59
|
+
}
|
|
60
|
+
set sender(value) {
|
|
61
|
+
this._sender = value;
|
|
62
|
+
this.markRebuildRequired();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Indicates whether this is a simulate transaction (dry run) or a real transaction.
|
|
66
|
+
* Simulate transactions use maximum gas values for estimation purposes.
|
|
67
|
+
*/
|
|
68
|
+
get isSimulateTx() {
|
|
69
|
+
return this._isSimulateTx;
|
|
70
|
+
}
|
|
71
|
+
set isSimulateTx(value) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
this.validateTxDataForRealTransaction();
|
|
74
|
+
this.markRebuildRequired();
|
|
75
|
+
}
|
|
76
|
+
this._isSimulateTx = value;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Marks that the transaction needs to be rebuilt before it can be signed or broadcast.
|
|
80
|
+
*/
|
|
81
|
+
markRebuildRequired() {
|
|
82
|
+
this._rebuildRequired = true;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validates transaction data when switching from simulate to real transaction mode.
|
|
86
|
+
*/
|
|
87
|
+
validateTxDataForRealTransaction() {
|
|
88
|
+
try {
|
|
89
|
+
this.validateTxData();
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
93
|
+
throw new Error(`Tx data validation failed: ${errorMessage}. {Cause: ${error}}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns the signable payload for this transaction.
|
|
98
|
+
* This is the Blake2b hash of the transaction data with intent message.
|
|
99
|
+
* @throws Error if transaction is in simulate mode or not built
|
|
100
|
+
*/
|
|
101
|
+
get signablePayload() {
|
|
102
|
+
if (this.isSimulateTx) {
|
|
103
|
+
throw new Error('Cannot sign a simulate tx');
|
|
104
|
+
}
|
|
105
|
+
this.ensureTransactionIsBuilt();
|
|
106
|
+
const intentMessage = this.messageWithIntent(this._txDataBytes);
|
|
107
|
+
return Buffer.from((0, blake2b_1.default)(32).update(intentMessage).digest('binary'));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns the transaction digest (ID).
|
|
111
|
+
* @throws Error if transaction is not built or needs rebuilding
|
|
112
|
+
*/
|
|
113
|
+
get id() {
|
|
114
|
+
this.ensureTransactionIsBuilt();
|
|
115
|
+
return transactions_1.TransactionDataBuilder.getDigestFromBytes(this._txDataBytes);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Ensures the transaction is built and doesn't need rebuilding.
|
|
119
|
+
* @throws Error if transaction is not built or rebuild is required
|
|
120
|
+
*/
|
|
121
|
+
ensureTransactionIsBuilt() {
|
|
122
|
+
if (this._txDataBytes === undefined || this._rebuildRequired) {
|
|
123
|
+
throw new Error('Tx not built or a rebuild is required');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Adds a signature from the transaction sender.
|
|
128
|
+
*/
|
|
129
|
+
addSignature(publicKey, signature) {
|
|
130
|
+
this._signature = { publicKey, signature };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Adds a signature from the gas sponsor (if different from sender).
|
|
134
|
+
*/
|
|
135
|
+
addGasSponsorSignature(publicKey, signature) {
|
|
136
|
+
this._gasSponsorSignature = { publicKey, signature };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Checks if this transaction can be signed.
|
|
140
|
+
* Only real transactions (not simulate) can be signed.
|
|
141
|
+
*/
|
|
142
|
+
canSign(_key) {
|
|
143
|
+
return !this.isSimulateTx;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns the transaction fee (gas budget).
|
|
147
|
+
*/
|
|
148
|
+
getFee() {
|
|
149
|
+
return this.gasBudget?.toString();
|
|
150
|
+
}
|
|
151
|
+
get serializedGasSponsorSignature() {
|
|
152
|
+
return this._serializedGasSponsorSignature;
|
|
153
|
+
}
|
|
154
|
+
get serializedSignature() {
|
|
155
|
+
return this._serializedSignature;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Serializes all signatures for the transaction.
|
|
159
|
+
* Includes both sender signature and gas sponsor signature if present.
|
|
160
|
+
*/
|
|
161
|
+
serializeSignatures() {
|
|
162
|
+
this._signatures = [];
|
|
163
|
+
if (this._signature) {
|
|
164
|
+
this._serializedSignature = this.serializeSignature(this._signature);
|
|
165
|
+
this._signatures.push(this._serializedSignature);
|
|
166
|
+
}
|
|
167
|
+
if (this._gasSponsorSignature) {
|
|
168
|
+
this._serializedGasSponsorSignature = this.serializeSignature(this._gasSponsorSignature);
|
|
169
|
+
this._signatures.push(this._serializedGasSponsorSignature);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Converts the transaction to broadcast format (base64 encoded).
|
|
174
|
+
*/
|
|
175
|
+
async toBroadcastFormat() {
|
|
176
|
+
const txDataBytes = await this.build();
|
|
177
|
+
return (0, utils_1.toBase64)(txDataBytes);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Builds the transaction bytes.
|
|
181
|
+
* If in simulate mode, builds a dry run transaction with max gas values.
|
|
182
|
+
* Otherwise, builds a real transaction with actual gas data.
|
|
183
|
+
*/
|
|
184
|
+
async build() {
|
|
185
|
+
if (this.isSimulateTx) {
|
|
186
|
+
return this.buildDryRunTransaction();
|
|
187
|
+
}
|
|
188
|
+
return this.buildRealTransaction();
|
|
8
189
|
}
|
|
9
190
|
toJson() {
|
|
10
|
-
|
|
191
|
+
return {
|
|
192
|
+
sender: this.sender,
|
|
193
|
+
gasBudget: this.gasBudget,
|
|
194
|
+
gasPrice: this.gasPrice,
|
|
195
|
+
gasPaymentObjects: this.gasPaymentObjects,
|
|
196
|
+
gasSponsor: this.gasSponsor,
|
|
197
|
+
type: this.type,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
parseFromJSON(txData) {
|
|
201
|
+
this.sender = txData.sender;
|
|
202
|
+
this.gasBudget = txData.gasBudget;
|
|
203
|
+
this.gasPrice = txData.gasPrice;
|
|
204
|
+
this.gasPaymentObjects = txData.gasPaymentObjects;
|
|
205
|
+
if (txData.gasSponsor !== undefined) {
|
|
206
|
+
this.gasSponsor = txData.gasSponsor;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Parses transaction data from its broadcast format (base64 or raw bytes).
|
|
211
|
+
* Extracts sender, gas data, and gas sponsor information.
|
|
212
|
+
*/
|
|
213
|
+
parseFromBroadcastTx(tx) {
|
|
214
|
+
const txData = transactions_1.Transaction.from(tx).getData();
|
|
215
|
+
this.parseSender(txData);
|
|
216
|
+
this.parseGasData(txData);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Parses the sender address from transaction data.
|
|
220
|
+
*/
|
|
221
|
+
parseSender(txData) {
|
|
222
|
+
if (txData.sender) {
|
|
223
|
+
this.sender = txData.sender;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parses gas-related data from transaction data.
|
|
228
|
+
*/
|
|
229
|
+
parseGasData(txData) {
|
|
230
|
+
const gasData = txData.gasData;
|
|
231
|
+
if (!gasData) {
|
|
232
|
+
this.gasBudget = undefined;
|
|
233
|
+
this.gasPrice = undefined;
|
|
234
|
+
this.gasPaymentObjects = undefined;
|
|
235
|
+
this.gasSponsor = undefined;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
this.gasBudget = gasData.budget ? Number(gasData.budget) : undefined;
|
|
239
|
+
this.gasPrice = gasData.price ? Number(gasData.price) : undefined;
|
|
240
|
+
this.gasPaymentObjects =
|
|
241
|
+
gasData.payment && gasData.payment.length > 0
|
|
242
|
+
? gasData.payment.map((payment) => payment)
|
|
243
|
+
: undefined;
|
|
244
|
+
this.gasSponsor = gasData.owner || undefined;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* @inheritDoc
|
|
248
|
+
*/
|
|
249
|
+
explainTransaction() {
|
|
250
|
+
const result = this.toJson();
|
|
251
|
+
const displayOrder = ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'];
|
|
252
|
+
const outputs = [];
|
|
253
|
+
const explanationResult = {
|
|
254
|
+
displayOrder,
|
|
255
|
+
id: this.id,
|
|
256
|
+
outputs,
|
|
257
|
+
outputAmount: '0',
|
|
258
|
+
changeOutputs: [],
|
|
259
|
+
changeAmount: '0',
|
|
260
|
+
fee: { fee: this.gasBudget ? this.gasBudget.toString() : '' },
|
|
261
|
+
sender: this.sender,
|
|
262
|
+
sponsor: this.gasSponsor,
|
|
263
|
+
type: this.type,
|
|
264
|
+
};
|
|
265
|
+
return this.explainTransactionImplementation(result, explanationResult);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Updates the simulate transaction flag based on gas data availability.
|
|
269
|
+
* If all gas data is present, switches to real transaction mode.
|
|
270
|
+
*/
|
|
271
|
+
updateIsSimulateTx() {
|
|
272
|
+
const hasAllGasData = this.gasBudget && this.gasPrice && this.gasPaymentObjects && this.gasPaymentObjects.length > 0;
|
|
273
|
+
this.isSimulateTx = !hasAllGasData;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Builds a dry run (simulate) transaction with maximum gas values.
|
|
277
|
+
* Used for gas estimation without committing the transaction.
|
|
278
|
+
*/
|
|
279
|
+
async buildDryRunTransaction() {
|
|
280
|
+
this.validateTxDataImplementation();
|
|
281
|
+
await this.populateTxData();
|
|
282
|
+
const txDataBuilder = new transactions_1.TransactionDataBuilder(this._iotaTransaction.getData());
|
|
283
|
+
return txDataBuilder.build({
|
|
284
|
+
overrides: {
|
|
285
|
+
gasData: {
|
|
286
|
+
budget: constants_1.MAX_GAS_BUDGET.toString(),
|
|
287
|
+
price: constants_1.MAX_GAS_PRICE.toString(),
|
|
288
|
+
payment: [],
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Builds a real transaction with actual gas data.
|
|
295
|
+
* Only builds if necessary (first time or rebuild required).
|
|
296
|
+
*/
|
|
297
|
+
async buildRealTransaction() {
|
|
298
|
+
if (this._txDataBytes === undefined || this._rebuildRequired) {
|
|
299
|
+
this.validateTxData();
|
|
300
|
+
await this.populateTxData();
|
|
301
|
+
this.setGasDataOnTransaction();
|
|
302
|
+
this._txDataBytes = await this._iotaTransaction.build();
|
|
303
|
+
this._rebuildRequired = false;
|
|
304
|
+
}
|
|
305
|
+
this.serializeSignatures();
|
|
306
|
+
return this._txDataBytes;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Sets gas data on the IOTA transaction object.
|
|
310
|
+
*/
|
|
311
|
+
setGasDataOnTransaction() {
|
|
312
|
+
this._iotaTransaction.setGasPrice(this.gasPrice);
|
|
313
|
+
this._iotaTransaction.setGasBudget(this.gasBudget);
|
|
314
|
+
this._iotaTransaction.setGasPayment(this.gasPaymentObjects.slice(0, constants_1.MAX_GAS_PAYMENT_OBJECTS - 1));
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Populates the IOTA transaction with inputs, commands, and gas sponsor if applicable.
|
|
318
|
+
*/
|
|
319
|
+
async populateTxData() {
|
|
320
|
+
this._iotaTransaction = new transactions_1.Transaction();
|
|
321
|
+
this.populateTxInputsAndCommands();
|
|
322
|
+
// If gas sponsor is different from sender, set up sponsored transaction
|
|
323
|
+
if (this.hasDifferentGasSponsor()) {
|
|
324
|
+
await this.setupGasSponsoredTransaction();
|
|
325
|
+
}
|
|
326
|
+
this._iotaTransaction.setSender(this.sender);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Checks if the transaction has a gas sponsor different from the sender.
|
|
330
|
+
*/
|
|
331
|
+
hasDifferentGasSponsor() {
|
|
332
|
+
return Boolean(this.gasSponsor && this._sender !== this.gasSponsor);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Sets up a gas-sponsored transaction by building the transaction kind
|
|
336
|
+
* and setting the gas owner.
|
|
337
|
+
*/
|
|
338
|
+
async setupGasSponsoredTransaction() {
|
|
339
|
+
const transactionKind = await this._iotaTransaction.build({ onlyTransactionKind: true });
|
|
340
|
+
this._iotaTransaction = transactions_1.Transaction.fromKind(transactionKind);
|
|
341
|
+
this._iotaTransaction.setGasOwner(this._gasSponsor);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Serializes a signature into IOTA's expected format.
|
|
345
|
+
* Format: [signature_scheme_flag (1 byte), signature, public_key]
|
|
346
|
+
* Currently hardcoded to EDDSA (0x00) as IOTA only supports this scheme.
|
|
347
|
+
*/
|
|
348
|
+
serializeSignature(signature) {
|
|
349
|
+
const SIGNATURE_SCHEME_EDDSA = 0x00;
|
|
350
|
+
const pubKey = Buffer.from(signature.publicKey.pub, 'hex');
|
|
351
|
+
const serializedSignature = new Uint8Array(1 + signature.signature.length + pubKey.length);
|
|
352
|
+
serializedSignature.set([SIGNATURE_SCHEME_EDDSA]);
|
|
353
|
+
serializedSignature.set(signature.signature, 1);
|
|
354
|
+
serializedSignature.set(pubKey, 1 + signature.signature.length);
|
|
355
|
+
return (0, utils_1.toBase64)(serializedSignature);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Validates all transaction data required for a real (non-simulate) transaction.
|
|
359
|
+
*/
|
|
360
|
+
validateTxData() {
|
|
361
|
+
this.validateTxDataImplementation();
|
|
362
|
+
this.validateCommonTxData();
|
|
363
|
+
this.validateSignatures();
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Validates common transaction data (sender, gas data).
|
|
367
|
+
*/
|
|
368
|
+
validateCommonTxData() {
|
|
369
|
+
if (!this.sender) {
|
|
370
|
+
throw new sdk_core_1.InvalidTransactionError('Transaction sender is required');
|
|
371
|
+
}
|
|
372
|
+
if (!this.gasPrice) {
|
|
373
|
+
throw new sdk_core_1.InvalidTransactionError('Gas price is required');
|
|
374
|
+
}
|
|
375
|
+
if (!this.gasBudget) {
|
|
376
|
+
throw new sdk_core_1.InvalidTransactionError('Gas budget is required');
|
|
377
|
+
}
|
|
378
|
+
if (!this.gasPaymentObjects || this.gasPaymentObjects.length === 0) {
|
|
379
|
+
throw new sdk_core_1.InvalidTransactionError('Gas payment objects are required');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Validates sender and gas sponsor signatures if present.
|
|
384
|
+
*/
|
|
385
|
+
validateSignatures() {
|
|
386
|
+
if (this._signature && !this.isValidSignature(this._signature)) {
|
|
387
|
+
throw new sdk_core_1.InvalidTransactionError('Invalid sender signature');
|
|
388
|
+
}
|
|
389
|
+
if (this._gasSponsorSignature && !this.isValidSignature(this._gasSponsorSignature)) {
|
|
390
|
+
throw new sdk_core_1.InvalidTransactionError('Invalid gas sponsor signature');
|
|
391
|
+
}
|
|
11
392
|
}
|
|
12
|
-
|
|
13
|
-
|
|
393
|
+
/**
|
|
394
|
+
* Checks if a signature has valid public key and signature data.
|
|
395
|
+
*/
|
|
396
|
+
isValidSignature(signature) {
|
|
397
|
+
return utils_2.default.isValidPublicKey(signature.publicKey.pub) && utils_2.default.isValidSignature((0, utils_1.toBase64)(signature.signature));
|
|
14
398
|
}
|
|
15
399
|
}
|
|
16
400
|
exports.Transaction = Transaction;
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUFnRTtBQUdoRSxNQUFhLFdBQVksU0FBUSwwQkFBZTtJQUM5QyxPQUFPLENBQUMsR0FBWTtRQUNsQixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUNELE1BQU07UUFDSixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUNELGlCQUFpQjtRQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUFWRCxrQ0FVQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJhc2VLZXksIEJhc2VUcmFuc2FjdGlvbiB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IFR4RGF0YSB9IGZyb20gJy4vaWZhY2UnO1xuXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb24gZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb24ge1xuICBjYW5TaWduKGtleTogQmFzZUtleSk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuICB0b0pzb24oKTogVHhEYXRhIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cbiAgdG9Ccm9hZGNhc3RGb3JtYXQoKTogc3RyaW5nIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cbn1cbiJdfQ==
|
|
401
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG1EQVE4QjtBQUU5Qiw4REFJcUM7QUFFckMsZ0RBQWdEO0FBQ2hELGtFQUEwQztBQUMxQywyQ0FBcUY7QUFDckYsb0RBQTRCO0FBRTVCOzs7R0FHRztBQUNILE1BQXNCLFdBQVksU0FBUSwwQkFBZTtJQXVCdkQsWUFBc0IsVUFBZ0M7UUFDcEQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7SUFDNUIsQ0FBQztJQUVELGlFQUFpRTtJQUNqRSxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQUVELElBQUksU0FBUyxDQUFDLEtBQXlCO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCwwRUFBMEU7SUFDMUUsSUFBSSxpQkFBaUI7UUFDbkIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztJQUVELElBQUksaUJBQWlCLENBQUMsS0FBMkM7UUFDL0QsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNoQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLElBQUksUUFBUTtRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBSSxRQUFRLENBQUMsS0FBeUI7UUFDcEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFL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QyxFQUFFLENBQUM7WUFDbkUsTUFBTSxJQUFJLGtDQUF1QixDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLGtCQUFrQjtRQUN4QixJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDL0QsTUFBTSxJQUFJLGtDQUF1QixDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDaEUsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUM7WUFDbkYsTUFBTSxJQUFJLGtDQUF1QixDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDckUsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLGdCQUFnQixDQUFDLFNBQW9CO1FBQzNDLE9BQU8sZUFBSyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksZUFBSyxDQUFDLGdCQUFnQixDQUFDLElBQUEsZ0JBQVEsRUFBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUNsSCxDQUFDO0NBQ0Y7QUFqZUQsa0NBaWVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQmFzZUtleSxcbiAgQmFzZVRyYW5zYWN0aW9uLFxuICBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcixcbiAgUHVibGljS2V5LFxuICBTaWduYXR1cmUsXG4gIFRyYW5zYWN0aW9uUmVjaXBpZW50LFxuICBUcmFuc2FjdGlvblR5cGUsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIENvaW5Db25maWcgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7XG4gIFRyYW5zYWN0aW9uRGF0YSBhcyBJb3RhVHJhbnNhY3Rpb25EYXRhLFxuICBUcmFuc2FjdGlvbiBhcyBJb3RhVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uRGF0YUJ1aWxkZXIgYXMgSW90YVRyYW5zYWN0aW9uRGF0YUJ1aWxkZXIsXG59IGZyb20gJ0Bpb3RhL2lvdGEtc2RrL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBUeERhdGEsIFRyYW5zYWN0aW9uT2JqZWN0SW5wdXQsIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24gfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IHRvQmFzZTY0IH0gZnJvbSAnQGlvdGEvaW90YS1zZGsvdXRpbHMnO1xuaW1wb3J0IGJsYWtlMmIgZnJvbSAnQGJpdGdvLWJldGEvYmxha2UyYic7XG5pbXBvcnQgeyBNQVhfR0FTX0JVREdFVCwgTUFYX0dBU19QQVlNRU5UX09CSkVDVFMsIE1BWF9HQVNfUFJJQ0UgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgSU9UQSB0cmFuc2FjdGlvbnMuXG4gKiBNYW5hZ2VzIHRyYW5zYWN0aW9uIHN0YXRlLCBnYXMgZGF0YSwgc2lnbmF0dXJlcywgYW5kIGJ1aWxkaW5nL3NlcmlhbGl6YXRpb24uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUcmFuc2FjdGlvbiBleHRlbmRzIEJhc2VUcmFuc2FjdGlvbiB7XG4gIC8vIFRyYW5zYWN0aW9uIHN0YXRlIG1hbmFnZW1lbnRcbiAgcHJvdGVjdGVkIF9yZWJ1aWxkUmVxdWlyZWQ6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBfdHlwZTogVHJhbnNhY3Rpb25UeXBlO1xuICBwcm90ZWN0ZWQgX2lvdGFUcmFuc2FjdGlvbjogSW90YVRyYW5zYWN0aW9uO1xuXG4gIC8vIEdhcyBhbmQgcGF5bWVudCBkYXRhXG4gIHByaXZhdGUgX2dhc0J1ZGdldD86IG51bWJlcjtcbiAgcHJpdmF0ZSBfZ2FzUGF5bWVudE9iamVjdHM/OiBUcmFuc2FjdGlvbk9iamVjdElucHV0W107XG4gIHByaXZhdGUgX2dhc1ByaWNlPzogbnVtYmVyO1xuICBwcml2YXRlIF9nYXNTcG9uc29yPzogc3RyaW5nO1xuXG4gIC8vIFRyYW5zYWN0aW9uIGlkZW50aWZpZXJzIGFuZCBkYXRhXG4gIHByaXZhdGUgX3NlbmRlcjogc3RyaW5nO1xuICBwcml2YXRlIF90eERhdGFCeXRlcz86IFVpbnQ4QXJyYXk8QXJyYXlCdWZmZXJMaWtlPjtcbiAgcHJpdmF0ZSBfaXNTaW11bGF0ZVR4OiBib29sZWFuO1xuXG4gIC8vIFNpZ25hdHVyZSBkYXRhXG4gIHByaXZhdGUgX3NpZ25hdHVyZT86IFNpZ25hdHVyZTtcbiAgcHJpdmF0ZSBfc2VyaWFsaXplZFNpZ25hdHVyZT86IHN0cmluZztcbiAgcHJpdmF0ZSBfZ2FzU3BvbnNvclNpZ25hdHVyZT86IFNpZ25hdHVyZTtcbiAgcHJpdmF0ZSBfc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmU/OiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoY29pbkNvbmZpZyk7XG4gICAgdGhpcy5fc2VuZGVyID0gJyc7XG4gICAgdGhpcy5fcmVidWlsZFJlcXVpcmVkID0gZmFsc2U7XG4gICAgdGhpcy5faXNTaW11bGF0ZVR4ID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIEdhcyBidWRnZXQgZ2V0dGVyL3NldHRlciAtIG1hcmtzIHJlYnVpbGQgcmVxdWlyZWQgd2hlbiBjaGFuZ2VkXG4gIGdldCBnYXNCdWRnZXQoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fZ2FzQnVkZ2V0O1xuICB9XG5cbiAgc2V0IGdhc0J1ZGdldCh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fZ2FzQnVkZ2V0ID0gdmFsdWU7XG4gICAgdGhpcy5tYXJrUmVidWlsZFJlcXVpcmVkKCk7XG4gIH1cblxuICAvLyBHYXMgcGF5bWVudCBvYmplY3RzIGdldHRlci9zZXR0ZXIgLSBtYXJrcyByZWJ1aWxkIHJlcXVpcmVkIHdoZW4gY2hhbmdlZFxuICBnZXQgZ2FzUGF5bWVudE9iamVjdHMoKTogVHJhbnNhY3Rpb25PYmplY3RJbnB1dFtdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fZ2FzUGF5bWVudE9iamVjdHM7XG4gIH1cblxuICBzZXQgZ2FzUGF5bWVudE9iamVjdHModmFsdWU6IFRyYW5zYWN0aW9uT2JqZWN0SW5wdXRbXSB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX2dhc1BheW1lbnRPYmplY3RzID0gdmFsdWU7XG4gICAgdGhpcy5tYXJrUmVidWlsZFJlcXVpcmVkKCk7XG4gIH1cblxuICAvLyBHYXMgcHJpY2UgZ2V0dGVyL3NldHRlciAtIG1hcmtzIHJlYnVpbGQgcmVxdWlyZWQgd2hlbiBjaGFuZ2VkXG4gIGdldCBnYXNQcmljZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9nYXNQcmljZTtcbiAgfVxuXG4gIHNldCBnYXNQcmljZSh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fZ2FzUHJpY2UgPSB2YWx1ZTtcbiAgICB0aGlzLm1hcmtSZWJ1aWxkUmVxdWlyZWQoKTtcbiAgfVxuXG4gIC8vIEdhcyBzcG9uc29yIGdldHRlci9zZXR0ZXIgLSBtYXJrcyByZWJ1aWxkIHJlcXVpcmVkIHdoZW4gY2hhbmdlZFxuICBnZXQgZ2FzU3BvbnNvcigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9nYXNTcG9uc29yO1xuICB9XG5cbiAgc2V0IGdhc1Nwb25zb3IodmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX2dhc1Nwb25zb3IgPSB2YWx1ZTtcbiAgICB0aGlzLm1hcmtSZWJ1aWxkUmVxdWlyZWQoKTtcbiAgfVxuXG4gIC8vIFRyYW5zYWN0aW9uIHNlbmRlciBnZXR0ZXIvc2V0dGVyIC0gbWFya3MgcmVidWlsZCByZXF1aXJlZCB3aGVuIGNoYW5nZWRcbiAgZ2V0IHNlbmRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zZW5kZXI7XG4gIH1cblxuICBzZXQgc2VuZGVyKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zZW5kZXIgPSB2YWx1ZTtcbiAgICB0aGlzLm1hcmtSZWJ1aWxkUmVxdWlyZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIGlzIGEgc2ltdWxhdGUgdHJhbnNhY3Rpb24gKGRyeSBydW4pIG9yIGEgcmVhbCB0cmFuc2FjdGlvbi5cbiAgICogU2ltdWxhdGUgdHJhbnNhY3Rpb25zIHVzZSBtYXhpbXVtIGdhcyB2YWx1ZXMgZm9yIGVzdGltYXRpb24gcHVycG9zZXMuXG4gICAqL1xuICBnZXQgaXNTaW11bGF0ZVR4KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pc1NpbXVsYXRlVHg7XG4gIH1cblxuICBzZXQgaXNTaW11bGF0ZVR4KHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhpcy52YWxpZGF0ZVR4RGF0YUZvclJlYWxUcmFuc2FjdGlvbigpO1xuICAgICAgdGhpcy5tYXJrUmVidWlsZFJlcXVpcmVkKCk7XG4gICAgfVxuICAgIHRoaXMuX2lzU2ltdWxhdGVUeCA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoYXQgdGhlIHRyYW5zYWN0aW9uIG5lZWRzIHRvIGJlIHJlYnVpbHQgYmVmb3JlIGl0IGNhbiBiZSBzaWduZWQgb3IgYnJvYWRjYXN0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYXJrUmVidWlsZFJlcXVpcmVkKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlYnVpbGRSZXF1aXJlZCA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRyYW5zYWN0aW9uIGRhdGEgd2hlbiBzd2l0Y2hpbmcgZnJvbSBzaW11bGF0ZSB0byByZWFsIHRyYW5zYWN0aW9uIG1vZGUuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVHhEYXRhRm9yUmVhbFRyYW5zYWN0aW9uKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbGlkYXRlVHhEYXRhKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUeCBkYXRhIHZhbGlkYXRpb24gZmFpbGVkOiAke2Vycm9yTWVzc2FnZX0uIHtDYXVzZTogJHtlcnJvcn19YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNpZ25hYmxlIHBheWxvYWQgZm9yIHRoaXMgdHJhbnNhY3Rpb24uXG4gICAqIFRoaXMgaXMgdGhlIEJsYWtlMmIgaGFzaCBvZiB0aGUgdHJhbnNhY3Rpb24gZGF0YSB3aXRoIGludGVudCBtZXNzYWdlLlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRyYW5zYWN0aW9uIGlzIGluIHNpbXVsYXRlIG1vZGUgb3Igbm90IGJ1aWx0XG4gICAqL1xuICBnZXQgc2lnbmFibGVQYXlsb2FkKCk6IEJ1ZmZlciB7XG4gICAgaWYgKHRoaXMuaXNTaW11bGF0ZVR4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzaWduIGEgc2ltdWxhdGUgdHgnKTtcbiAgICB9XG4gICAgdGhpcy5lbnN1cmVUcmFuc2FjdGlvbklzQnVpbHQoKTtcblxuICAgIGNvbnN0IGludGVudE1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VXaXRoSW50ZW50KHRoaXMuX3R4RGF0YUJ5dGVzIGFzIFVpbnQ4QXJyYXk8QXJyYXlCdWZmZXJMaWtlPik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJsYWtlMmIoMzIpLnVwZGF0ZShpbnRlbnRNZXNzYWdlKS5kaWdlc3QoJ2JpbmFyeScpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0cmFuc2FjdGlvbiBkaWdlc3QgKElEKS5cbiAgICogQHRocm93cyBFcnJvciBpZiB0cmFuc2FjdGlvbiBpcyBub3QgYnVpbHQgb3IgbmVlZHMgcmVidWlsZGluZ1xuICAgKi9cbiAgZ2V0IGlkKCk6IHN0cmluZyB7XG4gICAgdGhpcy5lbnN1cmVUcmFuc2FjdGlvbklzQnVpbHQoKTtcbiAgICByZXR1cm4gSW90YVRyYW5zYWN0aW9uRGF0YUJ1aWxkZXIuZ2V0RGlnZXN0RnJvbUJ5dGVzKHRoaXMuX3R4RGF0YUJ5dGVzIGFzIFVpbnQ4QXJyYXk8QXJyYXlCdWZmZXJMaWtlPik7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGUgdHJhbnNhY3Rpb24gaXMgYnVpbHQgYW5kIGRvZXNuJ3QgbmVlZCByZWJ1aWxkaW5nLlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRyYW5zYWN0aW9uIGlzIG5vdCBidWlsdCBvciByZWJ1aWxkIGlzIHJlcXVpcmVkXG4gICAqL1xuICBwcml2YXRlIGVuc3VyZVRyYW5zYWN0aW9uSXNCdWlsdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fdHhEYXRhQnl0ZXMgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl9yZWJ1aWxkUmVxdWlyZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHggbm90IGJ1aWx0IG9yIGEgcmVidWlsZCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgc2lnbmF0dXJlIGZyb20gdGhlIHRyYW5zYWN0aW9uIHNlbmRlci5cbiAgICovXG4gIGFkZFNpZ25hdHVyZShwdWJsaWNLZXk6IFB1YmxpY0tleSwgc2lnbmF0dXJlOiBCdWZmZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9zaWduYXR1cmUgPSB7IHB1YmxpY0tleSwgc2lnbmF0dXJlIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHNpZ25hdHVyZSBmcm9tIHRoZSBnYXMgc3BvbnNvciAoaWYgZGlmZmVyZW50IGZyb20gc2VuZGVyKS5cbiAgICovXG4gIGFkZEdhc1Nwb25zb3JTaWduYXR1cmUocHVibGljS2V5OiBQdWJsaWNLZXksIHNpZ25hdHVyZTogQnVmZmVyKTogdm9pZCB7XG4gICAgdGhpcy5fZ2FzU3BvbnNvclNpZ25hdHVyZSA9IHsgcHVibGljS2V5LCBzaWduYXR1cmUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyB0cmFuc2FjdGlvbiBjYW4gYmUgc2lnbmVkLlxuICAgKiBPbmx5IHJlYWwgdHJhbnNhY3Rpb25zIChub3Qgc2ltdWxhdGUpIGNhbiBiZSBzaWduZWQuXG4gICAqL1xuICBjYW5TaWduKF9rZXk6IEJhc2VLZXkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuaXNTaW11bGF0ZVR4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRyYW5zYWN0aW9uIGZlZSAoZ2FzIGJ1ZGdldCkuXG4gICAqL1xuICBnZXRGZWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nYXNCdWRnZXQ/LnRvU3RyaW5nKCk7XG4gIH1cblxuICBnZXQgc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmU7XG4gIH1cblxuICBnZXQgc2VyaWFsaXplZFNpZ25hdHVyZSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9zZXJpYWxpemVkU2lnbmF0dXJlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYWxsIHNpZ25hdHVyZXMgZm9yIHRoZSB0cmFuc2FjdGlvbi5cbiAgICogSW5jbHVkZXMgYm90aCBzZW5kZXIgc2lnbmF0dXJlIGFuZCBnYXMgc3BvbnNvciBzaWduYXR1cmUgaWYgcHJlc2VudC5cbiAgICovXG4gIHNlcmlhbGl6ZVNpZ25hdHVyZXMoKTogdm9pZCB7XG4gICAgdGhpcy5fc2lnbmF0dXJlcyA9IFtdO1xuXG4gICAgaWYgKHRoaXMuX3NpZ25hdHVyZSkge1xuICAgICAgdGhpcy5fc2VyaWFsaXplZFNpZ25hdHVyZSA9IHRoaXMuc2VyaWFsaXplU2lnbmF0dXJlKHRoaXMuX3NpZ25hdHVyZSk7XG4gICAgICB0aGlzLl9zaWduYXR1cmVzLnB1c2godGhpcy5fc2VyaWFsaXplZFNpZ25hdHVyZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2dhc1Nwb25zb3JTaWduYXR1cmUpIHtcbiAgICAgIHRoaXMuX3NlcmlhbGl6ZWRHYXNTcG9uc29yU2lnbmF0dXJlID0gdGhpcy5zZXJpYWxpemVTaWduYXR1cmUodGhpcy5fZ2FzU3BvbnNvclNpZ25hdHVyZSk7XG4gICAgICB0aGlzLl9zaWduYXR1cmVzLnB1c2godGhpcy5fc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgdHJhbnNhY3Rpb24gdG8gYnJvYWRjYXN0IGZvcm1hdCAoYmFzZTY0IGVuY29kZWQpLlxuICAgKi9cbiAgYXN5bmMgdG9Ccm9hZGNhc3RGb3JtYXQoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCB0eERhdGFCeXRlcyA9IGF3YWl0IHRoaXMuYnVpbGQoKTtcbiAgICByZXR1cm4gdG9CYXNlNjQodHhEYXRhQnl0ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgdHJhbnNhY3Rpb24gYnl0ZXMuXG4gICAqIElmIGluIHNpbXVsYXRlIG1vZGUsIGJ1aWxkcyBhIGRyeSBydW4gdHJhbnNhY3Rpb24gd2l0aCBtYXggZ2FzIHZhbHVlcy5cbiAgICogT3RoZXJ3aXNlLCBidWlsZHMgYSByZWFsIHRyYW5zYWN0aW9uIHdpdGggYWN0dWFsIGdhcyBkYXRhLlxuICAgKi9cbiAgYXN5bmMgYnVpbGQoKTogUHJvbWlzZTxVaW50OEFycmF5PEFycmF5QnVmZmVyTGlrZT4+IHtcbiAgICBpZiAodGhpcy5pc1NpbXVsYXRlVHgpIHtcbiAgICAgIHJldHVybiB0aGlzLmJ1aWxkRHJ5UnVuVHJhbnNhY3Rpb24oKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYnVpbGRSZWFsVHJhbnNhY3Rpb24oKTtcbiAgfVxuXG4gIHRvSnNvbigpOiBUeERhdGEge1xuICAgIHJldHVybiB7XG4gICAgICBzZW5kZXI6IHRoaXMuc2VuZGVyLFxuICAgICAgZ2FzQnVkZ2V0OiB0aGlzLmdhc0J1ZGdldCxcbiAgICAgIGdhc1ByaWNlOiB0aGlzLmdhc1ByaWNlLFxuICAgICAgZ2FzUGF5bWVudE9iamVjdHM6IHRoaXMuZ2FzUGF5bWVudE9iamVjdHMsXG4gICAgICBnYXNTcG9uc29yOiB0aGlzLmdhc1Nwb25zb3IsXG4gICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgfTtcbiAgfVxuXG4gIHBhcnNlRnJvbUpTT04odHhEYXRhOiBUeERhdGEpOiB2b2lkIHtcbiAgICB0aGlzLnNlbmRlciA9IHR4RGF0YS5zZW5kZXI7XG4gICAgdGhpcy5nYXNCdWRnZXQgPSB0eERhdGEuZ2FzQnVkZ2V0O1xuICAgIHRoaXMuZ2FzUHJpY2UgPSB0eERhdGEuZ2FzUHJpY2U7XG4gICAgdGhpcy5nYXNQYXltZW50T2JqZWN0cyA9IHR4RGF0YS5nYXNQYXltZW50T2JqZWN0cztcbiAgICBpZiAodHhEYXRhLmdhc1Nwb25zb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5nYXNTcG9uc29yID0gdHhEYXRhLmdhc1Nwb25zb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlcyB0cmFuc2FjdGlvbiBkYXRhIGZyb20gaXRzIGJyb2FkY2FzdCBmb3JtYXQgKGJhc2U2NCBvciByYXcgYnl0ZXMpLlxuICAgKiBFeHRyYWN0cyBzZW5kZXIsIGdhcyBkYXRhLCBhbmQgZ2FzIHNwb25zb3IgaW5mb3JtYXRpb24uXG4gICAqL1xuICBwYXJzZUZyb21Ccm9hZGNhc3RUeCh0eDogc3RyaW5nIHwgVWludDhBcnJheSk6IHZvaWQge1xuICAgIGNvbnN0IHR4RGF0YSA9IElvdGFUcmFuc2FjdGlvbi5mcm9tKHR4KS5nZXREYXRhKCk7XG5cbiAgICB0aGlzLnBhcnNlU2VuZGVyKHR4RGF0YSk7XG4gICAgdGhpcy5wYXJzZUdhc0RhdGEodHhEYXRhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgdGhlIHNlbmRlciBhZGRyZXNzIGZyb20gdHJhbnNhY3Rpb24gZGF0YS5cbiAgICovXG4gIHByaXZhdGUgcGFyc2VTZW5kZXIodHhEYXRhOiBSZXR1cm5UeXBlPElvdGFUcmFuc2FjdGlvblsnZ2V0RGF0YSddPik6IHZvaWQge1xuICAgIGlmICh0eERhdGEuc2VuZGVyKSB7XG4gICAgICB0aGlzLnNlbmRlciA9IHR4RGF0YS5zZW5kZXI7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBnYXMtcmVsYXRlZCBkYXRhIGZyb20gdHJhbnNhY3Rpb24gZGF0YS5cbiAgICovXG4gIHByaXZhdGUgcGFyc2VHYXNEYXRhKHR4RGF0YTogUmV0dXJuVHlwZTxJb3RhVHJhbnNhY3Rpb25bJ2dldERhdGEnXT4pOiB2b2lkIHtcbiAgICBjb25zdCBnYXNEYXRhID0gdHhEYXRhLmdhc0RhdGE7XG5cbiAgICBpZiAoIWdhc0RhdGEpIHtcbiAgICAgIHRoaXMuZ2FzQnVkZ2V0ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5nYXNQcmljZSA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZ2FzUGF5bWVudE9iamVjdHMgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmdhc1Nwb25zb3IgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5nYXNCdWRnZXQgPSBnYXNEYXRhLmJ1ZGdldCA/IE51bWJlcihnYXNEYXRhLmJ1ZGdldCkgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5nYXNQcmljZSA9IGdhc0RhdGEucHJpY2UgPyBOdW1iZXIoZ2FzRGF0YS5wcmljZSkgOiB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmdhc1BheW1lbnRPYmplY3RzID1cbiAgICAgIGdhc0RhdGEucGF5bWVudCAmJiBnYXNEYXRhLnBheW1lbnQubGVuZ3RoID4gMFxuICAgICAgICA/IGdhc0RhdGEucGF5bWVudC5tYXAoKHBheW1lbnQpID0+IHBheW1lbnQgYXMgVHJhbnNhY3Rpb25PYmplY3RJbnB1dClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmdhc1Nwb25zb3IgPSBnYXNEYXRhLm93bmVyIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgZXhwbGFpblRyYW5zYWN0aW9uKCk6IGFueSB7XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy50b0pzb24oKTtcbiAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd0eXBlJ107XG4gICAgY29uc3Qgb3V0cHV0czogVHJhbnNhY3Rpb25SZWNpcGllbnRbXSA9IFtdO1xuXG4gICAgY29uc3QgZXhwbGFuYXRpb25SZXN1bHQ6IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSB7XG4gICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIG91dHB1dHMsXG4gICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICBmZWU6IHsgZmVlOiB0aGlzLmdhc0J1ZGdldCA/IHRoaXMuZ2FzQnVkZ2V0LnRvU3RyaW5nKCkgOiAnJyB9LFxuICAgICAgc2VuZGVyOiB0aGlzLnNlbmRlcixcbiAgICAgIHNwb25zb3I6IHRoaXMuZ2FzU3BvbnNvcixcbiAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uSW1wbGVtZW50YXRpb24ocmVzdWx0LCBleHBsYW5hdGlvblJlc3VsdCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgc2ltdWxhdGUgdHJhbnNhY3Rpb24gZmxhZyBiYXNlZCBvbiBnYXMgZGF0YSBhdmFpbGFiaWxpdHkuXG4gICAqIElmIGFsbCBnYXMgZGF0YSBpcyBwcmVzZW50LCBzd2l0Y2hlcyB0byByZWFsIHRyYW5zYWN0aW9uIG1vZGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlSXNTaW11bGF0ZVR4KCk6IHZvaWQge1xuICAgIGNvbnN0IGhhc0FsbEdhc0RhdGEgPVxuICAgICAgdGhpcy5nYXNCdWRnZXQgJiYgdGhpcy5nYXNQcmljZSAmJiB0aGlzLmdhc1BheW1lbnRPYmplY3RzICYmIHRoaXMuZ2FzUGF5bWVudE9iamVjdHMubGVuZ3RoID4gMDtcblxuICAgIHRoaXMuaXNTaW11bGF0ZVR4ID0gIWhhc0FsbEdhc0RhdGE7XG4gIH1cblxuICAvLyBBYnN0cmFjdCBtZXRob2RzIHRvIGJlIGltcGxlbWVudGVkIGJ5IGNoaWxkIGNsYXNzZXNcbiAgcHJvdGVjdGVkIGFic3RyYWN0IG1lc3NhZ2VXaXRoSW50ZW50KG1lc3NhZ2U6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5O1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcG9wdWxhdGVUeElucHV0c0FuZENvbW1hbmRzKCk6IHZvaWQ7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCB2YWxpZGF0ZVR4RGF0YUltcGxlbWVudGF0aW9uKCk6IHZvaWQ7XG4gIGFic3RyYWN0IGFkZElucHV0c0FuZE91dHB1dHMoKTogdm9pZDtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGV4cGxhaW5UcmFuc2FjdGlvbkltcGxlbWVudGF0aW9uKFxuICAgIGpzb246IFR4RGF0YSxcbiAgICBleHBsYW5hdGlvblJlc3VsdDogVHJhbnNhY3Rpb25FeHBsYW5hdGlvblxuICApOiBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBkcnkgcnVuIChzaW11bGF0ZSkgdHJhbnNhY3Rpb24gd2l0aCBtYXhpbXVtIGdhcyB2YWx1ZXMuXG4gICAqIFVzZWQgZm9yIGdhcyBlc3RpbWF0aW9uIHdpdGhvdXQgY29tbWl0dGluZyB0aGUgdHJhbnNhY3Rpb24uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGJ1aWxkRHJ5UnVuVHJhbnNhY3Rpb24oKTogUHJvbWlzZTxVaW50OEFycmF5PEFycmF5QnVmZmVyTGlrZT4+IHtcbiAgICB0aGlzLnZhbGlkYXRlVHhEYXRhSW1wbGVtZW50YXRpb24oKTtcbiAgICBhd2FpdCB0aGlzLnBvcHVsYXRlVHhEYXRhKCk7XG5cbiAgICBjb25zdCB0eERhdGFCdWlsZGVyID0gbmV3IElvdGFUcmFuc2FjdGlvbkRhdGFCdWlsZGVyKHRoaXMuX2lvdGFUcmFuc2FjdGlvbi5nZXREYXRhKCkgYXMgSW90YVRyYW5zYWN0aW9uRGF0YSk7XG4gICAgcmV0dXJuIHR4RGF0YUJ1aWxkZXIuYnVpbGQoe1xuICAgICAgb3ZlcnJpZGVzOiB7XG4gICAgICAgIGdhc0RhdGE6IHtcbiAgICAgICAgICBidWRnZXQ6IE1BWF9HQVNfQlVER0VULnRvU3RyaW5nKCksXG4gICAgICAgICAgcHJpY2U6IE1BWF9HQVNfUFJJQ0UudG9TdHJpbmcoKSxcbiAgICAgICAgICBwYXltZW50OiBbXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgcmVhbCB0cmFuc2FjdGlvbiB3aXRoIGFjdHVhbCBnYXMgZGF0YS5cbiAgICogT25seSBidWlsZHMgaWYgbmVjZXNzYXJ5IChmaXJzdCB0aW1lIG9yIHJlYnVpbGQgcmVxdWlyZWQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBidWlsZFJlYWxUcmFuc2FjdGlvbigpOiBQcm9taXNlPFVpbnQ4QXJyYXk8QXJyYXlCdWZmZXJMaWtlPj4ge1xuICAgIGlmICh0aGlzLl90eERhdGFCeXRlcyA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX3JlYnVpbGRSZXF1aXJlZCkge1xuICAgICAgdGhpcy52YWxpZGF0ZVR4RGF0YSgpO1xuICAgICAgYXdhaXQgdGhpcy5wb3B1bGF0ZVR4RGF0YSgpO1xuICAgICAgdGhpcy5zZXRHYXNEYXRhT25UcmFuc2FjdGlvbigpO1xuICAgICAgdGhpcy5fdHhEYXRhQnl0ZXMgPSBhd2FpdCB0aGlzLl9pb3RhVHJhbnNhY3Rpb24uYnVpbGQoKTtcbiAgICAgIHRoaXMuX3JlYnVpbGRSZXF1aXJlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMuc2VyaWFsaXplU2lnbmF0dXJlcygpO1xuICAgIHJldHVybiB0aGlzLl90eERhdGFCeXRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGdhcyBkYXRhIG9uIHRoZSBJT1RBIHRyYW5zYWN0aW9uIG9iamVjdC5cbiAgICovXG4gIHByaXZhdGUgc2V0R2FzRGF0YU9uVHJhbnNhY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5faW90YVRyYW5zYWN0aW9uLnNldEdhc1ByaWNlKHRoaXMuZ2FzUHJpY2UhKTtcbiAgICB0aGlzLl9pb3RhVHJhbnNhY3Rpb24uc2V0R2FzQnVkZ2V0KHRoaXMuZ2FzQnVkZ2V0ISk7XG4gICAgdGhpcy5faW90YVRyYW5zYWN0aW9uLnNldEdhc1BheW1lbnQoXG4gICAgICB0aGlzLmdhc1BheW1lbnRPYmplY3RzIS5zbGljZSgwLCBNQVhfR0FTX1BBWU1FTlRfT0JKRUNUUyAtIDEpIGFzIFRyYW5zYWN0aW9uT2JqZWN0SW5wdXRbXVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUG9wdWxhdGVzIHRoZSBJT1RBIHRyYW5zYWN0aW9uIHdpdGggaW5wdXRzLCBjb21tYW5kcywgYW5kIGdhcyBzcG9uc29yIGlmIGFwcGxpY2FibGUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHBvcHVsYXRlVHhEYXRhKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuX2lvdGFUcmFuc2FjdGlvbiA9IG5ldyBJb3RhVHJhbnNhY3Rpb24oKTtcbiAgICB0aGlzLnBvcHVsYXRlVHhJbnB1dHNBbmRDb21tYW5kcygpO1xuXG4gICAgLy8gSWYgZ2FzIHNwb25zb3IgaXMgZGlmZmVyZW50IGZyb20gc2VuZGVyLCBzZXQgdXAgc3BvbnNvcmVkIHRyYW5zYWN0aW9uXG4gICAgaWYgKHRoaXMuaGFzRGlmZmVyZW50R2FzU3BvbnNvcigpKSB7XG4gICAgICBhd2FpdCB0aGlzLnNldHVwR2FzU3BvbnNvcmVkVHJhbnNhY3Rpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pb3RhVHJhbnNhY3Rpb24uc2V0U2VuZGVyKHRoaXMuc2VuZGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHRyYW5zYWN0aW9uIGhhcyBhIGdhcyBzcG9uc29yIGRpZmZlcmVudCBmcm9tIHRoZSBzZW5kZXIuXG4gICAqL1xuICBwcml2YXRlIGhhc0RpZmZlcmVudEdhc1Nwb25zb3IoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEJvb2xlYW4odGhpcy5nYXNTcG9uc29yICYmIHRoaXMuX3NlbmRlciAhPT0gdGhpcy5nYXNTcG9uc29yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHVwIGEgZ2FzLXNwb25zb3JlZCB0cmFuc2FjdGlvbiBieSBidWlsZGluZyB0aGUgdHJhbnNhY3Rpb24ga2luZFxuICAgKiBhbmQgc2V0dGluZyB0aGUgZ2FzIG93bmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cEdhc1Nwb25zb3JlZFRyYW5zYWN0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uS2luZCA9IGF3YWl0IHRoaXMuX2lvdGFUcmFuc2FjdGlvbi5idWlsZCh7IG9ubHlUcmFuc2FjdGlvbktpbmQ6IHRydWUgfSk7XG4gICAgdGhpcy5faW90YVRyYW5zYWN0aW9uID0gSW90YVRyYW5zYWN0aW9uLmZyb21LaW5kKHRyYW5zYWN0aW9uS2luZCk7XG4gICAgdGhpcy5faW90YVRyYW5zYWN0aW9uLnNldEdhc093bmVyKHRoaXMuX2dhc1Nwb25zb3IhKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXJpYWxpemVzIGEgc2lnbmF0dXJlIGludG8gSU9UQSdzIGV4cGVjdGVkIGZvcm1hdC5cbiAgICogRm9ybWF0OiBbc2lnbmF0dXJlX3NjaGVtZV9mbGFnICgxIGJ5dGUpLCBzaWduYXR1cmUsIHB1YmxpY19rZXldXG4gICAqIEN1cnJlbnRseSBoYXJkY29kZWQgdG8gRUREU0EgKDB4MDApIGFzIElPVEEgb25seSBzdXBwb3J0cyB0aGlzIHNjaGVtZS5cbiAgICovXG4gIHByaXZhdGUgc2VyaWFsaXplU2lnbmF0dXJlKHNpZ25hdHVyZTogU2lnbmF0dXJlKTogc3RyaW5nIHtcbiAgICBjb25zdCBTSUdOQVRVUkVfU0NIRU1FX0VERFNBID0gMHgwMDtcbiAgICBjb25zdCBwdWJLZXkgPSBCdWZmZXIuZnJvbShzaWduYXR1cmUucHVibGljS2V5LnB1YiwgJ2hleCcpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRTaWduYXR1cmUgPSBuZXcgVWludDhBcnJheSgxICsgc2lnbmF0dXJlLnNpZ25hdHVyZS5sZW5ndGggKyBwdWJLZXkubGVuZ3RoKTtcblxuICAgIHNlcmlhbGl6ZWRTaWduYXR1cmUuc2V0KFtTSUdOQVRVUkVfU0NIRU1FX0VERFNBXSk7XG4gICAgc2VyaWFsaXplZFNpZ25hdHVyZS5zZXQoc2lnbmF0dXJlLnNpZ25hdHVyZSwgMSk7XG4gICAgc2VyaWFsaXplZFNpZ25hdHVyZS5zZXQocHViS2V5LCAxICsgc2lnbmF0dXJlLnNpZ25hdHVyZS5sZW5ndGgpO1xuXG4gICAgcmV0dXJuIHRvQmFzZTY0KHNlcmlhbGl6ZWRTaWduYXR1cmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhbGwgdHJhbnNhY3Rpb24gZGF0YSByZXF1aXJlZCBmb3IgYSByZWFsIChub24tc2ltdWxhdGUpIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVR4RGF0YSgpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlVHhEYXRhSW1wbGVtZW50YXRpb24oKTtcbiAgICB0aGlzLnZhbGlkYXRlQ29tbW9uVHhEYXRhKCk7XG4gICAgdGhpcy52YWxpZGF0ZVNpZ25hdHVyZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgY29tbW9uIHRyYW5zYWN0aW9uIGRhdGEgKHNlbmRlciwgZ2FzIGRhdGEpLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUNvbW1vblR4RGF0YSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2VuZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ1RyYW5zYWN0aW9uIHNlbmRlciBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5nYXNQcmljZSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdHYXMgcHJpY2UgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZ2FzQnVkZ2V0KSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0dhcyBidWRnZXQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZ2FzUGF5bWVudE9iamVjdHMgfHwgdGhpcy5nYXNQYXltZW50T2JqZWN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignR2FzIHBheW1lbnQgb2JqZWN0cyBhcmUgcmVxdWlyZWQnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHNlbmRlciBhbmQgZ2FzIHNwb25zb3Igc2lnbmF0dXJlcyBpZiBwcmVzZW50LlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVNpZ25hdHVyZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3NpZ25hdHVyZSAmJiAhdGhpcy5pc1ZhbGlkU2lnbmF0dXJlKHRoaXMuX3NpZ25hdHVyZSkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBzZW5kZXIgc2lnbmF0dXJlJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2dhc1Nwb25zb3JTaWduYXR1cmUgJiYgIXRoaXMuaXNWYWxpZFNpZ25hdHVyZSh0aGlzLl9nYXNTcG9uc29yU2lnbmF0dXJlKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGdhcyBzcG9uc29yIHNpZ25hdHVyZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBzaWduYXR1cmUgaGFzIHZhbGlkIHB1YmxpYyBrZXkgYW5kIHNpZ25hdHVyZSBkYXRhLlxuICAgKi9cbiAgcHJpdmF0ZSBpc1ZhbGlkU2lnbmF0dXJlKHNpZ25hdHVyZTogU2lnbmF0dXJlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoc2lnbmF0dXJlLnB1YmxpY0tleS5wdWIpICYmIHV0aWxzLmlzVmFsaWRTaWduYXR1cmUodG9CYXNlNjQoc2lnbmF0dXJlLnNpZ25hdHVyZSkpO1xuICB9XG59XG4iXX0=
|