UNPKG

@bitgo/utxo-lib

Version:

Client-side Bitcoin JavaScript library

272 lines 37.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createTransactionFromBuffer = createTransactionFromBuffer; exports.createTransactionFromHex = createTransactionFromHex; exports.createPsbtFromBuffer = createPsbtFromBuffer; exports.createPsbtDecode = createPsbtDecode; exports.createPsbtFromHex = createPsbtFromHex; exports.createPsbtFromTransaction = createPsbtFromTransaction; exports.getDefaultTransactionVersion = getDefaultTransactionVersion; exports.setTransactionBuilderDefaults = setTransactionBuilderDefaults; exports.setPsbtDefaults = setPsbtDefaults; exports.createPsbtForNetwork = createPsbtForNetwork; exports.createTransactionBuilderForNetwork = createTransactionBuilderForNetwork; exports.createTransactionBuilderFromTransaction = createTransactionBuilderFromTransaction; const networks_1 = require("../networks"); const UtxoPsbt_1 = require("./UtxoPsbt"); const UtxoTransaction_1 = require("./UtxoTransaction"); const UtxoTransactionBuilder_1 = require("./UtxoTransactionBuilder"); const DashPsbt_1 = require("./dash/DashPsbt"); const DashTransaction_1 = require("./dash/DashTransaction"); const DashTransactionBuilder_1 = require("./dash/DashTransactionBuilder"); const ZcashPsbt_1 = require("./zcash/ZcashPsbt"); const ZcashTransactionBuilder_1 = require("./zcash/ZcashTransactionBuilder"); const ZcashTransaction_1 = require("./zcash/ZcashTransaction"); const litecoin_1 = require("./litecoin"); const PsbtUtil_1 = require("./PsbtUtil"); function createTransactionFromBuffer(buf, network, { version, amountType } = {}, deprecatedAmountType) { if (amountType) { if (deprecatedAmountType && amountType !== deprecatedAmountType) { throw new Error(`invalid arguments`); } } else { if (deprecatedAmountType) { amountType = deprecatedAmountType; } else { amountType = 'number'; } } switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: return UtxoTransaction_1.UtxoTransaction.fromBuffer(buf, false, amountType, network); case networks_1.networks.litecoin: return litecoin_1.LitecoinTransaction.fromBuffer(buf, false, amountType, network); case networks_1.networks.dash: return DashTransaction_1.DashTransaction.fromBuffer(buf, false, amountType, network); case networks_1.networks.zcash: return ZcashTransaction_1.ZcashTransaction.fromBufferWithVersion(buf, network, version, amountType); } /* istanbul ignore next */ throw new Error(`invalid network`); } function createTransactionFromHex(hex, network, p) { if (typeof p === 'string') { p = { amountType: p }; } return createTransactionFromBuffer(Buffer.from(hex, 'hex'), network, p); } /** * @param buf - must start with the PSBT magic bytes * @param network * @param bip32PathsAbsolute */ function createPsbtFromBuffer(buf, network, bip32PathsAbsolute = false) { if (!(0, PsbtUtil_1.isPsbt)(buf)) { throw new Error(`invalid psbt (does not start with 'psbt' magic bytes)`); } switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: return UtxoPsbt_1.UtxoPsbt.fromBuffer(buf, { network, bip32PathsAbsolute }); case networks_1.networks.litecoin: return litecoin_1.LitecoinPsbt.fromBuffer(buf, { network, bip32PathsAbsolute }); case networks_1.networks.dash: return DashPsbt_1.DashPsbt.fromBuffer(buf, { network, bip32PathsAbsolute }); case networks_1.networks.zcash: return ZcashPsbt_1.ZcashPsbt.fromBuffer(buf, { network, bip32PathsAbsolute }); } /* istanbul ignore next */ throw new Error(`invalid network`); } /** * Like createPsbtFromBuffer, but attempts hex and base64 decoding as well. * * @param buf * @param network * @param bip32PathsAbsolute */ function createPsbtDecode(buf, network, bip32PathsAbsolute = false) { return createPsbtFromBuffer((0, PsbtUtil_1.toPsbtBuffer)(buf), network, bip32PathsAbsolute); } function createPsbtFromHex(hex, network, bip32PathsAbsolute = false) { return createPsbtFromBuffer(Buffer.from(hex, 'hex'), network, bip32PathsAbsolute); } function createPsbtFromTransaction(tx, prevOuts) { switch ((0, networks_1.getMainnet)(tx.network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: return UtxoPsbt_1.UtxoPsbt.fromTransaction(tx, prevOuts); case networks_1.networks.litecoin: return litecoin_1.LitecoinPsbt.fromTransaction(tx, prevOuts); case networks_1.networks.dash: return DashPsbt_1.DashPsbt.fromTransaction(tx, prevOuts); case networks_1.networks.zcash: return ZcashPsbt_1.ZcashPsbt.fromTransaction(tx, prevOuts); } /* istanbul ignore next */ throw new Error(`invalid network`); } function getDefaultTransactionVersion(network) { // Use NU6_1 version for both mainnet and testnet // https://zips.z.cash/zip-0255 if (network === networks_1.networks.zcashTest) { return ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_NU6_1; } switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.ecash: return 2; case networks_1.networks.zcash: return ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_NU6_1; default: return 1; } } function setTransactionBuilderDefaults(txb, network, { version = getDefaultTransactionVersion(network) } = {}) { switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.ecash: if (version !== 2) { throw new Error(`invalid version`); } txb.setVersion(version); break; case networks_1.networks.zcash: txb.setDefaultsForVersion(network, version); break; default: if (version !== 1) { throw new Error(`invalid version`); } } } function setPsbtDefaults(psbt, network, { version = getDefaultTransactionVersion(network) } = {}) { switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.ecash: if (version !== 2) { throw new Error(`invalid version`); } break; case networks_1.networks.zcash: if (![ ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_CANOPY, ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_NU5, ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_NU6, ZcashTransaction_1.ZcashTransaction.VERSION4_BRANCH_NU6_1, ZcashTransaction_1.ZcashTransaction.VERSION5_BRANCH_NU5, ZcashTransaction_1.ZcashTransaction.VERSION5_BRANCH_NU6, ZcashTransaction_1.ZcashTransaction.VERSION5_BRANCH_NU6_1, ].includes(version)) { throw new Error(`invalid version`); } psbt.setDefaultsForVersion(network, version); break; default: if (version !== 1) { throw new Error(`invalid version`); } // FIXME: set version here, because there's a bug in the upstream PSBT // that defaults transactions to v2. psbt.setVersion(version); } } function createPsbtForNetwork(psbtOpts, { version } = {}) { let psbt; switch ((0, networks_1.getMainnet)(psbtOpts.network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: { psbt = UtxoPsbt_1.UtxoPsbt.createPsbt(psbtOpts); break; } case networks_1.networks.litecoin: { psbt = litecoin_1.LitecoinPsbt.createPsbt(psbtOpts); break; } case networks_1.networks.dash: { psbt = DashPsbt_1.DashPsbt.createPsbt(psbtOpts); break; } case networks_1.networks.zcash: { psbt = ZcashPsbt_1.ZcashPsbt.createPsbt(psbtOpts); break; } default: throw new Error(`unsupported network`); } setPsbtDefaults(psbt, psbtOpts.network, { version }); return psbt; } function createTransactionBuilderForNetwork(network, { version } = {}) { let txb; switch ((0, networks_1.getMainnet)(network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: { txb = new UtxoTransactionBuilder_1.UtxoTransactionBuilder(network); break; } case networks_1.networks.litecoin: { txb = new litecoin_1.LitecoinTransactionBuilder(network); break; } case networks_1.networks.dash: txb = new DashTransactionBuilder_1.DashTransactionBuilder(network); break; case networks_1.networks.zcash: { txb = new ZcashTransactionBuilder_1.ZcashTransactionBuilder(network); break; } default: throw new Error(`unsupported network`); } setTransactionBuilderDefaults(txb, network, { version }); return txb; } function createTransactionBuilderFromTransaction(tx, prevOutputs) { switch ((0, networks_1.getMainnet)(tx.network)) { case networks_1.networks.bitcoin: case networks_1.networks.bitcoincash: case networks_1.networks.bitcoinsv: case networks_1.networks.bitcoingold: case networks_1.networks.dogecoin: case networks_1.networks.ecash: return UtxoTransactionBuilder_1.UtxoTransactionBuilder.fromTransaction(tx, undefined, prevOutputs); case networks_1.networks.litecoin: return litecoin_1.LitecoinTransactionBuilder.fromTransaction(tx, undefined, prevOutputs); case networks_1.networks.dash: return DashTransactionBuilder_1.DashTransactionBuilder.fromTransaction(tx, undefined, prevOutputs); case networks_1.networks.zcash: return ZcashTransactionBuilder_1.ZcashTransactionBuilder.fromTransaction(tx, undefined, prevOutputs); } throw new Error(`invalid network`); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYml0Z28vdHJhbnNhY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUEyQkEsa0VBbUNDO0FBaUJELDREQVNDO0FBT0Qsb0RBc0JDO0FBU0QsNENBRUM7QUFFRCw4Q0FFQztBQUVELDhEQW1CQztBQUVELG9FQWtCQztBQUVELHNFQXVCQztBQUVELDBDQXNDQztBQUVELG9EQWdDQztBQUVELGdGQWlDQztBQUVELDBGQWlDQztBQW5WRCwwQ0FBNEQ7QUFFNUQseUNBQWdEO0FBQ2hELHVEQUFvRDtBQUNwRCxxRUFBa0U7QUFDbEUsOENBQTJDO0FBQzNDLDREQUF5RDtBQUN6RCwwRUFBdUU7QUFDdkUsaURBQThDO0FBQzlDLDZFQUEwRTtBQUMxRSwrREFBMEU7QUFDMUUseUNBQTJGO0FBQzNGLHlDQUFrRDtBQVlsRCxTQUFnQiwyQkFBMkIsQ0FDekMsR0FBVyxFQUNYLE9BQWdCLEVBQ2hCLEVBQUUsT0FBTyxFQUFFLFVBQVUsS0FBNkQsRUFBRSxFQUNwRixvQkFBMEM7SUFFMUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNmLElBQUksb0JBQW9CLElBQUksVUFBVSxLQUFLLG9CQUFvQixFQUFFLENBQUM7WUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO1NBQU0sQ0FBQztRQUNOLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUN6QixVQUFVLEdBQUcsb0JBQW9CLENBQUM7UUFDcEMsQ0FBQzthQUFNLENBQUM7WUFDTixVQUFVLEdBQUcsUUFBUSxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDO0lBQ0QsUUFBUSxJQUFBLHFCQUFVLEVBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUM1QixLQUFLLG1CQUFRLENBQUMsT0FBTyxDQUFDO1FBQ3RCLEtBQUssbUJBQVEsQ0FBQyxXQUFXLENBQUM7UUFD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LCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQgbm8tcmVkZWNsYXJlOiAwICovXG5pbXBvcnQgeyBUeE91dHB1dCB9IGZyb20gJ2JpdGNvaW5qcy1saWInO1xuXG5pbXBvcnQgeyBuZXR3b3JrcywgTmV0d29yaywgZ2V0TWFpbm5ldCB9IGZyb20gJy4uL25ldHdvcmtzJztcblxuaW1wb3J0IHsgVXR4b1BzYnQsIFBzYnRPcHRzIH0gZnJvbSAnLi9VdHhvUHNidCc7XG5pbXBvcnQgeyBVdHhvVHJhbnNhY3Rpb24gfSBmcm9tICcuL1V0eG9UcmFuc2FjdGlvbic7XG5pbXBvcnQgeyBVdHhvVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi9VdHhvVHJhbnNhY3Rpb25CdWlsZGVyJztcbmltcG9ydCB7IERhc2hQc2J0IH0gZnJvbSAnLi9kYXNoL0Rhc2hQc2J0JztcbmltcG9ydCB7IERhc2hUcmFuc2FjdGlvbiB9IGZyb20gJy4vZGFzaC9EYXNoVHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgRGFzaFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vZGFzaC9EYXNoVHJhbnNhY3Rpb25CdWlsZGVyJztcbmltcG9ydCB7IFpjYXNoUHNidCB9IGZyb20gJy4vemNhc2gvWmNhc2hQc2J0JztcbmltcG9ydCB7IFpjYXNoVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi96Y2FzaC9aY2FzaFRyYW5zYWN0aW9uQnVpbGRlcic7XG5pbXBvcnQgeyBaY2FzaE5ldHdvcmssIFpjYXNoVHJhbnNhY3Rpb24gfSBmcm9tICcuL3pjYXNoL1pjYXNoVHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgTGl0ZWNvaW5Qc2J0LCBMaXRlY29pblRyYW5zYWN0aW9uLCBMaXRlY29pblRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vbGl0ZWNvaW4nO1xuaW1wb3J0IHsgaXNQc2J0LCB0b1BzYnRCdWZmZXIgfSBmcm9tICcuL1BzYnRVdGlsJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zYWN0aW9uRnJvbUJ1ZmZlcihcbiAgYnVmOiBCdWZmZXIsXG4gIG5ldHdvcms6IE5ldHdvcmssXG4gIHBhcmFtczogeyB2ZXJzaW9uPzogbnVtYmVyOyBhbW91bnRUeXBlOiAnYmlnaW50JyB9XG4pOiBVdHhvVHJhbnNhY3Rpb248YmlnaW50PjtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbkZyb21CdWZmZXI8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gIGJ1ZjogQnVmZmVyLFxuICBuZXR3b3JrOiBOZXR3b3JrLFxuICBwYXJhbXM/OiB7IHZlcnNpb24/OiBudW1iZXI7IGFtb3VudFR5cGU/OiAnbnVtYmVyJyB8ICdiaWdpbnQnIH1cbik6IFV0eG9UcmFuc2FjdGlvbjxUTnVtYmVyPjtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbkZyb21CdWZmZXI8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIGJ1ZjogQnVmZmVyLFxuICBuZXR3b3JrOiBOZXR3b3JrLFxuICB7IHZlcnNpb24sIGFtb3VudFR5cGUgfTogeyB2ZXJzaW9uPzogbnVtYmVyOyBhbW91bnRUeXBlPzogJ251bWJlcicgfCAnYmlnaW50JyB9ID0ge30sXG4gIGRlcHJlY2F0ZWRBbW91bnRUeXBlPzogJ251bWJlcicgfCAnYmlnaW50J1xuKTogVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+IHtcbiAgaWYgKGFtb3VudFR5cGUpIHtcbiAgICBpZiAoZGVwcmVjYXRlZEFtb3VudFR5cGUgJiYgYW1vdW50VHlwZSAhPT0gZGVwcmVjYXRlZEFtb3VudFR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBhcmd1bWVudHNgKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlcHJlY2F0ZWRBbW91bnRUeXBlKSB7XG4gICAgICBhbW91bnRUeXBlID0gZGVwcmVjYXRlZEFtb3VudFR5cGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFtb3VudFR5cGUgPSAnbnVtYmVyJztcbiAgICB9XG4gIH1cbiAgc3dpdGNoIChnZXRNYWlubmV0KG5ldHdvcmspKSB7XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmNhc2g6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luc3Y6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luZ29sZDpcbiAgICBjYXNlIG5ldHdvcmtzLmRvZ2Vjb2luOlxuICAgIGNhc2UgbmV0d29ya3MuZWNhc2g6XG4gICAgICByZXR1cm4gVXR4b1RyYW5zYWN0aW9uLmZyb21CdWZmZXI8VE51bWJlcj4oYnVmLCBmYWxzZSwgYW1vdW50VHlwZSwgbmV0d29yayk7XG4gICAgY2FzZSBuZXR3b3Jrcy5saXRlY29pbjpcbiAgICAgIHJldHVybiBMaXRlY29pblRyYW5zYWN0aW9uLmZyb21CdWZmZXI8VE51bWJlcj4oYnVmLCBmYWxzZSwgYW1vdW50VHlwZSwgbmV0d29yayk7XG4gICAgY2FzZSBuZXR3b3Jrcy5kYXNoOlxuICAgICAgcmV0dXJuIERhc2hUcmFuc2FjdGlvbi5mcm9tQnVmZmVyPFROdW1iZXI+KGJ1ZiwgZmFsc2UsIGFtb3VudFR5cGUsIG5ldHdvcmspO1xuICAgIGNhc2UgbmV0d29ya3MuemNhc2g6XG4gICAgICByZXR1cm4gWmNhc2hUcmFuc2FjdGlvbi5mcm9tQnVmZmVyV2l0aFZlcnNpb248VE51bWJlcj4oYnVmLCBuZXR3b3JrIGFzIFpjYXNoTmV0d29yaywgdmVyc2lvbiwgYW1vdW50VHlwZSk7XG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbmV0d29ya2ApO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuLyoqIEBkZXByZWNhdGVkIC0gdXNlIGNyZWF0ZVRyYW5zYWN0aW9uRnJvbUJ1ZmZlciBpbnN0ZWFkICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KFxuICBoZXg6IHN0cmluZyxcbiAgbmV0d29yazogTmV0d29yayxcbiAgcDogeyBhbW91bnRUeXBlOiAnYmlnaW50JyB9XG4pOiBVdHhvVHJhbnNhY3Rpb248YmlnaW50Pjtcbi8qKiBAZGVwcmVjYXRlZCAtIHVzZSBjcmVhdGVUcmFuc2FjdGlvbkZyb21CdWZmZXIgaW5zdGVhZCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleChoZXg6IHN0cmluZywgbmV0d29yazogTmV0d29yaywgcDogeyBhbW91bnRUeXBlOiAnbnVtYmVyJyB9KTogVXR4b1RyYW5zYWN0aW9uO1xuLyoqIEBkZXByZWNhdGVkIC0gdXNlIGNyZWF0ZVRyYW5zYWN0aW9uRnJvbUJ1ZmZlciBpbnN0ZWFkICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICBoZXg6IHN0cmluZyxcbiAgbmV0d29yazogTmV0d29yayxcbiAgcD86IHsgYW1vdW50VHlwZT86ICdudW1iZXInIHwgJ2JpZ2ludCcgfSB8ICdudW1iZXInIHwgJ2JpZ2ludCdcbik6IFV0eG9UcmFuc2FjdGlvbjxUTnVtYmVyPjtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbkZyb21IZXg8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIGhleDogc3RyaW5nLFxuICBuZXR3b3JrOiBOZXR3b3JrLFxuICBwPzogeyBhbW91bnRUeXBlPzogJ251bWJlcicgfCAnYmlnaW50JyB9IHwgJ251bWJlcicgfCAnYmlnaW50J1xuKTogVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+IHtcbiAgaWYgKHR5cGVvZiBwID09PSAnc3RyaW5nJykge1xuICAgIHAgPSB7IGFtb3VudFR5cGU6IHAgfTtcbiAgfVxuICByZXR1cm4gY3JlYXRlVHJhbnNhY3Rpb25Gcm9tQnVmZmVyPFROdW1iZXI+KEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpLCBuZXR3b3JrLCBwKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gYnVmIC0gbXVzdCBzdGFydCB3aXRoIHRoZSBQU0JUIG1hZ2ljIGJ5dGVzXG4gKiBAcGFyYW0gbmV0d29ya1xuICogQHBhcmFtIGJpcDMyUGF0aHNBYnNvbHV0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHNidEZyb21CdWZmZXIoYnVmOiBCdWZmZXIsIG5ldHdvcms6IE5ldHdvcmssIGJpcDMyUGF0aHNBYnNvbHV0ZSA9IGZhbHNlKTogVXR4b1BzYnQge1xuICBpZiAoIWlzUHNidChidWYpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHBzYnQgKGRvZXMgbm90IHN0YXJ0IHdpdGggJ3BzYnQnIG1hZ2ljIGJ5dGVzKWApO1xuICB9XG4gIHN3aXRjaCAoZ2V0TWFpbm5ldChuZXR3b3JrKSkge1xuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5jYXNoOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbnN2OlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmdvbGQ6XG4gICAgY2FzZSBuZXR3b3Jrcy5kb2dlY29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmVjYXNoOlxuICAgICAgcmV0dXJuIFV0eG9Qc2J0LmZyb21CdWZmZXIoYnVmLCB7IG5ldHdvcmssIGJpcDMyUGF0aHNBYnNvbHV0ZSB9KTtcbiAgICBjYXNlIG5ldHdvcmtzLmxpdGVjb2luOlxuICAgICAgcmV0dXJuIExpdGVjb2luUHNidC5mcm9tQnVmZmVyKGJ1ZiwgeyBuZXR3b3JrLCBiaXAzMlBhdGhzQWJzb2x1dGUgfSk7XG4gICAgY2FzZSBuZXR3b3Jrcy5kYXNoOlxuICAgICAgcmV0dXJuIERhc2hQc2J0LmZyb21CdWZmZXIoYnVmLCB7IG5ldHdvcmssIGJpcDMyUGF0aHNBYnNvbHV0ZSB9KTtcbiAgICBjYXNlIG5ldHdvcmtzLnpjYXNoOlxuICAgICAgcmV0dXJuIFpjYXNoUHNidC5mcm9tQnVmZmVyKGJ1ZiwgeyBuZXR3b3JrLCBiaXAzMlBhdGhzQWJzb2x1dGUgfSk7XG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgbmV0d29ya2ApO1xufVxuXG4vKipcbiAqIExpa2UgY3JlYXRlUHNidEZyb21CdWZmZXIsIGJ1dCBhdHRlbXB0cyBoZXggYW5kIGJhc2U2NCBkZWNvZGluZyBhcyB3ZWxsLlxuICpcbiAqIEBwYXJhbSBidWZcbiAqIEBwYXJhbSBuZXR3b3JrXG4gKiBAcGFyYW0gYmlwMzJQYXRoc0Fic29sdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQc2J0RGVjb2RlKGJ1ZjogQnVmZmVyIHwgc3RyaW5nLCBuZXR3b3JrOiBOZXR3b3JrLCBiaXAzMlBhdGhzQWJzb2x1dGUgPSBmYWxzZSk6IFV0eG9Qc2J0IHtcbiAgcmV0dXJuIGNyZWF0ZVBzYnRGcm9tQnVmZmVyKHRvUHNidEJ1ZmZlcihidWYpLCBuZXR3b3JrLCBiaXAzMlBhdGhzQWJzb2x1dGUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHNidEZyb21IZXgoaGV4OiBzdHJpbmcsIG5ldHdvcms6IE5ldHdvcmssIGJpcDMyUGF0aHNBYnNvbHV0ZSA9IGZhbHNlKTogVXR4b1BzYnQge1xuICByZXR1cm4gY3JlYXRlUHNidEZyb21CdWZmZXIoQnVmZmVyLmZyb20oaGV4LCAnaGV4JyksIG5ldHdvcmssIGJpcDMyUGF0aHNBYnNvbHV0ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQc2J0RnJvbVRyYW5zYWN0aW9uKHR4OiBVdHhvVHJhbnNhY3Rpb248YmlnaW50PiwgcHJldk91dHM6IFR4T3V0cHV0PGJpZ2ludD5bXSk6IFV0eG9Qc2J0IHtcbiAgc3dpdGNoIChnZXRNYWlubmV0KHR4Lm5ldHdvcmspKSB7XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmNhc2g6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luc3Y6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luZ29sZDpcbiAgICBjYXNlIG5ldHdvcmtzLmRvZ2Vjb2luOlxuICAgIGNhc2UgbmV0d29ya3MuZWNhc2g6XG4gICAgICByZXR1cm4gVXR4b1BzYnQuZnJvbVRyYW5zYWN0aW9uKHR4LCBwcmV2T3V0cyk7XG4gICAgY2FzZSBuZXR3b3Jrcy5saXRlY29pbjpcbiAgICAgIHJldHVybiBMaXRlY29pblBzYnQuZnJvbVRyYW5zYWN0aW9uKHR4LCBwcmV2T3V0cyk7XG4gICAgY2FzZSBuZXR3b3Jrcy5kYXNoOlxuICAgICAgcmV0dXJuIERhc2hQc2J0LmZyb21UcmFuc2FjdGlvbih0eCwgcHJldk91dHMpO1xuICAgIGNhc2UgbmV0d29ya3MuemNhc2g6XG4gICAgICByZXR1cm4gWmNhc2hQc2J0LmZyb21UcmFuc2FjdGlvbih0eCwgcHJldk91dHMpO1xuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG5ldHdvcmtgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRUcmFuc2FjdGlvblZlcnNpb24obmV0d29yazogTmV0d29yayk6IG51bWJlciB7XG4gIC8vIFVzZSBOVTZfMSB2ZXJzaW9uIGZvciBib3RoIG1haW5uZXQgYW5kIHRlc3RuZXRcbiAgLy8gaHR0cHM6Ly96aXBzLnouY2FzaC96aXAtMDI1NVxuICBpZiAobmV0d29yayA9PT0gbmV0d29ya3MuemNhc2hUZXN0KSB7XG4gICAgcmV0dXJuIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjRfQlJBTkNIX05VNl8xO1xuICB9XG5cbiAgc3dpdGNoIChnZXRNYWlubmV0KG5ldHdvcmspKSB7XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luY2FzaDpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5zdjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5nb2xkOlxuICAgIGNhc2UgbmV0d29ya3MuZWNhc2g6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlIG5ldHdvcmtzLnpjYXNoOlxuICAgICAgcmV0dXJuIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjRfQlJBTkNIX05VNl8xO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gMTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNhY3Rpb25CdWlsZGVyRGVmYXVsdHM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gIHR4YjogVXR4b1RyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyPixcbiAgbmV0d29yazogTmV0d29yayxcbiAgeyB2ZXJzaW9uID0gZ2V0RGVmYXVsdFRyYW5zYWN0aW9uVmVyc2lvbihuZXR3b3JrKSB9OiB7IHZlcnNpb24/OiBudW1iZXIgfSA9IHt9XG4pOiB2b2lkIHtcbiAgc3dpdGNoIChnZXRNYWlubmV0KG5ldHdvcmspKSB7XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luY2FzaDpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5zdjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5nb2xkOlxuICAgIGNhc2UgbmV0d29ya3MuZWNhc2g6XG4gICAgICBpZiAodmVyc2lvbiAhPT0gMikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgdmVyc2lvbmApO1xuICAgICAgfVxuICAgICAgdHhiLnNldFZlcnNpb24odmVyc2lvbik7XG4gICAgICBicmVhaztcbiAgICBjYXNlIG5ldHdvcmtzLnpjYXNoOlxuICAgICAgKHR4YiBhcyBaY2FzaFRyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyPikuc2V0RGVmYXVsdHNGb3JWZXJzaW9uKG5ldHdvcmssIHZlcnNpb24pO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICh2ZXJzaW9uICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCB2ZXJzaW9uYCk7XG4gICAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFBzYnREZWZhdWx0cyhcbiAgcHNidDogVXR4b1BzYnQsXG4gIG5ldHdvcms6IE5ldHdvcmssXG4gIHsgdmVyc2lvbiA9IGdldERlZmF1bHRUcmFuc2FjdGlvblZlcnNpb24obmV0d29yaykgfTogeyB2ZXJzaW9uPzogbnVtYmVyIH0gPSB7fVxuKTogdm9pZCB7XG4gIHN3aXRjaCAoZ2V0TWFpbm5ldChuZXR3b3JrKSkge1xuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmNhc2g6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luc3Y6XG4gICAgY2FzZSBuZXR3b3Jrcy5iaXRjb2luZ29sZDpcbiAgICBjYXNlIG5ldHdvcmtzLmVjYXNoOlxuICAgICAgaWYgKHZlcnNpb24gIT09IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHZlcnNpb25gKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgbmV0d29ya3MuemNhc2g6XG4gICAgICBpZiAoXG4gICAgICAgICFbXG4gICAgICAgICAgWmNhc2hUcmFuc2FjdGlvbi5WRVJTSU9ONF9CUkFOQ0hfQ0FOT1BZLFxuICAgICAgICAgIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjRfQlJBTkNIX05VNSxcbiAgICAgICAgICBaY2FzaFRyYW5zYWN0aW9uLlZFUlNJT040X0JSQU5DSF9OVTYsXG4gICAgICAgICAgWmNhc2hUcmFuc2FjdGlvbi5WRVJTSU9ONF9CUkFOQ0hfTlU2XzEsXG4gICAgICAgICAgWmNhc2hUcmFuc2FjdGlvbi5WRVJTSU9ONV9CUkFOQ0hfTlU1LFxuICAgICAgICAgIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjVfQlJBTkNIX05VNixcbiAgICAgICAgICBaY2FzaFRyYW5zYWN0aW9uLlZFUlNJT041X0JSQU5DSF9OVTZfMSxcbiAgICAgICAgXS5pbmNsdWRlcyh2ZXJzaW9uKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCB2ZXJzaW9uYCk7XG4gICAgICB9XG4gICAgICAocHNidCBhcyBaY2FzaFBzYnQpLnNldERlZmF1bHRzRm9yVmVyc2lvbihuZXR3b3JrLCB2ZXJzaW9uKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBpZiAodmVyc2lvbiAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgdmVyc2lvbmApO1xuICAgICAgfVxuICAgICAgLy8gRklYTUU6IHNldCB2ZXJzaW9uIGhlcmUsIGJlY2F1c2UgdGhlcmUncyBhIGJ1ZyBpbiB0aGUgdXBzdHJlYW0gUFNCVFxuICAgICAgLy8gdGhhdCBkZWZhdWx0cyB0cmFuc2FjdGlvbnMgdG8gdjIuXG4gICAgICBwc2J0LnNldFZlcnNpb24odmVyc2lvbik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBzYnRGb3JOZXR3b3JrKHBzYnRPcHRzOiBQc2J0T3B0cywgeyB2ZXJzaW9uIH06IHsgdmVyc2lvbj86IG51bWJlciB9ID0ge30pOiBVdHhvUHNidCB7XG4gIGxldCBwc2J0O1xuXG4gIHN3aXRjaCAoZ2V0TWFpbm5ldChwc2J0T3B0cy5uZXR3b3JrKSkge1xuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5jYXNoOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbnN2OlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmdvbGQ6XG4gICAgY2FzZSBuZXR3b3Jrcy5kb2dlY29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmVjYXNoOiB7XG4gICAgICBwc2J0ID0gVXR4b1BzYnQuY3JlYXRlUHNidChwc2J0T3B0cyk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBuZXR3b3Jrcy5saXRlY29pbjoge1xuICAgICAgcHNidCA9IExpdGVjb2luUHNidC5jcmVhdGVQc2J0KHBzYnRPcHRzKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjYXNlIG5ldHdvcmtzLmRhc2g6IHtcbiAgICAgIHBzYnQgPSBEYXNoUHNidC5jcmVhdGVQc2J0KHBzYnRPcHRzKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjYXNlIG5ldHdvcmtzLnpjYXNoOiB7XG4gICAgICBwc2J0ID0gWmNhc2hQc2J0LmNyZWF0ZVBzYnQocHNidE9wdHMpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIG5ldHdvcmtgKTtcbiAgfVxuXG4gIHNldFBzYnREZWZhdWx0cyhwc2J0LCBwc2J0T3B0cy5uZXR3b3JrLCB7IHZlcnNpb24gfSk7XG5cbiAgcmV0dXJuIHBzYnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbkJ1aWxkZXJGb3JOZXR3b3JrPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICBuZXR3b3JrOiBOZXR3b3JrLFxuICB7IHZlcnNpb24gfTogeyB2ZXJzaW9uPzogbnVtYmVyIH0gPSB7fVxuKTogVXR4b1RyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyPiB7XG4gIGxldCB0eGI7XG4gIHN3aXRjaCAoZ2V0TWFpbm5ldChuZXR3b3JrKSkge1xuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5jYXNoOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbnN2OlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmdvbGQ6XG4gICAgY2FzZSBuZXR3b3Jrcy5kb2dlY29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmVjYXNoOiB7XG4gICAgICB0eGIgPSBuZXcgVXR4b1RyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyPihuZXR3b3JrKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjYXNlIG5ldHdvcmtzLmxpdGVjb2luOiB7XG4gICAgICB0eGIgPSBuZXcgTGl0ZWNvaW5UcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4obmV0d29yayk7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBuZXR3b3Jrcy5kYXNoOlxuICAgICAgdHhiID0gbmV3IERhc2hUcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4obmV0d29yayk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIG5ldHdvcmtzLnpjYXNoOiB7XG4gICAgICB0eGIgPSBuZXcgWmNhc2hUcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4obmV0d29yayBhcyBaY2FzaE5ldHdvcmspO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIG5ldHdvcmtgKTtcbiAgfVxuXG4gIHNldFRyYW5zYWN0aW9uQnVpbGRlckRlZmF1bHRzPFROdW1iZXI+KHR4YiwgbmV0d29yaywgeyB2ZXJzaW9uIH0pO1xuXG4gIHJldHVybiB0eGI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbkJ1aWxkZXJGcm9tVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gIHR4OiBVdHhvVHJhbnNhY3Rpb248VE51bWJlcj4sXG4gIHByZXZPdXRwdXRzPzogVHhPdXRwdXQ8VE51bWJlcj5bXVxuKTogVXR4b1RyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyPiB7XG4gIHN3aXRjaCAoZ2V0TWFpbm5ldCh0eC5uZXR3b3JrKSkge1xuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmJpdGNvaW5jYXNoOlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbnN2OlxuICAgIGNhc2UgbmV0d29ya3MuYml0Y29pbmdvbGQ6XG4gICAgY2FzZSBuZXR3b3Jrcy5kb2dlY29pbjpcbiAgICBjYXNlIG5ldHdvcmtzLmVjYXNoOlxuICAgICAgcmV0dXJuIFV0eG9UcmFuc2FjdGlvbkJ1aWxkZXIuZnJvbVRyYW5zYWN0aW9uPFROdW1iZXI+KHR4LCB1bmRlZmluZWQsIHByZXZPdXRwdXRzKTtcbiAgICBjYXNlIG5ldHdvcmtzLmxpdGVjb2luOlxuICAgICAgcmV0dXJuIExpdGVjb2luVHJhbnNhY3Rpb25CdWlsZGVyLmZyb21UcmFuc2FjdGlvbjxUTnVtYmVyPihcbiAgICAgICAgdHggYXMgTGl0ZWNvaW5UcmFuc2FjdGlvbjxUTnVtYmVyPixcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICBwcmV2T3V0cHV0cyBhcyBUeE91dHB1dDxUTnVtYmVyPltdXG4gICAgICApO1xuICAgIGNhc2UgbmV0d29ya3MuZGFzaDpcbiAgICAgIHJldHVybiBEYXNoVHJhbnNhY3Rpb25CdWlsZGVyLmZyb21UcmFuc2FjdGlvbjxUTnVtYmVyPihcbiAgICAgICAgdHggYXMgRGFzaFRyYW5zYWN0aW9uPFROdW1iZXI+LFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHByZXZPdXRwdXRzIGFzIFR4T3V0cHV0PFROdW1iZXI+W11cbiAgICAgICk7XG4gICAgY2FzZSBuZXR3b3Jrcy56Y2FzaDpcbiAgICAgIHJldHVybiBaY2FzaFRyYW5zYWN0aW9uQnVpbGRlci5mcm9tVHJhbnNhY3Rpb248VE51bWJlcj4oXG4gICAgICAgIHR4IGFzIFpjYXNoVHJhbnNhY3Rpb248VE51bWJlcj4sXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgcHJldk91dHB1dHMgYXMgVHhPdXRwdXQ8VE51bWJlcj5bXVxuICAgICAgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBuZXR3b3JrYCk7XG59XG4iXX0=