PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/test/integration_local_rpc/generate
Просмотр файла: RpcClient.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcClientWithWallet = exports.RpcClient = exports.RpcError = void 0;
const assert = require("assert");
const axios_1 = require("axios");
const debug_1 = require("debug");
const networks_1 = require("../../../src/networks");
const utxolib = require('../../../src');
const debug = (0, debug_1.default)('RpcClient');
function sleep(millis) {
return new Promise((resolve) => {
setTimeout(resolve, millis);
});
}
class RpcError extends Error {
constructor(rpcError) {
super(`RPC error: ${rpcError.message} (code=${rpcError.code})`);
this.rpcError = rpcError;
}
static isRpcErrorWithCode(e, code) {
return e instanceof RpcError && e.rpcError.code === code;
}
}
exports.RpcError = RpcError;
const BITCOIN_CORE_22_99 = '/Satoshi:22.99.0/';
class RpcClient {
constructor(network, url, networkInfo) {
this.network = network;
this.url = url;
this.networkInfo = networkInfo;
this.id = 0;
}
/**
* Poor man's Bluebird.map(arr, f, { concurrency })
* Processes promises in batches of 16
*
* @param arr
* @param f
* @param [concurrency=8]
*/
static async parallelMap(arr, f, { concurrency } = { concurrency: 16 }) {
const rest = arr.splice(concurrency);
const result = await Promise.all(arr.map((v, i) => f(v, i)));
if (rest.length) {
return [...result, ...(await this.parallelMap(rest, f))];
}
return result;
}
getUrl() {
return this.url;
}
async exec(method, ...params) {
try {
debug('>', this.getUrl(), method, params);
const response = await axios_1.default.post(this.getUrl(), {
jsonrpc: '1.0',
method,
params,
id: `${this.id++}`,
});
if (method === 'generate' || method === 'generatetoaddress') {
debug('<', '[...]');
}
else {
debug('<', response.data.result);
}
return response.data.result;
}
catch (e) {
if (e.isAxiosError && e.response) {
e = e;
debug('< ERROR', e.response.statusText, e.response.data);
e = e;
const { error = {} } = e.response.data;
throw new RpcError(error);
}
throw e;
}
}
requiresWalletPath() {
if (!this.networkInfo) {
throw new Error(`networkInfo must be set`);
}
return this.networkInfo.subversion === BITCOIN_CORE_22_99;
}
withWallet(walletName) {
if (!this.networkInfo) {
throw new Error(`networkInfo must be set`);
}
return new RpcClientWithWallet(this.network, this.url, this.networkInfo, walletName);
}
async getHelp() {
return this.exec('help');
}
async createWallet(walletName) {
return this.exec('createwallet', walletName);
}
async loadWallet(walletName) {
return this.exec('loadwallet', walletName);
}
async getNetworkInfo() {
return this.exec('getnetworkinfo');
}
async getBlockCount() {
return this.exec('getblockcount');
}
async getRawTransaction(txid) {
return Buffer.from(await this.exec('getrawtransaction', txid), 'hex');
}
async getRawTransactionVerbose(txid) {
const verbose = (0, networks_1.isZcash)(this.network) ? 1 : true;
return await this.exec('getrawtransaction', txid, verbose);
}
async sendRawTransaction(tx) {
return await this.exec('sendrawtransaction', tx.toString('hex'));
}
static async fromEnvvar(network) {
const networkName = (0, networks_1.getNetworkName)(network);
assert(networkName);
const envKey = 'RPC_' + networkName.toUpperCase();
const url = process.env[envKey];
if (url === undefined) {
throw new Error(`envvar ${envKey} not set`);
}
return this.forUrl(network, url);
}
static getSupportedNodeVersions(network) {
switch ((0, networks_1.getMainnet)(network)) {
case utxolib.networks.bitcoin:
return ['/Satoshi:0.20.0/', '/Satoshi:0.21.1/', '/Satoshi:22.0.0/', BITCOIN_CORE_22_99];
case utxolib.networks.bitcoincash:
return ['/Bitcoin Cash Node:23.0.0(EB32.0)/'];
case utxolib.networks.bitcoinsv:
return ['/Bitcoin SV:1.0.5/'];
case utxolib.networks.bitcoingold:
return ['/Bitcoin Gold:0.17.3/'];
case utxolib.networks.dash:
return ['/Dash Core:0.16.1.1/'];
case utxolib.networks.dogecoin:
return ['/Shibetoshi:1.14.5/'];
case utxolib.networks.ecash:
return ['/Bitcoin ABC:0.26.9(EB32.0)/'];
case utxolib.networks.litecoin:
return ['/LitecoinCore:0.17.1/'];
case utxolib.networks.zcash:
return ['/MagicBean:4.7.0/'];
default:
return [];
}
}
static async forUrl(network, url) {
const networkName = (0, networks_1.getNetworkName)(network);
const rpcClient = new RpcClient(network, url);
const networkinfo = await rpcClient.getNetworkInfo();
const versions = this.getSupportedNodeVersions(network);
if (!versions.includes(networkinfo.subversion)) {
throw new Error(`unsupported coin ${networkName} subversion=${networkinfo.subversion} versions=${versions}`);
}
return new RpcClient(network, url, networkinfo);
}
static async forUrlWait(network, url) {
for (let i = 0; i < 600; i++) {
try {
return await this.forUrl(network, url);
}
catch (e) {
console.error(`[${(0, networks_1.getNetworkName)(network)}] ${e}, waiting 1000 millis...`);
await sleep(1000);
}
}
throw new Error(`could not get RpcClient`);
}
}
exports.RpcClient = RpcClient;
class RpcClientWithWallet extends RpcClient {
constructor(network, url, networkInfo, walletName) {
super(network, url, networkInfo);
this.walletName = walletName;
}
getUrl() {
if (this.requiresWalletPath()) {
return super.getUrl() + '/wallet/' + this.walletName;
}
return super.getUrl();
}
async getWalletInfo() {
return await this.exec('getwalletinfo');
}
async getBalance() {
return await this.exec('getbalance');
}
async getNewAddress() {
return this.exec('getnewaddress');
}
async sendToAddress(address, amount) {
return this.exec('sendtoaddress', address, amount);
}
async generateToAddress(n, address) {
switch (this.network) {
case utxolib.networks.zcashTest:
await this.exec('generate', n);
await sleep(1000);
await this.sendToAddress(address, 1);
break;
default:
await this.exec('generatetoaddress', n, address);
}
}
}
exports.RpcClientWithWallet = RpcClientWithWallet;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUnBjQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9pbnRlZ3JhdGlvbl9sb2NhbF9ycGMvZ2VuZXJhdGUvUnBjQ2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlDQUFpQztBQUNqQyxpQ0FBMEM7QUFDMUMsaUNBQStCO0FBRS9CLG9EQUFxRjtBQUdyRixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFeEMsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFVLEVBQUMsV0FBVyxDQUFDLENBQUM7QUFFdEMsU0FBUyxLQUFLLENBQUMsTUFBYztJQUMzQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsVUFBVSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxNQUFhLFFBQVMsU0FBUSxLQUFLO0lBQ2pDLFlBQW1CLFFBQTJDO1FBQzVELEtBQUssQ0FBQyxjQUFjLFFBQVEsQ0FBQyxPQUFPLFVBQVUsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7UUFEL0MsYUFBUSxHQUFSLFFBQVEsQ0FBbUM7SUFFOUQsQ0FBQztJQUVELE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFRLEVBQUUsSUFBWTtRQUM5QyxPQUFPLENBQUMsWUFBWSxRQUFRLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDO0lBQzNELENBQUM7Q0FDRjtBQVJELDRCQVFDO0FBSUQsTUFBTSxrQkFBa0IsR0FBRyxtQkFBbUIsQ0FBQztBQUUvQyxNQUFhLFNBQVM7SUFHcEIsWUFBc0IsT0FBZ0IsRUFBWSxHQUFXLEVBQVksV0FBeUI7UUFBNUUsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUFZLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFBWSxnQkFBVyxHQUFYLFdBQVcsQ0FB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QWUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFTSxLQUFLLENBQUMsVUFBVTtRQUNyQixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDakIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLE9BQWUsRUFBRSxNQUF1QjtRQUMxRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQVMsRUFBRSxPQUFlO1FBQ2hELFFBQVEsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JCLEtBQUssT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTO2dCQUM3QixNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUMvQixNQUFNLEtBQUssQ0FBQyxJQUFLLENBQUMsQ0FBQztnQkFDbkIsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDckMsTUFBTTtZQUNSO2dCQUNFLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDckQsQ0FBQztJQUNILENBQUM7Q0FDRjtBQXZDRCxrREF1Q0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBheGlvcywgeyBBeGlvc0Vycm9yIH0gZnJvbSAnYXhpb3MnO1xuaW1wb3J0IGJ1aWxkRGVidWcgZnJvbSAnZGVidWcnO1xuXG5pbXBvcnQgeyBOZXR3b3JrLCBnZXRNYWlubmV0LCBnZXROZXR3b3JrTmFtZSwgaXNaY2FzaCB9IGZyb20gJy4uLy4uLy4uL3NyYy9uZXR3b3Jrcyc7XG5pbXBvcnQgeyBScGNUcmFuc2FjdGlvbiB9IGZyb20gJy4vUnBjVHlwZXMnO1xuXG5jb25zdCB1dHhvbGliID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjJyk7XG5cbmNvbnN0IGRlYnVnID0gYnVpbGREZWJ1ZygnUnBjQ2xpZW50Jyk7XG5cbmZ1bmN0aW9uIHNsZWVwKG1pbGxpczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBjbGFzcyBScGNFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IocHVibGljIHJwY0Vycm9yOiB7IGNvZGU6IG51bWJlcjsgbWVzc2FnZTogc3RyaW5nIH0pIHtcbiAgICBzdXBlcihgUlBDIGVycm9yOiAke3JwY0Vycm9yLm1lc3NhZ2V9IChjb2RlPSR7cnBjRXJyb3IuY29kZX0pYCk7XG4gIH1cblxuICBzdGF0aWMgaXNScGNFcnJvcldpdGhDb2RlKGU6IEVycm9yLCBjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZSBpbnN0YW5jZW9mIFJwY0Vycm9yICYmIGUucnBjRXJyb3IuY29kZSA9PT0gY29kZTtcbiAgfVxufVxuXG50eXBlIE5ldHdvcmtJbmZvID0geyBzdWJ2ZXJzaW9uOiBzdHJpbmcgfTtcblxuY29uc3QgQklUQ09JTl9DT1JFXzIyXzk5ID0gJy9TYXRvc2hpOjIyLjk5LjAvJztcblxuZXhwb3J0IGNsYXNzIFJwY0NsaWVudCB7XG4gIGlkID0gMDtcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgbmV0d29yazogTmV0d29yaywgcHJvdGVjdGVkIHVybDogc3RyaW5nLCBwcm90ZWN0ZWQgbmV0d29ya0luZm8/OiBOZXR3b3JrSW5mbykge31cblxuICAvKipcbiAgICogUG9vciBtYW4ncyBCbHVlYmlyZC5tYXAoYXJyLCBmLCB7IGNvbmN1cnJlbmN5IH0pXG4gICAqIFByb2Nlc3NlcyBwcm9taXNlcyBpbiBiYXRjaGVzIG9mIDE2XG4gICAqXG4gICAqIEBwYXJhbSBhcnJcbiAgICogQHBhcmFtIGZcbiAgICogQHBhcmFtIFtjb25jdXJyZW5jeT04XVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHBhcmFsbGVsTWFwPFMsIFQ+KFxuICAgIGFycjogU1tdLFxuICAgIGY6IChTLCBpOiBudW1iZXIpID0+IFByb21pc2U8VD4sXG4gICAgeyBjb25jdXJyZW5jeSB9OiB7IGNvbmN1cnJlbmN5OiBudW1iZXIgfSA9IHsgY29uY3VycmVuY3k6IDE2IH1cbiAgKTogUHJvbWlzZTxUW10+IHtcbiAgICBjb25zdCByZXN0OiBTW10gPSBhcnIuc3BsaWNlKGNvbmN1cnJlbmN5KTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLmFsbChhcnIubWFwKCh2LCBpKSA9PiBmKHYsIGkpKSk7XG4gICAgaWYgKHJlc3QubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gWy4uLnJlc3VsdCwgLi4uKGF3YWl0IHRoaXMucGFyYWxsZWxNYXAocmVzdCwgZikpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy51cmw7XG4gIH1cblxuICBhc3luYyBleGVjPFQ+KG1ldGhvZDogc3RyaW5nLCAuLi5wYXJhbXM6IHVua25vd25bXSk6IFByb21pc2U8VD4ge1xuICAgIHRyeSB7XG4gICAgICBkZWJ1ZygnPicsIHRoaXMuZ2V0VXJsKCksIG1ldGhvZCwgcGFyYW1zKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MucG9zdCh0aGlzLmdldFVybCgpLCB7XG4gICAgICAgIGpzb25ycGM6ICcxLjAnLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgaWQ6IGAke3RoaXMuaWQrK31gLFxuICAgICAgfSk7XG4gICAgICBpZiAobWV0aG9kID09PSAnZ2VuZXJhdGUnIHx8IG1ldGhvZCA9PT0gJ2dlbmVyYXRldG9hZGRyZXNzJykge1xuICAgICAgICBkZWJ1ZygnPCcsICdbLi4uXScpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJzwnLCByZXNwb25zZS5kYXRhLnJlc3VsdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5yZXN1bHQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUuaXNBeGlvc0Vycm9yICYmIGUucmVzcG9uc2UpIHtcbiAgICAgICAgZSA9IGUgYXMgQXhpb3NFcnJvcjtcbiAgICAgICAgZGVidWcoJzwgRVJST1InLCBlLnJlc3BvbnNlLnN0YXR1c1RleHQsIGUucmVzcG9uc2UuZGF0YSk7XG4gICAgICAgIGUgPSBlIGFzIEF4aW9zRXJyb3I7XG4gICAgICAgIGNvbnN0IHsgZXJyb3IgPSB7fSB9ID0gZS5yZXNwb25zZS5kYXRhO1xuICAgICAgICB0aHJvdyBuZXcgUnBjRXJyb3IoZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIHJlcXVpcmVzV2FsbGV0UGF0aCgpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMubmV0d29ya0luZm8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbmV0d29ya0luZm8gbXVzdCBiZSBzZXRgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmV0d29ya0luZm8uc3VidmVyc2lvbiA9PT0gQklUQ09JTl9DT1JFXzIyXzk5O1xuICB9XG5cbiAgd2l0aFdhbGxldCh3YWxsZXROYW1lOiBzdHJpbmcpOiBScGNDbGllbnRXaXRoV2FsbGV0IHtcbiAgICBpZiAoIXRoaXMubmV0d29ya0luZm8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbmV0d29ya0luZm8gbXVzdCBiZSBzZXRgKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBScGNDbGllbnRXaXRoV2FsbGV0KHRoaXMubmV0d29yaywgdGhpcy51cmwsIHRoaXMubmV0d29ya0luZm8sIHdhbGxldE5hbWUpO1xuICB9XG5cbiAgYXN5bmMgZ2V0SGVscCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWMoJ2hlbHAnKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVdhbGxldCh3YWxsZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWMoJ2NyZWF0ZXdhbGxldCcsIHdhbGxldE5hbWUpO1xuICB9XG5cbiAgYXN5bmMgbG9hZFdhbGxldCh3YWxsZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWMoJ2xvYWR3YWxsZXQnLCB3YWxsZXROYW1lKTtcbiAgfVxuXG4gIGFzeW5jIGdldE5ldHdvcmtJbmZvKCk6IFByb21pc2U8eyBzdWJ2ZXJzaW9uOiBzdHJpbmcgfT4ge1xuICAgIHJldHVybiB0aGlzLmV4ZWMoJ2dldG5ldHdvcmtpbmZvJyk7XG4gIH1cblxuICBhc3luYyBnZXRCbG9ja0NvdW50KCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlYygnZ2V0YmxvY2tjb3VudCcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmF3VHJhbnNhY3Rpb24odHhpZDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oYXdhaXQgdGhpcy5leGVjPHN0cmluZz4oJ2dldHJhd3RyYW5zYWN0aW9uJywgdHhpZCksICdoZXgnKTtcbiAgfVxuXG4gIGFzeW5jIGdldFJhd1RyYW5zYWN0aW9uVmVyYm9zZSh0eGlkOiBzdHJpbmcpOiBQcm9taXNlPFJwY1RyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdmVyYm9zZSA9IGlzWmNhc2godGhpcy5uZXR3b3JrKSA/IDEgOiB0cnVlO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmV4ZWMoJ2dldHJhd3RyYW5zYWN0aW9uJywgdHhpZCwgdmVyYm9zZSk7XG4gIH1cblxuICBhc3luYyBzZW5kUmF3VHJhbnNhY3Rpb24odHg6IEJ1ZmZlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZXhlYygnc2VuZHJhd3RyYW5zYWN0aW9uJywgdHgudG9TdHJpbmcoJ2hleCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBmcm9tRW52dmFyKG5ldHdvcms6IE5ldHdvcmspOiBQcm9taXNlPFJwY0NsaWVudD4ge1xuICAgIGNvbnN0IG5ldHdvcmtOYW1lID0gZ2V0TmV0d29ya05hbWUobmV0d29yayk7XG4gICAgYXNzZXJ0KG5ldHdvcmtOYW1lKTtcbiAgICBjb25zdCBlbnZLZXkgPSAnUlBDXycgKyBuZXR3b3JrTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIGNvbnN0IHVybCA9IHByb2Nlc3MuZW52W2VudktleV07XG4gICAgaWYgKHVybCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudnZhciAke2VudktleX0gbm90IHNldGApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZvclVybChuZXR3b3JrLCB1cmwpO1xuICB9XG5cbiAgc3RhdGljIGdldFN1cHBvcnRlZE5vZGVWZXJzaW9ucyhuZXR3b3JrOiBOZXR3b3JrKTogc3RyaW5nW10ge1xuICAgIHN3aXRjaCAoZ2V0TWFpbm5ldChuZXR3b3JrKSkge1xuICAgICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW46XG4gICAgICAgIHJldHVybiBbJy9TYXRvc2hpOjAuMjAuMC8nLCAnL1NhdG9zaGk6MC4yMS4xLycsICcvU2F0b3NoaToyMi4wLjAvJywgQklUQ09JTl9DT1JFXzIyXzk5XTtcbiAgICAgIGNhc2UgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luY2FzaDpcbiAgICAgICAgcmV0dXJuIFsnL0JpdGNvaW4gQ2FzaCBOb2RlOjIzLjAuMChFQjMyLjApLyddO1xuICAgICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW5zdjpcbiAgICAgICAgcmV0dXJuIFsnL0JpdGNvaW4gU1Y6MS4wLjUvJ107XG4gICAgICBjYXNlIHV0eG9saWIubmV0d29ya3MuYml0Y29pbmdvbGQ6XG4gICAgICAgIHJldHVybiBbJy9CaXRjb2luIEdvbGQ6MC4xNy4zLyddO1xuICAgICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmRhc2g6XG4gICAgICAgIHJldHVybiBbJy9EYXNoIENvcmU6MC4xNi4xLjEvJ107XG4gICAgICBjYXNlIHV0eG9saWIubmV0d29ya3MuZG9nZWNvaW46XG4gICAgICAgIHJldHVybiBbJy9TaGliZXRvc2hpOjEuMTQuNS8nXTtcbiAgICAgIGNhc2UgdXR4b2xpYi5uZXR3b3Jrcy5lY2FzaDpcbiAgICAgICAgcmV0dXJuIFsnL0JpdGNvaW4gQUJDOjAuMjYuOShFQjMyLjApLyddO1xuICAgICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmxpdGVjb2luOlxuICAgICAgICByZXR1cm4gWycvTGl0ZWNvaW5Db3JlOjAuMTcuMS8nXTtcbiAgICAgIGNhc2UgdXR4b2xpYi5uZXR3b3Jrcy56Y2FzaDpcbiAgICAgICAgcmV0dXJuIFsnL01hZ2ljQmVhbjo0LjcuMC8nXTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZm9yVXJsKG5ldHdvcms6IE5ldHdvcmssIHVybDogc3RyaW5nKTogUHJvbWlzZTxScGNDbGllbnQ+IHtcbiAgICBjb25zdCBuZXR3b3JrTmFtZSA9IGdldE5ldHdvcmtOYW1lKG5ldHdvcmspO1xuICAgIGNvbnN0IHJwY0NsaWVudCA9IG5ldyBScGNDbGllbnQobmV0d29yaywgdXJsKTtcbiAgICBjb25zdCBuZXR3b3JraW5mbyA9IGF3YWl0IHJwY0NsaWVudC5nZXROZXR3b3JrSW5mbygpO1xuXG4gICAgY29uc3QgdmVyc2lvbnMgPSB0aGlzLmdldFN1cHBvcnRlZE5vZGVWZXJzaW9ucyhuZXR3b3JrKTtcbiAgICBpZiAoIXZlcnNpb25zLmluY2x1ZGVzKG5ldHdvcmtpbmZvLnN1YnZlcnNpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGNvaW4gJHtuZXR3b3JrTmFtZX0gc3VidmVyc2lvbj0ke25ldHdvcmtpbmZvLnN1YnZlcnNpb259IHZlcnNpb25zPSR7dmVyc2lvbnN9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBScGNDbGllbnQobmV0d29yaywgdXJsLCBuZXR3b3JraW5mbyk7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZm9yVXJsV2FpdChuZXR3b3JrOiBOZXR3b3JrLCB1cmw6IHN0cmluZyk6IFByb21pc2U8UnBjQ2xpZW50PiB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2MDA7IGkrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZm9yVXJsKG5ldHdvcmssIHVybCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFske2dldE5ldHdvcmtOYW1lKG5ldHdvcmspfV0gJHtlfSwgd2FpdGluZyAxMDAwIG1pbGxpcy4uLmApO1xuICAgICAgICBhd2FpdCBzbGVlcCgxXzAwMCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgY291bGQgbm90IGdldCBScGNDbGllbnRgKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUnBjQ2xpZW50V2l0aFdhbGxldCBleHRlbmRzIFJwY0NsaWVudCB7XG4gIGNvbnN0cnVjdG9yKG5ldHdvcms6IE5ldHdvcmssIHVybDogc3RyaW5nLCBuZXR3b3JrSW5mbzogTmV0d29ya0luZm8sIHByaXZhdGUgd2FsbGV0TmFtZT86IHN0cmluZykge1xuICAgIHN1cGVyKG5ldHdvcmssIHVybCwgbmV0d29ya0luZm8pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFVybCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnJlcXVpcmVzV2FsbGV0UGF0aCgpKSB7XG4gICAgICByZXR1cm4gc3VwZXIuZ2V0VXJsKCkgKyAnL3dhbGxldC8nICsgdGhpcy53YWxsZXROYW1lO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuZ2V0VXJsKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0V2FsbGV0SW5mbygpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZXhlYygnZ2V0d2FsbGV0aW5mbycpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldEJhbGFuY2UoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjKCdnZXRiYWxhbmNlJyk7XG4gIH1cblxuICBhc3luYyBnZXROZXdBZGRyZXNzKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuZXhlYygnZ2V0bmV3YWRkcmVzcycpO1xuICB9XG5cbiAgYXN5bmMgc2VuZFRvQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcsIGFtb3VudDogbnVtYmVyIHwgc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5leGVjKCdzZW5kdG9hZGRyZXNzJywgYWRkcmVzcywgYW1vdW50KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlVG9BZGRyZXNzKG46IG51bWJlciwgYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc3dpdGNoICh0aGlzLm5ldHdvcmspIHtcbiAgICAgIGNhc2UgdXR4b2xpYi5uZXR3b3Jrcy56Y2FzaFRlc3Q6XG4gICAgICAgIGF3YWl0IHRoaXMuZXhlYygnZ2VuZXJhdGUnLCBuKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMV8wMDApO1xuICAgICAgICBhd2FpdCB0aGlzLnNlbmRUb0FkZHJlc3MoYWRkcmVzcywgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXdhaXQgdGhpcy5leGVjKCdnZW5lcmF0ZXRvYWRkcmVzcycsIG4sIGFkZHJlc3MpO1xuICAgIH1cbiAgfVxufVxuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!