PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-avaxp/dist/src/lib
Просмотр файла: atomicTransactionBuilder.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AtomicTransactionBuilder = void 0;
const avalanche_1 = require("avalanche");
const utils_1 = __importDefault(require("./utils"));
const deprecatedTransactionBuilder_1 = require("./deprecatedTransactionBuilder");
const platformvm_1 = require("avalanche/dist/apis/platformvm");
const sdk_core_1 = require("@bitgo/sdk-core");
const iface_1 = require("./iface");
/**
* Cross-chain transactions (export and import) are atomic operations.
*/
class AtomicTransactionBuilder extends deprecatedTransactionBuilder_1.DeprecatedTransactionBuilder {
constructor(_coinConfig) {
super(_coinConfig);
this.transaction._fee.fee = this.fixedFee;
}
/**
* The internal chain is the one set for the coin in coinConfig.network. The external chain is the other chain involved.
* The external chain id is the source on import and the destination on export.
*
* @param {string} chainId - id of the external chain
*/
externalChainId(chainId) {
const newTargetChainId = typeof chainId === 'string' ? utils_1.default.cb58Decode(chainId) : avalanche_1.Buffer.from(chainId);
this.validateChainId(newTargetChainId);
this._externalChainId = newTargetChainId;
return this;
}
/**
* Fee is fix for AVM atomic tx.
*
* @returns network.txFee
* @protected
*/
get fixedFee() {
return this.transaction._network.txFee;
}
// region utxo engine
/**
* Threshold must be 2 and since output always get reordered we want to make sure we can always add signatures in the correct location
* To find the correct location for the signature, we use the output's addresses to create the signatureIdx in the order that we desire
* 0: user key, 1: hsm key, 2: recovery key
* @protected
*/
createInputOutput(amount) {
const inputs = [];
const outputs = [];
// amount spent so far
let currentTotal = new avalanche_1.BN(0);
// delegating and validating have no fees
const totalTarget = amount.clone();
const credentials = [];
/*
A = user key
B = hsm key
C = backup key
bitgoAddresses = bitgo addresses [ A, B, C ]
utxo.addresses = IMS addresses [ B, C, A ]
utxo.addressesIndex = [ 2, 0, 1 ]
we pick 0, 1 for non-recovery
we pick 1, 2 for recovery
*/
this.transaction._utxos.forEach((utxo) => {
// in WP, output.addressesIndex is empty, so fill it
if (!utxo.addressesIndex || utxo.addressesIndex.length === 0) {
const utxoAddresses = utxo.addresses.map((a) => utils_1.default.parseAddress(a));
utxo.addressesIndex = this.transaction._fromAddresses.map((a) => utxoAddresses.findIndex((u) => a.equals(u)));
}
// in OVC, output.addressesIndex is defined correctly from the previous iteration
});
// validate the utxos
this.transaction._utxos.forEach((utxo) => {
if (!utxo) {
throw new sdk_core_1.BuildTransactionError('Utxo is undefined');
}
// addressesIndex should never have a mismatch
if (utxo.addressesIndex?.includes(-1)) {
throw new sdk_core_1.BuildTransactionError('Addresses are inconsistent: ' + utxo.txid);
}
if (utxo.threshold !== this.transaction._threshold) {
throw new sdk_core_1.BuildTransactionError('Threshold is inconsistent');
}
});
this.transaction._utxos.forEach((utxo, i) => {
if (utxo.outputID === iface_1.SECP256K1_Transfer_Output) {
const txidBuf = utils_1.default.cb58Decode(utxo.txid);
const amt = new avalanche_1.BN(utxo.amount);
const outputidx = utils_1.default.outputidxNumberToBuffer(utxo.outputidx);
const addressesIndex = utxo.addressesIndex ?? [];
// either user (0) or recovery (2)
const firstIndex = this.recoverSigner ? 2 : 0;
const bitgoIndex = 1;
currentTotal = currentTotal.add(amt);
const secpTransferInput = new platformvm_1.SECPTransferInput(amt);
// if user/backup > bitgo
if (addressesIndex[bitgoIndex] < addressesIndex[firstIndex]) {
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), // 9
['', this.transaction._fromAddresses[firstIndex].toString('hex')].map(utils_1.default.createSig)));
}
else {
secpTransferInput.addSignatureIdx(addressesIndex[firstIndex], this.transaction._fromAddresses[firstIndex]);
secpTransferInput.addSignatureIdx(addressesIndex[bitgoIndex], this.transaction._fromAddresses[bitgoIndex]);
credentials.push((0, platformvm_1.SelectCredentialClass)(secpTransferInput.getCredentialID(), [this.transaction._fromAddresses[firstIndex].toString('hex'), ''].map(utils_1.default.createSig)));
}
const input = new platformvm_1.TransferableInput(txidBuf, outputidx, this.transaction._assetId, secpTransferInput);
inputs.push(input);
}
});
if (currentTotal.lt(totalTarget)) {
throw new sdk_core_1.BuildTransactionError(`Utxo outputs get ${currentTotal.toString()} and ${totalTarget.toString()} is required`);
}
else if (currentTotal.gt(totalTarget)) {
outputs.push(new platformvm_1.TransferableOutput(this.transaction._assetId, new platformvm_1.SECPTransferOutput(currentTotal.sub(totalTarget), this.transaction._fromAddresses, this.transaction._locktime, this.transaction._threshold)));
}
return {
inputs,
outputs,
credentials,
};
}
}
exports.AtomicTransactionBuilder = AtomicTransactionBuilder;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbWljVHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9hdG9taWNUcmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EseUNBQXFEO0FBQ3JELG9EQUE0QjtBQUM1QixpRkFBOEU7QUFDOUUsK0RBTXdDO0FBRXhDLDhDQUF3RDtBQUN4RCxtQ0FBb0Q7QUFFcEQ7O0dBRUc7QUFDSCxNQUFzQix3QkFBeUIsU0FBUSwyREFBNEI7SUFHakYsWUFBWSxXQUFpQztRQUMzQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDbkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLE9BQXdCO1FBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxlQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1RyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1FBQ3pDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsSUFBYyxRQUFRO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxxQkFBcUI7SUFDckI7Ozs7O09BS0c7SUFDTyxpQkFBaUIsQ0FBQyxNQUFVO1FBS3BDLE1BQU0sTUFBTSxHQUF3QixFQUFFLENBQUM7UUFDdkMsTUFBTSxPQUFPLEdBQXlCLEVBQUUsQ0FBQztRQUV6QyxzQkFB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RCxNQUFNLEtBQUssR0FBc0IsSUFBSSw4QkFBaUIsQ0FDcEQsT0FBTyxFQUNQLFNBQVMsRUFDVCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsaUJBQWlCLENBQ2xCLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksZ0NBQXFCLENBQzdCLG9CQUFvQixZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsV0FBVyxDQUFDLFFBQVEsRUFBRSxjQUFjLENBQ3hGLENBQUM7UUFDSixDQUFDO2FBQU0sSUFBSSxZQUFZLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLCtCQUFrQixDQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSwrQkFBa0IsQ0FDcEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFDN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQy9CLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUMxQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FDNUIsQ0FDRixDQUNGLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTztZQUNMLE1BQU07WUFDTixPQUFPO1lBQ1AsV0FBVztTQUNaLENBQUM7SUFDSixDQUFDO0NBR0Y7QUE3SkQsNERBNkpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzZUNvaW4gYXMgQ29pbkNvbmZpZyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IEJOLCBCdWZmZXIgYXMgQnVmZmVyQXZheCB9IGZyb20gJ2F2YWxhbmNoZSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBEZXByZWNhdGVkVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi9kZXByZWNhdGVkVHJhbnNhY3Rpb25CdWlsZGVyJztcbmltcG9ydCB7XG4gIFNFQ1BUcmFuc2ZlcklucHV0LFxuICBTRUNQVHJhbnNmZXJPdXRwdXQsXG4gIFNlbGVjdENyZWRlbnRpYWxDbGFzcyxcbiAgVHJhbnNmZXJhYmxlSW5wdXQsXG4gIFRyYW5zZmVyYWJsZU91dHB1dCxcbn0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvYXBpcy9wbGF0Zm9ybXZtJztcbmltcG9ydCB7IENyZWRlbnRpYWwgfSBmcm9tICdhdmFsYW5jaGUvZGlzdC9jb21tb24nO1xuaW1wb3J0IHsgQnVpbGRUcmFuc2FjdGlvbkVycm9yIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFNFQ1AyNTZLMV9UcmFuc2Zlcl9PdXRwdXQgfSBmcm9tICcuL2lmYWNlJztcblxuLyoqXG4gKiBDcm9zcy1jaGFpbiB0cmFuc2FjdGlvbnMgKGV4cG9ydCBhbmQgaW1wb3J0KSBhcmUgYXRvbWljIG9wZXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBdG9taWNUcmFuc2FjdGlvbkJ1aWxkZXIgZXh0ZW5kcyBEZXByZWNhdGVkVHJhbnNhY3Rpb25CdWlsZGVyIHtcbiAgcHJvdGVjdGVkIF9leHRlcm5hbENoYWluSWQ6IEJ1ZmZlckF2YXg7XG5cbiAgY29uc3RydWN0b3IoX2NvaW5Db25maWc6IFJlYWRvbmx5PENvaW5Db25maWc+KSB7XG4gICAgc3VwZXIoX2NvaW5Db25maWcpO1xuICAgIHRoaXMudHJhbnNhY3Rpb24uX2ZlZS5mZWUgPSB0aGlzLmZpeGVkRmVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBpbnRlcm5hbCBjaGFpbiBpcyB0aGUgb25lIHNldCBmb3IgdGhlIGNvaW4gaW4gY29pbkNvbmZpZy5uZXR3b3JrLiBUaGUgZXh0ZXJuYWwgY2hhaW4gaXMgdGhlIG90aGVyIGNoYWluIGludm9sdmVkLlxuICAgKiBUaGUgZXh0ZXJuYWwgY2hhaW4gaWQgaXMgdGhlIHNvdXJjZSBvbiBpbXBvcnQgYW5kIHRoZSBkZXN0aW5hdGlvbiBvbiBleHBvcnQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFpbklkIC0gaWQgb2YgdGhlIGV4dGVybmFsIGNoYWluXG4gICAqL1xuICBleHRlcm5hbENoYWluSWQoY2hhaW5JZDogc3RyaW5nIHwgQnVmZmVyKTogdGhpcyB7XG4gICAgY29uc3QgbmV3VGFyZ2V0Q2hhaW5JZCA9IHR5cGVvZiBjaGFpbklkID09PSAnc3RyaW5nJyA/IHV0aWxzLmNiNThEZWNvZGUoY2hhaW5JZCkgOiBCdWZmZXJBdmF4LmZyb20oY2hhaW5JZCk7XG4gICAgdGhpcy52YWxpZGF0ZUNoYWluSWQobmV3VGFyZ2V0Q2hhaW5JZCk7XG4gICAgdGhpcy5fZXh0ZXJuYWxDaGFpbklkID0gbmV3VGFyZ2V0Q2hhaW5JZDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBGZWUgaXMgZml4IGZvciBBVk0gYXRvbWljIHR4LlxuICAgKlxuICAgKiBAcmV0dXJucyBuZXR3b3JrLnR4RmVlXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBnZXQgZml4ZWRGZWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbi5fbmV0d29yay50eEZlZTtcbiAgfVxuXG4gIC8vIHJlZ2lvbiB1dHhvIGVuZ2luZVxuICAvKipcbiAgICogVGhyZXNob2xkIG11c3QgYmUgMiBhbmQgc2luY2Ugb3V0cHV0IGFsd2F5cyBnZXQgcmVvcmRlcmVkIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGNhbiBhbHdheXMgYWRkIHNpZ25hdHVyZXMgaW4gdGhlIGNvcnJlY3QgbG9jYXRpb25cbiAgICogVG8gZmluZCB0aGUgY29ycmVjdCBsb2NhdGlvbiBmb3IgdGhlIHNpZ25hdHVyZSwgd2UgdXNlIHRoZSBvdXRwdXQncyBhZGRyZXNzZXMgdG8gY3JlYXRlIHRoZSBzaWduYXR1cmVJZHggaW4gdGhlIG9yZGVyIHRoYXQgd2UgZGVzaXJlXG4gICAqIDA6IHVzZXIga2V5LCAxOiBoc20ga2V5LCAyOiByZWNvdmVyeSBrZXlcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUlucHV0T3V0cHV0KGFtb3VudDogQk4pOiB7XG4gICAgaW5wdXRzOiBUcmFuc2ZlcmFibGVJbnB1dFtdO1xuICAgIG91dHB1dHM6IFRyYW5zZmVyYWJsZU91dHB1dFtdO1xuICAgIGNyZWRlbnRpYWxzOiBDcmVkZW50aWFsW107XG4gIH0ge1xuICAgIGNvbnN0IGlucHV0czogVHJhbnNmZXJhYmxlSW5wdXRbXSA9IFtdO1xuICAgIGNvbnN0IG91dHB1dHM6IFRyYW5zZmVyYWJsZU91dHB1dFtdID0gW107XG5cbiAgICAvLyBhbW91bnQgc3BlbnQgc28gZmFyXG4gICAgbGV0IGN1cnJlbnRUb3RhbDogQk4gPSBuZXcgQk4oMCk7XG5cbiAgICAvLyBkZWxlZ2F0aW5nIGFuZCB2YWxpZGF0aW5nIGhhdmUgbm8gZmVlc1xuICAgIGNvbnN0IHRvdGFsVGFyZ2V0ID0gYW1vdW50LmNsb25lKCk7XG5cbiAgICBjb25zdCBjcmVkZW50aWFsczogQ3JlZGVudGlhbFtdID0gW107XG5cbiAgICAvKlxuICAgIEEgPSB1c2VyIGtleVxuICAgIEIgPSBoc20ga2V5XG4gICAgQyA9IGJhY2t1cCBrZXlcbiAgICBiaXRnb0FkZHJlc3NlcyA9IGJpdGdvIGFkZHJlc3NlcyBbIEEsIEIsIEMgXVxuICAgIHV0eG8uYWRkcmVzc2VzID0gSU1TIGFkZHJlc3NlcyBbIEIsIEMsIEEgXVxuICAgIHV0eG8uYWRkcmVzc2VzSW5kZXggPSBbIDIsIDAsIDEgXVxuICAgIHdlIHBpY2sgMCwgMSBmb3Igbm9uLXJlY292ZXJ5XG4gICAgd2UgcGljayAxLCAyIGZvciByZWNvdmVyeVxuICAgICovXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdXR4b3MuZm9yRWFjaCgodXR4bykgPT4ge1xuICAgICAgLy8gaW4gV1AsIG91dHB1dC5hZGRyZXNzZXNJbmRleCBpcyBlbXB0eSwgc28gZmlsbCBpdFxuICAgICAgaWYgKCF1dHhvLmFkZHJlc3Nlc0luZGV4IHx8IHV0eG8uYWRkcmVzc2VzSW5kZXgubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHV0eG9BZGRyZXNzZXM6IEJ1ZmZlckF2YXhbXSA9IHV0eG8uYWRkcmVzc2VzLm1hcCgoYSkgPT4gdXRpbHMucGFyc2VBZGRyZXNzKGEpKTtcbiAgICAgICAgdXR4by5hZGRyZXNzZXNJbmRleCA9IHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMubWFwKChhKSA9PiB1dHhvQWRkcmVzc2VzLmZpbmRJbmRleCgodSkgPT4gYS5lcXVhbHModSkpKTtcbiAgICAgIH1cbiAgICAgIC8vIGluIE9WQywgb3V0cHV0LmFkZHJlc3Nlc0luZGV4IGlzIGRlZmluZWQgY29ycmVjdGx5IGZyb20gdGhlIHByZXZpb3VzIGl0ZXJhdGlvblxuICAgIH0pO1xuXG4gICAgLy8gdmFsaWRhdGUgdGhlIHV0eG9zXG4gICAgdGhpcy50cmFuc2FjdGlvbi5fdXR4b3MuZm9yRWFjaCgodXR4bykgPT4ge1xuICAgICAgaWYgKCF1dHhvKSB7XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ1V0eG8gaXMgdW5kZWZpbmVkJyk7XG4gICAgICB9XG4gICAgICAvLyBhZGRyZXNzZXNJbmRleCBzaG91bGQgbmV2ZXIgaGF2ZSBhIG1pc21hdGNoXG4gICAgICBpZiAodXR4by5hZGRyZXNzZXNJbmRleD8uaW5jbHVkZXMoLTEpKSB7XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0FkZHJlc3NlcyBhcmUgaW5jb25zaXN0ZW50OiAnICsgdXR4by50eGlkKTtcbiAgICAgIH1cbiAgICAgIGlmICh1dHhvLnRocmVzaG9sZCAhPT0gdGhpcy50cmFuc2FjdGlvbi5fdGhyZXNob2xkKSB7XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ1RocmVzaG9sZCBpcyBpbmNvbnNpc3RlbnQnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMudHJhbnNhY3Rpb24uX3V0eG9zLmZvckVhY2goKHV0eG8sIGkpID0+IHtcbiAgICAgIGlmICh1dHhvLm91dHB1dElEID09PSBTRUNQMjU2SzFfVHJhbnNmZXJfT3V0cHV0KSB7XG4gICAgICAgIGNvbnN0IHR4aWRCdWYgPSB1dGlscy5jYjU4RGVjb2RlKHV0eG8udHhpZCk7XG4gICAgICAgIGNvbnN0IGFtdDogQk4gPSBuZXcgQk4odXR4by5hbW91bnQpO1xuICAgICAgICBjb25zdCBvdXRwdXRpZHggPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcih1dHhvLm91dHB1dGlkeCk7XG4gICAgICAgIGNvbnN0IGFkZHJlc3Nlc0luZGV4ID0gdXR4by5hZGRyZXNzZXNJbmRleCA/PyBbXTtcblxuICAgICAgICAvLyBlaXRoZXIgdXNlciAoMCkgb3IgcmVjb3ZlcnkgKDIpXG4gICAgICAgIGNvbnN0IGZpcnN0SW5kZXggPSB0aGlzLnJlY292ZXJTaWduZXIgPyAyIDogMDtcbiAgICAgICAgY29uc3QgYml0Z29JbmRleCA9IDE7XG4gICAgICAgIGN1cnJlbnRUb3RhbCA9IGN1cnJlbnRUb3RhbC5hZGQoYW10KTtcblxuICAgICAgICBjb25zdCBzZWNwVHJhbnNmZXJJbnB1dCA9IG5ldyBTRUNQVHJhbnNmZXJJbnB1dChhbXQpO1xuXG4gICAgICAgIC8vIGlmIHVzZXIvYmFja3VwID4gYml0Z29cbiAgICAgICAgaWYgKGFkZHJlc3Nlc0luZGV4W2JpdGdvSW5kZXhdIDwgYWRkcmVzc2VzSW5kZXhbZmlyc3RJbmRleF0pIHtcbiAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5hZGRTaWduYXR1cmVJZHgoYWRkcmVzc2VzSW5kZXhbYml0Z29JbmRleF0sIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbYml0Z29JbmRleF0pO1xuICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0LmFkZFNpZ25hdHVyZUlkeChhZGRyZXNzZXNJbmRleFtmaXJzdEluZGV4XSwgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tmaXJzdEluZGV4XSk7XG4gICAgICAgICAgY3JlZGVudGlhbHMucHVzaChcbiAgICAgICAgICAgIFNlbGVjdENyZWRlbnRpYWxDbGFzcyhcbiAgICAgICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuZ2V0Q3JlZGVudGlhbElEKCksIC8vIDlcbiAgICAgICAgICAgICAgWycnLCB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2ZpcnN0SW5kZXhdLnRvU3RyaW5nKCdoZXgnKV0ubWFwKHV0aWxzLmNyZWF0ZVNpZylcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlY3BUcmFuc2ZlcklucHV0LmFkZFNpZ25hdHVyZUlkeChhZGRyZXNzZXNJbmRleFtmaXJzdEluZGV4XSwgdGhpcy50cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3Nlc1tmaXJzdEluZGV4XSk7XG4gICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXQuYWRkU2lnbmF0dXJlSWR4KGFkZHJlc3Nlc0luZGV4W2JpdGdvSW5kZXhdLCB0aGlzLnRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzW2JpdGdvSW5kZXhdKTtcbiAgICAgICAgICBjcmVkZW50aWFscy5wdXNoKFxuICAgICAgICAgICAgU2VsZWN0Q3JlZGVudGlhbENsYXNzKFxuICAgICAgICAgICAgICBzZWNwVHJhbnNmZXJJbnB1dC5nZXRDcmVkZW50aWFsSUQoKSxcbiAgICAgICAgICAgICAgW3RoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXNbZmlyc3RJbmRleF0udG9TdHJpbmcoJ2hleCcpLCAnJ10ubWFwKHV0aWxzLmNyZWF0ZVNpZylcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5wdXQ6IFRyYW5zZmVyYWJsZUlucHV0ID0gbmV3IFRyYW5zZmVyYWJsZUlucHV0KFxuICAgICAgICAgIHR4aWRCdWYsXG4gICAgICAgICAgb3V0cHV0aWR4LFxuICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2Fzc2V0SWQsXG4gICAgICAgICAgc2VjcFRyYW5zZmVySW5wdXRcbiAgICAgICAgKTtcbiAgICAgICAgaW5wdXRzLnB1c2goaW5wdXQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGN1cnJlbnRUb3RhbC5sdCh0b3RhbFRhcmdldCkpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoXG4gICAgICAgIGBVdHhvIG91dHB1dHMgZ2V0ICR7Y3VycmVudFRvdGFsLnRvU3RyaW5nKCl9IGFuZCAke3RvdGFsVGFyZ2V0LnRvU3RyaW5nKCl9IGlzIHJlcXVpcmVkYFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRUb3RhbC5ndCh0b3RhbFRhcmdldCkpIHtcbiAgICAgIG91dHB1dHMucHVzaChcbiAgICAgICAgbmV3IFRyYW5zZmVyYWJsZU91dHB1dChcbiAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9hc3NldElkLFxuICAgICAgICAgIG5ldyBTRUNQVHJhbnNmZXJPdXRwdXQoXG4gICAgICAgICAgICBjdXJyZW50VG90YWwuc3ViKHRvdGFsVGFyZ2V0KSxcbiAgICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMsXG4gICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLl9sb2NrdGltZSxcbiAgICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb24uX3RocmVzaG9sZFxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0cyxcbiAgICAgIG91dHB1dHMsXG4gICAgICBjcmVkZW50aWFscyxcbiAgICB9O1xuICB9XG5cbiAgLy8gZW5kcmVnaW9uXG59XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!