(function(_g){(function(f){if(typeof exports==='object'&&typeof module!=='undefined'){module.exports=f()}else if(typeof define==='function'&&define.amd){define([],f.bind(_g))}else{f()}})(function(define,module,exports){var _m =(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
    module.exports = "0.5.7";
    },{}],2:[function(require,module,exports){
    module.exports = {
        version: require('./version'),
        stringifyInfo: require('./stringify-info'),
        stringifyStream: require('./stringify-stream'),
        parseChunked: require('./parse-chunked')
    };
    
    },{"./parse-chunked":3,"./stringify-info":4,"./stringify-stream":5,"./version":1}],3:[function(require,module,exports){
    const { isReadableStream } = require('./utils');
    const TextDecoder = require('./text-decoder');
    
    const STACK_OBJECT = 1;
    const STACK_ARRAY = 2;
    const decoder = new TextDecoder();
    
    function isObject(value) {
        return value !== null && typeof value === 'object';
    }
    
    function adjustPosition(error, parser) {
        if (error.name === 'SyntaxError' && parser.jsonParseOffset) {
            error.message = error.message.replace(/at position (\d+)/, (_, pos) =>
                'at position ' + (Number(pos) + parser.jsonParseOffset)
            );
        }
    
        return error;
    }
    
    function append(array, elements) {
        // Note: Avoid to use array.push(...elements) since it may lead to
        // "RangeError: Maximum call stack size exceeded" for a long arrays
        const initialLength = array.length;
        array.length += elements.length;
    
        for (let i = 0; i < elements.length; i++) {
            array[initialLength + i] = elements[i];
        }
    }
    
    module.exports = function(chunkEmitter) {
        let parser = new ChunkParser();
    
        if (isObject(chunkEmitter) && isReadableStream(chunkEmitter)) {
            return new Promise((resolve, reject) => {
                chunkEmitter
                    .on('data', chunk => {
                        try {
                            parser.push(chunk);
                        } catch (e) {
                            reject(adjustPosition(e, parser));
                            parser = null;
                        }
                    })
                    .on('error', (e) => {
                        parser = null;
                        reject(e);
                    })
                    .on('end', () => {
                        try {
                            resolve(parser.finish());
                        } catch (e) {
                            reject(adjustPosition(e, parser));
                        } finally {
                            parser = null;
                        }
                    });
            });
        }
    
        if (typeof chunkEmitter === 'function') {
            const iterator = chunkEmitter();
    
            if (isObject(iterator) && (Symbol.iterator in iterator || Symbol.asyncIterator in iterator)) {
                return new Promise(async (resolve, reject) => {
                    try {
                        for await (const chunk of iterator) {
                            parser.push(chunk);
                        }
    
                        resolve(parser.finish());
                    } catch (e) {
                        reject(adjustPosition(e, parser));
                    } finally {
                        parser = null;
                    }
                });
            }
        }
    
        throw new Error(
            'Chunk emitter should be readable stream, generator, ' +
            'async generator or function returning an iterable object'
        );
    };
    
    class ChunkParser {
        constructor() {
            this.value = undefined;
            this.valueStack = null;
    
            this.stack = new Array(100);
            this.lastFlushDepth = 0;
            this.flushDepth = 0;
            this.stateString = false;
            this.stateStringEscape = false;
            this.pendingByteSeq = null;
            this.pendingChunk = null;
            this.chunkOffset = 0;
            this.jsonParseOffset = 0;
        }
    
        parseAndAppend(fragment, wrap) {
            // Append new entries or elements
            if (this.stack[this.lastFlushDepth - 1] === STACK_OBJECT) {
                if (wrap) {
                    this.jsonParseOffset--;
                    fragment = '{' + fragment + '}';
                }
    
                Object.assign(this.valueStack.value, JSON.parse(fragment));
            } else {
                if (wrap) {
                    this.jsonParseOffset--;
                    fragment = '[' + fragment + ']';
                }
    
                append(this.valueStack.value, JSON.parse(fragment));
            }
        }
    
        prepareAddition(fragment) {
            const { value } = this.valueStack;
            const expectComma = Array.isArray(value)
                ? value.length !== 0
                : Object.keys(value).length !== 0;
    
            if (expectComma) {
                // Skip a comma at the beginning of fragment, otherwise it would
                // fail to parse
                if (fragment[0] === ',') {
                    this.jsonParseOffset++;
                    return fragment.slice(1);
                }
    
                // When value (an object or array) is not empty and a fragment
                // doesn't start with a comma, a single valid fragment starting
                // is a closing bracket. If it's not, a prefix is adding to fail
                // parsing. Otherwise, the sequence of chunks can be successfully
                // parsed, although it should not, e.g. ["[{}", "{}]"]
                if (fragment[0] !== '}' && fragment[0] !== ']') {
                    this.jsonParseOffset -= 3;
                    return '[[]' + fragment;
                }
            }
    
            return fragment;
        }
    
        flush(chunk, start, end) {
            let fragment = chunk.slice(start, end);
    
            // Save position correction an error in JSON.parse() if any
            this.jsonParseOffset = this.chunkOffset + start;
    
            // Prepend pending chunk if any
            if (this.pendingChunk !== null) {
                fragment = this.pendingChunk + fragment;
                this.jsonParseOffset -= this.pendingChunk.length;
                this.pendingChunk = null;
            }
    
            if (this.flushDepth === this.lastFlushDepth) {
                // Depth didn't changed, so it's a root value or entry/element set
                if (this.flushDepth > 0) {
                    this.parseAndAppend(this.prepareAddition(fragment), true);
                } else {
                    // That's an entire value on a top level
                    this.value = JSON.parse(fragment);
                    this.valueStack = {
                        value: this.value,
                        prev: null
                    };
                }
            } else if (this.flushDepth > this.lastFlushDepth) {
                // Add missed closing brackets/parentheses
                for (let i = this.flushDepth - 1; i >= this.lastFlushDepth; i--) {
                    fragment += this.stack[i] === STACK_OBJECT ? '}' : ']';
                }
    
                if (this.lastFlushDepth === 0) {
                    // That's a root value
                    this.value = JSON.parse(fragment);
                    this.valueStack = {
                        value: this.value,
                        prev: null
                    };
                } else {
                    this.parseAndAppend(this.prepareAddition(fragment), true);
                }
    
                // Move down to the depths to the last object/array, which is current now
                for (let i = this.lastFlushDepth || 1; i < this.flushDepth; i++) {
                    let value = this.valueStack.value;
    
                    if (this.stack[i - 1] === STACK_OBJECT) {
                        // find last entry
                        let key;
                        // eslint-disable-next-line curly
                        for (key in value);
                        value = value[key];
                    } else {
                        // last element
                        value = value[value.length - 1];
                    }
    
                    this.valueStack = {
                        value,
                        prev: this.valueStack
                    };
                }
            } else /* this.flushDepth < this.lastFlushDepth */ {
                fragment = this.prepareAddition(fragment);
    
                // Add missed opening brackets/parentheses
                for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
                    this.jsonParseOffset--;
                    fragment = (this.stack[i] === STACK_OBJECT ? '{' : '[') + fragment;
                }
    
                this.parseAndAppend(fragment, false);
    
                for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
                    this.valueStack = this.valueStack.prev;
                }
            }
    
            this.lastFlushDepth = this.flushDepth;
        }
    
        push(chunk) {
            if (typeof chunk !== 'string') {
                // Suppose chunk is Buffer or Uint8Array
    
                // Prepend uncompleted byte sequence if any
                if (this.pendingByteSeq !== null) {
                    const origRawChunk = chunk;
                    chunk = new Uint8Array(this.pendingByteSeq.length + origRawChunk.length);
                    chunk.set(this.pendingByteSeq);
                    chunk.set(origRawChunk, this.pendingByteSeq.length);
                    this.pendingByteSeq = null;
                }
    
                // In case Buffer/Uint8Array, an input is encoded in UTF8
                // Seek for parts of uncompleted UTF8 symbol on the ending
                // This makes sense only if we expect more chunks and last char is not multi-bytes
                if (chunk[chunk.length - 1] > 127) {
                    for (let seqLength = 0; seqLength < chunk.length; seqLength++) {
                        const byte = chunk[chunk.length - 1 - seqLength];
    
                        // 10xxxxxx - 2nd, 3rd or 4th byte
                        // 110xxxxx – first byte of 2-byte sequence
                        // 1110xxxx - first byte of 3-byte sequence
                        // 11110xxx - first byte of 4-byte sequence
                        if (byte >> 6 === 3) {
                            seqLength++;
    
                            // If the sequence is really incomplete, then preserve it
                            // for the future chunk and cut off it from the current chunk
                            if ((seqLength !== 4 && byte >> 3 === 0b11110) ||
                                (seqLength !== 3 && byte >> 4 === 0b1110) ||
                                (seqLength !== 2 && byte >> 5 === 0b110)) {
                                this.pendingByteSeq = chunk.slice(chunk.length - seqLength);
                                chunk = chunk.slice(0, -seqLength);
                            }
    
                            break;
                        }
                    }
                }
    
                // Convert chunk to a string, since single decode per chunk
                // is much effective than decode multiple small substrings
                chunk = decoder.decode(chunk);
            }
    
            const chunkLength = chunk.length;
            let lastFlushPoint = 0;
            let flushPoint = 0;
    
            // Main scan loop
            scan: for (let i = 0; i < chunkLength; i++) {
                if (this.stateString) {
                    for (; i < chunkLength; i++) {
                        if (this.stateStringEscape) {
                            this.stateStringEscape = false;
                        } else {
                            switch (chunk.charCodeAt(i)) {
                                case 0x22: /* " */
                                    this.stateString = false;
                                    continue scan;
    
                                case 0x5C: /* \ */
                                    this.stateStringEscape = true;
                            }
                        }
                    }
    
                    break;
                }
    
                switch (chunk.charCodeAt(i)) {
                    case 0x22: /* " */
                        this.stateString = true;
                        this.stateStringEscape = false;
                        break;
    
                    case 0x2C: /* , */
                        flushPoint = i;
                        break;
    
                    case 0x7B: /* { */
                        // Open an object
                        flushPoint = i + 1;
                        this.stack[this.flushDepth++] = STACK_OBJECT;
                        break;
    
                    case 0x5B: /* [ */
                        // Open an array
                        flushPoint = i + 1;
                        this.stack[this.flushDepth++] = STACK_ARRAY;
                        break;
    
                    case 0x5D: /* ] */
                    case 0x7D: /* } */
                        // Close an object or array
                        flushPoint = i + 1;
                        this.flushDepth--;
    
                        if (this.flushDepth < this.lastFlushDepth) {
                            this.flush(chunk, lastFlushPoint, flushPoint);
                            lastFlushPoint = flushPoint;
                        }
    
                        break;
    
                    case 0x09: /* \t */
                    case 0x0A: /* \n */
                    case 0x0D: /* \r */
                    case 0x20: /* space */
                        // Move points forward when they points on current position and it's a whitespace
                        if (lastFlushPoint === i) {
                            lastFlushPoint++;
                        }
    
                        if (flushPoint === i) {
                            flushPoint++;
                        }
    
                        break;
                }
            }
    
            if (flushPoint > lastFlushPoint) {
                this.flush(chunk, lastFlushPoint, flushPoint);
            }
    
            // Produce pendingChunk if something left
            if (flushPoint < chunkLength) {
                if (this.pendingChunk !== null) {
                    // When there is already a pending chunk then no flush happened,
                    // appending entire chunk to pending one
                    this.pendingChunk += chunk;
                } else {
                    // Create a pending chunk, it will start with non-whitespace since
                    // flushPoint was moved forward away from whitespaces on scan
                    this.pendingChunk = chunk.slice(flushPoint, chunkLength);
                }
            }
    
            this.chunkOffset += chunkLength;
        }
    
        finish() {
            if (this.pendingChunk !== null) {
                this.flush('', 0, 0);
                this.pendingChunk = null;
            }
    
            return this.value;
        }
    };
    
    },{"./text-decoder":6,"./utils":7}],4:[function(require,module,exports){
    const {
        normalizeReplacer,
        normalizeSpace,
        replaceValue,
        getTypeNative,
        getTypeAsync,
        isLeadingSurrogate,
        isTrailingSurrogate,
        escapableCharCodeSubstitution,
        type: {
            PRIMITIVE,
            OBJECT,
            ARRAY,
            PROMISE,
            STRING_STREAM,
            OBJECT_STREAM
        }
    } = require('./utils');
    const charLength2048 = Array.from({ length: 2048 }).map((_, code) => {
        if (escapableCharCodeSubstitution.hasOwnProperty(code)) {
            return 2; // \X
        }
    
        if (code < 0x20) {
            return 6; // \uXXXX
        }
    
        return code < 128 ? 1 : 2; // UTF8 bytes
    });
    
    function stringLength(str) {
        let len = 0;
        let prevLeadingSurrogate = false;
    
        for (let i = 0; i < str.length; i++) {
            const code = str.charCodeAt(i);
    
            if (code < 2048) {
                len += charLength2048[code];
            } else if (isLeadingSurrogate(code)) {
                len += 6; // \uXXXX since no pair with trailing surrogate yet
                prevLeadingSurrogate = true;
                continue;
            } else if (isTrailingSurrogate(code)) {
                len = prevLeadingSurrogate
                    ? len - 2  // surrogate pair (4 bytes), since we calculate prev leading surrogate as 6 bytes, substruct 2 bytes
                    : len + 6; // \uXXXX
            } else {
                len += 3; // code >= 2048 is 3 bytes length for UTF8
            }
    
            prevLeadingSurrogate = false;
        }
    
        return len + 2; // +2 for quotes
    }
    
    function primitiveLength(value) {
        switch (typeof value) {
            case 'string':
                return stringLength(value);
    
            case 'number':
                return Number.isFinite(value) ? String(value).length : 4 /* null */;
    
            case 'boolean':
                return value ? 4 /* true */ : 5 /* false */;
    
            case 'undefined':
            case 'object':
                return 4; /* null */
    
            default:
                return 0;
        }
    }
    
    function spaceLength(space) {
        space = normalizeSpace(space);
        return typeof space === 'string' ? space.length : 0;
    }
    
    module.exports = function jsonStringifyInfo(value, replacer, space, options) {
        function walk(holder, key, value) {
            if (stop) {
                return;
            }
    
            value = replaceValue(holder, key, value, replacer);
    
            let type = getType(value);
    
            // check for circular structure
            if (type !== PRIMITIVE && stack.has(value)) {
                circular.add(value);
                length += 4; // treat as null
    
                if (!options.continueOnCircular) {
                    stop = true;
                }
    
                return;
            }
    
            switch (type) {
                case PRIMITIVE:
                    if (value !== undefined || Array.isArray(holder)) {
                        length += primitiveLength(value);
                    } else if (holder === root) {
                        length += 9; // FIXME: that's the length of undefined, should we normalize behaviour to convert it to null?
                    }
                    break;
    
                case OBJECT: {
                    if (visited.has(value)) {
                        duplicate.add(value);
                        length += visited.get(value);
                        break;
                    }
    
                    const valueLength = length;
                    let entries = 0;
    
                    length += 2; // {}
    
                    stack.add(value);
    
                    for (const key in value) {
                        if (hasOwnProperty.call(value, key) && (allowlist === null || allowlist.has(key))) {
                            const prevLength = length;
                            walk(value, key, value[key]);
    
                            if (prevLength !== length) {
                                // value is printed
                                length += stringLength(key) + 1; // "key":
                                entries++;
                            }
                        }
                    }
    
                    if (entries > 1) {
                        length += entries - 1; // commas
                    }
    
                    stack.delete(value);
    
                    if (space > 0 && entries > 0) {
                        length += (1 + (stack.size + 1) * space + 1) * entries; // for each key-value: \n{space}
                        length += 1 + stack.size * space; // for }
                    }
    
                    visited.set(value, length - valueLength);
    
                    break;
                }
    
                case ARRAY: {
                    if (visited.has(value)) {
                        duplicate.add(value);
                        length += visited.get(value);
                        break;
                    }
    
                    const valueLength = length;
    
                    length += 2; // []
    
                    stack.add(value);
    
                    for (let i = 0; i < value.length; i++) {
                        walk(value, i, value[i]);
                    }
    
                    if (value.length > 1) {
                        length += value.length - 1; // commas
                    }
    
                    stack.delete(value);
    
                    if (space > 0 && value.length > 0) {
                        length += (1 + (stack.size + 1) * space) * value.length; // for each element: \n{space}
                        length += 1 + stack.size * space; // for ]
                    }
    
                    visited.set(value, length - valueLength);
    
                    break;
                }
    
                case PROMISE:
                case STRING_STREAM:
                    async.add(value);
                    break;
    
                case OBJECT_STREAM:
                    length += 2; // []
                    async.add(value);
                    break;
            }
        }
    
        let allowlist = null;
        replacer = normalizeReplacer(replacer);
    
        if (Array.isArray(replacer)) {
            allowlist = new Set(replacer);
            replacer = null;
        }
    
        space = spaceLength(space);
        options = options || {};
    
        const visited = new Map();
        const stack = new Set();
        const duplicate = new Set();
        const circular = new Set();
        const async = new Set();
        const getType = options.async ? getTypeAsync : getTypeNative;
        const root = { '': value };
        let stop = false;
        let length = 0;
    
        walk(root, '', value);
    
        return {
            minLength: isNaN(length) ? Infinity : length,
            circular: [...circular],
            duplicate: [...duplicate],
            async: [...async]
        };
    };
    
    },{"./utils":7}],5:[function(require,module,exports){
    module.exports = () => {
        throw new Error('Method is not supported');
    };
    
    },{}],6:[function(require,module,exports){
    module.exports = TextDecoder;
    
    },{}],7:[function(require,module,exports){
    const PrimitiveType = 1;
    const ObjectType = 2;
    const ArrayType = 3;
    const PromiseType = 4;
    const ReadableStringType = 5;
    const ReadableObjectType = 6;
    // https://tc39.es/ecma262/#table-json-single-character-escapes
    const escapableCharCodeSubstitution = { // JSON Single Character Escape Sequences
        0x08: '\\b',
        0x09: '\\t',
        0x0a: '\\n',
        0x0c: '\\f',
        0x0d: '\\r',
        0x22: '\\\"',
        0x5c: '\\\\'
    };
    
    function isLeadingSurrogate(code) {
        return code >= 0xD800 && code <= 0xDBFF;
    }
    
    function isTrailingSurrogate(code) {
        return code >= 0xDC00 && code <= 0xDFFF;
    }
    
    function isReadableStream(value) {
        return (
            typeof value.pipe === 'function' &&
            typeof value._read === 'function' &&
            typeof value._readableState === 'object' && value._readableState !== null
        );
    }
    
    function replaceValue(holder, key, value, replacer) {
        if (value && typeof value.toJSON === 'function') {
            value = value.toJSON();
        }
    
        if (replacer !== null) {
            value = replacer.call(holder, String(key), value);
        }
    
        switch (typeof value) {
            case 'function':
            case 'symbol':
                value = undefined;
                break;
    
            case 'object':
                if (value !== null) {
                    const cls = value.constructor;
                    if (cls === String || cls === Number || cls === Boolean) {
                        value = value.valueOf();
                    }
                }
                break;
        }
    
        return value;
    }
    
    function getTypeNative(value) {
        if (value === null || typeof value !== 'object') {
            return PrimitiveType;
        }
    
        if (Array.isArray(value)) {
            return ArrayType;
        }
    
        return ObjectType;
    }
    
    function getTypeAsync(value) {
        if (value === null || typeof value !== 'object') {
            return PrimitiveType;
        }
    
        if (typeof value.then === 'function') {
            return PromiseType;
        }
    
        if (isReadableStream(value)) {
            return value._readableState.objectMode ? ReadableObjectType : ReadableStringType;
        }
    
        if (Array.isArray(value)) {
            return ArrayType;
        }
    
        return ObjectType;
    }
    
    function normalizeReplacer(replacer) {
        if (typeof replacer === 'function') {
            return replacer;
        }
    
        if (Array.isArray(replacer)) {
            const allowlist = new Set(replacer
                .map(item => {
                    const cls = item && item.constructor;
                    return cls === String || cls === Number ? String(item) : null;
                })
                .filter(item => typeof item === 'string')
            );
    
            return [...allowlist];
        }
    
        return null;
    }
    
    function normalizeSpace(space) {
        if (typeof space === 'number') {
            if (!Number.isFinite(space) || space < 1) {
                return false;
            }
    
            return ' '.repeat(Math.min(space, 10));
        }
    
        if (typeof space === 'string') {
            return space.slice(0, 10) || false;
        }
    
        return false;
    }
    
    module.exports = {
        escapableCharCodeSubstitution,
        isLeadingSurrogate,
        isTrailingSurrogate,
        type: {
            PRIMITIVE: PrimitiveType,
            PROMISE: PromiseType,
            ARRAY: ArrayType,
            OBJECT: ObjectType,
            STRING_STREAM: ReadableStringType,
            OBJECT_STREAM: ReadableObjectType
        },
    
        isReadableStream,
        replaceValue,
        getTypeNative,
        getTypeAsync,
        normalizeReplacer,
        normalizeSpace
    };
    
    },{}],8:[function(require,module,exports){
    /*! MIT License. Copyright 2015-2018 Richard Moore <me@ricmoo.com>. See LICENSE.txt. */
    (function(root) {
        "use strict";
    
        function checkInt(value) {
            return (parseInt(value) === value);
        }
    
        function checkInts(arrayish) {
            if (!checkInt(arrayish.length)) { return false; }
    
            for (var i = 0; i < arrayish.length; i++) {
                if (!checkInt(arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255) {
                    return false;
                }
            }
    
            return true;
        }
    
        function coerceArray(arg, copy) {
    
            // ArrayBuffer view
            if (arg.buffer && arg.name === 'Uint8Array') {
    
                if (copy) {
                    if (arg.slice) {
                        arg = arg.slice();
                    } else {
                        arg = Array.prototype.slice.call(arg);
                    }
                }
    
                return arg;
            }
    
            // It's an array; check it is a valid representation of a byte
            if (Array.isArray(arg)) {
                if (!checkInts(arg)) {
                    throw new Error('Array contains invalid value: ' + arg);
                }
    
                return new Uint8Array(arg);
            }
    
            // Something else, but behaves like an array (maybe a Buffer? Arguments?)
            if (checkInt(arg.length) && checkInts(arg)) {
                return new Uint8Array(arg);
            }
    
            throw new Error('unsupported array-like object');
        }
    
        function createArray(length) {
            return new Uint8Array(length);
        }
    
        function copyArray(sourceArray, targetArray, targetStart, sourceStart, sourceEnd) {
            if (sourceStart != null || sourceEnd != null) {
                if (sourceArray.slice) {
                    sourceArray = sourceArray.slice(sourceStart, sourceEnd);
                } else {
                    sourceArray = Array.prototype.slice.call(sourceArray, sourceStart, sourceEnd);
                }
            }
            targetArray.set(sourceArray, targetStart);
        }
    
    
    
        var convertUtf8 = (function() {
            function toBytes(text) {
                var result = [], i = 0;
                text = encodeURI(text);
                while (i < text.length) {
                    var c = text.charCodeAt(i++);
    
                    // if it is a % sign, encode the following 2 bytes as a hex value
                    if (c === 37) {
                        result.push(parseInt(text.substr(i, 2), 16))
                        i += 2;
    
                    // otherwise, just the actual byte
                    } else {
                        result.push(c)
                    }
                }
    
                return coerceArray(result);
            }
    
            function fromBytes(bytes) {
                var result = [], i = 0;
    
                while (i < bytes.length) {
                    var c = bytes[i];
    
                    if (c < 128) {
                        result.push(String.fromCharCode(c));
                        i++;
                    } else if (c > 191 && c < 224) {
                        result.push(String.fromCharCode(((c & 0x1f) << 6) | (bytes[i + 1] & 0x3f)));
                        i += 2;
                    } else {
                        result.push(String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f)));
                        i += 3;
                    }
                }
    
                return result.join('');
            }
    
            return {
                toBytes: toBytes,
                fromBytes: fromBytes,
            }
        })();
    
        var convertHex = (function() {
            function toBytes(text) {
                var result = [];
                for (var i = 0; i < text.length; i += 2) {
                    result.push(parseInt(text.substr(i, 2), 16));
                }
    
                return result;
            }
    
            // http://ixti.net/development/javascript/2011/11/11/base64-encodedecode-of-utf8-in-browser-with-js.html
            var Hex = '0123456789abcdef';
    
            function fromBytes(bytes) {
                    var result = [];
                    for (var i = 0; i < bytes.length; i++) {
                        var v = bytes[i];
                        result.push(Hex[(v & 0xf0) >> 4] + Hex[v & 0x0f]);
                    }
                    return result.join('');
            }
    
            return {
                toBytes: toBytes,
                fromBytes: fromBytes,
            }
        })();
    
    
        // Number of rounds by keysize
        var numberOfRounds = {16: 10, 24: 12, 32: 14}
    
        // Round constant words
        var rcon = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91];
    
        // S-box and Inverse S-box (S is for Substitution)
        var S = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16];
        var Si =[0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d];
    
        // Transformations for encryption
        var T1 = [0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a];
        var T2 = [0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0, 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5, 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c, 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e, 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616];
        var T3 = [0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c, 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008, 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e, 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16];
        var T4 = [0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8, 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810, 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c, 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c];
    
        // Transformations for decryption
        var T5 = [0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742];
        var T6 = [0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8, 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857];
        var T7 = [0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6, 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8];
        var T8 = [0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9, 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4, 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0];
    
        // Transformations for decryption key expansion
        var U1 = [0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3];
        var U2 = [0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f, 0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3, 0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac, 0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0, 0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814, 0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e, 0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa, 0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8, 0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6, 0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9, 0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225, 0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd, 0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91, 0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75, 0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842, 0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6, 0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa, 0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8, 0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544, 0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b, 0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647, 0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3, 0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697];
        var U3 = [0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253, 0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf, 0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920, 0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c, 0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8, 0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749, 0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd, 0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791, 0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e, 0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4, 0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2, 0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7, 0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b, 0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f, 0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8, 0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c, 0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030, 0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9, 0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635, 0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba, 0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6, 0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562, 0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46];
        var U4 = [0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562, 0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca, 0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9, 0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281, 0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59, 0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787, 0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb, 0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f, 0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17, 0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814, 0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc, 0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53, 0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b, 0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3, 0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0, 0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168, 0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04, 0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520, 0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e, 0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02, 0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026, 0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725, 0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d, 0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1, 0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5, 0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d];
    
        function convertToInt32(bytes) {
            var result = [];
            for (var i = 0; i < bytes.length; i += 4) {
                result.push(
                    (bytes[i    ] << 24) |
                    (bytes[i + 1] << 16) |
                    (bytes[i + 2] <<  8) |
                     bytes[i + 3]
                );
            }
            return result;
        }
    
        var AES = function(key) {
            if (!(this instanceof AES)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            Object.defineProperty(this, 'key', {
                value: coerceArray(key, true)
            });
    
            this._prepare();
        }
    
    
        AES.prototype._prepare = function() {
    
            var rounds = numberOfRounds[this.key.length];
            if (rounds == null) {
                throw new Error('invalid key size (must be 16, 24 or 32 bytes)');
            }
    
            // encryption round keys
            this._Ke = [];
    
            // decryption round keys
            this._Kd = [];
    
            for (var i = 0; i <= rounds; i++) {
                this._Ke.push([0, 0, 0, 0]);
                this._Kd.push([0, 0, 0, 0]);
            }
    
            var roundKeyCount = (rounds + 1) * 4;
            var KC = this.key.length / 4;
    
            // convert the key into ints
            var tk = convertToInt32(this.key);
    
            // copy values into round key arrays
            var index;
            for (var i = 0; i < KC; i++) {
                index = i >> 2;
                this._Ke[index][i % 4] = tk[i];
                this._Kd[rounds - index][i % 4] = tk[i];
            }
    
            // key expansion (fips-197 section 5.2)
            var rconpointer = 0;
            var t = KC, tt;
            while (t < roundKeyCount) {
                tt = tk[KC - 1];
                tk[0] ^= ((S[(tt >> 16) & 0xFF] << 24) ^
                          (S[(tt >>  8) & 0xFF] << 16) ^
                          (S[ tt        & 0xFF] <<  8) ^
                           S[(tt >> 24) & 0xFF]        ^
                          (rcon[rconpointer] << 24));
                rconpointer += 1;
    
                // key expansion (for non-256 bit)
                if (KC != 8) {
                    for (var i = 1; i < KC; i++) {
                        tk[i] ^= tk[i - 1];
                    }
    
                // key expansion for 256-bit keys is "slightly different" (fips-197)
                } else {
                    for (var i = 1; i < (KC / 2); i++) {
                        tk[i] ^= tk[i - 1];
                    }
                    tt = tk[(KC / 2) - 1];
    
                    tk[KC / 2] ^= (S[ tt        & 0xFF]        ^
                                  (S[(tt >>  8) & 0xFF] <<  8) ^
                                  (S[(tt >> 16) & 0xFF] << 16) ^
                                  (S[(tt >> 24) & 0xFF] << 24));
    
                    for (var i = (KC / 2) + 1; i < KC; i++) {
                        tk[i] ^= tk[i - 1];
                    }
                }
    
                // copy values into round key arrays
                var i = 0, r, c;
                while (i < KC && t < roundKeyCount) {
                    r = t >> 2;
                    c = t % 4;
                    this._Ke[r][c] = tk[i];
                    this._Kd[rounds - r][c] = tk[i++];
                    t++;
                }
            }
    
            // inverse-cipher-ify the decryption round key (fips-197 section 5.3)
            for (var r = 1; r < rounds; r++) {
                for (var c = 0; c < 4; c++) {
                    tt = this._Kd[r][c];
                    this._Kd[r][c] = (U1[(tt >> 24) & 0xFF] ^
                                      U2[(tt >> 16) & 0xFF] ^
                                      U3[(tt >>  8) & 0xFF] ^
                                      U4[ tt        & 0xFF]);
                }
            }
        }
    
        AES.prototype.encrypt = function(plaintext) {
            if (plaintext.length != 16) {
                throw new Error('invalid plaintext size (must be 16 bytes)');
            }
    
            var rounds = this._Ke.length - 1;
            var a = [0, 0, 0, 0];
    
            // convert plaintext to (ints ^ key)
            var t = convertToInt32(plaintext);
            for (var i = 0; i < 4; i++) {
                t[i] ^= this._Ke[0][i];
            }
    
            // apply round transforms
            for (var r = 1; r < rounds; r++) {
                for (var i = 0; i < 4; i++) {
                    a[i] = (T1[(t[ i         ] >> 24) & 0xff] ^
                            T2[(t[(i + 1) % 4] >> 16) & 0xff] ^
                            T3[(t[(i + 2) % 4] >>  8) & 0xff] ^
                            T4[ t[(i + 3) % 4]        & 0xff] ^
                            this._Ke[r][i]);
                }
                t = a.slice();
            }
    
            // the last round is special
            var result = createArray(16), tt;
            for (var i = 0; i < 4; i++) {
                tt = this._Ke[rounds][i];
                result[4 * i    ] = (S[(t[ i         ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
                result[4 * i + 1] = (S[(t[(i + 1) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
                result[4 * i + 2] = (S[(t[(i + 2) % 4] >>  8) & 0xff] ^ (tt >>  8)) & 0xff;
                result[4 * i + 3] = (S[ t[(i + 3) % 4]        & 0xff] ^  tt       ) & 0xff;
            }
    
            return result;
        }
    
        AES.prototype.decrypt = function(ciphertext) {
            if (ciphertext.length != 16) {
                throw new Error('invalid ciphertext size (must be 16 bytes)');
            }
    
            var rounds = this._Kd.length - 1;
            var a = [0, 0, 0, 0];
    
            // convert plaintext to (ints ^ key)
            var t = convertToInt32(ciphertext);
            for (var i = 0; i < 4; i++) {
                t[i] ^= this._Kd[0][i];
            }
    
            // apply round transforms
            for (var r = 1; r < rounds; r++) {
                for (var i = 0; i < 4; i++) {
                    a[i] = (T5[(t[ i          ] >> 24) & 0xff] ^
                            T6[(t[(i + 3) % 4] >> 16) & 0xff] ^
                            T7[(t[(i + 2) % 4] >>  8) & 0xff] ^
                            T8[ t[(i + 1) % 4]        & 0xff] ^
                            this._Kd[r][i]);
                }
                t = a.slice();
            }
    
            // the last round is special
            var result = createArray(16), tt;
            for (var i = 0; i < 4; i++) {
                tt = this._Kd[rounds][i];
                result[4 * i    ] = (Si[(t[ i         ] >> 24) & 0xff] ^ (tt >> 24)) & 0xff;
                result[4 * i + 1] = (Si[(t[(i + 3) % 4] >> 16) & 0xff] ^ (tt >> 16)) & 0xff;
                result[4 * i + 2] = (Si[(t[(i + 2) % 4] >>  8) & 0xff] ^ (tt >>  8)) & 0xff;
                result[4 * i + 3] = (Si[ t[(i + 1) % 4]        & 0xff] ^  tt       ) & 0xff;
            }
    
            return result;
        }
    
    
        /**
         *  Mode Of Operation - Electonic Codebook (ECB)
         */
        var ModeOfOperationECB = function(key) {
            if (!(this instanceof ModeOfOperationECB)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            this.description = "Electronic Code Block";
            this.name = "ecb";
    
            this._aes = new AES(key);
        }
    
        ModeOfOperationECB.prototype.encrypt = function(plaintext) {
            plaintext = coerceArray(plaintext);
    
            if ((plaintext.length % 16) !== 0) {
                throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
            }
    
            var ciphertext = createArray(plaintext.length);
            var block = createArray(16);
    
            for (var i = 0; i < plaintext.length; i += 16) {
                copyArray(plaintext, block, 0, i, i + 16);
                block = this._aes.encrypt(block);
                copyArray(block, ciphertext, i);
            }
    
            return ciphertext;
        }
    
        ModeOfOperationECB.prototype.decrypt = function(ciphertext) {
            ciphertext = coerceArray(ciphertext);
    
            if ((ciphertext.length % 16) !== 0) {
                throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
            }
    
            var plaintext = createArray(ciphertext.length);
            var block = createArray(16);
    
            for (var i = 0; i < ciphertext.length; i += 16) {
                copyArray(ciphertext, block, 0, i, i + 16);
                block = this._aes.decrypt(block);
                copyArray(block, plaintext, i);
            }
    
            return plaintext;
        }
    
    
        /**
         *  Mode Of Operation - Cipher Block Chaining (CBC)
         */
        var ModeOfOperationCBC = function(key, iv) {
            if (!(this instanceof ModeOfOperationCBC)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            this.description = "Cipher Block Chaining";
            this.name = "cbc";
    
            if (!iv) {
                iv = createArray(16);
    
            } else if (iv.length != 16) {
                throw new Error('invalid initialation vector size (must be 16 bytes)');
            }
    
            this._lastCipherblock = coerceArray(iv, true);
    
            this._aes = new AES(key);
        }
    
        ModeOfOperationCBC.prototype.encrypt = function(plaintext) {
            plaintext = coerceArray(plaintext);
    
            if ((plaintext.length % 16) !== 0) {
                throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
            }
    
            var ciphertext = createArray(plaintext.length);
            var block = createArray(16);
    
            for (var i = 0; i < plaintext.length; i += 16) {
                copyArray(plaintext, block, 0, i, i + 16);
    
                for (var j = 0; j < 16; j++) {
                    block[j] ^= this._lastCipherblock[j];
                }
    
                this._lastCipherblock = this._aes.encrypt(block);
                copyArray(this._lastCipherblock, ciphertext, i);
            }
    
            return ciphertext;
        }
    
        ModeOfOperationCBC.prototype.decrypt = function(ciphertext) {
            ciphertext = coerceArray(ciphertext);
    
            if ((ciphertext.length % 16) !== 0) {
                throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
            }
    
            var plaintext = createArray(ciphertext.length);
            var block = createArray(16);
    
            for (var i = 0; i < ciphertext.length; i += 16) {
                copyArray(ciphertext, block, 0, i, i + 16);
                block = this._aes.decrypt(block);
    
                for (var j = 0; j < 16; j++) {
                    plaintext[i + j] = block[j] ^ this._lastCipherblock[j];
                }
    
                copyArray(ciphertext, this._lastCipherblock, 0, i, i + 16);
            }
    
            return plaintext;
        }
    
    
        /**
         *  Mode Of Operation - Cipher Feedback (CFB)
         */
        var ModeOfOperationCFB = function(key, iv, segmentSize) {
            if (!(this instanceof ModeOfOperationCFB)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            this.description = "Cipher Feedback";
            this.name = "cfb";
    
            if (!iv) {
                iv = createArray(16);
    
            } else if (iv.length != 16) {
                throw new Error('invalid initialation vector size (must be 16 size)');
            }
    
            if (!segmentSize) { segmentSize = 1; }
    
            this.segmentSize = segmentSize;
    
            this._shiftRegister = coerceArray(iv, true);
    
            this._aes = new AES(key);
        }
    
        ModeOfOperationCFB.prototype.encrypt = function(plaintext) {
            if ((plaintext.length % this.segmentSize) != 0) {
                throw new Error('invalid plaintext size (must be segmentSize bytes)');
            }
    
            var encrypted = coerceArray(plaintext, true);
    
            var xorSegment;
            for (var i = 0; i < encrypted.length; i += this.segmentSize) {
                xorSegment = this._aes.encrypt(this._shiftRegister);
                for (var j = 0; j < this.segmentSize; j++) {
                    encrypted[i + j] ^= xorSegment[j];
                }
    
                // Shift the register
                copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
                copyArray(encrypted, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
            }
    
            return encrypted;
        }
    
        ModeOfOperationCFB.prototype.decrypt = function(ciphertext) {
            if ((ciphertext.length % this.segmentSize) != 0) {
                throw new Error('invalid ciphertext size (must be segmentSize bytes)');
            }
    
            var plaintext = coerceArray(ciphertext, true);
    
            var xorSegment;
            for (var i = 0; i < plaintext.length; i += this.segmentSize) {
                xorSegment = this._aes.encrypt(this._shiftRegister);
    
                for (var j = 0; j < this.segmentSize; j++) {
                    plaintext[i + j] ^= xorSegment[j];
                }
    
                // Shift the register
                copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
                copyArray(ciphertext, this._shiftRegister, 16 - this.segmentSize, i, i + this.segmentSize);
            }
    
            return plaintext;
        }
    
        /**
         *  Mode Of Operation - Output Feedback (OFB)
         */
        var ModeOfOperationOFB = function(key, iv) {
            if (!(this instanceof ModeOfOperationOFB)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            this.description = "Output Feedback";
            this.name = "ofb";
    
            if (!iv) {
                iv = createArray(16);
    
            } else if (iv.length != 16) {
                throw new Error('invalid initialation vector size (must be 16 bytes)');
            }
    
            this._lastPrecipher = coerceArray(iv, true);
            this._lastPrecipherIndex = 16;
    
            this._aes = new AES(key);
        }
    
        ModeOfOperationOFB.prototype.encrypt = function(plaintext) {
            var encrypted = coerceArray(plaintext, true);
    
            for (var i = 0; i < encrypted.length; i++) {
                if (this._lastPrecipherIndex === 16) {
                    this._lastPrecipher = this._aes.encrypt(this._lastPrecipher);
                    this._lastPrecipherIndex = 0;
                }
                encrypted[i] ^= this._lastPrecipher[this._lastPrecipherIndex++];
            }
    
            return encrypted;
        }
    
        // Decryption is symetric
        ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt;
    
    
        /**
         *  Counter object for CTR common mode of operation
         */
        var Counter = function(initialValue) {
            if (!(this instanceof Counter)) {
                throw Error('Counter must be instanitated with `new`');
            }
    
            // We allow 0, but anything false-ish uses the default 1
            if (initialValue !== 0 && !initialValue) { initialValue = 1; }
    
            if (typeof(initialValue) === 'number') {
                this._counter = createArray(16);
                this.setValue(initialValue);
    
            } else {
                this.setBytes(initialValue);
            }
        }
    
        Counter.prototype.setValue = function(value) {
            if (typeof(value) !== 'number' || parseInt(value) != value) {
                throw new Error('invalid counter value (must be an integer)');
            }
    
            // We cannot safely handle numbers beyond the safe range for integers
            if (value > Number.MAX_SAFE_INTEGER) {
                throw new Error('integer value out of safe range');
            }
    
            for (var index = 15; index >= 0; --index) {
                this._counter[index] = value % 256;
                value = parseInt(value / 256);
            }
        }
    
        Counter.prototype.setBytes = function(bytes) {
            bytes = coerceArray(bytes, true);
    
            if (bytes.length != 16) {
                throw new Error('invalid counter bytes size (must be 16 bytes)');
            }
    
            this._counter = bytes;
        };
    
        Counter.prototype.increment = function() {
            for (var i = 15; i >= 0; i--) {
                if (this._counter[i] === 255) {
                    this._counter[i] = 0;
                } else {
                    this._counter[i]++;
                    break;
                }
            }
        }
    
    
        /**
         *  Mode Of Operation - Counter (CTR)
         */
        var ModeOfOperationCTR = function(key, counter) {
            if (!(this instanceof ModeOfOperationCTR)) {
                throw Error('AES must be instanitated with `new`');
            }
    
            this.description = "Counter";
            this.name = "ctr";
    
            if (!(counter instanceof Counter)) {
                counter = new Counter(counter)
            }
    
            this._counter = counter;
    
            this._remainingCounter = null;
            this._remainingCounterIndex = 16;
    
            this._aes = new AES(key);
        }
    
        ModeOfOperationCTR.prototype.encrypt = function(plaintext) {
            var encrypted = coerceArray(plaintext, true);
    
            for (var i = 0; i < encrypted.length; i++) {
                if (this._remainingCounterIndex === 16) {
                    this._remainingCounter = this._aes.encrypt(this._counter._counter);
                    this._remainingCounterIndex = 0;
                    this._counter.increment();
                }
                encrypted[i] ^= this._remainingCounter[this._remainingCounterIndex++];
            }
    
            return encrypted;
        }
    
        // Decryption is symetric
        ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;
    
    
        ///////////////////////
        // Padding
    
        // See:https://tools.ietf.org/html/rfc2315
        function pkcs7pad(data) {
            data = coerceArray(data, true);
            var padder = 16 - (data.length % 16);
            var result = createArray(data.length + padder);
            copyArray(data, result);
            for (var i = data.length; i < result.length; i++) {
                result[i] = padder;
            }
            return result;
        }
    
        function pkcs7strip(data) {
            data = coerceArray(data, true);
            if (data.length < 16) { throw new Error('PKCS#7 invalid length'); }
    
            var padder = data[data.length - 1];
            if (padder > 16) { throw new Error('PKCS#7 padding byte out of range'); }
    
            var length = data.length - padder;
            for (var i = 0; i < padder; i++) {
                if (data[length + i] !== padder) {
                    throw new Error('PKCS#7 invalid padding byte');
                }
            }
    
            var result = createArray(length);
            copyArray(data, result, 0, 0, length);
            return result;
        }
    
        ///////////////////////
        // Exporting
    
    
        // The block cipher
        var aesjs = {
            AES: AES,
            Counter: Counter,
    
            ModeOfOperation: {
                ecb: ModeOfOperationECB,
                cbc: ModeOfOperationCBC,
                cfb: ModeOfOperationCFB,
                ofb: ModeOfOperationOFB,
                ctr: ModeOfOperationCTR
            },
    
            utils: {
                hex: convertHex,
                utf8: convertUtf8
            },
    
            padding: {
                pkcs7: {
                    pad: pkcs7pad,
                    strip: pkcs7strip
                }
            },
    
            _arrayTest: {
                coerceArray: coerceArray,
                createArray: createArray,
                copyArray: copyArray,
            }
        };
    
    
        // node.js
        if (typeof exports !== 'undefined') {
            module.exports = aesjs
    
        // RequireJS/AMD
        // http://www.requirejs.org/docs/api.html
        // https://github.com/amdjs/amdjs-api/wiki/AMD
        } else if (typeof(define) === 'function' && define.amd) {
            define([], function() { return aesjs; });
    
        // Web Browsers
        } else {
    
            // If there was an existing library at "aesjs" make sure it's still available
            if (root.aesjs) {
                aesjs._aesjs = root.aesjs;
            }
    
            root.aesjs = aesjs;
        }
    
    
    })(this);
    
    },{}],9:[function(require,module,exports){
    'use strict';
    
    const wrapAnsi16 = (fn, offset) => (...args) => {
        const code = fn(...args);
        return `\u001B[${code + offset}m`;
    };
    
    const wrapAnsi256 = (fn, offset) => (...args) => {
        const code = fn(...args);
        return `\u001B[${38 + offset};5;${code}m`;
    };
    
    const wrapAnsi16m = (fn, offset) => (...args) => {
        const rgb = fn(...args);
        return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
    };
    
    const ansi2ansi = n => n;
    const rgb2rgb = (r, g, b) => [r, g, b];
    
    const setLazyProperty = (object, property, get) => {
        Object.defineProperty(object, property, {
            get: () => {
                const value = get();
    
                Object.defineProperty(object, property, {
                    value,
                    enumerable: true,
                    configurable: true
                });
    
                return value;
            },
            enumerable: true,
            configurable: true
        });
    };
    
    /** @type {typeof import('color-convert')} */
    let colorConvert;
    const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
        if (colorConvert === undefined) {
            colorConvert = require('color-convert');
        }
    
        const offset = isBackground ? 10 : 0;
        const styles = {};
    
        for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
            const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace;
            if (sourceSpace === targetSpace) {
                styles[name] = wrap(identity, offset);
            } else if (typeof suite === 'object') {
                styles[name] = wrap(suite[targetSpace], offset);
            }
        }
    
        return styles;
    };
    
    function assembleStyles() {
        const codes = new Map();
        const styles = {
            modifier: {
                reset: [0, 0],
                // 21 isn't widely supported and 22 does the same thing
                bold: [1, 22],
                dim: [2, 22],
                italic: [3, 23],
                underline: [4, 24],
                inverse: [7, 27],
                hidden: [8, 28],
                strikethrough: [9, 29]
            },
            color: {
                black: [30, 39],
                red: [31, 39],
                green: [32, 39],
                yellow: [33, 39],
                blue: [34, 39],
                magenta: [35, 39],
                cyan: [36, 39],
                white: [37, 39],
    
                // Bright color
                blackBright: [90, 39],
                redBright: [91, 39],
                greenBright: [92, 39],
                yellowBright: [93, 39],
                blueBright: [94, 39],
                magentaBright: [95, 39],
                cyanBright: [96, 39],
                whiteBright: [97, 39]
            },
            bgColor: {
                bgBlack: [40, 49],
                bgRed: [41, 49],
                bgGreen: [42, 49],
                bgYellow: [43, 49],
                bgBlue: [44, 49],
                bgMagenta: [45, 49],
                bgCyan: [46, 49],
                bgWhite: [47, 49],
    
                // Bright color
                bgBlackBright: [100, 49],
                bgRedBright: [101, 49],
                bgGreenBright: [102, 49],
                bgYellowBright: [103, 49],
                bgBlueBright: [104, 49],
                bgMagentaBright: [105, 49],
                bgCyanBright: [106, 49],
                bgWhiteBright: [107, 49]
            }
        };
    
        // Alias bright black as gray (and grey)
        styles.color.gray = styles.color.blackBright;
        styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
        styles.color.grey = styles.color.blackBright;
        styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
    
        for (const [groupName, group] of Object.entries(styles)) {
            for (const [styleName, style] of Object.entries(group)) {
                styles[styleName] = {
                    open: `\u001B[${style[0]}m`,
                    close: `\u001B[${style[1]}m`
                };
    
                group[styleName] = styles[styleName];
    
                codes.set(style[0], style[1]);
            }
    
            Object.defineProperty(styles, groupName, {
                value: group,
                enumerable: false
            });
        }
    
        Object.defineProperty(styles, 'codes', {
            value: codes,
            enumerable: false
        });
    
        styles.color.close = '\u001B[39m';
        styles.bgColor.close = '\u001B[49m';
    
        setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false));
        setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false));
        setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false));
        setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true));
        setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true));
        setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true));
    
        return styles;
    }
    
    // Make the export immutable
    Object.defineProperty(module, 'exports', {
        enumerable: true,
        get: assembleStyles
    });
    
    },{"color-convert":96}],10:[function(require,module,exports){
    'use strict';
    
    const asn1 = exports;
    
    asn1.bignum = require('bn.js');
    
    asn1.define = require('./asn1/api').define;
    asn1.base = require('./asn1/base');
    asn1.constants = require('./asn1/constants');
    asn1.decoders = require('./asn1/decoders');
    asn1.encoders = require('./asn1/encoders');
    
    },{"./asn1/api":11,"./asn1/base":13,"./asn1/constants":17,"./asn1/decoders":19,"./asn1/encoders":22,"bn.js":33}],11:[function(require,module,exports){
    'use strict';
    
    const encoders = require('./encoders');
    const decoders = require('./decoders');
    const inherits = require('inherits');
    
    const api = exports;
    
    api.define = function define(name, body) {
      return new Entity(name, body);
    };
    
    function Entity(name, body) {
      this.name = name;
      this.body = body;
    
      this.decoders = {};
      this.encoders = {};
    }
    
    Entity.prototype._createNamed = function createNamed(Base) {
      const name = this.name;
    
      function Generated(entity) {
        this._initNamed(entity, name);
      }
      inherits(Generated, Base);
      Generated.prototype._initNamed = function _initNamed(entity, name) {
        Base.call(this, entity, name);
      };
    
      return new Generated(this);
    };
    
    Entity.prototype._getDecoder = function _getDecoder(enc) {
      enc = enc || 'der';
      // Lazily create decoder
      if (!this.decoders.hasOwnProperty(enc))
        this.decoders[enc] = this._createNamed(decoders[enc]);
      return this.decoders[enc];
    };
    
    Entity.prototype.decode = function decode(data, enc, options) {
      return this._getDecoder(enc).decode(data, options);
    };
    
    Entity.prototype._getEncoder = function _getEncoder(enc) {
      enc = enc || 'der';
      // Lazily create encoder
      if (!this.encoders.hasOwnProperty(enc))
        this.encoders[enc] = this._createNamed(encoders[enc]);
      return this.encoders[enc];
    };
    
    Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
      return this._getEncoder(enc).encode(data, reporter);
    };
    
    },{"./decoders":19,"./encoders":22,"inherits":182}],12:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    const Reporter = require('../base/reporter').Reporter;
    const Buffer = require('safer-buffer').Buffer;
    
    function DecoderBuffer(base, options) {
      Reporter.call(this, options);
      if (!Buffer.isBuffer(base)) {
        this.error('Input not Buffer');
        return;
      }
    
      this.base = base;
      this.offset = 0;
      this.length = base.length;
    }
    inherits(DecoderBuffer, Reporter);
    exports.DecoderBuffer = DecoderBuffer;
    
    DecoderBuffer.isDecoderBuffer = function isDecoderBuffer(data) {
      if (data instanceof DecoderBuffer) {
        return true;
      }
    
      // Or accept compatible API
      const isCompatible = typeof data === 'object' &&
        Buffer.isBuffer(data.base) &&
        data.constructor.name === 'DecoderBuffer' &&
        typeof data.offset === 'number' &&
        typeof data.length === 'number' &&
        typeof data.save === 'function' &&
        typeof data.restore === 'function' &&
        typeof data.isEmpty === 'function' &&
        typeof data.readUInt8 === 'function' &&
        typeof data.skip === 'function' &&
        typeof data.raw === 'function';
    
      return isCompatible;
    };
    
    DecoderBuffer.prototype.save = function save() {
      return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
    };
    
    DecoderBuffer.prototype.restore = function restore(save) {
      // Return skipped data
      const res = new DecoderBuffer(this.base);
      res.offset = save.offset;
      res.length = this.offset;
    
      this.offset = save.offset;
      Reporter.prototype.restore.call(this, save.reporter);
    
      return res;
    };
    
    DecoderBuffer.prototype.isEmpty = function isEmpty() {
      return this.offset === this.length;
    };
    
    DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
      if (this.offset + 1 <= this.length)
        return this.base.readUInt8(this.offset++, true);
      else
        return this.error(fail || 'DecoderBuffer overrun');
    };
    
    DecoderBuffer.prototype.skip = function skip(bytes, fail) {
      if (!(this.offset + bytes <= this.length))
        return this.error(fail || 'DecoderBuffer overrun');
    
      const res = new DecoderBuffer(this.base);
    
      // Share reporter state
      res._reporterState = this._reporterState;
    
      res.offset = this.offset;
      res.length = this.offset + bytes;
      this.offset += bytes;
      return res;
    };
    
    DecoderBuffer.prototype.raw = function raw(save) {
      return this.base.slice(save ? save.offset : this.offset, this.length);
    };
    
    function EncoderBuffer(value, reporter) {
      if (Array.isArray(value)) {
        this.length = 0;
        this.value = value.map(function(item) {
          if (!EncoderBuffer.isEncoderBuffer(item))
            item = new EncoderBuffer(item, reporter);
          this.length += item.length;
          return item;
        }, this);
      } else if (typeof value === 'number') {
        if (!(0 <= value && value <= 0xff))
          return reporter.error('non-byte EncoderBuffer value');
        this.value = value;
        this.length = 1;
      } else if (typeof value === 'string') {
        this.value = value;
        this.length = Buffer.byteLength(value);
      } else if (Buffer.isBuffer(value)) {
        this.value = value;
        this.length = value.length;
      } else {
        return reporter.error('Unsupported type: ' + typeof value);
      }
    }
    exports.EncoderBuffer = EncoderBuffer;
    
    EncoderBuffer.isEncoderBuffer = function isEncoderBuffer(data) {
      if (data instanceof EncoderBuffer) {
        return true;
      }
    
      // Or accept compatible API
      const isCompatible = typeof data === 'object' &&
        data.constructor.name === 'EncoderBuffer' &&
        typeof data.length === 'number' &&
        typeof data.join === 'function';
    
      return isCompatible;
    };
    
    EncoderBuffer.prototype.join = function join(out, offset) {
      if (!out)
        out = Buffer.alloc(this.length);
      if (!offset)
        offset = 0;
    
      if (this.length === 0)
        return out;
    
      if (Array.isArray(this.value)) {
        this.value.forEach(function(item) {
          item.join(out, offset);
          offset += item.length;
        });
      } else {
        if (typeof this.value === 'number')
          out[offset] = this.value;
        else if (typeof this.value === 'string')
          out.write(this.value, offset);
        else if (Buffer.isBuffer(this.value))
          this.value.copy(out, offset);
        offset += this.length;
      }
    
      return out;
    };
    
    },{"../base/reporter":15,"inherits":182,"safer-buffer":339}],13:[function(require,module,exports){
    'use strict';
    
    const base = exports;
    
    base.Reporter = require('./reporter').Reporter;
    base.DecoderBuffer = require('./buffer').DecoderBuffer;
    base.EncoderBuffer = require('./buffer').EncoderBuffer;
    base.Node = require('./node');
    
    },{"./buffer":12,"./node":14,"./reporter":15}],14:[function(require,module,exports){
    'use strict';
    
    const Reporter = require('../base/reporter').Reporter;
    const EncoderBuffer = require('../base/buffer').EncoderBuffer;
    const DecoderBuffer = require('../base/buffer').DecoderBuffer;
    const assert = require('minimalistic-assert');
    
    // Supported tags
    const tags = [
      'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
      'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc',
      'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
      'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
    ];
    
    // Public methods list
    const methods = [
      'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
      'any', 'contains'
    ].concat(tags);
    
    // Overrided methods list
    const overrided = [
      '_peekTag', '_decodeTag', '_use',
      '_decodeStr', '_decodeObjid', '_decodeTime',
      '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
    
      '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
      '_encodeNull', '_encodeInt', '_encodeBool'
    ];
    
    function Node(enc, parent, name) {
      const state = {};
      this._baseState = state;
    
      state.name = name;
      state.enc = enc;
    
      state.parent = parent || null;
      state.children = null;
    
      // State
      state.tag = null;
      state.args = null;
      state.reverseArgs = null;
      state.choice = null;
      state.optional = false;
      state.any = false;
      state.obj = false;
      state.use = null;
      state.useDecoder = null;
      state.key = null;
      state['default'] = null;
      state.explicit = null;
      state.implicit = null;
      state.contains = null;
    
      // Should create new instance on each method
      if (!state.parent) {
        state.children = [];
        this._wrap();
      }
    }
    module.exports = Node;
    
    const stateProps = [
      'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
      'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
      'implicit', 'contains'
    ];
    
    Node.prototype.clone = function clone() {
      const state = this._baseState;
      const cstate = {};
      stateProps.forEach(function(prop) {
        cstate[prop] = state[prop];
      });
      const res = new this.constructor(cstate.parent);
      res._baseState = cstate;
      return res;
    };
    
    Node.prototype._wrap = function wrap() {
      const state = this._baseState;
      methods.forEach(function(method) {
        this[method] = function _wrappedMethod() {
          const clone = new this.constructor(this);
          state.children.push(clone);
          return clone[method].apply(clone, arguments);
        };
      }, this);
    };
    
    Node.prototype._init = function init(body) {
      const state = this._baseState;
    
      assert(state.parent === null);
      body.call(this);
    
      // Filter children
      state.children = state.children.filter(function(child) {
        return child._baseState.parent === this;
      }, this);
      assert.equal(state.children.length, 1, 'Root node can have only one child');
    };
    
    Node.prototype._useArgs = function useArgs(args) {
      const state = this._baseState;
    
      // Filter children and args
      const children = args.filter(function(arg) {
        return arg instanceof this.constructor;
      }, this);
      args = args.filter(function(arg) {
        return !(arg instanceof this.constructor);
      }, this);
    
      if (children.length !== 0) {
        assert(state.children === null);
        state.children = children;
    
        // Replace parent to maintain backward link
        children.forEach(function(child) {
          child._baseState.parent = this;
        }, this);
      }
      if (args.length !== 0) {
        assert(state.args === null);
        state.args = args;
        state.reverseArgs = args.map(function(arg) {
          if (typeof arg !== 'object' || arg.constructor !== Object)
            return arg;
    
          const res = {};
          Object.keys(arg).forEach(function(key) {
            if (key == (key | 0))
              key |= 0;
            const value = arg[key];
            res[value] = key;
          });
          return res;
        });
      }
    };
    
    //
    // Overrided methods
    //
    
    overrided.forEach(function(method) {
      Node.prototype[method] = function _overrided() {
        const state = this._baseState;
        throw new Error(method + ' not implemented for encoding: ' + state.enc);
      };
    });
    
    //
    // Public methods
    //
    
    tags.forEach(function(tag) {
      Node.prototype[tag] = function _tagMethod() {
        const state = this._baseState;
        const args = Array.prototype.slice.call(arguments);
    
        assert(state.tag === null);
        state.tag = tag;
    
        this._useArgs(args);
    
        return this;
      };
    });
    
    Node.prototype.use = function use(item) {
      assert(item);
      const state = this._baseState;
    
      assert(state.use === null);
      state.use = item;
    
      return this;
    };
    
    Node.prototype.optional = function optional() {
      const state = this._baseState;
    
      state.optional = true;
    
      return this;
    };
    
    Node.prototype.def = function def(val) {
      const state = this._baseState;
    
      assert(state['default'] === null);
      state['default'] = val;
      state.optional = true;
    
      return this;
    };
    
    Node.prototype.explicit = function explicit(num) {
      const state = this._baseState;
    
      assert(state.explicit === null && state.implicit === null);
      state.explicit = num;
    
      return this;
    };
    
    Node.prototype.implicit = function implicit(num) {
      const state = this._baseState;
    
      assert(state.explicit === null && state.implicit === null);
      state.implicit = num;
    
      return this;
    };
    
    Node.prototype.obj = function obj() {
      const state = this._baseState;
      const args = Array.prototype.slice.call(arguments);
    
      state.obj = true;
    
      if (args.length !== 0)
        this._useArgs(args);
    
      return this;
    };
    
    Node.prototype.key = function key(newKey) {
      const state = this._baseState;
    
      assert(state.key === null);
      state.key = newKey;
    
      return this;
    };
    
    Node.prototype.any = function any() {
      const state = this._baseState;
    
      state.any = true;
    
      return this;
    };
    
    Node.prototype.choice = function choice(obj) {
      const state = this._baseState;
    
      assert(state.choice === null);
      state.choice = obj;
      this._useArgs(Object.keys(obj).map(function(key) {
        return obj[key];
      }));
    
      return this;
    };
    
    Node.prototype.contains = function contains(item) {
      const state = this._baseState;
    
      assert(state.use === null);
      state.contains = item;
    
      return this;
    };
    
    //
    // Decoding
    //
    
    Node.prototype._decode = function decode(input, options) {
      const state = this._baseState;
    
      // Decode root node
      if (state.parent === null)
        return input.wrapResult(state.children[0]._decode(input, options));
    
      let result = state['default'];
      let present = true;
    
      let prevKey = null;
      if (state.key !== null)
        prevKey = input.enterKey(state.key);
    
      // Check if tag is there
      if (state.optional) {
        let tag = null;
        if (state.explicit !== null)
          tag = state.explicit;
        else if (state.implicit !== null)
          tag = state.implicit;
        else if (state.tag !== null)
          tag = state.tag;
    
        if (tag === null && !state.any) {
          // Trial and Error
          const save = input.save();
          try {
            if (state.choice === null)
              this._decodeGeneric(state.tag, input, options);
            else
              this._decodeChoice(input, options);
            present = true;
          } catch (e) {
            present = false;
          }
          input.restore(save);
        } else {
          present = this._peekTag(input, tag, state.any);
    
          if (input.isError(present))
            return present;
        }
      }
    
      // Push object on stack
      let prevObj;
      if (state.obj && present)
        prevObj = input.enterObject();
    
      if (present) {
        // Unwrap explicit values
        if (state.explicit !== null) {
          const explicit = this._decodeTag(input, state.explicit);
          if (input.isError(explicit))
            return explicit;
          input = explicit;
        }
    
        const start = input.offset;
    
        // Unwrap implicit and normal values
        if (state.use === null && state.choice === null) {
          let save;
          if (state.any)
            save = input.save();
          const body = this._decodeTag(
            input,
            state.implicit !== null ? state.implicit : state.tag,
            state.any
          );
          if (input.isError(body))
            return body;
    
          if (state.any)
            result = input.raw(save);
          else
            input = body;
        }
    
        if (options && options.track && state.tag !== null)
          options.track(input.path(), start, input.length, 'tagged');
    
        if (options && options.track && state.tag !== null)
          options.track(input.path(), input.offset, input.length, 'content');
    
        // Select proper method for tag
        if (state.any) {
          // no-op
        } else if (state.choice === null) {
          result = this._decodeGeneric(state.tag, input, options);
        } else {
          result = this._decodeChoice(input, options);
        }
    
        if (input.isError(result))
          return result;
    
        // Decode children
        if (!state.any && state.choice === null && state.children !== null) {
          state.children.forEach(function decodeChildren(child) {
            // NOTE: We are ignoring errors here, to let parser continue with other
            // parts of encoded data
            child._decode(input, options);
          });
        }
    
        // Decode contained/encoded by schema, only in bit or octet strings
        if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
          const data = new DecoderBuffer(result);
          result = this._getUse(state.contains, input._reporterState.obj)
            ._decode(data, options);
        }
      }
    
      // Pop object
      if (state.obj && present)
        result = input.leaveObject(prevObj);
    
      // Set key
      if (state.key !== null && (result !== null || present === true))
        input.leaveKey(prevKey, state.key, result);
      else if (prevKey !== null)
        input.exitKey(prevKey);
    
      return result;
    };
    
    Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {
      const state = this._baseState;
    
      if (tag === 'seq' || tag === 'set')
        return null;
      if (tag === 'seqof' || tag === 'setof')
        return this._decodeList(input, tag, state.args[0], options);
      else if (/str$/.test(tag))
        return this._decodeStr(input, tag, options);
      else if (tag === 'objid' && state.args)
        return this._decodeObjid(input, state.args[0], state.args[1], options);
      else if (tag === 'objid')
        return this._decodeObjid(input, null, null, options);
      else if (tag === 'gentime' || tag === 'utctime')
        return this._decodeTime(input, tag, options);
      else if (tag === 'null_')
        return this._decodeNull(input, options);
      else if (tag === 'bool')
        return this._decodeBool(input, options);
      else if (tag === 'objDesc')
        return this._decodeStr(input, tag, options);
      else if (tag === 'int' || tag === 'enum')
        return this._decodeInt(input, state.args && state.args[0], options);
    
      if (state.use !== null) {
        return this._getUse(state.use, input._reporterState.obj)
          ._decode(input, options);
      } else {
        return input.error('unknown tag: ' + tag);
      }
    };
    
    Node.prototype._getUse = function _getUse(entity, obj) {
    
      const state = this._baseState;
      // Create altered use decoder if implicit is set
      state.useDecoder = this._use(entity, obj);
      assert(state.useDecoder._baseState.parent === null);
      state.useDecoder = state.useDecoder._baseState.children[0];
      if (state.implicit !== state.useDecoder._baseState.implicit) {
        state.useDecoder = state.useDecoder.clone();
        state.useDecoder._baseState.implicit = state.implicit;
      }
      return state.useDecoder;
    };
    
    Node.prototype._decodeChoice = function decodeChoice(input, options) {
      const state = this._baseState;
      let result = null;
      let match = false;
    
      Object.keys(state.choice).some(function(key) {
        const save = input.save();
        const node = state.choice[key];
        try {
          const value = node._decode(input, options);
          if (input.isError(value))
            return false;
    
          result = { type: key, value: value };
          match = true;
        } catch (e) {
          input.restore(save);
          return false;
        }
        return true;
      }, this);
    
      if (!match)
        return input.error('Choice not matched');
    
      return result;
    };
    
    //
    // Encoding
    //
    
    Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
      return new EncoderBuffer(data, this.reporter);
    };
    
    Node.prototype._encode = function encode(data, reporter, parent) {
      const state = this._baseState;
      if (state['default'] !== null && state['default'] === data)
        return;
    
      const result = this._encodeValue(data, reporter, parent);
      if (result === undefined)
        return;
    
      if (this._skipDefault(result, reporter, parent))
        return;
    
      return result;
    };
    
    Node.prototype._encodeValue = function encode(data, reporter, parent) {
      const state = this._baseState;
    
      // Decode root node
      if (state.parent === null)
        return state.children[0]._encode(data, reporter || new Reporter());
    
      let result = null;
    
      // Set reporter to share it with a child class
      this.reporter = reporter;
    
      // Check if data is there
      if (state.optional && data === undefined) {
        if (state['default'] !== null)
          data = state['default'];
        else
          return;
      }
    
      // Encode children first
      let content = null;
      let primitive = false;
      if (state.any) {
        // Anything that was given is translated to buffer
        result = this._createEncoderBuffer(data);
      } else if (state.choice) {
        result = this._encodeChoice(data, reporter);
      } else if (state.contains) {
        content = this._getUse(state.contains, parent)._encode(data, reporter);
        primitive = true;
      } else if (state.children) {
        content = state.children.map(function(child) {
          if (child._baseState.tag === 'null_')
            return child._encode(null, reporter, data);
    
          if (child._baseState.key === null)
            return reporter.error('Child should have a key');
          const prevKey = reporter.enterKey(child._baseState.key);
    
          if (typeof data !== 'object')
            return reporter.error('Child expected, but input is not object');
    
          const res = child._encode(data[child._baseState.key], reporter, data);
          reporter.leaveKey(prevKey);
    
          return res;
        }, this).filter(function(child) {
          return child;
        });
        content = this._createEncoderBuffer(content);
      } else {
        if (state.tag === 'seqof' || state.tag === 'setof') {
          // TODO(indutny): this should be thrown on DSL level
          if (!(state.args && state.args.length === 1))
            return reporter.error('Too many args for : ' + state.tag);
    
          if (!Array.isArray(data))
            return reporter.error('seqof/setof, but data is not Array');
    
          const child = this.clone();
          child._baseState.implicit = null;
          content = this._createEncoderBuffer(data.map(function(item) {
            const state = this._baseState;
    
            return this._getUse(state.args[0], data)._encode(item, reporter);
          }, child));
        } else if (state.use !== null) {
          result = this._getUse(state.use, parent)._encode(data, reporter);
        } else {
          content = this._encodePrimitive(state.tag, data);
          primitive = true;
        }
      }
    
      // Encode data itself
      if (!state.any && state.choice === null) {
        const tag = state.implicit !== null ? state.implicit : state.tag;
        const cls = state.implicit === null ? 'universal' : 'context';
    
        if (tag === null) {
          if (state.use === null)
            reporter.error('Tag could be omitted only for .use()');
        } else {
          if (state.use === null)
            result = this._encodeComposite(tag, primitive, cls, content);
        }
      }
    
      // Wrap in explicit
      if (state.explicit !== null)
        result = this._encodeComposite(state.explicit, false, 'context', result);
    
      return result;
    };
    
    Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
      const state = this._baseState;
    
      const node = state.choice[data.type];
      if (!node) {
        assert(
          false,
          data.type + ' not found in ' +
                JSON.stringify(Object.keys(state.choice)));
      }
      return node._encode(data.value, reporter);
    };
    
    Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
      const state = this._baseState;
    
      if (/str$/.test(tag))
        return this._encodeStr(data, tag);
      else if (tag === 'objid' && state.args)
        return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
      else if (tag === 'objid')
        return this._encodeObjid(data, null, null);
      else if (tag === 'gentime' || tag === 'utctime')
        return this._encodeTime(data, tag);
      else if (tag === 'null_')
        return this._encodeNull();
      else if (tag === 'int' || tag === 'enum')
        return this._encodeInt(data, state.args && state.reverseArgs[0]);
      else if (tag === 'bool')
        return this._encodeBool(data);
      else if (tag === 'objDesc')
        return this._encodeStr(data, tag);
      else
        throw new Error('Unsupported tag: ' + tag);
    };
    
    Node.prototype._isNumstr = function isNumstr(str) {
      return /^[0-9 ]*$/.test(str);
    };
    
    Node.prototype._isPrintstr = function isPrintstr(str) {
      return /^[A-Za-z0-9 '()+,-./:=?]*$/.test(str);
    };
    
    },{"../base/buffer":12,"../base/reporter":15,"minimalistic-assert":194}],15:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    
    function Reporter(options) {
      this._reporterState = {
        obj: null,
        path: [],
        options: options || {},
        errors: []
      };
    }
    exports.Reporter = Reporter;
    
    Reporter.prototype.isError = function isError(obj) {
      return obj instanceof ReporterError;
    };
    
    Reporter.prototype.save = function save() {
      const state = this._reporterState;
    
      return { obj: state.obj, pathLen: state.path.length };
    };
    
    Reporter.prototype.restore = function restore(data) {
      const state = this._reporterState;
    
      state.obj = data.obj;
      state.path = state.path.slice(0, data.pathLen);
    };
    
    Reporter.prototype.enterKey = function enterKey(key) {
      return this._reporterState.path.push(key);
    };
    
    Reporter.prototype.exitKey = function exitKey(index) {
      const state = this._reporterState;
    
      state.path = state.path.slice(0, index - 1);
    };
    
    Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
      const state = this._reporterState;
    
      this.exitKey(index);
      if (state.obj !== null)
        state.obj[key] = value;
    };
    
    Reporter.prototype.path = function path() {
      return this._reporterState.path.join('/');
    };
    
    Reporter.prototype.enterObject = function enterObject() {
      const state = this._reporterState;
    
      const prev = state.obj;
      state.obj = {};
      return prev;
    };
    
    Reporter.prototype.leaveObject = function leaveObject(prev) {
      const state = this._reporterState;
    
      const now = state.obj;
      state.obj = prev;
      return now;
    };
    
    Reporter.prototype.error = function error(msg) {
      let err;
      const state = this._reporterState;
    
      const inherited = msg instanceof ReporterError;
      if (inherited) {
        err = msg;
      } else {
        err = new ReporterError(state.path.map(function(elem) {
          return '[' + JSON.stringify(elem) + ']';
        }).join(''), msg.message || msg, msg.stack);
      }
    
      if (!state.options.partial)
        throw err;
    
      if (!inherited)
        state.errors.push(err);
    
      return err;
    };
    
    Reporter.prototype.wrapResult = function wrapResult(result) {
      const state = this._reporterState;
      if (!state.options.partial)
        return result;
    
      return {
        result: this.isError(result) ? null : result,
        errors: state.errors
      };
    };
    
    function ReporterError(path, msg) {
      this.path = path;
      this.rethrow(msg);
    }
    inherits(ReporterError, Error);
    
    ReporterError.prototype.rethrow = function rethrow(msg) {
      this.message = msg + ' at: ' + (this.path || '(shallow)');
      if (Error.captureStackTrace)
        Error.captureStackTrace(this, ReporterError);
    
      if (!this.stack) {
        try {
          // IE only adds stack when thrown
          throw new Error(this.message);
        } catch (e) {
          this.stack = e.stack;
        }
      }
      return this;
    };
    
    },{"inherits":182}],16:[function(require,module,exports){
    'use strict';
    
    // Helper
    function reverse(map) {
      const res = {};
    
      Object.keys(map).forEach(function(key) {
        // Convert key to integer if it is stringified
        if ((key | 0) == key)
          key = key | 0;
    
        const value = map[key];
        res[value] = key;
      });
    
      return res;
    }
    
    exports.tagClass = {
      0: 'universal',
      1: 'application',
      2: 'context',
      3: 'private'
    };
    exports.tagClassByName = reverse(exports.tagClass);
    
    exports.tag = {
      0x00: 'end',
      0x01: 'bool',
      0x02: 'int',
      0x03: 'bitstr',
      0x04: 'octstr',
      0x05: 'null_',
      0x06: 'objid',
      0x07: 'objDesc',
      0x08: 'external',
      0x09: 'real',
      0x0a: 'enum',
      0x0b: 'embed',
      0x0c: 'utf8str',
      0x0d: 'relativeOid',
      0x10: 'seq',
      0x11: 'set',
      0x12: 'numstr',
      0x13: 'printstr',
      0x14: 't61str',
      0x15: 'videostr',
      0x16: 'ia5str',
      0x17: 'utctime',
      0x18: 'gentime',
      0x19: 'graphstr',
      0x1a: 'iso646str',
      0x1b: 'genstr',
      0x1c: 'unistr',
      0x1d: 'charstr',
      0x1e: 'bmpstr'
    };
    exports.tagByName = reverse(exports.tag);
    
    },{}],17:[function(require,module,exports){
    'use strict';
    
    const constants = exports;
    
    // Helper
    constants._reverse = function reverse(map) {
      const res = {};
    
      Object.keys(map).forEach(function(key) {
        // Convert key to integer if it is stringified
        if ((key | 0) == key)
          key = key | 0;
    
        const value = map[key];
        res[value] = key;
      });
    
      return res;
    };
    
    constants.der = require('./der');
    
    },{"./der":16}],18:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    
    const bignum = require('bn.js');
    const DecoderBuffer = require('../base/buffer').DecoderBuffer;
    const Node = require('../base/node');
    
    // Import DER constants
    const der = require('../constants/der');
    
    function DERDecoder(entity) {
      this.enc = 'der';
      this.name = entity.name;
      this.entity = entity;
    
      // Construct base tree
      this.tree = new DERNode();
      this.tree._init(entity.body);
    }
    module.exports = DERDecoder;
    
    DERDecoder.prototype.decode = function decode(data, options) {
      if (!DecoderBuffer.isDecoderBuffer(data)) {
        data = new DecoderBuffer(data, options);
      }
    
      return this.tree._decode(data, options);
    };
    
    // Tree methods
    
    function DERNode(parent) {
      Node.call(this, 'der', parent);
    }
    inherits(DERNode, Node);
    
    DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {
      if (buffer.isEmpty())
        return false;
    
      const state = buffer.save();
      const decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');
      if (buffer.isError(decodedTag))
        return decodedTag;
    
      buffer.restore(state);
    
      return decodedTag.tag === tag || decodedTag.tagStr === tag ||
        (decodedTag.tagStr + 'of') === tag || any;
    };
    
    DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {
      const decodedTag = derDecodeTag(buffer,
        'Failed to decode tag of "' + tag + '"');
      if (buffer.isError(decodedTag))
        return decodedTag;
    
      let len = derDecodeLen(buffer,
        decodedTag.primitive,
        'Failed to get length of "' + tag + '"');
    
      // Failure
      if (buffer.isError(len))
        return len;
    
      if (!any &&
          decodedTag.tag !== tag &&
          decodedTag.tagStr !== tag &&
          decodedTag.tagStr + 'of' !== tag) {
        return buffer.error('Failed to match tag: "' + tag + '"');
      }
    
      if (decodedTag.primitive || len !== null)
        return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
    
      // Indefinite length... find END tag
      const state = buffer.save();
      const res = this._skipUntilEnd(
        buffer,
        'Failed to skip indefinite length body: "' + this.tag + '"');
      if (buffer.isError(res))
        return res;
    
      len = buffer.offset - state.offset;
      buffer.restore(state);
      return buffer.skip(len, 'Failed to match body of: "' + tag + '"');
    };
    
    DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {
      for (;;) {
        const tag = derDecodeTag(buffer, fail);
        if (buffer.isError(tag))
          return tag;
        const len = derDecodeLen(buffer, tag.primitive, fail);
        if (buffer.isError(len))
          return len;
    
        let res;
        if (tag.primitive || len !== null)
          res = buffer.skip(len);
        else
          res = this._skipUntilEnd(buffer, fail);
    
        // Failure
        if (buffer.isError(res))
          return res;
    
        if (tag.tagStr === 'end')
          break;
      }
    };
    
    DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,
      options) {
      const result = [];
      while (!buffer.isEmpty()) {
        const possibleEnd = this._peekTag(buffer, 'end');
        if (buffer.isError(possibleEnd))
          return possibleEnd;
    
        const res = decoder.decode(buffer, 'der', options);
        if (buffer.isError(res) && possibleEnd)
          break;
        result.push(res);
      }
      return result;
    };
    
    DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {
      if (tag === 'bitstr') {
        const unused = buffer.readUInt8();
        if (buffer.isError(unused))
          return unused;
        return { unused: unused, data: buffer.raw() };
      } else if (tag === 'bmpstr') {
        const raw = buffer.raw();
        if (raw.length % 2 === 1)
          return buffer.error('Decoding of string type: bmpstr length mismatch');
    
        let str = '';
        for (let i = 0; i < raw.length / 2; i++) {
          str += String.fromCharCode(raw.readUInt16BE(i * 2));
        }
        return str;
      } else if (tag === 'numstr') {
        const numstr = buffer.raw().toString('ascii');
        if (!this._isNumstr(numstr)) {
          return buffer.error('Decoding of string type: ' +
                              'numstr unsupported characters');
        }
        return numstr;
      } else if (tag === 'octstr') {
        return buffer.raw();
      } else if (tag === 'objDesc') {
        return buffer.raw();
      } else if (tag === 'printstr') {
        const printstr = buffer.raw().toString('ascii');
        if (!this._isPrintstr(printstr)) {
          return buffer.error('Decoding of string type: ' +
                              'printstr unsupported characters');
        }
        return printstr;
      } else if (/str$/.test(tag)) {
        return buffer.raw().toString();
      } else {
        return buffer.error('Decoding of string type: ' + tag + ' unsupported');
      }
    };
    
    DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {
      let result;
      const identifiers = [];
      let ident = 0;
      let subident = 0;
      while (!buffer.isEmpty()) {
        subident = buffer.readUInt8();
        ident <<= 7;
        ident |= subident & 0x7f;
        if ((subident & 0x80) === 0) {
          identifiers.push(ident);
          ident = 0;
        }
      }
      if (subident & 0x80)
        identifiers.push(ident);
    
      const first = (identifiers[0] / 40) | 0;
      const second = identifiers[0] % 40;
    
      if (relative)
        result = identifiers;
      else
        result = [first, second].concat(identifiers.slice(1));
    
      if (values) {
        let tmp = values[result.join(' ')];
        if (tmp === undefined)
          tmp = values[result.join('.')];
        if (tmp !== undefined)
          result = tmp;
      }
    
      return result;
    };
    
    DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {
      const str = buffer.raw().toString();
    
      let year;
      let mon;
      let day;
      let hour;
      let min;
      let sec;
      if (tag === 'gentime') {
        year = str.slice(0, 4) | 0;
        mon = str.slice(4, 6) | 0;
        day = str.slice(6, 8) | 0;
        hour = str.slice(8, 10) | 0;
        min = str.slice(10, 12) | 0;
        sec = str.slice(12, 14) | 0;
      } else if (tag === 'utctime') {
        year = str.slice(0, 2) | 0;
        mon = str.slice(2, 4) | 0;
        day = str.slice(4, 6) | 0;
        hour = str.slice(6, 8) | 0;
        min = str.slice(8, 10) | 0;
        sec = str.slice(10, 12) | 0;
        if (year < 70)
          year = 2000 + year;
        else
          year = 1900 + year;
      } else {
        return buffer.error('Decoding ' + tag + ' time is not supported yet');
      }
    
      return Date.UTC(year, mon - 1, day, hour, min, sec, 0);
    };
    
    DERNode.prototype._decodeNull = function decodeNull() {
      return null;
    };
    
    DERNode.prototype._decodeBool = function decodeBool(buffer) {
      const res = buffer.readUInt8();
      if (buffer.isError(res))
        return res;
      else
        return res !== 0;
    };
    
    DERNode.prototype._decodeInt = function decodeInt(buffer, values) {
      // Bigint, return as it is (assume big endian)
      const raw = buffer.raw();
      let res = new bignum(raw);
    
      if (values)
        res = values[res.toString(10)] || res;
    
      return res;
    };
    
    DERNode.prototype._use = function use(entity, obj) {
      if (typeof entity === 'function')
        entity = entity(obj);
      return entity._getDecoder('der').tree;
    };
    
    // Utility methods
    
    function derDecodeTag(buf, fail) {
      let tag = buf.readUInt8(fail);
      if (buf.isError(tag))
        return tag;
    
      const cls = der.tagClass[tag >> 6];
      const primitive = (tag & 0x20) === 0;
    
      // Multi-octet tag - load
      if ((tag & 0x1f) === 0x1f) {
        let oct = tag;
        tag = 0;
        while ((oct & 0x80) === 0x80) {
          oct = buf.readUInt8(fail);
          if (buf.isError(oct))
            return oct;
    
          tag <<= 7;
          tag |= oct & 0x7f;
        }
      } else {
        tag &= 0x1f;
      }
      const tagStr = der.tag[tag];
    
      return {
        cls: cls,
        primitive: primitive,
        tag: tag,
        tagStr: tagStr
      };
    }
    
    function derDecodeLen(buf, primitive, fail) {
      let len = buf.readUInt8(fail);
      if (buf.isError(len))
        return len;
    
      // Indefinite form
      if (!primitive && len === 0x80)
        return null;
    
      // Definite form
      if ((len & 0x80) === 0) {
        // Short form
        return len;
      }
    
      // Long form
      const num = len & 0x7f;
      if (num > 4)
        return buf.error('length octect is too long');
    
      len = 0;
      for (let i = 0; i < num; i++) {
        len <<= 8;
        const j = buf.readUInt8(fail);
        if (buf.isError(j))
          return j;
        len |= j;
      }
    
      return len;
    }
    
    },{"../base/buffer":12,"../base/node":14,"../constants/der":16,"bn.js":33,"inherits":182}],19:[function(require,module,exports){
    'use strict';
    
    const decoders = exports;
    
    decoders.der = require('./der');
    decoders.pem = require('./pem');
    
    },{"./der":18,"./pem":20}],20:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    const Buffer = require('safer-buffer').Buffer;
    
    const DERDecoder = require('./der');
    
    function PEMDecoder(entity) {
      DERDecoder.call(this, entity);
      this.enc = 'pem';
    }
    inherits(PEMDecoder, DERDecoder);
    module.exports = PEMDecoder;
    
    PEMDecoder.prototype.decode = function decode(data, options) {
      const lines = data.toString().split(/[\r\n]+/g);
    
      const label = options.label.toUpperCase();
    
      const re = /^-----(BEGIN|END) ([^-]+)-----$/;
      let start = -1;
      let end = -1;
      for (let i = 0; i < lines.length; i++) {
        const match = lines[i].match(re);
        if (match === null)
          continue;
    
        if (match[2] !== label)
          continue;
    
        if (start === -1) {
          if (match[1] !== 'BEGIN')
            break;
          start = i;
        } else {
          if (match[1] !== 'END')
            break;
          end = i;
          break;
        }
      }
      if (start === -1 || end === -1)
        throw new Error('PEM section not found for: ' + label);
    
      const base64 = lines.slice(start + 1, end).join('');
      // Remove excessive symbols
      base64.replace(/[^a-z0-9+/=]+/gi, '');
    
      const input = Buffer.from(base64, 'base64');
      return DERDecoder.prototype.decode.call(this, input, options);
    };
    
    },{"./der":18,"inherits":182,"safer-buffer":339}],21:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    const Buffer = require('safer-buffer').Buffer;
    const Node = require('../base/node');
    
    // Import DER constants
    const der = require('../constants/der');
    
    function DEREncoder(entity) {
      this.enc = 'der';
      this.name = entity.name;
      this.entity = entity;
    
      // Construct base tree
      this.tree = new DERNode();
      this.tree._init(entity.body);
    }
    module.exports = DEREncoder;
    
    DEREncoder.prototype.encode = function encode(data, reporter) {
      return this.tree._encode(data, reporter).join();
    };
    
    // Tree methods
    
    function DERNode(parent) {
      Node.call(this, 'der', parent);
    }
    inherits(DERNode, Node);
    
    DERNode.prototype._encodeComposite = function encodeComposite(tag,
      primitive,
      cls,
      content) {
      const encodedTag = encodeTag(tag, primitive, cls, this.reporter);
    
      // Short form
      if (content.length < 0x80) {
        const header = Buffer.alloc(2);
        header[0] = encodedTag;
        header[1] = content.length;
        return this._createEncoderBuffer([ header, content ]);
      }
    
      // Long form
      // Count octets required to store length
      let lenOctets = 1;
      for (let i = content.length; i >= 0x100; i >>= 8)
        lenOctets++;
    
      const header = Buffer.alloc(1 + 1 + lenOctets);
      header[0] = encodedTag;
      header[1] = 0x80 | lenOctets;
    
      for (let i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)
        header[i] = j & 0xff;
    
      return this._createEncoderBuffer([ header, content ]);
    };
    
    DERNode.prototype._encodeStr = function encodeStr(str, tag) {
      if (tag === 'bitstr') {
        return this._createEncoderBuffer([ str.unused | 0, str.data ]);
      } else if (tag === 'bmpstr') {
        const buf = Buffer.alloc(str.length * 2);
        for (let i = 0; i < str.length; i++) {
          buf.writeUInt16BE(str.charCodeAt(i), i * 2);
        }
        return this._createEncoderBuffer(buf);
      } else if (tag === 'numstr') {
        if (!this._isNumstr(str)) {
          return this.reporter.error('Encoding of string type: numstr supports ' +
                                     'only digits and space');
        }
        return this._createEncoderBuffer(str);
      } else if (tag === 'printstr') {
        if (!this._isPrintstr(str)) {
          return this.reporter.error('Encoding of string type: printstr supports ' +
                                     'only latin upper and lower case letters, ' +
                                     'digits, space, apostrophe, left and rigth ' +
                                     'parenthesis, plus sign, comma, hyphen, ' +
                                     'dot, slash, colon, equal sign, ' +
                                     'question mark');
        }
        return this._createEncoderBuffer(str);
      } else if (/str$/.test(tag)) {
        return this._createEncoderBuffer(str);
      } else if (tag === 'objDesc') {
        return this._createEncoderBuffer(str);
      } else {
        return this.reporter.error('Encoding of string type: ' + tag +
                                   ' unsupported');
      }
    };
    
    DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {
      if (typeof id === 'string') {
        if (!values)
          return this.reporter.error('string objid given, but no values map found');
        if (!values.hasOwnProperty(id))
          return this.reporter.error('objid not found in values map');
        id = values[id].split(/[\s.]+/g);
        for (let i = 0; i < id.length; i++)
          id[i] |= 0;
      } else if (Array.isArray(id)) {
        id = id.slice();
        for (let i = 0; i < id.length; i++)
          id[i] |= 0;
      }
    
      if (!Array.isArray(id)) {
        return this.reporter.error('objid() should be either array or string, ' +
                                   'got: ' + JSON.stringify(id));
      }
    
      if (!relative) {
        if (id[1] >= 40)
          return this.reporter.error('Second objid identifier OOB');
        id.splice(0, 2, id[0] * 40 + id[1]);
      }
    
      // Count number of octets
      let size = 0;
      for (let i = 0; i < id.length; i++) {
        let ident = id[i];
        for (size++; ident >= 0x80; ident >>= 7)
          size++;
      }
    
      const objid = Buffer.alloc(size);
      let offset = objid.length - 1;
      for (let i = id.length - 1; i >= 0; i--) {
        let ident = id[i];
        objid[offset--] = ident & 0x7f;
        while ((ident >>= 7) > 0)
          objid[offset--] = 0x80 | (ident & 0x7f);
      }
    
      return this._createEncoderBuffer(objid);
    };
    
    function two(num) {
      if (num < 10)
        return '0' + num;
      else
        return num;
    }
    
    DERNode.prototype._encodeTime = function encodeTime(time, tag) {
      let str;
      const date = new Date(time);
    
      if (tag === 'gentime') {
        str = [
          two(date.getUTCFullYear()),
          two(date.getUTCMonth() + 1),
          two(date.getUTCDate()),
          two(date.getUTCHours()),
          two(date.getUTCMinutes()),
          two(date.getUTCSeconds()),
          'Z'
        ].join('');
      } else if (tag === 'utctime') {
        str = [
          two(date.getUTCFullYear() % 100),
          two(date.getUTCMonth() + 1),
          two(date.getUTCDate()),
          two(date.getUTCHours()),
          two(date.getUTCMinutes()),
          two(date.getUTCSeconds()),
          'Z'
        ].join('');
      } else {
        this.reporter.error('Encoding ' + tag + ' time is not supported yet');
      }
    
      return this._encodeStr(str, 'octstr');
    };
    
    DERNode.prototype._encodeNull = function encodeNull() {
      return this._createEncoderBuffer('');
    };
    
    DERNode.prototype._encodeInt = function encodeInt(num, values) {
      if (typeof num === 'string') {
        if (!values)
          return this.reporter.error('String int or enum given, but no values map');
        if (!values.hasOwnProperty(num)) {
          return this.reporter.error('Values map doesn\'t contain: ' +
                                     JSON.stringify(num));
        }
        num = values[num];
      }
    
      // Bignum, assume big endian
      if (typeof num !== 'number' && !Buffer.isBuffer(num)) {
        const numArray = num.toArray();
        if (!num.sign && numArray[0] & 0x80) {
          numArray.unshift(0);
        }
        num = Buffer.from(numArray);
      }
    
      if (Buffer.isBuffer(num)) {
        let size = num.length;
        if (num.length === 0)
          size++;
    
        const out = Buffer.alloc(size);
        num.copy(out);
        if (num.length === 0)
          out[0] = 0;
        return this._createEncoderBuffer(out);
      }
    
      if (num < 0x80)
        return this._createEncoderBuffer(num);
    
      if (num < 0x100)
        return this._createEncoderBuffer([0, num]);
    
      let size = 1;
      for (let i = num; i >= 0x100; i >>= 8)
        size++;
    
      const out = new Array(size);
      for (let i = out.length - 1; i >= 0; i--) {
        out[i] = num & 0xff;
        num >>= 8;
      }
      if(out[0] & 0x80) {
        out.unshift(0);
      }
    
      return this._createEncoderBuffer(Buffer.from(out));
    };
    
    DERNode.prototype._encodeBool = function encodeBool(value) {
      return this._createEncoderBuffer(value ? 0xff : 0);
    };
    
    DERNode.prototype._use = function use(entity, obj) {
      if (typeof entity === 'function')
        entity = entity(obj);
      return entity._getEncoder('der').tree;
    };
    
    DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {
      const state = this._baseState;
      let i;
      if (state['default'] === null)
        return false;
    
      const data = dataBuffer.join();
      if (state.defaultBuffer === undefined)
        state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();
    
      if (data.length !== state.defaultBuffer.length)
        return false;
    
      for (i=0; i < data.length; i++)
        if (data[i] !== state.defaultBuffer[i])
          return false;
    
      return true;
    };
    
    // Utility methods
    
    function encodeTag(tag, primitive, cls, reporter) {
      let res;
    
      if (tag === 'seqof')
        tag = 'seq';
      else if (tag === 'setof')
        tag = 'set';
    
      if (der.tagByName.hasOwnProperty(tag))
        res = der.tagByName[tag];
      else if (typeof tag === 'number' && (tag | 0) === tag)
        res = tag;
      else
        return reporter.error('Unknown tag: ' + tag);
    
      if (res >= 0x1f)
        return reporter.error('Multi-octet tag encoding unsupported');
    
      if (!primitive)
        res |= 0x20;
    
      res |= (der.tagClassByName[cls || 'universal'] << 6);
    
      return res;
    }
    
    },{"../base/node":14,"../constants/der":16,"inherits":182,"safer-buffer":339}],22:[function(require,module,exports){
    'use strict';
    
    const encoders = exports;
    
    encoders.der = require('./der');
    encoders.pem = require('./pem');
    
    },{"./der":21,"./pem":23}],23:[function(require,module,exports){
    'use strict';
    
    const inherits = require('inherits');
    
    const DEREncoder = require('./der');
    
    function PEMEncoder(entity) {
      DEREncoder.call(this, entity);
      this.enc = 'pem';
    }
    inherits(PEMEncoder, DEREncoder);
    module.exports = PEMEncoder;
    
    PEMEncoder.prototype.encode = function encode(data, options) {
      const buf = DEREncoder.prototype.encode.call(this, data);
    
      const p = buf.toString('base64');
      const out = [ '-----BEGIN ' + options.label + '-----' ];
      for (let i = 0; i < p.length; i += 64)
        out.push(p.slice(i, i + 64));
      out.push('-----END ' + options.label + '-----');
      return out.join('\n');
    };
    
    },{"./der":21,"inherits":182}],24:[function(require,module,exports){
    (function (global){(function (){
    'use strict';
    
    var objectAssign = require('object.assign/polyfill')();
    
    // compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
    // original notice:
    
    /*!
     * The buffer module from node.js, for the browser.
     *
     * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
     * @license  MIT
     */
    function compare(a, b) {
      if (a === b) {
        return 0;
      }
    
      var x = a.length;
      var y = b.length;
    
      for (var i = 0, len = Math.min(x, y); i < len; ++i) {
        if (a[i] !== b[i]) {
          x = a[i];
          y = b[i];
          break;
        }
      }
    
      if (x < y) {
        return -1;
      }
      if (y < x) {
        return 1;
      }
      return 0;
    }
    function isBuffer(b) {
      if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
        return global.Buffer.isBuffer(b);
      }
      return !!(b != null && b._isBuffer);
    }
    
    // based on node assert, original notice:
    // NB: The URL to the CommonJS spec is kept just for tradition.
    //     node-assert has evolved a lot since then, both in API and behavior.
    
    // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
    //
    // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
    //
    // Originally from narwhal.js (http://narwhaljs.org)
    // Copyright (c) 2009 Thomas Robinson <280north.com>
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the 'Software'), to
    // deal in the Software without restriction, including without limitation the
    // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    // sell copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    var util = require('util/');
    var hasOwn = Object.prototype.hasOwnProperty;
    var pSlice = Array.prototype.slice;
    var functionsHaveNames = (function () {
      return function foo() {}.name === 'foo';
    }());
    function pToString (obj) {
      return Object.prototype.toString.call(obj);
    }
    function isView(arrbuf) {
      if (isBuffer(arrbuf)) {
        return false;
      }
      if (typeof global.ArrayBuffer !== 'function') {
        return false;
      }
      if (typeof ArrayBuffer.isView === 'function') {
        return ArrayBuffer.isView(arrbuf);
      }
      if (!arrbuf) {
        return false;
      }
      if (arrbuf instanceof DataView) {
        return true;
      }
      if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
        return true;
      }
      return false;
    }
    // 1. The assert module provides functions that throw
    // AssertionError's when particular conditions are not met. The
    // assert module must conform to the following interface.
    
    var assert = module.exports = ok;
    
    // 2. The AssertionError is defined in assert.
    // new assert.AssertionError({ message: message,
    //                             actual: actual,
    //                             expected: expected })
    
    var regex = /\s*function\s+([^\(\s]*)\s*/;
    // based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
    function getName(func) {
      if (!util.isFunction(func)) {
        return;
      }
      if (functionsHaveNames) {
        return func.name;
      }
      var str = func.toString();
      var match = str.match(regex);
      return match && match[1];
    }
    assert.AssertionError = function AssertionError(options) {
      this.name = 'AssertionError';
      this.actual = options.actual;
      this.expected = options.expected;
      this.operator = options.operator;
      if (options.message) {
        this.message = options.message;
        this.generatedMessage = false;
      } else {
        this.message = getMessage(this);
        this.generatedMessage = true;
      }
      var stackStartFunction = options.stackStartFunction || fail;
      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, stackStartFunction);
      } else {
        // non v8 browsers so we can have a stacktrace
        var err = new Error();
        if (err.stack) {
          var out = err.stack;
    
          // try to strip useless frames
          var fn_name = getName(stackStartFunction);
          var idx = out.indexOf('\n' + fn_name);
          if (idx >= 0) {
            // once we have located the function frame
            // we need to strip out everything before it (and its line)
            var next_line = out.indexOf('\n', idx + 1);
            out = out.substring(next_line + 1);
          }
    
          this.stack = out;
        }
      }
    };
    
    // assert.AssertionError instanceof Error
    util.inherits(assert.AssertionError, Error);
    
    function truncate(s, n) {
      if (typeof s === 'string') {
        return s.length < n ? s : s.slice(0, n);
      } else {
        return s;
      }
    }
    function inspect(something) {
      if (functionsHaveNames || !util.isFunction(something)) {
        return util.inspect(something);
      }
      var rawname = getName(something);
      var name = rawname ? ': ' + rawname : '';
      return '[Function' +  name + ']';
    }
    function getMessage(self) {
      return truncate(inspect(self.actual), 128) + ' ' +
             self.operator + ' ' +
             truncate(inspect(self.expected), 128);
    }
    
    // At present only the three keys mentioned above are used and
    // understood by the spec. Implementations or sub modules can pass
    // other keys to the AssertionError's constructor - they will be
    // ignored.
    
    // 3. All of the following functions must throw an AssertionError
    // when a corresponding condition is not met, with a message that
    // may be undefined if not provided.  All assertion methods provide
    // both the actual and expected values to the assertion error for
    // display purposes.
    
    function fail(actual, expected, message, operator, stackStartFunction) {
      throw new assert.AssertionError({
        message: message,
        actual: actual,
        expected: expected,
        operator: operator,
        stackStartFunction: stackStartFunction
      });
    }
    
    // EXTENSION! allows for well behaved errors defined elsewhere.
    assert.fail = fail;
    
    // 4. Pure assertion tests whether a value is truthy, as determined
    // by !!guard.
    // assert.ok(guard, message_opt);
    // This statement is equivalent to assert.equal(true, !!guard,
    // message_opt);. To test strictly for the value true, use
    // assert.strictEqual(true, guard, message_opt);.
    
    function ok(value, message) {
      if (!value) fail(value, true, message, '==', assert.ok);
    }
    assert.ok = ok;
    
    // 5. The equality assertion tests shallow, coercive equality with
    // ==.
    // assert.equal(actual, expected, message_opt);
    
    assert.equal = function equal(actual, expected, message) {
      if (actual != expected) fail(actual, expected, message, '==', assert.equal);
    };
    
    // 6. The non-equality assertion tests for whether two objects are not equal
    // with != assert.notEqual(actual, expected, message_opt);
    
    assert.notEqual = function notEqual(actual, expected, message) {
      if (actual == expected) {
        fail(actual, expected, message, '!=', assert.notEqual);
      }
    };
    
    // 7. The equivalence assertion tests a deep equality relation.
    // assert.deepEqual(actual, expected, message_opt);
    
    assert.deepEqual = function deepEqual(actual, expected, message) {
      if (!_deepEqual(actual, expected, false)) {
        fail(actual, expected, message, 'deepEqual', assert.deepEqual);
      }
    };
    
    assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
      if (!_deepEqual(actual, expected, true)) {
        fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
      }
    };
    
    function _deepEqual(actual, expected, strict, memos) {
      // 7.1. All identical values are equivalent, as determined by ===.
      if (actual === expected) {
        return true;
      } else if (isBuffer(actual) && isBuffer(expected)) {
        return compare(actual, expected) === 0;
    
      // 7.2. If the expected value is a Date object, the actual value is
      // equivalent if it is also a Date object that refers to the same time.
      } else if (util.isDate(actual) && util.isDate(expected)) {
        return actual.getTime() === expected.getTime();
    
      // 7.3 If the expected value is a RegExp object, the actual value is
      // equivalent if it is also a RegExp object with the same source and
      // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
      } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
        return actual.source === expected.source &&
               actual.global === expected.global &&
               actual.multiline === expected.multiline &&
               actual.lastIndex === expected.lastIndex &&
               actual.ignoreCase === expected.ignoreCase;
    
      // 7.4. Other pairs that do not both pass typeof value == 'object',
      // equivalence is determined by ==.
      } else if ((actual === null || typeof actual !== 'object') &&
                 (expected === null || typeof expected !== 'object')) {
        return strict ? actual === expected : actual == expected;
    
      // If both values are instances of typed arrays, wrap their underlying
      // ArrayBuffers in a Buffer each to increase performance
      // This optimization requires the arrays to have the same type as checked by
      // Object.prototype.toString (aka pToString). Never perform binary
      // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
      // bit patterns are not identical.
      } else if (isView(actual) && isView(expected) &&
                 pToString(actual) === pToString(expected) &&
                 !(actual instanceof Float32Array ||
                   actual instanceof Float64Array)) {
        return compare(new Uint8Array(actual.buffer),
                       new Uint8Array(expected.buffer)) === 0;
    
      // 7.5 For all other Object pairs, including Array objects, equivalence is
      // determined by having the same number of owned properties (as verified
      // with Object.prototype.hasOwnProperty.call), the same set of keys
      // (although not necessarily the same order), equivalent values for every
      // corresponding key, and an identical 'prototype' property. Note: this
      // accounts for both named and indexed properties on Arrays.
      } else if (isBuffer(actual) !== isBuffer(expected)) {
        return false;
      } else {
        memos = memos || {actual: [], expected: []};
    
        var actualIndex = memos.actual.indexOf(actual);
        if (actualIndex !== -1) {
          if (actualIndex === memos.expected.indexOf(expected)) {
            return true;
          }
        }
    
        memos.actual.push(actual);
        memos.expected.push(expected);
    
        return objEquiv(actual, expected, strict, memos);
      }
    }
    
    function isArguments(object) {
      return Object.prototype.toString.call(object) == '[object Arguments]';
    }
    
    function objEquiv(a, b, strict, actualVisitedObjects) {
      if (a === null || a === undefined || b === null || b === undefined)
        return false;
      // if one is a primitive, the other must be same
      if (util.isPrimitive(a) || util.isPrimitive(b))
        return a === b;
      if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
        return false;
      var aIsArgs = isArguments(a);
      var bIsArgs = isArguments(b);
      if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
        return false;
      if (aIsArgs) {
        a = pSlice.call(a);
        b = pSlice.call(b);
        return _deepEqual(a, b, strict);
      }
      var ka = objectKeys(a);
      var kb = objectKeys(b);
      var key, i;
      // having the same number of owned properties (keys incorporates
      // hasOwnProperty)
      if (ka.length !== kb.length)
        return false;
      //the same set of keys (although not necessarily the same order),
      ka.sort();
      kb.sort();
      //~~~cheap key test
      for (i = ka.length - 1; i >= 0; i--) {
        if (ka[i] !== kb[i])
          return false;
      }
      //equivalent values for every corresponding key, and
      //~~~possibly expensive deep test
      for (i = ka.length - 1; i >= 0; i--) {
        key = ka[i];
        if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
          return false;
      }
      return true;
    }
    
    // 8. The non-equivalence assertion tests for any deep inequality.
    // assert.notDeepEqual(actual, expected, message_opt);
    
    assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
      if (_deepEqual(actual, expected, false)) {
        fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
      }
    };
    
    assert.notDeepStrictEqual = notDeepStrictEqual;
    function notDeepStrictEqual(actual, expected, message) {
      if (_deepEqual(actual, expected, true)) {
        fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
      }
    }
    
    
    // 9. The strict equality assertion tests strict equality, as determined by ===.
    // assert.strictEqual(actual, expected, message_opt);
    
    assert.strictEqual = function strictEqual(actual, expected, message) {
      if (actual !== expected) {
        fail(actual, expected, message, '===', assert.strictEqual);
      }
    };
    
    // 10. The strict non-equality assertion tests for strict inequality, as
    // determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
    
    assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
      if (actual === expected) {
        fail(actual, expected, message, '!==', assert.notStrictEqual);
      }
    };
    
    function expectedException(actual, expected) {
      if (!actual || !expected) {
        return false;
      }
    
      if (Object.prototype.toString.call(expected) == '[object RegExp]') {
        return expected.test(actual);
      }
    
      try {
        if (actual instanceof expected) {
          return true;
        }
      } catch (e) {
        // Ignore.  The instanceof check doesn't work for arrow functions.
      }
    
      if (Error.isPrototypeOf(expected)) {
        return false;
      }
    
      return expected.call({}, actual) === true;
    }
    
    function _tryBlock(block) {
      var error;
      try {
        block();
      } catch (e) {
        error = e;
      }
      return error;
    }
    
    function _throws(shouldThrow, block, expected, message) {
      var actual;
    
      if (typeof block !== 'function') {
        throw new TypeError('"block" argument must be a function');
      }
    
      if (typeof expected === 'string') {
        message = expected;
        expected = null;
      }
    
      actual = _tryBlock(block);
    
      message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
                (message ? ' ' + message : '.');
    
      if (shouldThrow && !actual) {
        fail(actual, expected, 'Missing expected exception' + message);
      }
    
      var userProvidedMessage = typeof message === 'string';
      var isUnwantedException = !shouldThrow && util.isError(actual);
      var isUnexpectedException = !shouldThrow && actual && !expected;
    
      if ((isUnwantedException &&
          userProvidedMessage &&
          expectedException(actual, expected)) ||
          isUnexpectedException) {
        fail(actual, expected, 'Got unwanted exception' + message);
      }
    
      if ((shouldThrow && actual && expected &&
          !expectedException(actual, expected)) || (!shouldThrow && actual)) {
        throw actual;
      }
    }
    
    // 11. Expected to throw an error:
    // assert.throws(block, Error_opt, message_opt);
    
    assert.throws = function(block, /*optional*/error, /*optional*/message) {
      _throws(true, block, error, message);
    };
    
    // EXTENSION! This is annoying to write outside this module.
    assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
      _throws(false, block, error, message);
    };
    
    assert.ifError = function(err) { if (err) throw err; };
    
    // Expose a strict only variant of assert
    function strict(value, message) {
      if (!value) fail(value, true, message, '==', strict);
    }
    assert.strict = objectAssign(strict, assert, {
      equal: assert.strictEqual,
      deepEqual: assert.deepStrictEqual,
      notEqual: assert.notStrictEqual,
      notDeepEqual: assert.notDeepStrictEqual
    });
    assert.strict.strict = assert.strict;
    
    var objectKeys = Object.keys || function (obj) {
      var keys = [];
      for (var key in obj) {
        if (hasOwn.call(obj, key)) keys.push(key);
      }
      return keys;
    };
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"object.assign/polyfill":294,"util/":27}],25:[function(require,module,exports){
    if (typeof Object.create === 'function') {
      // implementation from standard node.js 'util' module
      module.exports = function inherits(ctor, superCtor) {
        ctor.super_ = superCtor
        ctor.prototype = Object.create(superCtor.prototype, {
          constructor: {
            value: ctor,
            enumerable: false,
            writable: true,
            configurable: true
          }
        });
      };
    } else {
      // old school shim for old browsers
      module.exports = function inherits(ctor, superCtor) {
        ctor.super_ = superCtor
        var TempCtor = function () {}
        TempCtor.prototype = superCtor.prototype
        ctor.prototype = new TempCtor()
        ctor.prototype.constructor = ctor
      }
    }
    
    },{}],26:[function(require,module,exports){
    module.exports = function isBuffer(arg) {
      return arg && typeof arg === 'object'
        && typeof arg.copy === 'function'
        && typeof arg.fill === 'function'
        && typeof arg.readUInt8 === 'function';
    }
    },{}],27:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    var formatRegExp = /%[sdj%]/g;
    exports.format = function(f) {
      if (!isString(f)) {
        var objects = [];
        for (var i = 0; i < arguments.length; i++) {
          objects.push(inspect(arguments[i]));
        }
        return objects.join(' ');
      }
    
      var i = 1;
      var args = arguments;
      var len = args.length;
      var str = String(f).replace(formatRegExp, function(x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch (x) {
          case '%s': return String(args[i++]);
          case '%d': return Number(args[i++]);
          case '%j':
            try {
              return JSON.stringify(args[i++]);
            } catch (_) {
              return '[Circular]';
            }
          default:
            return x;
        }
      });
      for (var x = args[i]; i < len; x = args[++i]) {
        if (isNull(x) || !isObject(x)) {
          str += ' ' + x;
        } else {
          str += ' ' + inspect(x);
        }
      }
      return str;
    };
    
    
    // Mark that a method should not be used.
    // Returns a modified function which warns once by default.
    // If --no-deprecation is set, then it is a no-op.
    exports.deprecate = function(fn, msg) {
      // Allow for deprecating things in the process of starting up.
      if (isUndefined(global.process)) {
        return function() {
          return exports.deprecate(fn, msg).apply(this, arguments);
        };
      }
    
      if (process.noDeprecation === true) {
        return fn;
      }
    
      var warned = false;
      function deprecated() {
        if (!warned) {
          if (process.throwDeprecation) {
            throw new Error(msg);
          } else if (process.traceDeprecation) {
            console.trace(msg);
          } else {
            console.error(msg);
          }
          warned = true;
        }
        return fn.apply(this, arguments);
      }
    
      return deprecated;
    };
    
    
    var debugs = {};
    var debugEnviron;
    exports.debuglog = function(set) {
      if (isUndefined(debugEnviron))
        debugEnviron = process.env.NODE_DEBUG || '';
      set = set.toUpperCase();
      if (!debugs[set]) {
        if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
          var pid = process.pid;
          debugs[set] = function() {
            var msg = exports.format.apply(exports, arguments);
            console.error('%s %d: %s', set, pid, msg);
          };
        } else {
          debugs[set] = function() {};
        }
      }
      return debugs[set];
    };
    
    
    /**
     * Echos the value of a value. Trys to print the value out
     * in the best way possible given the different types.
     *
     * @param {Object} obj The object to print out.
     * @param {Object} opts Optional options object that alters the output.
     */
    /* legacy: obj, showHidden, depth, colors*/
    function inspect(obj, opts) {
      // default options
      var ctx = {
        seen: [],
        stylize: stylizeNoColor
      };
      // legacy...
      if (arguments.length >= 3) ctx.depth = arguments[2];
      if (arguments.length >= 4) ctx.colors = arguments[3];
      if (isBoolean(opts)) {
        // legacy...
        ctx.showHidden = opts;
      } else if (opts) {
        // got an "options" object
        exports._extend(ctx, opts);
      }
      // set default options
      if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
      if (isUndefined(ctx.depth)) ctx.depth = 2;
      if (isUndefined(ctx.colors)) ctx.colors = false;
      if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
      if (ctx.colors) ctx.stylize = stylizeWithColor;
      return formatValue(ctx, obj, ctx.depth);
    }
    exports.inspect = inspect;
    
    
    // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
    inspect.colors = {
      'bold' : [1, 22],
      'italic' : [3, 23],
      'underline' : [4, 24],
      'inverse' : [7, 27],
      'white' : [37, 39],
      'grey' : [90, 39],
      'black' : [30, 39],
      'blue' : [34, 39],
      'cyan' : [36, 39],
      'green' : [32, 39],
      'magenta' : [35, 39],
      'red' : [31, 39],
      'yellow' : [33, 39]
    };
    
    // Don't use 'blue' not visible on cmd.exe
    inspect.styles = {
      'special': 'cyan',
      'number': 'yellow',
      'boolean': 'yellow',
      'undefined': 'grey',
      'null': 'bold',
      'string': 'green',
      'date': 'magenta',
      // "name": intentionally not styling
      'regexp': 'red'
    };
    
    
    function stylizeWithColor(str, styleType) {
      var style = inspect.styles[styleType];
    
      if (style) {
        return '\u001b[' + inspect.colors[style][0] + 'm' + str +
               '\u001b[' + inspect.colors[style][1] + 'm';
      } else {
        return str;
      }
    }
    
    
    function stylizeNoColor(str, styleType) {
      return str;
    }
    
    
    function arrayToHash(array) {
      var hash = {};
    
      array.forEach(function(val, idx) {
        hash[val] = true;
      });
    
      return hash;
    }
    
    
    function formatValue(ctx, value, recurseTimes) {
      // Provide a hook for user-specified inspect functions.
      // Check that value is an object with an inspect function on it
      if (ctx.customInspect &&
          value &&
          isFunction(value.inspect) &&
          // Filter out the util module, it's inspect function is special
          value.inspect !== exports.inspect &&
          // Also filter out any prototype objects using the circular check.
          !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) {
          ret = formatValue(ctx, ret, recurseTimes);
        }
        return ret;
      }
    
      // Primitive types cannot have properties
      var primitive = formatPrimitive(ctx, value);
      if (primitive) {
        return primitive;
      }
    
      // Look up the keys of the object.
      var keys = Object.keys(value);
      var visibleKeys = arrayToHash(keys);
    
      if (ctx.showHidden) {
        keys = Object.getOwnPropertyNames(value);
      }
    
      // IE doesn't make error fields non-enumerable
      // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
      if (isError(value)
          && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
        return formatError(value);
      }
    
      // Some type of object without properties can be shortcutted.
      if (keys.length === 0) {
        if (isFunction(value)) {
          var name = value.name ? ': ' + value.name : '';
          return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        }
        if (isDate(value)) {
          return ctx.stylize(Date.prototype.toString.call(value), 'date');
        }
        if (isError(value)) {
          return formatError(value);
        }
      }
    
      var base = '', array = false, braces = ['{', '}'];
    
      // Make Array say that they are Array
      if (isArray(value)) {
        array = true;
        braces = ['[', ']'];
      }
    
      // Make functions say that they are functions
      if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
      }
    
      // Make RegExps say that they are RegExps
      if (isRegExp(value)) {
        base = ' ' + RegExp.prototype.toString.call(value);
      }
    
      // Make dates with properties first say the date
      if (isDate(value)) {
        base = ' ' + Date.prototype.toUTCString.call(value);
      }
    
      // Make error with message first say the error
      if (isError(value)) {
        base = ' ' + formatError(value);
      }
    
      if (keys.length === 0 && (!array || value.length == 0)) {
        return braces[0] + base + braces[1];
      }
    
      if (recurseTimes < 0) {
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        } else {
          return ctx.stylize('[Object]', 'special');
        }
      }
    
      ctx.seen.push(value);
    
      var output;
      if (array) {
        output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
      } else {
        output = keys.map(function(key) {
          return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
        });
      }
    
      ctx.seen.pop();
    
      return reduceToSingleString(output, base, braces);
    }
    
    
    function formatPrimitive(ctx, value) {
      if (isUndefined(value))
        return ctx.stylize('undefined', 'undefined');
      if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                                 .replace(/'/g, "\\'")
                                                 .replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
      }
      if (isNumber(value))
        return ctx.stylize('' + value, 'number');
      if (isBoolean(value))
        return ctx.stylize('' + value, 'boolean');
      // For some reason typeof null is "object", so special case here.
      if (isNull(value))
        return ctx.stylize('null', 'null');
    }
    
    
    function formatError(value) {
      return '[' + Error.prototype.toString.call(value) + ']';
    }
    
    
    function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
      var output = [];
      for (var i = 0, l = value.length; i < l; ++i) {
        if (hasOwnProperty(value, String(i))) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              String(i), true));
        } else {
          output.push('');
        }
      }
      keys.forEach(function(key) {
        if (!key.match(/^\d+$/)) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              key, true));
        }
      });
      return output;
    }
    
    
    function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
      var name, str, desc;
      desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
      if (desc.get) {
        if (desc.set) {
          str = ctx.stylize('[Getter/Setter]', 'special');
        } else {
          str = ctx.stylize('[Getter]', 'special');
        }
      } else {
        if (desc.set) {
          str = ctx.stylize('[Setter]', 'special');
        }
      }
      if (!hasOwnProperty(visibleKeys, key)) {
        name = '[' + key + ']';
      }
      if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
          if (isNull(recurseTimes)) {
            str = formatValue(ctx, desc.value, null);
          } else {
            str = formatValue(ctx, desc.value, recurseTimes - 1);
          }
          if (str.indexOf('\n') > -1) {
            if (array) {
              str = str.split('\n').map(function(line) {
                return '  ' + line;
              }).join('\n').substr(2);
            } else {
              str = '\n' + str.split('\n').map(function(line) {
                return '   ' + line;
              }).join('\n');
            }
          }
        } else {
          str = ctx.stylize('[Circular]', 'special');
        }
      }
      if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) {
          return str;
        }
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
          name = name.substr(1, name.length - 2);
          name = ctx.stylize(name, 'name');
        } else {
          name = name.replace(/'/g, "\\'")
                     .replace(/\\"/g, '"')
                     .replace(/(^"|"$)/g, "'");
          name = ctx.stylize(name, 'string');
        }
      }
    
      return name + ': ' + str;
    }
    
    
    function reduceToSingleString(output, base, braces) {
      var numLinesEst = 0;
      var length = output.reduce(function(prev, cur) {
        numLinesEst++;
        if (cur.indexOf('\n') >= 0) numLinesEst++;
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
      }, 0);
    
      if (length > 60) {
        return braces[0] +
               (base === '' ? '' : base + '\n ') +
               ' ' +
               output.join(',\n  ') +
               ' ' +
               braces[1];
      }
    
      return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
    }
    
    
    // NOTE: These type checking functions intentionally don't use `instanceof`
    // because it is fragile and can be easily faked with `Object.create()`.
    function isArray(ar) {
      return Array.isArray(ar);
    }
    exports.isArray = isArray;
    
    function isBoolean(arg) {
      return typeof arg === 'boolean';
    }
    exports.isBoolean = isBoolean;
    
    function isNull(arg) {
      return arg === null;
    }
    exports.isNull = isNull;
    
    function isNullOrUndefined(arg) {
      return arg == null;
    }
    exports.isNullOrUndefined = isNullOrUndefined;
    
    function isNumber(arg) {
      return typeof arg === 'number';
    }
    exports.isNumber = isNumber;
    
    function isString(arg) {
      return typeof arg === 'string';
    }
    exports.isString = isString;
    
    function isSymbol(arg) {
      return typeof arg === 'symbol';
    }
    exports.isSymbol = isSymbol;
    
    function isUndefined(arg) {
      return arg === void 0;
    }
    exports.isUndefined = isUndefined;
    
    function isRegExp(re) {
      return isObject(re) && objectToString(re) === '[object RegExp]';
    }
    exports.isRegExp = isRegExp;
    
    function isObject(arg) {
      return typeof arg === 'object' && arg !== null;
    }
    exports.isObject = isObject;
    
    function isDate(d) {
      return isObject(d) && objectToString(d) === '[object Date]';
    }
    exports.isDate = isDate;
    
    function isError(e) {
      return isObject(e) &&
          (objectToString(e) === '[object Error]' || e instanceof Error);
    }
    exports.isError = isError;
    
    function isFunction(arg) {
      return typeof arg === 'function';
    }
    exports.isFunction = isFunction;
    
    function isPrimitive(arg) {
      return arg === null ||
             typeof arg === 'boolean' ||
             typeof arg === 'number' ||
             typeof arg === 'string' ||
             typeof arg === 'symbol' ||  // ES6 symbol
             typeof arg === 'undefined';
    }
    exports.isPrimitive = isPrimitive;
    
    exports.isBuffer = require('./support/isBuffer');
    
    function objectToString(o) {
      return Object.prototype.toString.call(o);
    }
    
    
    function pad(n) {
      return n < 10 ? '0' + n.toString(10) : n.toString(10);
    }
    
    
    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
                  'Oct', 'Nov', 'Dec'];
    
    // 26 Feb 16:19:34
    function timestamp() {
      var d = new Date();
      var time = [pad(d.getHours()),
                  pad(d.getMinutes()),
                  pad(d.getSeconds())].join(':');
      return [d.getDate(), months[d.getMonth()], time].join(' ');
    }
    
    
    // log is just a thin wrapper to console.log that prepends a timestamp
    exports.log = function() {
      console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
    };
    
    
    /**
     * Inherit the prototype methods from one constructor into another.
     *
     * The Function.prototype.inherits from lang.js rewritten as a standalone
     * function (not on Function.prototype). NOTE: If this file is to be loaded
     * during bootstrapping this function needs to be rewritten using some native
     * functions as prototype setup using normal JavaScript does not work as
     * expected during bootstrapping (see mirror.js in r114903).
     *
     * @param {function} ctor Constructor function which needs to inherit the
     *     prototype.
     * @param {function} superCtor Constructor function to inherit prototype from.
     */
    exports.inherits = require('inherits');
    
    exports._extend = function(origin, add) {
      // Don't do anything if add isn't an object
      if (!add || !isObject(add)) return origin;
    
      var keys = Object.keys(add);
      var i = keys.length;
      while (i--) {
        origin[keys[i]] = add[keys[i]];
      }
      return origin;
    };
    
    function hasOwnProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }
    
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"./support/isBuffer":26,"_process":321,"inherits":25}],28:[function(require,module,exports){
    (function (global){(function (){
    'use strict';
    
    var possibleNames = [
        'BigInt64Array',
        'BigUint64Array',
        'Float32Array',
        'Float64Array',
        'Int16Array',
        'Int32Array',
        'Int8Array',
        'Uint16Array',
        'Uint32Array',
        'Uint8Array',
        'Uint8ClampedArray'
    ];
    
    var g = typeof globalThis === 'undefined' ? global : globalThis;
    
    module.exports = function availableTypedArrays() {
        var out = [];
        for (var i = 0; i < possibleNames.length; i++) {
            if (typeof g[possibleNames[i]] === 'function') {
                out[out.length] = possibleNames[i];
            }
        }
        return out;
    };
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{}],29:[function(require,module,exports){
    'use strict';
    module.exports = balanced;
    function balanced(a, b, str) {
      if (a instanceof RegExp) a = maybeMatch(a, str);
      if (b instanceof RegExp) b = maybeMatch(b, str);
    
      var r = range(a, b, str);
    
      return r && {
        start: r[0],
        end: r[1],
        pre: str.slice(0, r[0]),
        body: str.slice(r[0] + a.length, r[1]),
        post: str.slice(r[1] + b.length)
      };
    }
    
    function maybeMatch(reg, str) {
      var m = str.match(reg);
      return m ? m[0] : null;
    }
    
    balanced.range = range;
    function range(a, b, str) {
      var begs, beg, left, right, result;
      var ai = str.indexOf(a);
      var bi = str.indexOf(b, ai + 1);
      var i = ai;
    
      if (ai >= 0 && bi > 0) {
        if(a===b) {
          return [ai, bi];
        }
        begs = [];
        left = str.length;
    
        while (i >= 0 && !result) {
          if (i == ai) {
            begs.push(i);
            ai = str.indexOf(a, i + 1);
          } else if (begs.length == 1) {
            result = [ begs.pop(), bi ];
          } else {
            beg = begs.pop();
            if (beg < left) {
              left = beg;
              right = bi;
            }
    
            bi = str.indexOf(b, i + 1);
          }
    
          i = ai < bi && ai >= 0 ? ai : bi;
        }
    
        if (begs.length) {
          result = [ left, right ];
        }
      }
    
      return result;
    }
    
    },{}],30:[function(require,module,exports){
    'use strict'
    // base-x encoding / decoding
    // Copyright (c) 2018 base-x contributors
    // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
    // Distributed under the MIT software license, see the accompanying
    // file LICENSE or http://www.opensource.org/licenses/mit-license.php.
    // @ts-ignore
    var _Buffer = require('safe-buffer').Buffer
    function base (ALPHABET) {
      if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }
      var BASE_MAP = new Uint8Array(256)
      for (var j = 0; j < BASE_MAP.length; j++) {
        BASE_MAP[j] = 255
      }
      for (var i = 0; i < ALPHABET.length; i++) {
        var x = ALPHABET.charAt(i)
        var xc = x.charCodeAt(0)
        if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }
        BASE_MAP[xc] = i
      }
      var BASE = ALPHABET.length
      var LEADER = ALPHABET.charAt(0)
      var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
      var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
      function encode (source) {
        if (Array.isArray(source) || source instanceof Uint8Array) { source = _Buffer.from(source) }
        if (!_Buffer.isBuffer(source)) { throw new TypeError('Expected Buffer') }
        if (source.length === 0) { return '' }
            // Skip & count leading zeroes.
        var zeroes = 0
        var length = 0
        var pbegin = 0
        var pend = source.length
        while (pbegin !== pend && source[pbegin] === 0) {
          pbegin++
          zeroes++
        }
            // Allocate enough space in big-endian base58 representation.
        var size = ((pend - pbegin) * iFACTOR + 1) >>> 0
        var b58 = new Uint8Array(size)
            // Process the bytes.
        while (pbegin !== pend) {
          var carry = source[pbegin]
                // Apply "b58 = b58 * 256 + ch".
          var i = 0
          for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {
            carry += (256 * b58[it1]) >>> 0
            b58[it1] = (carry % BASE) >>> 0
            carry = (carry / BASE) >>> 0
          }
          if (carry !== 0) { throw new Error('Non-zero carry') }
          length = i
          pbegin++
        }
            // Skip leading zeroes in base58 result.
        var it2 = size - length
        while (it2 !== size && b58[it2] === 0) {
          it2++
        }
            // Translate the result into a string.
        var str = LEADER.repeat(zeroes)
        for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }
        return str
      }
      function decodeUnsafe (source) {
        if (typeof source !== 'string') { throw new TypeError('Expected String') }
        if (source.length === 0) { return _Buffer.alloc(0) }
        var psz = 0
            // Skip and count leading '1's.
        var zeroes = 0
        var length = 0
        while (source[psz] === LEADER) {
          zeroes++
          psz++
        }
            // Allocate enough space in big-endian base256 representation.
        var size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.
        var b256 = new Uint8Array(size)
            // Process the characters.
        while (source[psz]) {
                // Decode character
          var carry = BASE_MAP[source.charCodeAt(psz)]
                // Invalid character
          if (carry === 255) { return }
          var i = 0
          for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {
            carry += (BASE * b256[it3]) >>> 0
            b256[it3] = (carry % 256) >>> 0
            carry = (carry / 256) >>> 0
          }
          if (carry !== 0) { throw new Error('Non-zero carry') }
          length = i
          psz++
        }
            // Skip leading zeroes in b256.
        var it4 = size - length
        while (it4 !== size && b256[it4] === 0) {
          it4++
        }
        var vch = _Buffer.allocUnsafe(zeroes + (size - it4))
        vch.fill(0x00, 0, zeroes)
        var j = zeroes
        while (it4 !== size) {
          vch[j++] = b256[it4++]
        }
        return vch
      }
      function decode (string) {
        var buffer = decodeUnsafe(string)
        if (buffer) { return buffer }
        throw new Error('Non-base' + BASE + ' character')
      }
      return {
        encode: encode,
        decodeUnsafe: decodeUnsafe,
        decode: decode
      }
    }
    module.exports = base
    
    },{"safe-buffer":338}],31:[function(require,module,exports){
    'use strict'
    
    exports.byteLength = byteLength
    exports.toByteArray = toByteArray
    exports.fromByteArray = fromByteArray
    
    var lookup = []
    var revLookup = []
    var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
    
    var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    for (var i = 0, len = code.length; i < len; ++i) {
      lookup[i] = code[i]
      revLookup[code.charCodeAt(i)] = i
    }
    
    // Support decoding URL-safe base64 strings, as Node.js does.
    // See: https://en.wikipedia.org/wiki/Base64#URL_applications
    revLookup['-'.charCodeAt(0)] = 62
    revLookup['_'.charCodeAt(0)] = 63
    
    function getLens (b64) {
      var len = b64.length
    
      if (len % 4 > 0) {
        throw new Error('Invalid string. Length must be a multiple of 4')
      }
    
      // Trim off extra bytes after placeholder bytes are found
      // See: https://github.com/beatgammit/base64-js/issues/42
      var validLen = b64.indexOf('=')
      if (validLen === -1) validLen = len
    
      var placeHoldersLen = validLen === len
        ? 0
        : 4 - (validLen % 4)
    
      return [validLen, placeHoldersLen]
    }
    
    // base64 is 4/3 + up to two characters of the original data
    function byteLength (b64) {
      var lens = getLens(b64)
      var validLen = lens[0]
      var placeHoldersLen = lens[1]
      return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
    }
    
    function _byteLength (b64, validLen, placeHoldersLen) {
      return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
    }
    
    function toByteArray (b64) {
      var tmp
      var lens = getLens(b64)
      var validLen = lens[0]
      var placeHoldersLen = lens[1]
    
      var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
    
      var curByte = 0
    
      // if there are placeholders, only get up to the last complete 4 chars
      var len = placeHoldersLen > 0
        ? validLen - 4
        : validLen
    
      var i
      for (i = 0; i < len; i += 4) {
        tmp =
          (revLookup[b64.charCodeAt(i)] << 18) |
          (revLookup[b64.charCodeAt(i + 1)] << 12) |
          (revLookup[b64.charCodeAt(i + 2)] << 6) |
          revLookup[b64.charCodeAt(i + 3)]
        arr[curByte++] = (tmp >> 16) & 0xFF
        arr[curByte++] = (tmp >> 8) & 0xFF
        arr[curByte++] = tmp & 0xFF
      }
    
      if (placeHoldersLen === 2) {
        tmp =
          (revLookup[b64.charCodeAt(i)] << 2) |
          (revLookup[b64.charCodeAt(i + 1)] >> 4)
        arr[curByte++] = tmp & 0xFF
      }
    
      if (placeHoldersLen === 1) {
        tmp =
          (revLookup[b64.charCodeAt(i)] << 10) |
          (revLookup[b64.charCodeAt(i + 1)] << 4) |
          (revLookup[b64.charCodeAt(i + 2)] >> 2)
        arr[curByte++] = (tmp >> 8) & 0xFF
        arr[curByte++] = tmp & 0xFF
      }
    
      return arr
    }
    
    function tripletToBase64 (num) {
      return lookup[num >> 18 & 0x3F] +
        lookup[num >> 12 & 0x3F] +
        lookup[num >> 6 & 0x3F] +
        lookup[num & 0x3F]
    }
    
    function encodeChunk (uint8, start, end) {
      var tmp
      var output = []
      for (var i = start; i < end; i += 3) {
        tmp =
          ((uint8[i] << 16) & 0xFF0000) +
          ((uint8[i + 1] << 8) & 0xFF00) +
          (uint8[i + 2] & 0xFF)
        output.push(tripletToBase64(tmp))
      }
      return output.join('')
    }
    
    function fromByteArray (uint8) {
      var tmp
      var len = uint8.length
      var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
      var parts = []
      var maxChunkLength = 16383 // must be multiple of 3
    
      // go through the array every three bytes, we'll deal with trailing stuff later
      for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
        parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
      }
    
      // pad the end with zeros, but make sure to not forget the extra bytes
      if (extraBytes === 1) {
        tmp = uint8[len - 1]
        parts.push(
          lookup[tmp >> 2] +
          lookup[(tmp << 4) & 0x3F] +
          '=='
        )
      } else if (extraBytes === 2) {
        tmp = (uint8[len - 2] << 8) + uint8[len - 1]
        parts.push(
          lookup[tmp >> 10] +
          lookup[(tmp >> 4) & 0x3F] +
          lookup[(tmp << 2) & 0x3F] +
          '='
        )
      }
    
      return parts.join('')
    }
    
    },{}],32:[function(require,module,exports){
    ;(function (globalObject) {
      'use strict';
    
    /*
     *      bignumber.js v9.1.2
     *      A JavaScript library for arbitrary-precision arithmetic.
     *      https://github.com/MikeMcl/bignumber.js
     *      Copyright (c) 2022 Michael Mclaughlin <M8ch88l@gmail.com>
     *      MIT Licensed.
     *
     *      BigNumber.prototype methods     |  BigNumber methods
     *                                      |
     *      absoluteValue            abs    |  clone
     *      comparedTo                      |  config               set
     *      decimalPlaces            dp     |      DECIMAL_PLACES
     *      dividedBy                div    |      ROUNDING_MODE
     *      dividedToIntegerBy       idiv   |      EXPONENTIAL_AT
     *      exponentiatedBy          pow    |      RANGE
     *      integerValue                    |      CRYPTO
     *      isEqualTo                eq     |      MODULO_MODE
     *      isFinite                        |      POW_PRECISION
     *      isGreaterThan            gt     |      FORMAT
     *      isGreaterThanOrEqualTo   gte    |      ALPHABET
     *      isInteger                       |  isBigNumber
     *      isLessThan               lt     |  maximum              max
     *      isLessThanOrEqualTo      lte    |  minimum              min
     *      isNaN                           |  random
     *      isNegative                      |  sum
     *      isPositive                      |
     *      isZero                          |
     *      minus                           |
     *      modulo                   mod    |
     *      multipliedBy             times  |
     *      negated                         |
     *      plus                            |
     *      precision                sd     |
     *      shiftedBy                       |
     *      squareRoot               sqrt   |
     *      toExponential                   |
     *      toFixed                         |
     *      toFormat                        |
     *      toFraction                      |
     *      toJSON                          |
     *      toNumber                        |
     *      toPrecision                     |
     *      toString                        |
     *      valueOf                         |
     *
     */
    
    
      var BigNumber,
        isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,
        mathceil = Math.ceil,
        mathfloor = Math.floor,
    
        bignumberError = '[BigNumber Error] ',
        tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ',
    
        BASE = 1e14,
        LOG_BASE = 14,
        MAX_SAFE_INTEGER = 0x1fffffffffffff,         // 2^53 - 1
        // MAX_INT32 = 0x7fffffff,                   // 2^31 - 1
        POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13],
        SQRT_BASE = 1e7,
    
        // EDITABLE
        // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and
        // the arguments to toExponential, toFixed, toFormat, and toPrecision.
        MAX = 1E9;                                   // 0 to MAX_INT32
    
    
      /*
       * Create and return a BigNumber constructor.
       */
      function clone(configObject) {
        var div, convertBase, parseNumeric,
          P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null },
          ONE = new BigNumber(1),
    
    
          //----------------------------- EDITABLE CONFIG DEFAULTS -------------------------------
    
    
          // The default values below must be integers within the inclusive ranges stated.
          // The values can also be changed at run-time using BigNumber.set.
    
          // The maximum number of decimal places for operations involving division.
          DECIMAL_PLACES = 20,                     // 0 to MAX
    
          // The rounding mode used when rounding to the above decimal places, and when using
          // toExponential, toFixed, toFormat and toPrecision, and round (default value).
          // UP         0 Away from zero.
          // DOWN       1 Towards zero.
          // CEIL       2 Towards +Infinity.
          // FLOOR      3 Towards -Infinity.
          // HALF_UP    4 Towards nearest neighbour. If equidistant, up.
          // HALF_DOWN  5 Towards nearest neighbour. If equidistant, down.
          // HALF_EVEN  6 Towards nearest neighbour. If equidistant, towards even neighbour.
          // HALF_CEIL  7 Towards nearest neighbour. If equidistant, towards +Infinity.
          // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
          ROUNDING_MODE = 4,                       // 0 to 8
    
          // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]
    
          // The exponent value at and beneath which toString returns exponential notation.
          // Number type: -7
          TO_EXP_NEG = -7,                         // 0 to -MAX
    
          // The exponent value at and above which toString returns exponential notation.
          // Number type: 21
          TO_EXP_POS = 21,                         // 0 to MAX
    
          // RANGE : [MIN_EXP, MAX_EXP]
    
          // The minimum exponent value, beneath which underflow to zero occurs.
          // Number type: -324  (5e-324)
          MIN_EXP = -1e7,                          // -1 to -MAX
    
          // The maximum exponent value, above which overflow to Infinity occurs.
          // Number type:  308  (1.7976931348623157e+308)
          // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow.
          MAX_EXP = 1e7,                           // 1 to MAX
    
          // Whether to use cryptographically-secure random number generation, if available.
          CRYPTO = false,                          // true or false
    
          // The modulo mode used when calculating the modulus: a mod n.
          // The quotient (q = a / n) is calculated according to the corresponding rounding mode.
          // The remainder (r) is calculated as: r = a - n * q.
          //
          // UP        0 The remainder is positive if the dividend is negative, else is negative.
          // DOWN      1 The remainder has the same sign as the dividend.
          //             This modulo mode is commonly known as 'truncated division' and is
          //             equivalent to (a % n) in JavaScript.
          // FLOOR     3 The remainder has the same sign as the divisor (Python %).
          // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function.
          // EUCLID    9 Euclidian division. q = sign(n) * floor(a / abs(n)).
          //             The remainder is always positive.
          //
          // The truncated division, floored division, Euclidian division and IEEE 754 remainder
          // modes are commonly used for the modulus operation.
          // Although the other rounding modes can also be used, they may not give useful results.
          MODULO_MODE = 1,                         // 0 to 9
    
          // The maximum number of significant digits of the result of the exponentiatedBy operation.
          // If POW_PRECISION is 0, there will be unlimited significant digits.
          POW_PRECISION = 0,                       // 0 to MAX
    
          // The format specification used by the BigNumber.prototype.toFormat method.
          FORMAT = {
            prefix: '',
            groupSize: 3,
            secondaryGroupSize: 0,
            groupSeparator: ',',
            decimalSeparator: '.',
            fractionGroupSize: 0,
            fractionGroupSeparator: '\xA0',        // non-breaking space
            suffix: ''
          },
    
          // The alphabet used for base conversion. It must be at least 2 characters long, with no '+',
          // '-', '.', whitespace, or repeated character.
          // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'
          ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz',
          alphabetHasNormalDecimalDigits = true;
    
    
        //------------------------------------------------------------------------------------------
    
    
        // CONSTRUCTOR
    
    
        /*
         * The BigNumber constructor and exported function.
         * Create and return a new instance of a BigNumber object.
         *
         * v {number|string|BigNumber} A numeric value.
         * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive.
         */
        function BigNumber(v, b) {
          var alphabet, c, caseChanged, e, i, isNum, len, str,
            x = this;
    
          // Enable constructor call without `new`.
          if (!(x instanceof BigNumber)) return new BigNumber(v, b);
    
          if (b == null) {
    
            if (v && v._isBigNumber === true) {
              x.s = v.s;
    
              if (!v.c || v.e > MAX_EXP) {
                x.c = x.e = null;
              } else if (v.e < MIN_EXP) {
                x.c = [x.e = 0];
              } else {
                x.e = v.e;
                x.c = v.c.slice();
              }
    
              return;
            }
    
            if ((isNum = typeof v == 'number') && v * 0 == 0) {
    
              // Use `1 / n` to handle minus zero also.
              x.s = 1 / v < 0 ? (v = -v, -1) : 1;
    
              // Fast path for integers, where n < 2147483648 (2**31).
              if (v === ~~v) {
                for (e = 0, i = v; i >= 10; i /= 10, e++);
    
                if (e > MAX_EXP) {
                  x.c = x.e = null;
                } else {
                  x.e = e;
                  x.c = [v];
                }
    
                return;
              }
    
              str = String(v);
            } else {
    
              if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum);
    
              x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1;
            }
    
            // Decimal point?
            if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
    
            // Exponential form?
            if ((i = str.search(/e/i)) > 0) {
    
              // Determine exponent.
              if (e < 0) e = i;
              e += +str.slice(i + 1);
              str = str.substring(0, i);
            } else if (e < 0) {
    
              // Integer.
              e = str.length;
            }
    
          } else {
    
            // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
            intCheck(b, 2, ALPHABET.length, 'Base');
    
            // Allow exponential notation to be used with base 10 argument, while
            // also rounding to DECIMAL_PLACES as with other bases.
            if (b == 10 && alphabetHasNormalDecimalDigits) {
              x = new BigNumber(v);
              return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE);
            }
    
            str = String(v);
    
            if (isNum = typeof v == 'number') {
    
              // Avoid potential interpretation of Infinity and NaN as base 44+ values.
              if (v * 0 != 0) return parseNumeric(x, str, isNum, b);
    
              x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1;
    
              // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
              if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) {
                throw Error
                 (tooManyDigits + v);
              }
            } else {
              x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1;
            }
    
            alphabet = ALPHABET.slice(0, b);
            e = i = 0;
    
            // Check that str is a valid base b number.
            // Don't use RegExp, so alphabet can contain special characters.
            for (len = str.length; i < len; i++) {
              if (alphabet.indexOf(c = str.charAt(i)) < 0) {
                if (c == '.') {
    
                  // If '.' is not the first character and it has not be found before.
                  if (i > e) {
                    e = len;
                    continue;
                  }
                } else if (!caseChanged) {
    
                  // Allow e.g. hexadecimal 'FF' as well as 'ff'.
                  if (str == str.toUpperCase() && (str = str.toLowerCase()) ||
                      str == str.toLowerCase() && (str = str.toUpperCase())) {
                    caseChanged = true;
                    i = -1;
                    e = 0;
                    continue;
                  }
                }
    
                return parseNumeric(x, String(v), isNum, b);
              }
            }
    
            // Prevent later check for length on converted number.
            isNum = false;
            str = convertBase(str, b, 10, x.s);
    
            // Decimal point?
            if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
            else e = str.length;
          }
    
          // Determine leading zeros.
          for (i = 0; str.charCodeAt(i) === 48; i++);
    
          // Determine trailing zeros.
          for (len = str.length; str.charCodeAt(--len) === 48;);
    
          if (str = str.slice(i, ++len)) {
            len -= i;
    
            // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
            if (isNum && BigNumber.DEBUG &&
              len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) {
                throw Error
                 (tooManyDigits + (x.s * v));
            }
    
             // Overflow?
            if ((e = e - i - 1) > MAX_EXP) {
    
              // Infinity.
              x.c = x.e = null;
    
            // Underflow?
            } else if (e < MIN_EXP) {
    
              // Zero.
              x.c = [x.e = 0];
            } else {
              x.e = e;
              x.c = [];
    
              // Transform base
    
              // e is the base 10 exponent.
              // i is where to slice str to get the first element of the coefficient array.
              i = (e + 1) % LOG_BASE;
              if (e < 0) i += LOG_BASE;  // i < 1
    
              if (i < len) {
                if (i) x.c.push(+str.slice(0, i));
    
                for (len -= LOG_BASE; i < len;) {
                  x.c.push(+str.slice(i, i += LOG_BASE));
                }
    
                i = LOG_BASE - (str = str.slice(i)).length;
              } else {
                i -= len;
              }
    
              for (; i--; str += '0');
              x.c.push(+str);
            }
          } else {
    
            // Zero.
            x.c = [x.e = 0];
          }
        }
    
    
        // CONSTRUCTOR PROPERTIES
    
    
        BigNumber.clone = clone;
    
        BigNumber.ROUND_UP = 0;
        BigNumber.ROUND_DOWN = 1;
        BigNumber.ROUND_CEIL = 2;
        BigNumber.ROUND_FLOOR = 3;
        BigNumber.ROUND_HALF_UP = 4;
        BigNumber.ROUND_HALF_DOWN = 5;
        BigNumber.ROUND_HALF_EVEN = 6;
        BigNumber.ROUND_HALF_CEIL = 7;
        BigNumber.ROUND_HALF_FLOOR = 8;
        BigNumber.EUCLID = 9;
    
    
        /*
         * Configure infrequently-changing library-wide settings.
         *
         * Accept an object with the following optional properties (if the value of a property is
         * a number, it must be an integer within the inclusive range stated):
         *
         *   DECIMAL_PLACES   {number}           0 to MAX
         *   ROUNDING_MODE    {number}           0 to 8
         *   EXPONENTIAL_AT   {number|number[]}  -MAX to MAX  or  [-MAX to 0, 0 to MAX]
         *   RANGE            {number|number[]}  -MAX to MAX (not zero)  or  [-MAX to -1, 1 to MAX]
         *   CRYPTO           {boolean}          true or false
         *   MODULO_MODE      {number}           0 to 9
         *   POW_PRECISION       {number}           0 to MAX
         *   ALPHABET         {string}           A string of two or more unique characters which does
         *                                       not contain '.'.
         *   FORMAT           {object}           An object with some of the following properties:
         *     prefix                 {string}
         *     groupSize              {number}
         *     secondaryGroupSize     {number}
         *     groupSeparator         {string}
         *     decimalSeparator       {string}
         *     fractionGroupSize      {number}
         *     fractionGroupSeparator {string}
         *     suffix                 {string}
         *
         * (The values assigned to the above FORMAT object properties are not checked for validity.)
         *
         * E.g.
         * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
         *
         * Ignore properties/parameters set to null or undefined, except for ALPHABET.
         *
         * Return an object with the properties current values.
         */
        BigNumber.config = BigNumber.set = function (obj) {
          var p, v;
    
          if (obj != null) {
    
            if (typeof obj == 'object') {
    
              // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive.
              // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}'
              if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) {
                v = obj[p];
                intCheck(v, 0, MAX, p);
                DECIMAL_PLACES = v;
              }
    
              // ROUNDING_MODE {number} Integer, 0 to 8 inclusive.
              // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}'
              if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) {
                v = obj[p];
                intCheck(v, 0, 8, p);
                ROUNDING_MODE = v;
              }
    
              // EXPONENTIAL_AT {number|number[]}
              // Integer, -MAX to MAX inclusive or
              // [integer -MAX to 0 inclusive, 0 to MAX inclusive].
              // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}'
              if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) {
                v = obj[p];
                if (v && v.pop) {
                  intCheck(v[0], -MAX, 0, p);
                  intCheck(v[1], 0, MAX, p);
                  TO_EXP_NEG = v[0];
                  TO_EXP_POS = v[1];
                } else {
                  intCheck(v, -MAX, MAX, p);
                  TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v);
                }
              }
    
              // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or
              // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive].
              // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}'
              if (obj.hasOwnProperty(p = 'RANGE')) {
                v = obj[p];
                if (v && v.pop) {
                  intCheck(v[0], -MAX, -1, p);
                  intCheck(v[1], 1, MAX, p);
                  MIN_EXP = v[0];
                  MAX_EXP = v[1];
                } else {
                  intCheck(v, -MAX, MAX, p);
                  if (v) {
                    MIN_EXP = -(MAX_EXP = v < 0 ? -v : v);
                  } else {
                    throw Error
                     (bignumberError + p + ' cannot be zero: ' + v);
                  }
                }
              }
    
              // CRYPTO {boolean} true or false.
              // '[BigNumber Error] CRYPTO not true or false: {v}'
              // '[BigNumber Error] crypto unavailable'
              if (obj.hasOwnProperty(p = 'CRYPTO')) {
                v = obj[p];
                if (v === !!v) {
                  if (v) {
                    if (typeof crypto != 'undefined' && crypto &&
                     (crypto.getRandomValues || crypto.randomBytes)) {
                      CRYPTO = v;
                    } else {
                      CRYPTO = !v;
                      throw Error
                       (bignumberError + 'crypto unavailable');
                    }
                  } else {
                    CRYPTO = v;
                  }
                } else {
                  throw Error
                   (bignumberError + p + ' not true or false: ' + v);
                }
              }
    
              // MODULO_MODE {number} Integer, 0 to 9 inclusive.
              // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}'
              if (obj.hasOwnProperty(p = 'MODULO_MODE')) {
                v = obj[p];
                intCheck(v, 0, 9, p);
                MODULO_MODE = v;
              }
    
              // POW_PRECISION {number} Integer, 0 to MAX inclusive.
              // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}'
              if (obj.hasOwnProperty(p = 'POW_PRECISION')) {
                v = obj[p];
                intCheck(v, 0, MAX, p);
                POW_PRECISION = v;
              }
    
              // FORMAT {object}
              // '[BigNumber Error] FORMAT not an object: {v}'
              if (obj.hasOwnProperty(p = 'FORMAT')) {
                v = obj[p];
                if (typeof v == 'object') FORMAT = v;
                else throw Error
                 (bignumberError + p + ' not an object: ' + v);
              }
    
              // ALPHABET {string}
              // '[BigNumber Error] ALPHABET invalid: {v}'
              if (obj.hasOwnProperty(p = 'ALPHABET')) {
                v = obj[p];
    
                // Disallow if less than two characters,
                // or if it contains '+', '-', '.', whitespace, or a repeated character.
                if (typeof v == 'string' && !/^.?$|[+\-.\s]|(.).*\1/.test(v)) {
                  alphabetHasNormalDecimalDigits = v.slice(0, 10) == '0123456789';
                  ALPHABET = v;
                } else {
                  throw Error
                   (bignumberError + p + ' invalid: ' + v);
                }
              }
    
            } else {
    
              // '[BigNumber Error] Object expected: {v}'
              throw Error
               (bignumberError + 'Object expected: ' + obj);
            }
          }
    
          return {
            DECIMAL_PLACES: DECIMAL_PLACES,
            ROUNDING_MODE: ROUNDING_MODE,
            EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS],
            RANGE: [MIN_EXP, MAX_EXP],
            CRYPTO: CRYPTO,
            MODULO_MODE: MODULO_MODE,
            POW_PRECISION: POW_PRECISION,
            FORMAT: FORMAT,
            ALPHABET: ALPHABET
          };
        };
    
    
        /*
         * Return true if v is a BigNumber instance, otherwise return false.
         *
         * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed.
         *
         * v {any}
         *
         * '[BigNumber Error] Invalid BigNumber: {v}'
         */
        BigNumber.isBigNumber = function (v) {
          if (!v || v._isBigNumber !== true) return false;
          if (!BigNumber.DEBUG) return true;
    
          var i, n,
            c = v.c,
            e = v.e,
            s = v.s;
    
          out: if ({}.toString.call(c) == '[object Array]') {
    
            if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) {
    
              // If the first element is zero, the BigNumber value must be zero.
              if (c[0] === 0) {
                if (e === 0 && c.length === 1) return true;
                break out;
              }
    
              // Calculate number of digits that c[0] should have, based on the exponent.
              i = (e + 1) % LOG_BASE;
              if (i < 1) i += LOG_BASE;
    
              // Calculate number of digits of c[0].
              //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) {
              if (String(c[0]).length == i) {
    
                for (i = 0; i < c.length; i++) {
                  n = c[i];
                  if (n < 0 || n >= BASE || n !== mathfloor(n)) break out;
                }
    
                // Last element cannot be zero, unless it is the only element.
                if (n !== 0) return true;
              }
            }
    
          // Infinity/NaN
          } else if (c === null && e === null && (s === null || s === 1 || s === -1)) {
            return true;
          }
    
          throw Error
            (bignumberError + 'Invalid BigNumber: ' + v);
        };
    
    
        /*
         * Return a new BigNumber whose value is the maximum of the arguments.
         *
         * arguments {number|string|BigNumber}
         */
        BigNumber.maximum = BigNumber.max = function () {
          return maxOrMin(arguments, -1);
        };
    
    
        /*
         * Return a new BigNumber whose value is the minimum of the arguments.
         *
         * arguments {number|string|BigNumber}
         */
        BigNumber.minimum = BigNumber.min = function () {
          return maxOrMin(arguments, 1);
        };
    
    
        /*
         * Return a new BigNumber with a random value equal to or greater than 0 and less than 1,
         * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing
         * zeros are produced).
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}'
         * '[BigNumber Error] crypto unavailable'
         */
        BigNumber.random = (function () {
          var pow2_53 = 0x20000000000000;
    
          // Return a 53 bit integer n, where 0 <= n < 9007199254740992.
          // Check if Math.random() produces more than 32 bits of randomness.
          // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits.
          // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1.
          var random53bitInt = (Math.random() * pow2_53) & 0x1fffff
           ? function () { return mathfloor(Math.random() * pow2_53); }
           : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) +
             (Math.random() * 0x800000 | 0); };
    
          return function (dp) {
            var a, b, e, k, v,
              i = 0,
              c = [],
              rand = new BigNumber(ONE);
    
            if (dp == null) dp = DECIMAL_PLACES;
            else intCheck(dp, 0, MAX);
    
            k = mathceil(dp / LOG_BASE);
    
            if (CRYPTO) {
    
              // Browsers supporting crypto.getRandomValues.
              if (crypto.getRandomValues) {
    
                a = crypto.getRandomValues(new Uint32Array(k *= 2));
    
                for (; i < k;) {
    
                  // 53 bits:
                  // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2)
                  // 11111 11111111 11111111 11111111 11100000 00000000 00000000
                  // ((Math.pow(2, 32) - 1) >>> 11).toString(2)
                  //                                     11111 11111111 11111111
                  // 0x20000 is 2^21.
                  v = a[i] * 0x20000 + (a[i + 1] >>> 11);
    
                  // Rejection sampling:
                  // 0 <= v < 9007199254740992
                  // Probability that v >= 9e15, is
                  // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251
                  if (v >= 9e15) {
                    b = crypto.getRandomValues(new Uint32Array(2));
                    a[i] = b[0];
                    a[i + 1] = b[1];
                  } else {
    
                    // 0 <= v <= 8999999999999999
                    // 0 <= (v % 1e14) <= 99999999999999
                    c.push(v % 1e14);
                    i += 2;
                  }
                }
                i = k / 2;
    
              // Node.js supporting crypto.randomBytes.
              } else if (crypto.randomBytes) {
    
                // buffer
                a = crypto.randomBytes(k *= 7);
    
                for (; i < k;) {
    
                  // 0x1000000000000 is 2^48, 0x10000000000 is 2^40
                  // 0x100000000 is 2^32, 0x1000000 is 2^24
                  // 11111 11111111 11111111 11111111 11111111 11111111 11111111
                  // 0 <= v < 9007199254740992
                  v = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) +
                     (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) +
                     (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6];
    
                  if (v >= 9e15) {
                    crypto.randomBytes(7).copy(a, i);
                  } else {
    
                    // 0 <= (v % 1e14) <= 99999999999999
                    c.push(v % 1e14);
                    i += 7;
                  }
                }
                i = k / 7;
              } else {
                CRYPTO = false;
                throw Error
                 (bignumberError + 'crypto unavailable');
              }
            }
    
            // Use Math.random.
            if (!CRYPTO) {
    
              for (; i < k;) {
                v = random53bitInt();
                if (v < 9e15) c[i++] = v % 1e14;
              }
            }
    
            k = c[--i];
            dp %= LOG_BASE;
    
            // Convert trailing digits to zeros according to dp.
            if (k && dp) {
              v = POWS_TEN[LOG_BASE - dp];
              c[i] = mathfloor(k / v) * v;
            }
    
            // Remove trailing elements which are zero.
            for (; c[i] === 0; c.pop(), i--);
    
            // Zero?
            if (i < 0) {
              c = [e = 0];
            } else {
    
              // Remove leading elements which are zero and adjust exponent accordingly.
              for (e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE);
    
              // Count the digits of the first element of c to determine leading zeros, and...
              for (i = 1, v = c[0]; v >= 10; v /= 10, i++);
    
              // adjust the exponent accordingly.
              if (i < LOG_BASE) e -= LOG_BASE - i;
            }
    
            rand.e = e;
            rand.c = c;
            return rand;
          };
        })();
    
    
        /*
         * Return a BigNumber whose value is the sum of the arguments.
         *
         * arguments {number|string|BigNumber}
         */
        BigNumber.sum = function () {
          var i = 1,
            args = arguments,
            sum = new BigNumber(args[0]);
          for (; i < args.length;) sum = sum.plus(args[i++]);
          return sum;
        };
    
    
        // PRIVATE FUNCTIONS
    
    
        // Called by BigNumber and BigNumber.prototype.toString.
        convertBase = (function () {
          var decimal = '0123456789';
    
          /*
           * Convert string of baseIn to an array of numbers of baseOut.
           * Eg. toBaseOut('255', 10, 16) returns [15, 15].
           * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5].
           */
          function toBaseOut(str, baseIn, baseOut, alphabet) {
            var j,
              arr = [0],
              arrL,
              i = 0,
              len = str.length;
    
            for (; i < len;) {
              for (arrL = arr.length; arrL--; arr[arrL] *= baseIn);
    
              arr[0] += alphabet.indexOf(str.charAt(i++));
    
              for (j = 0; j < arr.length; j++) {
    
                if (arr[j] > baseOut - 1) {
                  if (arr[j + 1] == null) arr[j + 1] = 0;
                  arr[j + 1] += arr[j] / baseOut | 0;
                  arr[j] %= baseOut;
                }
              }
            }
    
            return arr.reverse();
          }
    
          // Convert a numeric string of baseIn to a numeric string of baseOut.
          // If the caller is toString, we are converting from base 10 to baseOut.
          // If the caller is BigNumber, we are converting from baseIn to base 10.
          return function (str, baseIn, baseOut, sign, callerIsToString) {
            var alphabet, d, e, k, r, x, xc, y,
              i = str.indexOf('.'),
              dp = DECIMAL_PLACES,
              rm = ROUNDING_MODE;
    
            // Non-integer.
            if (i >= 0) {
              k = POW_PRECISION;
    
              // Unlimited precision.
              POW_PRECISION = 0;
              str = str.replace('.', '');
              y = new BigNumber(baseIn);
              x = y.pow(str.length - i);
              POW_PRECISION = k;
    
              // Convert str as if an integer, then restore the fraction part by dividing the
              // result by its base raised to a power.
    
              y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'),
               10, baseOut, decimal);
              y.e = y.c.length;
            }
    
            // Convert the number as integer.
    
            xc = toBaseOut(str, baseIn, baseOut, callerIsToString
             ? (alphabet = ALPHABET, decimal)
             : (alphabet = decimal, ALPHABET));
    
            // xc now represents str as an integer and converted to baseOut. e is the exponent.
            e = k = xc.length;
    
            // Remove trailing zeros.
            for (; xc[--k] == 0; xc.pop());
    
            // Zero?
            if (!xc[0]) return alphabet.charAt(0);
    
            // Does str represent an integer? If so, no need for the division.
            if (i < 0) {
              --e;
            } else {
              x.c = xc;
              x.e = e;
    
              // The sign is needed for correct rounding.
              x.s = sign;
              x = div(x, y, dp, rm, baseOut);
              xc = x.c;
              r = x.r;
              e = x.e;
            }
    
            // xc now represents str converted to baseOut.
    
            // THe index of the rounding digit.
            d = e + dp + 1;
    
            // The rounding digit: the digit to the right of the digit that may be rounded up.
            i = xc[d];
    
            // Look at the rounding digits and mode to determine whether to round up.
    
            k = baseOut / 2;
            r = r || d < 0 || xc[d + 1] != null;
    
            r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
                  : i > k || i == k &&(rm == 4 || r || rm == 6 && xc[d - 1] & 1 ||
                   rm == (x.s < 0 ? 8 : 7));
    
            // If the index of the rounding digit is not greater than zero, or xc represents
            // zero, then the result of the base conversion is zero or, if rounding up, a value
            // such as 0.00001.
            if (d < 1 || !xc[0]) {
    
              // 1^-dp or 0
              str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0);
            } else {
    
              // Truncate xc to the required number of decimal places.
              xc.length = d;
    
              // Round up?
              if (r) {
    
                // Rounding up may mean the previous digit has to be rounded up and so on.
                for (--baseOut; ++xc[--d] > baseOut;) {
                  xc[d] = 0;
    
                  if (!d) {
                    ++e;
                    xc = [1].concat(xc);
                  }
                }
              }
    
              // Determine trailing zeros.
              for (k = xc.length; !xc[--k];);
    
              // E.g. [4, 11, 15] becomes 4bf.
              for (i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++]));
    
              // Add leading zeros, decimal point and trailing zeros as required.
              str = toFixedPoint(str, e, alphabet.charAt(0));
            }
    
            // The caller will add the sign.
            return str;
          };
        })();
    
    
        // Perform division in the specified base. Called by div and convertBase.
        div = (function () {
    
          // Assume non-zero x and k.
          function multiply(x, k, base) {
            var m, temp, xlo, xhi,
              carry = 0,
              i = x.length,
              klo = k % SQRT_BASE,
              khi = k / SQRT_BASE | 0;
    
            for (x = x.slice(); i--;) {
              xlo = x[i] % SQRT_BASE;
              xhi = x[i] / SQRT_BASE | 0;
              m = khi * xlo + xhi * klo;
              temp = klo * xlo + ((m % SQRT_BASE) * SQRT_BASE) + carry;
              carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi;
              x[i] = temp % base;
            }
    
            if (carry) x = [carry].concat(x);
    
            return x;
          }
    
          function compare(a, b, aL, bL) {
            var i, cmp;
    
            if (aL != bL) {
              cmp = aL > bL ? 1 : -1;
            } else {
    
              for (i = cmp = 0; i < aL; i++) {
    
                if (a[i] != b[i]) {
                  cmp = a[i] > b[i] ? 1 : -1;
                  break;
                }
              }
            }
    
            return cmp;
          }
    
          function subtract(a, b, aL, base) {
            var i = 0;
    
            // Subtract b from a.
            for (; aL--;) {
              a[aL] -= i;
              i = a[aL] < b[aL] ? 1 : 0;
              a[aL] = i * base + a[aL] - b[aL];
            }
    
            // Remove leading zeros.
            for (; !a[0] && a.length > 1; a.splice(0, 1));
          }
    
          // x: dividend, y: divisor.
          return function (x, y, dp, rm, base) {
            var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0,
              yL, yz,
              s = x.s == y.s ? 1 : -1,
              xc = x.c,
              yc = y.c;
    
            // Either NaN, Infinity or 0?
            if (!xc || !xc[0] || !yc || !yc[0]) {
    
              return new BigNumber(
    
               // Return NaN if either NaN, or both Infinity or 0.
               !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN :
    
                // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.
                xc && xc[0] == 0 || !yc ? s * 0 : s / 0
             );
            }
    
            q = new BigNumber(s);
            qc = q.c = [];
            e = x.e - y.e;
            s = dp + e + 1;
    
            if (!base) {
              base = BASE;
              e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE);
              s = s / LOG_BASE | 0;
            }
    
            // Result exponent may be one less then the current value of e.
            // The coefficients of the BigNumbers from convertBase may have trailing zeros.
            for (i = 0; yc[i] == (xc[i] || 0); i++);
    
            if (yc[i] > (xc[i] || 0)) e--;
    
            if (s < 0) {
              qc.push(1);
              more = true;
            } else {
              xL = xc.length;
              yL = yc.length;
              i = 0;
              s += 2;
    
              // Normalise xc and yc so highest order digit of yc is >= base / 2.
    
              n = mathfloor(base / (yc[0] + 1));
    
              // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1.
              // if (n > 1 || n++ == 1 && yc[0] < base / 2) {
              if (n > 1) {
                yc = multiply(yc, n, base);
                xc = multiply(xc, n, base);
                yL = yc.length;
                xL = xc.length;
              }
    
              xi = yL;
              rem = xc.slice(0, yL);
              remL = rem.length;
    
              // Add zeros to make remainder as long as divisor.
              for (; remL < yL; rem[remL++] = 0);
              yz = yc.slice();
              yz = [0].concat(yz);
              yc0 = yc[0];
              if (yc[1] >= base / 2) yc0++;
              // Not necessary, but to prevent trial digit n > base, when using base 3.
              // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15;
    
              do {
                n = 0;
    
                // Compare divisor and remainder.
                cmp = compare(yc, rem, yL, remL);
    
                // If divisor < remainder.
                if (cmp < 0) {
    
                  // Calculate trial digit, n.
    
                  rem0 = rem[0];
                  if (yL != remL) rem0 = rem0 * base + (rem[1] || 0);
    
                  // n is how many times the divisor goes into the current remainder.
                  n = mathfloor(rem0 / yc0);
    
                  //  Algorithm:
                  //  product = divisor multiplied by trial digit (n).
                  //  Compare product and remainder.
                  //  If product is greater than remainder:
                  //    Subtract divisor from product, decrement trial digit.
                  //  Subtract product from remainder.
                  //  If product was less than remainder at the last compare:
                  //    Compare new remainder and divisor.
                  //    If remainder is greater than divisor:
                  //      Subtract divisor from remainder, increment trial digit.
    
                  if (n > 1) {
    
                    // n may be > base only when base is 3.
                    if (n >= base) n = base - 1;
    
                    // product = divisor * trial digit.
                    prod = multiply(yc, n, base);
                    prodL = prod.length;
                    remL = rem.length;
    
                    // Compare product and remainder.
                    // If product > remainder then trial digit n too high.
                    // n is 1 too high about 5% of the time, and is not known to have
                    // ever been more than 1 too high.
                    while (compare(prod, rem, prodL, remL) == 1) {
                      n--;
    
                      // Subtract divisor from product.
                      subtract(prod, yL < prodL ? yz : yc, prodL, base);
                      prodL = prod.length;
                      cmp = 1;
                    }
                  } else {
    
                    // n is 0 or 1, cmp is -1.
                    // If n is 0, there is no need to compare yc and rem again below,
                    // so change cmp to 1 to avoid it.
                    // If n is 1, leave cmp as -1, so yc and rem are compared again.
                    if (n == 0) {
    
                      // divisor < remainder, so n must be at least 1.
                      cmp = n = 1;
                    }
    
                    // product = divisor
                    prod = yc.slice();
                    prodL = prod.length;
                  }
    
                  if (prodL < remL) prod = [0].concat(prod);
    
                  // Subtract product from remainder.
                  subtract(rem, prod, remL, base);
                  remL = rem.length;
    
                   // If product was < remainder.
                  if (cmp == -1) {
    
                    // Compare divisor and new remainder.
                    // If divisor < new remainder, subtract divisor from remainder.
                    // Trial digit n too low.
                    // n is 1 too low about 5% of the time, and very rarely 2 too low.
                    while (compare(yc, rem, yL, remL) < 1) {
                      n++;
    
                      // Subtract divisor from remainder.
                      subtract(rem, yL < remL ? yz : yc, remL, base);
                      remL = rem.length;
                    }
                  }
                } else if (cmp === 0) {
                  n++;
                  rem = [0];
                } // else cmp === 1 and n will be 0
    
                // Add the next digit, n, to the result array.
                qc[i++] = n;
    
                // Update the remainder.
                if (rem[0]) {
                  rem[remL++] = xc[xi] || 0;
                } else {
                  rem = [xc[xi]];
                  remL = 1;
                }
              } while ((xi++ < xL || rem[0] != null) && s--);
    
              more = rem[0] != null;
    
              // Leading zero?
              if (!qc[0]) qc.splice(0, 1);
            }
    
            if (base == BASE) {
    
              // To calculate q.e, first get the number of digits of qc[0].
              for (i = 1, s = qc[0]; s >= 10; s /= 10, i++);
    
              round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more);
    
            // Caller is convertBase.
            } else {
              q.e = e;
              q.r = +more;
            }
    
            return q;
          };
        })();
    
    
        /*
         * Return a string representing the value of BigNumber n in fixed-point or exponential
         * notation rounded to the specified decimal places or significant digits.
         *
         * n: a BigNumber.
         * i: the index of the last digit required (i.e. the digit that may be rounded up).
         * rm: the rounding mode.
         * id: 1 (toExponential) or 2 (toPrecision).
         */
        function format(n, i, rm, id) {
          var c0, e, ne, len, str;
    
          if (rm == null) rm = ROUNDING_MODE;
          else intCheck(rm, 0, 8);
    
          if (!n.c) return n.toString();
    
          c0 = n.c[0];
          ne = n.e;
    
          if (i == null) {
            str = coeffToString(n.c);
            str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS)
             ? toExponential(str, ne)
             : toFixedPoint(str, ne, '0');
          } else {
            n = round(new BigNumber(n), i, rm);
    
            // n.e may have changed if the value was rounded up.
            e = n.e;
    
            str = coeffToString(n.c);
            len = str.length;
    
            // toPrecision returns exponential notation if the number of significant digits
            // specified is less than the number of digits necessary to represent the integer
            // part of the value in fixed-point notation.
    
            // Exponential notation.
            if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) {
    
              // Append zeros?
              for (; len < i; str += '0', len++);
              str = toExponential(str, e);
    
            // Fixed-point notation.
            } else {
              i -= ne;
              str = toFixedPoint(str, e, '0');
    
              // Append zeros?
              if (e + 1 > len) {
                if (--i > 0) for (str += '.'; i--; str += '0');
              } else {
                i += e - len;
                if (i > 0) {
                  if (e + 1 == len) str += '.';
                  for (; i--; str += '0');
                }
              }
            }
          }
    
          return n.s < 0 && c0 ? '-' + str : str;
        }
    
    
        // Handle BigNumber.max and BigNumber.min.
        // If any number is NaN, return NaN.
        function maxOrMin(args, n) {
          var k, y,
            i = 1,
            x = new BigNumber(args[0]);
    
          for (; i < args.length; i++) {
            y = new BigNumber(args[i]);
            if (!y.s || (k = compare(x, y)) === n || k === 0 && x.s === n) {
              x = y;
            }
          }
    
          return x;
        }
    
    
        /*
         * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP.
         * Called by minus, plus and times.
         */
        function normalise(n, c, e) {
          var i = 1,
            j = c.length;
    
           // Remove trailing zeros.
          for (; !c[--j]; c.pop());
    
          // Calculate the base 10 exponent. First get the number of digits of c[0].
          for (j = c[0]; j >= 10; j /= 10, i++);
    
          // Overflow?
          if ((e = i + e * LOG_BASE - 1) > MAX_EXP) {
    
            // Infinity.
            n.c = n.e = null;
    
          // Underflow?
          } else if (e < MIN_EXP) {
    
            // Zero.
            n.c = [n.e = 0];
          } else {
            n.e = e;
            n.c = c;
          }
    
          return n;
        }
    
    
        // Handle values that fail the validity test in BigNumber.
        parseNumeric = (function () {
          var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i,
            dotAfter = /^([^.]+)\.$/,
            dotBefore = /^\.([^.]+)$/,
            isInfinityOrNaN = /^-?(Infinity|NaN)$/,
            whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;
    
          return function (x, str, isNum, b) {
            var base,
              s = isNum ? str : str.replace(whitespaceOrPlus, '');
    
            // No exception on ±Infinity or NaN.
            if (isInfinityOrNaN.test(s)) {
              x.s = isNaN(s) ? null : s < 0 ? -1 : 1;
            } else {
              if (!isNum) {
    
                // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i
                s = s.replace(basePrefix, function (m, p1, p2) {
                  base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8;
                  return !b || b == base ? p1 : m;
                });
    
                if (b) {
                  base = b;
    
                  // E.g. '1.' to '1', '.1' to '0.1'
                  s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1');
                }
    
                if (str != s) return new BigNumber(s, base);
              }
    
              // '[BigNumber Error] Not a number: {n}'
              // '[BigNumber Error] Not a base {b} number: {n}'
              if (BigNumber.DEBUG) {
                throw Error
                  (bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str);
              }
    
              // NaN
              x.s = null;
            }
    
            x.c = x.e = null;
          }
        })();
    
    
        /*
         * Round x to sd significant digits using rounding mode rm. Check for over/under-flow.
         * If r is truthy, it is known that there are more digits after the rounding digit.
         */
        function round(x, sd, rm, r) {
          var d, i, j, k, n, ni, rd,
            xc = x.c,
            pows10 = POWS_TEN;
    
          // if x is not Infinity or NaN...
          if (xc) {
    
            // rd is the rounding digit, i.e. the digit after the digit that may be rounded up.
            // n is a base 1e14 number, the value of the element of array x.c containing rd.
            // ni is the index of n within x.c.
            // d is the number of digits of n.
            // i is the index of rd within n including leading zeros.
            // j is the actual index of rd within n (if < 0, rd is a leading zero).
            out: {
    
              // Get the number of digits of the first element of xc.
              for (d = 1, k = xc[0]; k >= 10; k /= 10, d++);
              i = sd - d;
    
              // If the rounding digit is in the first element of xc...
              if (i < 0) {
                i += LOG_BASE;
                j = sd;
                n = xc[ni = 0];
    
                // Get the rounding digit at index j of n.
                rd = mathfloor(n / pows10[d - j - 1] % 10);
              } else {
                ni = mathceil((i + 1) / LOG_BASE);
    
                if (ni >= xc.length) {
    
                  if (r) {
    
                    // Needed by sqrt.
                    for (; xc.length <= ni; xc.push(0));
                    n = rd = 0;
                    d = 1;
                    i %= LOG_BASE;
                    j = i - LOG_BASE + 1;
                  } else {
                    break out;
                  }
                } else {
                  n = k = xc[ni];
    
                  // Get the number of digits of n.
                  for (d = 1; k >= 10; k /= 10, d++);
    
                  // Get the index of rd within n.
                  i %= LOG_BASE;
    
                  // Get the index of rd within n, adjusted for leading zeros.
                  // The number of leading zeros of n is given by LOG_BASE - d.
                  j = i - LOG_BASE + d;
    
                  // Get the rounding digit at index j of n.
                  rd = j < 0 ? 0 : mathfloor(n / pows10[d - j - 1] % 10);
                }
              }
    
              r = r || sd < 0 ||
    
              // Are there any non-zero digits after the rounding digit?
              // The expression  n % pows10[d - j - 1]  returns all digits of n to the right
              // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.
               xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]);
    
              r = rm < 4
               ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
               : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 &&
    
                // Check whether the digit to the left of the rounding digit is odd.
                ((i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10) & 1 ||
                 rm == (x.s < 0 ? 8 : 7));
    
              if (sd < 1 || !xc[0]) {
                xc.length = 0;
    
                if (r) {
    
                  // Convert sd to decimal places.
                  sd -= x.e + 1;
    
                  // 1, 0.1, 0.01, 0.001, 0.0001 etc.
                  xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE];
                  x.e = -sd || 0;
                } else {
    
                  // Zero.
                  xc[0] = x.e = 0;
                }
    
                return x;
              }
    
              // Remove excess digits.
              if (i == 0) {
                xc.length = ni;
                k = 1;
                ni--;
              } else {
                xc.length = ni + 1;
                k = pows10[LOG_BASE - i];
    
                // E.g. 56700 becomes 56000 if 7 is the rounding digit.
                // j > 0 means i > number of leading zeros of n.
                xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0;
              }
    
              // Round up?
              if (r) {
    
                for (; ;) {
    
                  // If the digit to be rounded up is in the first element of xc...
                  if (ni == 0) {
    
                    // i will be the length of xc[0] before k is added.
                    for (i = 1, j = xc[0]; j >= 10; j /= 10, i++);
                    j = xc[0] += k;
                    for (k = 1; j >= 10; j /= 10, k++);
    
                    // if i != k the length has increased.
                    if (i != k) {
                      x.e++;
                      if (xc[0] == BASE) xc[0] = 1;
                    }
    
                    break;
                  } else {
                    xc[ni] += k;
                    if (xc[ni] != BASE) break;
                    xc[ni--] = 0;
                    k = 1;
                  }
                }
              }
    
              // Remove trailing zeros.
              for (i = xc.length; xc[--i] === 0; xc.pop());
            }
    
            // Overflow? Infinity.
            if (x.e > MAX_EXP) {
              x.c = x.e = null;
    
            // Underflow? Zero.
            } else if (x.e < MIN_EXP) {
              x.c = [x.e = 0];
            }
          }
    
          return x;
        }
    
    
        function valueOf(n) {
          var str,
            e = n.e;
    
          if (e === null) return n.toString();
    
          str = coeffToString(n.c);
    
          str = e <= TO_EXP_NEG || e >= TO_EXP_POS
            ? toExponential(str, e)
            : toFixedPoint(str, e, '0');
    
          return n.s < 0 ? '-' + str : str;
        }
    
    
        // PROTOTYPE/INSTANCE METHODS
    
    
        /*
         * Return a new BigNumber whose value is the absolute value of this BigNumber.
         */
        P.absoluteValue = P.abs = function () {
          var x = new BigNumber(this);
          if (x.s < 0) x.s = 1;
          return x;
        };
    
    
        /*
         * Return
         *   1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
         *   -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
         *   0 if they have the same value,
         *   or null if the value of either is NaN.
         */
        P.comparedTo = function (y, b) {
          return compare(this, new BigNumber(y, b));
        };
    
    
        /*
         * If dp is undefined or null or true or false, return the number of decimal places of the
         * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
         *
         * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this
         * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or
         * ROUNDING_MODE if rm is omitted.
         *
         * [dp] {number} Decimal places: integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
         */
        P.decimalPlaces = P.dp = function (dp, rm) {
          var c, n, v,
            x = this;
    
          if (dp != null) {
            intCheck(dp, 0, MAX);
            if (rm == null) rm = ROUNDING_MODE;
            else intCheck(rm, 0, 8);
    
            return round(new BigNumber(x), dp + x.e + 1, rm);
          }
    
          if (!(c = x.c)) return null;
          n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE;
    
          // Subtract the number of trailing zeros of the last number.
          if (v = c[v]) for (; v % 10 == 0; v /= 10, n--);
          if (n < 0) n = 0;
    
          return n;
        };
    
    
        /*
         *  n / 0 = I
         *  n / N = N
         *  n / I = 0
         *  0 / n = 0
         *  0 / 0 = N
         *  0 / N = N
         *  0 / I = 0
         *  N / n = N
         *  N / 0 = N
         *  N / N = N
         *  N / I = N
         *  I / n = I
         *  I / 0 = I
         *  I / N = N
         *  I / I = N
         *
         * Return a new BigNumber whose value is the value of this BigNumber divided by the value of
         * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE.
         */
        P.dividedBy = P.div = function (y, b) {
          return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE);
        };
    
    
        /*
         * Return a new BigNumber whose value is the integer part of dividing the value of this
         * BigNumber by the value of BigNumber(y, b).
         */
        P.dividedToIntegerBy = P.idiv = function (y, b) {
          return div(this, new BigNumber(y, b), 0, 1);
        };
    
    
        /*
         * Return a BigNumber whose value is the value of this BigNumber exponentiated by n.
         *
         * If m is present, return the result modulo m.
         * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
         * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE.
         *
         * The modular power operation works efficiently when x, n, and m are integers, otherwise it
         * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0.
         *
         * n {number|string|BigNumber} The exponent. An integer.
         * [m] {number|string|BigNumber} The modulus.
         *
         * '[BigNumber Error] Exponent not an integer: {n}'
         */
        P.exponentiatedBy = P.pow = function (n, m) {
          var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y,
            x = this;
    
          n = new BigNumber(n);
    
          // Allow NaN and ±Infinity, but not other non-integers.
          if (n.c && !n.isInteger()) {
            throw Error
              (bignumberError + 'Exponent not an integer: ' + valueOf(n));
          }
    
          if (m != null) m = new BigNumber(m);
    
          // Exponent of MAX_SAFE_INTEGER is 15.
          nIsBig = n.e > 14;
    
          // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0.
          if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) {
    
            // The sign of the result of pow when x is negative depends on the evenness of n.
            // If +n overflows to ±Infinity, the evenness of n would be not be known.
            y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? n.s * (2 - isOdd(n)) : +valueOf(n)));
            return m ? y.mod(m) : y;
          }
    
          nIsNeg = n.s < 0;
    
          if (m) {
    
            // x % m returns NaN if abs(m) is zero, or m is NaN.
            if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN);
    
            isModExp = !nIsNeg && x.isInteger() && m.isInteger();
    
            if (isModExp) x = x.mod(m);
    
          // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15.
          // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15.
          } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0
            // [1, 240000000]
            ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7
            // [80000000000000]  [99999750000000]
            : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) {
    
            // If x is negative and n is odd, k = -0, else k = 0.
            k = x.s < 0 && isOdd(n) ? -0 : 0;
    
            // If x >= 1, k = ±Infinity.
            if (x.e > -1) k = 1 / k;
    
            // If n is negative return ±0, else return ±Infinity.
            return new BigNumber(nIsNeg ? 1 / k : k);
    
          } else if (POW_PRECISION) {
    
            // Truncating each coefficient array to a length of k after each multiplication
            // equates to truncating significant digits to POW_PRECISION + [28, 41],
            // i.e. there will be a minimum of 28 guard digits retained.
            k = mathceil(POW_PRECISION / LOG_BASE + 2);
          }
    
          if (nIsBig) {
            half = new BigNumber(0.5);
            if (nIsNeg) n.s = 1;
            nIsOdd = isOdd(n);
          } else {
            i = Math.abs(+valueOf(n));
            nIsOdd = i % 2;
          }
    
          y = new BigNumber(ONE);
    
          // Performs 54 loop iterations for n of 9007199254740991.
          for (; ;) {
    
            if (nIsOdd) {
              y = y.times(x);
              if (!y.c) break;
    
              if (k) {
                if (y.c.length > k) y.c.length = k;
              } else if (isModExp) {
                y = y.mod(m);    //y = y.minus(div(y, m, 0, MODULO_MODE).times(m));
              }
            }
    
            if (i) {
              i = mathfloor(i / 2);
              if (i === 0) break;
              nIsOdd = i % 2;
            } else {
              n = n.times(half);
              round(n, n.e + 1, 1);
    
              if (n.e > 14) {
                nIsOdd = isOdd(n);
              } else {
                i = +valueOf(n);
                if (i === 0) break;
                nIsOdd = i % 2;
              }
            }
    
            x = x.times(x);
    
            if (k) {
              if (x.c && x.c.length > k) x.c.length = k;
            } else if (isModExp) {
              x = x.mod(m);    //x = x.minus(div(x, m, 0, MODULO_MODE).times(m));
            }
          }
    
          if (isModExp) return y;
          if (nIsNeg) y = ONE.div(y);
    
          return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y;
        };
    
    
        /*
         * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer
         * using rounding mode rm, or ROUNDING_MODE if rm is omitted.
         *
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}'
         */
        P.integerValue = function (rm) {
          var n = new BigNumber(this);
          if (rm == null) rm = ROUNDING_MODE;
          else intCheck(rm, 0, 8);
          return round(n, n.e + 1, rm);
        };
    
    
        /*
         * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b),
         * otherwise return false.
         */
        P.isEqualTo = P.eq = function (y, b) {
          return compare(this, new BigNumber(y, b)) === 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is a finite number, otherwise return false.
         */
        P.isFinite = function () {
          return !!this.c;
        };
    
    
        /*
         * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b),
         * otherwise return false.
         */
        P.isGreaterThan = P.gt = function (y, b) {
          return compare(this, new BigNumber(y, b)) > 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is greater than or equal to the value of
         * BigNumber(y, b), otherwise return false.
         */
        P.isGreaterThanOrEqualTo = P.gte = function (y, b) {
          return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0;
    
        };
    
    
        /*
         * Return true if the value of this BigNumber is an integer, otherwise return false.
         */
        P.isInteger = function () {
          return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2;
        };
    
    
        /*
         * Return true if the value of this BigNumber is less than the value of BigNumber(y, b),
         * otherwise return false.
         */
        P.isLessThan = P.lt = function (y, b) {
          return compare(this, new BigNumber(y, b)) < 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is less than or equal to the value of
         * BigNumber(y, b), otherwise return false.
         */
        P.isLessThanOrEqualTo = P.lte = function (y, b) {
          return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is NaN, otherwise return false.
         */
        P.isNaN = function () {
          return !this.s;
        };
    
    
        /*
         * Return true if the value of this BigNumber is negative, otherwise return false.
         */
        P.isNegative = function () {
          return this.s < 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is positive, otherwise return false.
         */
        P.isPositive = function () {
          return this.s > 0;
        };
    
    
        /*
         * Return true if the value of this BigNumber is 0 or -0, otherwise return false.
         */
        P.isZero = function () {
          return !!this.c && this.c[0] == 0;
        };
    
    
        /*
         *  n - 0 = n
         *  n - N = N
         *  n - I = -I
         *  0 - n = -n
         *  0 - 0 = 0
         *  0 - N = N
         *  0 - I = -I
         *  N - n = N
         *  N - 0 = N
         *  N - N = N
         *  N - I = N
         *  I - n = I
         *  I - 0 = I
         *  I - N = N
         *  I - I = N
         *
         * Return a new BigNumber whose value is the value of this BigNumber minus the value of
         * BigNumber(y, b).
         */
        P.minus = function (y, b) {
          var i, j, t, xLTy,
            x = this,
            a = x.s;
    
          y = new BigNumber(y, b);
          b = y.s;
    
          // Either NaN?
          if (!a || !b) return new BigNumber(NaN);
    
          // Signs differ?
          if (a != b) {
            y.s = -b;
            return x.plus(y);
          }
    
          var xe = x.e / LOG_BASE,
            ye = y.e / LOG_BASE,
            xc = x.c,
            yc = y.c;
    
          if (!xe || !ye) {
    
            // Either Infinity?
            if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN);
    
            // Either zero?
            if (!xc[0] || !yc[0]) {
    
              // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
              return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x :
    
               // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
               ROUNDING_MODE == 3 ? -0 : 0);
            }
          }
    
          xe = bitFloor(xe);
          ye = bitFloor(ye);
          xc = xc.slice();
    
          // Determine which is the bigger number.
          if (a = xe - ye) {
    
            if (xLTy = a < 0) {
              a = -a;
              t = xc;
            } else {
              ye = xe;
              t = yc;
            }
    
            t.reverse();
    
            // Prepend zeros to equalise exponents.
            for (b = a; b--; t.push(0));
            t.reverse();
          } else {
    
            // Exponents equal. Check digit by digit.
            j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b;
    
            for (a = b = 0; b < j; b++) {
    
              if (xc[b] != yc[b]) {
                xLTy = xc[b] < yc[b];
                break;
              }
            }
          }
    
          // x < y? Point xc to the array of the bigger number.
          if (xLTy) {
            t = xc;
            xc = yc;
            yc = t;
            y.s = -y.s;
          }
    
          b = (j = yc.length) - (i = xc.length);
    
          // Append zeros to xc if shorter.
          // No need to add zeros to yc if shorter as subtract only needs to start at yc.length.
          if (b > 0) for (; b--; xc[i++] = 0);
          b = BASE - 1;
    
          // Subtract yc from xc.
          for (; j > a;) {
    
            if (xc[--j] < yc[j]) {
              for (i = j; i && !xc[--i]; xc[i] = b);
              --xc[i];
              xc[j] += BASE;
            }
    
            xc[j] -= yc[j];
          }
    
          // Remove leading zeros and adjust exponent accordingly.
          for (; xc[0] == 0; xc.splice(0, 1), --ye);
    
          // Zero?
          if (!xc[0]) {
    
            // Following IEEE 754 (2008) 6.3,
            // n - n = +0  but  n - n = -0  when rounding towards -Infinity.
            y.s = ROUNDING_MODE == 3 ? -1 : 1;
            y.c = [y.e = 0];
            return y;
          }
    
          // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
          // for finite x and y.
          return normalise(y, xc, ye);
        };
    
    
        /*
         *   n % 0 =  N
         *   n % N =  N
         *   n % I =  n
         *   0 % n =  0
         *  -0 % n = -0
         *   0 % 0 =  N
         *   0 % N =  N
         *   0 % I =  0
         *   N % n =  N
         *   N % 0 =  N
         *   N % N =  N
         *   N % I =  N
         *   I % n =  N
         *   I % 0 =  N
         *   I % N =  N
         *   I % I =  N
         *
         * Return a new BigNumber whose value is the value of this BigNumber modulo the value of
         * BigNumber(y, b). The result depends on the value of MODULO_MODE.
         */
        P.modulo = P.mod = function (y, b) {
          var q, s,
            x = this;
    
          y = new BigNumber(y, b);
    
          // Return NaN if x is Infinity or NaN, or y is NaN or zero.
          if (!x.c || !y.s || y.c && !y.c[0]) {
            return new BigNumber(NaN);
    
          // Return x if y is Infinity or x is zero.
          } else if (!y.c || x.c && !x.c[0]) {
            return new BigNumber(x);
          }
    
          if (MODULO_MODE == 9) {
    
            // Euclidian division: q = sign(y) * floor(x / abs(y))
            // r = x - qy    where  0 <= r < abs(y)
            s = y.s;
            y.s = 1;
            q = div(x, y, 0, 3);
            y.s = s;
            q.s *= s;
          } else {
            q = div(x, y, 0, MODULO_MODE);
          }
    
          y = x.minus(q.times(y));
    
          // To match JavaScript %, ensure sign of zero is sign of dividend.
          if (!y.c[0] && MODULO_MODE == 1) y.s = x.s;
    
          return y;
        };
    
    
        /*
         *  n * 0 = 0
         *  n * N = N
         *  n * I = I
         *  0 * n = 0
         *  0 * 0 = 0
         *  0 * N = N
         *  0 * I = N
         *  N * n = N
         *  N * 0 = N
         *  N * N = N
         *  N * I = N
         *  I * n = I
         *  I * 0 = N
         *  I * N = N
         *  I * I = I
         *
         * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value
         * of BigNumber(y, b).
         */
        P.multipliedBy = P.times = function (y, b) {
          var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc,
            base, sqrtBase,
            x = this,
            xc = x.c,
            yc = (y = new BigNumber(y, b)).c;
    
          // Either NaN, ±Infinity or ±0?
          if (!xc || !yc || !xc[0] || !yc[0]) {
    
            // Return NaN if either is NaN, or one is 0 and the other is Infinity.
            if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) {
              y.c = y.e = y.s = null;
            } else {
              y.s *= x.s;
    
              // Return ±Infinity if either is ±Infinity.
              if (!xc || !yc) {
                y.c = y.e = null;
    
              // Return ±0 if either is ±0.
              } else {
                y.c = [0];
                y.e = 0;
              }
            }
    
            return y;
          }
    
          e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE);
          y.s *= x.s;
          xcL = xc.length;
          ycL = yc.length;
    
          // Ensure xc points to longer array and xcL to its length.
          if (xcL < ycL) {
            zc = xc;
            xc = yc;
            yc = zc;
            i = xcL;
            xcL = ycL;
            ycL = i;
          }
    
          // Initialise the result array with zeros.
          for (i = xcL + ycL, zc = []; i--; zc.push(0));
    
          base = BASE;
          sqrtBase = SQRT_BASE;
    
          for (i = ycL; --i >= 0;) {
            c = 0;
            ylo = yc[i] % sqrtBase;
            yhi = yc[i] / sqrtBase | 0;
    
            for (k = xcL, j = i + k; j > i;) {
              xlo = xc[--k] % sqrtBase;
              xhi = xc[k] / sqrtBase | 0;
              m = yhi * xlo + xhi * ylo;
              xlo = ylo * xlo + ((m % sqrtBase) * sqrtBase) + zc[j] + c;
              c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi;
              zc[j--] = xlo % base;
            }
    
            zc[j] = c;
          }
    
          if (c) {
            ++e;
          } else {
            zc.splice(0, 1);
          }
    
          return normalise(y, zc, e);
        };
    
    
        /*
         * Return a new BigNumber whose value is the value of this BigNumber negated,
         * i.e. multiplied by -1.
         */
        P.negated = function () {
          var x = new BigNumber(this);
          x.s = -x.s || null;
          return x;
        };
    
    
        /*
         *  n + 0 = n
         *  n + N = N
         *  n + I = I
         *  0 + n = n
         *  0 + 0 = 0
         *  0 + N = N
         *  0 + I = I
         *  N + n = N
         *  N + 0 = N
         *  N + N = N
         *  N + I = N
         *  I + n = I
         *  I + 0 = I
         *  I + N = N
         *  I + I = I
         *
         * Return a new BigNumber whose value is the value of this BigNumber plus the value of
         * BigNumber(y, b).
         */
        P.plus = function (y, b) {
          var t,
            x = this,
            a = x.s;
    
          y = new BigNumber(y, b);
          b = y.s;
    
          // Either NaN?
          if (!a || !b) return new BigNumber(NaN);
    
          // Signs differ?
           if (a != b) {
            y.s = -b;
            return x.minus(y);
          }
    
          var xe = x.e / LOG_BASE,
            ye = y.e / LOG_BASE,
            xc = x.c,
            yc = y.c;
    
          if (!xe || !ye) {
    
            // Return ±Infinity if either ±Infinity.
            if (!xc || !yc) return new BigNumber(a / 0);
    
            // Either zero?
            // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
            if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0);
          }
    
          xe = bitFloor(xe);
          ye = bitFloor(ye);
          xc = xc.slice();
    
          // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts.
          if (a = xe - ye) {
            if (a > 0) {
              ye = xe;
              t = yc;
            } else {
              a = -a;
              t = xc;
            }
    
            t.reverse();
            for (; a--; t.push(0));
            t.reverse();
          }
    
          a = xc.length;
          b = yc.length;
    
          // Point xc to the longer array, and b to the shorter length.
          if (a - b < 0) {
            t = yc;
            yc = xc;
            xc = t;
            b = a;
          }
    
          // Only start adding at yc.length - 1 as the further digits of xc can be ignored.
          for (a = 0; b;) {
            a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0;
            xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE;
          }
    
          if (a) {
            xc = [a].concat(xc);
            ++ye;
          }
    
          // No need to check for zero, as +x + +y != 0 && -x + -y != 0
          // ye = MAX_EXP + 1 possible
          return normalise(y, xc, ye);
        };
    
    
        /*
         * If sd is undefined or null or true or false, return the number of significant digits of
         * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
         * If sd is true include integer-part trailing zeros in the count.
         *
         * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this
         * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or
         * ROUNDING_MODE if rm is omitted.
         *
         * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive.
         *                     boolean: whether to count integer-part trailing zeros: true or false.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
         */
        P.precision = P.sd = function (sd, rm) {
          var c, n, v,
            x = this;
    
          if (sd != null && sd !== !!sd) {
            intCheck(sd, 1, MAX);
            if (rm == null) rm = ROUNDING_MODE;
            else intCheck(rm, 0, 8);
    
            return round(new BigNumber(x), sd, rm);
          }
    
          if (!(c = x.c)) return null;
          v = c.length - 1;
          n = v * LOG_BASE + 1;
    
          if (v = c[v]) {
    
            // Subtract the number of trailing zeros of the last element.
            for (; v % 10 == 0; v /= 10, n--);
    
            // Add the number of digits of the first element.
            for (v = c[0]; v >= 10; v /= 10, n++);
          }
    
          if (sd && x.e + 1 > n) n = x.e + 1;
    
          return n;
        };
    
    
        /*
         * Return a new BigNumber whose value is the value of this BigNumber shifted by k places
         * (powers of 10). Shift to the right if n > 0, and to the left if n < 0.
         *
         * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}'
         */
        P.shiftedBy = function (k) {
          intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
          return this.times('1e' + k);
        };
    
    
        /*
         *  sqrt(-n) =  N
         *  sqrt(N) =  N
         *  sqrt(-I) =  N
         *  sqrt(I) =  I
         *  sqrt(0) =  0
         *  sqrt(-0) = -0
         *
         * Return a new BigNumber whose value is the square root of the value of this BigNumber,
         * rounded according to DECIMAL_PLACES and ROUNDING_MODE.
         */
        P.squareRoot = P.sqrt = function () {
          var m, n, r, rep, t,
            x = this,
            c = x.c,
            s = x.s,
            e = x.e,
            dp = DECIMAL_PLACES + 4,
            half = new BigNumber('0.5');
    
          // Negative/NaN/Infinity/zero?
          if (s !== 1 || !c || !c[0]) {
            return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0);
          }
    
          // Initial estimate.
          s = Math.sqrt(+valueOf(x));
    
          // Math.sqrt underflow/overflow?
          // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
          if (s == 0 || s == 1 / 0) {
            n = coeffToString(c);
            if ((n.length + e) % 2 == 0) n += '0';
            s = Math.sqrt(+n);
            e = bitFloor((e + 1) / 2) - (e < 0 || e % 2);
    
            if (s == 1 / 0) {
              n = '5e' + e;
            } else {
              n = s.toExponential();
              n = n.slice(0, n.indexOf('e') + 1) + e;
            }
    
            r = new BigNumber(n);
          } else {
            r = new BigNumber(s + '');
          }
    
          // Check for zero.
          // r could be zero if MIN_EXP is changed after the this value was created.
          // This would cause a division by zero (x/t) and hence Infinity below, which would cause
          // coeffToString to throw.
          if (r.c[0]) {
            e = r.e;
            s = e + dp;
            if (s < 3) s = 0;
    
            // Newton-Raphson iteration.
            for (; ;) {
              t = r;
              r = half.times(t.plus(div(x, t, dp, 1)));
    
              if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) {
    
                // The exponent of r may here be one less than the final result exponent,
                // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits
                // are indexed correctly.
                if (r.e < e) --s;
                n = n.slice(s - 3, s + 1);
    
                // The 4th rounding digit may be in error by -1 so if the 4 rounding digits
                // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the
                // iteration.
                if (n == '9999' || !rep && n == '4999') {
    
                  // On the first iteration only, check to see if rounding up gives the
                  // exact result as the nines may infinitely repeat.
                  if (!rep) {
                    round(t, t.e + DECIMAL_PLACES + 2, 0);
    
                    if (t.times(t).eq(x)) {
                      r = t;
                      break;
                    }
                  }
    
                  dp += 4;
                  s += 4;
                  rep = 1;
                } else {
    
                  // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact
                  // result. If not, then there are further digits and m will be truthy.
                  if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
    
                    // Truncate to the first rounding digit.
                    round(r, r.e + DECIMAL_PLACES + 2, 1);
                    m = !r.times(r).eq(x);
                  }
    
                  break;
                }
              }
            }
          }
    
          return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m);
        };
    
    
        /*
         * Return a string representing the value of this BigNumber in exponential notation and
         * rounded using ROUNDING_MODE to dp fixed decimal places.
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
         */
        P.toExponential = function (dp, rm) {
          if (dp != null) {
            intCheck(dp, 0, MAX);
            dp++;
          }
          return format(this, dp, rm, 1);
        };
    
    
        /*
         * Return a string representing the value of this BigNumber in fixed-point notation rounding
         * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted.
         *
         * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
         * but e.g. (-0.00001).toFixed(0) is '-0'.
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
         */
        P.toFixed = function (dp, rm) {
          if (dp != null) {
            intCheck(dp, 0, MAX);
            dp = dp + this.e + 1;
          }
          return format(this, dp, rm);
        };
    
    
        /*
         * Return a string representing the value of this BigNumber in fixed-point notation rounded
         * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties
         * of the format or FORMAT object (see BigNumber.set).
         *
         * The formatting object may contain some or all of the properties shown below.
         *
         * FORMAT = {
         *   prefix: '',
         *   groupSize: 3,
         *   secondaryGroupSize: 0,
         *   groupSeparator: ',',
         *   decimalSeparator: '.',
         *   fractionGroupSize: 0,
         *   fractionGroupSeparator: '\xA0',      // non-breaking space
         *   suffix: ''
         * };
         *
         * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         * [format] {object} Formatting options. See FORMAT pbject above.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
         * '[BigNumber Error] Argument not an object: {format}'
         */
        P.toFormat = function (dp, rm, format) {
          var str,
            x = this;
    
          if (format == null) {
            if (dp != null && rm && typeof rm == 'object') {
              format = rm;
              rm = null;
            } else if (dp && typeof dp == 'object') {
              format = dp;
              dp = rm = null;
            } else {
              format = FORMAT;
            }
          } else if (typeof format != 'object') {
            throw Error
              (bignumberError + 'Argument not an object: ' + format);
          }
    
          str = x.toFixed(dp, rm);
    
          if (x.c) {
            var i,
              arr = str.split('.'),
              g1 = +format.groupSize,
              g2 = +format.secondaryGroupSize,
              groupSeparator = format.groupSeparator || '',
              intPart = arr[0],
              fractionPart = arr[1],
              isNeg = x.s < 0,
              intDigits = isNeg ? intPart.slice(1) : intPart,
              len = intDigits.length;
    
            if (g2) {
              i = g1;
              g1 = g2;
              g2 = i;
              len -= i;
            }
    
            if (g1 > 0 && len > 0) {
              i = len % g1 || g1;
              intPart = intDigits.substr(0, i);
              for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1);
              if (g2 > 0) intPart += groupSeparator + intDigits.slice(i);
              if (isNeg) intPart = '-' + intPart;
            }
    
            str = fractionPart
             ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize)
              ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'),
               '$&' + (format.fractionGroupSeparator || ''))
              : fractionPart)
             : intPart;
          }
    
          return (format.prefix || '') + str + (format.suffix || '');
        };
    
    
        /*
         * Return an array of two BigNumbers representing the value of this BigNumber as a simple
         * fraction with an integer numerator and an integer denominator.
         * The denominator will be a positive non-zero value less than or equal to the specified
         * maximum denominator. If a maximum denominator is not specified, the denominator will be
         * the lowest value necessary to represent the number exactly.
         *
         * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator.
         *
         * '[BigNumber Error] Argument {not an integer|out of range} : {md}'
         */
        P.toFraction = function (md) {
          var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s,
            x = this,
            xc = x.c;
    
          if (md != null) {
            n = new BigNumber(md);
    
            // Throw if md is less than one or is not an integer, unless it is Infinity.
            if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) {
              throw Error
                (bignumberError + 'Argument ' +
                  (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n));
            }
          }
    
          if (!xc) return new BigNumber(x);
    
          d = new BigNumber(ONE);
          n1 = d0 = new BigNumber(ONE);
          d1 = n0 = new BigNumber(ONE);
          s = coeffToString(xc);
    
          // Determine initial denominator.
          // d is a power of 10 and the minimum max denominator that specifies the value exactly.
          e = d.e = s.length - x.e - 1;
          d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp];
          md = !md || n.comparedTo(d) > 0 ? (e > 0 ? d : n1) : n;
    
          exp = MAX_EXP;
          MAX_EXP = 1 / 0;
          n = new BigNumber(s);
    
          // n0 = d1 = 0
          n0.c[0] = 0;
    
          for (; ;)  {
            q = div(n, d, 0, 1);
            d2 = d0.plus(q.times(d1));
            if (d2.comparedTo(md) == 1) break;
            d0 = d1;
            d1 = d2;
            n1 = n0.plus(q.times(d2 = n1));
            n0 = d2;
            d = n.minus(q.times(d2 = d));
            n = d2;
          }
    
          d2 = div(md.minus(d0), d1, 0, 1);
          n0 = n0.plus(d2.times(n1));
          d0 = d0.plus(d2.times(d1));
          n0.s = n1.s = x.s;
          e = e * 2;
    
          // Determine which fraction is closer to x, n0/d0 or n1/d1
          r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo(
              div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0];
    
          MAX_EXP = exp;
    
          return r;
        };
    
    
        /*
         * Return the value of this BigNumber converted to a number primitive.
         */
        P.toNumber = function () {
          return +valueOf(this);
        };
    
    
        /*
         * Return a string representing the value of this BigNumber rounded to sd significant digits
         * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits
         * necessary to represent the integer part of the value in fixed-point notation, then use
         * exponential notation.
         *
         * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.
         * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
         *
         * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
         */
        P.toPrecision = function (sd, rm) {
          if (sd != null) intCheck(sd, 1, MAX);
          return format(this, sd, rm, 2);
        };
    
    
        /*
         * Return a string representing the value of this BigNumber in base b, or base 10 if b is
         * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and
         * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent
         * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than
         * TO_EXP_NEG, return exponential notation.
         *
         * [b] {number} Integer, 2 to ALPHABET.length inclusive.
         *
         * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
         */
        P.toString = function (b) {
          var str,
            n = this,
            s = n.s,
            e = n.e;
    
          // Infinity or NaN?
          if (e === null) {
            if (s) {
              str = 'Infinity';
              if (s < 0) str = '-' + str;
            } else {
              str = 'NaN';
            }
          } else {
            if (b == null) {
              str = e <= TO_EXP_NEG || e >= TO_EXP_POS
               ? toExponential(coeffToString(n.c), e)
               : toFixedPoint(coeffToString(n.c), e, '0');
            } else if (b === 10 && alphabetHasNormalDecimalDigits) {
              n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE);
              str = toFixedPoint(coeffToString(n.c), n.e, '0');
            } else {
              intCheck(b, 2, ALPHABET.length, 'Base');
              str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true);
            }
    
            if (s < 0 && n.c[0]) str = '-' + str;
          }
    
          return str;
        };
    
    
        /*
         * Return as toString, but do not accept a base argument, and include the minus sign for
         * negative zero.
         */
        P.valueOf = P.toJSON = function () {
          return valueOf(this);
        };
    
    
        P._isBigNumber = true;
    
        if (configObject != null) BigNumber.set(configObject);
    
        return BigNumber;
      }
    
    
      // PRIVATE HELPER FUNCTIONS
    
      // These functions don't need access to variables,
      // e.g. DECIMAL_PLACES, in the scope of the `clone` function above.
    
    
      function bitFloor(n) {
        var i = n | 0;
        return n > 0 || n === i ? i : i - 1;
      }
    
    
      // Return a coefficient array as a string of base 10 digits.
      function coeffToString(a) {
        var s, z,
          i = 1,
          j = a.length,
          r = a[0] + '';
    
        for (; i < j;) {
          s = a[i++] + '';
          z = LOG_BASE - s.length;
          for (; z--; s = '0' + s);
          r += s;
        }
    
        // Determine trailing zeros.
        for (j = r.length; r.charCodeAt(--j) === 48;);
    
        return r.slice(0, j + 1 || 1);
      }
    
    
      // Compare the value of BigNumbers x and y.
      function compare(x, y) {
        var a, b,
          xc = x.c,
          yc = y.c,
          i = x.s,
          j = y.s,
          k = x.e,
          l = y.e;
    
        // Either NaN?
        if (!i || !j) return null;
    
        a = xc && !xc[0];
        b = yc && !yc[0];
    
        // Either zero?
        if (a || b) return a ? b ? 0 : -j : i;
    
        // Signs differ?
        if (i != j) return i;
    
        a = i < 0;
        b = k == l;
    
        // Either Infinity?
        if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1;
    
        // Compare exponents.
        if (!b) return k > l ^ a ? 1 : -1;
    
        j = (k = xc.length) < (l = yc.length) ? k : l;
    
        // Compare digit by digit.
        for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1;
    
        // Compare lengths.
        return k == l ? 0 : k > l ^ a ? 1 : -1;
      }
    
    
      /*
       * Check that n is a primitive number, an integer, and in range, otherwise throw.
       */
      function intCheck(n, min, max, name) {
        if (n < min || n > max || n !== mathfloor(n)) {
          throw Error
           (bignumberError + (name || 'Argument') + (typeof n == 'number'
             ? n < min || n > max ? ' out of range: ' : ' not an integer: '
             : ' not a primitive number: ') + String(n));
        }
      }
    
    
      // Assumes finite n.
      function isOdd(n) {
        var k = n.c.length - 1;
        return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0;
      }
    
    
      function toExponential(str, e) {
        return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) +
         (e < 0 ? 'e' : 'e+') + e;
      }
    
    
      function toFixedPoint(str, e, z) {
        var len, zs;
    
        // Negative exponent?
        if (e < 0) {
    
          // Prepend zeros.
          for (zs = z + '.'; ++e; zs += z);
          str = zs + str;
    
        // Positive exponent
        } else {
          len = str.length;
    
          // Append zeros.
          if (++e > len) {
            for (zs = z, e -= len; --e; zs += z);
            str += zs;
          } else if (e < len) {
            str = str.slice(0, e) + '.' + str.slice(e);
          }
        }
    
        return str;
      }
    
    
      // EXPORT
    
    
      BigNumber = clone();
      BigNumber['default'] = BigNumber.BigNumber = BigNumber;
    
      // AMD.
      if (typeof define == 'function' && define.amd) {
        define(function () { return BigNumber; });
    
      // Node.js and other environments that support module.exports.
      } else if (typeof module != 'undefined' && module.exports) {
        module.exports = BigNumber;
    
      // Browser.
      } else {
        if (!globalObject) {
          globalObject = typeof self != 'undefined' && self ? self : window;
        }
    
        globalObject.BigNumber = BigNumber;
      }
    })(this);
    
    },{}],33:[function(require,module,exports){
    (function (module, exports) {
      'use strict';
    
      // Utils
      function assert (val, msg) {
        if (!val) throw new Error(msg || 'Assertion failed');
      }
    
      // Could use `inherits` module, but don't want to move from single file
      // architecture yet.
      function inherits (ctor, superCtor) {
        ctor.super_ = superCtor;
        var TempCtor = function () {};
        TempCtor.prototype = superCtor.prototype;
        ctor.prototype = new TempCtor();
        ctor.prototype.constructor = ctor;
      }
    
      // BN
    
      function BN (number, base, endian) {
        if (BN.isBN(number)) {
          return number;
        }
    
        this.negative = 0;
        this.words = null;
        this.length = 0;
    
        // Reduction context
        this.red = null;
    
        if (number !== null) {
          if (base === 'le' || base === 'be') {
            endian = base;
            base = 10;
          }
    
          this._init(number || 0, base || 10, endian || 'be');
        }
      }
      if (typeof module === 'object') {
        module.exports = BN;
      } else {
        exports.BN = BN;
      }
    
      BN.BN = BN;
      BN.wordSize = 26;
    
      var Buffer;
      try {
        if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') {
          Buffer = window.Buffer;
        } else {
          Buffer = require('buffer').Buffer;
        }
      } catch (e) {
      }
    
      BN.isBN = function isBN (num) {
        if (num instanceof BN) {
          return true;
        }
    
        return num !== null && typeof num === 'object' &&
          num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
      };
    
      BN.max = function max (left, right) {
        if (left.cmp(right) > 0) return left;
        return right;
      };
    
      BN.min = function min (left, right) {
        if (left.cmp(right) < 0) return left;
        return right;
      };
    
      BN.prototype._init = function init (number, base, endian) {
        if (typeof number === 'number') {
          return this._initNumber(number, base, endian);
        }
    
        if (typeof number === 'object') {
          return this._initArray(number, base, endian);
        }
    
        if (base === 'hex') {
          base = 16;
        }
        assert(base === (base | 0) && base >= 2 && base <= 36);
    
        number = number.toString().replace(/\s+/g, '');
        var start = 0;
        if (number[0] === '-') {
          start++;
          this.negative = 1;
        }
    
        if (start < number.length) {
          if (base === 16) {
            this._parseHex(number, start, endian);
          } else {
            this._parseBase(number, base, start);
            if (endian === 'le') {
              this._initArray(this.toArray(), base, endian);
            }
          }
        }
      };
    
      BN.prototype._initNumber = function _initNumber (number, base, endian) {
        if (number < 0) {
          this.negative = 1;
          number = -number;
        }
        if (number < 0x4000000) {
          this.words = [ number & 0x3ffffff ];
          this.length = 1;
        } else if (number < 0x10000000000000) {
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff
          ];
          this.length = 2;
        } else {
          assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff,
            1
          ];
          this.length = 3;
        }
    
        if (endian !== 'le') return;
    
        // Reverse the bytes
        this._initArray(this.toArray(), base, endian);
      };
    
      BN.prototype._initArray = function _initArray (number, base, endian) {
        // Perhaps a Uint8Array
        assert(typeof number.length === 'number');
        if (number.length <= 0) {
          this.words = [ 0 ];
          this.length = 1;
          return this;
        }
    
        this.length = Math.ceil(number.length / 3);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        var j, w;
        var off = 0;
        if (endian === 'be') {
          for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
            w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        } else if (endian === 'le') {
          for (i = 0, j = 0; i < number.length; i += 3) {
            w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        }
        return this.strip();
      };
    
      function parseHex4Bits (string, index) {
        var c = string.charCodeAt(index);
        // 'A' - 'F'
        if (c >= 65 && c <= 70) {
          return c - 55;
        // 'a' - 'f'
        } else if (c >= 97 && c <= 102) {
          return c - 87;
        // '0' - '9'
        } else {
          return (c - 48) & 0xf;
        }
      }
    
      function parseHexByte (string, lowerBound, index) {
        var r = parseHex4Bits(string, index);
        if (index - 1 >= lowerBound) {
          r |= parseHex4Bits(string, index - 1) << 4;
        }
        return r;
      }
    
      BN.prototype._parseHex = function _parseHex (number, start, endian) {
        // Create possibly bigger array to ensure that it fits the number
        this.length = Math.ceil((number.length - start) / 6);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        // 24-bits chunks
        var off = 0;
        var j = 0;
    
        var w;
        if (endian === 'be') {
          for (i = number.length - 1; i >= start; i -= 2) {
            w = parseHexByte(number, start, i) << off;
            this.words[j] |= w & 0x3ffffff;
            if (off >= 18) {
              off -= 18;
              j += 1;
              this.words[j] |= w >>> 26;
            } else {
              off += 8;
            }
          }
        } else {
          var parseLength = number.length - start;
          for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) {
            w = parseHexByte(number, start, i) << off;
            this.words[j] |= w & 0x3ffffff;
            if (off >= 18) {
              off -= 18;
              j += 1;
              this.words[j] |= w >>> 26;
            } else {
              off += 8;
            }
          }
        }
    
        this.strip();
      };
    
      function parseBase (str, start, end, mul) {
        var r = 0;
        var len = Math.min(str.length, end);
        for (var i = start; i < len; i++) {
          var c = str.charCodeAt(i) - 48;
    
          r *= mul;
    
          // 'a'
          if (c >= 49) {
            r += c - 49 + 0xa;
    
          // 'A'
          } else if (c >= 17) {
            r += c - 17 + 0xa;
    
          // '0' - '9'
          } else {
            r += c;
          }
        }
        return r;
      }
    
      BN.prototype._parseBase = function _parseBase (number, base, start) {
        // Initialize as zero
        this.words = [ 0 ];
        this.length = 1;
    
        // Find length of limb in base
        for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
          limbLen++;
        }
        limbLen--;
        limbPow = (limbPow / base) | 0;
    
        var total = number.length - start;
        var mod = total % limbLen;
        var end = Math.min(total, total - mod) + start;
    
        var word = 0;
        for (var i = start; i < end; i += limbLen) {
          word = parseBase(number, i, i + limbLen, base);
    
          this.imuln(limbPow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
    
        if (mod !== 0) {
          var pow = 1;
          word = parseBase(number, i, number.length, base);
    
          for (i = 0; i < mod; i++) {
            pow *= base;
          }
    
          this.imuln(pow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
    
        this.strip();
      };
    
      BN.prototype.copy = function copy (dest) {
        dest.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          dest.words[i] = this.words[i];
        }
        dest.length = this.length;
        dest.negative = this.negative;
        dest.red = this.red;
      };
    
      BN.prototype.clone = function clone () {
        var r = new BN(null);
        this.copy(r);
        return r;
      };
    
      BN.prototype._expand = function _expand (size) {
        while (this.length < size) {
          this.words[this.length++] = 0;
        }
        return this;
      };
    
      // Remove leading `0` from `this`
      BN.prototype.strip = function strip () {
        while (this.length > 1 && this.words[this.length - 1] === 0) {
          this.length--;
        }
        return this._normSign();
      };
    
      BN.prototype._normSign = function _normSign () {
        // -0 = 0
        if (this.length === 1 && this.words[0] === 0) {
          this.negative = 0;
        }
        return this;
      };
    
      BN.prototype.inspect = function inspect () {
        return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
      };
    
      /*
    
      var zeros = [];
      var groupSizes = [];
      var groupBases = [];
    
      var s = '';
      var i = -1;
      while (++i < BN.wordSize) {
        zeros[i] = s;
        s += '0';
      }
      groupSizes[0] = 0;
      groupSizes[1] = 0;
      groupBases[0] = 0;
      groupBases[1] = 0;
      var base = 2 - 1;
      while (++base < 36 + 1) {
        var groupSize = 0;
        var groupBase = 1;
        while (groupBase < (1 << BN.wordSize) / base) {
          groupBase *= base;
          groupSize += 1;
        }
        groupSizes[base] = groupSize;
        groupBases[base] = groupBase;
      }
    
      */
    
      var zeros = [
        '',
        '0',
        '00',
        '000',
        '0000',
        '00000',
        '000000',
        '0000000',
        '00000000',
        '000000000',
        '0000000000',
        '00000000000',
        '000000000000',
        '0000000000000',
        '00000000000000',
        '000000000000000',
        '0000000000000000',
        '00000000000000000',
        '000000000000000000',
        '0000000000000000000',
        '00000000000000000000',
        '000000000000000000000',
        '0000000000000000000000',
        '00000000000000000000000',
        '000000000000000000000000',
        '0000000000000000000000000'
      ];
    
      var groupSizes = [
        0, 0,
        25, 16, 12, 11, 10, 9, 8,
        8, 7, 7, 7, 7, 6, 6,
        6, 6, 6, 6, 6, 5, 5,
        5, 5, 5, 5, 5, 5, 5,
        5, 5, 5, 5, 5, 5, 5
      ];
    
      var groupBases = [
        0, 0,
        33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
        43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
        16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
        6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
        24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
      ];
    
      BN.prototype.toString = function toString (base, padding) {
        base = base || 10;
        padding = padding | 0 || 1;
    
        var out;
        if (base === 16 || base === 'hex') {
          out = '';
          var off = 0;
          var carry = 0;
          for (var i = 0; i < this.length; i++) {
            var w = this.words[i];
            var word = (((w << off) | carry) & 0xffffff).toString(16);
            carry = (w >>> (24 - off)) & 0xffffff;
            if (carry !== 0 || i !== this.length - 1) {
              out = zeros[6 - word.length] + word + out;
            } else {
              out = word + out;
            }
            off += 2;
            if (off >= 26) {
              off -= 26;
              i--;
            }
          }
          if (carry !== 0) {
            out = carry.toString(16) + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        if (base === (base | 0) && base >= 2 && base <= 36) {
          // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
          var groupSize = groupSizes[base];
          // var groupBase = Math.pow(base, groupSize);
          var groupBase = groupBases[base];
          out = '';
          var c = this.clone();
          c.negative = 0;
          while (!c.isZero()) {
            var r = c.modn(groupBase).toString(base);
            c = c.idivn(groupBase);
    
            if (!c.isZero()) {
              out = zeros[groupSize - r.length] + r + out;
            } else {
              out = r + out;
            }
          }
          if (this.isZero()) {
            out = '0' + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        assert(false, 'Base should be between 2 and 36');
      };
    
      BN.prototype.toNumber = function toNumber () {
        var ret = this.words[0];
        if (this.length === 2) {
          ret += this.words[1] * 0x4000000;
        } else if (this.length === 3 && this.words[2] === 0x01) {
          // NOTE: at this stage it is known that the top bit is set
          ret += 0x10000000000000 + (this.words[1] * 0x4000000);
        } else if (this.length > 2) {
          assert(false, 'Number can only safely store up to 53 bits');
        }
        return (this.negative !== 0) ? -ret : ret;
      };
    
      BN.prototype.toJSON = function toJSON () {
        return this.toString(16);
      };
    
      BN.prototype.toBuffer = function toBuffer (endian, length) {
        assert(typeof Buffer !== 'undefined');
        return this.toArrayLike(Buffer, endian, length);
      };
    
      BN.prototype.toArray = function toArray (endian, length) {
        return this.toArrayLike(Array, endian, length);
      };
    
      BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
        var byteLength = this.byteLength();
        var reqLength = length || Math.max(1, byteLength);
        assert(byteLength <= reqLength, 'byte array longer than desired length');
        assert(reqLength > 0, 'Requested array length <= 0');
    
        this.strip();
        var littleEndian = endian === 'le';
        var res = new ArrayType(reqLength);
    
        var b, i;
        var q = this.clone();
        if (!littleEndian) {
          // Assume big-endian
          for (i = 0; i < reqLength - byteLength; i++) {
            res[i] = 0;
          }
    
          for (i = 0; !q.isZero(); i++) {
            b = q.andln(0xff);
            q.iushrn(8);
    
            res[reqLength - i - 1] = b;
          }
        } else {
          for (i = 0; !q.isZero(); i++) {
            b = q.andln(0xff);
            q.iushrn(8);
    
            res[i] = b;
          }
    
          for (; i < reqLength; i++) {
            res[i] = 0;
          }
        }
    
        return res;
      };
    
      if (Math.clz32) {
        BN.prototype._countBits = function _countBits (w) {
          return 32 - Math.clz32(w);
        };
      } else {
        BN.prototype._countBits = function _countBits (w) {
          var t = w;
          var r = 0;
          if (t >= 0x1000) {
            r += 13;
            t >>>= 13;
          }
          if (t >= 0x40) {
            r += 7;
            t >>>= 7;
          }
          if (t >= 0x8) {
            r += 4;
            t >>>= 4;
          }
          if (t >= 0x02) {
            r += 2;
            t >>>= 2;
          }
          return r + t;
        };
      }
    
      BN.prototype._zeroBits = function _zeroBits (w) {
        // Short-cut
        if (w === 0) return 26;
    
        var t = w;
        var r = 0;
        if ((t & 0x1fff) === 0) {
          r += 13;
          t >>>= 13;
        }
        if ((t & 0x7f) === 0) {
          r += 7;
          t >>>= 7;
        }
        if ((t & 0xf) === 0) {
          r += 4;
          t >>>= 4;
        }
        if ((t & 0x3) === 0) {
          r += 2;
          t >>>= 2;
        }
        if ((t & 0x1) === 0) {
          r++;
        }
        return r;
      };
    
      // Return number of used bits in a BN
      BN.prototype.bitLength = function bitLength () {
        var w = this.words[this.length - 1];
        var hi = this._countBits(w);
        return (this.length - 1) * 26 + hi;
      };
    
      function toBitArray (num) {
        var w = new Array(num.bitLength());
    
        for (var bit = 0; bit < w.length; bit++) {
          var off = (bit / 26) | 0;
          var wbit = bit % 26;
    
          w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
        }
    
        return w;
      }
    
      // Number of trailing zero bits
      BN.prototype.zeroBits = function zeroBits () {
        if (this.isZero()) return 0;
    
        var r = 0;
        for (var i = 0; i < this.length; i++) {
          var b = this._zeroBits(this.words[i]);
          r += b;
          if (b !== 26) break;
        }
        return r;
      };
    
      BN.prototype.byteLength = function byteLength () {
        return Math.ceil(this.bitLength() / 8);
      };
    
      BN.prototype.toTwos = function toTwos (width) {
        if (this.negative !== 0) {
          return this.abs().inotn(width).iaddn(1);
        }
        return this.clone();
      };
    
      BN.prototype.fromTwos = function fromTwos (width) {
        if (this.testn(width - 1)) {
          return this.notn(width).iaddn(1).ineg();
        }
        return this.clone();
      };
    
      BN.prototype.isNeg = function isNeg () {
        return this.negative !== 0;
      };
    
      // Return negative clone of `this`
      BN.prototype.neg = function neg () {
        return this.clone().ineg();
      };
    
      BN.prototype.ineg = function ineg () {
        if (!this.isZero()) {
          this.negative ^= 1;
        }
    
        return this;
      };
    
      // Or `num` with `this` in-place
      BN.prototype.iuor = function iuor (num) {
        while (this.length < num.length) {
          this.words[this.length++] = 0;
        }
    
        for (var i = 0; i < num.length; i++) {
          this.words[i] = this.words[i] | num.words[i];
        }
    
        return this.strip();
      };
    
      BN.prototype.ior = function ior (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuor(num);
      };
    
      // Or `num` with `this`
      BN.prototype.or = function or (num) {
        if (this.length > num.length) return this.clone().ior(num);
        return num.clone().ior(this);
      };
    
      BN.prototype.uor = function uor (num) {
        if (this.length > num.length) return this.clone().iuor(num);
        return num.clone().iuor(this);
      };
    
      // And `num` with `this` in-place
      BN.prototype.iuand = function iuand (num) {
        // b = min-length(num, this)
        var b;
        if (this.length > num.length) {
          b = num;
        } else {
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = this.words[i] & num.words[i];
        }
    
        this.length = b.length;
    
        return this.strip();
      };
    
      BN.prototype.iand = function iand (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuand(num);
      };
    
      // And `num` with `this`
      BN.prototype.and = function and (num) {
        if (this.length > num.length) return this.clone().iand(num);
        return num.clone().iand(this);
      };
    
      BN.prototype.uand = function uand (num) {
        if (this.length > num.length) return this.clone().iuand(num);
        return num.clone().iuand(this);
      };
    
      // Xor `num` with `this` in-place
      BN.prototype.iuxor = function iuxor (num) {
        // a.length > b.length
        var a;
        var b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = a.words[i] ^ b.words[i];
        }
    
        if (this !== a) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = a.length;
    
        return this.strip();
      };
    
      BN.prototype.ixor = function ixor (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuxor(num);
      };
    
      // Xor `num` with `this`
      BN.prototype.xor = function xor (num) {
        if (this.length > num.length) return this.clone().ixor(num);
        return num.clone().ixor(this);
      };
    
      BN.prototype.uxor = function uxor (num) {
        if (this.length > num.length) return this.clone().iuxor(num);
        return num.clone().iuxor(this);
      };
    
      // Not ``this`` with ``width`` bitwidth
      BN.prototype.inotn = function inotn (width) {
        assert(typeof width === 'number' && width >= 0);
    
        var bytesNeeded = Math.ceil(width / 26) | 0;
        var bitsLeft = width % 26;
    
        // Extend the buffer with leading zeroes
        this._expand(bytesNeeded);
    
        if (bitsLeft > 0) {
          bytesNeeded--;
        }
    
        // Handle complete words
        for (var i = 0; i < bytesNeeded; i++) {
          this.words[i] = ~this.words[i] & 0x3ffffff;
        }
    
        // Handle the residue
        if (bitsLeft > 0) {
          this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
        }
    
        // And remove leading zeroes
        return this.strip();
      };
    
      BN.prototype.notn = function notn (width) {
        return this.clone().inotn(width);
      };
    
      // Set `bit` of `this`
      BN.prototype.setn = function setn (bit, val) {
        assert(typeof bit === 'number' && bit >= 0);
    
        var off = (bit / 26) | 0;
        var wbit = bit % 26;
    
        this._expand(off + 1);
    
        if (val) {
          this.words[off] = this.words[off] | (1 << wbit);
        } else {
          this.words[off] = this.words[off] & ~(1 << wbit);
        }
    
        return this.strip();
      };
    
      // Add `num` to `this` in-place
      BN.prototype.iadd = function iadd (num) {
        var r;
    
        // negative + positive
        if (this.negative !== 0 && num.negative === 0) {
          this.negative = 0;
          r = this.isub(num);
          this.negative ^= 1;
          return this._normSign();
    
        // positive + negative
        } else if (this.negative === 0 && num.negative !== 0) {
          num.negative = 0;
          r = this.isub(num);
          num.negative = 1;
          return r._normSign();
        }
    
        // a.length > b.length
        var a, b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
    
        this.length = a.length;
        if (carry !== 0) {
          this.words[this.length] = carry;
          this.length++;
        // Copy the rest of the words
        } else if (a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        return this;
      };
    
      // Add `num` to `this`
      BN.prototype.add = function add (num) {
        var res;
        if (num.negative !== 0 && this.negative === 0) {
          num.negative = 0;
          res = this.sub(num);
          num.negative ^= 1;
          return res;
        } else if (num.negative === 0 && this.negative !== 0) {
          this.negative = 0;
          res = num.sub(this);
          this.negative = 1;
          return res;
        }
    
        if (this.length > num.length) return this.clone().iadd(num);
    
        return num.clone().iadd(this);
      };
    
      // Subtract `num` from `this` in-place
      BN.prototype.isub = function isub (num) {
        // this - (-num) = this + num
        if (num.negative !== 0) {
          num.negative = 0;
          var r = this.iadd(num);
          num.negative = 1;
          return r._normSign();
    
        // -this - num = -(this + num)
        } else if (this.negative !== 0) {
          this.negative = 0;
          this.iadd(num);
          this.negative = 1;
          return this._normSign();
        }
    
        // At this point both numbers are positive
        var cmp = this.cmp(num);
    
        // Optimization - zeroify
        if (cmp === 0) {
          this.negative = 0;
          this.length = 1;
          this.words[0] = 0;
          return this;
        }
    
        // a > b
        var a, b;
        if (cmp > 0) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
    
        // Copy rest of the words
        if (carry === 0 && i < a.length && a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = Math.max(this.length, i);
    
        if (a !== this) {
          this.negative = 1;
        }
    
        return this.strip();
      };
    
      // Subtract `num` from `this`
      BN.prototype.sub = function sub (num) {
        return this.clone().isub(num);
      };
    
      function smallMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        var len = (self.length + num.length) | 0;
        out.length = len;
        len = (len - 1) | 0;
    
        // Peel one iteration (compiler can't do it, because of code complexity)
        var a = self.words[0] | 0;
        var b = num.words[0] | 0;
        var r = a * b;
    
        var lo = r & 0x3ffffff;
        var carry = (r / 0x4000000) | 0;
        out.words[0] = lo;
    
        for (var k = 1; k < len; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = carry >>> 26;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = (k - j) | 0;
            a = self.words[i] | 0;
            b = num.words[j] | 0;
            r = a * b + rword;
            ncarry += (r / 0x4000000) | 0;
            rword = r & 0x3ffffff;
          }
          out.words[k] = rword | 0;
          carry = ncarry | 0;
        }
        if (carry !== 0) {
          out.words[k] = carry | 0;
        } else {
          out.length--;
        }
    
        return out.strip();
      }
    
      // TODO(indutny): it may be reasonable to omit it for users who don't need
      // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
      // multiplication (like elliptic secp256k1).
      var comb10MulTo = function comb10MulTo (self, num, out) {
        var a = self.words;
        var b = num.words;
        var o = out.words;
        var c = 0;
        var lo;
        var mid;
        var hi;
        var a0 = a[0] | 0;
        var al0 = a0 & 0x1fff;
        var ah0 = a0 >>> 13;
        var a1 = a[1] | 0;
        var al1 = a1 & 0x1fff;
        var ah1 = a1 >>> 13;
        var a2 = a[2] | 0;
        var al2 = a2 & 0x1fff;
        var ah2 = a2 >>> 13;
        var a3 = a[3] | 0;
        var al3 = a3 & 0x1fff;
        var ah3 = a3 >>> 13;
        var a4 = a[4] | 0;
        var al4 = a4 & 0x1fff;
        var ah4 = a4 >>> 13;
        var a5 = a[5] | 0;
        var al5 = a5 & 0x1fff;
        var ah5 = a5 >>> 13;
        var a6 = a[6] | 0;
        var al6 = a6 & 0x1fff;
        var ah6 = a6 >>> 13;
        var a7 = a[7] | 0;
        var al7 = a7 & 0x1fff;
        var ah7 = a7 >>> 13;
        var a8 = a[8] | 0;
        var al8 = a8 & 0x1fff;
        var ah8 = a8 >>> 13;
        var a9 = a[9] | 0;
        var al9 = a9 & 0x1fff;
        var ah9 = a9 >>> 13;
        var b0 = b[0] | 0;
        var bl0 = b0 & 0x1fff;
        var bh0 = b0 >>> 13;
        var b1 = b[1] | 0;
        var bl1 = b1 & 0x1fff;
        var bh1 = b1 >>> 13;
        var b2 = b[2] | 0;
        var bl2 = b2 & 0x1fff;
        var bh2 = b2 >>> 13;
        var b3 = b[3] | 0;
        var bl3 = b3 & 0x1fff;
        var bh3 = b3 >>> 13;
        var b4 = b[4] | 0;
        var bl4 = b4 & 0x1fff;
        var bh4 = b4 >>> 13;
        var b5 = b[5] | 0;
        var bl5 = b5 & 0x1fff;
        var bh5 = b5 >>> 13;
        var b6 = b[6] | 0;
        var bl6 = b6 & 0x1fff;
        var bh6 = b6 >>> 13;
        var b7 = b[7] | 0;
        var bl7 = b7 & 0x1fff;
        var bh7 = b7 >>> 13;
        var b8 = b[8] | 0;
        var bl8 = b8 & 0x1fff;
        var bh8 = b8 >>> 13;
        var b9 = b[9] | 0;
        var bl9 = b9 & 0x1fff;
        var bh9 = b9 >>> 13;
    
        out.negative = self.negative ^ num.negative;
        out.length = 19;
        /* k = 0 */
        lo = Math.imul(al0, bl0);
        mid = Math.imul(al0, bh0);
        mid = (mid + Math.imul(ah0, bl0)) | 0;
        hi = Math.imul(ah0, bh0);
        var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
        w0 &= 0x3ffffff;
        /* k = 1 */
        lo = Math.imul(al1, bl0);
        mid = Math.imul(al1, bh0);
        mid = (mid + Math.imul(ah1, bl0)) | 0;
        hi = Math.imul(ah1, bh0);
        lo = (lo + Math.imul(al0, bl1)) | 0;
        mid = (mid + Math.imul(al0, bh1)) | 0;
        mid = (mid + Math.imul(ah0, bl1)) | 0;
        hi = (hi + Math.imul(ah0, bh1)) | 0;
        var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
        w1 &= 0x3ffffff;
        /* k = 2 */
        lo = Math.imul(al2, bl0);
        mid = Math.imul(al2, bh0);
        mid = (mid + Math.imul(ah2, bl0)) | 0;
        hi = Math.imul(ah2, bh0);
        lo = (lo + Math.imul(al1, bl1)) | 0;
        mid = (mid + Math.imul(al1, bh1)) | 0;
        mid = (mid + Math.imul(ah1, bl1)) | 0;
        hi = (hi + Math.imul(ah1, bh1)) | 0;
        lo = (lo + Math.imul(al0, bl2)) | 0;
        mid = (mid + Math.imul(al0, bh2)) | 0;
        mid = (mid + Math.imul(ah0, bl2)) | 0;
        hi = (hi + Math.imul(ah0, bh2)) | 0;
        var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
        w2 &= 0x3ffffff;
        /* k = 3 */
        lo = Math.imul(al3, bl0);
        mid = Math.imul(al3, bh0);
        mid = (mid + Math.imul(ah3, bl0)) | 0;
        hi = Math.imul(ah3, bh0);
        lo = (lo + Math.imul(al2, bl1)) | 0;
        mid = (mid + Math.imul(al2, bh1)) | 0;
        mid = (mid + Math.imul(ah2, bl1)) | 0;
        hi = (hi + Math.imul(ah2, bh1)) | 0;
        lo = (lo + Math.imul(al1, bl2)) | 0;
        mid = (mid + Math.imul(al1, bh2)) | 0;
        mid = (mid + Math.imul(ah1, bl2)) | 0;
        hi = (hi + Math.imul(ah1, bh2)) | 0;
        lo = (lo + Math.imul(al0, bl3)) | 0;
        mid = (mid + Math.imul(al0, bh3)) | 0;
        mid = (mid + Math.imul(ah0, bl3)) | 0;
        hi = (hi + Math.imul(ah0, bh3)) | 0;
        var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
        w3 &= 0x3ffffff;
        /* k = 4 */
        lo = Math.imul(al4, bl0);
        mid = Math.imul(al4, bh0);
        mid = (mid + Math.imul(ah4, bl0)) | 0;
        hi = Math.imul(ah4, bh0);
        lo = (lo + Math.imul(al3, bl1)) | 0;
        mid = (mid + Math.imul(al3, bh1)) | 0;
        mid = (mid + Math.imul(ah3, bl1)) | 0;
        hi = (hi + Math.imul(ah3, bh1)) | 0;
        lo = (lo + Math.imul(al2, bl2)) | 0;
        mid = (mid + Math.imul(al2, bh2)) | 0;
        mid = (mid + Math.imul(ah2, bl2)) | 0;
        hi = (hi + Math.imul(ah2, bh2)) | 0;
        lo = (lo + Math.imul(al1, bl3)) | 0;
        mid = (mid + Math.imul(al1, bh3)) | 0;
        mid = (mid + Math.imul(ah1, bl3)) | 0;
        hi = (hi + Math.imul(ah1, bh3)) | 0;
        lo = (lo + Math.imul(al0, bl4)) | 0;
        mid = (mid + Math.imul(al0, bh4)) | 0;
        mid = (mid + Math.imul(ah0, bl4)) | 0;
        hi = (hi + Math.imul(ah0, bh4)) | 0;
        var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
        w4 &= 0x3ffffff;
        /* k = 5 */
        lo = Math.imul(al5, bl0);
        mid = Math.imul(al5, bh0);
        mid = (mid + Math.imul(ah5, bl0)) | 0;
        hi = Math.imul(ah5, bh0);
        lo = (lo + Math.imul(al4, bl1)) | 0;
        mid = (mid + Math.imul(al4, bh1)) | 0;
        mid = (mid + Math.imul(ah4, bl1)) | 0;
        hi = (hi + Math.imul(ah4, bh1)) | 0;
        lo = (lo + Math.imul(al3, bl2)) | 0;
        mid = (mid + Math.imul(al3, bh2)) | 0;
        mid = (mid + Math.imul(ah3, bl2)) | 0;
        hi = (hi + Math.imul(ah3, bh2)) | 0;
        lo = (lo + Math.imul(al2, bl3)) | 0;
        mid = (mid + Math.imul(al2, bh3)) | 0;
        mid = (mid + Math.imul(ah2, bl3)) | 0;
        hi = (hi + Math.imul(ah2, bh3)) | 0;
        lo = (lo + Math.imul(al1, bl4)) | 0;
        mid = (mid + Math.imul(al1, bh4)) | 0;
        mid = (mid + Math.imul(ah1, bl4)) | 0;
        hi = (hi + Math.imul(ah1, bh4)) | 0;
        lo = (lo + Math.imul(al0, bl5)) | 0;
        mid = (mid + Math.imul(al0, bh5)) | 0;
        mid = (mid + Math.imul(ah0, bl5)) | 0;
        hi = (hi + Math.imul(ah0, bh5)) | 0;
        var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
        w5 &= 0x3ffffff;
        /* k = 6 */
        lo = Math.imul(al6, bl0);
        mid = Math.imul(al6, bh0);
        mid = (mid + Math.imul(ah6, bl0)) | 0;
        hi = Math.imul(ah6, bh0);
        lo = (lo + Math.imul(al5, bl1)) | 0;
        mid = (mid + Math.imul(al5, bh1)) | 0;
        mid = (mid + Math.imul(ah5, bl1)) | 0;
        hi = (hi + Math.imul(ah5, bh1)) | 0;
        lo = (lo + Math.imul(al4, bl2)) | 0;
        mid = (mid + Math.imul(al4, bh2)) | 0;
        mid = (mid + Math.imul(ah4, bl2)) | 0;
        hi = (hi + Math.imul(ah4, bh2)) | 0;
        lo = (lo + Math.imul(al3, bl3)) | 0;
        mid = (mid + Math.imul(al3, bh3)) | 0;
        mid = (mid + Math.imul(ah3, bl3)) | 0;
        hi = (hi + Math.imul(ah3, bh3)) | 0;
        lo = (lo + Math.imul(al2, bl4)) | 0;
        mid = (mid + Math.imul(al2, bh4)) | 0;
        mid = (mid + Math.imul(ah2, bl4)) | 0;
        hi = (hi + Math.imul(ah2, bh4)) | 0;
        lo = (lo + Math.imul(al1, bl5)) | 0;
        mid = (mid + Math.imul(al1, bh5)) | 0;
        mid = (mid + Math.imul(ah1, bl5)) | 0;
        hi = (hi + Math.imul(ah1, bh5)) | 0;
        lo = (lo + Math.imul(al0, bl6)) | 0;
        mid = (mid + Math.imul(al0, bh6)) | 0;
        mid = (mid + Math.imul(ah0, bl6)) | 0;
        hi = (hi + Math.imul(ah0, bh6)) | 0;
        var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
        w6 &= 0x3ffffff;
        /* k = 7 */
        lo = Math.imul(al7, bl0);
        mid = Math.imul(al7, bh0);
        mid = (mid + Math.imul(ah7, bl0)) | 0;
        hi = Math.imul(ah7, bh0);
        lo = (lo + Math.imul(al6, bl1)) | 0;
        mid = (mid + Math.imul(al6, bh1)) | 0;
        mid = (mid + Math.imul(ah6, bl1)) | 0;
        hi = (hi + Math.imul(ah6, bh1)) | 0;
        lo = (lo + Math.imul(al5, bl2)) | 0;
        mid = (mid + Math.imul(al5, bh2)) | 0;
        mid = (mid + Math.imul(ah5, bl2)) | 0;
        hi = (hi + Math.imul(ah5, bh2)) | 0;
        lo = (lo + Math.imul(al4, bl3)) | 0;
        mid = (mid + Math.imul(al4, bh3)) | 0;
        mid = (mid + Math.imul(ah4, bl3)) | 0;
        hi = (hi + Math.imul(ah4, bh3)) | 0;
        lo = (lo + Math.imul(al3, bl4)) | 0;
        mid = (mid + Math.imul(al3, bh4)) | 0;
        mid = (mid + Math.imul(ah3, bl4)) | 0;
        hi = (hi + Math.imul(ah3, bh4)) | 0;
        lo = (lo + Math.imul(al2, bl5)) | 0;
        mid = (mid + Math.imul(al2, bh5)) | 0;
        mid = (mid + Math.imul(ah2, bl5)) | 0;
        hi = (hi + Math.imul(ah2, bh5)) | 0;
        lo = (lo + Math.imul(al1, bl6)) | 0;
        mid = (mid + Math.imul(al1, bh6)) | 0;
        mid = (mid + Math.imul(ah1, bl6)) | 0;
        hi = (hi + Math.imul(ah1, bh6)) | 0;
        lo = (lo + Math.imul(al0, bl7)) | 0;
        mid = (mid + Math.imul(al0, bh7)) | 0;
        mid = (mid + Math.imul(ah0, bl7)) | 0;
        hi = (hi + Math.imul(ah0, bh7)) | 0;
        var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
        w7 &= 0x3ffffff;
        /* k = 8 */
        lo = Math.imul(al8, bl0);
        mid = Math.imul(al8, bh0);
        mid = (mid + Math.imul(ah8, bl0)) | 0;
        hi = Math.imul(ah8, bh0);
        lo = (lo + Math.imul(al7, bl1)) | 0;
        mid = (mid + Math.imul(al7, bh1)) | 0;
        mid = (mid + Math.imul(ah7, bl1)) | 0;
        hi = (hi + Math.imul(ah7, bh1)) | 0;
        lo = (lo + Math.imul(al6, bl2)) | 0;
        mid = (mid + Math.imul(al6, bh2)) | 0;
        mid = (mid + Math.imul(ah6, bl2)) | 0;
        hi = (hi + Math.imul(ah6, bh2)) | 0;
        lo = (lo + Math.imul(al5, bl3)) | 0;
        mid = (mid + Math.imul(al5, bh3)) | 0;
        mid = (mid + Math.imul(ah5, bl3)) | 0;
        hi = (hi + Math.imul(ah5, bh3)) | 0;
        lo = (lo + Math.imul(al4, bl4)) | 0;
        mid = (mid + Math.imul(al4, bh4)) | 0;
        mid = (mid + Math.imul(ah4, bl4)) | 0;
        hi = (hi + Math.imul(ah4, bh4)) | 0;
        lo = (lo + Math.imul(al3, bl5)) | 0;
        mid = (mid + Math.imul(al3, bh5)) | 0;
        mid = (mid + Math.imul(ah3, bl5)) | 0;
        hi = (hi + Math.imul(ah3, bh5)) | 0;
        lo = (lo + Math.imul(al2, bl6)) | 0;
        mid = (mid + Math.imul(al2, bh6)) | 0;
        mid = (mid + Math.imul(ah2, bl6)) | 0;
        hi = (hi + Math.imul(ah2, bh6)) | 0;
        lo = (lo + Math.imul(al1, bl7)) | 0;
        mid = (mid + Math.imul(al1, bh7)) | 0;
        mid = (mid + Math.imul(ah1, bl7)) | 0;
        hi = (hi + Math.imul(ah1, bh7)) | 0;
        lo = (lo + Math.imul(al0, bl8)) | 0;
        mid = (mid + Math.imul(al0, bh8)) | 0;
        mid = (mid + Math.imul(ah0, bl8)) | 0;
        hi = (hi + Math.imul(ah0, bh8)) | 0;
        var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
        w8 &= 0x3ffffff;
        /* k = 9 */
        lo = Math.imul(al9, bl0);
        mid = Math.imul(al9, bh0);
        mid = (mid + Math.imul(ah9, bl0)) | 0;
        hi = Math.imul(ah9, bh0);
        lo = (lo + Math.imul(al8, bl1)) | 0;
        mid = (mid + Math.imul(al8, bh1)) | 0;
        mid = (mid + Math.imul(ah8, bl1)) | 0;
        hi = (hi + Math.imul(ah8, bh1)) | 0;
        lo = (lo + Math.imul(al7, bl2)) | 0;
        mid = (mid + Math.imul(al7, bh2)) | 0;
        mid = (mid + Math.imul(ah7, bl2)) | 0;
        hi = (hi + Math.imul(ah7, bh2)) | 0;
        lo = (lo + Math.imul(al6, bl3)) | 0;
        mid = (mid + Math.imul(al6, bh3)) | 0;
        mid = (mid + Math.imul(ah6, bl3)) | 0;
        hi = (hi + Math.imul(ah6, bh3)) | 0;
        lo = (lo + Math.imul(al5, bl4)) | 0;
        mid = (mid + Math.imul(al5, bh4)) | 0;
        mid = (mid + Math.imul(ah5, bl4)) | 0;
        hi = (hi + Math.imul(ah5, bh4)) | 0;
        lo = (lo + Math.imul(al4, bl5)) | 0;
        mid = (mid + Math.imul(al4, bh5)) | 0;
        mid = (mid + Math.imul(ah4, bl5)) | 0;
        hi = (hi + Math.imul(ah4, bh5)) | 0;
        lo = (lo + Math.imul(al3, bl6)) | 0;
        mid = (mid + Math.imul(al3, bh6)) | 0;
        mid = (mid + Math.imul(ah3, bl6)) | 0;
        hi = (hi + Math.imul(ah3, bh6)) | 0;
        lo = (lo + Math.imul(al2, bl7)) | 0;
        mid = (mid + Math.imul(al2, bh7)) | 0;
        mid = (mid + Math.imul(ah2, bl7)) | 0;
        hi = (hi + Math.imul(ah2, bh7)) | 0;
        lo = (lo + Math.imul(al1, bl8)) | 0;
        mid = (mid + Math.imul(al1, bh8)) | 0;
        mid = (mid + Math.imul(ah1, bl8)) | 0;
        hi = (hi + Math.imul(ah1, bh8)) | 0;
        lo = (lo + Math.imul(al0, bl9)) | 0;
        mid = (mid + Math.imul(al0, bh9)) | 0;
        mid = (mid + Math.imul(ah0, bl9)) | 0;
        hi = (hi + Math.imul(ah0, bh9)) | 0;
        var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
        w9 &= 0x3ffffff;
        /* k = 10 */
        lo = Math.imul(al9, bl1);
        mid = Math.imul(al9, bh1);
        mid = (mid + Math.imul(ah9, bl1)) | 0;
        hi = Math.imul(ah9, bh1);
        lo = (lo + Math.imul(al8, bl2)) | 0;
        mid = (mid + Math.imul(al8, bh2)) | 0;
        mid = (mid + Math.imul(ah8, bl2)) | 0;
        hi = (hi + Math.imul(ah8, bh2)) | 0;
        lo = (lo + Math.imul(al7, bl3)) | 0;
        mid = (mid + Math.imul(al7, bh3)) | 0;
        mid = (mid + Math.imul(ah7, bl3)) | 0;
        hi = (hi + Math.imul(ah7, bh3)) | 0;
        lo = (lo + Math.imul(al6, bl4)) | 0;
        mid = (mid + Math.imul(al6, bh4)) | 0;
        mid = (mid + Math.imul(ah6, bl4)) | 0;
        hi = (hi + Math.imul(ah6, bh4)) | 0;
        lo = (lo + Math.imul(al5, bl5)) | 0;
        mid = (mid + Math.imul(al5, bh5)) | 0;
        mid = (mid + Math.imul(ah5, bl5)) | 0;
        hi = (hi + Math.imul(ah5, bh5)) | 0;
        lo = (lo + Math.imul(al4, bl6)) | 0;
        mid = (mid + Math.imul(al4, bh6)) | 0;
        mid = (mid + Math.imul(ah4, bl6)) | 0;
        hi = (hi + Math.imul(ah4, bh6)) | 0;
        lo = (lo + Math.imul(al3, bl7)) | 0;
        mid = (mid + Math.imul(al3, bh7)) | 0;
        mid = (mid + Math.imul(ah3, bl7)) | 0;
        hi = (hi + Math.imul(ah3, bh7)) | 0;
        lo = (lo + Math.imul(al2, bl8)) | 0;
        mid = (mid + Math.imul(al2, bh8)) | 0;
        mid = (mid + Math.imul(ah2, bl8)) | 0;
        hi = (hi + Math.imul(ah2, bh8)) | 0;
        lo = (lo + Math.imul(al1, bl9)) | 0;
        mid = (mid + Math.imul(al1, bh9)) | 0;
        mid = (mid + Math.imul(ah1, bl9)) | 0;
        hi = (hi + Math.imul(ah1, bh9)) | 0;
        var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
        w10 &= 0x3ffffff;
        /* k = 11 */
        lo = Math.imul(al9, bl2);
        mid = Math.imul(al9, bh2);
        mid = (mid + Math.imul(ah9, bl2)) | 0;
        hi = Math.imul(ah9, bh2);
        lo = (lo + Math.imul(al8, bl3)) | 0;
        mid = (mid + Math.imul(al8, bh3)) | 0;
        mid = (mid + Math.imul(ah8, bl3)) | 0;
        hi = (hi + Math.imul(ah8, bh3)) | 0;
        lo = (lo + Math.imul(al7, bl4)) | 0;
        mid = (mid + Math.imul(al7, bh4)) | 0;
        mid = (mid + Math.imul(ah7, bl4)) | 0;
        hi = (hi + Math.imul(ah7, bh4)) | 0;
        lo = (lo + Math.imul(al6, bl5)) | 0;
        mid = (mid + Math.imul(al6, bh5)) | 0;
        mid = (mid + Math.imul(ah6, bl5)) | 0;
        hi = (hi + Math.imul(ah6, bh5)) | 0;
        lo = (lo + Math.imul(al5, bl6)) | 0;
        mid = (mid + Math.imul(al5, bh6)) | 0;
        mid = (mid + Math.imul(ah5, bl6)) | 0;
        hi = (hi + Math.imul(ah5, bh6)) | 0;
        lo = (lo + Math.imul(al4, bl7)) | 0;
        mid = (mid + Math.imul(al4, bh7)) | 0;
        mid = (mid + Math.imul(ah4, bl7)) | 0;
        hi = (hi + Math.imul(ah4, bh7)) | 0;
        lo = (lo + Math.imul(al3, bl8)) | 0;
        mid = (mid + Math.imul(al3, bh8)) | 0;
        mid = (mid + Math.imul(ah3, bl8)) | 0;
        hi = (hi + Math.imul(ah3, bh8)) | 0;
        lo = (lo + Math.imul(al2, bl9)) | 0;
        mid = (mid + Math.imul(al2, bh9)) | 0;
        mid = (mid + Math.imul(ah2, bl9)) | 0;
        hi = (hi + Math.imul(ah2, bh9)) | 0;
        var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
        w11 &= 0x3ffffff;
        /* k = 12 */
        lo = Math.imul(al9, bl3);
        mid = Math.imul(al9, bh3);
        mid = (mid + Math.imul(ah9, bl3)) | 0;
        hi = Math.imul(ah9, bh3);
        lo = (lo + Math.imul(al8, bl4)) | 0;
        mid = (mid + Math.imul(al8, bh4)) | 0;
        mid = (mid + Math.imul(ah8, bl4)) | 0;
        hi = (hi + Math.imul(ah8, bh4)) | 0;
        lo = (lo + Math.imul(al7, bl5)) | 0;
        mid = (mid + Math.imul(al7, bh5)) | 0;
        mid = (mid + Math.imul(ah7, bl5)) | 0;
        hi = (hi + Math.imul(ah7, bh5)) | 0;
        lo = (lo + Math.imul(al6, bl6)) | 0;
        mid = (mid + Math.imul(al6, bh6)) | 0;
        mid = (mid + Math.imul(ah6, bl6)) | 0;
        hi = (hi + Math.imul(ah6, bh6)) | 0;
        lo = (lo + Math.imul(al5, bl7)) | 0;
        mid = (mid + Math.imul(al5, bh7)) | 0;
        mid = (mid + Math.imul(ah5, bl7)) | 0;
        hi = (hi + Math.imul(ah5, bh7)) | 0;
        lo = (lo + Math.imul(al4, bl8)) | 0;
        mid = (mid + Math.imul(al4, bh8)) | 0;
        mid = (mid + Math.imul(ah4, bl8)) | 0;
        hi = (hi + Math.imul(ah4, bh8)) | 0;
        lo = (lo + Math.imul(al3, bl9)) | 0;
        mid = (mid + Math.imul(al3, bh9)) | 0;
        mid = (mid + Math.imul(ah3, bl9)) | 0;
        hi = (hi + Math.imul(ah3, bh9)) | 0;
        var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
        w12 &= 0x3ffffff;
        /* k = 13 */
        lo = Math.imul(al9, bl4);
        mid = Math.imul(al9, bh4);
        mid = (mid + Math.imul(ah9, bl4)) | 0;
        hi = Math.imul(ah9, bh4);
        lo = (lo + Math.imul(al8, bl5)) | 0;
        mid = (mid + Math.imul(al8, bh5)) | 0;
        mid = (mid + Math.imul(ah8, bl5)) | 0;
        hi = (hi + Math.imul(ah8, bh5)) | 0;
        lo = (lo + Math.imul(al7, bl6)) | 0;
        mid = (mid + Math.imul(al7, bh6)) | 0;
        mid = (mid + Math.imul(ah7, bl6)) | 0;
        hi = (hi + Math.imul(ah7, bh6)) | 0;
        lo = (lo + Math.imul(al6, bl7)) | 0;
        mid = (mid + Math.imul(al6, bh7)) | 0;
        mid = (mid + Math.imul(ah6, bl7)) | 0;
        hi = (hi + Math.imul(ah6, bh7)) | 0;
        lo = (lo + Math.imul(al5, bl8)) | 0;
        mid = (mid + Math.imul(al5, bh8)) | 0;
        mid = (mid + Math.imul(ah5, bl8)) | 0;
        hi = (hi + Math.imul(ah5, bh8)) | 0;
        lo = (lo + Math.imul(al4, bl9)) | 0;
        mid = (mid + Math.imul(al4, bh9)) | 0;
        mid = (mid + Math.imul(ah4, bl9)) | 0;
        hi = (hi + Math.imul(ah4, bh9)) | 0;
        var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
        w13 &= 0x3ffffff;
        /* k = 14 */
        lo = Math.imul(al9, bl5);
        mid = Math.imul(al9, bh5);
        mid = (mid + Math.imul(ah9, bl5)) | 0;
        hi = Math.imul(ah9, bh5);
        lo = (lo + Math.imul(al8, bl6)) | 0;
        mid = (mid + Math.imul(al8, bh6)) | 0;
        mid = (mid + Math.imul(ah8, bl6)) | 0;
        hi = (hi + Math.imul(ah8, bh6)) | 0;
        lo = (lo + Math.imul(al7, bl7)) | 0;
        mid = (mid + Math.imul(al7, bh7)) | 0;
        mid = (mid + Math.imul(ah7, bl7)) | 0;
        hi = (hi + Math.imul(ah7, bh7)) | 0;
        lo = (lo + Math.imul(al6, bl8)) | 0;
        mid = (mid + Math.imul(al6, bh8)) | 0;
        mid = (mid + Math.imul(ah6, bl8)) | 0;
        hi = (hi + Math.imul(ah6, bh8)) | 0;
        lo = (lo + Math.imul(al5, bl9)) | 0;
        mid = (mid + Math.imul(al5, bh9)) | 0;
        mid = (mid + Math.imul(ah5, bl9)) | 0;
        hi = (hi + Math.imul(ah5, bh9)) | 0;
        var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
        w14 &= 0x3ffffff;
        /* k = 15 */
        lo = Math.imul(al9, bl6);
        mid = Math.imul(al9, bh6);
        mid = (mid + Math.imul(ah9, bl6)) | 0;
        hi = Math.imul(ah9, bh6);
        lo = (lo + Math.imul(al8, bl7)) | 0;
        mid = (mid + Math.imul(al8, bh7)) | 0;
        mid = (mid + Math.imul(ah8, bl7)) | 0;
        hi = (hi + Math.imul(ah8, bh7)) | 0;
        lo = (lo + Math.imul(al7, bl8)) | 0;
        mid = (mid + Math.imul(al7, bh8)) | 0;
        mid = (mid + Math.imul(ah7, bl8)) | 0;
        hi = (hi + Math.imul(ah7, bh8)) | 0;
        lo = (lo + Math.imul(al6, bl9)) | 0;
        mid = (mid + Math.imul(al6, bh9)) | 0;
        mid = (mid + Math.imul(ah6, bl9)) | 0;
        hi = (hi + Math.imul(ah6, bh9)) | 0;
        var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
        w15 &= 0x3ffffff;
        /* k = 16 */
        lo = Math.imul(al9, bl7);
        mid = Math.imul(al9, bh7);
        mid = (mid + Math.imul(ah9, bl7)) | 0;
        hi = Math.imul(ah9, bh7);
        lo = (lo + Math.imul(al8, bl8)) | 0;
        mid = (mid + Math.imul(al8, bh8)) | 0;
        mid = (mid + Math.imul(ah8, bl8)) | 0;
        hi = (hi + Math.imul(ah8, bh8)) | 0;
        lo = (lo + Math.imul(al7, bl9)) | 0;
        mid = (mid + Math.imul(al7, bh9)) | 0;
        mid = (mid + Math.imul(ah7, bl9)) | 0;
        hi = (hi + Math.imul(ah7, bh9)) | 0;
        var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
        w16 &= 0x3ffffff;
        /* k = 17 */
        lo = Math.imul(al9, bl8);
        mid = Math.imul(al9, bh8);
        mid = (mid + Math.imul(ah9, bl8)) | 0;
        hi = Math.imul(ah9, bh8);
        lo = (lo + Math.imul(al8, bl9)) | 0;
        mid = (mid + Math.imul(al8, bh9)) | 0;
        mid = (mid + Math.imul(ah8, bl9)) | 0;
        hi = (hi + Math.imul(ah8, bh9)) | 0;
        var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
        w17 &= 0x3ffffff;
        /* k = 18 */
        lo = Math.imul(al9, bl9);
        mid = Math.imul(al9, bh9);
        mid = (mid + Math.imul(ah9, bl9)) | 0;
        hi = Math.imul(ah9, bh9);
        var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
        w18 &= 0x3ffffff;
        o[0] = w0;
        o[1] = w1;
        o[2] = w2;
        o[3] = w3;
        o[4] = w4;
        o[5] = w5;
        o[6] = w6;
        o[7] = w7;
        o[8] = w8;
        o[9] = w9;
        o[10] = w10;
        o[11] = w11;
        o[12] = w12;
        o[13] = w13;
        o[14] = w14;
        o[15] = w15;
        o[16] = w16;
        o[17] = w17;
        o[18] = w18;
        if (c !== 0) {
          o[19] = c;
          out.length++;
        }
        return out;
      };
    
      // Polyfill comb
      if (!Math.imul) {
        comb10MulTo = smallMulTo;
      }
    
      function bigMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        out.length = self.length + num.length;
    
        var carry = 0;
        var hncarry = 0;
        for (var k = 0; k < out.length - 1; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = hncarry;
          hncarry = 0;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = k - j;
            var a = self.words[i] | 0;
            var b = num.words[j] | 0;
            var r = a * b;
    
            var lo = r & 0x3ffffff;
            ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
            lo = (lo + rword) | 0;
            rword = lo & 0x3ffffff;
            ncarry = (ncarry + (lo >>> 26)) | 0;
    
            hncarry += ncarry >>> 26;
            ncarry &= 0x3ffffff;
          }
          out.words[k] = rword;
          carry = ncarry;
          ncarry = hncarry;
        }
        if (carry !== 0) {
          out.words[k] = carry;
        } else {
          out.length--;
        }
    
        return out.strip();
      }
    
      function jumboMulTo (self, num, out) {
        var fftm = new FFTM();
        return fftm.mulp(self, num, out);
      }
    
      BN.prototype.mulTo = function mulTo (num, out) {
        var res;
        var len = this.length + num.length;
        if (this.length === 10 && num.length === 10) {
          res = comb10MulTo(this, num, out);
        } else if (len < 63) {
          res = smallMulTo(this, num, out);
        } else if (len < 1024) {
          res = bigMulTo(this, num, out);
        } else {
          res = jumboMulTo(this, num, out);
        }
    
        return res;
      };
    
      // Cooley-Tukey algorithm for FFT
      // slightly revisited to rely on looping instead of recursion
    
      function FFTM (x, y) {
        this.x = x;
        this.y = y;
      }
    
      FFTM.prototype.makeRBT = function makeRBT (N) {
        var t = new Array(N);
        var l = BN.prototype._countBits(N) - 1;
        for (var i = 0; i < N; i++) {
          t[i] = this.revBin(i, l, N);
        }
    
        return t;
      };
    
      // Returns binary-reversed representation of `x`
      FFTM.prototype.revBin = function revBin (x, l, N) {
        if (x === 0 || x === N - 1) return x;
    
        var rb = 0;
        for (var i = 0; i < l; i++) {
          rb |= (x & 1) << (l - i - 1);
          x >>= 1;
        }
    
        return rb;
      };
    
      // Performs "tweedling" phase, therefore 'emulating'
      // behaviour of the recursive algorithm
      FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
        for (var i = 0; i < N; i++) {
          rtws[i] = rws[rbt[i]];
          itws[i] = iws[rbt[i]];
        }
      };
    
      FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
        this.permute(rbt, rws, iws, rtws, itws, N);
    
        for (var s = 1; s < N; s <<= 1) {
          var l = s << 1;
    
          var rtwdf = Math.cos(2 * Math.PI / l);
          var itwdf = Math.sin(2 * Math.PI / l);
    
          for (var p = 0; p < N; p += l) {
            var rtwdf_ = rtwdf;
            var itwdf_ = itwdf;
    
            for (var j = 0; j < s; j++) {
              var re = rtws[p + j];
              var ie = itws[p + j];
    
              var ro = rtws[p + j + s];
              var io = itws[p + j + s];
    
              var rx = rtwdf_ * ro - itwdf_ * io;
    
              io = rtwdf_ * io + itwdf_ * ro;
              ro = rx;
    
              rtws[p + j] = re + ro;
              itws[p + j] = ie + io;
    
              rtws[p + j + s] = re - ro;
              itws[p + j + s] = ie - io;
    
              /* jshint maxdepth : false */
              if (j !== l) {
                rx = rtwdf * rtwdf_ - itwdf * itwdf_;
    
                itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
                rtwdf_ = rx;
              }
            }
          }
        }
      };
    
      FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
        var N = Math.max(m, n) | 1;
        var odd = N & 1;
        var i = 0;
        for (N = N / 2 | 0; N; N = N >>> 1) {
          i++;
        }
    
        return 1 << i + 1 + odd;
      };
    
      FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
        if (N <= 1) return;
    
        for (var i = 0; i < N / 2; i++) {
          var t = rws[i];
    
          rws[i] = rws[N - i - 1];
          rws[N - i - 1] = t;
    
          t = iws[i];
    
          iws[i] = -iws[N - i - 1];
          iws[N - i - 1] = -t;
        }
      };
    
      FFTM.prototype.normalize13b = function normalize13b (ws, N) {
        var carry = 0;
        for (var i = 0; i < N / 2; i++) {
          var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
            Math.round(ws[2 * i] / N) +
            carry;
    
          ws[i] = w & 0x3ffffff;
    
          if (w < 0x4000000) {
            carry = 0;
          } else {
            carry = w / 0x4000000 | 0;
          }
        }
    
        return ws;
      };
    
      FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
        var carry = 0;
        for (var i = 0; i < len; i++) {
          carry = carry + (ws[i] | 0);
    
          rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
          rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
        }
    
        // Pad with zeroes
        for (i = 2 * len; i < N; ++i) {
          rws[i] = 0;
        }
    
        assert(carry === 0);
        assert((carry & ~0x1fff) === 0);
      };
    
      FFTM.prototype.stub = function stub (N) {
        var ph = new Array(N);
        for (var i = 0; i < N; i++) {
          ph[i] = 0;
        }
    
        return ph;
      };
    
      FFTM.prototype.mulp = function mulp (x, y, out) {
        var N = 2 * this.guessLen13b(x.length, y.length);
    
        var rbt = this.makeRBT(N);
    
        var _ = this.stub(N);
    
        var rws = new Array(N);
        var rwst = new Array(N);
        var iwst = new Array(N);
    
        var nrws = new Array(N);
        var nrwst = new Array(N);
        var niwst = new Array(N);
    
        var rmws = out.words;
        rmws.length = N;
    
        this.convert13b(x.words, x.length, rws, N);
        this.convert13b(y.words, y.length, nrws, N);
    
        this.transform(rws, _, rwst, iwst, N, rbt);
        this.transform(nrws, _, nrwst, niwst, N, rbt);
    
        for (var i = 0; i < N; i++) {
          var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
          iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
          rwst[i] = rx;
        }
    
        this.conjugate(rwst, iwst, N);
        this.transform(rwst, iwst, rmws, _, N, rbt);
        this.conjugate(rmws, _, N);
        this.normalize13b(rmws, N);
    
        out.negative = x.negative ^ y.negative;
        out.length = x.length + y.length;
        return out.strip();
      };
    
      // Multiply `this` by `num`
      BN.prototype.mul = function mul (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return this.mulTo(num, out);
      };
    
      // Multiply employing FFT
      BN.prototype.mulf = function mulf (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return jumboMulTo(this, num, out);
      };
    
      // In-place Multiplication
      BN.prototype.imul = function imul (num) {
        return this.clone().mulTo(num, this);
      };
    
      BN.prototype.imuln = function imuln (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
    
        // Carry
        var carry = 0;
        for (var i = 0; i < this.length; i++) {
          var w = (this.words[i] | 0) * num;
          var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
          carry >>= 26;
          carry += (w / 0x4000000) | 0;
          // NOTE: lo is 27bit maximum
          carry += lo >>> 26;
          this.words[i] = lo & 0x3ffffff;
        }
    
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
    
        return this;
      };
    
      BN.prototype.muln = function muln (num) {
        return this.clone().imuln(num);
      };
    
      // `this` * `this`
      BN.prototype.sqr = function sqr () {
        return this.mul(this);
      };
    
      // `this` * `this` in-place
      BN.prototype.isqr = function isqr () {
        return this.imul(this.clone());
      };
    
      // Math.pow(`this`, `num`)
      BN.prototype.pow = function pow (num) {
        var w = toBitArray(num);
        if (w.length === 0) return new BN(1);
    
        // Skip leading zeroes
        var res = this;
        for (var i = 0; i < w.length; i++, res = res.sqr()) {
          if (w[i] !== 0) break;
        }
    
        if (++i < w.length) {
          for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
            if (w[i] === 0) continue;
    
            res = res.mul(q);
          }
        }
    
        return res;
      };
    
      // Shift-left in-place
      BN.prototype.iushln = function iushln (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
        var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
        var i;
    
        if (r !== 0) {
          var carry = 0;
    
          for (i = 0; i < this.length; i++) {
            var newCarry = this.words[i] & carryMask;
            var c = ((this.words[i] | 0) - newCarry) << r;
            this.words[i] = c | carry;
            carry = newCarry >>> (26 - r);
          }
    
          if (carry) {
            this.words[i] = carry;
            this.length++;
          }
        }
    
        if (s !== 0) {
          for (i = this.length - 1; i >= 0; i--) {
            this.words[i + s] = this.words[i];
          }
    
          for (i = 0; i < s; i++) {
            this.words[i] = 0;
          }
    
          this.length += s;
        }
    
        return this.strip();
      };
    
      BN.prototype.ishln = function ishln (bits) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushln(bits);
      };
    
      // Shift-right in-place
      // NOTE: `hint` is a lowest bit before trailing zeroes
      // NOTE: if `extended` is present - it will be filled with destroyed bits
      BN.prototype.iushrn = function iushrn (bits, hint, extended) {
        assert(typeof bits === 'number' && bits >= 0);
        var h;
        if (hint) {
          h = (hint - (hint % 26)) / 26;
        } else {
          h = 0;
        }
    
        var r = bits % 26;
        var s = Math.min((bits - r) / 26, this.length);
        var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
        var maskedWords = extended;
    
        h -= s;
        h = Math.max(0, h);
    
        // Extended mode, copy masked part
        if (maskedWords) {
          for (var i = 0; i < s; i++) {
            maskedWords.words[i] = this.words[i];
          }
          maskedWords.length = s;
        }
    
        if (s === 0) {
          // No-op, we should not move anything at all
        } else if (this.length > s) {
          this.length -= s;
          for (i = 0; i < this.length; i++) {
            this.words[i] = this.words[i + s];
          }
        } else {
          this.words[0] = 0;
          this.length = 1;
        }
    
        var carry = 0;
        for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
          var word = this.words[i] | 0;
          this.words[i] = (carry << (26 - r)) | (word >>> r);
          carry = word & mask;
        }
    
        // Push carried bits as a mask
        if (maskedWords && carry !== 0) {
          maskedWords.words[maskedWords.length++] = carry;
        }
    
        if (this.length === 0) {
          this.words[0] = 0;
          this.length = 1;
        }
    
        return this.strip();
      };
    
      BN.prototype.ishrn = function ishrn (bits, hint, extended) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushrn(bits, hint, extended);
      };
    
      // Shift-left
      BN.prototype.shln = function shln (bits) {
        return this.clone().ishln(bits);
      };
    
      BN.prototype.ushln = function ushln (bits) {
        return this.clone().iushln(bits);
      };
    
      // Shift-right
      BN.prototype.shrn = function shrn (bits) {
        return this.clone().ishrn(bits);
      };
    
      BN.prototype.ushrn = function ushrn (bits) {
        return this.clone().iushrn(bits);
      };
    
      // Test if n bit is set
      BN.prototype.testn = function testn (bit) {
        assert(typeof bit === 'number' && bit >= 0);
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) return false;
    
        // Check bit and return
        var w = this.words[s];
    
        return !!(w & q);
      };
    
      // Return only lowers bits of number (in-place)
      BN.prototype.imaskn = function imaskn (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
    
        assert(this.negative === 0, 'imaskn works only with positive numbers');
    
        if (this.length <= s) {
          return this;
        }
    
        if (r !== 0) {
          s++;
        }
        this.length = Math.min(s, this.length);
    
        if (r !== 0) {
          var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
          this.words[this.length - 1] &= mask;
        }
    
        return this.strip();
      };
    
      // Return only lowers bits of number
      BN.prototype.maskn = function maskn (bits) {
        return this.clone().imaskn(bits);
      };
    
      // Add plain number `num` to `this`
      BN.prototype.iaddn = function iaddn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.isubn(-num);
    
        // Possible sign change
        if (this.negative !== 0) {
          if (this.length === 1 && (this.words[0] | 0) < num) {
            this.words[0] = num - (this.words[0] | 0);
            this.negative = 0;
            return this;
          }
    
          this.negative = 0;
          this.isubn(num);
          this.negative = 1;
          return this;
        }
    
        // Add without checks
        return this._iaddn(num);
      };
    
      BN.prototype._iaddn = function _iaddn (num) {
        this.words[0] += num;
    
        // Carry
        for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
          this.words[i] -= 0x4000000;
          if (i === this.length - 1) {
            this.words[i + 1] = 1;
          } else {
            this.words[i + 1]++;
          }
        }
        this.length = Math.max(this.length, i + 1);
    
        return this;
      };
    
      // Subtract plain number `num` from `this`
      BN.prototype.isubn = function isubn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.iaddn(-num);
    
        if (this.negative !== 0) {
          this.negative = 0;
          this.iaddn(num);
          this.negative = 1;
          return this;
        }
    
        this.words[0] -= num;
    
        if (this.length === 1 && this.words[0] < 0) {
          this.words[0] = -this.words[0];
          this.negative = 1;
        } else {
          // Carry
          for (var i = 0; i < this.length && this.words[i] < 0; i++) {
            this.words[i] += 0x4000000;
            this.words[i + 1] -= 1;
          }
        }
    
        return this.strip();
      };
    
      BN.prototype.addn = function addn (num) {
        return this.clone().iaddn(num);
      };
    
      BN.prototype.subn = function subn (num) {
        return this.clone().isubn(num);
      };
    
      BN.prototype.iabs = function iabs () {
        this.negative = 0;
    
        return this;
      };
    
      BN.prototype.abs = function abs () {
        return this.clone().iabs();
      };
    
      BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
        var len = num.length + shift;
        var i;
    
        this._expand(len);
    
        var w;
        var carry = 0;
        for (i = 0; i < num.length; i++) {
          w = (this.words[i + shift] | 0) + carry;
          var right = (num.words[i] | 0) * mul;
          w -= right & 0x3ffffff;
          carry = (w >> 26) - ((right / 0x4000000) | 0);
          this.words[i + shift] = w & 0x3ffffff;
        }
        for (; i < this.length - shift; i++) {
          w = (this.words[i + shift] | 0) + carry;
          carry = w >> 26;
          this.words[i + shift] = w & 0x3ffffff;
        }
    
        if (carry === 0) return this.strip();
    
        // Subtraction overflow
        assert(carry === -1);
        carry = 0;
        for (i = 0; i < this.length; i++) {
          w = -(this.words[i] | 0) + carry;
          carry = w >> 26;
          this.words[i] = w & 0x3ffffff;
        }
        this.negative = 1;
    
        return this.strip();
      };
    
      BN.prototype._wordDiv = function _wordDiv (num, mode) {
        var shift = this.length - num.length;
    
        var a = this.clone();
        var b = num;
    
        // Normalize
        var bhi = b.words[b.length - 1] | 0;
        var bhiBits = this._countBits(bhi);
        shift = 26 - bhiBits;
        if (shift !== 0) {
          b = b.ushln(shift);
          a.iushln(shift);
          bhi = b.words[b.length - 1] | 0;
        }
    
        // Initialize quotient
        var m = a.length - b.length;
        var q;
    
        if (mode !== 'mod') {
          q = new BN(null);
          q.length = m + 1;
          q.words = new Array(q.length);
          for (var i = 0; i < q.length; i++) {
            q.words[i] = 0;
          }
        }
    
        var diff = a.clone()._ishlnsubmul(b, 1, m);
        if (diff.negative === 0) {
          a = diff;
          if (q) {
            q.words[m] = 1;
          }
        }
    
        for (var j = m - 1; j >= 0; j--) {
          var qj = (a.words[b.length + j] | 0) * 0x4000000 +
            (a.words[b.length + j - 1] | 0);
    
          // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
          // (0x7ffffff)
          qj = Math.min((qj / bhi) | 0, 0x3ffffff);
    
          a._ishlnsubmul(b, qj, j);
          while (a.negative !== 0) {
            qj--;
            a.negative = 0;
            a._ishlnsubmul(b, 1, j);
            if (!a.isZero()) {
              a.negative ^= 1;
            }
          }
          if (q) {
            q.words[j] = qj;
          }
        }
        if (q) {
          q.strip();
        }
        a.strip();
    
        // Denormalize
        if (mode !== 'div' && shift !== 0) {
          a.iushrn(shift);
        }
    
        return {
          div: q || null,
          mod: a
        };
      };
    
      // NOTE: 1) `mode` can be set to `mod` to request mod only,
      //       to `div` to request div only, or be absent to
      //       request both div & mod
      //       2) `positive` is true if unsigned mod is requested
      BN.prototype.divmod = function divmod (num, mode, positive) {
        assert(!num.isZero());
    
        if (this.isZero()) {
          return {
            div: new BN(0),
            mod: new BN(0)
          };
        }
    
        var div, mod, res;
        if (this.negative !== 0 && num.negative === 0) {
          res = this.neg().divmod(num, mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.iadd(num);
            }
          }
    
          return {
            div: div,
            mod: mod
          };
        }
    
        if (this.negative === 0 && num.negative !== 0) {
          res = this.divmod(num.neg(), mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          return {
            div: div,
            mod: res.mod
          };
        }
    
        if ((this.negative & num.negative) !== 0) {
          res = this.neg().divmod(num.neg(), mode);
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.isub(num);
            }
          }
    
          return {
            div: res.div,
            mod: mod
          };
        }
    
        // Both numbers are positive at this point
    
        // Strip both numbers to approximate shift value
        if (num.length > this.length || this.cmp(num) < 0) {
          return {
            div: new BN(0),
            mod: this
          };
        }
    
        // Very short reduction
        if (num.length === 1) {
          if (mode === 'div') {
            return {
              div: this.divn(num.words[0]),
              mod: null
            };
          }
    
          if (mode === 'mod') {
            return {
              div: null,
              mod: new BN(this.modn(num.words[0]))
            };
          }
    
          return {
            div: this.divn(num.words[0]),
            mod: new BN(this.modn(num.words[0]))
          };
        }
    
        return this._wordDiv(num, mode);
      };
    
      // Find `this` / `num`
      BN.prototype.div = function div (num) {
        return this.divmod(num, 'div', false).div;
      };
    
      // Find `this` % `num`
      BN.prototype.mod = function mod (num) {
        return this.divmod(num, 'mod', false).mod;
      };
    
      BN.prototype.umod = function umod (num) {
        return this.divmod(num, 'mod', true).mod;
      };
    
      // Find Round(`this` / `num`)
      BN.prototype.divRound = function divRound (num) {
        var dm = this.divmod(num);
    
        // Fast case - exact division
        if (dm.mod.isZero()) return dm.div;
    
        var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
    
        var half = num.ushrn(1);
        var r2 = num.andln(1);
        var cmp = mod.cmp(half);
    
        // Round down
        if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
    
        // Round up
        return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
      };
    
      BN.prototype.modn = function modn (num) {
        assert(num <= 0x3ffffff);
        var p = (1 << 26) % num;
    
        var acc = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          acc = (p * acc + (this.words[i] | 0)) % num;
        }
    
        return acc;
      };
    
      // In-place division by number
      BN.prototype.idivn = function idivn (num) {
        assert(num <= 0x3ffffff);
    
        var carry = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var w = (this.words[i] | 0) + carry * 0x4000000;
          this.words[i] = (w / num) | 0;
          carry = w % num;
        }
    
        return this.strip();
      };
    
      BN.prototype.divn = function divn (num) {
        return this.clone().idivn(num);
      };
    
      BN.prototype.egcd = function egcd (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var x = this;
        var y = p.clone();
    
        if (x.negative !== 0) {
          x = x.umod(p);
        } else {
          x = x.clone();
        }
    
        // A * x + B * y = x
        var A = new BN(1);
        var B = new BN(0);
    
        // C * x + D * y = y
        var C = new BN(0);
        var D = new BN(1);
    
        var g = 0;
    
        while (x.isEven() && y.isEven()) {
          x.iushrn(1);
          y.iushrn(1);
          ++g;
        }
    
        var yp = y.clone();
        var xp = x.clone();
    
        while (!x.isZero()) {
          for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            x.iushrn(i);
            while (i-- > 0) {
              if (A.isOdd() || B.isOdd()) {
                A.iadd(yp);
                B.isub(xp);
              }
    
              A.iushrn(1);
              B.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            y.iushrn(j);
            while (j-- > 0) {
              if (C.isOdd() || D.isOdd()) {
                C.iadd(yp);
                D.isub(xp);
              }
    
              C.iushrn(1);
              D.iushrn(1);
            }
          }
    
          if (x.cmp(y) >= 0) {
            x.isub(y);
            A.isub(C);
            B.isub(D);
          } else {
            y.isub(x);
            C.isub(A);
            D.isub(B);
          }
        }
    
        return {
          a: C,
          b: D,
          gcd: y.iushln(g)
        };
      };
    
      // This is reduced incarnation of the binary EEA
      // above, designated to invert members of the
      // _prime_ fields F(p) at a maximal speed
      BN.prototype._invmp = function _invmp (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var a = this;
        var b = p.clone();
    
        if (a.negative !== 0) {
          a = a.umod(p);
        } else {
          a = a.clone();
        }
    
        var x1 = new BN(1);
        var x2 = new BN(0);
    
        var delta = b.clone();
    
        while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
          for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            a.iushrn(i);
            while (i-- > 0) {
              if (x1.isOdd()) {
                x1.iadd(delta);
              }
    
              x1.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            b.iushrn(j);
            while (j-- > 0) {
              if (x2.isOdd()) {
                x2.iadd(delta);
              }
    
              x2.iushrn(1);
            }
          }
    
          if (a.cmp(b) >= 0) {
            a.isub(b);
            x1.isub(x2);
          } else {
            b.isub(a);
            x2.isub(x1);
          }
        }
    
        var res;
        if (a.cmpn(1) === 0) {
          res = x1;
        } else {
          res = x2;
        }
    
        if (res.cmpn(0) < 0) {
          res.iadd(p);
        }
    
        return res;
      };
    
      BN.prototype.gcd = function gcd (num) {
        if (this.isZero()) return num.abs();
        if (num.isZero()) return this.abs();
    
        var a = this.clone();
        var b = num.clone();
        a.negative = 0;
        b.negative = 0;
    
        // Remove common factor of two
        for (var shift = 0; a.isEven() && b.isEven(); shift++) {
          a.iushrn(1);
          b.iushrn(1);
        }
    
        do {
          while (a.isEven()) {
            a.iushrn(1);
          }
          while (b.isEven()) {
            b.iushrn(1);
          }
    
          var r = a.cmp(b);
          if (r < 0) {
            // Swap `a` and `b` to make `a` always bigger than `b`
            var t = a;
            a = b;
            b = t;
          } else if (r === 0 || b.cmpn(1) === 0) {
            break;
          }
    
          a.isub(b);
        } while (true);
    
        return b.iushln(shift);
      };
    
      // Invert number in the field F(num)
      BN.prototype.invm = function invm (num) {
        return this.egcd(num).a.umod(num);
      };
    
      BN.prototype.isEven = function isEven () {
        return (this.words[0] & 1) === 0;
      };
    
      BN.prototype.isOdd = function isOdd () {
        return (this.words[0] & 1) === 1;
      };
    
      // And first word and num
      BN.prototype.andln = function andln (num) {
        return this.words[0] & num;
      };
    
      // Increment at the bit position in-line
      BN.prototype.bincn = function bincn (bit) {
        assert(typeof bit === 'number');
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) {
          this._expand(s + 1);
          this.words[s] |= q;
          return this;
        }
    
        // Add bit and propagate, if needed
        var carry = q;
        for (var i = s; carry !== 0 && i < this.length; i++) {
          var w = this.words[i] | 0;
          w += carry;
          carry = w >>> 26;
          w &= 0x3ffffff;
          this.words[i] = w;
        }
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
        return this;
      };
    
      BN.prototype.isZero = function isZero () {
        return this.length === 1 && this.words[0] === 0;
      };
    
      BN.prototype.cmpn = function cmpn (num) {
        var negative = num < 0;
    
        if (this.negative !== 0 && !negative) return -1;
        if (this.negative === 0 && negative) return 1;
    
        this.strip();
    
        var res;
        if (this.length > 1) {
          res = 1;
        } else {
          if (negative) {
            num = -num;
          }
    
          assert(num <= 0x3ffffff, 'Number is too big');
    
          var w = this.words[0] | 0;
          res = w === num ? 0 : w < num ? -1 : 1;
        }
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Compare two numbers and return:
      // 1 - if `this` > `num`
      // 0 - if `this` == `num`
      // -1 - if `this` < `num`
      BN.prototype.cmp = function cmp (num) {
        if (this.negative !== 0 && num.negative === 0) return -1;
        if (this.negative === 0 && num.negative !== 0) return 1;
    
        var res = this.ucmp(num);
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Unsigned comparison
      BN.prototype.ucmp = function ucmp (num) {
        // At this point both numbers have the same sign
        if (this.length > num.length) return 1;
        if (this.length < num.length) return -1;
    
        var res = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var a = this.words[i] | 0;
          var b = num.words[i] | 0;
    
          if (a === b) continue;
          if (a < b) {
            res = -1;
          } else if (a > b) {
            res = 1;
          }
          break;
        }
        return res;
      };
    
      BN.prototype.gtn = function gtn (num) {
        return this.cmpn(num) === 1;
      };
    
      BN.prototype.gt = function gt (num) {
        return this.cmp(num) === 1;
      };
    
      BN.prototype.gten = function gten (num) {
        return this.cmpn(num) >= 0;
      };
    
      BN.prototype.gte = function gte (num) {
        return this.cmp(num) >= 0;
      };
    
      BN.prototype.ltn = function ltn (num) {
        return this.cmpn(num) === -1;
      };
    
      BN.prototype.lt = function lt (num) {
        return this.cmp(num) === -1;
      };
    
      BN.prototype.lten = function lten (num) {
        return this.cmpn(num) <= 0;
      };
    
      BN.prototype.lte = function lte (num) {
        return this.cmp(num) <= 0;
      };
    
      BN.prototype.eqn = function eqn (num) {
        return this.cmpn(num) === 0;
      };
    
      BN.prototype.eq = function eq (num) {
        return this.cmp(num) === 0;
      };
    
      //
      // A reduce context, could be using montgomery or something better, depending
      // on the `m` itself.
      //
      BN.red = function red (num) {
        return new Red(num);
      };
    
      BN.prototype.toRed = function toRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        assert(this.negative === 0, 'red works only with positives');
        return ctx.convertTo(this)._forceRed(ctx);
      };
    
      BN.prototype.fromRed = function fromRed () {
        assert(this.red, 'fromRed works only with numbers in reduction context');
        return this.red.convertFrom(this);
      };
    
      BN.prototype._forceRed = function _forceRed (ctx) {
        this.red = ctx;
        return this;
      };
    
      BN.prototype.forceRed = function forceRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        return this._forceRed(ctx);
      };
    
      BN.prototype.redAdd = function redAdd (num) {
        assert(this.red, 'redAdd works only with red numbers');
        return this.red.add(this, num);
      };
    
      BN.prototype.redIAdd = function redIAdd (num) {
        assert(this.red, 'redIAdd works only with red numbers');
        return this.red.iadd(this, num);
      };
    
      BN.prototype.redSub = function redSub (num) {
        assert(this.red, 'redSub works only with red numbers');
        return this.red.sub(this, num);
      };
    
      BN.prototype.redISub = function redISub (num) {
        assert(this.red, 'redISub works only with red numbers');
        return this.red.isub(this, num);
      };
    
      BN.prototype.redShl = function redShl (num) {
        assert(this.red, 'redShl works only with red numbers');
        return this.red.shl(this, num);
      };
    
      BN.prototype.redMul = function redMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.mul(this, num);
      };
    
      BN.prototype.redIMul = function redIMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.imul(this, num);
      };
    
      BN.prototype.redSqr = function redSqr () {
        assert(this.red, 'redSqr works only with red numbers');
        this.red._verify1(this);
        return this.red.sqr(this);
      };
    
      BN.prototype.redISqr = function redISqr () {
        assert(this.red, 'redISqr works only with red numbers');
        this.red._verify1(this);
        return this.red.isqr(this);
      };
    
      // Square root over p
      BN.prototype.redSqrt = function redSqrt () {
        assert(this.red, 'redSqrt works only with red numbers');
        this.red._verify1(this);
        return this.red.sqrt(this);
      };
    
      BN.prototype.redInvm = function redInvm () {
        assert(this.red, 'redInvm works only with red numbers');
        this.red._verify1(this);
        return this.red.invm(this);
      };
    
      // Return negative clone of `this` % `red modulo`
      BN.prototype.redNeg = function redNeg () {
        assert(this.red, 'redNeg works only with red numbers');
        this.red._verify1(this);
        return this.red.neg(this);
      };
    
      BN.prototype.redPow = function redPow (num) {
        assert(this.red && !num.red, 'redPow(normalNum)');
        this.red._verify1(this);
        return this.red.pow(this, num);
      };
    
      // Prime numbers with efficient reduction
      var primes = {
        k256: null,
        p224: null,
        p192: null,
        p25519: null
      };
    
      // Pseudo-Mersenne prime
      function MPrime (name, p) {
        // P = 2 ^ N - K
        this.name = name;
        this.p = new BN(p, 16);
        this.n = this.p.bitLength();
        this.k = new BN(1).iushln(this.n).isub(this.p);
    
        this.tmp = this._tmp();
      }
    
      MPrime.prototype._tmp = function _tmp () {
        var tmp = new BN(null);
        tmp.words = new Array(Math.ceil(this.n / 13));
        return tmp;
      };
    
      MPrime.prototype.ireduce = function ireduce (num) {
        // Assumes that `num` is less than `P^2`
        // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
        var r = num;
        var rlen;
    
        do {
          this.split(r, this.tmp);
          r = this.imulK(r);
          r = r.iadd(this.tmp);
          rlen = r.bitLength();
        } while (rlen > this.n);
    
        var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
        if (cmp === 0) {
          r.words[0] = 0;
          r.length = 1;
        } else if (cmp > 0) {
          r.isub(this.p);
        } else {
          if (r.strip !== undefined) {
            // r is BN v4 instance
            r.strip();
          } else {
            // r is BN v5 instance
            r._strip();
          }
        }
    
        return r;
      };
    
      MPrime.prototype.split = function split (input, out) {
        input.iushrn(this.n, 0, out);
      };
    
      MPrime.prototype.imulK = function imulK (num) {
        return num.imul(this.k);
      };
    
      function K256 () {
        MPrime.call(
          this,
          'k256',
          'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
      }
      inherits(K256, MPrime);
    
      K256.prototype.split = function split (input, output) {
        // 256 = 9 * 26 + 22
        var mask = 0x3fffff;
    
        var outLen = Math.min(input.length, 9);
        for (var i = 0; i < outLen; i++) {
          output.words[i] = input.words[i];
        }
        output.length = outLen;
    
        if (input.length <= 9) {
          input.words[0] = 0;
          input.length = 1;
          return;
        }
    
        // Shift by 9 limbs
        var prev = input.words[9];
        output.words[output.length++] = prev & mask;
    
        for (i = 10; i < input.length; i++) {
          var next = input.words[i] | 0;
          input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
          prev = next;
        }
        prev >>>= 22;
        input.words[i - 10] = prev;
        if (prev === 0 && input.length > 10) {
          input.length -= 10;
        } else {
          input.length -= 9;
        }
      };
    
      K256.prototype.imulK = function imulK (num) {
        // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
        num.words[num.length] = 0;
        num.words[num.length + 1] = 0;
        num.length += 2;
    
        // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
        var lo = 0;
        for (var i = 0; i < num.length; i++) {
          var w = num.words[i] | 0;
          lo += w * 0x3d1;
          num.words[i] = lo & 0x3ffffff;
          lo = w * 0x40 + ((lo / 0x4000000) | 0);
        }
    
        // Fast length reduction
        if (num.words[num.length - 1] === 0) {
          num.length--;
          if (num.words[num.length - 1] === 0) {
            num.length--;
          }
        }
        return num;
      };
    
      function P224 () {
        MPrime.call(
          this,
          'p224',
          'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
      }
      inherits(P224, MPrime);
    
      function P192 () {
        MPrime.call(
          this,
          'p192',
          'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
      }
      inherits(P192, MPrime);
    
      function P25519 () {
        // 2 ^ 255 - 19
        MPrime.call(
          this,
          '25519',
          '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
      }
      inherits(P25519, MPrime);
    
      P25519.prototype.imulK = function imulK (num) {
        // K = 0x13
        var carry = 0;
        for (var i = 0; i < num.length; i++) {
          var hi = (num.words[i] | 0) * 0x13 + carry;
          var lo = hi & 0x3ffffff;
          hi >>>= 26;
    
          num.words[i] = lo;
          carry = hi;
        }
        if (carry !== 0) {
          num.words[num.length++] = carry;
        }
        return num;
      };
    
      // Exported mostly for testing purposes, use plain name instead
      BN._prime = function prime (name) {
        // Cached version of prime
        if (primes[name]) return primes[name];
    
        var prime;
        if (name === 'k256') {
          prime = new K256();
        } else if (name === 'p224') {
          prime = new P224();
        } else if (name === 'p192') {
          prime = new P192();
        } else if (name === 'p25519') {
          prime = new P25519();
        } else {
          throw new Error('Unknown prime ' + name);
        }
        primes[name] = prime;
    
        return prime;
      };
    
      //
      // Base reduction engine
      //
      function Red (m) {
        if (typeof m === 'string') {
          var prime = BN._prime(m);
          this.m = prime.p;
          this.prime = prime;
        } else {
          assert(m.gtn(1), 'modulus must be greater than 1');
          this.m = m;
          this.prime = null;
        }
      }
    
      Red.prototype._verify1 = function _verify1 (a) {
        assert(a.negative === 0, 'red works only with positives');
        assert(a.red, 'red works only with red numbers');
      };
    
      Red.prototype._verify2 = function _verify2 (a, b) {
        assert((a.negative | b.negative) === 0, 'red works only with positives');
        assert(a.red && a.red === b.red,
          'red works only with red numbers');
      };
    
      Red.prototype.imod = function imod (a) {
        if (this.prime) return this.prime.ireduce(a)._forceRed(this);
        return a.umod(this.m)._forceRed(this);
      };
    
      Red.prototype.neg = function neg (a) {
        if (a.isZero()) {
          return a.clone();
        }
    
        return this.m.sub(a)._forceRed(this);
      };
    
      Red.prototype.add = function add (a, b) {
        this._verify2(a, b);
    
        var res = a.add(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.iadd = function iadd (a, b) {
        this._verify2(a, b);
    
        var res = a.iadd(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res;
      };
    
      Red.prototype.sub = function sub (a, b) {
        this._verify2(a, b);
    
        var res = a.sub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.isub = function isub (a, b) {
        this._verify2(a, b);
    
        var res = a.isub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res;
      };
    
      Red.prototype.shl = function shl (a, num) {
        this._verify1(a);
        return this.imod(a.ushln(num));
      };
    
      Red.prototype.imul = function imul (a, b) {
        this._verify2(a, b);
        return this.imod(a.imul(b));
      };
    
      Red.prototype.mul = function mul (a, b) {
        this._verify2(a, b);
        return this.imod(a.mul(b));
      };
    
      Red.prototype.isqr = function isqr (a) {
        return this.imul(a, a.clone());
      };
    
      Red.prototype.sqr = function sqr (a) {
        return this.mul(a, a);
      };
    
      Red.prototype.sqrt = function sqrt (a) {
        if (a.isZero()) return a.clone();
    
        var mod3 = this.m.andln(3);
        assert(mod3 % 2 === 1);
    
        // Fast case
        if (mod3 === 3) {
          var pow = this.m.add(new BN(1)).iushrn(2);
          return this.pow(a, pow);
        }
    
        // Tonelli-Shanks algorithm (Totally unoptimized and slow)
        //
        // Find Q and S, that Q * 2 ^ S = (P - 1)
        var q = this.m.subn(1);
        var s = 0;
        while (!q.isZero() && q.andln(1) === 0) {
          s++;
          q.iushrn(1);
        }
        assert(!q.isZero());
    
        var one = new BN(1).toRed(this);
        var nOne = one.redNeg();
    
        // Find quadratic non-residue
        // NOTE: Max is such because of generalized Riemann hypothesis.
        var lpow = this.m.subn(1).iushrn(1);
        var z = this.m.bitLength();
        z = new BN(2 * z * z).toRed(this);
    
        while (this.pow(z, lpow).cmp(nOne) !== 0) {
          z.redIAdd(nOne);
        }
    
        var c = this.pow(z, q);
        var r = this.pow(a, q.addn(1).iushrn(1));
        var t = this.pow(a, q);
        var m = s;
        while (t.cmp(one) !== 0) {
          var tmp = t;
          for (var i = 0; tmp.cmp(one) !== 0; i++) {
            tmp = tmp.redSqr();
          }
          assert(i < m);
          var b = this.pow(c, new BN(1).iushln(m - i - 1));
    
          r = r.redMul(b);
          c = b.redSqr();
          t = t.redMul(c);
          m = i;
        }
    
        return r;
      };
    
      Red.prototype.invm = function invm (a) {
        var inv = a._invmp(this.m);
        if (inv.negative !== 0) {
          inv.negative = 0;
          return this.imod(inv).redNeg();
        } else {
          return this.imod(inv);
        }
      };
    
      Red.prototype.pow = function pow (a, num) {
        if (num.isZero()) return new BN(1).toRed(this);
        if (num.cmpn(1) === 0) return a.clone();
    
        var windowSize = 4;
        var wnd = new Array(1 << windowSize);
        wnd[0] = new BN(1).toRed(this);
        wnd[1] = a;
        for (var i = 2; i < wnd.length; i++) {
          wnd[i] = this.mul(wnd[i - 1], a);
        }
    
        var res = wnd[0];
        var current = 0;
        var currentLen = 0;
        var start = num.bitLength() % 26;
        if (start === 0) {
          start = 26;
        }
    
        for (i = num.length - 1; i >= 0; i--) {
          var word = num.words[i];
          for (var j = start - 1; j >= 0; j--) {
            var bit = (word >> j) & 1;
            if (res !== wnd[0]) {
              res = this.sqr(res);
            }
    
            if (bit === 0 && current === 0) {
              currentLen = 0;
              continue;
            }
    
            current <<= 1;
            current |= bit;
            currentLen++;
            if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
    
            res = this.mul(res, wnd[current]);
            currentLen = 0;
            current = 0;
          }
          start = 26;
        }
    
        return res;
      };
    
      Red.prototype.convertTo = function convertTo (num) {
        var r = num.umod(this.m);
    
        return r === num ? r.clone() : r;
      };
    
      Red.prototype.convertFrom = function convertFrom (num) {
        var res = num.clone();
        res.red = null;
        return res;
      };
    
      //
      // Montgomery method engine
      //
    
      BN.mont = function mont (num) {
        return new Mont(num);
      };
    
      function Mont (m) {
        Red.call(this, m);
    
        this.shift = this.m.bitLength();
        if (this.shift % 26 !== 0) {
          this.shift += 26 - (this.shift % 26);
        }
    
        this.r = new BN(1).iushln(this.shift);
        this.r2 = this.imod(this.r.sqr());
        this.rinv = this.r._invmp(this.m);
    
        this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
        this.minv = this.minv.umod(this.r);
        this.minv = this.r.sub(this.minv);
      }
      inherits(Mont, Red);
    
      Mont.prototype.convertTo = function convertTo (num) {
        return this.imod(num.ushln(this.shift));
      };
    
      Mont.prototype.convertFrom = function convertFrom (num) {
        var r = this.imod(num.mul(this.rinv));
        r.red = null;
        return r;
      };
    
      Mont.prototype.imul = function imul (a, b) {
        if (a.isZero() || b.isZero()) {
          a.words[0] = 0;
          a.length = 1;
          return a;
        }
    
        var t = a.imul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
    
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.mul = function mul (a, b) {
        if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
    
        var t = a.mul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.invm = function invm (a) {
        // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
        var res = this.imod(a._invmp(this.m).mul(this.r2));
        return res._forceRed(this);
      };
    })(typeof module === 'undefined' || module, this);
    
    },{"buffer":36}],34:[function(require,module,exports){
    var concatMap = require('concat-map');
    var balanced = require('balanced-match');
    
    module.exports = expandTop;
    
    var escSlash = '\0SLASH'+Math.random()+'\0';
    var escOpen = '\0OPEN'+Math.random()+'\0';
    var escClose = '\0CLOSE'+Math.random()+'\0';
    var escComma = '\0COMMA'+Math.random()+'\0';
    var escPeriod = '\0PERIOD'+Math.random()+'\0';
    
    function numeric(str) {
      return parseInt(str, 10) == str
        ? parseInt(str, 10)
        : str.charCodeAt(0);
    }
    
    function escapeBraces(str) {
      return str.split('\\\\').join(escSlash)
                .split('\\{').join(escOpen)
                .split('\\}').join(escClose)
                .split('\\,').join(escComma)
                .split('\\.').join(escPeriod);
    }
    
    function unescapeBraces(str) {
      return str.split(escSlash).join('\\')
                .split(escOpen).join('{')
                .split(escClose).join('}')
                .split(escComma).join(',')
                .split(escPeriod).join('.');
    }
    
    
    // Basically just str.split(","), but handling cases
    // where we have nested braced sections, which should be
    // treated as individual members, like {a,{b,c},d}
    function parseCommaParts(str) {
      if (!str)
        return [''];
    
      var parts = [];
      var m = balanced('{', '}', str);
    
      if (!m)
        return str.split(',');
    
      var pre = m.pre;
      var body = m.body;
      var post = m.post;
      var p = pre.split(',');
    
      p[p.length-1] += '{' + body + '}';
      var postParts = parseCommaParts(post);
      if (post.length) {
        p[p.length-1] += postParts.shift();
        p.push.apply(p, postParts);
      }
    
      parts.push.apply(parts, p);
    
      return parts;
    }
    
    function expandTop(str) {
      if (!str)
        return [];
    
      // I don't know why Bash 4.3 does this, but it does.
      // Anything starting with {} will have the first two bytes preserved
      // but *only* at the top level, so {},a}b will not expand to anything,
      // but a{},b}c will be expanded to [a}c,abc].
      // One could argue that this is a bug in Bash, but since the goal of
      // this module is to match Bash's rules, we escape a leading {}
      if (str.substr(0, 2) === '{}') {
        str = '\\{\\}' + str.substr(2);
      }
    
      return expand(escapeBraces(str), true).map(unescapeBraces);
    }
    
    function identity(e) {
      return e;
    }
    
    function embrace(str) {
      return '{' + str + '}';
    }
    function isPadded(el) {
      return /^-?0\d/.test(el);
    }
    
    function lte(i, y) {
      return i <= y;
    }
    function gte(i, y) {
      return i >= y;
    }
    
    function expand(str, isTop) {
      var expansions = [];
    
      var m = balanced('{', '}', str);
      if (!m || /\$$/.test(m.pre)) return [str];
    
      var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
      var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
      var isSequence = isNumericSequence || isAlphaSequence;
      var isOptions = m.body.indexOf(',') >= 0;
      if (!isSequence && !isOptions) {
        // {a},b}
        if (m.post.match(/,.*\}/)) {
          str = m.pre + '{' + m.body + escClose + m.post;
          return expand(str);
        }
        return [str];
      }
    
      var n;
      if (isSequence) {
        n = m.body.split(/\.\./);
      } else {
        n = parseCommaParts(m.body);
        if (n.length === 1) {
          // x{{a,b}}y ==> x{a}y x{b}y
          n = expand(n[0], false).map(embrace);
          if (n.length === 1) {
            var post = m.post.length
              ? expand(m.post, false)
              : [''];
            return post.map(function(p) {
              return m.pre + n[0] + p;
            });
          }
        }
      }
    
      // at this point, n is the parts, and we know it's not a comma set
      // with a single entry.
    
      // no need to expand pre, since it is guaranteed to be free of brace-sets
      var pre = m.pre;
      var post = m.post.length
        ? expand(m.post, false)
        : [''];
    
      var N;
    
      if (isSequence) {
        var x = numeric(n[0]);
        var y = numeric(n[1]);
        var width = Math.max(n[0].length, n[1].length)
        var incr = n.length == 3
          ? Math.abs(numeric(n[2]))
          : 1;
        var test = lte;
        var reverse = y < x;
        if (reverse) {
          incr *= -1;
          test = gte;
        }
        var pad = n.some(isPadded);
    
        N = [];
    
        for (var i = x; test(i, y); i += incr) {
          var c;
          if (isAlphaSequence) {
            c = String.fromCharCode(i);
            if (c === '\\')
              c = '';
          } else {
            c = String(i);
            if (pad) {
              var need = width - c.length;
              if (need > 0) {
                var z = new Array(need + 1).join('0');
                if (i < 0)
                  c = '-' + z + c.slice(1);
                else
                  c = z + c;
              }
            }
          }
          N.push(c);
        }
      } else {
        N = concatMap(n, function(el) { return expand(el, false) });
      }
    
      for (var j = 0; j < N.length; j++) {
        for (var k = 0; k < post.length; k++) {
          var expansion = pre + N[j] + post[k];
          if (!isTop || isSequence || expansion)
            expansions.push(expansion);
        }
      }
    
      return expansions;
    }
    
    
    },{"balanced-match":29,"concat-map":100}],35:[function(require,module,exports){
    var r;
    
    module.exports = function rand(len) {
      if (!r)
        r = new Rand(null);
    
      return r.generate(len);
    };
    
    function Rand(rand) {
      this.rand = rand;
    }
    module.exports.Rand = Rand;
    
    Rand.prototype.generate = function generate(len) {
      return this._rand(len);
    };
    
    // Emulate crypto API using randy
    Rand.prototype._rand = function _rand(n) {
      if (this.rand.getBytes)
        return this.rand.getBytes(n);
    
      var res = new Uint8Array(n);
      for (var i = 0; i < res.length; i++)
        res[i] = this.rand.getByte();
      return res;
    };
    
    if (typeof self === 'object') {
      if (self.crypto && self.crypto.getRandomValues) {
        // Modern browsers
        Rand.prototype._rand = function _rand(n) {
          var arr = new Uint8Array(n);
          self.crypto.getRandomValues(arr);
          return arr;
        };
      } else if (self.msCrypto && self.msCrypto.getRandomValues) {
        // IE
        Rand.prototype._rand = function _rand(n) {
          var arr = new Uint8Array(n);
          self.msCrypto.getRandomValues(arr);
          return arr;
        };
    
      // Safari's WebWorkers do not have `crypto`
      } else if (typeof window === 'object') {
        // Old junk
        Rand.prototype._rand = function() {
          throw new Error('Not implemented yet');
        };
      }
    } else {
      // Node.js or Web worker with no crypto support
      try {
        var crypto = require('crypto');
        if (typeof crypto.randomBytes !== 'function')
          throw new Error('Not supported');
    
        Rand.prototype._rand = function _rand(n) {
          return crypto.randomBytes(n);
        };
      } catch (e) {
      }
    }
    
    },{"crypto":36}],36:[function(require,module,exports){
    
    },{}],37:[function(require,module,exports){
    // based on the aes implimentation in triple sec
    // https://github.com/keybase/triplesec
    // which is in turn based on the one from crypto-js
    // https://code.google.com/p/crypto-js/
    
    var Buffer = require('safe-buffer').Buffer
    
    function asUInt32Array (buf) {
      if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)
    
      var len = (buf.length / 4) | 0
      var out = new Array(len)
    
      for (var i = 0; i < len; i++) {
        out[i] = buf.readUInt32BE(i * 4)
      }
    
      return out
    }
    
    function scrubVec (v) {
      for (var i = 0; i < v.length; v++) {
        v[i] = 0
      }
    }
    
    function cryptBlock (M, keySchedule, SUB_MIX, SBOX, nRounds) {
      var SUB_MIX0 = SUB_MIX[0]
      var SUB_MIX1 = SUB_MIX[1]
      var SUB_MIX2 = SUB_MIX[2]
      var SUB_MIX3 = SUB_MIX[3]
    
      var s0 = M[0] ^ keySchedule[0]
      var s1 = M[1] ^ keySchedule[1]
      var s2 = M[2] ^ keySchedule[2]
      var s3 = M[3] ^ keySchedule[3]
      var t0, t1, t2, t3
      var ksRow = 4
    
      for (var round = 1; round < nRounds; round++) {
        t0 = SUB_MIX0[s0 >>> 24] ^ SUB_MIX1[(s1 >>> 16) & 0xff] ^ SUB_MIX2[(s2 >>> 8) & 0xff] ^ SUB_MIX3[s3 & 0xff] ^ keySchedule[ksRow++]
        t1 = SUB_MIX0[s1 >>> 24] ^ SUB_MIX1[(s2 >>> 16) & 0xff] ^ SUB_MIX2[(s3 >>> 8) & 0xff] ^ SUB_MIX3[s0 & 0xff] ^ keySchedule[ksRow++]
        t2 = SUB_MIX0[s2 >>> 24] ^ SUB_MIX1[(s3 >>> 16) & 0xff] ^ SUB_MIX2[(s0 >>> 8) & 0xff] ^ SUB_MIX3[s1 & 0xff] ^ keySchedule[ksRow++]
        t3 = SUB_MIX0[s3 >>> 24] ^ SUB_MIX1[(s0 >>> 16) & 0xff] ^ SUB_MIX2[(s1 >>> 8) & 0xff] ^ SUB_MIX3[s2 & 0xff] ^ keySchedule[ksRow++]
        s0 = t0
        s1 = t1
        s2 = t2
        s3 = t3
      }
    
      t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]
      t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]
      t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]
      t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]
      t0 = t0 >>> 0
      t1 = t1 >>> 0
      t2 = t2 >>> 0
      t3 = t3 >>> 0
    
      return [t0, t1, t2, t3]
    }
    
    // AES constants
    var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]
    var G = (function () {
      // Compute double table
      var d = new Array(256)
      for (var j = 0; j < 256; j++) {
        if (j < 128) {
          d[j] = j << 1
        } else {
          d[j] = (j << 1) ^ 0x11b
        }
      }
    
      var SBOX = []
      var INV_SBOX = []
      var SUB_MIX = [[], [], [], []]
      var INV_SUB_MIX = [[], [], [], []]
    
      // Walk GF(2^8)
      var x = 0
      var xi = 0
      for (var i = 0; i < 256; ++i) {
        // Compute sbox
        var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)
        sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63
        SBOX[x] = sx
        INV_SBOX[sx] = x
    
        // Compute multiplication
        var x2 = d[x]
        var x4 = d[x2]
        var x8 = d[x4]
    
        // Compute sub bytes, mix columns tables
        var t = (d[sx] * 0x101) ^ (sx * 0x1010100)
        SUB_MIX[0][x] = (t << 24) | (t >>> 8)
        SUB_MIX[1][x] = (t << 16) | (t >>> 16)
        SUB_MIX[2][x] = (t << 8) | (t >>> 24)
        SUB_MIX[3][x] = t
    
        // Compute inv sub bytes, inv mix columns tables
        t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)
        INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)
        INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)
        INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)
        INV_SUB_MIX[3][sx] = t
    
        if (x === 0) {
          x = xi = 1
        } else {
          x = x2 ^ d[d[d[x8 ^ x2]]]
          xi ^= d[d[xi]]
        }
      }
    
      return {
        SBOX: SBOX,
        INV_SBOX: INV_SBOX,
        SUB_MIX: SUB_MIX,
        INV_SUB_MIX: INV_SUB_MIX
      }
    })()
    
    function AES (key) {
      this._key = asUInt32Array(key)
      this._reset()
    }
    
    AES.blockSize = 4 * 4
    AES.keySize = 256 / 8
    AES.prototype.blockSize = AES.blockSize
    AES.prototype.keySize = AES.keySize
    AES.prototype._reset = function () {
      var keyWords = this._key
      var keySize = keyWords.length
      var nRounds = keySize + 6
      var ksRows = (nRounds + 1) * 4
    
      var keySchedule = []
      for (var k = 0; k < keySize; k++) {
        keySchedule[k] = keyWords[k]
      }
    
      for (k = keySize; k < ksRows; k++) {
        var t = keySchedule[k - 1]
    
        if (k % keySize === 0) {
          t = (t << 8) | (t >>> 24)
          t =
            (G.SBOX[t >>> 24] << 24) |
            (G.SBOX[(t >>> 16) & 0xff] << 16) |
            (G.SBOX[(t >>> 8) & 0xff] << 8) |
            (G.SBOX[t & 0xff])
    
          t ^= RCON[(k / keySize) | 0] << 24
        } else if (keySize > 6 && k % keySize === 4) {
          t =
            (G.SBOX[t >>> 24] << 24) |
            (G.SBOX[(t >>> 16) & 0xff] << 16) |
            (G.SBOX[(t >>> 8) & 0xff] << 8) |
            (G.SBOX[t & 0xff])
        }
    
        keySchedule[k] = keySchedule[k - keySize] ^ t
      }
    
      var invKeySchedule = []
      for (var ik = 0; ik < ksRows; ik++) {
        var ksR = ksRows - ik
        var tt = keySchedule[ksR - (ik % 4 ? 0 : 4)]
    
        if (ik < 4 || ksR <= 4) {
          invKeySchedule[ik] = tt
        } else {
          invKeySchedule[ik] =
            G.INV_SUB_MIX[0][G.SBOX[tt >>> 24]] ^
            G.INV_SUB_MIX[1][G.SBOX[(tt >>> 16) & 0xff]] ^
            G.INV_SUB_MIX[2][G.SBOX[(tt >>> 8) & 0xff]] ^
            G.INV_SUB_MIX[3][G.SBOX[tt & 0xff]]
        }
      }
    
      this._nRounds = nRounds
      this._keySchedule = keySchedule
      this._invKeySchedule = invKeySchedule
    }
    
    AES.prototype.encryptBlockRaw = function (M) {
      M = asUInt32Array(M)
      return cryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX, this._nRounds)
    }
    
    AES.prototype.encryptBlock = function (M) {
      var out = this.encryptBlockRaw(M)
      var buf = Buffer.allocUnsafe(16)
      buf.writeUInt32BE(out[0], 0)
      buf.writeUInt32BE(out[1], 4)
      buf.writeUInt32BE(out[2], 8)
      buf.writeUInt32BE(out[3], 12)
      return buf
    }
    
    AES.prototype.decryptBlock = function (M) {
      M = asUInt32Array(M)
    
      // swap
      var m1 = M[1]
      M[1] = M[3]
      M[3] = m1
    
      var out = cryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX, this._nRounds)
      var buf = Buffer.allocUnsafe(16)
      buf.writeUInt32BE(out[0], 0)
      buf.writeUInt32BE(out[3], 4)
      buf.writeUInt32BE(out[2], 8)
      buf.writeUInt32BE(out[1], 12)
      return buf
    }
    
    AES.prototype.scrub = function () {
      scrubVec(this._keySchedule)
      scrubVec(this._invKeySchedule)
      scrubVec(this._key)
    }
    
    module.exports.AES = AES
    
    },{"safe-buffer":338}],38:[function(require,module,exports){
    var aes = require('./aes')
    var Buffer = require('safe-buffer').Buffer
    var Transform = require('cipher-base')
    var inherits = require('inherits')
    var GHASH = require('./ghash')
    var xor = require('buffer-xor')
    var incr32 = require('./incr32')
    
    function xorTest (a, b) {
      var out = 0
      if (a.length !== b.length) out++
    
      var len = Math.min(a.length, b.length)
      for (var i = 0; i < len; ++i) {
        out += (a[i] ^ b[i])
      }
    
      return out
    }
    
    function calcIv (self, iv, ck) {
      if (iv.length === 12) {
        self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])
        return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])
      }
      var ghash = new GHASH(ck)
      var len = iv.length
      var toPad = len % 16
      ghash.update(iv)
      if (toPad) {
        toPad = 16 - toPad
        ghash.update(Buffer.alloc(toPad, 0))
      }
      ghash.update(Buffer.alloc(8, 0))
      var ivBits = len * 8
      var tail = Buffer.alloc(8)
      tail.writeUIntBE(ivBits, 0, 8)
      ghash.update(tail)
      self._finID = ghash.state
      var out = Buffer.from(self._finID)
      incr32(out)
      return out
    }
    function StreamCipher (mode, key, iv, decrypt) {
      Transform.call(this)
    
      var h = Buffer.alloc(4, 0)
    
      this._cipher = new aes.AES(key)
      var ck = this._cipher.encryptBlock(h)
      this._ghash = new GHASH(ck)
      iv = calcIv(this, iv, ck)
    
      this._prev = Buffer.from(iv)
      this._cache = Buffer.allocUnsafe(0)
      this._secCache = Buffer.allocUnsafe(0)
      this._decrypt = decrypt
      this._alen = 0
      this._len = 0
      this._mode = mode
    
      this._authTag = null
      this._called = false
    }
    
    inherits(StreamCipher, Transform)
    
    StreamCipher.prototype._update = function (chunk) {
      if (!this._called && this._alen) {
        var rump = 16 - (this._alen % 16)
        if (rump < 16) {
          rump = Buffer.alloc(rump, 0)
          this._ghash.update(rump)
        }
      }
    
      this._called = true
      var out = this._mode.encrypt(this, chunk)
      if (this._decrypt) {
        this._ghash.update(chunk)
      } else {
        this._ghash.update(out)
      }
      this._len += chunk.length
      return out
    }
    
    StreamCipher.prototype._final = function () {
      if (this._decrypt && !this._authTag) throw new Error('Unsupported state or unable to authenticate data')
    
      var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))
      if (this._decrypt && xorTest(tag, this._authTag)) throw new Error('Unsupported state or unable to authenticate data')
    
      this._authTag = tag
      this._cipher.scrub()
    }
    
    StreamCipher.prototype.getAuthTag = function getAuthTag () {
      if (this._decrypt || !Buffer.isBuffer(this._authTag)) throw new Error('Attempting to get auth tag in unsupported state')
    
      return this._authTag
    }
    
    StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {
      if (!this._decrypt) throw new Error('Attempting to set auth tag in unsupported state')
    
      this._authTag = tag
    }
    
    StreamCipher.prototype.setAAD = function setAAD (buf) {
      if (this._called) throw new Error('Attempting to set AAD in unsupported state')
    
      this._ghash.update(buf)
      this._alen += buf.length
    }
    
    module.exports = StreamCipher
    
    },{"./aes":37,"./ghash":42,"./incr32":43,"buffer-xor":86,"cipher-base":94,"inherits":182,"safe-buffer":338}],39:[function(require,module,exports){
    var ciphers = require('./encrypter')
    var deciphers = require('./decrypter')
    var modes = require('./modes/list.json')
    
    function getCiphers () {
      return Object.keys(modes)
    }
    
    exports.createCipher = exports.Cipher = ciphers.createCipher
    exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv
    exports.createDecipher = exports.Decipher = deciphers.createDecipher
    exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv
    exports.listCiphers = exports.getCiphers = getCiphers
    
    },{"./decrypter":40,"./encrypter":41,"./modes/list.json":51}],40:[function(require,module,exports){
    var AuthCipher = require('./authCipher')
    var Buffer = require('safe-buffer').Buffer
    var MODES = require('./modes')
    var StreamCipher = require('./streamCipher')
    var Transform = require('cipher-base')
    var aes = require('./aes')
    var ebtk = require('evp_bytestokey')
    var inherits = require('inherits')
    
    function Decipher (mode, key, iv) {
      Transform.call(this)
    
      this._cache = new Splitter()
      this._last = void 0
      this._cipher = new aes.AES(key)
      this._prev = Buffer.from(iv)
      this._mode = mode
      this._autopadding = true
    }
    
    inherits(Decipher, Transform)
    
    Decipher.prototype._update = function (data) {
      this._cache.add(data)
      var chunk
      var thing
      var out = []
      while ((chunk = this._cache.get(this._autopadding))) {
        thing = this._mode.decrypt(this, chunk)
        out.push(thing)
      }
      return Buffer.concat(out)
    }
    
    Decipher.prototype._final = function () {
      var chunk = this._cache.flush()
      if (this._autopadding) {
        return unpad(this._mode.decrypt(this, chunk))
      } else if (chunk) {
        throw new Error('data not multiple of block length')
      }
    }
    
    Decipher.prototype.setAutoPadding = function (setTo) {
      this._autopadding = !!setTo
      return this
    }
    
    function Splitter () {
      this.cache = Buffer.allocUnsafe(0)
    }
    
    Splitter.prototype.add = function (data) {
      this.cache = Buffer.concat([this.cache, data])
    }
    
    Splitter.prototype.get = function (autoPadding) {
      var out
      if (autoPadding) {
        if (this.cache.length > 16) {
          out = this.cache.slice(0, 16)
          this.cache = this.cache.slice(16)
          return out
        }
      } else {
        if (this.cache.length >= 16) {
          out = this.cache.slice(0, 16)
          this.cache = this.cache.slice(16)
          return out
        }
      }
    
      return null
    }
    
    Splitter.prototype.flush = function () {
      if (this.cache.length) return this.cache
    }
    
    function unpad (last) {
      var padded = last[15]
      if (padded < 1 || padded > 16) {
        throw new Error('unable to decrypt data')
      }
      var i = -1
      while (++i < padded) {
        if (last[(i + (16 - padded))] !== padded) {
          throw new Error('unable to decrypt data')
        }
      }
      if (padded === 16) return
    
      return last.slice(0, 16 - padded)
    }
    
    function createDecipheriv (suite, password, iv) {
      var config = MODES[suite.toLowerCase()]
      if (!config) throw new TypeError('invalid suite type')
    
      if (typeof iv === 'string') iv = Buffer.from(iv)
      if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
    
      if (typeof password === 'string') password = Buffer.from(password)
      if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
    
      if (config.type === 'stream') {
        return new StreamCipher(config.module, password, iv, true)
      } else if (config.type === 'auth') {
        return new AuthCipher(config.module, password, iv, true)
      }
    
      return new Decipher(config.module, password, iv)
    }
    
    function createDecipher (suite, password) {
      var config = MODES[suite.toLowerCase()]
      if (!config) throw new TypeError('invalid suite type')
    
      var keys = ebtk(password, false, config.key, config.iv)
      return createDecipheriv(suite, keys.key, keys.iv)
    }
    
    exports.createDecipher = createDecipher
    exports.createDecipheriv = createDecipheriv
    
    },{"./aes":37,"./authCipher":38,"./modes":50,"./streamCipher":53,"cipher-base":94,"evp_bytestokey":135,"inherits":182,"safe-buffer":338}],41:[function(require,module,exports){
    var MODES = require('./modes')
    var AuthCipher = require('./authCipher')
    var Buffer = require('safe-buffer').Buffer
    var StreamCipher = require('./streamCipher')
    var Transform = require('cipher-base')
    var aes = require('./aes')
    var ebtk = require('evp_bytestokey')
    var inherits = require('inherits')
    
    function Cipher (mode, key, iv) {
      Transform.call(this)
    
      this._cache = new Splitter()
      this._cipher = new aes.AES(key)
      this._prev = Buffer.from(iv)
      this._mode = mode
      this._autopadding = true
    }
    
    inherits(Cipher, Transform)
    
    Cipher.prototype._update = function (data) {
      this._cache.add(data)
      var chunk
      var thing
      var out = []
    
      while ((chunk = this._cache.get())) {
        thing = this._mode.encrypt(this, chunk)
        out.push(thing)
      }
    
      return Buffer.concat(out)
    }
    
    var PADDING = Buffer.alloc(16, 0x10)
    
    Cipher.prototype._final = function () {
      var chunk = this._cache.flush()
      if (this._autopadding) {
        chunk = this._mode.encrypt(this, chunk)
        this._cipher.scrub()
        return chunk
      }
    
      if (!chunk.equals(PADDING)) {
        this._cipher.scrub()
        throw new Error('data not multiple of block length')
      }
    }
    
    Cipher.prototype.setAutoPadding = function (setTo) {
      this._autopadding = !!setTo
      return this
    }
    
    function Splitter () {
      this.cache = Buffer.allocUnsafe(0)
    }
    
    Splitter.prototype.add = function (data) {
      this.cache = Buffer.concat([this.cache, data])
    }
    
    Splitter.prototype.get = function () {
      if (this.cache.length > 15) {
        var out = this.cache.slice(0, 16)
        this.cache = this.cache.slice(16)
        return out
      }
      return null
    }
    
    Splitter.prototype.flush = function () {
      var len = 16 - this.cache.length
      var padBuff = Buffer.allocUnsafe(len)
    
      var i = -1
      while (++i < len) {
        padBuff.writeUInt8(len, i)
      }
    
      return Buffer.concat([this.cache, padBuff])
    }
    
    function createCipheriv (suite, password, iv) {
      var config = MODES[suite.toLowerCase()]
      if (!config) throw new TypeError('invalid suite type')
    
      if (typeof password === 'string') password = Buffer.from(password)
      if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)
    
      if (typeof iv === 'string') iv = Buffer.from(iv)
      if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)
    
      if (config.type === 'stream') {
        return new StreamCipher(config.module, password, iv)
      } else if (config.type === 'auth') {
        return new AuthCipher(config.module, password, iv)
      }
    
      return new Cipher(config.module, password, iv)
    }
    
    function createCipher (suite, password) {
      var config = MODES[suite.toLowerCase()]
      if (!config) throw new TypeError('invalid suite type')
    
      var keys = ebtk(password, false, config.key, config.iv)
      return createCipheriv(suite, keys.key, keys.iv)
    }
    
    exports.createCipheriv = createCipheriv
    exports.createCipher = createCipher
    
    },{"./aes":37,"./authCipher":38,"./modes":50,"./streamCipher":53,"cipher-base":94,"evp_bytestokey":135,"inherits":182,"safe-buffer":338}],42:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    var ZEROES = Buffer.alloc(16, 0)
    
    function toArray (buf) {
      return [
        buf.readUInt32BE(0),
        buf.readUInt32BE(4),
        buf.readUInt32BE(8),
        buf.readUInt32BE(12)
      ]
    }
    
    function fromArray (out) {
      var buf = Buffer.allocUnsafe(16)
      buf.writeUInt32BE(out[0] >>> 0, 0)
      buf.writeUInt32BE(out[1] >>> 0, 4)
      buf.writeUInt32BE(out[2] >>> 0, 8)
      buf.writeUInt32BE(out[3] >>> 0, 12)
      return buf
    }
    
    function GHASH (key) {
      this.h = key
      this.state = Buffer.alloc(16, 0)
      this.cache = Buffer.allocUnsafe(0)
    }
    
    // from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html
    // by Juho Vähä-Herttua
    GHASH.prototype.ghash = function (block) {
      var i = -1
      while (++i < block.length) {
        this.state[i] ^= block[i]
      }
      this._multiply()
    }
    
    GHASH.prototype._multiply = function () {
      var Vi = toArray(this.h)
      var Zi = [0, 0, 0, 0]
      var j, xi, lsbVi
      var i = -1
      while (++i < 128) {
        xi = (this.state[~~(i / 8)] & (1 << (7 - (i % 8)))) !== 0
        if (xi) {
          // Z_i+1 = Z_i ^ V_i
          Zi[0] ^= Vi[0]
          Zi[1] ^= Vi[1]
          Zi[2] ^= Vi[2]
          Zi[3] ^= Vi[3]
        }
    
        // Store the value of LSB(V_i)
        lsbVi = (Vi[3] & 1) !== 0
    
        // V_i+1 = V_i >> 1
        for (j = 3; j > 0; j--) {
          Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)
        }
        Vi[0] = Vi[0] >>> 1
    
        // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R
        if (lsbVi) {
          Vi[0] = Vi[0] ^ (0xe1 << 24)
        }
      }
      this.state = fromArray(Zi)
    }
    
    GHASH.prototype.update = function (buf) {
      this.cache = Buffer.concat([this.cache, buf])
      var chunk
      while (this.cache.length >= 16) {
        chunk = this.cache.slice(0, 16)
        this.cache = this.cache.slice(16)
        this.ghash(chunk)
      }
    }
    
    GHASH.prototype.final = function (abl, bl) {
      if (this.cache.length) {
        this.ghash(Buffer.concat([this.cache, ZEROES], 16))
      }
    
      this.ghash(fromArray([0, abl, 0, bl]))
      return this.state
    }
    
    module.exports = GHASH
    
    },{"safe-buffer":338}],43:[function(require,module,exports){
    function incr32 (iv) {
      var len = iv.length
      var item
      while (len--) {
        item = iv.readUInt8(len)
        if (item === 255) {
          iv.writeUInt8(0, len)
        } else {
          item++
          iv.writeUInt8(item, len)
          break
        }
      }
    }
    module.exports = incr32
    
    },{}],44:[function(require,module,exports){
    var xor = require('buffer-xor')
    
    exports.encrypt = function (self, block) {
      var data = xor(block, self._prev)
    
      self._prev = self._cipher.encryptBlock(data)
      return self._prev
    }
    
    exports.decrypt = function (self, block) {
      var pad = self._prev
    
      self._prev = block
      var out = self._cipher.decryptBlock(block)
    
      return xor(out, pad)
    }
    
    },{"buffer-xor":86}],45:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    var xor = require('buffer-xor')
    
    function encryptStart (self, data, decrypt) {
      var len = data.length
      var out = xor(data, self._cache)
      self._cache = self._cache.slice(len)
      self._prev = Buffer.concat([self._prev, decrypt ? data : out])
      return out
    }
    
    exports.encrypt = function (self, data, decrypt) {
      var out = Buffer.allocUnsafe(0)
      var len
    
      while (data.length) {
        if (self._cache.length === 0) {
          self._cache = self._cipher.encryptBlock(self._prev)
          self._prev = Buffer.allocUnsafe(0)
        }
    
        if (self._cache.length <= data.length) {
          len = self._cache.length
          out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])
          data = data.slice(len)
        } else {
          out = Buffer.concat([out, encryptStart(self, data, decrypt)])
          break
        }
      }
    
      return out
    }
    
    },{"buffer-xor":86,"safe-buffer":338}],46:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    
    function encryptByte (self, byteParam, decrypt) {
      var pad
      var i = -1
      var len = 8
      var out = 0
      var bit, value
      while (++i < len) {
        pad = self._cipher.encryptBlock(self._prev)
        bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0
        value = pad[0] ^ bit
        out += ((value & 0x80) >> (i % 8))
        self._prev = shiftIn(self._prev, decrypt ? bit : value)
      }
      return out
    }
    
    function shiftIn (buffer, value) {
      var len = buffer.length
      var i = -1
      var out = Buffer.allocUnsafe(buffer.length)
      buffer = Buffer.concat([buffer, Buffer.from([value])])
    
      while (++i < len) {
        out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)
      }
    
      return out
    }
    
    exports.encrypt = function (self, chunk, decrypt) {
      var len = chunk.length
      var out = Buffer.allocUnsafe(len)
      var i = -1
    
      while (++i < len) {
        out[i] = encryptByte(self, chunk[i], decrypt)
      }
    
      return out
    }
    
    },{"safe-buffer":338}],47:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    
    function encryptByte (self, byteParam, decrypt) {
      var pad = self._cipher.encryptBlock(self._prev)
      var out = pad[0] ^ byteParam
    
      self._prev = Buffer.concat([
        self._prev.slice(1),
        Buffer.from([decrypt ? byteParam : out])
      ])
    
      return out
    }
    
    exports.encrypt = function (self, chunk, decrypt) {
      var len = chunk.length
      var out = Buffer.allocUnsafe(len)
      var i = -1
    
      while (++i < len) {
        out[i] = encryptByte(self, chunk[i], decrypt)
      }
    
      return out
    }
    
    },{"safe-buffer":338}],48:[function(require,module,exports){
    var xor = require('buffer-xor')
    var Buffer = require('safe-buffer').Buffer
    var incr32 = require('../incr32')
    
    function getBlock (self) {
      var out = self._cipher.encryptBlockRaw(self._prev)
      incr32(self._prev)
      return out
    }
    
    var blockSize = 16
    exports.encrypt = function (self, chunk) {
      var chunkNum = Math.ceil(chunk.length / blockSize)
      var start = self._cache.length
      self._cache = Buffer.concat([
        self._cache,
        Buffer.allocUnsafe(chunkNum * blockSize)
      ])
      for (var i = 0; i < chunkNum; i++) {
        var out = getBlock(self)
        var offset = start + i * blockSize
        self._cache.writeUInt32BE(out[0], offset + 0)
        self._cache.writeUInt32BE(out[1], offset + 4)
        self._cache.writeUInt32BE(out[2], offset + 8)
        self._cache.writeUInt32BE(out[3], offset + 12)
      }
      var pad = self._cache.slice(0, chunk.length)
      self._cache = self._cache.slice(chunk.length)
      return xor(chunk, pad)
    }
    
    },{"../incr32":43,"buffer-xor":86,"safe-buffer":338}],49:[function(require,module,exports){
    exports.encrypt = function (self, block) {
      return self._cipher.encryptBlock(block)
    }
    
    exports.decrypt = function (self, block) {
      return self._cipher.decryptBlock(block)
    }
    
    },{}],50:[function(require,module,exports){
    var modeModules = {
      ECB: require('./ecb'),
      CBC: require('./cbc'),
      CFB: require('./cfb'),
      CFB8: require('./cfb8'),
      CFB1: require('./cfb1'),
      OFB: require('./ofb'),
      CTR: require('./ctr'),
      GCM: require('./ctr')
    }
    
    var modes = require('./list.json')
    
    for (var key in modes) {
      modes[key].module = modeModules[modes[key].mode]
    }
    
    module.exports = modes
    
    },{"./cbc":44,"./cfb":45,"./cfb1":46,"./cfb8":47,"./ctr":48,"./ecb":49,"./list.json":51,"./ofb":52}],51:[function(require,module,exports){
    module.exports={
      "aes-128-ecb": {
        "cipher": "AES",
        "key": 128,
        "iv": 0,
        "mode": "ECB",
        "type": "block"
      },
      "aes-192-ecb": {
        "cipher": "AES",
        "key": 192,
        "iv": 0,
        "mode": "ECB",
        "type": "block"
      },
      "aes-256-ecb": {
        "cipher": "AES",
        "key": 256,
        "iv": 0,
        "mode": "ECB",
        "type": "block"
      },
      "aes-128-cbc": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes-192-cbc": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes-256-cbc": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes128": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes192": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes256": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CBC",
        "type": "block"
      },
      "aes-128-cfb": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CFB",
        "type": "stream"
      },
      "aes-192-cfb": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CFB",
        "type": "stream"
      },
      "aes-256-cfb": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CFB",
        "type": "stream"
      },
      "aes-128-cfb8": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CFB8",
        "type": "stream"
      },
      "aes-192-cfb8": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CFB8",
        "type": "stream"
      },
      "aes-256-cfb8": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CFB8",
        "type": "stream"
      },
      "aes-128-cfb1": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CFB1",
        "type": "stream"
      },
      "aes-192-cfb1": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CFB1",
        "type": "stream"
      },
      "aes-256-cfb1": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CFB1",
        "type": "stream"
      },
      "aes-128-ofb": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "OFB",
        "type": "stream"
      },
      "aes-192-ofb": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "OFB",
        "type": "stream"
      },
      "aes-256-ofb": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "OFB",
        "type": "stream"
      },
      "aes-128-ctr": {
        "cipher": "AES",
        "key": 128,
        "iv": 16,
        "mode": "CTR",
        "type": "stream"
      },
      "aes-192-ctr": {
        "cipher": "AES",
        "key": 192,
        "iv": 16,
        "mode": "CTR",
        "type": "stream"
      },
      "aes-256-ctr": {
        "cipher": "AES",
        "key": 256,
        "iv": 16,
        "mode": "CTR",
        "type": "stream"
      },
      "aes-128-gcm": {
        "cipher": "AES",
        "key": 128,
        "iv": 12,
        "mode": "GCM",
        "type": "auth"
      },
      "aes-192-gcm": {
        "cipher": "AES",
        "key": 192,
        "iv": 12,
        "mode": "GCM",
        "type": "auth"
      },
      "aes-256-gcm": {
        "cipher": "AES",
        "key": 256,
        "iv": 12,
        "mode": "GCM",
        "type": "auth"
      }
    }
    
    },{}],52:[function(require,module,exports){
    (function (Buffer){(function (){
    var xor = require('buffer-xor')
    
    function getBlock (self) {
      self._prev = self._cipher.encryptBlock(self._prev)
      return self._prev
    }
    
    exports.encrypt = function (self, chunk) {
      while (self._cache.length < chunk.length) {
        self._cache = Buffer.concat([self._cache, getBlock(self)])
      }
    
      var pad = self._cache.slice(0, chunk.length)
      self._cache = self._cache.slice(chunk.length)
      return xor(chunk, pad)
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84,"buffer-xor":86}],53:[function(require,module,exports){
    var aes = require('./aes')
    var Buffer = require('safe-buffer').Buffer
    var Transform = require('cipher-base')
    var inherits = require('inherits')
    
    function StreamCipher (mode, key, iv, decrypt) {
      Transform.call(this)
    
      this._cipher = new aes.AES(key)
      this._prev = Buffer.from(iv)
      this._cache = Buffer.allocUnsafe(0)
      this._secCache = Buffer.allocUnsafe(0)
      this._decrypt = decrypt
      this._mode = mode
    }
    
    inherits(StreamCipher, Transform)
    
    StreamCipher.prototype._update = function (chunk) {
      return this._mode.encrypt(this, chunk, this._decrypt)
    }
    
    StreamCipher.prototype._final = function () {
      this._cipher.scrub()
    }
    
    module.exports = StreamCipher
    
    },{"./aes":37,"cipher-base":94,"inherits":182,"safe-buffer":338}],54:[function(require,module,exports){
    var DES = require('browserify-des')
    var aes = require('browserify-aes/browser')
    var aesModes = require('browserify-aes/modes')
    var desModes = require('browserify-des/modes')
    var ebtk = require('evp_bytestokey')
    
    function createCipher (suite, password) {
      suite = suite.toLowerCase()
    
      var keyLen, ivLen
      if (aesModes[suite]) {
        keyLen = aesModes[suite].key
        ivLen = aesModes[suite].iv
      } else if (desModes[suite]) {
        keyLen = desModes[suite].key * 8
        ivLen = desModes[suite].iv
      } else {
        throw new TypeError('invalid suite type')
      }
    
      var keys = ebtk(password, false, keyLen, ivLen)
      return createCipheriv(suite, keys.key, keys.iv)
    }
    
    function createDecipher (suite, password) {
      suite = suite.toLowerCase()
    
      var keyLen, ivLen
      if (aesModes[suite]) {
        keyLen = aesModes[suite].key
        ivLen = aesModes[suite].iv
      } else if (desModes[suite]) {
        keyLen = desModes[suite].key * 8
        ivLen = desModes[suite].iv
      } else {
        throw new TypeError('invalid suite type')
      }
    
      var keys = ebtk(password, false, keyLen, ivLen)
      return createDecipheriv(suite, keys.key, keys.iv)
    }
    
    function createCipheriv (suite, key, iv) {
      suite = suite.toLowerCase()
      if (aesModes[suite]) return aes.createCipheriv(suite, key, iv)
      if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite })
    
      throw new TypeError('invalid suite type')
    }
    
    function createDecipheriv (suite, key, iv) {
      suite = suite.toLowerCase()
      if (aesModes[suite]) return aes.createDecipheriv(suite, key, iv)
      if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite, decrypt: true })
    
      throw new TypeError('invalid suite type')
    }
    
    function getCiphers () {
      return Object.keys(desModes).concat(aes.getCiphers())
    }
    
    exports.createCipher = exports.Cipher = createCipher
    exports.createCipheriv = exports.Cipheriv = createCipheriv
    exports.createDecipher = exports.Decipher = createDecipher
    exports.createDecipheriv = exports.Decipheriv = createDecipheriv
    exports.listCiphers = exports.getCiphers = getCiphers
    
    },{"browserify-aes/browser":39,"browserify-aes/modes":50,"browserify-des":55,"browserify-des/modes":56,"evp_bytestokey":135}],55:[function(require,module,exports){
    var CipherBase = require('cipher-base')
    var des = require('des.js')
    var inherits = require('inherits')
    var Buffer = require('safe-buffer').Buffer
    
    var modes = {
      'des-ede3-cbc': des.CBC.instantiate(des.EDE),
      'des-ede3': des.EDE,
      'des-ede-cbc': des.CBC.instantiate(des.EDE),
      'des-ede': des.EDE,
      'des-cbc': des.CBC.instantiate(des.DES),
      'des-ecb': des.DES
    }
    modes.des = modes['des-cbc']
    modes.des3 = modes['des-ede3-cbc']
    module.exports = DES
    inherits(DES, CipherBase)
    function DES (opts) {
      CipherBase.call(this)
      var modeName = opts.mode.toLowerCase()
      var mode = modes[modeName]
      var type
      if (opts.decrypt) {
        type = 'decrypt'
      } else {
        type = 'encrypt'
      }
      var key = opts.key
      if (!Buffer.isBuffer(key)) {
        key = Buffer.from(key)
      }
      if (modeName === 'des-ede' || modeName === 'des-ede-cbc') {
        key = Buffer.concat([key, key.slice(0, 8)])
      }
      var iv = opts.iv
      if (!Buffer.isBuffer(iv)) {
        iv = Buffer.from(iv)
      }
      this._des = mode.create({
        key: key,
        iv: iv,
        type: type
      })
    }
    DES.prototype._update = function (data) {
      return Buffer.from(this._des.update(data))
    }
    DES.prototype._final = function () {
      return Buffer.from(this._des.final())
    }
    
    },{"cipher-base":94,"des.js":108,"inherits":182,"safe-buffer":338}],56:[function(require,module,exports){
    exports['des-ecb'] = {
      key: 8,
      iv: 0
    }
    exports['des-cbc'] = exports.des = {
      key: 8,
      iv: 8
    }
    exports['des-ede3-cbc'] = exports.des3 = {
      key: 24,
      iv: 8
    }
    exports['des-ede3'] = {
      key: 24,
      iv: 0
    }
    exports['des-ede-cbc'] = {
      key: 16,
      iv: 8
    }
    exports['des-ede'] = {
      key: 16,
      iv: 0
    }
    
    },{}],57:[function(require,module,exports){
    (function (Buffer){(function (){
    var BN = require('bn.js')
    var randomBytes = require('randombytes')
    
    function blind (priv) {
      var r = getr(priv)
      var blinder = r.toRed(BN.mont(priv.modulus)).redPow(new BN(priv.publicExponent)).fromRed()
      return { blinder: blinder, unblinder: r.invm(priv.modulus) }
    }
    
    function getr (priv) {
      var len = priv.modulus.byteLength()
      var r
      do {
        r = new BN(randomBytes(len))
      } while (r.cmp(priv.modulus) >= 0 || !r.umod(priv.prime1) || !r.umod(priv.prime2))
      return r
    }
    
    function crt (msg, priv) {
      var blinds = blind(priv)
      var len = priv.modulus.byteLength()
      var blinded = new BN(msg).mul(blinds.blinder).umod(priv.modulus)
      var c1 = blinded.toRed(BN.mont(priv.prime1))
      var c2 = blinded.toRed(BN.mont(priv.prime2))
      var qinv = priv.coefficient
      var p = priv.prime1
      var q = priv.prime2
      var m1 = c1.redPow(priv.exponent1).fromRed()
      var m2 = c2.redPow(priv.exponent2).fromRed()
      var h = m1.isub(m2).imul(qinv).umod(p).imul(q)
      return m2.iadd(h).imul(blinds.unblinder).umod(priv.modulus).toArrayLike(Buffer, 'be', len)
    }
    crt.getr = getr
    
    module.exports = crt
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"bn.js":58,"buffer":84,"randombytes":334}],58:[function(require,module,exports){
    (function (module, exports) {
      'use strict';
    
      // Utils
      function assert (val, msg) {
        if (!val) throw new Error(msg || 'Assertion failed');
      }
    
      // Could use `inherits` module, but don't want to move from single file
      // architecture yet.
      function inherits (ctor, superCtor) {
        ctor.super_ = superCtor;
        var TempCtor = function () {};
        TempCtor.prototype = superCtor.prototype;
        ctor.prototype = new TempCtor();
        ctor.prototype.constructor = ctor;
      }
    
      // BN
    
      function BN (number, base, endian) {
        if (BN.isBN(number)) {
          return number;
        }
    
        this.negative = 0;
        this.words = null;
        this.length = 0;
    
        // Reduction context
        this.red = null;
    
        if (number !== null) {
          if (base === 'le' || base === 'be') {
            endian = base;
            base = 10;
          }
    
          this._init(number || 0, base || 10, endian || 'be');
        }
      }
      if (typeof module === 'object') {
        module.exports = BN;
      } else {
        exports.BN = BN;
      }
    
      BN.BN = BN;
      BN.wordSize = 26;
    
      var Buffer;
      try {
        if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') {
          Buffer = window.Buffer;
        } else {
          Buffer = require('buffer').Buffer;
        }
      } catch (e) {
      }
    
      BN.isBN = function isBN (num) {
        if (num instanceof BN) {
          return true;
        }
    
        return num !== null && typeof num === 'object' &&
          num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
      };
    
      BN.max = function max (left, right) {
        if (left.cmp(right) > 0) return left;
        return right;
      };
    
      BN.min = function min (left, right) {
        if (left.cmp(right) < 0) return left;
        return right;
      };
    
      BN.prototype._init = function init (number, base, endian) {
        if (typeof number === 'number') {
          return this._initNumber(number, base, endian);
        }
    
        if (typeof number === 'object') {
          return this._initArray(number, base, endian);
        }
    
        if (base === 'hex') {
          base = 16;
        }
        assert(base === (base | 0) && base >= 2 && base <= 36);
    
        number = number.toString().replace(/\s+/g, '');
        var start = 0;
        if (number[0] === '-') {
          start++;
          this.negative = 1;
        }
    
        if (start < number.length) {
          if (base === 16) {
            this._parseHex(number, start, endian);
          } else {
            this._parseBase(number, base, start);
            if (endian === 'le') {
              this._initArray(this.toArray(), base, endian);
            }
          }
        }
      };
    
      BN.prototype._initNumber = function _initNumber (number, base, endian) {
        if (number < 0) {
          this.negative = 1;
          number = -number;
        }
        if (number < 0x4000000) {
          this.words = [number & 0x3ffffff];
          this.length = 1;
        } else if (number < 0x10000000000000) {
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff
          ];
          this.length = 2;
        } else {
          assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff,
            1
          ];
          this.length = 3;
        }
    
        if (endian !== 'le') return;
    
        // Reverse the bytes
        this._initArray(this.toArray(), base, endian);
      };
    
      BN.prototype._initArray = function _initArray (number, base, endian) {
        // Perhaps a Uint8Array
        assert(typeof number.length === 'number');
        if (number.length <= 0) {
          this.words = [0];
          this.length = 1;
          return this;
        }
    
        this.length = Math.ceil(number.length / 3);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        var j, w;
        var off = 0;
        if (endian === 'be') {
          for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
            w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        } else if (endian === 'le') {
          for (i = 0, j = 0; i < number.length; i += 3) {
            w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        }
        return this._strip();
      };
    
      function parseHex4Bits (string, index) {
        var c = string.charCodeAt(index);
        // '0' - '9'
        if (c >= 48 && c <= 57) {
          return c - 48;
        // 'A' - 'F'
        } else if (c >= 65 && c <= 70) {
          return c - 55;
        // 'a' - 'f'
        } else if (c >= 97 && c <= 102) {
          return c - 87;
        } else {
          assert(false, 'Invalid character in ' + string);
        }
      }
    
      function parseHexByte (string, lowerBound, index) {
        var r = parseHex4Bits(string, index);
        if (index - 1 >= lowerBound) {
          r |= parseHex4Bits(string, index - 1) << 4;
        }
        return r;
      }
    
      BN.prototype._parseHex = function _parseHex (number, start, endian) {
        // Create possibly bigger array to ensure that it fits the number
        this.length = Math.ceil((number.length - start) / 6);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        // 24-bits chunks
        var off = 0;
        var j = 0;
    
        var w;
        if (endian === 'be') {
          for (i = number.length - 1; i >= start; i -= 2) {
            w = parseHexByte(number, start, i) << off;
            this.words[j] |= w & 0x3ffffff;
            if (off >= 18) {
              off -= 18;
              j += 1;
              this.words[j] |= w >>> 26;
            } else {
              off += 8;
            }
          }
        } else {
          var parseLength = number.length - start;
          for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) {
            w = parseHexByte(number, start, i) << off;
            this.words[j] |= w & 0x3ffffff;
            if (off >= 18) {
              off -= 18;
              j += 1;
              this.words[j] |= w >>> 26;
            } else {
              off += 8;
            }
          }
        }
    
        this._strip();
      };
    
      function parseBase (str, start, end, mul) {
        var r = 0;
        var b = 0;
        var len = Math.min(str.length, end);
        for (var i = start; i < len; i++) {
          var c = str.charCodeAt(i) - 48;
    
          r *= mul;
    
          // 'a'
          if (c >= 49) {
            b = c - 49 + 0xa;
    
          // 'A'
          } else if (c >= 17) {
            b = c - 17 + 0xa;
    
          // '0' - '9'
          } else {
            b = c;
          }
          assert(c >= 0 && b < mul, 'Invalid character');
          r += b;
        }
        return r;
      }
    
      BN.prototype._parseBase = function _parseBase (number, base, start) {
        // Initialize as zero
        this.words = [0];
        this.length = 1;
    
        // Find length of limb in base
        for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
          limbLen++;
        }
        limbLen--;
        limbPow = (limbPow / base) | 0;
    
        var total = number.length - start;
        var mod = total % limbLen;
        var end = Math.min(total, total - mod) + start;
    
        var word = 0;
        for (var i = start; i < end; i += limbLen) {
          word = parseBase(number, i, i + limbLen, base);
    
          this.imuln(limbPow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
    
        if (mod !== 0) {
          var pow = 1;
          word = parseBase(number, i, number.length, base);
    
          for (i = 0; i < mod; i++) {
            pow *= base;
          }
    
          this.imuln(pow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
    
        this._strip();
      };
    
      BN.prototype.copy = function copy (dest) {
        dest.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          dest.words[i] = this.words[i];
        }
        dest.length = this.length;
        dest.negative = this.negative;
        dest.red = this.red;
      };
    
      function move (dest, src) {
        dest.words = src.words;
        dest.length = src.length;
        dest.negative = src.negative;
        dest.red = src.red;
      }
    
      BN.prototype._move = function _move (dest) {
        move(dest, this);
      };
    
      BN.prototype.clone = function clone () {
        var r = new BN(null);
        this.copy(r);
        return r;
      };
    
      BN.prototype._expand = function _expand (size) {
        while (this.length < size) {
          this.words[this.length++] = 0;
        }
        return this;
      };
    
      // Remove leading `0` from `this`
      BN.prototype._strip = function strip () {
        while (this.length > 1 && this.words[this.length - 1] === 0) {
          this.length--;
        }
        return this._normSign();
      };
    
      BN.prototype._normSign = function _normSign () {
        // -0 = 0
        if (this.length === 1 && this.words[0] === 0) {
          this.negative = 0;
        }
        return this;
      };
    
      // Check Symbol.for because not everywhere where Symbol defined
      // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
      if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
        try {
          BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect;
        } catch (e) {
          BN.prototype.inspect = inspect;
        }
      } else {
        BN.prototype.inspect = inspect;
      }
    
      function inspect () {
        return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
      }
    
      /*
    
      var zeros = [];
      var groupSizes = [];
      var groupBases = [];
    
      var s = '';
      var i = -1;
      while (++i < BN.wordSize) {
        zeros[i] = s;
        s += '0';
      }
      groupSizes[0] = 0;
      groupSizes[1] = 0;
      groupBases[0] = 0;
      groupBases[1] = 0;
      var base = 2 - 1;
      while (++base < 36 + 1) {
        var groupSize = 0;
        var groupBase = 1;
        while (groupBase < (1 << BN.wordSize) / base) {
          groupBase *= base;
          groupSize += 1;
        }
        groupSizes[base] = groupSize;
        groupBases[base] = groupBase;
      }
    
      */
    
      var zeros = [
        '',
        '0',
        '00',
        '000',
        '0000',
        '00000',
        '000000',
        '0000000',
        '00000000',
        '000000000',
        '0000000000',
        '00000000000',
        '000000000000',
        '0000000000000',
        '00000000000000',
        '000000000000000',
        '0000000000000000',
        '00000000000000000',
        '000000000000000000',
        '0000000000000000000',
        '00000000000000000000',
        '000000000000000000000',
        '0000000000000000000000',
        '00000000000000000000000',
        '000000000000000000000000',
        '0000000000000000000000000'
      ];
    
      var groupSizes = [
        0, 0,
        25, 16, 12, 11, 10, 9, 8,
        8, 7, 7, 7, 7, 6, 6,
        6, 6, 6, 6, 6, 5, 5,
        5, 5, 5, 5, 5, 5, 5,
        5, 5, 5, 5, 5, 5, 5
      ];
    
      var groupBases = [
        0, 0,
        33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
        43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
        16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
        6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
        24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
      ];
    
      BN.prototype.toString = function toString (base, padding) {
        base = base || 10;
        padding = padding | 0 || 1;
    
        var out;
        if (base === 16 || base === 'hex') {
          out = '';
          var off = 0;
          var carry = 0;
          for (var i = 0; i < this.length; i++) {
            var w = this.words[i];
            var word = (((w << off) | carry) & 0xffffff).toString(16);
            carry = (w >>> (24 - off)) & 0xffffff;
            off += 2;
            if (off >= 26) {
              off -= 26;
              i--;
            }
            if (carry !== 0 || i !== this.length - 1) {
              out = zeros[6 - word.length] + word + out;
            } else {
              out = word + out;
            }
          }
          if (carry !== 0) {
            out = carry.toString(16) + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        if (base === (base | 0) && base >= 2 && base <= 36) {
          // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
          var groupSize = groupSizes[base];
          // var groupBase = Math.pow(base, groupSize);
          var groupBase = groupBases[base];
          out = '';
          var c = this.clone();
          c.negative = 0;
          while (!c.isZero()) {
            var r = c.modrn(groupBase).toString(base);
            c = c.idivn(groupBase);
    
            if (!c.isZero()) {
              out = zeros[groupSize - r.length] + r + out;
            } else {
              out = r + out;
            }
          }
          if (this.isZero()) {
            out = '0' + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        assert(false, 'Base should be between 2 and 36');
      };
    
      BN.prototype.toNumber = function toNumber () {
        var ret = this.words[0];
        if (this.length === 2) {
          ret += this.words[1] * 0x4000000;
        } else if (this.length === 3 && this.words[2] === 0x01) {
          // NOTE: at this stage it is known that the top bit is set
          ret += 0x10000000000000 + (this.words[1] * 0x4000000);
        } else if (this.length > 2) {
          assert(false, 'Number can only safely store up to 53 bits');
        }
        return (this.negative !== 0) ? -ret : ret;
      };
    
      BN.prototype.toJSON = function toJSON () {
        return this.toString(16, 2);
      };
    
      if (Buffer) {
        BN.prototype.toBuffer = function toBuffer (endian, length) {
          return this.toArrayLike(Buffer, endian, length);
        };
      }
    
      BN.prototype.toArray = function toArray (endian, length) {
        return this.toArrayLike(Array, endian, length);
      };
    
      var allocate = function allocate (ArrayType, size) {
        if (ArrayType.allocUnsafe) {
          return ArrayType.allocUnsafe(size);
        }
        return new ArrayType(size);
      };
    
      BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
        this._strip();
    
        var byteLength = this.byteLength();
        var reqLength = length || Math.max(1, byteLength);
        assert(byteLength <= reqLength, 'byte array longer than desired length');
        assert(reqLength > 0, 'Requested array length <= 0');
    
        var res = allocate(ArrayType, reqLength);
        var postfix = endian === 'le' ? 'LE' : 'BE';
        this['_toArrayLike' + postfix](res, byteLength);
        return res;
      };
    
      BN.prototype._toArrayLikeLE = function _toArrayLikeLE (res, byteLength) {
        var position = 0;
        var carry = 0;
    
        for (var i = 0, shift = 0; i < this.length; i++) {
          var word = (this.words[i] << shift) | carry;
    
          res[position++] = word & 0xff;
          if (position < res.length) {
            res[position++] = (word >> 8) & 0xff;
          }
          if (position < res.length) {
            res[position++] = (word >> 16) & 0xff;
          }
    
          if (shift === 6) {
            if (position < res.length) {
              res[position++] = (word >> 24) & 0xff;
            }
            carry = 0;
            shift = 0;
          } else {
            carry = word >>> 24;
            shift += 2;
          }
        }
    
        if (position < res.length) {
          res[position++] = carry;
    
          while (position < res.length) {
            res[position++] = 0;
          }
        }
      };
    
      BN.prototype._toArrayLikeBE = function _toArrayLikeBE (res, byteLength) {
        var position = res.length - 1;
        var carry = 0;
    
        for (var i = 0, shift = 0; i < this.length; i++) {
          var word = (this.words[i] << shift) | carry;
    
          res[position--] = word & 0xff;
          if (position >= 0) {
            res[position--] = (word >> 8) & 0xff;
          }
          if (position >= 0) {
            res[position--] = (word >> 16) & 0xff;
          }
    
          if (shift === 6) {
            if (position >= 0) {
              res[position--] = (word >> 24) & 0xff;
            }
            carry = 0;
            shift = 0;
          } else {
            carry = word >>> 24;
            shift += 2;
          }
        }
    
        if (position >= 0) {
          res[position--] = carry;
    
          while (position >= 0) {
            res[position--] = 0;
          }
        }
      };
    
      if (Math.clz32) {
        BN.prototype._countBits = function _countBits (w) {
          return 32 - Math.clz32(w);
        };
      } else {
        BN.prototype._countBits = function _countBits (w) {
          var t = w;
          var r = 0;
          if (t >= 0x1000) {
            r += 13;
            t >>>= 13;
          }
          if (t >= 0x40) {
            r += 7;
            t >>>= 7;
          }
          if (t >= 0x8) {
            r += 4;
            t >>>= 4;
          }
          if (t >= 0x02) {
            r += 2;
            t >>>= 2;
          }
          return r + t;
        };
      }
    
      BN.prototype._zeroBits = function _zeroBits (w) {
        // Short-cut
        if (w === 0) return 26;
    
        var t = w;
        var r = 0;
        if ((t & 0x1fff) === 0) {
          r += 13;
          t >>>= 13;
        }
        if ((t & 0x7f) === 0) {
          r += 7;
          t >>>= 7;
        }
        if ((t & 0xf) === 0) {
          r += 4;
          t >>>= 4;
        }
        if ((t & 0x3) === 0) {
          r += 2;
          t >>>= 2;
        }
        if ((t & 0x1) === 0) {
          r++;
        }
        return r;
      };
    
      // Return number of used bits in a BN
      BN.prototype.bitLength = function bitLength () {
        var w = this.words[this.length - 1];
        var hi = this._countBits(w);
        return (this.length - 1) * 26 + hi;
      };
    
      function toBitArray (num) {
        var w = new Array(num.bitLength());
    
        for (var bit = 0; bit < w.length; bit++) {
          var off = (bit / 26) | 0;
          var wbit = bit % 26;
    
          w[bit] = (num.words[off] >>> wbit) & 0x01;
        }
    
        return w;
      }
    
      // Number of trailing zero bits
      BN.prototype.zeroBits = function zeroBits () {
        if (this.isZero()) return 0;
    
        var r = 0;
        for (var i = 0; i < this.length; i++) {
          var b = this._zeroBits(this.words[i]);
          r += b;
          if (b !== 26) break;
        }
        return r;
      };
    
      BN.prototype.byteLength = function byteLength () {
        return Math.ceil(this.bitLength() / 8);
      };
    
      BN.prototype.toTwos = function toTwos (width) {
        if (this.negative !== 0) {
          return this.abs().inotn(width).iaddn(1);
        }
        return this.clone();
      };
    
      BN.prototype.fromTwos = function fromTwos (width) {
        if (this.testn(width - 1)) {
          return this.notn(width).iaddn(1).ineg();
        }
        return this.clone();
      };
    
      BN.prototype.isNeg = function isNeg () {
        return this.negative !== 0;
      };
    
      // Return negative clone of `this`
      BN.prototype.neg = function neg () {
        return this.clone().ineg();
      };
    
      BN.prototype.ineg = function ineg () {
        if (!this.isZero()) {
          this.negative ^= 1;
        }
    
        return this;
      };
    
      // Or `num` with `this` in-place
      BN.prototype.iuor = function iuor (num) {
        while (this.length < num.length) {
          this.words[this.length++] = 0;
        }
    
        for (var i = 0; i < num.length; i++) {
          this.words[i] = this.words[i] | num.words[i];
        }
    
        return this._strip();
      };
    
      BN.prototype.ior = function ior (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuor(num);
      };
    
      // Or `num` with `this`
      BN.prototype.or = function or (num) {
        if (this.length > num.length) return this.clone().ior(num);
        return num.clone().ior(this);
      };
    
      BN.prototype.uor = function uor (num) {
        if (this.length > num.length) return this.clone().iuor(num);
        return num.clone().iuor(this);
      };
    
      // And `num` with `this` in-place
      BN.prototype.iuand = function iuand (num) {
        // b = min-length(num, this)
        var b;
        if (this.length > num.length) {
          b = num;
        } else {
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = this.words[i] & num.words[i];
        }
    
        this.length = b.length;
    
        return this._strip();
      };
    
      BN.prototype.iand = function iand (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuand(num);
      };
    
      // And `num` with `this`
      BN.prototype.and = function and (num) {
        if (this.length > num.length) return this.clone().iand(num);
        return num.clone().iand(this);
      };
    
      BN.prototype.uand = function uand (num) {
        if (this.length > num.length) return this.clone().iuand(num);
        return num.clone().iuand(this);
      };
    
      // Xor `num` with `this` in-place
      BN.prototype.iuxor = function iuxor (num) {
        // a.length > b.length
        var a;
        var b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = a.words[i] ^ b.words[i];
        }
    
        if (this !== a) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = a.length;
    
        return this._strip();
      };
    
      BN.prototype.ixor = function ixor (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuxor(num);
      };
    
      // Xor `num` with `this`
      BN.prototype.xor = function xor (num) {
        if (this.length > num.length) return this.clone().ixor(num);
        return num.clone().ixor(this);
      };
    
      BN.prototype.uxor = function uxor (num) {
        if (this.length > num.length) return this.clone().iuxor(num);
        return num.clone().iuxor(this);
      };
    
      // Not ``this`` with ``width`` bitwidth
      BN.prototype.inotn = function inotn (width) {
        assert(typeof width === 'number' && width >= 0);
    
        var bytesNeeded = Math.ceil(width / 26) | 0;
        var bitsLeft = width % 26;
    
        // Extend the buffer with leading zeroes
        this._expand(bytesNeeded);
    
        if (bitsLeft > 0) {
          bytesNeeded--;
        }
    
        // Handle complete words
        for (var i = 0; i < bytesNeeded; i++) {
          this.words[i] = ~this.words[i] & 0x3ffffff;
        }
    
        // Handle the residue
        if (bitsLeft > 0) {
          this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
        }
    
        // And remove leading zeroes
        return this._strip();
      };
    
      BN.prototype.notn = function notn (width) {
        return this.clone().inotn(width);
      };
    
      // Set `bit` of `this`
      BN.prototype.setn = function setn (bit, val) {
        assert(typeof bit === 'number' && bit >= 0);
    
        var off = (bit / 26) | 0;
        var wbit = bit % 26;
    
        this._expand(off + 1);
    
        if (val) {
          this.words[off] = this.words[off] | (1 << wbit);
        } else {
          this.words[off] = this.words[off] & ~(1 << wbit);
        }
    
        return this._strip();
      };
    
      // Add `num` to `this` in-place
      BN.prototype.iadd = function iadd (num) {
        var r;
    
        // negative + positive
        if (this.negative !== 0 && num.negative === 0) {
          this.negative = 0;
          r = this.isub(num);
          this.negative ^= 1;
          return this._normSign();
    
        // positive + negative
        } else if (this.negative === 0 && num.negative !== 0) {
          num.negative = 0;
          r = this.isub(num);
          num.negative = 1;
          return r._normSign();
        }
    
        // a.length > b.length
        var a, b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
    
        this.length = a.length;
        if (carry !== 0) {
          this.words[this.length] = carry;
          this.length++;
        // Copy the rest of the words
        } else if (a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        return this;
      };
    
      // Add `num` to `this`
      BN.prototype.add = function add (num) {
        var res;
        if (num.negative !== 0 && this.negative === 0) {
          num.negative = 0;
          res = this.sub(num);
          num.negative ^= 1;
          return res;
        } else if (num.negative === 0 && this.negative !== 0) {
          this.negative = 0;
          res = num.sub(this);
          this.negative = 1;
          return res;
        }
    
        if (this.length > num.length) return this.clone().iadd(num);
    
        return num.clone().iadd(this);
      };
    
      // Subtract `num` from `this` in-place
      BN.prototype.isub = function isub (num) {
        // this - (-num) = this + num
        if (num.negative !== 0) {
          num.negative = 0;
          var r = this.iadd(num);
          num.negative = 1;
          return r._normSign();
    
        // -this - num = -(this + num)
        } else if (this.negative !== 0) {
          this.negative = 0;
          this.iadd(num);
          this.negative = 1;
          return this._normSign();
        }
    
        // At this point both numbers are positive
        var cmp = this.cmp(num);
    
        // Optimization - zeroify
        if (cmp === 0) {
          this.negative = 0;
          this.length = 1;
          this.words[0] = 0;
          return this;
        }
    
        // a > b
        var a, b;
        if (cmp > 0) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
    
        // Copy rest of the words
        if (carry === 0 && i < a.length && a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = Math.max(this.length, i);
    
        if (a !== this) {
          this.negative = 1;
        }
    
        return this._strip();
      };
    
      // Subtract `num` from `this`
      BN.prototype.sub = function sub (num) {
        return this.clone().isub(num);
      };
    
      function smallMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        var len = (self.length + num.length) | 0;
        out.length = len;
        len = (len - 1) | 0;
    
        // Peel one iteration (compiler can't do it, because of code complexity)
        var a = self.words[0] | 0;
        var b = num.words[0] | 0;
        var r = a * b;
    
        var lo = r & 0x3ffffff;
        var carry = (r / 0x4000000) | 0;
        out.words[0] = lo;
    
        for (var k = 1; k < len; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = carry >>> 26;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = (k - j) | 0;
            a = self.words[i] | 0;
            b = num.words[j] | 0;
            r = a * b + rword;
            ncarry += (r / 0x4000000) | 0;
            rword = r & 0x3ffffff;
          }
          out.words[k] = rword | 0;
          carry = ncarry | 0;
        }
        if (carry !== 0) {
          out.words[k] = carry | 0;
        } else {
          out.length--;
        }
    
        return out._strip();
      }
    
      // TODO(indutny): it may be reasonable to omit it for users who don't need
      // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
      // multiplication (like elliptic secp256k1).
      var comb10MulTo = function comb10MulTo (self, num, out) {
        var a = self.words;
        var b = num.words;
        var o = out.words;
        var c = 0;
        var lo;
        var mid;
        var hi;
        var a0 = a[0] | 0;
        var al0 = a0 & 0x1fff;
        var ah0 = a0 >>> 13;
        var a1 = a[1] | 0;
        var al1 = a1 & 0x1fff;
        var ah1 = a1 >>> 13;
        var a2 = a[2] | 0;
        var al2 = a2 & 0x1fff;
        var ah2 = a2 >>> 13;
        var a3 = a[3] | 0;
        var al3 = a3 & 0x1fff;
        var ah3 = a3 >>> 13;
        var a4 = a[4] | 0;
        var al4 = a4 & 0x1fff;
        var ah4 = a4 >>> 13;
        var a5 = a[5] | 0;
        var al5 = a5 & 0x1fff;
        var ah5 = a5 >>> 13;
        var a6 = a[6] | 0;
        var al6 = a6 & 0x1fff;
        var ah6 = a6 >>> 13;
        var a7 = a[7] | 0;
        var al7 = a7 & 0x1fff;
        var ah7 = a7 >>> 13;
        var a8 = a[8] | 0;
        var al8 = a8 & 0x1fff;
        var ah8 = a8 >>> 13;
        var a9 = a[9] | 0;
        var al9 = a9 & 0x1fff;
        var ah9 = a9 >>> 13;
        var b0 = b[0] | 0;
        var bl0 = b0 & 0x1fff;
        var bh0 = b0 >>> 13;
        var b1 = b[1] | 0;
        var bl1 = b1 & 0x1fff;
        var bh1 = b1 >>> 13;
        var b2 = b[2] | 0;
        var bl2 = b2 & 0x1fff;
        var bh2 = b2 >>> 13;
        var b3 = b[3] | 0;
        var bl3 = b3 & 0x1fff;
        var bh3 = b3 >>> 13;
        var b4 = b[4] | 0;
        var bl4 = b4 & 0x1fff;
        var bh4 = b4 >>> 13;
        var b5 = b[5] | 0;
        var bl5 = b5 & 0x1fff;
        var bh5 = b5 >>> 13;
        var b6 = b[6] | 0;
        var bl6 = b6 & 0x1fff;
        var bh6 = b6 >>> 13;
        var b7 = b[7] | 0;
        var bl7 = b7 & 0x1fff;
        var bh7 = b7 >>> 13;
        var b8 = b[8] | 0;
        var bl8 = b8 & 0x1fff;
        var bh8 = b8 >>> 13;
        var b9 = b[9] | 0;
        var bl9 = b9 & 0x1fff;
        var bh9 = b9 >>> 13;
    
        out.negative = self.negative ^ num.negative;
        out.length = 19;
        /* k = 0 */
        lo = Math.imul(al0, bl0);
        mid = Math.imul(al0, bh0);
        mid = (mid + Math.imul(ah0, bl0)) | 0;
        hi = Math.imul(ah0, bh0);
        var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
        w0 &= 0x3ffffff;
        /* k = 1 */
        lo = Math.imul(al1, bl0);
        mid = Math.imul(al1, bh0);
        mid = (mid + Math.imul(ah1, bl0)) | 0;
        hi = Math.imul(ah1, bh0);
        lo = (lo + Math.imul(al0, bl1)) | 0;
        mid = (mid + Math.imul(al0, bh1)) | 0;
        mid = (mid + Math.imul(ah0, bl1)) | 0;
        hi = (hi + Math.imul(ah0, bh1)) | 0;
        var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
        w1 &= 0x3ffffff;
        /* k = 2 */
        lo = Math.imul(al2, bl0);
        mid = Math.imul(al2, bh0);
        mid = (mid + Math.imul(ah2, bl0)) | 0;
        hi = Math.imul(ah2, bh0);
        lo = (lo + Math.imul(al1, bl1)) | 0;
        mid = (mid + Math.imul(al1, bh1)) | 0;
        mid = (mid + Math.imul(ah1, bl1)) | 0;
        hi = (hi + Math.imul(ah1, bh1)) | 0;
        lo = (lo + Math.imul(al0, bl2)) | 0;
        mid = (mid + Math.imul(al0, bh2)) | 0;
        mid = (mid + Math.imul(ah0, bl2)) | 0;
        hi = (hi + Math.imul(ah0, bh2)) | 0;
        var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
        w2 &= 0x3ffffff;
        /* k = 3 */
        lo = Math.imul(al3, bl0);
        mid = Math.imul(al3, bh0);
        mid = (mid + Math.imul(ah3, bl0)) | 0;
        hi = Math.imul(ah3, bh0);
        lo = (lo + Math.imul(al2, bl1)) | 0;
        mid = (mid + Math.imul(al2, bh1)) | 0;
        mid = (mid + Math.imul(ah2, bl1)) | 0;
        hi = (hi + Math.imul(ah2, bh1)) | 0;
        lo = (lo + Math.imul(al1, bl2)) | 0;
        mid = (mid + Math.imul(al1, bh2)) | 0;
        mid = (mid + Math.imul(ah1, bl2)) | 0;
        hi = (hi + Math.imul(ah1, bh2)) | 0;
        lo = (lo + Math.imul(al0, bl3)) | 0;
        mid = (mid + Math.imul(al0, bh3)) | 0;
        mid = (mid + Math.imul(ah0, bl3)) | 0;
        hi = (hi + Math.imul(ah0, bh3)) | 0;
        var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
        w3 &= 0x3ffffff;
        /* k = 4 */
        lo = Math.imul(al4, bl0);
        mid = Math.imul(al4, bh0);
        mid = (mid + Math.imul(ah4, bl0)) | 0;
        hi = Math.imul(ah4, bh0);
        lo = (lo + Math.imul(al3, bl1)) | 0;
        mid = (mid + Math.imul(al3, bh1)) | 0;
        mid = (mid + Math.imul(ah3, bl1)) | 0;
        hi = (hi + Math.imul(ah3, bh1)) | 0;
        lo = (lo + Math.imul(al2, bl2)) | 0;
        mid = (mid + Math.imul(al2, bh2)) | 0;
        mid = (mid + Math.imul(ah2, bl2)) | 0;
        hi = (hi + Math.imul(ah2, bh2)) | 0;
        lo = (lo + Math.imul(al1, bl3)) | 0;
        mid = (mid + Math.imul(al1, bh3)) | 0;
        mid = (mid + Math.imul(ah1, bl3)) | 0;
        hi = (hi + Math.imul(ah1, bh3)) | 0;
        lo = (lo + Math.imul(al0, bl4)) | 0;
        mid = (mid + Math.imul(al0, bh4)) | 0;
        mid = (mid + Math.imul(ah0, bl4)) | 0;
        hi = (hi + Math.imul(ah0, bh4)) | 0;
        var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
        w4 &= 0x3ffffff;
        /* k = 5 */
        lo = Math.imul(al5, bl0);
        mid = Math.imul(al5, bh0);
        mid = (mid + Math.imul(ah5, bl0)) | 0;
        hi = Math.imul(ah5, bh0);
        lo = (lo + Math.imul(al4, bl1)) | 0;
        mid = (mid + Math.imul(al4, bh1)) | 0;
        mid = (mid + Math.imul(ah4, bl1)) | 0;
        hi = (hi + Math.imul(ah4, bh1)) | 0;
        lo = (lo + Math.imul(al3, bl2)) | 0;
        mid = (mid + Math.imul(al3, bh2)) | 0;
        mid = (mid + Math.imul(ah3, bl2)) | 0;
        hi = (hi + Math.imul(ah3, bh2)) | 0;
        lo = (lo + Math.imul(al2, bl3)) | 0;
        mid = (mid + Math.imul(al2, bh3)) | 0;
        mid = (mid + Math.imul(ah2, bl3)) | 0;
        hi = (hi + Math.imul(ah2, bh3)) | 0;
        lo = (lo + Math.imul(al1, bl4)) | 0;
        mid = (mid + Math.imul(al1, bh4)) | 0;
        mid = (mid + Math.imul(ah1, bl4)) | 0;
        hi = (hi + Math.imul(ah1, bh4)) | 0;
        lo = (lo + Math.imul(al0, bl5)) | 0;
        mid = (mid + Math.imul(al0, bh5)) | 0;
        mid = (mid + Math.imul(ah0, bl5)) | 0;
        hi = (hi + Math.imul(ah0, bh5)) | 0;
        var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
        w5 &= 0x3ffffff;
        /* k = 6 */
        lo = Math.imul(al6, bl0);
        mid = Math.imul(al6, bh0);
        mid = (mid + Math.imul(ah6, bl0)) | 0;
        hi = Math.imul(ah6, bh0);
        lo = (lo + Math.imul(al5, bl1)) | 0;
        mid = (mid + Math.imul(al5, bh1)) | 0;
        mid = (mid + Math.imul(ah5, bl1)) | 0;
        hi = (hi + Math.imul(ah5, bh1)) | 0;
        lo = (lo + Math.imul(al4, bl2)) | 0;
        mid = (mid + Math.imul(al4, bh2)) | 0;
        mid = (mid + Math.imul(ah4, bl2)) | 0;
        hi = (hi + Math.imul(ah4, bh2)) | 0;
        lo = (lo + Math.imul(al3, bl3)) | 0;
        mid = (mid + Math.imul(al3, bh3)) | 0;
        mid = (mid + Math.imul(ah3, bl3)) | 0;
        hi = (hi + Math.imul(ah3, bh3)) | 0;
        lo = (lo + Math.imul(al2, bl4)) | 0;
        mid = (mid + Math.imul(al2, bh4)) | 0;
        mid = (mid + Math.imul(ah2, bl4)) | 0;
        hi = (hi + Math.imul(ah2, bh4)) | 0;
        lo = (lo + Math.imul(al1, bl5)) | 0;
        mid = (mid + Math.imul(al1, bh5)) | 0;
        mid = (mid + Math.imul(ah1, bl5)) | 0;
        hi = (hi + Math.imul(ah1, bh5)) | 0;
        lo = (lo + Math.imul(al0, bl6)) | 0;
        mid = (mid + Math.imul(al0, bh6)) | 0;
        mid = (mid + Math.imul(ah0, bl6)) | 0;
        hi = (hi + Math.imul(ah0, bh6)) | 0;
        var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
        w6 &= 0x3ffffff;
        /* k = 7 */
        lo = Math.imul(al7, bl0);
        mid = Math.imul(al7, bh0);
        mid = (mid + Math.imul(ah7, bl0)) | 0;
        hi = Math.imul(ah7, bh0);
        lo = (lo + Math.imul(al6, bl1)) | 0;
        mid = (mid + Math.imul(al6, bh1)) | 0;
        mid = (mid + Math.imul(ah6, bl1)) | 0;
        hi = (hi + Math.imul(ah6, bh1)) | 0;
        lo = (lo + Math.imul(al5, bl2)) | 0;
        mid = (mid + Math.imul(al5, bh2)) | 0;
        mid = (mid + Math.imul(ah5, bl2)) | 0;
        hi = (hi + Math.imul(ah5, bh2)) | 0;
        lo = (lo + Math.imul(al4, bl3)) | 0;
        mid = (mid + Math.imul(al4, bh3)) | 0;
        mid = (mid + Math.imul(ah4, bl3)) | 0;
        hi = (hi + Math.imul(ah4, bh3)) | 0;
        lo = (lo + Math.imul(al3, bl4)) | 0;
        mid = (mid + Math.imul(al3, bh4)) | 0;
        mid = (mid + Math.imul(ah3, bl4)) | 0;
        hi = (hi + Math.imul(ah3, bh4)) | 0;
        lo = (lo + Math.imul(al2, bl5)) | 0;
        mid = (mid + Math.imul(al2, bh5)) | 0;
        mid = (mid + Math.imul(ah2, bl5)) | 0;
        hi = (hi + Math.imul(ah2, bh5)) | 0;
        lo = (lo + Math.imul(al1, bl6)) | 0;
        mid = (mid + Math.imul(al1, bh6)) | 0;
        mid = (mid + Math.imul(ah1, bl6)) | 0;
        hi = (hi + Math.imul(ah1, bh6)) | 0;
        lo = (lo + Math.imul(al0, bl7)) | 0;
        mid = (mid + Math.imul(al0, bh7)) | 0;
        mid = (mid + Math.imul(ah0, bl7)) | 0;
        hi = (hi + Math.imul(ah0, bh7)) | 0;
        var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
        w7 &= 0x3ffffff;
        /* k = 8 */
        lo = Math.imul(al8, bl0);
        mid = Math.imul(al8, bh0);
        mid = (mid + Math.imul(ah8, bl0)) | 0;
        hi = Math.imul(ah8, bh0);
        lo = (lo + Math.imul(al7, bl1)) | 0;
        mid = (mid + Math.imul(al7, bh1)) | 0;
        mid = (mid + Math.imul(ah7, bl1)) | 0;
        hi = (hi + Math.imul(ah7, bh1)) | 0;
        lo = (lo + Math.imul(al6, bl2)) | 0;
        mid = (mid + Math.imul(al6, bh2)) | 0;
        mid = (mid + Math.imul(ah6, bl2)) | 0;
        hi = (hi + Math.imul(ah6, bh2)) | 0;
        lo = (lo + Math.imul(al5, bl3)) | 0;
        mid = (mid + Math.imul(al5, bh3)) | 0;
        mid = (mid + Math.imul(ah5, bl3)) | 0;
        hi = (hi + Math.imul(ah5, bh3)) | 0;
        lo = (lo + Math.imul(al4, bl4)) | 0;
        mid = (mid + Math.imul(al4, bh4)) | 0;
        mid = (mid + Math.imul(ah4, bl4)) | 0;
        hi = (hi + Math.imul(ah4, bh4)) | 0;
        lo = (lo + Math.imul(al3, bl5)) | 0;
        mid = (mid + Math.imul(al3, bh5)) | 0;
        mid = (mid + Math.imul(ah3, bl5)) | 0;
        hi = (hi + Math.imul(ah3, bh5)) | 0;
        lo = (lo + Math.imul(al2, bl6)) | 0;
        mid = (mid + Math.imul(al2, bh6)) | 0;
        mid = (mid + Math.imul(ah2, bl6)) | 0;
        hi = (hi + Math.imul(ah2, bh6)) | 0;
        lo = (lo + Math.imul(al1, bl7)) | 0;
        mid = (mid + Math.imul(al1, bh7)) | 0;
        mid = (mid + Math.imul(ah1, bl7)) | 0;
        hi = (hi + Math.imul(ah1, bh7)) | 0;
        lo = (lo + Math.imul(al0, bl8)) | 0;
        mid = (mid + Math.imul(al0, bh8)) | 0;
        mid = (mid + Math.imul(ah0, bl8)) | 0;
        hi = (hi + Math.imul(ah0, bh8)) | 0;
        var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
        w8 &= 0x3ffffff;
        /* k = 9 */
        lo = Math.imul(al9, bl0);
        mid = Math.imul(al9, bh0);
        mid = (mid + Math.imul(ah9, bl0)) | 0;
        hi = Math.imul(ah9, bh0);
        lo = (lo + Math.imul(al8, bl1)) | 0;
        mid = (mid + Math.imul(al8, bh1)) | 0;
        mid = (mid + Math.imul(ah8, bl1)) | 0;
        hi = (hi + Math.imul(ah8, bh1)) | 0;
        lo = (lo + Math.imul(al7, bl2)) | 0;
        mid = (mid + Math.imul(al7, bh2)) | 0;
        mid = (mid + Math.imul(ah7, bl2)) | 0;
        hi = (hi + Math.imul(ah7, bh2)) | 0;
        lo = (lo + Math.imul(al6, bl3)) | 0;
        mid = (mid + Math.imul(al6, bh3)) | 0;
        mid = (mid + Math.imul(ah6, bl3)) | 0;
        hi = (hi + Math.imul(ah6, bh3)) | 0;
        lo = (lo + Math.imul(al5, bl4)) | 0;
        mid = (mid + Math.imul(al5, bh4)) | 0;
        mid = (mid + Math.imul(ah5, bl4)) | 0;
        hi = (hi + Math.imul(ah5, bh4)) | 0;
        lo = (lo + Math.imul(al4, bl5)) | 0;
        mid = (mid + Math.imul(al4, bh5)) | 0;
        mid = (mid + Math.imul(ah4, bl5)) | 0;
        hi = (hi + Math.imul(ah4, bh5)) | 0;
        lo = (lo + Math.imul(al3, bl6)) | 0;
        mid = (mid + Math.imul(al3, bh6)) | 0;
        mid = (mid + Math.imul(ah3, bl6)) | 0;
        hi = (hi + Math.imul(ah3, bh6)) | 0;
        lo = (lo + Math.imul(al2, bl7)) | 0;
        mid = (mid + Math.imul(al2, bh7)) | 0;
        mid = (mid + Math.imul(ah2, bl7)) | 0;
        hi = (hi + Math.imul(ah2, bh7)) | 0;
        lo = (lo + Math.imul(al1, bl8)) | 0;
        mid = (mid + Math.imul(al1, bh8)) | 0;
        mid = (mid + Math.imul(ah1, bl8)) | 0;
        hi = (hi + Math.imul(ah1, bh8)) | 0;
        lo = (lo + Math.imul(al0, bl9)) | 0;
        mid = (mid + Math.imul(al0, bh9)) | 0;
        mid = (mid + Math.imul(ah0, bl9)) | 0;
        hi = (hi + Math.imul(ah0, bh9)) | 0;
        var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
        w9 &= 0x3ffffff;
        /* k = 10 */
        lo = Math.imul(al9, bl1);
        mid = Math.imul(al9, bh1);
        mid = (mid + Math.imul(ah9, bl1)) | 0;
        hi = Math.imul(ah9, bh1);
        lo = (lo + Math.imul(al8, bl2)) | 0;
        mid = (mid + Math.imul(al8, bh2)) | 0;
        mid = (mid + Math.imul(ah8, bl2)) | 0;
        hi = (hi + Math.imul(ah8, bh2)) | 0;
        lo = (lo + Math.imul(al7, bl3)) | 0;
        mid = (mid + Math.imul(al7, bh3)) | 0;
        mid = (mid + Math.imul(ah7, bl3)) | 0;
        hi = (hi + Math.imul(ah7, bh3)) | 0;
        lo = (lo + Math.imul(al6, bl4)) | 0;
        mid = (mid + Math.imul(al6, bh4)) | 0;
        mid = (mid + Math.imul(ah6, bl4)) | 0;
        hi = (hi + Math.imul(ah6, bh4)) | 0;
        lo = (lo + Math.imul(al5, bl5)) | 0;
        mid = (mid + Math.imul(al5, bh5)) | 0;
        mid = (mid + Math.imul(ah5, bl5)) | 0;
        hi = (hi + Math.imul(ah5, bh5)) | 0;
        lo = (lo + Math.imul(al4, bl6)) | 0;
        mid = (mid + Math.imul(al4, bh6)) | 0;
        mid = (mid + Math.imul(ah4, bl6)) | 0;
        hi = (hi + Math.imul(ah4, bh6)) | 0;
        lo = (lo + Math.imul(al3, bl7)) | 0;
        mid = (mid + Math.imul(al3, bh7)) | 0;
        mid = (mid + Math.imul(ah3, bl7)) | 0;
        hi = (hi + Math.imul(ah3, bh7)) | 0;
        lo = (lo + Math.imul(al2, bl8)) | 0;
        mid = (mid + Math.imul(al2, bh8)) | 0;
        mid = (mid + Math.imul(ah2, bl8)) | 0;
        hi = (hi + Math.imul(ah2, bh8)) | 0;
        lo = (lo + Math.imul(al1, bl9)) | 0;
        mid = (mid + Math.imul(al1, bh9)) | 0;
        mid = (mid + Math.imul(ah1, bl9)) | 0;
        hi = (hi + Math.imul(ah1, bh9)) | 0;
        var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
        w10 &= 0x3ffffff;
        /* k = 11 */
        lo = Math.imul(al9, bl2);
        mid = Math.imul(al9, bh2);
        mid = (mid + Math.imul(ah9, bl2)) | 0;
        hi = Math.imul(ah9, bh2);
        lo = (lo + Math.imul(al8, bl3)) | 0;
        mid = (mid + Math.imul(al8, bh3)) | 0;
        mid = (mid + Math.imul(ah8, bl3)) | 0;
        hi = (hi + Math.imul(ah8, bh3)) | 0;
        lo = (lo + Math.imul(al7, bl4)) | 0;
        mid = (mid + Math.imul(al7, bh4)) | 0;
        mid = (mid + Math.imul(ah7, bl4)) | 0;
        hi = (hi + Math.imul(ah7, bh4)) | 0;
        lo = (lo + Math.imul(al6, bl5)) | 0;
        mid = (mid + Math.imul(al6, bh5)) | 0;
        mid = (mid + Math.imul(ah6, bl5)) | 0;
        hi = (hi + Math.imul(ah6, bh5)) | 0;
        lo = (lo + Math.imul(al5, bl6)) | 0;
        mid = (mid + Math.imul(al5, bh6)) | 0;
        mid = (mid + Math.imul(ah5, bl6)) | 0;
        hi = (hi + Math.imul(ah5, bh6)) | 0;
        lo = (lo + Math.imul(al4, bl7)) | 0;
        mid = (mid + Math.imul(al4, bh7)) | 0;
        mid = (mid + Math.imul(ah4, bl7)) | 0;
        hi = (hi + Math.imul(ah4, bh7)) | 0;
        lo = (lo + Math.imul(al3, bl8)) | 0;
        mid = (mid + Math.imul(al3, bh8)) | 0;
        mid = (mid + Math.imul(ah3, bl8)) | 0;
        hi = (hi + Math.imul(ah3, bh8)) | 0;
        lo = (lo + Math.imul(al2, bl9)) | 0;
        mid = (mid + Math.imul(al2, bh9)) | 0;
        mid = (mid + Math.imul(ah2, bl9)) | 0;
        hi = (hi + Math.imul(ah2, bh9)) | 0;
        var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
        w11 &= 0x3ffffff;
        /* k = 12 */
        lo = Math.imul(al9, bl3);
        mid = Math.imul(al9, bh3);
        mid = (mid + Math.imul(ah9, bl3)) | 0;
        hi = Math.imul(ah9, bh3);
        lo = (lo + Math.imul(al8, bl4)) | 0;
        mid = (mid + Math.imul(al8, bh4)) | 0;
        mid = (mid + Math.imul(ah8, bl4)) | 0;
        hi = (hi + Math.imul(ah8, bh4)) | 0;
        lo = (lo + Math.imul(al7, bl5)) | 0;
        mid = (mid + Math.imul(al7, bh5)) | 0;
        mid = (mid + Math.imul(ah7, bl5)) | 0;
        hi = (hi + Math.imul(ah7, bh5)) | 0;
        lo = (lo + Math.imul(al6, bl6)) | 0;
        mid = (mid + Math.imul(al6, bh6)) | 0;
        mid = (mid + Math.imul(ah6, bl6)) | 0;
        hi = (hi + Math.imul(ah6, bh6)) | 0;
        lo = (lo + Math.imul(al5, bl7)) | 0;
        mid = (mid + Math.imul(al5, bh7)) | 0;
        mid = (mid + Math.imul(ah5, bl7)) | 0;
        hi = (hi + Math.imul(ah5, bh7)) | 0;
        lo = (lo + Math.imul(al4, bl8)) | 0;
        mid = (mid + Math.imul(al4, bh8)) | 0;
        mid = (mid + Math.imul(ah4, bl8)) | 0;
        hi = (hi + Math.imul(ah4, bh8)) | 0;
        lo = (lo + Math.imul(al3, bl9)) | 0;
        mid = (mid + Math.imul(al3, bh9)) | 0;
        mid = (mid + Math.imul(ah3, bl9)) | 0;
        hi = (hi + Math.imul(ah3, bh9)) | 0;
        var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
        w12 &= 0x3ffffff;
        /* k = 13 */
        lo = Math.imul(al9, bl4);
        mid = Math.imul(al9, bh4);
        mid = (mid + Math.imul(ah9, bl4)) | 0;
        hi = Math.imul(ah9, bh4);
        lo = (lo + Math.imul(al8, bl5)) | 0;
        mid = (mid + Math.imul(al8, bh5)) | 0;
        mid = (mid + Math.imul(ah8, bl5)) | 0;
        hi = (hi + Math.imul(ah8, bh5)) | 0;
        lo = (lo + Math.imul(al7, bl6)) | 0;
        mid = (mid + Math.imul(al7, bh6)) | 0;
        mid = (mid + Math.imul(ah7, bl6)) | 0;
        hi = (hi + Math.imul(ah7, bh6)) | 0;
        lo = (lo + Math.imul(al6, bl7)) | 0;
        mid = (mid + Math.imul(al6, bh7)) | 0;
        mid = (mid + Math.imul(ah6, bl7)) | 0;
        hi = (hi + Math.imul(ah6, bh7)) | 0;
        lo = (lo + Math.imul(al5, bl8)) | 0;
        mid = (mid + Math.imul(al5, bh8)) | 0;
        mid = (mid + Math.imul(ah5, bl8)) | 0;
        hi = (hi + Math.imul(ah5, bh8)) | 0;
        lo = (lo + Math.imul(al4, bl9)) | 0;
        mid = (mid + Math.imul(al4, bh9)) | 0;
        mid = (mid + Math.imul(ah4, bl9)) | 0;
        hi = (hi + Math.imul(ah4, bh9)) | 0;
        var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
        w13 &= 0x3ffffff;
        /* k = 14 */
        lo = Math.imul(al9, bl5);
        mid = Math.imul(al9, bh5);
        mid = (mid + Math.imul(ah9, bl5)) | 0;
        hi = Math.imul(ah9, bh5);
        lo = (lo + Math.imul(al8, bl6)) | 0;
        mid = (mid + Math.imul(al8, bh6)) | 0;
        mid = (mid + Math.imul(ah8, bl6)) | 0;
        hi = (hi + Math.imul(ah8, bh6)) | 0;
        lo = (lo + Math.imul(al7, bl7)) | 0;
        mid = (mid + Math.imul(al7, bh7)) | 0;
        mid = (mid + Math.imul(ah7, bl7)) | 0;
        hi = (hi + Math.imul(ah7, bh7)) | 0;
        lo = (lo + Math.imul(al6, bl8)) | 0;
        mid = (mid + Math.imul(al6, bh8)) | 0;
        mid = (mid + Math.imul(ah6, bl8)) | 0;
        hi = (hi + Math.imul(ah6, bh8)) | 0;
        lo = (lo + Math.imul(al5, bl9)) | 0;
        mid = (mid + Math.imul(al5, bh9)) | 0;
        mid = (mid + Math.imul(ah5, bl9)) | 0;
        hi = (hi + Math.imul(ah5, bh9)) | 0;
        var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
        w14 &= 0x3ffffff;
        /* k = 15 */
        lo = Math.imul(al9, bl6);
        mid = Math.imul(al9, bh6);
        mid = (mid + Math.imul(ah9, bl6)) | 0;
        hi = Math.imul(ah9, bh6);
        lo = (lo + Math.imul(al8, bl7)) | 0;
        mid = (mid + Math.imul(al8, bh7)) | 0;
        mid = (mid + Math.imul(ah8, bl7)) | 0;
        hi = (hi + Math.imul(ah8, bh7)) | 0;
        lo = (lo + Math.imul(al7, bl8)) | 0;
        mid = (mid + Math.imul(al7, bh8)) | 0;
        mid = (mid + Math.imul(ah7, bl8)) | 0;
        hi = (hi + Math.imul(ah7, bh8)) | 0;
        lo = (lo + Math.imul(al6, bl9)) | 0;
        mid = (mid + Math.imul(al6, bh9)) | 0;
        mid = (mid + Math.imul(ah6, bl9)) | 0;
        hi = (hi + Math.imul(ah6, bh9)) | 0;
        var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
        w15 &= 0x3ffffff;
        /* k = 16 */
        lo = Math.imul(al9, bl7);
        mid = Math.imul(al9, bh7);
        mid = (mid + Math.imul(ah9, bl7)) | 0;
        hi = Math.imul(ah9, bh7);
        lo = (lo + Math.imul(al8, bl8)) | 0;
        mid = (mid + Math.imul(al8, bh8)) | 0;
        mid = (mid + Math.imul(ah8, bl8)) | 0;
        hi = (hi + Math.imul(ah8, bh8)) | 0;
        lo = (lo + Math.imul(al7, bl9)) | 0;
        mid = (mid + Math.imul(al7, bh9)) | 0;
        mid = (mid + Math.imul(ah7, bl9)) | 0;
        hi = (hi + Math.imul(ah7, bh9)) | 0;
        var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
        w16 &= 0x3ffffff;
        /* k = 17 */
        lo = Math.imul(al9, bl8);
        mid = Math.imul(al9, bh8);
        mid = (mid + Math.imul(ah9, bl8)) | 0;
        hi = Math.imul(ah9, bh8);
        lo = (lo + Math.imul(al8, bl9)) | 0;
        mid = (mid + Math.imul(al8, bh9)) | 0;
        mid = (mid + Math.imul(ah8, bl9)) | 0;
        hi = (hi + Math.imul(ah8, bh9)) | 0;
        var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
        w17 &= 0x3ffffff;
        /* k = 18 */
        lo = Math.imul(al9, bl9);
        mid = Math.imul(al9, bh9);
        mid = (mid + Math.imul(ah9, bl9)) | 0;
        hi = Math.imul(ah9, bh9);
        var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
        w18 &= 0x3ffffff;
        o[0] = w0;
        o[1] = w1;
        o[2] = w2;
        o[3] = w3;
        o[4] = w4;
        o[5] = w5;
        o[6] = w6;
        o[7] = w7;
        o[8] = w8;
        o[9] = w9;
        o[10] = w10;
        o[11] = w11;
        o[12] = w12;
        o[13] = w13;
        o[14] = w14;
        o[15] = w15;
        o[16] = w16;
        o[17] = w17;
        o[18] = w18;
        if (c !== 0) {
          o[19] = c;
          out.length++;
        }
        return out;
      };
    
      // Polyfill comb
      if (!Math.imul) {
        comb10MulTo = smallMulTo;
      }
    
      function bigMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        out.length = self.length + num.length;
    
        var carry = 0;
        var hncarry = 0;
        for (var k = 0; k < out.length - 1; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = hncarry;
          hncarry = 0;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = k - j;
            var a = self.words[i] | 0;
            var b = num.words[j] | 0;
            var r = a * b;
    
            var lo = r & 0x3ffffff;
            ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
            lo = (lo + rword) | 0;
            rword = lo & 0x3ffffff;
            ncarry = (ncarry + (lo >>> 26)) | 0;
    
            hncarry += ncarry >>> 26;
            ncarry &= 0x3ffffff;
          }
          out.words[k] = rword;
          carry = ncarry;
          ncarry = hncarry;
        }
        if (carry !== 0) {
          out.words[k] = carry;
        } else {
          out.length--;
        }
    
        return out._strip();
      }
    
      function jumboMulTo (self, num, out) {
        // Temporary disable, see https://github.com/indutny/bn.js/issues/211
        // var fftm = new FFTM();
        // return fftm.mulp(self, num, out);
        return bigMulTo(self, num, out);
      }
    
      BN.prototype.mulTo = function mulTo (num, out) {
        var res;
        var len = this.length + num.length;
        if (this.length === 10 && num.length === 10) {
          res = comb10MulTo(this, num, out);
        } else if (len < 63) {
          res = smallMulTo(this, num, out);
        } else if (len < 1024) {
          res = bigMulTo(this, num, out);
        } else {
          res = jumboMulTo(this, num, out);
        }
    
        return res;
      };
    
      // Cooley-Tukey algorithm for FFT
      // slightly revisited to rely on looping instead of recursion
    
      function FFTM (x, y) {
        this.x = x;
        this.y = y;
      }
    
      FFTM.prototype.makeRBT = function makeRBT (N) {
        var t = new Array(N);
        var l = BN.prototype._countBits(N) - 1;
        for (var i = 0; i < N; i++) {
          t[i] = this.revBin(i, l, N);
        }
    
        return t;
      };
    
      // Returns binary-reversed representation of `x`
      FFTM.prototype.revBin = function revBin (x, l, N) {
        if (x === 0 || x === N - 1) return x;
    
        var rb = 0;
        for (var i = 0; i < l; i++) {
          rb |= (x & 1) << (l - i - 1);
          x >>= 1;
        }
    
        return rb;
      };
    
      // Performs "tweedling" phase, therefore 'emulating'
      // behaviour of the recursive algorithm
      FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
        for (var i = 0; i < N; i++) {
          rtws[i] = rws[rbt[i]];
          itws[i] = iws[rbt[i]];
        }
      };
    
      FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
        this.permute(rbt, rws, iws, rtws, itws, N);
    
        for (var s = 1; s < N; s <<= 1) {
          var l = s << 1;
    
          var rtwdf = Math.cos(2 * Math.PI / l);
          var itwdf = Math.sin(2 * Math.PI / l);
    
          for (var p = 0; p < N; p += l) {
            var rtwdf_ = rtwdf;
            var itwdf_ = itwdf;
    
            for (var j = 0; j < s; j++) {
              var re = rtws[p + j];
              var ie = itws[p + j];
    
              var ro = rtws[p + j + s];
              var io = itws[p + j + s];
    
              var rx = rtwdf_ * ro - itwdf_ * io;
    
              io = rtwdf_ * io + itwdf_ * ro;
              ro = rx;
    
              rtws[p + j] = re + ro;
              itws[p + j] = ie + io;
    
              rtws[p + j + s] = re - ro;
              itws[p + j + s] = ie - io;
    
              /* jshint maxdepth : false */
              if (j !== l) {
                rx = rtwdf * rtwdf_ - itwdf * itwdf_;
    
                itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
                rtwdf_ = rx;
              }
            }
          }
        }
      };
    
      FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
        var N = Math.max(m, n) | 1;
        var odd = N & 1;
        var i = 0;
        for (N = N / 2 | 0; N; N = N >>> 1) {
          i++;
        }
    
        return 1 << i + 1 + odd;
      };
    
      FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
        if (N <= 1) return;
    
        for (var i = 0; i < N / 2; i++) {
          var t = rws[i];
    
          rws[i] = rws[N - i - 1];
          rws[N - i - 1] = t;
    
          t = iws[i];
    
          iws[i] = -iws[N - i - 1];
          iws[N - i - 1] = -t;
        }
      };
    
      FFTM.prototype.normalize13b = function normalize13b (ws, N) {
        var carry = 0;
        for (var i = 0; i < N / 2; i++) {
          var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
            Math.round(ws[2 * i] / N) +
            carry;
    
          ws[i] = w & 0x3ffffff;
    
          if (w < 0x4000000) {
            carry = 0;
          } else {
            carry = w / 0x4000000 | 0;
          }
        }
    
        return ws;
      };
    
      FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
        var carry = 0;
        for (var i = 0; i < len; i++) {
          carry = carry + (ws[i] | 0);
    
          rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
          rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
        }
    
        // Pad with zeroes
        for (i = 2 * len; i < N; ++i) {
          rws[i] = 0;
        }
    
        assert(carry === 0);
        assert((carry & ~0x1fff) === 0);
      };
    
      FFTM.prototype.stub = function stub (N) {
        var ph = new Array(N);
        for (var i = 0; i < N; i++) {
          ph[i] = 0;
        }
    
        return ph;
      };
    
      FFTM.prototype.mulp = function mulp (x, y, out) {
        var N = 2 * this.guessLen13b(x.length, y.length);
    
        var rbt = this.makeRBT(N);
    
        var _ = this.stub(N);
    
        var rws = new Array(N);
        var rwst = new Array(N);
        var iwst = new Array(N);
    
        var nrws = new Array(N);
        var nrwst = new Array(N);
        var niwst = new Array(N);
    
        var rmws = out.words;
        rmws.length = N;
    
        this.convert13b(x.words, x.length, rws, N);
        this.convert13b(y.words, y.length, nrws, N);
    
        this.transform(rws, _, rwst, iwst, N, rbt);
        this.transform(nrws, _, nrwst, niwst, N, rbt);
    
        for (var i = 0; i < N; i++) {
          var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
          iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
          rwst[i] = rx;
        }
    
        this.conjugate(rwst, iwst, N);
        this.transform(rwst, iwst, rmws, _, N, rbt);
        this.conjugate(rmws, _, N);
        this.normalize13b(rmws, N);
    
        out.negative = x.negative ^ y.negative;
        out.length = x.length + y.length;
        return out._strip();
      };
    
      // Multiply `this` by `num`
      BN.prototype.mul = function mul (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return this.mulTo(num, out);
      };
    
      // Multiply employing FFT
      BN.prototype.mulf = function mulf (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return jumboMulTo(this, num, out);
      };
    
      // In-place Multiplication
      BN.prototype.imul = function imul (num) {
        return this.clone().mulTo(num, this);
      };
    
      BN.prototype.imuln = function imuln (num) {
        var isNegNum = num < 0;
        if (isNegNum) num = -num;
    
        assert(typeof num === 'number');
        assert(num < 0x4000000);
    
        // Carry
        var carry = 0;
        for (var i = 0; i < this.length; i++) {
          var w = (this.words[i] | 0) * num;
          var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
          carry >>= 26;
          carry += (w / 0x4000000) | 0;
          // NOTE: lo is 27bit maximum
          carry += lo >>> 26;
          this.words[i] = lo & 0x3ffffff;
        }
    
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
    
        return isNegNum ? this.ineg() : this;
      };
    
      BN.prototype.muln = function muln (num) {
        return this.clone().imuln(num);
      };
    
      // `this` * `this`
      BN.prototype.sqr = function sqr () {
        return this.mul(this);
      };
    
      // `this` * `this` in-place
      BN.prototype.isqr = function isqr () {
        return this.imul(this.clone());
      };
    
      // Math.pow(`this`, `num`)
      BN.prototype.pow = function pow (num) {
        var w = toBitArray(num);
        if (w.length === 0) return new BN(1);
    
        // Skip leading zeroes
        var res = this;
        for (var i = 0; i < w.length; i++, res = res.sqr()) {
          if (w[i] !== 0) break;
        }
    
        if (++i < w.length) {
          for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
            if (w[i] === 0) continue;
    
            res = res.mul(q);
          }
        }
    
        return res;
      };
    
      // Shift-left in-place
      BN.prototype.iushln = function iushln (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
        var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
        var i;
    
        if (r !== 0) {
          var carry = 0;
    
          for (i = 0; i < this.length; i++) {
            var newCarry = this.words[i] & carryMask;
            var c = ((this.words[i] | 0) - newCarry) << r;
            this.words[i] = c | carry;
            carry = newCarry >>> (26 - r);
          }
    
          if (carry) {
            this.words[i] = carry;
            this.length++;
          }
        }
    
        if (s !== 0) {
          for (i = this.length - 1; i >= 0; i--) {
            this.words[i + s] = this.words[i];
          }
    
          for (i = 0; i < s; i++) {
            this.words[i] = 0;
          }
    
          this.length += s;
        }
    
        return this._strip();
      };
    
      BN.prototype.ishln = function ishln (bits) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushln(bits);
      };
    
      // Shift-right in-place
      // NOTE: `hint` is a lowest bit before trailing zeroes
      // NOTE: if `extended` is present - it will be filled with destroyed bits
      BN.prototype.iushrn = function iushrn (bits, hint, extended) {
        assert(typeof bits === 'number' && bits >= 0);
        var h;
        if (hint) {
          h = (hint - (hint % 26)) / 26;
        } else {
          h = 0;
        }
    
        var r = bits % 26;
        var s = Math.min((bits - r) / 26, this.length);
        var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
        var maskedWords = extended;
    
        h -= s;
        h = Math.max(0, h);
    
        // Extended mode, copy masked part
        if (maskedWords) {
          for (var i = 0; i < s; i++) {
            maskedWords.words[i] = this.words[i];
          }
          maskedWords.length = s;
        }
    
        if (s === 0) {
          // No-op, we should not move anything at all
        } else if (this.length > s) {
          this.length -= s;
          for (i = 0; i < this.length; i++) {
            this.words[i] = this.words[i + s];
          }
        } else {
          this.words[0] = 0;
          this.length = 1;
        }
    
        var carry = 0;
        for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
          var word = this.words[i] | 0;
          this.words[i] = (carry << (26 - r)) | (word >>> r);
          carry = word & mask;
        }
    
        // Push carried bits as a mask
        if (maskedWords && carry !== 0) {
          maskedWords.words[maskedWords.length++] = carry;
        }
    
        if (this.length === 0) {
          this.words[0] = 0;
          this.length = 1;
        }
    
        return this._strip();
      };
    
      BN.prototype.ishrn = function ishrn (bits, hint, extended) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushrn(bits, hint, extended);
      };
    
      // Shift-left
      BN.prototype.shln = function shln (bits) {
        return this.clone().ishln(bits);
      };
    
      BN.prototype.ushln = function ushln (bits) {
        return this.clone().iushln(bits);
      };
    
      // Shift-right
      BN.prototype.shrn = function shrn (bits) {
        return this.clone().ishrn(bits);
      };
    
      BN.prototype.ushrn = function ushrn (bits) {
        return this.clone().iushrn(bits);
      };
    
      // Test if n bit is set
      BN.prototype.testn = function testn (bit) {
        assert(typeof bit === 'number' && bit >= 0);
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) return false;
    
        // Check bit and return
        var w = this.words[s];
    
        return !!(w & q);
      };
    
      // Return only lowers bits of number (in-place)
      BN.prototype.imaskn = function imaskn (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
    
        assert(this.negative === 0, 'imaskn works only with positive numbers');
    
        if (this.length <= s) {
          return this;
        }
    
        if (r !== 0) {
          s++;
        }
        this.length = Math.min(s, this.length);
    
        if (r !== 0) {
          var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
          this.words[this.length - 1] &= mask;
        }
    
        return this._strip();
      };
    
      // Return only lowers bits of number
      BN.prototype.maskn = function maskn (bits) {
        return this.clone().imaskn(bits);
      };
    
      // Add plain number `num` to `this`
      BN.prototype.iaddn = function iaddn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.isubn(-num);
    
        // Possible sign change
        if (this.negative !== 0) {
          if (this.length === 1 && (this.words[0] | 0) <= num) {
            this.words[0] = num - (this.words[0] | 0);
            this.negative = 0;
            return this;
          }
    
          this.negative = 0;
          this.isubn(num);
          this.negative = 1;
          return this;
        }
    
        // Add without checks
        return this._iaddn(num);
      };
    
      BN.prototype._iaddn = function _iaddn (num) {
        this.words[0] += num;
    
        // Carry
        for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
          this.words[i] -= 0x4000000;
          if (i === this.length - 1) {
            this.words[i + 1] = 1;
          } else {
            this.words[i + 1]++;
          }
        }
        this.length = Math.max(this.length, i + 1);
    
        return this;
      };
    
      // Subtract plain number `num` from `this`
      BN.prototype.isubn = function isubn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.iaddn(-num);
    
        if (this.negative !== 0) {
          this.negative = 0;
          this.iaddn(num);
          this.negative = 1;
          return this;
        }
    
        this.words[0] -= num;
    
        if (this.length === 1 && this.words[0] < 0) {
          this.words[0] = -this.words[0];
          this.negative = 1;
        } else {
          // Carry
          for (var i = 0; i < this.length && this.words[i] < 0; i++) {
            this.words[i] += 0x4000000;
            this.words[i + 1] -= 1;
          }
        }
    
        return this._strip();
      };
    
      BN.prototype.addn = function addn (num) {
        return this.clone().iaddn(num);
      };
    
      BN.prototype.subn = function subn (num) {
        return this.clone().isubn(num);
      };
    
      BN.prototype.iabs = function iabs () {
        this.negative = 0;
    
        return this;
      };
    
      BN.prototype.abs = function abs () {
        return this.clone().iabs();
      };
    
      BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
        var len = num.length + shift;
        var i;
    
        this._expand(len);
    
        var w;
        var carry = 0;
        for (i = 0; i < num.length; i++) {
          w = (this.words[i + shift] | 0) + carry;
          var right = (num.words[i] | 0) * mul;
          w -= right & 0x3ffffff;
          carry = (w >> 26) - ((right / 0x4000000) | 0);
          this.words[i + shift] = w & 0x3ffffff;
        }
        for (; i < this.length - shift; i++) {
          w = (this.words[i + shift] | 0) + carry;
          carry = w >> 26;
          this.words[i + shift] = w & 0x3ffffff;
        }
    
        if (carry === 0) return this._strip();
    
        // Subtraction overflow
        assert(carry === -1);
        carry = 0;
        for (i = 0; i < this.length; i++) {
          w = -(this.words[i] | 0) + carry;
          carry = w >> 26;
          this.words[i] = w & 0x3ffffff;
        }
        this.negative = 1;
    
        return this._strip();
      };
    
      BN.prototype._wordDiv = function _wordDiv (num, mode) {
        var shift = this.length - num.length;
    
        var a = this.clone();
        var b = num;
    
        // Normalize
        var bhi = b.words[b.length - 1] | 0;
        var bhiBits = this._countBits(bhi);
        shift = 26 - bhiBits;
        if (shift !== 0) {
          b = b.ushln(shift);
          a.iushln(shift);
          bhi = b.words[b.length - 1] | 0;
        }
    
        // Initialize quotient
        var m = a.length - b.length;
        var q;
    
        if (mode !== 'mod') {
          q = new BN(null);
          q.length = m + 1;
          q.words = new Array(q.length);
          for (var i = 0; i < q.length; i++) {
            q.words[i] = 0;
          }
        }
    
        var diff = a.clone()._ishlnsubmul(b, 1, m);
        if (diff.negative === 0) {
          a = diff;
          if (q) {
            q.words[m] = 1;
          }
        }
    
        for (var j = m - 1; j >= 0; j--) {
          var qj = (a.words[b.length + j] | 0) * 0x4000000 +
            (a.words[b.length + j - 1] | 0);
    
          // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
          // (0x7ffffff)
          qj = Math.min((qj / bhi) | 0, 0x3ffffff);
    
          a._ishlnsubmul(b, qj, j);
          while (a.negative !== 0) {
            qj--;
            a.negative = 0;
            a._ishlnsubmul(b, 1, j);
            if (!a.isZero()) {
              a.negative ^= 1;
            }
          }
          if (q) {
            q.words[j] = qj;
          }
        }
        if (q) {
          q._strip();
        }
        a._strip();
    
        // Denormalize
        if (mode !== 'div' && shift !== 0) {
          a.iushrn(shift);
        }
    
        return {
          div: q || null,
          mod: a
        };
      };
    
      // NOTE: 1) `mode` can be set to `mod` to request mod only,
      //       to `div` to request div only, or be absent to
      //       request both div & mod
      //       2) `positive` is true if unsigned mod is requested
      BN.prototype.divmod = function divmod (num, mode, positive) {
        assert(!num.isZero());
    
        if (this.isZero()) {
          return {
            div: new BN(0),
            mod: new BN(0)
          };
        }
    
        var div, mod, res;
        if (this.negative !== 0 && num.negative === 0) {
          res = this.neg().divmod(num, mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.iadd(num);
            }
          }
    
          return {
            div: div,
            mod: mod
          };
        }
    
        if (this.negative === 0 && num.negative !== 0) {
          res = this.divmod(num.neg(), mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          return {
            div: div,
            mod: res.mod
          };
        }
    
        if ((this.negative & num.negative) !== 0) {
          res = this.neg().divmod(num.neg(), mode);
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.isub(num);
            }
          }
    
          return {
            div: res.div,
            mod: mod
          };
        }
    
        // Both numbers are positive at this point
    
        // Strip both numbers to approximate shift value
        if (num.length > this.length || this.cmp(num) < 0) {
          return {
            div: new BN(0),
            mod: this
          };
        }
    
        // Very short reduction
        if (num.length === 1) {
          if (mode === 'div') {
            return {
              div: this.divn(num.words[0]),
              mod: null
            };
          }
    
          if (mode === 'mod') {
            return {
              div: null,
              mod: new BN(this.modrn(num.words[0]))
            };
          }
    
          return {
            div: this.divn(num.words[0]),
            mod: new BN(this.modrn(num.words[0]))
          };
        }
    
        return this._wordDiv(num, mode);
      };
    
      // Find `this` / `num`
      BN.prototype.div = function div (num) {
        return this.divmod(num, 'div', false).div;
      };
    
      // Find `this` % `num`
      BN.prototype.mod = function mod (num) {
        return this.divmod(num, 'mod', false).mod;
      };
    
      BN.prototype.umod = function umod (num) {
        return this.divmod(num, 'mod', true).mod;
      };
    
      // Find Round(`this` / `num`)
      BN.prototype.divRound = function divRound (num) {
        var dm = this.divmod(num);
    
        // Fast case - exact division
        if (dm.mod.isZero()) return dm.div;
    
        var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
    
        var half = num.ushrn(1);
        var r2 = num.andln(1);
        var cmp = mod.cmp(half);
    
        // Round down
        if (cmp < 0 || (r2 === 1 && cmp === 0)) return dm.div;
    
        // Round up
        return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
      };
    
      BN.prototype.modrn = function modrn (num) {
        var isNegNum = num < 0;
        if (isNegNum) num = -num;
    
        assert(num <= 0x3ffffff);
        var p = (1 << 26) % num;
    
        var acc = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          acc = (p * acc + (this.words[i] | 0)) % num;
        }
    
        return isNegNum ? -acc : acc;
      };
    
      // WARNING: DEPRECATED
      BN.prototype.modn = function modn (num) {
        return this.modrn(num);
      };
    
      // In-place division by number
      BN.prototype.idivn = function idivn (num) {
        var isNegNum = num < 0;
        if (isNegNum) num = -num;
    
        assert(num <= 0x3ffffff);
    
        var carry = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var w = (this.words[i] | 0) + carry * 0x4000000;
          this.words[i] = (w / num) | 0;
          carry = w % num;
        }
    
        this._strip();
        return isNegNum ? this.ineg() : this;
      };
    
      BN.prototype.divn = function divn (num) {
        return this.clone().idivn(num);
      };
    
      BN.prototype.egcd = function egcd (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var x = this;
        var y = p.clone();
    
        if (x.negative !== 0) {
          x = x.umod(p);
        } else {
          x = x.clone();
        }
    
        // A * x + B * y = x
        var A = new BN(1);
        var B = new BN(0);
    
        // C * x + D * y = y
        var C = new BN(0);
        var D = new BN(1);
    
        var g = 0;
    
        while (x.isEven() && y.isEven()) {
          x.iushrn(1);
          y.iushrn(1);
          ++g;
        }
    
        var yp = y.clone();
        var xp = x.clone();
    
        while (!x.isZero()) {
          for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            x.iushrn(i);
            while (i-- > 0) {
              if (A.isOdd() || B.isOdd()) {
                A.iadd(yp);
                B.isub(xp);
              }
    
              A.iushrn(1);
              B.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            y.iushrn(j);
            while (j-- > 0) {
              if (C.isOdd() || D.isOdd()) {
                C.iadd(yp);
                D.isub(xp);
              }
    
              C.iushrn(1);
              D.iushrn(1);
            }
          }
    
          if (x.cmp(y) >= 0) {
            x.isub(y);
            A.isub(C);
            B.isub(D);
          } else {
            y.isub(x);
            C.isub(A);
            D.isub(B);
          }
        }
    
        return {
          a: C,
          b: D,
          gcd: y.iushln(g)
        };
      };
    
      // This is reduced incarnation of the binary EEA
      // above, designated to invert members of the
      // _prime_ fields F(p) at a maximal speed
      BN.prototype._invmp = function _invmp (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var a = this;
        var b = p.clone();
    
        if (a.negative !== 0) {
          a = a.umod(p);
        } else {
          a = a.clone();
        }
    
        var x1 = new BN(1);
        var x2 = new BN(0);
    
        var delta = b.clone();
    
        while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
          for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            a.iushrn(i);
            while (i-- > 0) {
              if (x1.isOdd()) {
                x1.iadd(delta);
              }
    
              x1.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            b.iushrn(j);
            while (j-- > 0) {
              if (x2.isOdd()) {
                x2.iadd(delta);
              }
    
              x2.iushrn(1);
            }
          }
    
          if (a.cmp(b) >= 0) {
            a.isub(b);
            x1.isub(x2);
          } else {
            b.isub(a);
            x2.isub(x1);
          }
        }
    
        var res;
        if (a.cmpn(1) === 0) {
          res = x1;
        } else {
          res = x2;
        }
    
        if (res.cmpn(0) < 0) {
          res.iadd(p);
        }
    
        return res;
      };
    
      BN.prototype.gcd = function gcd (num) {
        if (this.isZero()) return num.abs();
        if (num.isZero()) return this.abs();
    
        var a = this.clone();
        var b = num.clone();
        a.negative = 0;
        b.negative = 0;
    
        // Remove common factor of two
        for (var shift = 0; a.isEven() && b.isEven(); shift++) {
          a.iushrn(1);
          b.iushrn(1);
        }
    
        do {
          while (a.isEven()) {
            a.iushrn(1);
          }
          while (b.isEven()) {
            b.iushrn(1);
          }
    
          var r = a.cmp(b);
          if (r < 0) {
            // Swap `a` and `b` to make `a` always bigger than `b`
            var t = a;
            a = b;
            b = t;
          } else if (r === 0 || b.cmpn(1) === 0) {
            break;
          }
    
          a.isub(b);
        } while (true);
    
        return b.iushln(shift);
      };
    
      // Invert number in the field F(num)
      BN.prototype.invm = function invm (num) {
        return this.egcd(num).a.umod(num);
      };
    
      BN.prototype.isEven = function isEven () {
        return (this.words[0] & 1) === 0;
      };
    
      BN.prototype.isOdd = function isOdd () {
        return (this.words[0] & 1) === 1;
      };
    
      // And first word and num
      BN.prototype.andln = function andln (num) {
        return this.words[0] & num;
      };
    
      // Increment at the bit position in-line
      BN.prototype.bincn = function bincn (bit) {
        assert(typeof bit === 'number');
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) {
          this._expand(s + 1);
          this.words[s] |= q;
          return this;
        }
    
        // Add bit and propagate, if needed
        var carry = q;
        for (var i = s; carry !== 0 && i < this.length; i++) {
          var w = this.words[i] | 0;
          w += carry;
          carry = w >>> 26;
          w &= 0x3ffffff;
          this.words[i] = w;
        }
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
        return this;
      };
    
      BN.prototype.isZero = function isZero () {
        return this.length === 1 && this.words[0] === 0;
      };
    
      BN.prototype.cmpn = function cmpn (num) {
        var negative = num < 0;
    
        if (this.negative !== 0 && !negative) return -1;
        if (this.negative === 0 && negative) return 1;
    
        this._strip();
    
        var res;
        if (this.length > 1) {
          res = 1;
        } else {
          if (negative) {
            num = -num;
          }
    
          assert(num <= 0x3ffffff, 'Number is too big');
    
          var w = this.words[0] | 0;
          res = w === num ? 0 : w < num ? -1 : 1;
        }
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Compare two numbers and return:
      // 1 - if `this` > `num`
      // 0 - if `this` == `num`
      // -1 - if `this` < `num`
      BN.prototype.cmp = function cmp (num) {
        if (this.negative !== 0 && num.negative === 0) return -1;
        if (this.negative === 0 && num.negative !== 0) return 1;
    
        var res = this.ucmp(num);
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Unsigned comparison
      BN.prototype.ucmp = function ucmp (num) {
        // At this point both numbers have the same sign
        if (this.length > num.length) return 1;
        if (this.length < num.length) return -1;
    
        var res = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var a = this.words[i] | 0;
          var b = num.words[i] | 0;
    
          if (a === b) continue;
          if (a < b) {
            res = -1;
          } else if (a > b) {
            res = 1;
          }
          break;
        }
        return res;
      };
    
      BN.prototype.gtn = function gtn (num) {
        return this.cmpn(num) === 1;
      };
    
      BN.prototype.gt = function gt (num) {
        return this.cmp(num) === 1;
      };
    
      BN.prototype.gten = function gten (num) {
        return this.cmpn(num) >= 0;
      };
    
      BN.prototype.gte = function gte (num) {
        return this.cmp(num) >= 0;
      };
    
      BN.prototype.ltn = function ltn (num) {
        return this.cmpn(num) === -1;
      };
    
      BN.prototype.lt = function lt (num) {
        return this.cmp(num) === -1;
      };
    
      BN.prototype.lten = function lten (num) {
        return this.cmpn(num) <= 0;
      };
    
      BN.prototype.lte = function lte (num) {
        return this.cmp(num) <= 0;
      };
    
      BN.prototype.eqn = function eqn (num) {
        return this.cmpn(num) === 0;
      };
    
      BN.prototype.eq = function eq (num) {
        return this.cmp(num) === 0;
      };
    
      //
      // A reduce context, could be using montgomery or something better, depending
      // on the `m` itself.
      //
      BN.red = function red (num) {
        return new Red(num);
      };
    
      BN.prototype.toRed = function toRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        assert(this.negative === 0, 'red works only with positives');
        return ctx.convertTo(this)._forceRed(ctx);
      };
    
      BN.prototype.fromRed = function fromRed () {
        assert(this.red, 'fromRed works only with numbers in reduction context');
        return this.red.convertFrom(this);
      };
    
      BN.prototype._forceRed = function _forceRed (ctx) {
        this.red = ctx;
        return this;
      };
    
      BN.prototype.forceRed = function forceRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        return this._forceRed(ctx);
      };
    
      BN.prototype.redAdd = function redAdd (num) {
        assert(this.red, 'redAdd works only with red numbers');
        return this.red.add(this, num);
      };
    
      BN.prototype.redIAdd = function redIAdd (num) {
        assert(this.red, 'redIAdd works only with red numbers');
        return this.red.iadd(this, num);
      };
    
      BN.prototype.redSub = function redSub (num) {
        assert(this.red, 'redSub works only with red numbers');
        return this.red.sub(this, num);
      };
    
      BN.prototype.redISub = function redISub (num) {
        assert(this.red, 'redISub works only with red numbers');
        return this.red.isub(this, num);
      };
    
      BN.prototype.redShl = function redShl (num) {
        assert(this.red, 'redShl works only with red numbers');
        return this.red.shl(this, num);
      };
    
      BN.prototype.redMul = function redMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.mul(this, num);
      };
    
      BN.prototype.redIMul = function redIMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.imul(this, num);
      };
    
      BN.prototype.redSqr = function redSqr () {
        assert(this.red, 'redSqr works only with red numbers');
        this.red._verify1(this);
        return this.red.sqr(this);
      };
    
      BN.prototype.redISqr = function redISqr () {
        assert(this.red, 'redISqr works only with red numbers');
        this.red._verify1(this);
        return this.red.isqr(this);
      };
    
      // Square root over p
      BN.prototype.redSqrt = function redSqrt () {
        assert(this.red, 'redSqrt works only with red numbers');
        this.red._verify1(this);
        return this.red.sqrt(this);
      };
    
      BN.prototype.redInvm = function redInvm () {
        assert(this.red, 'redInvm works only with red numbers');
        this.red._verify1(this);
        return this.red.invm(this);
      };
    
      // Return negative clone of `this` % `red modulo`
      BN.prototype.redNeg = function redNeg () {
        assert(this.red, 'redNeg works only with red numbers');
        this.red._verify1(this);
        return this.red.neg(this);
      };
    
      BN.prototype.redPow = function redPow (num) {
        assert(this.red && !num.red, 'redPow(normalNum)');
        this.red._verify1(this);
        return this.red.pow(this, num);
      };
    
      // Prime numbers with efficient reduction
      var primes = {
        k256: null,
        p224: null,
        p192: null,
        p25519: null
      };
    
      // Pseudo-Mersenne prime
      function MPrime (name, p) {
        // P = 2 ^ N - K
        this.name = name;
        this.p = new BN(p, 16);
        this.n = this.p.bitLength();
        this.k = new BN(1).iushln(this.n).isub(this.p);
    
        this.tmp = this._tmp();
      }
    
      MPrime.prototype._tmp = function _tmp () {
        var tmp = new BN(null);
        tmp.words = new Array(Math.ceil(this.n / 13));
        return tmp;
      };
    
      MPrime.prototype.ireduce = function ireduce (num) {
        // Assumes that `num` is less than `P^2`
        // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
        var r = num;
        var rlen;
    
        do {
          this.split(r, this.tmp);
          r = this.imulK(r);
          r = r.iadd(this.tmp);
          rlen = r.bitLength();
        } while (rlen > this.n);
    
        var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
        if (cmp === 0) {
          r.words[0] = 0;
          r.length = 1;
        } else if (cmp > 0) {
          r.isub(this.p);
        } else {
          if (r.strip !== undefined) {
            // r is a BN v4 instance
            r.strip();
          } else {
            // r is a BN v5 instance
            r._strip();
          }
        }
    
        return r;
      };
    
      MPrime.prototype.split = function split (input, out) {
        input.iushrn(this.n, 0, out);
      };
    
      MPrime.prototype.imulK = function imulK (num) {
        return num.imul(this.k);
      };
    
      function K256 () {
        MPrime.call(
          this,
          'k256',
          'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
      }
      inherits(K256, MPrime);
    
      K256.prototype.split = function split (input, output) {
        // 256 = 9 * 26 + 22
        var mask = 0x3fffff;
    
        var outLen = Math.min(input.length, 9);
        for (var i = 0; i < outLen; i++) {
          output.words[i] = input.words[i];
        }
        output.length = outLen;
    
        if (input.length <= 9) {
          input.words[0] = 0;
          input.length = 1;
          return;
        }
    
        // Shift by 9 limbs
        var prev = input.words[9];
        output.words[output.length++] = prev & mask;
    
        for (i = 10; i < input.length; i++) {
          var next = input.words[i] | 0;
          input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
          prev = next;
        }
        prev >>>= 22;
        input.words[i - 10] = prev;
        if (prev === 0 && input.length > 10) {
          input.length -= 10;
        } else {
          input.length -= 9;
        }
      };
    
      K256.prototype.imulK = function imulK (num) {
        // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
        num.words[num.length] = 0;
        num.words[num.length + 1] = 0;
        num.length += 2;
    
        // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
        var lo = 0;
        for (var i = 0; i < num.length; i++) {
          var w = num.words[i] | 0;
          lo += w * 0x3d1;
          num.words[i] = lo & 0x3ffffff;
          lo = w * 0x40 + ((lo / 0x4000000) | 0);
        }
    
        // Fast length reduction
        if (num.words[num.length - 1] === 0) {
          num.length--;
          if (num.words[num.length - 1] === 0) {
            num.length--;
          }
        }
        return num;
      };
    
      function P224 () {
        MPrime.call(
          this,
          'p224',
          'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
      }
      inherits(P224, MPrime);
    
      function P192 () {
        MPrime.call(
          this,
          'p192',
          'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
      }
      inherits(P192, MPrime);
    
      function P25519 () {
        // 2 ^ 255 - 19
        MPrime.call(
          this,
          '25519',
          '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
      }
      inherits(P25519, MPrime);
    
      P25519.prototype.imulK = function imulK (num) {
        // K = 0x13
        var carry = 0;
        for (var i = 0; i < num.length; i++) {
          var hi = (num.words[i] | 0) * 0x13 + carry;
          var lo = hi & 0x3ffffff;
          hi >>>= 26;
    
          num.words[i] = lo;
          carry = hi;
        }
        if (carry !== 0) {
          num.words[num.length++] = carry;
        }
        return num;
      };
    
      // Exported mostly for testing purposes, use plain name instead
      BN._prime = function prime (name) {
        // Cached version of prime
        if (primes[name]) return primes[name];
    
        var prime;
        if (name === 'k256') {
          prime = new K256();
        } else if (name === 'p224') {
          prime = new P224();
        } else if (name === 'p192') {
          prime = new P192();
        } else if (name === 'p25519') {
          prime = new P25519();
        } else {
          throw new Error('Unknown prime ' + name);
        }
        primes[name] = prime;
    
        return prime;
      };
    
      //
      // Base reduction engine
      //
      function Red (m) {
        if (typeof m === 'string') {
          var prime = BN._prime(m);
          this.m = prime.p;
          this.prime = prime;
        } else {
          assert(m.gtn(1), 'modulus must be greater than 1');
          this.m = m;
          this.prime = null;
        }
      }
    
      Red.prototype._verify1 = function _verify1 (a) {
        assert(a.negative === 0, 'red works only with positives');
        assert(a.red, 'red works only with red numbers');
      };
    
      Red.prototype._verify2 = function _verify2 (a, b) {
        assert((a.negative | b.negative) === 0, 'red works only with positives');
        assert(a.red && a.red === b.red,
          'red works only with red numbers');
      };
    
      Red.prototype.imod = function imod (a) {
        if (this.prime) return this.prime.ireduce(a)._forceRed(this);
    
        move(a, a.umod(this.m)._forceRed(this));
        return a;
      };
    
      Red.prototype.neg = function neg (a) {
        if (a.isZero()) {
          return a.clone();
        }
    
        return this.m.sub(a)._forceRed(this);
      };
    
      Red.prototype.add = function add (a, b) {
        this._verify2(a, b);
    
        var res = a.add(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.iadd = function iadd (a, b) {
        this._verify2(a, b);
    
        var res = a.iadd(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res;
      };
    
      Red.prototype.sub = function sub (a, b) {
        this._verify2(a, b);
    
        var res = a.sub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.isub = function isub (a, b) {
        this._verify2(a, b);
    
        var res = a.isub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res;
      };
    
      Red.prototype.shl = function shl (a, num) {
        this._verify1(a);
        return this.imod(a.ushln(num));
      };
    
      Red.prototype.imul = function imul (a, b) {
        this._verify2(a, b);
        return this.imod(a.imul(b));
      };
    
      Red.prototype.mul = function mul (a, b) {
        this._verify2(a, b);
        return this.imod(a.mul(b));
      };
    
      Red.prototype.isqr = function isqr (a) {
        return this.imul(a, a.clone());
      };
    
      Red.prototype.sqr = function sqr (a) {
        return this.mul(a, a);
      };
    
      Red.prototype.sqrt = function sqrt (a) {
        if (a.isZero()) return a.clone();
    
        var mod3 = this.m.andln(3);
        assert(mod3 % 2 === 1);
    
        // Fast case
        if (mod3 === 3) {
          var pow = this.m.add(new BN(1)).iushrn(2);
          return this.pow(a, pow);
        }
    
        // Tonelli-Shanks algorithm (Totally unoptimized and slow)
        //
        // Find Q and S, that Q * 2 ^ S = (P - 1)
        var q = this.m.subn(1);
        var s = 0;
        while (!q.isZero() && q.andln(1) === 0) {
          s++;
          q.iushrn(1);
        }
        assert(!q.isZero());
    
        var one = new BN(1).toRed(this);
        var nOne = one.redNeg();
    
        // Find quadratic non-residue
        // NOTE: Max is such because of generalized Riemann hypothesis.
        var lpow = this.m.subn(1).iushrn(1);
        var z = this.m.bitLength();
        z = new BN(2 * z * z).toRed(this);
    
        while (this.pow(z, lpow).cmp(nOne) !== 0) {
          z.redIAdd(nOne);
        }
    
        var c = this.pow(z, q);
        var r = this.pow(a, q.addn(1).iushrn(1));
        var t = this.pow(a, q);
        var m = s;
        while (t.cmp(one) !== 0) {
          var tmp = t;
          for (var i = 0; tmp.cmp(one) !== 0; i++) {
            tmp = tmp.redSqr();
          }
          assert(i < m);
          var b = this.pow(c, new BN(1).iushln(m - i - 1));
    
          r = r.redMul(b);
          c = b.redSqr();
          t = t.redMul(c);
          m = i;
        }
    
        return r;
      };
    
      Red.prototype.invm = function invm (a) {
        var inv = a._invmp(this.m);
        if (inv.negative !== 0) {
          inv.negative = 0;
          return this.imod(inv).redNeg();
        } else {
          return this.imod(inv);
        }
      };
    
      Red.prototype.pow = function pow (a, num) {
        if (num.isZero()) return new BN(1).toRed(this);
        if (num.cmpn(1) === 0) return a.clone();
    
        var windowSize = 4;
        var wnd = new Array(1 << windowSize);
        wnd[0] = new BN(1).toRed(this);
        wnd[1] = a;
        for (var i = 2; i < wnd.length; i++) {
          wnd[i] = this.mul(wnd[i - 1], a);
        }
    
        var res = wnd[0];
        var current = 0;
        var currentLen = 0;
        var start = num.bitLength() % 26;
        if (start === 0) {
          start = 26;
        }
    
        for (i = num.length - 1; i >= 0; i--) {
          var word = num.words[i];
          for (var j = start - 1; j >= 0; j--) {
            var bit = (word >> j) & 1;
            if (res !== wnd[0]) {
              res = this.sqr(res);
            }
    
            if (bit === 0 && current === 0) {
              currentLen = 0;
              continue;
            }
    
            current <<= 1;
            current |= bit;
            currentLen++;
            if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
    
            res = this.mul(res, wnd[current]);
            currentLen = 0;
            current = 0;
          }
          start = 26;
        }
    
        return res;
      };
    
      Red.prototype.convertTo = function convertTo (num) {
        var r = num.umod(this.m);
    
        return r === num ? r.clone() : r;
      };
    
      Red.prototype.convertFrom = function convertFrom (num) {
        var res = num.clone();
        res.red = null;
        return res;
      };
    
      //
      // Montgomery method engine
      //
    
      BN.mont = function mont (num) {
        return new Mont(num);
      };
    
      function Mont (m) {
        Red.call(this, m);
    
        this.shift = this.m.bitLength();
        if (this.shift % 26 !== 0) {
          this.shift += 26 - (this.shift % 26);
        }
    
        this.r = new BN(1).iushln(this.shift);
        this.r2 = this.imod(this.r.sqr());
        this.rinv = this.r._invmp(this.m);
    
        this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
        this.minv = this.minv.umod(this.r);
        this.minv = this.r.sub(this.minv);
      }
      inherits(Mont, Red);
    
      Mont.prototype.convertTo = function convertTo (num) {
        return this.imod(num.ushln(this.shift));
      };
    
      Mont.prototype.convertFrom = function convertFrom (num) {
        var r = this.imod(num.mul(this.rinv));
        r.red = null;
        return r;
      };
    
      Mont.prototype.imul = function imul (a, b) {
        if (a.isZero() || b.isZero()) {
          a.words[0] = 0;
          a.length = 1;
          return a;
        }
    
        var t = a.imul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
    
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.mul = function mul (a, b) {
        if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
    
        var t = a.mul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.invm = function invm (a) {
        // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
        var res = this.imod(a._invmp(this.m).mul(this.r2));
        return res._forceRed(this);
      };
    })(typeof module === 'undefined' || module, this);
    
    },{"buffer":36}],59:[function(require,module,exports){
    module.exports = require('./browser/algorithms.json')
    
    },{"./browser/algorithms.json":60}],60:[function(require,module,exports){
    module.exports={
      "sha224WithRSAEncryption": {
        "sign": "rsa",
        "hash": "sha224",
        "id": "302d300d06096086480165030402040500041c"
      },
      "RSA-SHA224": {
        "sign": "ecdsa/rsa",
        "hash": "sha224",
        "id": "302d300d06096086480165030402040500041c"
      },
      "sha256WithRSAEncryption": {
        "sign": "rsa",
        "hash": "sha256",
        "id": "3031300d060960864801650304020105000420"
      },
      "RSA-SHA256": {
        "sign": "ecdsa/rsa",
        "hash": "sha256",
        "id": "3031300d060960864801650304020105000420"
      },
      "sha384WithRSAEncryption": {
        "sign": "rsa",
        "hash": "sha384",
        "id": "3041300d060960864801650304020205000430"
      },
      "RSA-SHA384": {
        "sign": "ecdsa/rsa",
        "hash": "sha384",
        "id": "3041300d060960864801650304020205000430"
      },
      "sha512WithRSAEncryption": {
        "sign": "rsa",
        "hash": "sha512",
        "id": "3051300d060960864801650304020305000440"
      },
      "RSA-SHA512": {
        "sign": "ecdsa/rsa",
        "hash": "sha512",
        "id": "3051300d060960864801650304020305000440"
      },
      "RSA-SHA1": {
        "sign": "rsa",
        "hash": "sha1",
        "id": "3021300906052b0e03021a05000414"
      },
      "ecdsa-with-SHA1": {
        "sign": "ecdsa",
        "hash": "sha1",
        "id": ""
      },
      "sha256": {
        "sign": "ecdsa",
        "hash": "sha256",
        "id": ""
      },
      "sha224": {
        "sign": "ecdsa",
        "hash": "sha224",
        "id": ""
      },
      "sha384": {
        "sign": "ecdsa",
        "hash": "sha384",
        "id": ""
      },
      "sha512": {
        "sign": "ecdsa",
        "hash": "sha512",
        "id": ""
      },
      "DSA-SHA": {
        "sign": "dsa",
        "hash": "sha1",
        "id": ""
      },
      "DSA-SHA1": {
        "sign": "dsa",
        "hash": "sha1",
        "id": ""
      },
      "DSA": {
        "sign": "dsa",
        "hash": "sha1",
        "id": ""
      },
      "DSA-WITH-SHA224": {
        "sign": "dsa",
        "hash": "sha224",
        "id": ""
      },
      "DSA-SHA224": {
        "sign": "dsa",
        "hash": "sha224",
        "id": ""
      },
      "DSA-WITH-SHA256": {
        "sign": "dsa",
        "hash": "sha256",
        "id": ""
      },
      "DSA-SHA256": {
        "sign": "dsa",
        "hash": "sha256",
        "id": ""
      },
      "DSA-WITH-SHA384": {
        "sign": "dsa",
        "hash": "sha384",
        "id": ""
      },
      "DSA-SHA384": {
        "sign": "dsa",
        "hash": "sha384",
        "id": ""
      },
      "DSA-WITH-SHA512": {
        "sign": "dsa",
        "hash": "sha512",
        "id": ""
      },
      "DSA-SHA512": {
        "sign": "dsa",
        "hash": "sha512",
        "id": ""
      },
      "DSA-RIPEMD160": {
        "sign": "dsa",
        "hash": "rmd160",
        "id": ""
      },
      "ripemd160WithRSA": {
        "sign": "rsa",
        "hash": "rmd160",
        "id": "3021300906052b2403020105000414"
      },
      "RSA-RIPEMD160": {
        "sign": "rsa",
        "hash": "rmd160",
        "id": "3021300906052b2403020105000414"
      },
      "md5WithRSAEncryption": {
        "sign": "rsa",
        "hash": "md5",
        "id": "3020300c06082a864886f70d020505000410"
      },
      "RSA-MD5": {
        "sign": "rsa",
        "hash": "md5",
        "id": "3020300c06082a864886f70d020505000410"
      }
    }
    
    },{}],61:[function(require,module,exports){
    module.exports={
      "1.3.132.0.10": "secp256k1",
      "1.3.132.0.33": "p224",
      "1.2.840.10045.3.1.1": "p192",
      "1.2.840.10045.3.1.7": "p256",
      "1.3.132.0.34": "p384",
      "1.3.132.0.35": "p521"
    }
    
    },{}],62:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    var createHash = require('create-hash')
    var stream = require('readable-stream')
    var inherits = require('inherits')
    var sign = require('./sign')
    var verify = require('./verify')
    
    var algorithms = require('./algorithms.json')
    Object.keys(algorithms).forEach(function (key) {
      algorithms[key].id = Buffer.from(algorithms[key].id, 'hex')
      algorithms[key.toLowerCase()] = algorithms[key]
    })
    
    function Sign (algorithm) {
      stream.Writable.call(this)
    
      var data = algorithms[algorithm]
      if (!data) throw new Error('Unknown message digest')
    
      this._hashType = data.hash
      this._hash = createHash(data.hash)
      this._tag = data.id
      this._signType = data.sign
    }
    inherits(Sign, stream.Writable)
    
    Sign.prototype._write = function _write (data, _, done) {
      this._hash.update(data)
      done()
    }
    
    Sign.prototype.update = function update (data, enc) {
      if (typeof data === 'string') data = Buffer.from(data, enc)
    
      this._hash.update(data)
      return this
    }
    
    Sign.prototype.sign = function signMethod (key, enc) {
      this.end()
      var hash = this._hash.digest()
      var sig = sign(hash, key, this._hashType, this._signType, this._tag)
    
      return enc ? sig.toString(enc) : sig
    }
    
    function Verify (algorithm) {
      stream.Writable.call(this)
    
      var data = algorithms[algorithm]
      if (!data) throw new Error('Unknown message digest')
    
      this._hash = createHash(data.hash)
      this._tag = data.id
      this._signType = data.sign
    }
    inherits(Verify, stream.Writable)
    
    Verify.prototype._write = function _write (data, _, done) {
      this._hash.update(data)
      done()
    }
    
    Verify.prototype.update = function update (data, enc) {
      if (typeof data === 'string') data = Buffer.from(data, enc)
    
      this._hash.update(data)
      return this
    }
    
    Verify.prototype.verify = function verifyMethod (key, sig, enc) {
      if (typeof sig === 'string') sig = Buffer.from(sig, enc)
    
      this.end()
      var hash = this._hash.digest()
      return verify(sig, hash, key, this._signType, this._tag)
    }
    
    function createSign (algorithm) {
      return new Sign(algorithm)
    }
    
    function createVerify (algorithm) {
      return new Verify(algorithm)
    }
    
    module.exports = {
      Sign: createSign,
      Verify: createVerify,
      createSign: createSign,
      createVerify: createVerify
    }
    
    },{"./algorithms.json":60,"./sign":63,"./verify":64,"create-hash":102,"inherits":182,"readable-stream":80,"safe-buffer":338}],63:[function(require,module,exports){
    // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
    var Buffer = require('safe-buffer').Buffer
    var createHmac = require('create-hmac')
    var crt = require('browserify-rsa')
    var EC = require('elliptic').ec
    var BN = require('bn.js')
    var parseKeys = require('parse-asn1')
    var curves = require('./curves.json')
    
    function sign (hash, key, hashType, signType, tag) {
      var priv = parseKeys(key)
      if (priv.curve) {
        // rsa keys can be interpreted as ecdsa ones in openssl
        if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
        return ecSign(hash, priv)
      } else if (priv.type === 'dsa') {
        if (signType !== 'dsa') throw new Error('wrong private key type')
        return dsaSign(hash, priv, hashType)
      } else {
        if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')
      }
      hash = Buffer.concat([tag, hash])
      var len = priv.modulus.byteLength()
      var pad = [0, 1]
      while (hash.length + pad.length + 1 < len) pad.push(0xff)
      pad.push(0x00)
      var i = -1
      while (++i < hash.length) pad.push(hash[i])
    
      var out = crt(pad, priv)
      return out
    }
    
    function ecSign (hash, priv) {
      var curveId = curves[priv.curve.join('.')]
      if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.'))
    
      var curve = new EC(curveId)
      var key = curve.keyFromPrivate(priv.privateKey)
      var out = key.sign(hash)
    
      return Buffer.from(out.toDER())
    }
    
    function dsaSign (hash, priv, algo) {
      var x = priv.params.priv_key
      var p = priv.params.p
      var q = priv.params.q
      var g = priv.params.g
      var r = new BN(0)
      var k
      var H = bits2int(hash, q).mod(q)
      var s = false
      var kv = getKey(x, q, hash, algo)
      while (s === false) {
        k = makeKey(q, kv, algo)
        r = makeR(g, k, p, q)
        s = k.invm(q).imul(H.add(x.mul(r))).mod(q)
        if (s.cmpn(0) === 0) {
          s = false
          r = new BN(0)
        }
      }
      return toDER(r, s)
    }
    
    function toDER (r, s) {
      r = r.toArray()
      s = s.toArray()
    
      // Pad values
      if (r[0] & 0x80) r = [0].concat(r)
      if (s[0] & 0x80) s = [0].concat(s)
    
      var total = r.length + s.length + 4
      var res = [0x30, total, 0x02, r.length]
      res = res.concat(r, [0x02, s.length], s)
      return Buffer.from(res)
    }
    
    function getKey (x, q, hash, algo) {
      x = Buffer.from(x.toArray())
      if (x.length < q.byteLength()) {
        var zeros = Buffer.alloc(q.byteLength() - x.length)
        x = Buffer.concat([zeros, x])
      }
      var hlen = hash.length
      var hbits = bits2octets(hash, q)
      var v = Buffer.alloc(hlen)
      v.fill(1)
      var k = Buffer.alloc(hlen)
      k = createHmac(algo, k).update(v).update(Buffer.from([0])).update(x).update(hbits).digest()
      v = createHmac(algo, k).update(v).digest()
      k = createHmac(algo, k).update(v).update(Buffer.from([1])).update(x).update(hbits).digest()
      v = createHmac(algo, k).update(v).digest()
      return { k: k, v: v }
    }
    
    function bits2int (obits, q) {
      var bits = new BN(obits)
      var shift = (obits.length << 3) - q.bitLength()
      if (shift > 0) bits.ishrn(shift)
      return bits
    }
    
    function bits2octets (bits, q) {
      bits = bits2int(bits, q)
      bits = bits.mod(q)
      var out = Buffer.from(bits.toArray())
      if (out.length < q.byteLength()) {
        var zeros = Buffer.alloc(q.byteLength() - out.length)
        out = Buffer.concat([zeros, out])
      }
      return out
    }
    
    function makeKey (q, kv, algo) {
      var t
      var k
    
      do {
        t = Buffer.alloc(0)
    
        while (t.length * 8 < q.bitLength()) {
          kv.v = createHmac(algo, kv.k).update(kv.v).digest()
          t = Buffer.concat([t, kv.v])
        }
    
        k = bits2int(t, q)
        kv.k = createHmac(algo, kv.k).update(kv.v).update(Buffer.from([0])).digest()
        kv.v = createHmac(algo, kv.k).update(kv.v).digest()
      } while (k.cmp(q) !== -1)
    
      return k
    }
    
    function makeR (g, k, p, q) {
      return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q)
    }
    
    module.exports = sign
    module.exports.getKey = getKey
    module.exports.makeKey = makeKey
    
    },{"./curves.json":61,"bn.js":65,"browserify-rsa":57,"create-hmac":104,"elliptic":118,"parse-asn1":312,"safe-buffer":338}],64:[function(require,module,exports){
    // much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
    var Buffer = require('safe-buffer').Buffer
    var BN = require('bn.js')
    var EC = require('elliptic').ec
    var parseKeys = require('parse-asn1')
    var curves = require('./curves.json')
    
    function verify (sig, hash, key, signType, tag) {
      var pub = parseKeys(key)
      if (pub.type === 'ec') {
        // rsa keys can be interpreted as ecdsa ones in openssl
        if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
        return ecVerify(sig, hash, pub)
      } else if (pub.type === 'dsa') {
        if (signType !== 'dsa') throw new Error('wrong public key type')
        return dsaVerify(sig, hash, pub)
      } else {
        if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')
      }
      hash = Buffer.concat([tag, hash])
      var len = pub.modulus.byteLength()
      var pad = [1]
      var padNum = 0
      while (hash.length + pad.length + 2 < len) {
        pad.push(0xff)
        padNum++
      }
      pad.push(0x00)
      var i = -1
      while (++i < hash.length) {
        pad.push(hash[i])
      }
      pad = Buffer.from(pad)
      var red = BN.mont(pub.modulus)
      sig = new BN(sig).toRed(red)
    
      sig = sig.redPow(new BN(pub.publicExponent))
      sig = Buffer.from(sig.fromRed().toArray())
      var out = padNum < 8 ? 1 : 0
      len = Math.min(sig.length, pad.length)
      if (sig.length !== pad.length) out = 1
    
      i = -1
      while (++i < len) out |= sig[i] ^ pad[i]
      return out === 0
    }
    
    function ecVerify (sig, hash, pub) {
      var curveId = curves[pub.data.algorithm.curve.join('.')]
      if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))
    
      var curve = new EC(curveId)
      var pubkey = pub.data.subjectPrivateKey.data
    
      return curve.verify(hash, sig, pubkey)
    }
    
    function dsaVerify (sig, hash, pub) {
      var p = pub.data.p
      var q = pub.data.q
      var g = pub.data.g
      var y = pub.data.pub_key
      var unpacked = parseKeys.signature.decode(sig, 'der')
      var s = unpacked.s
      var r = unpacked.r
      checkValue(s, q)
      checkValue(r, q)
      var montp = BN.mont(p)
      var w = s.invm(q)
      var v = g.toRed(montp)
        .redPow(new BN(hash).mul(w).mod(q))
        .fromRed()
        .mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed())
        .mod(p)
        .mod(q)
      return v.cmp(r) === 0
    }
    
    function checkValue (b, q) {
      if (b.cmpn(0) <= 0) throw new Error('invalid sig')
      if (b.cmp(q) >= q) throw new Error('invalid sig')
    }
    
    module.exports = verify
    
    },{"./curves.json":61,"bn.js":65,"elliptic":118,"parse-asn1":312,"safe-buffer":338}],65:[function(require,module,exports){
    arguments[4][58][0].apply(exports,arguments)
    },{"buffer":36,"dup":58}],66:[function(require,module,exports){
    'use strict';
    
    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
    
    var codes = {};
    
    function createErrorType(code, message, Base) {
      if (!Base) {
        Base = Error;
      }
    
      function getMessage(arg1, arg2, arg3) {
        if (typeof message === 'string') {
          return message;
        } else {
          return message(arg1, arg2, arg3);
        }
      }
    
      var NodeError =
      /*#__PURE__*/
      function (_Base) {
        _inheritsLoose(NodeError, _Base);
    
        function NodeError(arg1, arg2, arg3) {
          return _Base.call(this, getMessage(arg1, arg2, arg3)) || this;
        }
    
        return NodeError;
      }(Base);
    
      NodeError.prototype.name = Base.name;
      NodeError.prototype.code = code;
      codes[code] = NodeError;
    } // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js
    
    
    function oneOf(expected, thing) {
      if (Array.isArray(expected)) {
        var len = expected.length;
        expected = expected.map(function (i) {
          return String(i);
        });
    
        if (len > 2) {
          return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1];
        } else if (len === 2) {
          return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]);
        } else {
          return "of ".concat(thing, " ").concat(expected[0]);
        }
      } else {
        return "of ".concat(thing, " ").concat(String(expected));
      }
    } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
    
    
    function startsWith(str, search, pos) {
      return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
    } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
    
    
    function endsWith(str, search, this_len) {
      if (this_len === undefined || this_len > str.length) {
        this_len = str.length;
      }
    
      return str.substring(this_len - search.length, this_len) === search;
    } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
    
    
    function includes(str, search, start) {
      if (typeof start !== 'number') {
        start = 0;
      }
    
      if (start + search.length > str.length) {
        return false;
      } else {
        return str.indexOf(search, start) !== -1;
      }
    }
    
    createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) {
      return 'The value "' + value + '" is invalid for option "' + name + '"';
    }, TypeError);
    createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) {
      // determiner: 'must be' or 'must not be'
      var determiner;
    
      if (typeof expected === 'string' && startsWith(expected, 'not ')) {
        determiner = 'must not be';
        expected = expected.replace(/^not /, '');
      } else {
        determiner = 'must be';
      }
    
      var msg;
    
      if (endsWith(name, ' argument')) {
        // For cases like 'first argument'
        msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
      } else {
        var type = includes(name, '.') ? 'property' : 'argument';
        msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type'));
      }
    
      msg += ". Received type ".concat(typeof actual);
      return msg;
    }, TypeError);
    createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
    createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) {
      return 'The ' + name + ' method is not implemented';
    });
    createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
    createErrorType('ERR_STREAM_DESTROYED', function (name) {
      return 'Cannot call ' + name + ' after a stream was destroyed';
    });
    createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
    createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
    createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end');
    createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError);
    createErrorType('ERR_UNKNOWN_ENCODING', function (arg) {
      return 'Unknown encoding: ' + arg;
    }, TypeError);
    createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event');
    module.exports.codes = codes;
    
    },{}],67:[function(require,module,exports){
    (function (process){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // a duplex stream is just a stream that is both readable and writable.
    // Since JS doesn't have multiple prototypal inheritance, this class
    // prototypally inherits from Readable, and then parasitically from
    // Writable.
    
    'use strict';
    
    /*<replacement>*/
    var objectKeys = Object.keys || function (obj) {
      var keys = [];
      for (var key in obj) keys.push(key);
      return keys;
    };
    /*</replacement>*/
    
    module.exports = Duplex;
    var Readable = require('./_stream_readable');
    var Writable = require('./_stream_writable');
    require('inherits')(Duplex, Readable);
    {
      // Allow the keys array to be GC'ed.
      var keys = objectKeys(Writable.prototype);
      for (var v = 0; v < keys.length; v++) {
        var method = keys[v];
        if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
      }
    }
    function Duplex(options) {
      if (!(this instanceof Duplex)) return new Duplex(options);
      Readable.call(this, options);
      Writable.call(this, options);
      this.allowHalfOpen = true;
      if (options) {
        if (options.readable === false) this.readable = false;
        if (options.writable === false) this.writable = false;
        if (options.allowHalfOpen === false) {
          this.allowHalfOpen = false;
          this.once('end', onend);
        }
      }
    }
    Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    
    // the no-half-open enforcer
    function onend() {
      // If the writable side ended, then we're ok.
      if (this._writableState.ended) return;
    
      // no more data can be written.
      // But allow more writes to happen in this tick.
      process.nextTick(onEndNT, this);
    }
    function onEndNT(self) {
      self.end();
    }
    Object.defineProperty(Duplex.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined || this._writableState === undefined) {
          return false;
        }
        return this._readableState.destroyed && this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (this._readableState === undefined || this._writableState === undefined) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
        this._writableState.destroyed = value;
      }
    });
    }).call(this)}).call(this,require('_process'))
    
    },{"./_stream_readable":69,"./_stream_writable":71,"_process":321,"inherits":182}],68:[function(require,module,exports){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // a passthrough stream.
    // basically just the most minimal sort of Transform stream.
    // Every written chunk gets output as-is.
    
    'use strict';
    
    module.exports = PassThrough;
    var Transform = require('./_stream_transform');
    require('inherits')(PassThrough, Transform);
    function PassThrough(options) {
      if (!(this instanceof PassThrough)) return new PassThrough(options);
      Transform.call(this, options);
    }
    PassThrough.prototype._transform = function (chunk, encoding, cb) {
      cb(null, chunk);
    };
    },{"./_stream_transform":70,"inherits":182}],69:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    module.exports = Readable;
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Readable.ReadableState = ReadableState;
    
    /*<replacement>*/
    var EE = require('events').EventEmitter;
    var EElistenerCount = function EElistenerCount(emitter, type) {
      return emitter.listeners(type).length;
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    
    /*<replacement>*/
    var debugUtil = require('util');
    var debug;
    if (debugUtil && debugUtil.debuglog) {
      debug = debugUtil.debuglog('stream');
    } else {
      debug = function debug() {};
    }
    /*</replacement>*/
    
    var BufferList = require('./internal/streams/buffer_list');
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;
    
    // Lazy loaded to improve the startup performance.
    var StringDecoder;
    var createReadableStreamAsyncIterator;
    var from;
    require('inherits')(Readable, Stream);
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
    function prependListener(emitter, event, fn) {
      // Sadly this is not cacheable as some libraries bundle their own
      // event emitter implementation with them.
      if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
    
      // This is a hack to make sure that our error handler is attached before any
      // userland ones.  NEVER DO THIS. This is here only because this code needs
      // to continue to work with older versions of Node.js that do not include
      // the prependListener() method. The goal is to eventually remove this hack.
      if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
    }
    function ReadableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream.
      // These options can be provided separately as readableXXX and writableXXX.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag. Used to make read(n) ignore n and to
      // make all the buffer merging and length checks go away
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
    
      // the point at which it stops calling _read() to fill the buffer
      // Note: 0 is a valid value, means "don't call _read preemptively ever"
      this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex);
    
      // A linked list is used to store data chunks instead of an array because the
      // linked list can remove elements from the beginning faster than
      // array.shift()
      this.buffer = new BufferList();
      this.length = 0;
      this.pipes = null;
      this.pipesCount = 0;
      this.flowing = null;
      this.ended = false;
      this.endEmitted = false;
      this.reading = false;
    
      // a flag to be able to tell if the event 'readable'/'data' is emitted
      // immediately, or on a later tick.  We set this to true at first, because
      // any actions that shouldn't happen until "later" should generally also
      // not happen before the first read call.
      this.sync = true;
    
      // whenever we return null, then we set a flag to say
      // that we're awaiting a 'readable' event emission.
      this.needReadable = false;
      this.emittedReadable = false;
      this.readableListening = false;
      this.resumeScheduled = false;
      this.paused = true;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'end' (and potentially 'finish')
      this.autoDestroy = !!options.autoDestroy;
    
      // has it been destroyed
      this.destroyed = false;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // the number of writers that are awaiting a drain event in .pipe()s
      this.awaitDrain = 0;
    
      // if true, a maybeReadMore has been scheduled
      this.readingMore = false;
      this.decoder = null;
      this.encoding = null;
      if (options.encoding) {
        if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
        this.decoder = new StringDecoder(options.encoding);
        this.encoding = options.encoding;
      }
    }
    function Readable(options) {
      Duplex = Duplex || require('./_stream_duplex');
      if (!(this instanceof Readable)) return new Readable(options);
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the ReadableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      this._readableState = new ReadableState(options, this, isDuplex);
    
      // legacy
      this.readable = true;
      if (options) {
        if (typeof options.read === 'function') this._read = options.read;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
      }
      Stream.call(this);
    }
    Object.defineProperty(Readable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined) {
          return false;
        }
        return this._readableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._readableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
      }
    });
    Readable.prototype.destroy = destroyImpl.destroy;
    Readable.prototype._undestroy = destroyImpl.undestroy;
    Readable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    
    // Manually shove something into the read() buffer.
    // This returns true if the highWaterMark has not been hit yet,
    // similar to how Writable.write() returns true if you should
    // write() some more.
    Readable.prototype.push = function (chunk, encoding) {
      var state = this._readableState;
      var skipChunkCheck;
      if (!state.objectMode) {
        if (typeof chunk === 'string') {
          encoding = encoding || state.defaultEncoding;
          if (encoding !== state.encoding) {
            chunk = Buffer.from(chunk, encoding);
            encoding = '';
          }
          skipChunkCheck = true;
        }
      } else {
        skipChunkCheck = true;
      }
      return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
    };
    
    // Unshift should *always* be something directly out of read()
    Readable.prototype.unshift = function (chunk) {
      return readableAddChunk(this, chunk, null, true, false);
    };
    function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
      debug('readableAddChunk', chunk);
      var state = stream._readableState;
      if (chunk === null) {
        state.reading = false;
        onEofChunk(stream, state);
      } else {
        var er;
        if (!skipChunkCheck) er = chunkInvalid(state, chunk);
        if (er) {
          errorOrDestroy(stream, er);
        } else if (state.objectMode || chunk && chunk.length > 0) {
          if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
            chunk = _uint8ArrayToBuffer(chunk);
          }
          if (addToFront) {
            if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
          } else if (state.ended) {
            errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
          } else if (state.destroyed) {
            return false;
          } else {
            state.reading = false;
            if (state.decoder && !encoding) {
              chunk = state.decoder.write(chunk);
              if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
            } else {
              addChunk(stream, state, chunk, false);
            }
          }
        } else if (!addToFront) {
          state.reading = false;
          maybeReadMore(stream, state);
        }
      }
    
      // We can push more data if we are below the highWaterMark.
      // Also, if we have no data yet, we can stand some more bytes.
      // This is to work around cases where hwm=0, such as the repl.
      return !state.ended && (state.length < state.highWaterMark || state.length === 0);
    }
    function addChunk(stream, state, chunk, addToFront) {
      if (state.flowing && state.length === 0 && !state.sync) {
        state.awaitDrain = 0;
        stream.emit('data', chunk);
      } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
        if (state.needReadable) emitReadable(stream);
      }
      maybeReadMore(stream, state);
    }
    function chunkInvalid(state, chunk) {
      var er;
      if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
      }
      return er;
    }
    Readable.prototype.isPaused = function () {
      return this._readableState.flowing === false;
    };
    
    // backwards compatibility.
    Readable.prototype.setEncoding = function (enc) {
      if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
      var decoder = new StringDecoder(enc);
      this._readableState.decoder = decoder;
      // If setEncoding(null), decoder.encoding equals utf8
      this._readableState.encoding = this._readableState.decoder.encoding;
    
      // Iterate over current buffer to convert already stored Buffers:
      var p = this._readableState.buffer.head;
      var content = '';
      while (p !== null) {
        content += decoder.write(p.data);
        p = p.next;
      }
      this._readableState.buffer.clear();
      if (content !== '') this._readableState.buffer.push(content);
      this._readableState.length = content.length;
      return this;
    };
    
    // Don't raise the hwm > 1GB
    var MAX_HWM = 0x40000000;
    function computeNewHighWaterMark(n) {
      if (n >= MAX_HWM) {
        // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
        n = MAX_HWM;
      } else {
        // Get the next highest power of 2 to prevent increasing hwm excessively in
        // tiny amounts
        n--;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        n++;
      }
      return n;
    }
    
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function howMuchToRead(n, state) {
      if (n <= 0 || state.length === 0 && state.ended) return 0;
      if (state.objectMode) return 1;
      if (n !== n) {
        // Only flow one buffer at a time
        if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
      }
      // If we're asking for more than the current hwm, then raise the hwm.
      if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
      if (n <= state.length) return n;
      // Don't have enough
      if (!state.ended) {
        state.needReadable = true;
        return 0;
      }
      return state.length;
    }
    
    // you can override either this method, or the async _read(n) below.
    Readable.prototype.read = function (n) {
      debug('read', n);
      n = parseInt(n, 10);
      var state = this._readableState;
      var nOrig = n;
      if (n !== 0) state.emittedReadable = false;
    
      // if we're doing read(0) to trigger a readable event, but we
      // already have a bunch of data in the buffer, then just trigger
      // the 'readable' event and move on.
      if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
        debug('read: emitReadable', state.length, state.ended);
        if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
        return null;
      }
      n = howMuchToRead(n, state);
    
      // if we've ended, and we're now clear, then finish it up.
      if (n === 0 && state.ended) {
        if (state.length === 0) endReadable(this);
        return null;
      }
    
      // All the actual chunk generation logic needs to be
      // *below* the call to _read.  The reason is that in certain
      // synthetic stream cases, such as passthrough streams, _read
      // may be a completely synchronous operation which may change
      // the state of the read buffer, providing enough data when
      // before there was *not* enough.
      //
      // So, the steps are:
      // 1. Figure out what the state of things will be after we do
      // a read from the buffer.
      //
      // 2. If that resulting state will trigger a _read, then call _read.
      // Note that this may be asynchronous, or synchronous.  Yes, it is
      // deeply ugly to write APIs this way, but that still doesn't mean
      // that the Readable class should behave improperly, as streams are
      // designed to be sync/async agnostic.
      // Take note if the _read call is sync or async (ie, if the read call
      // has returned yet), so that we know whether or not it's safe to emit
      // 'readable' etc.
      //
      // 3. Actually pull the requested chunks out of the buffer and return.
    
      // if we need a readable event, then we need to do some reading.
      var doRead = state.needReadable;
      debug('need readable', doRead);
    
      // if we currently have less than the highWaterMark, then also read some
      if (state.length === 0 || state.length - n < state.highWaterMark) {
        doRead = true;
        debug('length less than watermark', doRead);
      }
    
      // however, if we've ended, then there's no point, and if we're already
      // reading, then it's unnecessary.
      if (state.ended || state.reading) {
        doRead = false;
        debug('reading or ended', doRead);
      } else if (doRead) {
        debug('do read');
        state.reading = true;
        state.sync = true;
        // if the length is currently zero, then we *need* a readable event.
        if (state.length === 0) state.needReadable = true;
        // call internal read method
        this._read(state.highWaterMark);
        state.sync = false;
        // If _read pushed data synchronously, then `reading` will be false,
        // and we need to re-evaluate how much data we can return to the user.
        if (!state.reading) n = howMuchToRead(nOrig, state);
      }
      var ret;
      if (n > 0) ret = fromList(n, state);else ret = null;
      if (ret === null) {
        state.needReadable = state.length <= state.highWaterMark;
        n = 0;
      } else {
        state.length -= n;
        state.awaitDrain = 0;
      }
      if (state.length === 0) {
        // If we have nothing in the buffer, then we want to know
        // as soon as we *do* get something into the buffer.
        if (!state.ended) state.needReadable = true;
    
        // If we tried to read() past the EOF, then emit end on the next tick.
        if (nOrig !== n && state.ended) endReadable(this);
      }
      if (ret !== null) this.emit('data', ret);
      return ret;
    };
    function onEofChunk(stream, state) {
      debug('onEofChunk');
      if (state.ended) return;
      if (state.decoder) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length) {
          state.buffer.push(chunk);
          state.length += state.objectMode ? 1 : chunk.length;
        }
      }
      state.ended = true;
      if (state.sync) {
        // if we are sync, wait until next tick to emit the data.
        // Otherwise we risk emitting data in the flow()
        // the readable code triggers during a read() call
        emitReadable(stream);
      } else {
        // emit 'readable' now to make sure it gets picked up.
        state.needReadable = false;
        if (!state.emittedReadable) {
          state.emittedReadable = true;
          emitReadable_(stream);
        }
      }
    }
    
    // Don't emit readable right away in sync mode, because this can trigger
    // another read() call => stack overflow.  This way, it might trigger
    // a nextTick recursion warning, but that's not so bad.
    function emitReadable(stream) {
      var state = stream._readableState;
      debug('emitReadable', state.needReadable, state.emittedReadable);
      state.needReadable = false;
      if (!state.emittedReadable) {
        debug('emitReadable', state.flowing);
        state.emittedReadable = true;
        process.nextTick(emitReadable_, stream);
      }
    }
    function emitReadable_(stream) {
      var state = stream._readableState;
      debug('emitReadable_', state.destroyed, state.length, state.ended);
      if (!state.destroyed && (state.length || state.ended)) {
        stream.emit('readable');
        state.emittedReadable = false;
      }
    
      // The stream needs another readable event if
      // 1. It is not flowing, as the flow mechanism will take
      //    care of it.
      // 2. It is not ended.
      // 3. It is below the highWaterMark, so we can schedule
      //    another readable later.
      state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
      flow(stream);
    }
    
    // at this point, the user has presumably seen the 'readable' event,
    // and called read() to consume some data.  that may have triggered
    // in turn another _read(n) call, in which case reading = true if
    // it's in progress.
    // However, if we're not ended, or reading, and the length < hwm,
    // then go ahead and try to read some more preemptively.
    function maybeReadMore(stream, state) {
      if (!state.readingMore) {
        state.readingMore = true;
        process.nextTick(maybeReadMore_, stream, state);
      }
    }
    function maybeReadMore_(stream, state) {
      // Attempt to read more data if we should.
      //
      // The conditions for reading more data are (one of):
      // - Not enough data buffered (state.length < state.highWaterMark). The loop
      //   is responsible for filling the buffer with enough data if such data
      //   is available. If highWaterMark is 0 and we are not in the flowing mode
      //   we should _not_ attempt to buffer any extra data. We'll get more data
      //   when the stream consumer calls read() instead.
      // - No data in the buffer, and the stream is in flowing mode. In this mode
      //   the loop below is responsible for ensuring read() is called. Failing to
      //   call read here would abort the flow and there's no other mechanism for
      //   continuing the flow if the stream consumer has just subscribed to the
      //   'data' event.
      //
      // In addition to the above conditions to keep reading data, the following
      // conditions prevent the data from being read:
      // - The stream has ended (state.ended).
      // - There is already a pending 'read' operation (state.reading). This is a
      //   case where the the stream has called the implementation defined _read()
      //   method, but they are processing the call asynchronously and have _not_
      //   called push() with new data. In this case we skip performing more
      //   read()s. The execution ends in this method again after the _read() ends
      //   up calling push() with more data.
      while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
        var len = state.length;
        debug('maybeReadMore read 0');
        stream.read(0);
        if (len === state.length)
          // didn't get any data, stop spinning.
          break;
      }
      state.readingMore = false;
    }
    
    // abstract method.  to be overridden in specific implementation classes.
    // call cb(er, data) where data is <= n in length.
    // for virtual (non-string, non-buffer) streams, "length" is somewhat
    // arbitrary, and perhaps not very meaningful.
    Readable.prototype._read = function (n) {
      errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
    };
    Readable.prototype.pipe = function (dest, pipeOpts) {
      var src = this;
      var state = this._readableState;
      switch (state.pipesCount) {
        case 0:
          state.pipes = dest;
          break;
        case 1:
          state.pipes = [state.pipes, dest];
          break;
        default:
          state.pipes.push(dest);
          break;
      }
      state.pipesCount += 1;
      debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
      var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
      var endFn = doEnd ? onend : unpipe;
      if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
      dest.on('unpipe', onunpipe);
      function onunpipe(readable, unpipeInfo) {
        debug('onunpipe');
        if (readable === src) {
          if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
            unpipeInfo.hasUnpiped = true;
            cleanup();
          }
        }
      }
      function onend() {
        debug('onend');
        dest.end();
      }
    
      // when the dest drains, it reduces the awaitDrain counter
      // on the source.  This would be more elegant with a .once()
      // handler in flow(), but adding and removing repeatedly is
      // too slow.
      var ondrain = pipeOnDrain(src);
      dest.on('drain', ondrain);
      var cleanedUp = false;
      function cleanup() {
        debug('cleanup');
        // cleanup event handlers once the pipe is broken
        dest.removeListener('close', onclose);
        dest.removeListener('finish', onfinish);
        dest.removeListener('drain', ondrain);
        dest.removeListener('error', onerror);
        dest.removeListener('unpipe', onunpipe);
        src.removeListener('end', onend);
        src.removeListener('end', unpipe);
        src.removeListener('data', ondata);
        cleanedUp = true;
    
        // if the reader is waiting for a drain event from this
        // specific writer, then it would cause it to never start
        // flowing again.
        // So, if this is awaiting a drain, then we just call it now.
        // If we don't know, then assume that we are waiting for one.
        if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
      }
      src.on('data', ondata);
      function ondata(chunk) {
        debug('ondata');
        var ret = dest.write(chunk);
        debug('dest.write', ret);
        if (ret === false) {
          // If the user unpiped during `dest.write()`, it is possible
          // to get stuck in a permanently paused state if that write
          // also returned false.
          // => Check whether `dest` is still a piping destination.
          if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
            debug('false write response, pause', state.awaitDrain);
            state.awaitDrain++;
          }
          src.pause();
        }
      }
    
      // if the dest has an error, then stop piping into it.
      // however, don't suppress the throwing behavior for this.
      function onerror(er) {
        debug('onerror', er);
        unpipe();
        dest.removeListener('error', onerror);
        if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
      }
    
      // Make sure our error handler is attached before userland ones.
      prependListener(dest, 'error', onerror);
    
      // Both close and finish should trigger unpipe, but only once.
      function onclose() {
        dest.removeListener('finish', onfinish);
        unpipe();
      }
      dest.once('close', onclose);
      function onfinish() {
        debug('onfinish');
        dest.removeListener('close', onclose);
        unpipe();
      }
      dest.once('finish', onfinish);
      function unpipe() {
        debug('unpipe');
        src.unpipe(dest);
      }
    
      // tell the dest that it's being piped to
      dest.emit('pipe', src);
    
      // start the flow if it hasn't been started already.
      if (!state.flowing) {
        debug('pipe resume');
        src.resume();
      }
      return dest;
    };
    function pipeOnDrain(src) {
      return function pipeOnDrainFunctionResult() {
        var state = src._readableState;
        debug('pipeOnDrain', state.awaitDrain);
        if (state.awaitDrain) state.awaitDrain--;
        if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
          state.flowing = true;
          flow(src);
        }
      };
    }
    Readable.prototype.unpipe = function (dest) {
      var state = this._readableState;
      var unpipeInfo = {
        hasUnpiped: false
      };
    
      // if we're not piping anywhere, then do nothing.
      if (state.pipesCount === 0) return this;
    
      // just one destination.  most common case.
      if (state.pipesCount === 1) {
        // passed in one, but it's not the right one.
        if (dest && dest !== state.pipes) return this;
        if (!dest) dest = state.pipes;
    
        // got a match.
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        if (dest) dest.emit('unpipe', this, unpipeInfo);
        return this;
      }
    
      // slow case. multiple pipe destinations.
    
      if (!dest) {
        // remove all.
        var dests = state.pipes;
        var len = state.pipesCount;
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, {
          hasUnpiped: false
        });
        return this;
      }
    
      // try to find the right one.
      var index = indexOf(state.pipes, dest);
      if (index === -1) return this;
      state.pipes.splice(index, 1);
      state.pipesCount -= 1;
      if (state.pipesCount === 1) state.pipes = state.pipes[0];
      dest.emit('unpipe', this, unpipeInfo);
      return this;
    };
    
    // set up data events if they are asked for
    // Ensure readable listeners eventually get something
    Readable.prototype.on = function (ev, fn) {
      var res = Stream.prototype.on.call(this, ev, fn);
      var state = this._readableState;
      if (ev === 'data') {
        // update readableListening so that resume() may be a no-op
        // a few lines down. This is needed to support once('readable').
        state.readableListening = this.listenerCount('readable') > 0;
    
        // Try start flowing on next tick if stream isn't explicitly paused
        if (state.flowing !== false) this.resume();
      } else if (ev === 'readable') {
        if (!state.endEmitted && !state.readableListening) {
          state.readableListening = state.needReadable = true;
          state.flowing = false;
          state.emittedReadable = false;
          debug('on readable', state.length, state.reading);
          if (state.length) {
            emitReadable(this);
          } else if (!state.reading) {
            process.nextTick(nReadingNextTick, this);
          }
        }
      }
      return res;
    };
    Readable.prototype.addListener = Readable.prototype.on;
    Readable.prototype.removeListener = function (ev, fn) {
      var res = Stream.prototype.removeListener.call(this, ev, fn);
      if (ev === 'readable') {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    Readable.prototype.removeAllListeners = function (ev) {
      var res = Stream.prototype.removeAllListeners.apply(this, arguments);
      if (ev === 'readable' || ev === undefined) {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    function updateReadableListening(self) {
      var state = self._readableState;
      state.readableListening = self.listenerCount('readable') > 0;
      if (state.resumeScheduled && !state.paused) {
        // flowing needs to be set to true now, otherwise
        // the upcoming resume will not flow.
        state.flowing = true;
    
        // crude way to check if we should resume
      } else if (self.listenerCount('data') > 0) {
        self.resume();
      }
    }
    function nReadingNextTick(self) {
      debug('readable nexttick read 0');
      self.read(0);
    }
    
    // pause() and resume() are remnants of the legacy readable stream API
    // If the user uses them, then switch into old mode.
    Readable.prototype.resume = function () {
      var state = this._readableState;
      if (!state.flowing) {
        debug('resume');
        // we flow only if there is no one listening
        // for readable, but we still have to call
        // resume()
        state.flowing = !state.readableListening;
        resume(this, state);
      }
      state.paused = false;
      return this;
    };
    function resume(stream, state) {
      if (!state.resumeScheduled) {
        state.resumeScheduled = true;
        process.nextTick(resume_, stream, state);
      }
    }
    function resume_(stream, state) {
      debug('resume', state.reading);
      if (!state.reading) {
        stream.read(0);
      }
      state.resumeScheduled = false;
      stream.emit('resume');
      flow(stream);
      if (state.flowing && !state.reading) stream.read(0);
    }
    Readable.prototype.pause = function () {
      debug('call pause flowing=%j', this._readableState.flowing);
      if (this._readableState.flowing !== false) {
        debug('pause');
        this._readableState.flowing = false;
        this.emit('pause');
      }
      this._readableState.paused = true;
      return this;
    };
    function flow(stream) {
      var state = stream._readableState;
      debug('flow', state.flowing);
      while (state.flowing && stream.read() !== null);
    }
    
    // wrap an old-style stream as the async data source.
    // This is *not* part of the readable stream interface.
    // It is an ugly unfortunate mess of history.
    Readable.prototype.wrap = function (stream) {
      var _this = this;
      var state = this._readableState;
      var paused = false;
      stream.on('end', function () {
        debug('wrapped end');
        if (state.decoder && !state.ended) {
          var chunk = state.decoder.end();
          if (chunk && chunk.length) _this.push(chunk);
        }
        _this.push(null);
      });
      stream.on('data', function (chunk) {
        debug('wrapped data');
        if (state.decoder) chunk = state.decoder.write(chunk);
    
        // don't skip over falsy values in objectMode
        if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
        var ret = _this.push(chunk);
        if (!ret) {
          paused = true;
          stream.pause();
        }
      });
    
      // proxy all the other methods.
      // important when wrapping filters and duplexes.
      for (var i in stream) {
        if (this[i] === undefined && typeof stream[i] === 'function') {
          this[i] = function methodWrap(method) {
            return function methodWrapReturnFunction() {
              return stream[method].apply(stream, arguments);
            };
          }(i);
        }
      }
    
      // proxy certain important events.
      for (var n = 0; n < kProxyEvents.length; n++) {
        stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
      }
    
      // when we try to consume some more bytes, simply unpause the
      // underlying stream.
      this._read = function (n) {
        debug('wrapped _read', n);
        if (paused) {
          paused = false;
          stream.resume();
        }
      };
      return this;
    };
    if (typeof Symbol === 'function') {
      Readable.prototype[Symbol.asyncIterator] = function () {
        if (createReadableStreamAsyncIterator === undefined) {
          createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
        }
        return createReadableStreamAsyncIterator(this);
      };
    }
    Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.highWaterMark;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState && this._readableState.buffer;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableFlowing', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.flowing;
      },
      set: function set(state) {
        if (this._readableState) {
          this._readableState.flowing = state;
        }
      }
    });
    
    // exposed for testing purposes only.
    Readable._fromList = fromList;
    Object.defineProperty(Readable.prototype, 'readableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.length;
      }
    });
    
    // Pluck off n bytes from an array of buffers.
    // Length is the combined lengths of all the buffers in the list.
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function fromList(n, state) {
      // nothing buffered
      if (state.length === 0) return null;
      var ret;
      if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
        // read it all, truncate the list
        if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
        state.buffer.clear();
      } else {
        // read part of list
        ret = state.buffer.consume(n, state.decoder);
      }
      return ret;
    }
    function endReadable(stream) {
      var state = stream._readableState;
      debug('endReadable', state.endEmitted);
      if (!state.endEmitted) {
        state.ended = true;
        process.nextTick(endReadableNT, state, stream);
      }
    }
    function endReadableNT(state, stream) {
      debug('endReadableNT', state.endEmitted, state.length);
    
      // Check that we didn't get one last unshift.
      if (!state.endEmitted && state.length === 0) {
        state.endEmitted = true;
        stream.readable = false;
        stream.emit('end');
        if (state.autoDestroy) {
          // In case of duplex streams we need a way to detect
          // if the writable side is ready for autoDestroy as well
          var wState = stream._writableState;
          if (!wState || wState.autoDestroy && wState.finished) {
            stream.destroy();
          }
        }
      }
    }
    if (typeof Symbol === 'function') {
      Readable.from = function (iterable, opts) {
        if (from === undefined) {
          from = require('./internal/streams/from');
        }
        return from(Readable, iterable, opts);
      };
    }
    function indexOf(xs, x) {
      for (var i = 0, l = xs.length; i < l; i++) {
        if (xs[i] === x) return i;
      }
      return -1;
    }
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":66,"./_stream_duplex":67,"./internal/streams/async_iterator":72,"./internal/streams/buffer_list":73,"./internal/streams/destroy":74,"./internal/streams/from":76,"./internal/streams/state":78,"./internal/streams/stream":79,"_process":321,"buffer":84,"events":134,"inherits":182,"string_decoder/":365,"util":36}],70:[function(require,module,exports){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // a transform stream is a readable/writable stream where you do
    // something with the data.  Sometimes it's called a "filter",
    // but that's not a great name for it, since that implies a thing where
    // some bits pass through, and others are simply ignored.  (That would
    // be a valid example of a transform, of course.)
    //
    // While the output is causally related to the input, it's not a
    // necessarily symmetric or synchronous transformation.  For example,
    // a zlib stream might take multiple plain-text writes(), and then
    // emit a single compressed chunk some time in the future.
    //
    // Here's how this works:
    //
    // The Transform stream has all the aspects of the readable and writable
    // stream classes.  When you write(chunk), that calls _write(chunk,cb)
    // internally, and returns false if there's a lot of pending writes
    // buffered up.  When you call read(), that calls _read(n) until
    // there's enough pending readable data buffered up.
    //
    // In a transform stream, the written data is placed in a buffer.  When
    // _read(n) is called, it transforms the queued up data, calling the
    // buffered _write cb's as it consumes chunks.  If consuming a single
    // written chunk would result in multiple output chunks, then the first
    // outputted bit calls the readcb, and subsequent chunks just go into
    // the read buffer, and will cause it to emit 'readable' if necessary.
    //
    // This way, back-pressure is actually determined by the reading side,
    // since _read has to be called to start processing a new chunk.  However,
    // a pathological inflate type of transform can cause excessive buffering
    // here.  For example, imagine a stream where every byte of input is
    // interpreted as an integer from 0-255, and then results in that many
    // bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
    // 1kb of data being output.  In this case, you could write a very small
    // amount of input, and end up with a very large amount of output.  In
    // such a pathological inflating mechanism, there'd be no way to tell
    // the system to stop doing the transform.  A single 4MB write could
    // cause the system to run out of memory.
    //
    // However, even in such a pathological case, only a single written chunk
    // would be consumed, and then the rest would wait (un-transformed) until
    // the results of the previous transformed chunk were consumed.
    
    'use strict';
    
    module.exports = Transform;
    var _require$codes = require('../errors').codes,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
      ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING,
      ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0;
    var Duplex = require('./_stream_duplex');
    require('inherits')(Transform, Duplex);
    function afterTransform(er, data) {
      var ts = this._transformState;
      ts.transforming = false;
      var cb = ts.writecb;
      if (cb === null) {
        return this.emit('error', new ERR_MULTIPLE_CALLBACK());
      }
      ts.writechunk = null;
      ts.writecb = null;
      if (data != null)
        // single equals check for both `null` and `undefined`
        this.push(data);
      cb(er);
      var rs = this._readableState;
      rs.reading = false;
      if (rs.needReadable || rs.length < rs.highWaterMark) {
        this._read(rs.highWaterMark);
      }
    }
    function Transform(options) {
      if (!(this instanceof Transform)) return new Transform(options);
      Duplex.call(this, options);
      this._transformState = {
        afterTransform: afterTransform.bind(this),
        needTransform: false,
        transforming: false,
        writecb: null,
        writechunk: null,
        writeencoding: null
      };
    
      // start out asking for a readable event once data is transformed.
      this._readableState.needReadable = true;
    
      // we have implemented the _read method, and done the other things
      // that Readable wants before the first _read call, so unset the
      // sync guard flag.
      this._readableState.sync = false;
      if (options) {
        if (typeof options.transform === 'function') this._transform = options.transform;
        if (typeof options.flush === 'function') this._flush = options.flush;
      }
    
      // When the writable side finishes, then flush out anything remaining.
      this.on('prefinish', prefinish);
    }
    function prefinish() {
      var _this = this;
      if (typeof this._flush === 'function' && !this._readableState.destroyed) {
        this._flush(function (er, data) {
          done(_this, er, data);
        });
      } else {
        done(this, null, null);
      }
    }
    Transform.prototype.push = function (chunk, encoding) {
      this._transformState.needTransform = false;
      return Duplex.prototype.push.call(this, chunk, encoding);
    };
    
    // This is the part where you do stuff!
    // override this function in implementation classes.
    // 'chunk' is an input chunk.
    //
    // Call `push(newChunk)` to pass along transformed output
    // to the readable side.  You may call 'push' zero or more times.
    //
    // Call `cb(err)` when you are done with this chunk.  If you pass
    // an error, then that'll put the hurt on the whole operation.  If you
    // never call cb(), then you'll never get another chunk.
    Transform.prototype._transform = function (chunk, encoding, cb) {
      cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()'));
    };
    Transform.prototype._write = function (chunk, encoding, cb) {
      var ts = this._transformState;
      ts.writecb = cb;
      ts.writechunk = chunk;
      ts.writeencoding = encoding;
      if (!ts.transforming) {
        var rs = this._readableState;
        if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
      }
    };
    
    // Doesn't matter what the args are here.
    // _transform does all the work.
    // That we got here means that the readable side wants more data.
    Transform.prototype._read = function (n) {
      var ts = this._transformState;
      if (ts.writechunk !== null && !ts.transforming) {
        ts.transforming = true;
        this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
      } else {
        // mark that we need a transform, so that any data that comes in
        // will get processed, now that we've asked for it.
        ts.needTransform = true;
      }
    };
    Transform.prototype._destroy = function (err, cb) {
      Duplex.prototype._destroy.call(this, err, function (err2) {
        cb(err2);
      });
    };
    function done(stream, er, data) {
      if (er) return stream.emit('error', er);
      if (data != null)
        // single equals check for both `null` and `undefined`
        stream.push(data);
    
      // TODO(BridgeAR): Write a test for these two error cases
      // if there's nothing in the write buffer, then that means
      // that nothing more will ever be provided
      if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0();
      if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING();
      return stream.push(null);
    }
    },{"../errors":66,"./_stream_duplex":67,"inherits":182}],71:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // A bit simpler than readable streams.
    // Implement an async ._write(chunk, encoding, cb), and it'll handle all
    // the drain event emission and buffering.
    
    'use strict';
    
    module.exports = Writable;
    
    /* <replacement> */
    function WriteReq(chunk, encoding, cb) {
      this.chunk = chunk;
      this.encoding = encoding;
      this.callback = cb;
      this.next = null;
    }
    
    // It seems a linked list but it is not
    // there will be only 2 of these for each stream
    function CorkedRequest(state) {
      var _this = this;
      this.next = null;
      this.entry = null;
      this.finish = function () {
        onCorkedFinish(_this, state);
      };
    }
    /* </replacement> */
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Writable.WritableState = WritableState;
    
    /*<replacement>*/
    var internalUtil = {
      deprecate: require('util-deprecate')
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
      ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
      ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
      ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
      ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
      ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    require('inherits')(Writable, Stream);
    function nop() {}
    function WritableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream,
      // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag to indicate whether or not this stream
      // contains buffers or objects.
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
    
      // the point at which write() starts returning false
      // Note: 0 is a valid value, means that we always return false if
      // the entire buffer is not flushed immediately on write()
      this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex);
    
      // if _final has been called
      this.finalCalled = false;
    
      // drain event flag.
      this.needDrain = false;
      // at the start of calling end()
      this.ending = false;
      // when end() has been called, and returned
      this.ended = false;
      // when 'finish' is emitted
      this.finished = false;
    
      // has it been destroyed
      this.destroyed = false;
    
      // should we decode strings into buffers before passing to _write?
      // this is here so that some node-core streams can optimize string
      // handling at a lower level.
      var noDecode = options.decodeStrings === false;
      this.decodeStrings = !noDecode;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // not an actual buffer we keep track of, but a measurement
      // of how much we're waiting to get pushed to some underlying
      // socket or file.
      this.length = 0;
    
      // a flag to see when we're in the middle of a write.
      this.writing = false;
    
      // when true all writes will be buffered until .uncork() call
      this.corked = 0;
    
      // a flag to be able to tell if the onwrite cb is called immediately,
      // or on a later tick.  We set this to true at first, because any
      // actions that shouldn't happen until "later" should generally also
      // not happen before the first write call.
      this.sync = true;
    
      // a flag to know if we're processing previously buffered items, which
      // may call the _write() callback in the same tick, so that we don't
      // end up in an overlapped onwrite situation.
      this.bufferProcessing = false;
    
      // the callback that's passed to _write(chunk,cb)
      this.onwrite = function (er) {
        onwrite(stream, er);
      };
    
      // the callback that the user supplies to write(chunk,encoding,cb)
      this.writecb = null;
    
      // the amount that is being written when _write is called.
      this.writelen = 0;
      this.bufferedRequest = null;
      this.lastBufferedRequest = null;
    
      // number of pending user-supplied write callbacks
      // this must be 0 before 'finish' can be emitted
      this.pendingcb = 0;
    
      // emit prefinish if the only thing we're waiting for is _write cbs
      // This is relevant for synchronous Transform streams
      this.prefinished = false;
    
      // True if the error was already emitted and should not be thrown again
      this.errorEmitted = false;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'finish' (and potentially 'end')
      this.autoDestroy = !!options.autoDestroy;
    
      // count buffered requests
      this.bufferedRequestCount = 0;
    
      // allocate the first CorkedRequest, there is always
      // one allocated and free to use, and we maintain at most two
      this.corkedRequestsFree = new CorkedRequest(this);
    }
    WritableState.prototype.getBuffer = function getBuffer() {
      var current = this.bufferedRequest;
      var out = [];
      while (current) {
        out.push(current);
        current = current.next;
      }
      return out;
    };
    (function () {
      try {
        Object.defineProperty(WritableState.prototype, 'buffer', {
          get: internalUtil.deprecate(function writableStateBufferGetter() {
            return this.getBuffer();
          }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
        });
      } catch (_) {}
    })();
    
    // Test _writableState for inheritance to account for Duplex streams,
    // whose prototype chain only points to Readable.
    var realHasInstance;
    if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
      realHasInstance = Function.prototype[Symbol.hasInstance];
      Object.defineProperty(Writable, Symbol.hasInstance, {
        value: function value(object) {
          if (realHasInstance.call(this, object)) return true;
          if (this !== Writable) return false;
          return object && object._writableState instanceof WritableState;
        }
      });
    } else {
      realHasInstance = function realHasInstance(object) {
        return object instanceof this;
      };
    }
    function Writable(options) {
      Duplex = Duplex || require('./_stream_duplex');
    
      // Writable ctor is applied to Duplexes, too.
      // `realHasInstance` is necessary because using plain `instanceof`
      // would return false, as no `_writableState` property is attached.
    
      // Trying to use the custom `instanceof` for Writable here will also break the
      // Node.js LazyTransform implementation, which has a non-trivial getter for
      // `_writableState` that would lead to infinite recursion.
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the WritableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
      this._writableState = new WritableState(options, this, isDuplex);
    
      // legacy.
      this.writable = true;
      if (options) {
        if (typeof options.write === 'function') this._write = options.write;
        if (typeof options.writev === 'function') this._writev = options.writev;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
        if (typeof options.final === 'function') this._final = options.final;
      }
      Stream.call(this);
    }
    
    // Otherwise people can pipe Writable streams, which is just wrong.
    Writable.prototype.pipe = function () {
      errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
    };
    function writeAfterEnd(stream, cb) {
      var er = new ERR_STREAM_WRITE_AFTER_END();
      // TODO: defer error events consistently everywhere, not just the cb
      errorOrDestroy(stream, er);
      process.nextTick(cb, er);
    }
    
    // Checks that a user-supplied chunk is valid, especially for the particular
    // mode the stream is in. Currently this means that `null` is never accepted
    // and undefined/non-string values are only allowed in object mode.
    function validChunk(stream, state, chunk, cb) {
      var er;
      if (chunk === null) {
        er = new ERR_STREAM_NULL_VALUES();
      } else if (typeof chunk !== 'string' && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
      }
      if (er) {
        errorOrDestroy(stream, er);
        process.nextTick(cb, er);
        return false;
      }
      return true;
    }
    Writable.prototype.write = function (chunk, encoding, cb) {
      var state = this._writableState;
      var ret = false;
      var isBuf = !state.objectMode && _isUint8Array(chunk);
      if (isBuf && !Buffer.isBuffer(chunk)) {
        chunk = _uint8ArrayToBuffer(chunk);
      }
      if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
      if (typeof cb !== 'function') cb = nop;
      if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
        state.pendingcb++;
        ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
      }
      return ret;
    };
    Writable.prototype.cork = function () {
      this._writableState.corked++;
    };
    Writable.prototype.uncork = function () {
      var state = this._writableState;
      if (state.corked) {
        state.corked--;
        if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
      }
    };
    Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
      // node::ParseEncoding() requires lower case.
      if (typeof encoding === 'string') encoding = encoding.toLowerCase();
      if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
      this._writableState.defaultEncoding = encoding;
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    function decodeChunk(state, chunk, encoding) {
      if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
        chunk = Buffer.from(chunk, encoding);
      }
      return chunk;
    }
    Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    
    // if we're already writing something, then just put this
    // in the queue, and wait our turn.  Otherwise, call _write
    // If we return false, then we need a drain event, so set that flag.
    function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
      if (!isBuf) {
        var newChunk = decodeChunk(state, chunk, encoding);
        if (chunk !== newChunk) {
          isBuf = true;
          encoding = 'buffer';
          chunk = newChunk;
        }
      }
      var len = state.objectMode ? 1 : chunk.length;
      state.length += len;
      var ret = state.length < state.highWaterMark;
      // we must ensure that previous needDrain will not be reset to false.
      if (!ret) state.needDrain = true;
      if (state.writing || state.corked) {
        var last = state.lastBufferedRequest;
        state.lastBufferedRequest = {
          chunk: chunk,
          encoding: encoding,
          isBuf: isBuf,
          callback: cb,
          next: null
        };
        if (last) {
          last.next = state.lastBufferedRequest;
        } else {
          state.bufferedRequest = state.lastBufferedRequest;
        }
        state.bufferedRequestCount += 1;
      } else {
        doWrite(stream, state, false, len, chunk, encoding, cb);
      }
      return ret;
    }
    function doWrite(stream, state, writev, len, chunk, encoding, cb) {
      state.writelen = len;
      state.writecb = cb;
      state.writing = true;
      state.sync = true;
      if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
      state.sync = false;
    }
    function onwriteError(stream, state, sync, er, cb) {
      --state.pendingcb;
      if (sync) {
        // defer the callback if we are being called synchronously
        // to avoid piling up things on the stack
        process.nextTick(cb, er);
        // this can emit finish, and it will always happen
        // after error
        process.nextTick(finishMaybe, stream, state);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
      } else {
        // the caller expect this to happen before if
        // it is async
        cb(er);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
        // this can emit finish, but finish must
        // always follow error
        finishMaybe(stream, state);
      }
    }
    function onwriteStateUpdate(state) {
      state.writing = false;
      state.writecb = null;
      state.length -= state.writelen;
      state.writelen = 0;
    }
    function onwrite(stream, er) {
      var state = stream._writableState;
      var sync = state.sync;
      var cb = state.writecb;
      if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
      onwriteStateUpdate(state);
      if (er) onwriteError(stream, state, sync, er, cb);else {
        // Check if we're actually ready to finish, but don't emit yet
        var finished = needFinish(state) || stream.destroyed;
        if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
          clearBuffer(stream, state);
        }
        if (sync) {
          process.nextTick(afterWrite, stream, state, finished, cb);
        } else {
          afterWrite(stream, state, finished, cb);
        }
      }
    }
    function afterWrite(stream, state, finished, cb) {
      if (!finished) onwriteDrain(stream, state);
      state.pendingcb--;
      cb();
      finishMaybe(stream, state);
    }
    
    // Must force callback to be called on nextTick, so that we don't
    // emit 'drain' before the write() consumer gets the 'false' return
    // value, and has a chance to attach a 'drain' listener.
    function onwriteDrain(stream, state) {
      if (state.length === 0 && state.needDrain) {
        state.needDrain = false;
        stream.emit('drain');
      }
    }
    
    // if there's something in the buffer waiting, then process it
    function clearBuffer(stream, state) {
      state.bufferProcessing = true;
      var entry = state.bufferedRequest;
      if (stream._writev && entry && entry.next) {
        // Fast case, write everything using _writev()
        var l = state.bufferedRequestCount;
        var buffer = new Array(l);
        var holder = state.corkedRequestsFree;
        holder.entry = entry;
        var count = 0;
        var allBuffers = true;
        while (entry) {
          buffer[count] = entry;
          if (!entry.isBuf) allBuffers = false;
          entry = entry.next;
          count += 1;
        }
        buffer.allBuffers = allBuffers;
        doWrite(stream, state, true, state.length, buffer, '', holder.finish);
    
        // doWrite is almost always async, defer these to save a bit of time
        // as the hot path ends with doWrite
        state.pendingcb++;
        state.lastBufferedRequest = null;
        if (holder.next) {
          state.corkedRequestsFree = holder.next;
          holder.next = null;
        } else {
          state.corkedRequestsFree = new CorkedRequest(state);
        }
        state.bufferedRequestCount = 0;
      } else {
        // Slow case, write chunks one-by-one
        while (entry) {
          var chunk = entry.chunk;
          var encoding = entry.encoding;
          var cb = entry.callback;
          var len = state.objectMode ? 1 : chunk.length;
          doWrite(stream, state, false, len, chunk, encoding, cb);
          entry = entry.next;
          state.bufferedRequestCount--;
          // if we didn't call the onwrite immediately, then
          // it means that we need to wait until it does.
          // also, that means that the chunk and cb are currently
          // being processed, so move the buffer counter past them.
          if (state.writing) {
            break;
          }
        }
        if (entry === null) state.lastBufferedRequest = null;
      }
      state.bufferedRequest = entry;
      state.bufferProcessing = false;
    }
    Writable.prototype._write = function (chunk, encoding, cb) {
      cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
    };
    Writable.prototype._writev = null;
    Writable.prototype.end = function (chunk, encoding, cb) {
      var state = this._writableState;
      if (typeof chunk === 'function') {
        cb = chunk;
        chunk = null;
        encoding = null;
      } else if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
    
      // .end() fully uncorks
      if (state.corked) {
        state.corked = 1;
        this.uncork();
      }
    
      // ignore unnecessary end() calls.
      if (!state.ending) endWritable(this, state, cb);
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    function needFinish(state) {
      return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
    }
    function callFinal(stream, state) {
      stream._final(function (err) {
        state.pendingcb--;
        if (err) {
          errorOrDestroy(stream, err);
        }
        state.prefinished = true;
        stream.emit('prefinish');
        finishMaybe(stream, state);
      });
    }
    function prefinish(stream, state) {
      if (!state.prefinished && !state.finalCalled) {
        if (typeof stream._final === 'function' && !state.destroyed) {
          state.pendingcb++;
          state.finalCalled = true;
          process.nextTick(callFinal, stream, state);
        } else {
          state.prefinished = true;
          stream.emit('prefinish');
        }
      }
    }
    function finishMaybe(stream, state) {
      var need = needFinish(state);
      if (need) {
        prefinish(stream, state);
        if (state.pendingcb === 0) {
          state.finished = true;
          stream.emit('finish');
          if (state.autoDestroy) {
            // In case of duplex streams we need a way to detect
            // if the readable side is ready for autoDestroy as well
            var rState = stream._readableState;
            if (!rState || rState.autoDestroy && rState.endEmitted) {
              stream.destroy();
            }
          }
        }
      }
      return need;
    }
    function endWritable(stream, state, cb) {
      state.ending = true;
      finishMaybe(stream, state);
      if (cb) {
        if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
      }
      state.ended = true;
      stream.writable = false;
    }
    function onCorkedFinish(corkReq, state, err) {
      var entry = corkReq.entry;
      corkReq.entry = null;
      while (entry) {
        var cb = entry.callback;
        state.pendingcb--;
        cb(err);
        entry = entry.next;
      }
    
      // reuse the free corkReq.
      state.corkedRequestsFree.next = corkReq;
    }
    Object.defineProperty(Writable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._writableState === undefined) {
          return false;
        }
        return this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._writableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._writableState.destroyed = value;
      }
    });
    Writable.prototype.destroy = destroyImpl.destroy;
    Writable.prototype._undestroy = destroyImpl.undestroy;
    Writable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":66,"./_stream_duplex":67,"./internal/streams/destroy":74,"./internal/streams/state":78,"./internal/streams/stream":79,"_process":321,"buffer":84,"inherits":182,"util-deprecate":369}],72:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    var _Object$setPrototypeO;
    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
    function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
    function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
    var finished = require('./end-of-stream');
    var kLastResolve = Symbol('lastResolve');
    var kLastReject = Symbol('lastReject');
    var kError = Symbol('error');
    var kEnded = Symbol('ended');
    var kLastPromise = Symbol('lastPromise');
    var kHandlePromise = Symbol('handlePromise');
    var kStream = Symbol('stream');
    function createIterResult(value, done) {
      return {
        value: value,
        done: done
      };
    }
    function readAndResolve(iter) {
      var resolve = iter[kLastResolve];
      if (resolve !== null) {
        var data = iter[kStream].read();
        // we defer if data is null
        // we can be expecting either 'end' or
        // 'error'
        if (data !== null) {
          iter[kLastPromise] = null;
          iter[kLastResolve] = null;
          iter[kLastReject] = null;
          resolve(createIterResult(data, false));
        }
      }
    }
    function onReadable(iter) {
      // we wait for the next tick, because it might
      // emit an error with process.nextTick
      process.nextTick(readAndResolve, iter);
    }
    function wrapForNext(lastPromise, iter) {
      return function (resolve, reject) {
        lastPromise.then(function () {
          if (iter[kEnded]) {
            resolve(createIterResult(undefined, true));
            return;
          }
          iter[kHandlePromise](resolve, reject);
        }, reject);
      };
    }
    var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
    var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
      get stream() {
        return this[kStream];
      },
      next: function next() {
        var _this = this;
        // if we have detected an error in the meanwhile
        // reject straight away
        var error = this[kError];
        if (error !== null) {
          return Promise.reject(error);
        }
        if (this[kEnded]) {
          return Promise.resolve(createIterResult(undefined, true));
        }
        if (this[kStream].destroyed) {
          // We need to defer via nextTick because if .destroy(err) is
          // called, the error will be emitted via nextTick, and
          // we cannot guarantee that there is no error lingering around
          // waiting to be emitted.
          return new Promise(function (resolve, reject) {
            process.nextTick(function () {
              if (_this[kError]) {
                reject(_this[kError]);
              } else {
                resolve(createIterResult(undefined, true));
              }
            });
          });
        }
    
        // if we have multiple next() calls
        // we will wait for the previous Promise to finish
        // this logic is optimized to support for await loops,
        // where next() is only called once at a time
        var lastPromise = this[kLastPromise];
        var promise;
        if (lastPromise) {
          promise = new Promise(wrapForNext(lastPromise, this));
        } else {
          // fast path needed to support multiple this.push()
          // without triggering the next() queue
          var data = this[kStream].read();
          if (data !== null) {
            return Promise.resolve(createIterResult(data, false));
          }
          promise = new Promise(this[kHandlePromise]);
        }
        this[kLastPromise] = promise;
        return promise;
      }
    }, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
      return this;
    }), _defineProperty(_Object$setPrototypeO, "return", function _return() {
      var _this2 = this;
      // destroy(err, cb) is a private API
      // we can guarantee we have that here, because we control the
      // Readable class this is attached to
      return new Promise(function (resolve, reject) {
        _this2[kStream].destroy(null, function (err) {
          if (err) {
            reject(err);
            return;
          }
          resolve(createIterResult(undefined, true));
        });
      });
    }), _Object$setPrototypeO), AsyncIteratorPrototype);
    var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
      var _Object$create;
      var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
        value: stream,
        writable: true
      }), _defineProperty(_Object$create, kLastResolve, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kLastReject, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kError, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kEnded, {
        value: stream._readableState.endEmitted,
        writable: true
      }), _defineProperty(_Object$create, kHandlePromise, {
        value: function value(resolve, reject) {
          var data = iterator[kStream].read();
          if (data) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            resolve(createIterResult(data, false));
          } else {
            iterator[kLastResolve] = resolve;
            iterator[kLastReject] = reject;
          }
        },
        writable: true
      }), _Object$create));
      iterator[kLastPromise] = null;
      finished(stream, function (err) {
        if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
          var reject = iterator[kLastReject];
          // reject if we are waiting for data in the Promise
          // returned by next() and store the error
          if (reject !== null) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            reject(err);
          }
          iterator[kError] = err;
          return;
        }
        var resolve = iterator[kLastResolve];
        if (resolve !== null) {
          iterator[kLastPromise] = null;
          iterator[kLastResolve] = null;
          iterator[kLastReject] = null;
          resolve(createIterResult(undefined, true));
        }
        iterator[kEnded] = true;
      });
      stream.on('readable', onReadable.bind(null, iterator));
      return iterator;
    };
    module.exports = createReadableStreamAsyncIterator;
    }).call(this)}).call(this,require('_process'))
    
    },{"./end-of-stream":75,"_process":321}],73:[function(require,module,exports){
    'use strict';
    
    function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
    function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
    function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
    function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
    function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
    var _require = require('buffer'),
      Buffer = _require.Buffer;
    var _require2 = require('util'),
      inspect = _require2.inspect;
    var custom = inspect && inspect.custom || 'inspect';
    function copyBuffer(src, target, offset) {
      Buffer.prototype.copy.call(src, target, offset);
    }
    module.exports = /*#__PURE__*/function () {
      function BufferList() {
        _classCallCheck(this, BufferList);
        this.head = null;
        this.tail = null;
        this.length = 0;
      }
      _createClass(BufferList, [{
        key: "push",
        value: function push(v) {
          var entry = {
            data: v,
            next: null
          };
          if (this.length > 0) this.tail.next = entry;else this.head = entry;
          this.tail = entry;
          ++this.length;
        }
      }, {
        key: "unshift",
        value: function unshift(v) {
          var entry = {
            data: v,
            next: this.head
          };
          if (this.length === 0) this.tail = entry;
          this.head = entry;
          ++this.length;
        }
      }, {
        key: "shift",
        value: function shift() {
          if (this.length === 0) return;
          var ret = this.head.data;
          if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
          --this.length;
          return ret;
        }
      }, {
        key: "clear",
        value: function clear() {
          this.head = this.tail = null;
          this.length = 0;
        }
      }, {
        key: "join",
        value: function join(s) {
          if (this.length === 0) return '';
          var p = this.head;
          var ret = '' + p.data;
          while (p = p.next) ret += s + p.data;
          return ret;
        }
      }, {
        key: "concat",
        value: function concat(n) {
          if (this.length === 0) return Buffer.alloc(0);
          var ret = Buffer.allocUnsafe(n >>> 0);
          var p = this.head;
          var i = 0;
          while (p) {
            copyBuffer(p.data, ret, i);
            i += p.data.length;
            p = p.next;
          }
          return ret;
        }
    
        // Consumes a specified amount of bytes or characters from the buffered data.
      }, {
        key: "consume",
        value: function consume(n, hasStrings) {
          var ret;
          if (n < this.head.data.length) {
            // `slice` is the same for buffers and strings.
            ret = this.head.data.slice(0, n);
            this.head.data = this.head.data.slice(n);
          } else if (n === this.head.data.length) {
            // First chunk is a perfect match.
            ret = this.shift();
          } else {
            // Result spans more than one buffer.
            ret = hasStrings ? this._getString(n) : this._getBuffer(n);
          }
          return ret;
        }
      }, {
        key: "first",
        value: function first() {
          return this.head.data;
        }
    
        // Consumes a specified amount of characters from the buffered data.
      }, {
        key: "_getString",
        value: function _getString(n) {
          var p = this.head;
          var c = 1;
          var ret = p.data;
          n -= ret.length;
          while (p = p.next) {
            var str = p.data;
            var nb = n > str.length ? str.length : n;
            if (nb === str.length) ret += str;else ret += str.slice(0, n);
            n -= nb;
            if (n === 0) {
              if (nb === str.length) {
                ++c;
                if (p.next) this.head = p.next;else this.head = this.tail = null;
              } else {
                this.head = p;
                p.data = str.slice(nb);
              }
              break;
            }
            ++c;
          }
          this.length -= c;
          return ret;
        }
    
        // Consumes a specified amount of bytes from the buffered data.
      }, {
        key: "_getBuffer",
        value: function _getBuffer(n) {
          var ret = Buffer.allocUnsafe(n);
          var p = this.head;
          var c = 1;
          p.data.copy(ret);
          n -= p.data.length;
          while (p = p.next) {
            var buf = p.data;
            var nb = n > buf.length ? buf.length : n;
            buf.copy(ret, ret.length - n, 0, nb);
            n -= nb;
            if (n === 0) {
              if (nb === buf.length) {
                ++c;
                if (p.next) this.head = p.next;else this.head = this.tail = null;
              } else {
                this.head = p;
                p.data = buf.slice(nb);
              }
              break;
            }
            ++c;
          }
          this.length -= c;
          return ret;
        }
    
        // Make sure the linked list only shows the minimal necessary information.
      }, {
        key: custom,
        value: function value(_, options) {
          return inspect(this, _objectSpread(_objectSpread({}, options), {}, {
            // Only inspect one level.
            depth: 0,
            // It should not recurse.
            customInspect: false
          }));
        }
      }]);
      return BufferList;
    }();
    },{"buffer":84,"util":36}],74:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    // undocumented cb() API, needed for core, not for public API
    function destroy(err, cb) {
      var _this = this;
      var readableDestroyed = this._readableState && this._readableState.destroyed;
      var writableDestroyed = this._writableState && this._writableState.destroyed;
      if (readableDestroyed || writableDestroyed) {
        if (cb) {
          cb(err);
        } else if (err) {
          if (!this._writableState) {
            process.nextTick(emitErrorNT, this, err);
          } else if (!this._writableState.errorEmitted) {
            this._writableState.errorEmitted = true;
            process.nextTick(emitErrorNT, this, err);
          }
        }
        return this;
      }
    
      // we set destroyed to true before firing error callbacks in order
      // to make it re-entrance safe in case destroy() is called within callbacks
    
      if (this._readableState) {
        this._readableState.destroyed = true;
      }
    
      // if this is a duplex stream mark the writable part as destroyed as well
      if (this._writableState) {
        this._writableState.destroyed = true;
      }
      this._destroy(err || null, function (err) {
        if (!cb && err) {
          if (!_this._writableState) {
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else if (!_this._writableState.errorEmitted) {
            _this._writableState.errorEmitted = true;
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else {
            process.nextTick(emitCloseNT, _this);
          }
        } else if (cb) {
          process.nextTick(emitCloseNT, _this);
          cb(err);
        } else {
          process.nextTick(emitCloseNT, _this);
        }
      });
      return this;
    }
    function emitErrorAndCloseNT(self, err) {
      emitErrorNT(self, err);
      emitCloseNT(self);
    }
    function emitCloseNT(self) {
      if (self._writableState && !self._writableState.emitClose) return;
      if (self._readableState && !self._readableState.emitClose) return;
      self.emit('close');
    }
    function undestroy() {
      if (this._readableState) {
        this._readableState.destroyed = false;
        this._readableState.reading = false;
        this._readableState.ended = false;
        this._readableState.endEmitted = false;
      }
      if (this._writableState) {
        this._writableState.destroyed = false;
        this._writableState.ended = false;
        this._writableState.ending = false;
        this._writableState.finalCalled = false;
        this._writableState.prefinished = false;
        this._writableState.finished = false;
        this._writableState.errorEmitted = false;
      }
    }
    function emitErrorNT(self, err) {
      self.emit('error', err);
    }
    function errorOrDestroy(stream, err) {
      // We have tests that rely on errors being emitted
      // in the same tick, so changing this is semver major.
      // For now when you opt-in to autoDestroy we allow
      // the error to be emitted nextTick. In a future
      // semver major update we should change the default to this.
    
      var rState = stream._readableState;
      var wState = stream._writableState;
      if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
    }
    module.exports = {
      destroy: destroy,
      undestroy: undestroy,
      errorOrDestroy: errorOrDestroy
    };
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321}],75:[function(require,module,exports){
    // Ported from https://github.com/mafintosh/end-of-stream with
    // permission from the author, Mathias Buus (@mafintosh).
    
    'use strict';
    
    var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE;
    function once(callback) {
      var called = false;
      return function () {
        if (called) return;
        called = true;
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }
        callback.apply(this, args);
      };
    }
    function noop() {}
    function isRequest(stream) {
      return stream.setHeader && typeof stream.abort === 'function';
    }
    function eos(stream, opts, callback) {
      if (typeof opts === 'function') return eos(stream, null, opts);
      if (!opts) opts = {};
      callback = once(callback || noop);
      var readable = opts.readable || opts.readable !== false && stream.readable;
      var writable = opts.writable || opts.writable !== false && stream.writable;
      var onlegacyfinish = function onlegacyfinish() {
        if (!stream.writable) onfinish();
      };
      var writableEnded = stream._writableState && stream._writableState.finished;
      var onfinish = function onfinish() {
        writable = false;
        writableEnded = true;
        if (!readable) callback.call(stream);
      };
      var readableEnded = stream._readableState && stream._readableState.endEmitted;
      var onend = function onend() {
        readable = false;
        readableEnded = true;
        if (!writable) callback.call(stream);
      };
      var onerror = function onerror(err) {
        callback.call(stream, err);
      };
      var onclose = function onclose() {
        var err;
        if (readable && !readableEnded) {
          if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
          return callback.call(stream, err);
        }
        if (writable && !writableEnded) {
          if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE();
          return callback.call(stream, err);
        }
      };
      var onrequest = function onrequest() {
        stream.req.on('finish', onfinish);
      };
      if (isRequest(stream)) {
        stream.on('complete', onfinish);
        stream.on('abort', onclose);
        if (stream.req) onrequest();else stream.on('request', onrequest);
      } else if (writable && !stream._writableState) {
        // legacy streams
        stream.on('end', onlegacyfinish);
        stream.on('close', onlegacyfinish);
      }
      stream.on('end', onend);
      stream.on('finish', onfinish);
      if (opts.error !== false) stream.on('error', onerror);
      stream.on('close', onclose);
      return function () {
        stream.removeListener('complete', onfinish);
        stream.removeListener('abort', onclose);
        stream.removeListener('request', onrequest);
        if (stream.req) stream.req.removeListener('finish', onfinish);
        stream.removeListener('end', onlegacyfinish);
        stream.removeListener('close', onlegacyfinish);
        stream.removeListener('finish', onfinish);
        stream.removeListener('end', onend);
        stream.removeListener('error', onerror);
        stream.removeListener('close', onclose);
      };
    }
    module.exports = eos;
    },{"../../../errors":66}],76:[function(require,module,exports){
    module.exports = function () {
      throw new Error('Readable.from is not available in the browser')
    };
    
    },{}],77:[function(require,module,exports){
    // Ported from https://github.com/mafintosh/pump with
    // permission from the author, Mathias Buus (@mafintosh).
    
    'use strict';
    
    var eos;
    function once(callback) {
      var called = false;
      return function () {
        if (called) return;
        called = true;
        callback.apply(void 0, arguments);
      };
    }
    var _require$codes = require('../../../errors').codes,
      ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS,
      ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED;
    function noop(err) {
      // Rethrow the error if it exists to avoid swallowing it
      if (err) throw err;
    }
    function isRequest(stream) {
      return stream.setHeader && typeof stream.abort === 'function';
    }
    function destroyer(stream, reading, writing, callback) {
      callback = once(callback);
      var closed = false;
      stream.on('close', function () {
        closed = true;
      });
      if (eos === undefined) eos = require('./end-of-stream');
      eos(stream, {
        readable: reading,
        writable: writing
      }, function (err) {
        if (err) return callback(err);
        closed = true;
        callback();
      });
      var destroyed = false;
      return function (err) {
        if (closed) return;
        if (destroyed) return;
        destroyed = true;
    
        // request.destroy just do .end - .abort is what we want
        if (isRequest(stream)) return stream.abort();
        if (typeof stream.destroy === 'function') return stream.destroy();
        callback(err || new ERR_STREAM_DESTROYED('pipe'));
      };
    }
    function call(fn) {
      fn();
    }
    function pipe(from, to) {
      return from.pipe(to);
    }
    function popCallback(streams) {
      if (!streams.length) return noop;
      if (typeof streams[streams.length - 1] !== 'function') return noop;
      return streams.pop();
    }
    function pipeline() {
      for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) {
        streams[_key] = arguments[_key];
      }
      var callback = popCallback(streams);
      if (Array.isArray(streams[0])) streams = streams[0];
      if (streams.length < 2) {
        throw new ERR_MISSING_ARGS('streams');
      }
      var error;
      var destroys = streams.map(function (stream, i) {
        var reading = i < streams.length - 1;
        var writing = i > 0;
        return destroyer(stream, reading, writing, function (err) {
          if (!error) error = err;
          if (err) destroys.forEach(call);
          if (reading) return;
          destroys.forEach(call);
          callback(error);
        });
      });
      return streams.reduce(pipe);
    }
    module.exports = pipeline;
    },{"../../../errors":66,"./end-of-stream":75}],78:[function(require,module,exports){
    'use strict';
    
    var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE;
    function highWaterMarkFrom(options, isDuplex, duplexKey) {
      return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null;
    }
    function getHighWaterMark(state, options, duplexKey, isDuplex) {
      var hwm = highWaterMarkFrom(options, isDuplex, duplexKey);
      if (hwm != null) {
        if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) {
          var name = isDuplex ? duplexKey : 'highWaterMark';
          throw new ERR_INVALID_OPT_VALUE(name, hwm);
        }
        return Math.floor(hwm);
      }
    
      // Default value
      return state.objectMode ? 16 : 16 * 1024;
    }
    module.exports = {
      getHighWaterMark: getHighWaterMark
    };
    },{"../../../errors":66}],79:[function(require,module,exports){
    module.exports = require('events').EventEmitter;
    
    },{"events":134}],80:[function(require,module,exports){
    exports = module.exports = require('./lib/_stream_readable.js');
    exports.Stream = exports;
    exports.Readable = exports;
    exports.Writable = require('./lib/_stream_writable.js');
    exports.Duplex = require('./lib/_stream_duplex.js');
    exports.Transform = require('./lib/_stream_transform.js');
    exports.PassThrough = require('./lib/_stream_passthrough.js');
    exports.finished = require('./lib/internal/streams/end-of-stream.js');
    exports.pipeline = require('./lib/internal/streams/pipeline.js');
    
    },{"./lib/_stream_duplex.js":67,"./lib/_stream_passthrough.js":68,"./lib/_stream_readable.js":69,"./lib/_stream_transform.js":70,"./lib/_stream_writable.js":71,"./lib/internal/streams/end-of-stream.js":75,"./lib/internal/streams/pipeline.js":77}],81:[function(require,module,exports){
    (function (process,Buffer){(function (){
    'use strict';
    /* eslint camelcase: "off" */
    
    var assert = require('assert');
    
    var Zstream = require('pako/lib/zlib/zstream');
    var zlib_deflate = require('pako/lib/zlib/deflate.js');
    var zlib_inflate = require('pako/lib/zlib/inflate.js');
    var constants = require('pako/lib/zlib/constants');
    
    for (var key in constants) {
      exports[key] = constants[key];
    }
    
    // zlib modes
    exports.NONE = 0;
    exports.DEFLATE = 1;
    exports.INFLATE = 2;
    exports.GZIP = 3;
    exports.GUNZIP = 4;
    exports.DEFLATERAW = 5;
    exports.INFLATERAW = 6;
    exports.UNZIP = 7;
    
    var GZIP_HEADER_ID1 = 0x1f;
    var GZIP_HEADER_ID2 = 0x8b;
    
    /**
     * Emulate Node's zlib C++ layer for use by the JS layer in index.js
     */
    function Zlib(mode) {
      if (typeof mode !== 'number' || mode < exports.DEFLATE || mode > exports.UNZIP) {
        throw new TypeError('Bad argument');
      }
    
      this.dictionary = null;
      this.err = 0;
      this.flush = 0;
      this.init_done = false;
      this.level = 0;
      this.memLevel = 0;
      this.mode = mode;
      this.strategy = 0;
      this.windowBits = 0;
      this.write_in_progress = false;
      this.pending_close = false;
      this.gzip_id_bytes_read = 0;
    }
    
    Zlib.prototype.close = function () {
      if (this.write_in_progress) {
        this.pending_close = true;
        return;
      }
    
      this.pending_close = false;
    
      assert(this.init_done, 'close before init');
      assert(this.mode <= exports.UNZIP);
    
      if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) {
        zlib_deflate.deflateEnd(this.strm);
      } else if (this.mode === exports.INFLATE || this.mode === exports.GUNZIP || this.mode === exports.INFLATERAW || this.mode === exports.UNZIP) {
        zlib_inflate.inflateEnd(this.strm);
      }
    
      this.mode = exports.NONE;
    
      this.dictionary = null;
    };
    
    Zlib.prototype.write = function (flush, input, in_off, in_len, out, out_off, out_len) {
      return this._write(true, flush, input, in_off, in_len, out, out_off, out_len);
    };
    
    Zlib.prototype.writeSync = function (flush, input, in_off, in_len, out, out_off, out_len) {
      return this._write(false, flush, input, in_off, in_len, out, out_off, out_len);
    };
    
    Zlib.prototype._write = function (async, flush, input, in_off, in_len, out, out_off, out_len) {
      assert.equal(arguments.length, 8);
    
      assert(this.init_done, 'write before init');
      assert(this.mode !== exports.NONE, 'already finalized');
      assert.equal(false, this.write_in_progress, 'write already in progress');
      assert.equal(false, this.pending_close, 'close is pending');
    
      this.write_in_progress = true;
    
      assert.equal(false, flush === undefined, 'must provide flush value');
    
      this.write_in_progress = true;
    
      if (flush !== exports.Z_NO_FLUSH && flush !== exports.Z_PARTIAL_FLUSH && flush !== exports.Z_SYNC_FLUSH && flush !== exports.Z_FULL_FLUSH && flush !== exports.Z_FINISH && flush !== exports.Z_BLOCK) {
        throw new Error('Invalid flush value');
      }
    
      if (input == null) {
        input = Buffer.alloc(0);
        in_len = 0;
        in_off = 0;
      }
    
      this.strm.avail_in = in_len;
      this.strm.input = input;
      this.strm.next_in = in_off;
      this.strm.avail_out = out_len;
      this.strm.output = out;
      this.strm.next_out = out_off;
      this.flush = flush;
    
      if (!async) {
        // sync version
        this._process();
    
        if (this._checkError()) {
          return this._afterSync();
        }
        return;
      }
    
      // async version
      var self = this;
      process.nextTick(function () {
        self._process();
        self._after();
      });
    
      return this;
    };
    
    Zlib.prototype._afterSync = function () {
      var avail_out = this.strm.avail_out;
      var avail_in = this.strm.avail_in;
    
      this.write_in_progress = false;
    
      return [avail_in, avail_out];
    };
    
    Zlib.prototype._process = function () {
      var next_expected_header_byte = null;
    
      // If the avail_out is left at 0, then it means that it ran out
      // of room.  If there was avail_out left over, then it means
      // that all of the input was consumed.
      switch (this.mode) {
        case exports.DEFLATE:
        case exports.GZIP:
        case exports.DEFLATERAW:
          this.err = zlib_deflate.deflate(this.strm, this.flush);
          break;
        case exports.UNZIP:
          if (this.strm.avail_in > 0) {
            next_expected_header_byte = this.strm.next_in;
          }
    
          switch (this.gzip_id_bytes_read) {
            case 0:
              if (next_expected_header_byte === null) {
                break;
              }
    
              if (this.strm.input[next_expected_header_byte] === GZIP_HEADER_ID1) {
                this.gzip_id_bytes_read = 1;
                next_expected_header_byte++;
    
                if (this.strm.avail_in === 1) {
                  // The only available byte was already read.
                  break;
                }
              } else {
                this.mode = exports.INFLATE;
                break;
              }
    
            // fallthrough
            case 1:
              if (next_expected_header_byte === null) {
                break;
              }
    
              if (this.strm.input[next_expected_header_byte] === GZIP_HEADER_ID2) {
                this.gzip_id_bytes_read = 2;
                this.mode = exports.GUNZIP;
              } else {
                // There is no actual difference between INFLATE and INFLATERAW
                // (after initialization).
                this.mode = exports.INFLATE;
              }
    
              break;
            default:
              throw new Error('invalid number of gzip magic number bytes read');
          }
    
        // fallthrough
        case exports.INFLATE:
        case exports.GUNZIP:
        case exports.INFLATERAW:
          this.err = zlib_inflate.inflate(this.strm, this.flush
    
          // If data was encoded with dictionary
          );if (this.err === exports.Z_NEED_DICT && this.dictionary) {
            // Load it
            this.err = zlib_inflate.inflateSetDictionary(this.strm, this.dictionary);
            if (this.err === exports.Z_OK) {
              // And try to decode again
              this.err = zlib_inflate.inflate(this.strm, this.flush);
            } else if (this.err === exports.Z_DATA_ERROR) {
              // Both inflateSetDictionary() and inflate() return Z_DATA_ERROR.
              // Make it possible for After() to tell a bad dictionary from bad
              // input.
              this.err = exports.Z_NEED_DICT;
            }
          }
          while (this.strm.avail_in > 0 && this.mode === exports.GUNZIP && this.err === exports.Z_STREAM_END && this.strm.next_in[0] !== 0x00) {
            // Bytes remain in input buffer. Perhaps this is another compressed
            // member in the same archive, or just trailing garbage.
            // Trailing zero bytes are okay, though, since they are frequently
            // used for padding.
    
            this.reset();
            this.err = zlib_inflate.inflate(this.strm, this.flush);
          }
          break;
        default:
          throw new Error('Unknown mode ' + this.mode);
      }
    };
    
    Zlib.prototype._checkError = function () {
      // Acceptable error states depend on the type of zlib stream.
      switch (this.err) {
        case exports.Z_OK:
        case exports.Z_BUF_ERROR:
          if (this.strm.avail_out !== 0 && this.flush === exports.Z_FINISH) {
            this._error('unexpected end of file');
            return false;
          }
          break;
        case exports.Z_STREAM_END:
          // normal statuses, not fatal
          break;
        case exports.Z_NEED_DICT:
          if (this.dictionary == null) {
            this._error('Missing dictionary');
          } else {
            this._error('Bad dictionary');
          }
          return false;
        default:
          // something else.
          this._error('Zlib error');
          return false;
      }
    
      return true;
    };
    
    Zlib.prototype._after = function () {
      if (!this._checkError()) {
        return;
      }
    
      var avail_out = this.strm.avail_out;
      var avail_in = this.strm.avail_in;
    
      this.write_in_progress = false;
    
      // call the write() cb
      this.callback(avail_in, avail_out);
    
      if (this.pending_close) {
        this.close();
      }
    };
    
    Zlib.prototype._error = function (message) {
      if (this.strm.msg) {
        message = this.strm.msg;
      }
      this.onerror(message, this.err
    
      // no hope of rescue.
      );this.write_in_progress = false;
      if (this.pending_close) {
        this.close();
      }
    };
    
    Zlib.prototype.init = function (windowBits, level, memLevel, strategy, dictionary) {
      assert(arguments.length === 4 || arguments.length === 5, 'init(windowBits, level, memLevel, strategy, [dictionary])');
    
      assert(windowBits >= 8 && windowBits <= 15, 'invalid windowBits');
      assert(level >= -1 && level <= 9, 'invalid compression level');
    
      assert(memLevel >= 1 && memLevel <= 9, 'invalid memlevel');
    
      assert(strategy === exports.Z_FILTERED || strategy === exports.Z_HUFFMAN_ONLY || strategy === exports.Z_RLE || strategy === exports.Z_FIXED || strategy === exports.Z_DEFAULT_STRATEGY, 'invalid strategy');
    
      this._init(level, windowBits, memLevel, strategy, dictionary);
      this._setDictionary();
    };
    
    Zlib.prototype.params = function () {
      throw new Error('deflateParams Not supported');
    };
    
    Zlib.prototype.reset = function () {
      this._reset();
      this._setDictionary();
    };
    
    Zlib.prototype._init = function (level, windowBits, memLevel, strategy, dictionary) {
      this.level = level;
      this.windowBits = windowBits;
      this.memLevel = memLevel;
      this.strategy = strategy;
    
      this.flush = exports.Z_NO_FLUSH;
    
      this.err = exports.Z_OK;
    
      if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) {
        this.windowBits += 16;
      }
    
      if (this.mode === exports.UNZIP) {
        this.windowBits += 32;
      }
    
      if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) {
        this.windowBits = -1 * this.windowBits;
      }
    
      this.strm = new Zstream();
    
      switch (this.mode) {
        case exports.DEFLATE:
        case exports.GZIP:
        case exports.DEFLATERAW:
          this.err = zlib_deflate.deflateInit2(this.strm, this.level, exports.Z_DEFLATED, this.windowBits, this.memLevel, this.strategy);
          break;
        case exports.INFLATE:
        case exports.GUNZIP:
        case exports.INFLATERAW:
        case exports.UNZIP:
          this.err = zlib_inflate.inflateInit2(this.strm, this.windowBits);
          break;
        default:
          throw new Error('Unknown mode ' + this.mode);
      }
    
      if (this.err !== exports.Z_OK) {
        this._error('Init error');
      }
    
      this.dictionary = dictionary;
    
      this.write_in_progress = false;
      this.init_done = true;
    };
    
    Zlib.prototype._setDictionary = function () {
      if (this.dictionary == null) {
        return;
      }
    
      this.err = exports.Z_OK;
    
      switch (this.mode) {
        case exports.DEFLATE:
        case exports.DEFLATERAW:
          this.err = zlib_deflate.deflateSetDictionary(this.strm, this.dictionary);
          break;
        default:
          break;
      }
    
      if (this.err !== exports.Z_OK) {
        this._error('Failed to set dictionary');
      }
    };
    
    Zlib.prototype._reset = function () {
      this.err = exports.Z_OK;
    
      switch (this.mode) {
        case exports.DEFLATE:
        case exports.DEFLATERAW:
        case exports.GZIP:
          this.err = zlib_deflate.deflateReset(this.strm);
          break;
        case exports.INFLATE:
        case exports.INFLATERAW:
        case exports.GUNZIP:
          this.err = zlib_inflate.inflateReset(this.strm);
          break;
        default:
          break;
      }
    
      if (this.err !== exports.Z_OK) {
        this._error('Failed to reset stream');
      }
    };
    
    exports.Zlib = Zlib;
    }).call(this)}).call(this,require('_process'),require("buffer").Buffer)
    
    },{"_process":321,"assert":24,"buffer":84,"pako/lib/zlib/constants":299,"pako/lib/zlib/deflate.js":301,"pako/lib/zlib/inflate.js":303,"pako/lib/zlib/zstream":307}],82:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    var Buffer = require('buffer').Buffer;
    var Transform = require('stream').Transform;
    var binding = require('./binding');
    var util = require('util');
    var assert = require('assert').ok;
    var kMaxLength = require('buffer').kMaxLength;
    var kRangeErrorMessage = 'Cannot create final Buffer. It would be larger ' + 'than 0x' + kMaxLength.toString(16) + ' bytes';
    
    // zlib doesn't provide these, so kludge them in following the same
    // const naming scheme zlib uses.
    binding.Z_MIN_WINDOWBITS = 8;
    binding.Z_MAX_WINDOWBITS = 15;
    binding.Z_DEFAULT_WINDOWBITS = 15;
    
    // fewer than 64 bytes per chunk is stupid.
    // technically it could work with as few as 8, but even 64 bytes
    // is absurdly low.  Usually a MB or more is best.
    binding.Z_MIN_CHUNK = 64;
    binding.Z_MAX_CHUNK = Infinity;
    binding.Z_DEFAULT_CHUNK = 16 * 1024;
    
    binding.Z_MIN_MEMLEVEL = 1;
    binding.Z_MAX_MEMLEVEL = 9;
    binding.Z_DEFAULT_MEMLEVEL = 8;
    
    binding.Z_MIN_LEVEL = -1;
    binding.Z_MAX_LEVEL = 9;
    binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION;
    
    // expose all the zlib constants
    var bkeys = Object.keys(binding);
    for (var bk = 0; bk < bkeys.length; bk++) {
      var bkey = bkeys[bk];
      if (bkey.match(/^Z/)) {
        Object.defineProperty(exports, bkey, {
          enumerable: true, value: binding[bkey], writable: false
        });
      }
    }
    
    // translation table for return codes.
    var codes = {
      Z_OK: binding.Z_OK,
      Z_STREAM_END: binding.Z_STREAM_END,
      Z_NEED_DICT: binding.Z_NEED_DICT,
      Z_ERRNO: binding.Z_ERRNO,
      Z_STREAM_ERROR: binding.Z_STREAM_ERROR,
      Z_DATA_ERROR: binding.Z_DATA_ERROR,
      Z_MEM_ERROR: binding.Z_MEM_ERROR,
      Z_BUF_ERROR: binding.Z_BUF_ERROR,
      Z_VERSION_ERROR: binding.Z_VERSION_ERROR
    };
    
    var ckeys = Object.keys(codes);
    for (var ck = 0; ck < ckeys.length; ck++) {
      var ckey = ckeys[ck];
      codes[codes[ckey]] = ckey;
    }
    
    Object.defineProperty(exports, 'codes', {
      enumerable: true, value: Object.freeze(codes), writable: false
    });
    
    exports.Deflate = Deflate;
    exports.Inflate = Inflate;
    exports.Gzip = Gzip;
    exports.Gunzip = Gunzip;
    exports.DeflateRaw = DeflateRaw;
    exports.InflateRaw = InflateRaw;
    exports.Unzip = Unzip;
    
    exports.createDeflate = function (o) {
      return new Deflate(o);
    };
    
    exports.createInflate = function (o) {
      return new Inflate(o);
    };
    
    exports.createDeflateRaw = function (o) {
      return new DeflateRaw(o);
    };
    
    exports.createInflateRaw = function (o) {
      return new InflateRaw(o);
    };
    
    exports.createGzip = function (o) {
      return new Gzip(o);
    };
    
    exports.createGunzip = function (o) {
      return new Gunzip(o);
    };
    
    exports.createUnzip = function (o) {
      return new Unzip(o);
    };
    
    // Convenience methods.
    // compress/decompress a string or buffer in one step.
    exports.deflate = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new Deflate(opts), buffer, callback);
    };
    
    exports.deflateSync = function (buffer, opts) {
      return zlibBufferSync(new Deflate(opts), buffer);
    };
    
    exports.gzip = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new Gzip(opts), buffer, callback);
    };
    
    exports.gzipSync = function (buffer, opts) {
      return zlibBufferSync(new Gzip(opts), buffer);
    };
    
    exports.deflateRaw = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new DeflateRaw(opts), buffer, callback);
    };
    
    exports.deflateRawSync = function (buffer, opts) {
      return zlibBufferSync(new DeflateRaw(opts), buffer);
    };
    
    exports.unzip = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new Unzip(opts), buffer, callback);
    };
    
    exports.unzipSync = function (buffer, opts) {
      return zlibBufferSync(new Unzip(opts), buffer);
    };
    
    exports.inflate = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new Inflate(opts), buffer, callback);
    };
    
    exports.inflateSync = function (buffer, opts) {
      return zlibBufferSync(new Inflate(opts), buffer);
    };
    
    exports.gunzip = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new Gunzip(opts), buffer, callback);
    };
    
    exports.gunzipSync = function (buffer, opts) {
      return zlibBufferSync(new Gunzip(opts), buffer);
    };
    
    exports.inflateRaw = function (buffer, opts, callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      return zlibBuffer(new InflateRaw(opts), buffer, callback);
    };
    
    exports.inflateRawSync = function (buffer, opts) {
      return zlibBufferSync(new InflateRaw(opts), buffer);
    };
    
    function zlibBuffer(engine, buffer, callback) {
      var buffers = [];
      var nread = 0;
    
      engine.on('error', onError);
      engine.on('end', onEnd);
    
      engine.end(buffer);
      flow();
    
      function flow() {
        var chunk;
        while (null !== (chunk = engine.read())) {
          buffers.push(chunk);
          nread += chunk.length;
        }
        engine.once('readable', flow);
      }
    
      function onError(err) {
        engine.removeListener('end', onEnd);
        engine.removeListener('readable', flow);
        callback(err);
      }
    
      function onEnd() {
        var buf;
        var err = null;
    
        if (nread >= kMaxLength) {
          err = new RangeError(kRangeErrorMessage);
        } else {
          buf = Buffer.concat(buffers, nread);
        }
    
        buffers = [];
        engine.close();
        callback(err, buf);
      }
    }
    
    function zlibBufferSync(engine, buffer) {
      if (typeof buffer === 'string') buffer = Buffer.from(buffer);
    
      if (!Buffer.isBuffer(buffer)) throw new TypeError('Not a string or buffer');
    
      var flushFlag = engine._finishFlushFlag;
    
      return engine._processChunk(buffer, flushFlag);
    }
    
    // generic zlib
    // minimal 2-byte header
    function Deflate(opts) {
      if (!(this instanceof Deflate)) return new Deflate(opts);
      Zlib.call(this, opts, binding.DEFLATE);
    }
    
    function Inflate(opts) {
      if (!(this instanceof Inflate)) return new Inflate(opts);
      Zlib.call(this, opts, binding.INFLATE);
    }
    
    // gzip - bigger header, same deflate compression
    function Gzip(opts) {
      if (!(this instanceof Gzip)) return new Gzip(opts);
      Zlib.call(this, opts, binding.GZIP);
    }
    
    function Gunzip(opts) {
      if (!(this instanceof Gunzip)) return new Gunzip(opts);
      Zlib.call(this, opts, binding.GUNZIP);
    }
    
    // raw - no header
    function DeflateRaw(opts) {
      if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts);
      Zlib.call(this, opts, binding.DEFLATERAW);
    }
    
    function InflateRaw(opts) {
      if (!(this instanceof InflateRaw)) return new InflateRaw(opts);
      Zlib.call(this, opts, binding.INFLATERAW);
    }
    
    // auto-detect header.
    function Unzip(opts) {
      if (!(this instanceof Unzip)) return new Unzip(opts);
      Zlib.call(this, opts, binding.UNZIP);
    }
    
    function isValidFlushFlag(flag) {
      return flag === binding.Z_NO_FLUSH || flag === binding.Z_PARTIAL_FLUSH || flag === binding.Z_SYNC_FLUSH || flag === binding.Z_FULL_FLUSH || flag === binding.Z_FINISH || flag === binding.Z_BLOCK;
    }
    
    // the Zlib class they all inherit from
    // This thing manages the queue of requests, and returns
    // true or false if there is anything in the queue when
    // you call the .write() method.
    
    function Zlib(opts, mode) {
      var _this = this;
    
      this._opts = opts = opts || {};
      this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK;
    
      Transform.call(this, opts);
    
      if (opts.flush && !isValidFlushFlag(opts.flush)) {
        throw new Error('Invalid flush flag: ' + opts.flush);
      }
      if (opts.finishFlush && !isValidFlushFlag(opts.finishFlush)) {
        throw new Error('Invalid flush flag: ' + opts.finishFlush);
      }
    
      this._flushFlag = opts.flush || binding.Z_NO_FLUSH;
      this._finishFlushFlag = typeof opts.finishFlush !== 'undefined' ? opts.finishFlush : binding.Z_FINISH;
    
      if (opts.chunkSize) {
        if (opts.chunkSize < exports.Z_MIN_CHUNK || opts.chunkSize > exports.Z_MAX_CHUNK) {
          throw new Error('Invalid chunk size: ' + opts.chunkSize);
        }
      }
    
      if (opts.windowBits) {
        if (opts.windowBits < exports.Z_MIN_WINDOWBITS || opts.windowBits > exports.Z_MAX_WINDOWBITS) {
          throw new Error('Invalid windowBits: ' + opts.windowBits);
        }
      }
    
      if (opts.level) {
        if (opts.level < exports.Z_MIN_LEVEL || opts.level > exports.Z_MAX_LEVEL) {
          throw new Error('Invalid compression level: ' + opts.level);
        }
      }
    
      if (opts.memLevel) {
        if (opts.memLevel < exports.Z_MIN_MEMLEVEL || opts.memLevel > exports.Z_MAX_MEMLEVEL) {
          throw new Error('Invalid memLevel: ' + opts.memLevel);
        }
      }
    
      if (opts.strategy) {
        if (opts.strategy != exports.Z_FILTERED && opts.strategy != exports.Z_HUFFMAN_ONLY && opts.strategy != exports.Z_RLE && opts.strategy != exports.Z_FIXED && opts.strategy != exports.Z_DEFAULT_STRATEGY) {
          throw new Error('Invalid strategy: ' + opts.strategy);
        }
      }
    
      if (opts.dictionary) {
        if (!Buffer.isBuffer(opts.dictionary)) {
          throw new Error('Invalid dictionary: it should be a Buffer instance');
        }
      }
    
      this._handle = new binding.Zlib(mode);
    
      var self = this;
      this._hadError = false;
      this._handle.onerror = function (message, errno) {
        // there is no way to cleanly recover.
        // continuing only obscures problems.
        _close(self);
        self._hadError = true;
    
        var error = new Error(message);
        error.errno = errno;
        error.code = exports.codes[errno];
        self.emit('error', error);
      };
    
      var level = exports.Z_DEFAULT_COMPRESSION;
      if (typeof opts.level === 'number') level = opts.level;
    
      var strategy = exports.Z_DEFAULT_STRATEGY;
      if (typeof opts.strategy === 'number') strategy = opts.strategy;
    
      this._handle.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, level, opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, strategy, opts.dictionary);
    
      this._buffer = Buffer.allocUnsafe(this._chunkSize);
      this._offset = 0;
      this._level = level;
      this._strategy = strategy;
    
      this.once('end', this.close);
    
      Object.defineProperty(this, '_closed', {
        get: function () {
          return !_this._handle;
        },
        configurable: true,
        enumerable: true
      });
    }
    
    util.inherits(Zlib, Transform);
    
    Zlib.prototype.params = function (level, strategy, callback) {
      if (level < exports.Z_MIN_LEVEL || level > exports.Z_MAX_LEVEL) {
        throw new RangeError('Invalid compression level: ' + level);
      }
      if (strategy != exports.Z_FILTERED && strategy != exports.Z_HUFFMAN_ONLY && strategy != exports.Z_RLE && strategy != exports.Z_FIXED && strategy != exports.Z_DEFAULT_STRATEGY) {
        throw new TypeError('Invalid strategy: ' + strategy);
      }
    
      if (this._level !== level || this._strategy !== strategy) {
        var self = this;
        this.flush(binding.Z_SYNC_FLUSH, function () {
          assert(self._handle, 'zlib binding closed');
          self._handle.params(level, strategy);
          if (!self._hadError) {
            self._level = level;
            self._strategy = strategy;
            if (callback) callback();
          }
        });
      } else {
        process.nextTick(callback);
      }
    };
    
    Zlib.prototype.reset = function () {
      assert(this._handle, 'zlib binding closed');
      return this._handle.reset();
    };
    
    // This is the _flush function called by the transform class,
    // internally, when the last chunk has been written.
    Zlib.prototype._flush = function (callback) {
      this._transform(Buffer.alloc(0), '', callback);
    };
    
    Zlib.prototype.flush = function (kind, callback) {
      var _this2 = this;
    
      var ws = this._writableState;
    
      if (typeof kind === 'function' || kind === undefined && !callback) {
        callback = kind;
        kind = binding.Z_FULL_FLUSH;
      }
    
      if (ws.ended) {
        if (callback) process.nextTick(callback);
      } else if (ws.ending) {
        if (callback) this.once('end', callback);
      } else if (ws.needDrain) {
        if (callback) {
          this.once('drain', function () {
            return _this2.flush(kind, callback);
          });
        }
      } else {
        this._flushFlag = kind;
        this.write(Buffer.alloc(0), '', callback);
      }
    };
    
    Zlib.prototype.close = function (callback) {
      _close(this, callback);
      process.nextTick(emitCloseNT, this);
    };
    
    function _close(engine, callback) {
      if (callback) process.nextTick(callback);
    
      // Caller may invoke .close after a zlib error (which will null _handle).
      if (!engine._handle) return;
    
      engine._handle.close();
      engine._handle = null;
    }
    
    function emitCloseNT(self) {
      self.emit('close');
    }
    
    Zlib.prototype._transform = function (chunk, encoding, cb) {
      var flushFlag;
      var ws = this._writableState;
      var ending = ws.ending || ws.ended;
      var last = ending && (!chunk || ws.length === chunk.length);
    
      if (chunk !== null && !Buffer.isBuffer(chunk)) return cb(new Error('invalid input'));
    
      if (!this._handle) return cb(new Error('zlib binding closed'));
    
      // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag
      // (or whatever flag was provided using opts.finishFlush).
      // If it's explicitly flushing at some other time, then we use
      // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression
      // goodness.
      if (last) flushFlag = this._finishFlushFlag;else {
        flushFlag = this._flushFlag;
        // once we've flushed the last of the queue, stop flushing and
        // go back to the normal behavior.
        if (chunk.length >= ws.length) {
          this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH;
        }
      }
    
      this._processChunk(chunk, flushFlag, cb);
    };
    
    Zlib.prototype._processChunk = function (chunk, flushFlag, cb) {
      var availInBefore = chunk && chunk.length;
      var availOutBefore = this._chunkSize - this._offset;
      var inOff = 0;
    
      var self = this;
    
      var async = typeof cb === 'function';
    
      if (!async) {
        var buffers = [];
        var nread = 0;
    
        var error;
        this.on('error', function (er) {
          error = er;
        });
    
        assert(this._handle, 'zlib binding closed');
        do {
          var res = this._handle.writeSync(flushFlag, chunk, // in
          inOff, // in_off
          availInBefore, // in_len
          this._buffer, // out
          this._offset, //out_off
          availOutBefore); // out_len
        } while (!this._hadError && callback(res[0], res[1]));
    
        if (this._hadError) {
          throw error;
        }
    
        if (nread >= kMaxLength) {
          _close(this);
          throw new RangeError(kRangeErrorMessage);
        }
    
        var buf = Buffer.concat(buffers, nread);
        _close(this);
    
        return buf;
      }
    
      assert(this._handle, 'zlib binding closed');
      var req = this._handle.write(flushFlag, chunk, // in
      inOff, // in_off
      availInBefore, // in_len
      this._buffer, // out
      this._offset, //out_off
      availOutBefore); // out_len
    
      req.buffer = chunk;
      req.callback = callback;
    
      function callback(availInAfter, availOutAfter) {
        // When the callback is used in an async write, the callback's
        // context is the `req` object that was created. The req object
        // is === this._handle, and that's why it's important to null
        // out the values after they are done being used. `this._handle`
        // can stay in memory longer than the callback and buffer are needed.
        if (this) {
          this.buffer = null;
          this.callback = null;
        }
    
        if (self._hadError) return;
    
        var have = availOutBefore - availOutAfter;
        assert(have >= 0, 'have should not go down');
    
        if (have > 0) {
          var out = self._buffer.slice(self._offset, self._offset + have);
          self._offset += have;
          // serve some output to the consumer.
          if (async) {
            self.push(out);
          } else {
            buffers.push(out);
            nread += out.length;
          }
        }
    
        // exhausted the output buffer, or used all the input create a new one.
        if (availOutAfter === 0 || self._offset >= self._chunkSize) {
          availOutBefore = self._chunkSize;
          self._offset = 0;
          self._buffer = Buffer.allocUnsafe(self._chunkSize);
        }
    
        if (availOutAfter === 0) {
          // Not actually done.  Need to reprocess.
          // Also, update the availInBefore to the availInAfter value,
          // so that if we have to hit it a third (fourth, etc.) time,
          // it'll have the correct byte counts.
          inOff += availInBefore - availInAfter;
          availInBefore = availInAfter;
    
          if (!async) return true;
    
          var newReq = self._handle.write(flushFlag, chunk, inOff, availInBefore, self._buffer, self._offset, self._chunkSize);
          newReq.callback = callback; // this same function
          newReq.buffer = chunk;
          return;
        }
    
        if (!async) return false;
    
        // finished with the chunk.
        cb();
      }
    };
    
    util.inherits(Deflate, Zlib);
    util.inherits(Inflate, Zlib);
    util.inherits(Gzip, Zlib);
    util.inherits(Gunzip, Zlib);
    util.inherits(DeflateRaw, Zlib);
    util.inherits(InflateRaw, Zlib);
    util.inherits(Unzip, Zlib);
    }).call(this)}).call(this,require('_process'))
    
    },{"./binding":81,"_process":321,"assert":24,"buffer":84,"stream":350,"util":372}],83:[function(require,module,exports){
    arguments[4][36][0].apply(exports,arguments)
    },{"dup":36}],84:[function(require,module,exports){
    (function (Buffer){(function (){
    /*!
     * The buffer module from node.js, for the browser.
     *
     * @author   Feross Aboukhadijeh <https://feross.org>
     * @license  MIT
     */
    /* eslint-disable no-proto */
    
    'use strict'
    
    var base64 = require('base64-js')
    var ieee754 = require('ieee754')
    
    exports.Buffer = Buffer
    exports.SlowBuffer = SlowBuffer
    exports.INSPECT_MAX_BYTES = 50
    
    var K_MAX_LENGTH = 0x7fffffff
    exports.kMaxLength = K_MAX_LENGTH
    
    /**
     * If `Buffer.TYPED_ARRAY_SUPPORT`:
     *   === true    Use Uint8Array implementation (fastest)
     *   === false   Print warning and recommend using `buffer` v4.x which has an Object
     *               implementation (most compatible, even IE6)
     *
     * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
     * Opera 11.6+, iOS 4.2+.
     *
     * We report that the browser does not support typed arrays if the are not subclassable
     * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
     * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
     * for __proto__ and has a buggy typed array implementation.
     */
    Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
    
    if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
        typeof console.error === 'function') {
      console.error(
        'This browser lacks typed array (Uint8Array) support which is required by ' +
        '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
      )
    }
    
    function typedArraySupport () {
      // Can typed array instances can be augmented?
      try {
        var arr = new Uint8Array(1)
        arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
        return arr.foo() === 42
      } catch (e) {
        return false
      }
    }
    
    Object.defineProperty(Buffer.prototype, 'parent', {
      enumerable: true,
      get: function () {
        if (!Buffer.isBuffer(this)) return undefined
        return this.buffer
      }
    })
    
    Object.defineProperty(Buffer.prototype, 'offset', {
      enumerable: true,
      get: function () {
        if (!Buffer.isBuffer(this)) return undefined
        return this.byteOffset
      }
    })
    
    function createBuffer (length) {
      if (length > K_MAX_LENGTH) {
        throw new RangeError('The value "' + length + '" is invalid for option "size"')
      }
      // Return an augmented `Uint8Array` instance
      var buf = new Uint8Array(length)
      buf.__proto__ = Buffer.prototype
      return buf
    }
    
    /**
     * The Buffer constructor returns instances of `Uint8Array` that have their
     * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
     * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
     * and the `Uint8Array` methods. Square bracket notation works as expected -- it
     * returns a single octet.
     *
     * The `Uint8Array` prototype remains unmodified.
     */
    
    function Buffer (arg, encodingOrOffset, length) {
      // Common case.
      if (typeof arg === 'number') {
        if (typeof encodingOrOffset === 'string') {
          throw new TypeError(
            'The "string" argument must be of type string. Received type number'
          )
        }
        return allocUnsafe(arg)
      }
      return from(arg, encodingOrOffset, length)
    }
    
    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
    if (typeof Symbol !== 'undefined' && Symbol.species != null &&
        Buffer[Symbol.species] === Buffer) {
      Object.defineProperty(Buffer, Symbol.species, {
        value: null,
        configurable: true,
        enumerable: false,
        writable: false
      })
    }
    
    Buffer.poolSize = 8192 // not used by this implementation
    
    function from (value, encodingOrOffset, length) {
      if (typeof value === 'string') {
        return fromString(value, encodingOrOffset)
      }
    
      if (ArrayBuffer.isView(value)) {
        return fromArrayLike(value)
      }
    
      if (value == null) {
        throw TypeError(
          'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
          'or Array-like Object. Received type ' + (typeof value)
        )
      }
    
      if (isInstance(value, ArrayBuffer) ||
          (value && isInstance(value.buffer, ArrayBuffer))) {
        return fromArrayBuffer(value, encodingOrOffset, length)
      }
    
      if (typeof value === 'number') {
        throw new TypeError(
          'The "value" argument must not be of type number. Received type number'
        )
      }
    
      var valueOf = value.valueOf && value.valueOf()
      if (valueOf != null && valueOf !== value) {
        return Buffer.from(valueOf, encodingOrOffset, length)
      }
    
      var b = fromObject(value)
      if (b) return b
    
      if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
          typeof value[Symbol.toPrimitive] === 'function') {
        return Buffer.from(
          value[Symbol.toPrimitive]('string'), encodingOrOffset, length
        )
      }
    
      throw new TypeError(
        'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
        'or Array-like Object. Received type ' + (typeof value)
      )
    }
    
    /**
     * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
     * if value is a number.
     * Buffer.from(str[, encoding])
     * Buffer.from(array)
     * Buffer.from(buffer)
     * Buffer.from(arrayBuffer[, byteOffset[, length]])
     **/
    Buffer.from = function (value, encodingOrOffset, length) {
      return from(value, encodingOrOffset, length)
    }
    
    // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
    // https://github.com/feross/buffer/pull/148
    Buffer.prototype.__proto__ = Uint8Array.prototype
    Buffer.__proto__ = Uint8Array
    
    function assertSize (size) {
      if (typeof size !== 'number') {
        throw new TypeError('"size" argument must be of type number')
      } else if (size < 0) {
        throw new RangeError('The value "' + size + '" is invalid for option "size"')
      }
    }
    
    function alloc (size, fill, encoding) {
      assertSize(size)
      if (size <= 0) {
        return createBuffer(size)
      }
      if (fill !== undefined) {
        // Only pay attention to encoding if it's a string. This
        // prevents accidentally sending in a number that would
        // be interpretted as a start offset.
        return typeof encoding === 'string'
          ? createBuffer(size).fill(fill, encoding)
          : createBuffer(size).fill(fill)
      }
      return createBuffer(size)
    }
    
    /**
     * Creates a new filled Buffer instance.
     * alloc(size[, fill[, encoding]])
     **/
    Buffer.alloc = function (size, fill, encoding) {
      return alloc(size, fill, encoding)
    }
    
    function allocUnsafe (size) {
      assertSize(size)
      return createBuffer(size < 0 ? 0 : checked(size) | 0)
    }
    
    /**
     * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
     * */
    Buffer.allocUnsafe = function (size) {
      return allocUnsafe(size)
    }
    /**
     * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
     */
    Buffer.allocUnsafeSlow = function (size) {
      return allocUnsafe(size)
    }
    
    function fromString (string, encoding) {
      if (typeof encoding !== 'string' || encoding === '') {
        encoding = 'utf8'
      }
    
      if (!Buffer.isEncoding(encoding)) {
        throw new TypeError('Unknown encoding: ' + encoding)
      }
    
      var length = byteLength(string, encoding) | 0
      var buf = createBuffer(length)
    
      var actual = buf.write(string, encoding)
    
      if (actual !== length) {
        // Writing a hex string, for example, that contains invalid characters will
        // cause everything after the first invalid character to be ignored. (e.g.
        // 'abxxcd' will be treated as 'ab')
        buf = buf.slice(0, actual)
      }
    
      return buf
    }
    
    function fromArrayLike (array) {
      var length = array.length < 0 ? 0 : checked(array.length) | 0
      var buf = createBuffer(length)
      for (var i = 0; i < length; i += 1) {
        buf[i] = array[i] & 255
      }
      return buf
    }
    
    function fromArrayBuffer (array, byteOffset, length) {
      if (byteOffset < 0 || array.byteLength < byteOffset) {
        throw new RangeError('"offset" is outside of buffer bounds')
      }
    
      if (array.byteLength < byteOffset + (length || 0)) {
        throw new RangeError('"length" is outside of buffer bounds')
      }
    
      var buf
      if (byteOffset === undefined && length === undefined) {
        buf = new Uint8Array(array)
      } else if (length === undefined) {
        buf = new Uint8Array(array, byteOffset)
      } else {
        buf = new Uint8Array(array, byteOffset, length)
      }
    
      // Return an augmented `Uint8Array` instance
      buf.__proto__ = Buffer.prototype
      return buf
    }
    
    function fromObject (obj) {
      if (Buffer.isBuffer(obj)) {
        var len = checked(obj.length) | 0
        var buf = createBuffer(len)
    
        if (buf.length === 0) {
          return buf
        }
    
        obj.copy(buf, 0, 0, len)
        return buf
      }
    
      if (obj.length !== undefined) {
        if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
          return createBuffer(0)
        }
        return fromArrayLike(obj)
      }
    
      if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
        return fromArrayLike(obj.data)
      }
    }
    
    function checked (length) {
      // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
      // length is NaN (which is otherwise coerced to zero.)
      if (length >= K_MAX_LENGTH) {
        throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                             'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
      }
      return length | 0
    }
    
    function SlowBuffer (length) {
      if (+length != length) { // eslint-disable-line eqeqeq
        length = 0
      }
      return Buffer.alloc(+length)
    }
    
    Buffer.isBuffer = function isBuffer (b) {
      return b != null && b._isBuffer === true &&
        b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
    }
    
    Buffer.compare = function compare (a, b) {
      if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
      if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
      if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
        throw new TypeError(
          'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
        )
      }
    
      if (a === b) return 0
    
      var x = a.length
      var y = b.length
    
      for (var i = 0, len = Math.min(x, y); i < len; ++i) {
        if (a[i] !== b[i]) {
          x = a[i]
          y = b[i]
          break
        }
      }
    
      if (x < y) return -1
      if (y < x) return 1
      return 0
    }
    
    Buffer.isEncoding = function isEncoding (encoding) {
      switch (String(encoding).toLowerCase()) {
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'latin1':
        case 'binary':
        case 'base64':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return true
        default:
          return false
      }
    }
    
    Buffer.concat = function concat (list, length) {
      if (!Array.isArray(list)) {
        throw new TypeError('"list" argument must be an Array of Buffers')
      }
    
      if (list.length === 0) {
        return Buffer.alloc(0)
      }
    
      var i
      if (length === undefined) {
        length = 0
        for (i = 0; i < list.length; ++i) {
          length += list[i].length
        }
      }
    
      var buffer = Buffer.allocUnsafe(length)
      var pos = 0
      for (i = 0; i < list.length; ++i) {
        var buf = list[i]
        if (isInstance(buf, Uint8Array)) {
          buf = Buffer.from(buf)
        }
        if (!Buffer.isBuffer(buf)) {
          throw new TypeError('"list" argument must be an Array of Buffers')
        }
        buf.copy(buffer, pos)
        pos += buf.length
      }
      return buffer
    }
    
    function byteLength (string, encoding) {
      if (Buffer.isBuffer(string)) {
        return string.length
      }
      if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
        return string.byteLength
      }
      if (typeof string !== 'string') {
        throw new TypeError(
          'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
          'Received type ' + typeof string
        )
      }
    
      var len = string.length
      var mustMatch = (arguments.length > 2 && arguments[2] === true)
      if (!mustMatch && len === 0) return 0
    
      // Use a for loop to avoid recursion
      var loweredCase = false
      for (;;) {
        switch (encoding) {
          case 'ascii':
          case 'latin1':
          case 'binary':
            return len
          case 'utf8':
          case 'utf-8':
            return utf8ToBytes(string).length
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return len * 2
          case 'hex':
            return len >>> 1
          case 'base64':
            return base64ToBytes(string).length
          default:
            if (loweredCase) {
              return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
            }
            encoding = ('' + encoding).toLowerCase()
            loweredCase = true
        }
      }
    }
    Buffer.byteLength = byteLength
    
    function slowToString (encoding, start, end) {
      var loweredCase = false
    
      // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
      // property of a typed array.
    
      // This behaves neither like String nor Uint8Array in that we set start/end
      // to their upper/lower bounds if the value passed is out of range.
      // undefined is handled specially as per ECMA-262 6th Edition,
      // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
      if (start === undefined || start < 0) {
        start = 0
      }
      // Return early if start > this.length. Done here to prevent potential uint32
      // coercion fail below.
      if (start > this.length) {
        return ''
      }
    
      if (end === undefined || end > this.length) {
        end = this.length
      }
    
      if (end <= 0) {
        return ''
      }
    
      // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
      end >>>= 0
      start >>>= 0
    
      if (end <= start) {
        return ''
      }
    
      if (!encoding) encoding = 'utf8'
    
      while (true) {
        switch (encoding) {
          case 'hex':
            return hexSlice(this, start, end)
    
          case 'utf8':
          case 'utf-8':
            return utf8Slice(this, start, end)
    
          case 'ascii':
            return asciiSlice(this, start, end)
    
          case 'latin1':
          case 'binary':
            return latin1Slice(this, start, end)
    
          case 'base64':
            return base64Slice(this, start, end)
    
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return utf16leSlice(this, start, end)
    
          default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
            encoding = (encoding + '').toLowerCase()
            loweredCase = true
        }
      }
    }
    
    // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
    // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
    // reliably in a browserify context because there could be multiple different
    // copies of the 'buffer' package in use. This method works even for Buffer
    // instances that were created from another copy of the `buffer` package.
    // See: https://github.com/feross/buffer/issues/154
    Buffer.prototype._isBuffer = true
    
    function swap (b, n, m) {
      var i = b[n]
      b[n] = b[m]
      b[m] = i
    }
    
    Buffer.prototype.swap16 = function swap16 () {
      var len = this.length
      if (len % 2 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 16-bits')
      }
      for (var i = 0; i < len; i += 2) {
        swap(this, i, i + 1)
      }
      return this
    }
    
    Buffer.prototype.swap32 = function swap32 () {
      var len = this.length
      if (len % 4 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 32-bits')
      }
      for (var i = 0; i < len; i += 4) {
        swap(this, i, i + 3)
        swap(this, i + 1, i + 2)
      }
      return this
    }
    
    Buffer.prototype.swap64 = function swap64 () {
      var len = this.length
      if (len % 8 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 64-bits')
      }
      for (var i = 0; i < len; i += 8) {
        swap(this, i, i + 7)
        swap(this, i + 1, i + 6)
        swap(this, i + 2, i + 5)
        swap(this, i + 3, i + 4)
      }
      return this
    }
    
    Buffer.prototype.toString = function toString () {
      var length = this.length
      if (length === 0) return ''
      if (arguments.length === 0) return utf8Slice(this, 0, length)
      return slowToString.apply(this, arguments)
    }
    
    Buffer.prototype.toLocaleString = Buffer.prototype.toString
    
    Buffer.prototype.equals = function equals (b) {
      if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
      if (this === b) return true
      return Buffer.compare(this, b) === 0
    }
    
    Buffer.prototype.inspect = function inspect () {
      var str = ''
      var max = exports.INSPECT_MAX_BYTES
      str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
      if (this.length > max) str += ' ... '
      return '<Buffer ' + str + '>'
    }
    
    Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
      if (isInstance(target, Uint8Array)) {
        target = Buffer.from(target, target.offset, target.byteLength)
      }
      if (!Buffer.isBuffer(target)) {
        throw new TypeError(
          'The "target" argument must be one of type Buffer or Uint8Array. ' +
          'Received type ' + (typeof target)
        )
      }
    
      if (start === undefined) {
        start = 0
      }
      if (end === undefined) {
        end = target ? target.length : 0
      }
      if (thisStart === undefined) {
        thisStart = 0
      }
      if (thisEnd === undefined) {
        thisEnd = this.length
      }
    
      if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
        throw new RangeError('out of range index')
      }
    
      if (thisStart >= thisEnd && start >= end) {
        return 0
      }
      if (thisStart >= thisEnd) {
        return -1
      }
      if (start >= end) {
        return 1
      }
    
      start >>>= 0
      end >>>= 0
      thisStart >>>= 0
      thisEnd >>>= 0
    
      if (this === target) return 0
    
      var x = thisEnd - thisStart
      var y = end - start
      var len = Math.min(x, y)
    
      var thisCopy = this.slice(thisStart, thisEnd)
      var targetCopy = target.slice(start, end)
    
      for (var i = 0; i < len; ++i) {
        if (thisCopy[i] !== targetCopy[i]) {
          x = thisCopy[i]
          y = targetCopy[i]
          break
        }
      }
    
      if (x < y) return -1
      if (y < x) return 1
      return 0
    }
    
    // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
    // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
    //
    // Arguments:
    // - buffer - a Buffer to search
    // - val - a string, Buffer, or number
    // - byteOffset - an index into `buffer`; will be clamped to an int32
    // - encoding - an optional encoding, relevant is val is a string
    // - dir - true for indexOf, false for lastIndexOf
    function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
      // Empty buffer means no match
      if (buffer.length === 0) return -1
    
      // Normalize byteOffset
      if (typeof byteOffset === 'string') {
        encoding = byteOffset
        byteOffset = 0
      } else if (byteOffset > 0x7fffffff) {
        byteOffset = 0x7fffffff
      } else if (byteOffset < -0x80000000) {
        byteOffset = -0x80000000
      }
      byteOffset = +byteOffset // Coerce to Number.
      if (numberIsNaN(byteOffset)) {
        // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
        byteOffset = dir ? 0 : (buffer.length - 1)
      }
    
      // Normalize byteOffset: negative offsets start from the end of the buffer
      if (byteOffset < 0) byteOffset = buffer.length + byteOffset
      if (byteOffset >= buffer.length) {
        if (dir) return -1
        else byteOffset = buffer.length - 1
      } else if (byteOffset < 0) {
        if (dir) byteOffset = 0
        else return -1
      }
    
      // Normalize val
      if (typeof val === 'string') {
        val = Buffer.from(val, encoding)
      }
    
      // Finally, search either indexOf (if dir is true) or lastIndexOf
      if (Buffer.isBuffer(val)) {
        // Special case: looking for empty string/buffer always fails
        if (val.length === 0) {
          return -1
        }
        return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
      } else if (typeof val === 'number') {
        val = val & 0xFF // Search for a byte value [0-255]
        if (typeof Uint8Array.prototype.indexOf === 'function') {
          if (dir) {
            return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
          } else {
            return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
          }
        }
        return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
      }
    
      throw new TypeError('val must be string, number or Buffer')
    }
    
    function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
      var indexSize = 1
      var arrLength = arr.length
      var valLength = val.length
    
      if (encoding !== undefined) {
        encoding = String(encoding).toLowerCase()
        if (encoding === 'ucs2' || encoding === 'ucs-2' ||
            encoding === 'utf16le' || encoding === 'utf-16le') {
          if (arr.length < 2 || val.length < 2) {
            return -1
          }
          indexSize = 2
          arrLength /= 2
          valLength /= 2
          byteOffset /= 2
        }
      }
    
      function read (buf, i) {
        if (indexSize === 1) {
          return buf[i]
        } else {
          return buf.readUInt16BE(i * indexSize)
        }
      }
    
      var i
      if (dir) {
        var foundIndex = -1
        for (i = byteOffset; i < arrLength; i++) {
          if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
            if (foundIndex === -1) foundIndex = i
            if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
          } else {
            if (foundIndex !== -1) i -= i - foundIndex
            foundIndex = -1
          }
        }
      } else {
        if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
        for (i = byteOffset; i >= 0; i--) {
          var found = true
          for (var j = 0; j < valLength; j++) {
            if (read(arr, i + j) !== read(val, j)) {
              found = false
              break
            }
          }
          if (found) return i
        }
      }
    
      return -1
    }
    
    Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
      return this.indexOf(val, byteOffset, encoding) !== -1
    }
    
    Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
      return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
    }
    
    Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
      return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
    }
    
    function hexWrite (buf, string, offset, length) {
      offset = Number(offset) || 0
      var remaining = buf.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
    
      var strLen = string.length
    
      if (length > strLen / 2) {
        length = strLen / 2
      }
      for (var i = 0; i < length; ++i) {
        var parsed = parseInt(string.substr(i * 2, 2), 16)
        if (numberIsNaN(parsed)) return i
        buf[offset + i] = parsed
      }
      return i
    }
    
    function utf8Write (buf, string, offset, length) {
      return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
    }
    
    function asciiWrite (buf, string, offset, length) {
      return blitBuffer(asciiToBytes(string), buf, offset, length)
    }
    
    function latin1Write (buf, string, offset, length) {
      return asciiWrite(buf, string, offset, length)
    }
    
    function base64Write (buf, string, offset, length) {
      return blitBuffer(base64ToBytes(string), buf, offset, length)
    }
    
    function ucs2Write (buf, string, offset, length) {
      return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
    }
    
    Buffer.prototype.write = function write (string, offset, length, encoding) {
      // Buffer#write(string)
      if (offset === undefined) {
        encoding = 'utf8'
        length = this.length
        offset = 0
      // Buffer#write(string, encoding)
      } else if (length === undefined && typeof offset === 'string') {
        encoding = offset
        length = this.length
        offset = 0
      // Buffer#write(string, offset[, length][, encoding])
      } else if (isFinite(offset)) {
        offset = offset >>> 0
        if (isFinite(length)) {
          length = length >>> 0
          if (encoding === undefined) encoding = 'utf8'
        } else {
          encoding = length
          length = undefined
        }
      } else {
        throw new Error(
          'Buffer.write(string, encoding, offset[, length]) is no longer supported'
        )
      }
    
      var remaining = this.length - offset
      if (length === undefined || length > remaining) length = remaining
    
      if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
        throw new RangeError('Attempt to write outside buffer bounds')
      }
    
      if (!encoding) encoding = 'utf8'
    
      var loweredCase = false
      for (;;) {
        switch (encoding) {
          case 'hex':
            return hexWrite(this, string, offset, length)
    
          case 'utf8':
          case 'utf-8':
            return utf8Write(this, string, offset, length)
    
          case 'ascii':
            return asciiWrite(this, string, offset, length)
    
          case 'latin1':
          case 'binary':
            return latin1Write(this, string, offset, length)
    
          case 'base64':
            // Warning: maxLength not taken into account in base64Write
            return base64Write(this, string, offset, length)
    
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return ucs2Write(this, string, offset, length)
    
          default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
            encoding = ('' + encoding).toLowerCase()
            loweredCase = true
        }
      }
    }
    
    Buffer.prototype.toJSON = function toJSON () {
      return {
        type: 'Buffer',
        data: Array.prototype.slice.call(this._arr || this, 0)
      }
    }
    
    function base64Slice (buf, start, end) {
      if (start === 0 && end === buf.length) {
        return base64.fromByteArray(buf)
      } else {
        return base64.fromByteArray(buf.slice(start, end))
      }
    }
    
    function utf8Slice (buf, start, end) {
      end = Math.min(buf.length, end)
      var res = []
    
      var i = start
      while (i < end) {
        var firstByte = buf[i]
        var codePoint = null
        var bytesPerSequence = (firstByte > 0xEF) ? 4
          : (firstByte > 0xDF) ? 3
            : (firstByte > 0xBF) ? 2
              : 1
    
        if (i + bytesPerSequence <= end) {
          var secondByte, thirdByte, fourthByte, tempCodePoint
    
          switch (bytesPerSequence) {
            case 1:
              if (firstByte < 0x80) {
                codePoint = firstByte
              }
              break
            case 2:
              secondByte = buf[i + 1]
              if ((secondByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
                if (tempCodePoint > 0x7F) {
                  codePoint = tempCodePoint
                }
              }
              break
            case 3:
              secondByte = buf[i + 1]
              thirdByte = buf[i + 2]
              if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
                if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                  codePoint = tempCodePoint
                }
              }
              break
            case 4:
              secondByte = buf[i + 1]
              thirdByte = buf[i + 2]
              fourthByte = buf[i + 3]
              if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
                if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                  codePoint = tempCodePoint
                }
              }
          }
        }
    
        if (codePoint === null) {
          // we did not generate a valid codePoint so insert a
          // replacement char (U+FFFD) and advance only 1 byte
          codePoint = 0xFFFD
          bytesPerSequence = 1
        } else if (codePoint > 0xFFFF) {
          // encode to utf16 (surrogate pair dance)
          codePoint -= 0x10000
          res.push(codePoint >>> 10 & 0x3FF | 0xD800)
          codePoint = 0xDC00 | codePoint & 0x3FF
        }
    
        res.push(codePoint)
        i += bytesPerSequence
      }
    
      return decodeCodePointsArray(res)
    }
    
    // Based on http://stackoverflow.com/a/22747272/680742, the browser with
    // the lowest limit is Chrome, with 0x10000 args.
    // We go 1 magnitude less, for safety
    var MAX_ARGUMENTS_LENGTH = 0x1000
    
    function decodeCodePointsArray (codePoints) {
      var len = codePoints.length
      if (len <= MAX_ARGUMENTS_LENGTH) {
        return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
      }
    
      // Decode in chunks to avoid "call stack size exceeded".
      var res = ''
      var i = 0
      while (i < len) {
        res += String.fromCharCode.apply(
          String,
          codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
        )
      }
      return res
    }
    
    function asciiSlice (buf, start, end) {
      var ret = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; ++i) {
        ret += String.fromCharCode(buf[i] & 0x7F)
      }
      return ret
    }
    
    function latin1Slice (buf, start, end) {
      var ret = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; ++i) {
        ret += String.fromCharCode(buf[i])
      }
      return ret
    }
    
    function hexSlice (buf, start, end) {
      var len = buf.length
    
      if (!start || start < 0) start = 0
      if (!end || end < 0 || end > len) end = len
    
      var out = ''
      for (var i = start; i < end; ++i) {
        out += toHex(buf[i])
      }
      return out
    }
    
    function utf16leSlice (buf, start, end) {
      var bytes = buf.slice(start, end)
      var res = ''
      for (var i = 0; i < bytes.length; i += 2) {
        res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
      }
      return res
    }
    
    Buffer.prototype.slice = function slice (start, end) {
      var len = this.length
      start = ~~start
      end = end === undefined ? len : ~~end
    
      if (start < 0) {
        start += len
        if (start < 0) start = 0
      } else if (start > len) {
        start = len
      }
    
      if (end < 0) {
        end += len
        if (end < 0) end = 0
      } else if (end > len) {
        end = len
      }
    
      if (end < start) end = start
    
      var newBuf = this.subarray(start, end)
      // Return an augmented `Uint8Array` instance
      newBuf.__proto__ = Buffer.prototype
      return newBuf
    }
    
    /*
     * Need to make sure that buffer isn't trying to write out of bounds.
     */
    function checkOffset (offset, ext, length) {
      if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
      if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
    }
    
    Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      var val = this[offset]
      var mul = 1
      var i = 0
      while (++i < byteLength && (mul *= 0x100)) {
        val += this[offset + i] * mul
      }
    
      return val
    }
    
    Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        checkOffset(offset, byteLength, this.length)
      }
    
      var val = this[offset + --byteLength]
      var mul = 1
      while (byteLength > 0 && (mul *= 0x100)) {
        val += this[offset + --byteLength] * mul
      }
    
      return val
    }
    
    Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 1, this.length)
      return this[offset]
    }
    
    Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      return this[offset] | (this[offset + 1] << 8)
    }
    
    Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      return (this[offset] << 8) | this[offset + 1]
    }
    
    Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return ((this[offset]) |
          (this[offset + 1] << 8) |
          (this[offset + 2] << 16)) +
          (this[offset + 3] * 0x1000000)
    }
    
    Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset] * 0x1000000) +
        ((this[offset + 1] << 16) |
        (this[offset + 2] << 8) |
        this[offset + 3])
    }
    
    Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      var val = this[offset]
      var mul = 1
      var i = 0
      while (++i < byteLength && (mul *= 0x100)) {
        val += this[offset + i] * mul
      }
      mul *= 0x80
    
      if (val >= mul) val -= Math.pow(2, 8 * byteLength)
    
      return val
    }
    
    Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      var i = byteLength
      var mul = 1
      var val = this[offset + --i]
      while (i > 0 && (mul *= 0x100)) {
        val += this[offset + --i] * mul
      }
      mul *= 0x80
    
      if (val >= mul) val -= Math.pow(2, 8 * byteLength)
    
      return val
    }
    
    Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 1, this.length)
      if (!(this[offset] & 0x80)) return (this[offset])
      return ((0xff - this[offset] + 1) * -1)
    }
    
    Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      var val = this[offset] | (this[offset + 1] << 8)
      return (val & 0x8000) ? val | 0xFFFF0000 : val
    }
    
    Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      var val = this[offset + 1] | (this[offset] << 8)
      return (val & 0x8000) ? val | 0xFFFF0000 : val
    }
    
    Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset]) |
        (this[offset + 1] << 8) |
        (this[offset + 2] << 16) |
        (this[offset + 3] << 24)
    }
    
    Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset] << 24) |
        (this[offset + 1] << 16) |
        (this[offset + 2] << 8) |
        (this[offset + 3])
    }
    
    Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
      return ieee754.read(this, offset, true, 23, 4)
    }
    
    Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
      return ieee754.read(this, offset, false, 23, 4)
    }
    
    Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 8, this.length)
      return ieee754.read(this, offset, true, 52, 8)
    }
    
    Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 8, this.length)
      return ieee754.read(this, offset, false, 52, 8)
    }
    
    function checkInt (buf, value, offset, ext, max, min) {
      if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
      if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
      if (offset + ext > buf.length) throw new RangeError('Index out of range')
    }
    
    Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        var maxBytes = Math.pow(2, 8 * byteLength) - 1
        checkInt(this, value, offset, byteLength, maxBytes, 0)
      }
    
      var mul = 1
      var i = 0
      this[offset] = value & 0xFF
      while (++i < byteLength && (mul *= 0x100)) {
        this[offset + i] = (value / mul) & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        var maxBytes = Math.pow(2, 8 * byteLength) - 1
        checkInt(this, value, offset, byteLength, maxBytes, 0)
      }
    
      var i = byteLength - 1
      var mul = 1
      this[offset + i] = value & 0xFF
      while (--i >= 0 && (mul *= 0x100)) {
        this[offset + i] = (value / mul) & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
      this[offset] = (value & 0xff)
      return offset + 1
    }
    
    Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      return offset + 2
    }
    
    Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
      return offset + 2
    }
    
    Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
      this[offset + 3] = (value >>> 24)
      this[offset + 2] = (value >>> 16)
      this[offset + 1] = (value >>> 8)
      this[offset] = (value & 0xff)
      return offset + 4
    }
    
    Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
      return offset + 4
    }
    
    Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        var limit = Math.pow(2, (8 * byteLength) - 1)
    
        checkInt(this, value, offset, byteLength, limit - 1, -limit)
      }
    
      var i = 0
      var mul = 1
      var sub = 0
      this[offset] = value & 0xFF
      while (++i < byteLength && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
          sub = 1
        }
        this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        var limit = Math.pow(2, (8 * byteLength) - 1)
    
        checkInt(this, value, offset, byteLength, limit - 1, -limit)
      }
    
      var i = byteLength - 1
      var mul = 1
      var sub = 0
      this[offset + i] = value & 0xFF
      while (--i >= 0 && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
          sub = 1
        }
        this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
      if (value < 0) value = 0xff + value + 1
      this[offset] = (value & 0xff)
      return offset + 1
    }
    
    Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      return offset + 2
    }
    
    Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
      return offset + 2
    }
    
    Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      this[offset + 2] = (value >>> 16)
      this[offset + 3] = (value >>> 24)
      return offset + 4
    }
    
    Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
      if (value < 0) value = 0xffffffff + value + 1
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
      return offset + 4
    }
    
    function checkIEEE754 (buf, value, offset, ext, max, min) {
      if (offset + ext > buf.length) throw new RangeError('Index out of range')
      if (offset < 0) throw new RangeError('Index out of range')
    }
    
    function writeFloat (buf, value, offset, littleEndian, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
      }
      ieee754.write(buf, value, offset, littleEndian, 23, 4)
      return offset + 4
    }
    
    Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
      return writeFloat(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
      return writeFloat(this, value, offset, false, noAssert)
    }
    
    function writeDouble (buf, value, offset, littleEndian, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
      }
      ieee754.write(buf, value, offset, littleEndian, 52, 8)
      return offset + 8
    }
    
    Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
      return writeDouble(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
      return writeDouble(this, value, offset, false, noAssert)
    }
    
    // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
    Buffer.prototype.copy = function copy (target, targetStart, start, end) {
      if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
      if (!start) start = 0
      if (!end && end !== 0) end = this.length
      if (targetStart >= target.length) targetStart = target.length
      if (!targetStart) targetStart = 0
      if (end > 0 && end < start) end = start
    
      // Copy 0 bytes; we're done
      if (end === start) return 0
      if (target.length === 0 || this.length === 0) return 0
    
      // Fatal error conditions
      if (targetStart < 0) {
        throw new RangeError('targetStart out of bounds')
      }
      if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
      if (end < 0) throw new RangeError('sourceEnd out of bounds')
    
      // Are we oob?
      if (end > this.length) end = this.length
      if (target.length - targetStart < end - start) {
        end = target.length - targetStart + start
      }
    
      var len = end - start
    
      if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
        // Use built-in when available, missing from IE11
        this.copyWithin(targetStart, start, end)
      } else if (this === target && start < targetStart && targetStart < end) {
        // descending copy from end
        for (var i = len - 1; i >= 0; --i) {
          target[i + targetStart] = this[i + start]
        }
      } else {
        Uint8Array.prototype.set.call(
          target,
          this.subarray(start, end),
          targetStart
        )
      }
    
      return len
    }
    
    // Usage:
    //    buffer.fill(number[, offset[, end]])
    //    buffer.fill(buffer[, offset[, end]])
    //    buffer.fill(string[, offset[, end]][, encoding])
    Buffer.prototype.fill = function fill (val, start, end, encoding) {
      // Handle string cases:
      if (typeof val === 'string') {
        if (typeof start === 'string') {
          encoding = start
          start = 0
          end = this.length
        } else if (typeof end === 'string') {
          encoding = end
          end = this.length
        }
        if (encoding !== undefined && typeof encoding !== 'string') {
          throw new TypeError('encoding must be a string')
        }
        if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
          throw new TypeError('Unknown encoding: ' + encoding)
        }
        if (val.length === 1) {
          var code = val.charCodeAt(0)
          if ((encoding === 'utf8' && code < 128) ||
              encoding === 'latin1') {
            // Fast path: If `val` fits into a single byte, use that numeric value.
            val = code
          }
        }
      } else if (typeof val === 'number') {
        val = val & 255
      }
    
      // Invalid ranges are not set to a default, so can range check early.
      if (start < 0 || this.length < start || this.length < end) {
        throw new RangeError('Out of range index')
      }
    
      if (end <= start) {
        return this
      }
    
      start = start >>> 0
      end = end === undefined ? this.length : end >>> 0
    
      if (!val) val = 0
    
      var i
      if (typeof val === 'number') {
        for (i = start; i < end; ++i) {
          this[i] = val
        }
      } else {
        var bytes = Buffer.isBuffer(val)
          ? val
          : Buffer.from(val, encoding)
        var len = bytes.length
        if (len === 0) {
          throw new TypeError('The value "' + val +
            '" is invalid for argument "value"')
        }
        for (i = 0; i < end - start; ++i) {
          this[i + start] = bytes[i % len]
        }
      }
    
      return this
    }
    
    // HELPER FUNCTIONS
    // ================
    
    var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
    
    function base64clean (str) {
      // Node takes equal signs as end of the Base64 encoding
      str = str.split('=')[0]
      // Node strips out invalid characters like \n and \t from the string, base64-js does not
      str = str.trim().replace(INVALID_BASE64_RE, '')
      // Node converts strings with length < 2 to ''
      if (str.length < 2) return ''
      // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
      while (str.length % 4 !== 0) {
        str = str + '='
      }
      return str
    }
    
    function toHex (n) {
      if (n < 16) return '0' + n.toString(16)
      return n.toString(16)
    }
    
    function utf8ToBytes (string, units) {
      units = units || Infinity
      var codePoint
      var length = string.length
      var leadSurrogate = null
      var bytes = []
    
      for (var i = 0; i < length; ++i) {
        codePoint = string.charCodeAt(i)
    
        // is surrogate component
        if (codePoint > 0xD7FF && codePoint < 0xE000) {
          // last char was a lead
          if (!leadSurrogate) {
            // no lead yet
            if (codePoint > 0xDBFF) {
              // unexpected trail
              if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
              continue
            } else if (i + 1 === length) {
              // unpaired lead
              if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
              continue
            }
    
            // valid lead
            leadSurrogate = codePoint
    
            continue
          }
    
          // 2 leads in a row
          if (codePoint < 0xDC00) {
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            leadSurrogate = codePoint
            continue
          }
    
          // valid surrogate pair
          codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
        } else if (leadSurrogate) {
          // valid bmp char, but last char was a lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
        }
    
        leadSurrogate = null
    
        // encode utf8
        if (codePoint < 0x80) {
          if ((units -= 1) < 0) break
          bytes.push(codePoint)
        } else if (codePoint < 0x800) {
          if ((units -= 2) < 0) break
          bytes.push(
            codePoint >> 0x6 | 0xC0,
            codePoint & 0x3F | 0x80
          )
        } else if (codePoint < 0x10000) {
          if ((units -= 3) < 0) break
          bytes.push(
            codePoint >> 0xC | 0xE0,
            codePoint >> 0x6 & 0x3F | 0x80,
            codePoint & 0x3F | 0x80
          )
        } else if (codePoint < 0x110000) {
          if ((units -= 4) < 0) break
          bytes.push(
            codePoint >> 0x12 | 0xF0,
            codePoint >> 0xC & 0x3F | 0x80,
            codePoint >> 0x6 & 0x3F | 0x80,
            codePoint & 0x3F | 0x80
          )
        } else {
          throw new Error('Invalid code point')
        }
      }
    
      return bytes
    }
    
    function asciiToBytes (str) {
      var byteArray = []
      for (var i = 0; i < str.length; ++i) {
        // Node's code seems to be doing this and not & 0x7F..
        byteArray.push(str.charCodeAt(i) & 0xFF)
      }
      return byteArray
    }
    
    function utf16leToBytes (str, units) {
      var c, hi, lo
      var byteArray = []
      for (var i = 0; i < str.length; ++i) {
        if ((units -= 2) < 0) break
    
        c = str.charCodeAt(i)
        hi = c >> 8
        lo = c % 256
        byteArray.push(lo)
        byteArray.push(hi)
      }
    
      return byteArray
    }
    
    function base64ToBytes (str) {
      return base64.toByteArray(base64clean(str))
    }
    
    function blitBuffer (src, dst, offset, length) {
      for (var i = 0; i < length; ++i) {
        if ((i + offset >= dst.length) || (i >= src.length)) break
        dst[i + offset] = src[i]
      }
      return i
    }
    
    // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
    // the `instanceof` check but they should be treated as of that type.
    // See: https://github.com/feross/buffer/issues/166
    function isInstance (obj, type) {
      return obj instanceof type ||
        (obj != null && obj.constructor != null && obj.constructor.name != null &&
          obj.constructor.name === type.name)
    }
    function numberIsNaN (obj) {
      // For IE11 support
      return obj !== obj // eslint-disable-line no-self-compare
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"base64-js":31,"buffer":84,"ieee754":180}],85:[function(require,module,exports){
    var basex = require('base-x')
    var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
    
    module.exports = basex(ALPHABET)
    
    },{"base-x":30}],86:[function(require,module,exports){
    (function (Buffer){(function (){
    module.exports = function xor (a, b) {
      var length = Math.min(a.length, b.length)
      var buffer = new Buffer(length)
    
      for (var i = 0; i < length; ++i) {
        buffer[i] = a[i] ^ b[i]
      }
    
      return buffer
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84}],87:[function(require,module,exports){
    (function (Buffer){(function (){
    /*!
     * The buffer module from node.js, for the browser.
     *
     * @author   Feross Aboukhadijeh <https://feross.org>
     * @license  MIT
     */
    /* eslint-disable no-proto */
    
    'use strict'
    
    const base64 = require('base64-js')
    const ieee754 = require('ieee754')
    const customInspectSymbol =
      (typeof Symbol === 'function' && typeof Symbol['for'] === 'function') // eslint-disable-line dot-notation
        ? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation
        : null
    
    exports.Buffer = Buffer
    exports.SlowBuffer = SlowBuffer
    exports.INSPECT_MAX_BYTES = 50
    
    const K_MAX_LENGTH = 0x7fffffff
    exports.kMaxLength = K_MAX_LENGTH
    
    /**
     * If `Buffer.TYPED_ARRAY_SUPPORT`:
     *   === true    Use Uint8Array implementation (fastest)
     *   === false   Print warning and recommend using `buffer` v4.x which has an Object
     *               implementation (most compatible, even IE6)
     *
     * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
     * Opera 11.6+, iOS 4.2+.
     *
     * We report that the browser does not support typed arrays if the are not subclassable
     * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
     * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
     * for __proto__ and has a buggy typed array implementation.
     */
    Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
    
    if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
        typeof console.error === 'function') {
      console.error(
        'This browser lacks typed array (Uint8Array) support which is required by ' +
        '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
      )
    }
    
    function typedArraySupport () {
      // Can typed array instances can be augmented?
      try {
        const arr = new Uint8Array(1)
        const proto = { foo: function () { return 42 } }
        Object.setPrototypeOf(proto, Uint8Array.prototype)
        Object.setPrototypeOf(arr, proto)
        return arr.foo() === 42
      } catch (e) {
        return false
      }
    }
    
    Object.defineProperty(Buffer.prototype, 'parent', {
      enumerable: true,
      get: function () {
        if (!Buffer.isBuffer(this)) return undefined
        return this.buffer
      }
    })
    
    Object.defineProperty(Buffer.prototype, 'offset', {
      enumerable: true,
      get: function () {
        if (!Buffer.isBuffer(this)) return undefined
        return this.byteOffset
      }
    })
    
    function createBuffer (length) {
      if (length > K_MAX_LENGTH) {
        throw new RangeError('The value "' + length + '" is invalid for option "size"')
      }
      // Return an augmented `Uint8Array` instance
      const buf = new Uint8Array(length)
      Object.setPrototypeOf(buf, Buffer.prototype)
      return buf
    }
    
    /**
     * The Buffer constructor returns instances of `Uint8Array` that have their
     * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
     * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
     * and the `Uint8Array` methods. Square bracket notation works as expected -- it
     * returns a single octet.
     *
     * The `Uint8Array` prototype remains unmodified.
     */
    
    function Buffer (arg, encodingOrOffset, length) {
      // Common case.
      if (typeof arg === 'number') {
        if (typeof encodingOrOffset === 'string') {
          throw new TypeError(
            'The "string" argument must be of type string. Received type number'
          )
        }
        return allocUnsafe(arg)
      }
      return from(arg, encodingOrOffset, length)
    }
    
    Buffer.poolSize = 8192 // not used by this implementation
    
    function from (value, encodingOrOffset, length) {
      if (typeof value === 'string') {
        return fromString(value, encodingOrOffset)
      }
    
      if (ArrayBuffer.isView(value)) {
        return fromArrayView(value)
      }
    
      if (value == null) {
        throw new TypeError(
          'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
          'or Array-like Object. Received type ' + (typeof value)
        )
      }
    
      if (isInstance(value, ArrayBuffer) ||
          (value && isInstance(value.buffer, ArrayBuffer))) {
        return fromArrayBuffer(value, encodingOrOffset, length)
      }
    
      if (typeof SharedArrayBuffer !== 'undefined' &&
          (isInstance(value, SharedArrayBuffer) ||
          (value && isInstance(value.buffer, SharedArrayBuffer)))) {
        return fromArrayBuffer(value, encodingOrOffset, length)
      }
    
      if (typeof value === 'number') {
        throw new TypeError(
          'The "value" argument must not be of type number. Received type number'
        )
      }
    
      const valueOf = value.valueOf && value.valueOf()
      if (valueOf != null && valueOf !== value) {
        return Buffer.from(valueOf, encodingOrOffset, length)
      }
    
      const b = fromObject(value)
      if (b) return b
    
      if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
          typeof value[Symbol.toPrimitive] === 'function') {
        return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length)
      }
    
      throw new TypeError(
        'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
        'or Array-like Object. Received type ' + (typeof value)
      )
    }
    
    /**
     * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
     * if value is a number.
     * Buffer.from(str[, encoding])
     * Buffer.from(array)
     * Buffer.from(buffer)
     * Buffer.from(arrayBuffer[, byteOffset[, length]])
     **/
    Buffer.from = function (value, encodingOrOffset, length) {
      return from(value, encodingOrOffset, length)
    }
    
    // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
    // https://github.com/feross/buffer/pull/148
    Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype)
    Object.setPrototypeOf(Buffer, Uint8Array)
    
    function assertSize (size) {
      if (typeof size !== 'number') {
        throw new TypeError('"size" argument must be of type number')
      } else if (size < 0) {
        throw new RangeError('The value "' + size + '" is invalid for option "size"')
      }
    }
    
    function alloc (size, fill, encoding) {
      assertSize(size)
      if (size <= 0) {
        return createBuffer(size)
      }
      if (fill !== undefined) {
        // Only pay attention to encoding if it's a string. This
        // prevents accidentally sending in a number that would
        // be interpreted as a start offset.
        return typeof encoding === 'string'
          ? createBuffer(size).fill(fill, encoding)
          : createBuffer(size).fill(fill)
      }
      return createBuffer(size)
    }
    
    /**
     * Creates a new filled Buffer instance.
     * alloc(size[, fill[, encoding]])
     **/
    Buffer.alloc = function (size, fill, encoding) {
      return alloc(size, fill, encoding)
    }
    
    function allocUnsafe (size) {
      assertSize(size)
      return createBuffer(size < 0 ? 0 : checked(size) | 0)
    }
    
    /**
     * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
     * */
    Buffer.allocUnsafe = function (size) {
      return allocUnsafe(size)
    }
    /**
     * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
     */
    Buffer.allocUnsafeSlow = function (size) {
      return allocUnsafe(size)
    }
    
    function fromString (string, encoding) {
      if (typeof encoding !== 'string' || encoding === '') {
        encoding = 'utf8'
      }
    
      if (!Buffer.isEncoding(encoding)) {
        throw new TypeError('Unknown encoding: ' + encoding)
      }
    
      const length = byteLength(string, encoding) | 0
      let buf = createBuffer(length)
    
      const actual = buf.write(string, encoding)
    
      if (actual !== length) {
        // Writing a hex string, for example, that contains invalid characters will
        // cause everything after the first invalid character to be ignored. (e.g.
        // 'abxxcd' will be treated as 'ab')
        buf = buf.slice(0, actual)
      }
    
      return buf
    }
    
    function fromArrayLike (array) {
      const length = array.length < 0 ? 0 : checked(array.length) | 0
      const buf = createBuffer(length)
      for (let i = 0; i < length; i += 1) {
        buf[i] = array[i] & 255
      }
      return buf
    }
    
    function fromArrayView (arrayView) {
      if (isInstance(arrayView, Uint8Array)) {
        const copy = new Uint8Array(arrayView)
        return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength)
      }
      return fromArrayLike(arrayView)
    }
    
    function fromArrayBuffer (array, byteOffset, length) {
      if (byteOffset < 0 || array.byteLength < byteOffset) {
        throw new RangeError('"offset" is outside of buffer bounds')
      }
    
      if (array.byteLength < byteOffset + (length || 0)) {
        throw new RangeError('"length" is outside of buffer bounds')
      }
    
      let buf
      if (byteOffset === undefined && length === undefined) {
        buf = new Uint8Array(array)
      } else if (length === undefined) {
        buf = new Uint8Array(array, byteOffset)
      } else {
        buf = new Uint8Array(array, byteOffset, length)
      }
    
      // Return an augmented `Uint8Array` instance
      Object.setPrototypeOf(buf, Buffer.prototype)
    
      return buf
    }
    
    function fromObject (obj) {
      if (Buffer.isBuffer(obj)) {
        const len = checked(obj.length) | 0
        const buf = createBuffer(len)
    
        if (buf.length === 0) {
          return buf
        }
    
        obj.copy(buf, 0, 0, len)
        return buf
      }
    
      if (obj.length !== undefined) {
        if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
          return createBuffer(0)
        }
        return fromArrayLike(obj)
      }
    
      if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
        return fromArrayLike(obj.data)
      }
    }
    
    function checked (length) {
      // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
      // length is NaN (which is otherwise coerced to zero.)
      if (length >= K_MAX_LENGTH) {
        throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                             'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
      }
      return length | 0
    }
    
    function SlowBuffer (length) {
      if (+length != length) { // eslint-disable-line eqeqeq
        length = 0
      }
      return Buffer.alloc(+length)
    }
    
    Buffer.isBuffer = function isBuffer (b) {
      return b != null && b._isBuffer === true &&
        b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
    }
    
    Buffer.compare = function compare (a, b) {
      if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
      if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
      if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
        throw new TypeError(
          'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
        )
      }
    
      if (a === b) return 0
    
      let x = a.length
      let y = b.length
    
      for (let i = 0, len = Math.min(x, y); i < len; ++i) {
        if (a[i] !== b[i]) {
          x = a[i]
          y = b[i]
          break
        }
      }
    
      if (x < y) return -1
      if (y < x) return 1
      return 0
    }
    
    Buffer.isEncoding = function isEncoding (encoding) {
      switch (String(encoding).toLowerCase()) {
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'latin1':
        case 'binary':
        case 'base64':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return true
        default:
          return false
      }
    }
    
    Buffer.concat = function concat (list, length) {
      if (!Array.isArray(list)) {
        throw new TypeError('"list" argument must be an Array of Buffers')
      }
    
      if (list.length === 0) {
        return Buffer.alloc(0)
      }
    
      let i
      if (length === undefined) {
        length = 0
        for (i = 0; i < list.length; ++i) {
          length += list[i].length
        }
      }
    
      const buffer = Buffer.allocUnsafe(length)
      let pos = 0
      for (i = 0; i < list.length; ++i) {
        let buf = list[i]
        if (isInstance(buf, Uint8Array)) {
          if (pos + buf.length > buffer.length) {
            if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)
            buf.copy(buffer, pos)
          } else {
            Uint8Array.prototype.set.call(
              buffer,
              buf,
              pos
            )
          }
        } else if (!Buffer.isBuffer(buf)) {
          throw new TypeError('"list" argument must be an Array of Buffers')
        } else {
          buf.copy(buffer, pos)
        }
        pos += buf.length
      }
      return buffer
    }
    
    function byteLength (string, encoding) {
      if (Buffer.isBuffer(string)) {
        return string.length
      }
      if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
        return string.byteLength
      }
      if (typeof string !== 'string') {
        throw new TypeError(
          'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
          'Received type ' + typeof string
        )
      }
    
      const len = string.length
      const mustMatch = (arguments.length > 2 && arguments[2] === true)
      if (!mustMatch && len === 0) return 0
    
      // Use a for loop to avoid recursion
      let loweredCase = false
      for (;;) {
        switch (encoding) {
          case 'ascii':
          case 'latin1':
          case 'binary':
            return len
          case 'utf8':
          case 'utf-8':
            return utf8ToBytes(string).length
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return len * 2
          case 'hex':
            return len >>> 1
          case 'base64':
            return base64ToBytes(string).length
          default:
            if (loweredCase) {
              return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
            }
            encoding = ('' + encoding).toLowerCase()
            loweredCase = true
        }
      }
    }
    Buffer.byteLength = byteLength
    
    function slowToString (encoding, start, end) {
      let loweredCase = false
    
      // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
      // property of a typed array.
    
      // This behaves neither like String nor Uint8Array in that we set start/end
      // to their upper/lower bounds if the value passed is out of range.
      // undefined is handled specially as per ECMA-262 6th Edition,
      // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
      if (start === undefined || start < 0) {
        start = 0
      }
      // Return early if start > this.length. Done here to prevent potential uint32
      // coercion fail below.
      if (start > this.length) {
        return ''
      }
    
      if (end === undefined || end > this.length) {
        end = this.length
      }
    
      if (end <= 0) {
        return ''
      }
    
      // Force coercion to uint32. This will also coerce falsey/NaN values to 0.
      end >>>= 0
      start >>>= 0
    
      if (end <= start) {
        return ''
      }
    
      if (!encoding) encoding = 'utf8'
    
      while (true) {
        switch (encoding) {
          case 'hex':
            return hexSlice(this, start, end)
    
          case 'utf8':
          case 'utf-8':
            return utf8Slice(this, start, end)
    
          case 'ascii':
            return asciiSlice(this, start, end)
    
          case 'latin1':
          case 'binary':
            return latin1Slice(this, start, end)
    
          case 'base64':
            return base64Slice(this, start, end)
    
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return utf16leSlice(this, start, end)
    
          default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
            encoding = (encoding + '').toLowerCase()
            loweredCase = true
        }
      }
    }
    
    // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
    // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
    // reliably in a browserify context because there could be multiple different
    // copies of the 'buffer' package in use. This method works even for Buffer
    // instances that were created from another copy of the `buffer` package.
    // See: https://github.com/feross/buffer/issues/154
    Buffer.prototype._isBuffer = true
    
    function swap (b, n, m) {
      const i = b[n]
      b[n] = b[m]
      b[m] = i
    }
    
    Buffer.prototype.swap16 = function swap16 () {
      const len = this.length
      if (len % 2 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 16-bits')
      }
      for (let i = 0; i < len; i += 2) {
        swap(this, i, i + 1)
      }
      return this
    }
    
    Buffer.prototype.swap32 = function swap32 () {
      const len = this.length
      if (len % 4 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 32-bits')
      }
      for (let i = 0; i < len; i += 4) {
        swap(this, i, i + 3)
        swap(this, i + 1, i + 2)
      }
      return this
    }
    
    Buffer.prototype.swap64 = function swap64 () {
      const len = this.length
      if (len % 8 !== 0) {
        throw new RangeError('Buffer size must be a multiple of 64-bits')
      }
      for (let i = 0; i < len; i += 8) {
        swap(this, i, i + 7)
        swap(this, i + 1, i + 6)
        swap(this, i + 2, i + 5)
        swap(this, i + 3, i + 4)
      }
      return this
    }
    
    Buffer.prototype.toString = function toString () {
      const length = this.length
      if (length === 0) return ''
      if (arguments.length === 0) return utf8Slice(this, 0, length)
      return slowToString.apply(this, arguments)
    }
    
    Buffer.prototype.toLocaleString = Buffer.prototype.toString
    
    Buffer.prototype.equals = function equals (b) {
      if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
      if (this === b) return true
      return Buffer.compare(this, b) === 0
    }
    
    Buffer.prototype.inspect = function inspect () {
      let str = ''
      const max = exports.INSPECT_MAX_BYTES
      str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
      if (this.length > max) str += ' ... '
      return '<Buffer ' + str + '>'
    }
    if (customInspectSymbol) {
      Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect
    }
    
    Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
      if (isInstance(target, Uint8Array)) {
        target = Buffer.from(target, target.offset, target.byteLength)
      }
      if (!Buffer.isBuffer(target)) {
        throw new TypeError(
          'The "target" argument must be one of type Buffer or Uint8Array. ' +
          'Received type ' + (typeof target)
        )
      }
    
      if (start === undefined) {
        start = 0
      }
      if (end === undefined) {
        end = target ? target.length : 0
      }
      if (thisStart === undefined) {
        thisStart = 0
      }
      if (thisEnd === undefined) {
        thisEnd = this.length
      }
    
      if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
        throw new RangeError('out of range index')
      }
    
      if (thisStart >= thisEnd && start >= end) {
        return 0
      }
      if (thisStart >= thisEnd) {
        return -1
      }
      if (start >= end) {
        return 1
      }
    
      start >>>= 0
      end >>>= 0
      thisStart >>>= 0
      thisEnd >>>= 0
    
      if (this === target) return 0
    
      let x = thisEnd - thisStart
      let y = end - start
      const len = Math.min(x, y)
    
      const thisCopy = this.slice(thisStart, thisEnd)
      const targetCopy = target.slice(start, end)
    
      for (let i = 0; i < len; ++i) {
        if (thisCopy[i] !== targetCopy[i]) {
          x = thisCopy[i]
          y = targetCopy[i]
          break
        }
      }
    
      if (x < y) return -1
      if (y < x) return 1
      return 0
    }
    
    // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
    // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
    //
    // Arguments:
    // - buffer - a Buffer to search
    // - val - a string, Buffer, or number
    // - byteOffset - an index into `buffer`; will be clamped to an int32
    // - encoding - an optional encoding, relevant is val is a string
    // - dir - true for indexOf, false for lastIndexOf
    function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
      // Empty buffer means no match
      if (buffer.length === 0) return -1
    
      // Normalize byteOffset
      if (typeof byteOffset === 'string') {
        encoding = byteOffset
        byteOffset = 0
      } else if (byteOffset > 0x7fffffff) {
        byteOffset = 0x7fffffff
      } else if (byteOffset < -0x80000000) {
        byteOffset = -0x80000000
      }
      byteOffset = +byteOffset // Coerce to Number.
      if (numberIsNaN(byteOffset)) {
        // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
        byteOffset = dir ? 0 : (buffer.length - 1)
      }
    
      // Normalize byteOffset: negative offsets start from the end of the buffer
      if (byteOffset < 0) byteOffset = buffer.length + byteOffset
      if (byteOffset >= buffer.length) {
        if (dir) return -1
        else byteOffset = buffer.length - 1
      } else if (byteOffset < 0) {
        if (dir) byteOffset = 0
        else return -1
      }
    
      // Normalize val
      if (typeof val === 'string') {
        val = Buffer.from(val, encoding)
      }
    
      // Finally, search either indexOf (if dir is true) or lastIndexOf
      if (Buffer.isBuffer(val)) {
        // Special case: looking for empty string/buffer always fails
        if (val.length === 0) {
          return -1
        }
        return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
      } else if (typeof val === 'number') {
        val = val & 0xFF // Search for a byte value [0-255]
        if (typeof Uint8Array.prototype.indexOf === 'function') {
          if (dir) {
            return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
          } else {
            return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
          }
        }
        return arrayIndexOf(buffer, [val], byteOffset, encoding, dir)
      }
    
      throw new TypeError('val must be string, number or Buffer')
    }
    
    function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
      let indexSize = 1
      let arrLength = arr.length
      let valLength = val.length
    
      if (encoding !== undefined) {
        encoding = String(encoding).toLowerCase()
        if (encoding === 'ucs2' || encoding === 'ucs-2' ||
            encoding === 'utf16le' || encoding === 'utf-16le') {
          if (arr.length < 2 || val.length < 2) {
            return -1
          }
          indexSize = 2
          arrLength /= 2
          valLength /= 2
          byteOffset /= 2
        }
      }
    
      function read (buf, i) {
        if (indexSize === 1) {
          return buf[i]
        } else {
          return buf.readUInt16BE(i * indexSize)
        }
      }
    
      let i
      if (dir) {
        let foundIndex = -1
        for (i = byteOffset; i < arrLength; i++) {
          if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
            if (foundIndex === -1) foundIndex = i
            if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
          } else {
            if (foundIndex !== -1) i -= i - foundIndex
            foundIndex = -1
          }
        }
      } else {
        if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
        for (i = byteOffset; i >= 0; i--) {
          let found = true
          for (let j = 0; j < valLength; j++) {
            if (read(arr, i + j) !== read(val, j)) {
              found = false
              break
            }
          }
          if (found) return i
        }
      }
    
      return -1
    }
    
    Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
      return this.indexOf(val, byteOffset, encoding) !== -1
    }
    
    Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
      return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
    }
    
    Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
      return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
    }
    
    function hexWrite (buf, string, offset, length) {
      offset = Number(offset) || 0
      const remaining = buf.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
    
      const strLen = string.length
    
      if (length > strLen / 2) {
        length = strLen / 2
      }
      let i
      for (i = 0; i < length; ++i) {
        const parsed = parseInt(string.substr(i * 2, 2), 16)
        if (numberIsNaN(parsed)) return i
        buf[offset + i] = parsed
      }
      return i
    }
    
    function utf8Write (buf, string, offset, length) {
      return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
    }
    
    function asciiWrite (buf, string, offset, length) {
      return blitBuffer(asciiToBytes(string), buf, offset, length)
    }
    
    function base64Write (buf, string, offset, length) {
      return blitBuffer(base64ToBytes(string), buf, offset, length)
    }
    
    function ucs2Write (buf, string, offset, length) {
      return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
    }
    
    Buffer.prototype.write = function write (string, offset, length, encoding) {
      // Buffer#write(string)
      if (offset === undefined) {
        encoding = 'utf8'
        length = this.length
        offset = 0
      // Buffer#write(string, encoding)
      } else if (length === undefined && typeof offset === 'string') {
        encoding = offset
        length = this.length
        offset = 0
      // Buffer#write(string, offset[, length][, encoding])
      } else if (isFinite(offset)) {
        offset = offset >>> 0
        if (isFinite(length)) {
          length = length >>> 0
          if (encoding === undefined) encoding = 'utf8'
        } else {
          encoding = length
          length = undefined
        }
      } else {
        throw new Error(
          'Buffer.write(string, encoding, offset[, length]) is no longer supported'
        )
      }
    
      const remaining = this.length - offset
      if (length === undefined || length > remaining) length = remaining
    
      if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
        throw new RangeError('Attempt to write outside buffer bounds')
      }
    
      if (!encoding) encoding = 'utf8'
    
      let loweredCase = false
      for (;;) {
        switch (encoding) {
          case 'hex':
            return hexWrite(this, string, offset, length)
    
          case 'utf8':
          case 'utf-8':
            return utf8Write(this, string, offset, length)
    
          case 'ascii':
          case 'latin1':
          case 'binary':
            return asciiWrite(this, string, offset, length)
    
          case 'base64':
            // Warning: maxLength not taken into account in base64Write
            return base64Write(this, string, offset, length)
    
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return ucs2Write(this, string, offset, length)
    
          default:
            if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
            encoding = ('' + encoding).toLowerCase()
            loweredCase = true
        }
      }
    }
    
    Buffer.prototype.toJSON = function toJSON () {
      return {
        type: 'Buffer',
        data: Array.prototype.slice.call(this._arr || this, 0)
      }
    }
    
    function base64Slice (buf, start, end) {
      if (start === 0 && end === buf.length) {
        return base64.fromByteArray(buf)
      } else {
        return base64.fromByteArray(buf.slice(start, end))
      }
    }
    
    function utf8Slice (buf, start, end) {
      end = Math.min(buf.length, end)
      const res = []
    
      let i = start
      while (i < end) {
        const firstByte = buf[i]
        let codePoint = null
        let bytesPerSequence = (firstByte > 0xEF)
          ? 4
          : (firstByte > 0xDF)
              ? 3
              : (firstByte > 0xBF)
                  ? 2
                  : 1
    
        if (i + bytesPerSequence <= end) {
          let secondByte, thirdByte, fourthByte, tempCodePoint
    
          switch (bytesPerSequence) {
            case 1:
              if (firstByte < 0x80) {
                codePoint = firstByte
              }
              break
            case 2:
              secondByte = buf[i + 1]
              if ((secondByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
                if (tempCodePoint > 0x7F) {
                  codePoint = tempCodePoint
                }
              }
              break
            case 3:
              secondByte = buf[i + 1]
              thirdByte = buf[i + 2]
              if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
                if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                  codePoint = tempCodePoint
                }
              }
              break
            case 4:
              secondByte = buf[i + 1]
              thirdByte = buf[i + 2]
              fourthByte = buf[i + 3]
              if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
                tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
                if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                  codePoint = tempCodePoint
                }
              }
          }
        }
    
        if (codePoint === null) {
          // we did not generate a valid codePoint so insert a
          // replacement char (U+FFFD) and advance only 1 byte
          codePoint = 0xFFFD
          bytesPerSequence = 1
        } else if (codePoint > 0xFFFF) {
          // encode to utf16 (surrogate pair dance)
          codePoint -= 0x10000
          res.push(codePoint >>> 10 & 0x3FF | 0xD800)
          codePoint = 0xDC00 | codePoint & 0x3FF
        }
    
        res.push(codePoint)
        i += bytesPerSequence
      }
    
      return decodeCodePointsArray(res)
    }
    
    // Based on http://stackoverflow.com/a/22747272/680742, the browser with
    // the lowest limit is Chrome, with 0x10000 args.
    // We go 1 magnitude less, for safety
    const MAX_ARGUMENTS_LENGTH = 0x1000
    
    function decodeCodePointsArray (codePoints) {
      const len = codePoints.length
      if (len <= MAX_ARGUMENTS_LENGTH) {
        return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
      }
    
      // Decode in chunks to avoid "call stack size exceeded".
      let res = ''
      let i = 0
      while (i < len) {
        res += String.fromCharCode.apply(
          String,
          codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
        )
      }
      return res
    }
    
    function asciiSlice (buf, start, end) {
      let ret = ''
      end = Math.min(buf.length, end)
    
      for (let i = start; i < end; ++i) {
        ret += String.fromCharCode(buf[i] & 0x7F)
      }
      return ret
    }
    
    function latin1Slice (buf, start, end) {
      let ret = ''
      end = Math.min(buf.length, end)
    
      for (let i = start; i < end; ++i) {
        ret += String.fromCharCode(buf[i])
      }
      return ret
    }
    
    function hexSlice (buf, start, end) {
      const len = buf.length
    
      if (!start || start < 0) start = 0
      if (!end || end < 0 || end > len) end = len
    
      let out = ''
      for (let i = start; i < end; ++i) {
        out += hexSliceLookupTable[buf[i]]
      }
      return out
    }
    
    function utf16leSlice (buf, start, end) {
      const bytes = buf.slice(start, end)
      let res = ''
      // If bytes.length is odd, the last 8 bits must be ignored (same as node.js)
      for (let i = 0; i < bytes.length - 1; i += 2) {
        res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
      }
      return res
    }
    
    Buffer.prototype.slice = function slice (start, end) {
      const len = this.length
      start = ~~start
      end = end === undefined ? len : ~~end
    
      if (start < 0) {
        start += len
        if (start < 0) start = 0
      } else if (start > len) {
        start = len
      }
    
      if (end < 0) {
        end += len
        if (end < 0) end = 0
      } else if (end > len) {
        end = len
      }
    
      if (end < start) end = start
    
      const newBuf = this.subarray(start, end)
      // Return an augmented `Uint8Array` instance
      Object.setPrototypeOf(newBuf, Buffer.prototype)
    
      return newBuf
    }
    
    /*
     * Need to make sure that buffer isn't trying to write out of bounds.
     */
    function checkOffset (offset, ext, length) {
      if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
      if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
    }
    
    Buffer.prototype.readUintLE =
    Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      let val = this[offset]
      let mul = 1
      let i = 0
      while (++i < byteLength && (mul *= 0x100)) {
        val += this[offset + i] * mul
      }
    
      return val
    }
    
    Buffer.prototype.readUintBE =
    Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        checkOffset(offset, byteLength, this.length)
      }
    
      let val = this[offset + --byteLength]
      let mul = 1
      while (byteLength > 0 && (mul *= 0x100)) {
        val += this[offset + --byteLength] * mul
      }
    
      return val
    }
    
    Buffer.prototype.readUint8 =
    Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 1, this.length)
      return this[offset]
    }
    
    Buffer.prototype.readUint16LE =
    Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      return this[offset] | (this[offset + 1] << 8)
    }
    
    Buffer.prototype.readUint16BE =
    Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      return (this[offset] << 8) | this[offset + 1]
    }
    
    Buffer.prototype.readUint32LE =
    Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return ((this[offset]) |
          (this[offset + 1] << 8) |
          (this[offset + 2] << 16)) +
          (this[offset + 3] * 0x1000000)
    }
    
    Buffer.prototype.readUint32BE =
    Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset] * 0x1000000) +
        ((this[offset + 1] << 16) |
        (this[offset + 2] << 8) |
        this[offset + 3])
    }
    
    Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE (offset) {
      offset = offset >>> 0
      validateNumber(offset, 'offset')
      const first = this[offset]
      const last = this[offset + 7]
      if (first === undefined || last === undefined) {
        boundsError(offset, this.length - 8)
      }
    
      const lo = first +
        this[++offset] * 2 ** 8 +
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 24
    
      const hi = this[++offset] +
        this[++offset] * 2 ** 8 +
        this[++offset] * 2 ** 16 +
        last * 2 ** 24
    
      return BigInt(lo) + (BigInt(hi) << BigInt(32))
    })
    
    Buffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE (offset) {
      offset = offset >>> 0
      validateNumber(offset, 'offset')
      const first = this[offset]
      const last = this[offset + 7]
      if (first === undefined || last === undefined) {
        boundsError(offset, this.length - 8)
      }
    
      const hi = first * 2 ** 24 +
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 8 +
        this[++offset]
    
      const lo = this[++offset] * 2 ** 24 +
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 8 +
        last
    
      return (BigInt(hi) << BigInt(32)) + BigInt(lo)
    })
    
    Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      let val = this[offset]
      let mul = 1
      let i = 0
      while (++i < byteLength && (mul *= 0x100)) {
        val += this[offset + i] * mul
      }
      mul *= 0x80
    
      if (val >= mul) val -= Math.pow(2, 8 * byteLength)
    
      return val
    }
    
    Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) checkOffset(offset, byteLength, this.length)
    
      let i = byteLength
      let mul = 1
      let val = this[offset + --i]
      while (i > 0 && (mul *= 0x100)) {
        val += this[offset + --i] * mul
      }
      mul *= 0x80
    
      if (val >= mul) val -= Math.pow(2, 8 * byteLength)
    
      return val
    }
    
    Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 1, this.length)
      if (!(this[offset] & 0x80)) return (this[offset])
      return ((0xff - this[offset] + 1) * -1)
    }
    
    Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      const val = this[offset] | (this[offset + 1] << 8)
      return (val & 0x8000) ? val | 0xFFFF0000 : val
    }
    
    Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 2, this.length)
      const val = this[offset + 1] | (this[offset] << 8)
      return (val & 0x8000) ? val | 0xFFFF0000 : val
    }
    
    Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset]) |
        (this[offset + 1] << 8) |
        (this[offset + 2] << 16) |
        (this[offset + 3] << 24)
    }
    
    Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
    
      return (this[offset] << 24) |
        (this[offset + 1] << 16) |
        (this[offset + 2] << 8) |
        (this[offset + 3])
    }
    
    Buffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE (offset) {
      offset = offset >>> 0
      validateNumber(offset, 'offset')
      const first = this[offset]
      const last = this[offset + 7]
      if (first === undefined || last === undefined) {
        boundsError(offset, this.length - 8)
      }
    
      const val = this[offset + 4] +
        this[offset + 5] * 2 ** 8 +
        this[offset + 6] * 2 ** 16 +
        (last << 24) // Overflow
    
      return (BigInt(val) << BigInt(32)) +
        BigInt(first +
        this[++offset] * 2 ** 8 +
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 24)
    })
    
    Buffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE (offset) {
      offset = offset >>> 0
      validateNumber(offset, 'offset')
      const first = this[offset]
      const last = this[offset + 7]
      if (first === undefined || last === undefined) {
        boundsError(offset, this.length - 8)
      }
    
      const val = (first << 24) + // Overflow
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 8 +
        this[++offset]
    
      return (BigInt(val) << BigInt(32)) +
        BigInt(this[++offset] * 2 ** 24 +
        this[++offset] * 2 ** 16 +
        this[++offset] * 2 ** 8 +
        last)
    })
    
    Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
      return ieee754.read(this, offset, true, 23, 4)
    }
    
    Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 4, this.length)
      return ieee754.read(this, offset, false, 23, 4)
    }
    
    Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 8, this.length)
      return ieee754.read(this, offset, true, 52, 8)
    }
    
    Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
      offset = offset >>> 0
      if (!noAssert) checkOffset(offset, 8, this.length)
      return ieee754.read(this, offset, false, 52, 8)
    }
    
    function checkInt (buf, value, offset, ext, max, min) {
      if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
      if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
      if (offset + ext > buf.length) throw new RangeError('Index out of range')
    }
    
    Buffer.prototype.writeUintLE =
    Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        const maxBytes = Math.pow(2, 8 * byteLength) - 1
        checkInt(this, value, offset, byteLength, maxBytes, 0)
      }
    
      let mul = 1
      let i = 0
      this[offset] = value & 0xFF
      while (++i < byteLength && (mul *= 0x100)) {
        this[offset + i] = (value / mul) & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeUintBE =
    Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      byteLength = byteLength >>> 0
      if (!noAssert) {
        const maxBytes = Math.pow(2, 8 * byteLength) - 1
        checkInt(this, value, offset, byteLength, maxBytes, 0)
      }
    
      let i = byteLength - 1
      let mul = 1
      this[offset + i] = value & 0xFF
      while (--i >= 0 && (mul *= 0x100)) {
        this[offset + i] = (value / mul) & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeUint8 =
    Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
      this[offset] = (value & 0xff)
      return offset + 1
    }
    
    Buffer.prototype.writeUint16LE =
    Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      return offset + 2
    }
    
    Buffer.prototype.writeUint16BE =
    Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
      return offset + 2
    }
    
    Buffer.prototype.writeUint32LE =
    Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
      this[offset + 3] = (value >>> 24)
      this[offset + 2] = (value >>> 16)
      this[offset + 1] = (value >>> 8)
      this[offset] = (value & 0xff)
      return offset + 4
    }
    
    Buffer.prototype.writeUint32BE =
    Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
      return offset + 4
    }
    
    function wrtBigUInt64LE (buf, value, offset, min, max) {
      checkIntBI(value, min, max, buf, offset, 7)
    
      let lo = Number(value & BigInt(0xffffffff))
      buf[offset++] = lo
      lo = lo >> 8
      buf[offset++] = lo
      lo = lo >> 8
      buf[offset++] = lo
      lo = lo >> 8
      buf[offset++] = lo
      let hi = Number(value >> BigInt(32) & BigInt(0xffffffff))
      buf[offset++] = hi
      hi = hi >> 8
      buf[offset++] = hi
      hi = hi >> 8
      buf[offset++] = hi
      hi = hi >> 8
      buf[offset++] = hi
      return offset
    }
    
    function wrtBigUInt64BE (buf, value, offset, min, max) {
      checkIntBI(value, min, max, buf, offset, 7)
    
      let lo = Number(value & BigInt(0xffffffff))
      buf[offset + 7] = lo
      lo = lo >> 8
      buf[offset + 6] = lo
      lo = lo >> 8
      buf[offset + 5] = lo
      lo = lo >> 8
      buf[offset + 4] = lo
      let hi = Number(value >> BigInt(32) & BigInt(0xffffffff))
      buf[offset + 3] = hi
      hi = hi >> 8
      buf[offset + 2] = hi
      hi = hi >> 8
      buf[offset + 1] = hi
      hi = hi >> 8
      buf[offset] = hi
      return offset + 8
    }
    
    Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE (value, offset = 0) {
      return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'))
    })
    
    Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE (value, offset = 0) {
      return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff'))
    })
    
    Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        const limit = Math.pow(2, (8 * byteLength) - 1)
    
        checkInt(this, value, offset, byteLength, limit - 1, -limit)
      }
    
      let i = 0
      let mul = 1
      let sub = 0
      this[offset] = value & 0xFF
      while (++i < byteLength && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
          sub = 1
        }
        this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        const limit = Math.pow(2, (8 * byteLength) - 1)
    
        checkInt(this, value, offset, byteLength, limit - 1, -limit)
      }
    
      let i = byteLength - 1
      let mul = 1
      let sub = 0
      this[offset + i] = value & 0xFF
      while (--i >= 0 && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
          sub = 1
        }
        this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
      }
    
      return offset + byteLength
    }
    
    Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
      if (value < 0) value = 0xff + value + 1
      this[offset] = (value & 0xff)
      return offset + 1
    }
    
    Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      return offset + 2
    }
    
    Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
      return offset + 2
    }
    
    Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      this[offset + 2] = (value >>> 16)
      this[offset + 3] = (value >>> 24)
      return offset + 4
    }
    
    Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
      if (value < 0) value = 0xffffffff + value + 1
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
      return offset + 4
    }
    
    Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE (value, offset = 0) {
      return wrtBigUInt64LE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'))
    })
    
    Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE (value, offset = 0) {
      return wrtBigUInt64BE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff'))
    })
    
    function checkIEEE754 (buf, value, offset, ext, max, min) {
      if (offset + ext > buf.length) throw new RangeError('Index out of range')
      if (offset < 0) throw new RangeError('Index out of range')
    }
    
    function writeFloat (buf, value, offset, littleEndian, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
      }
      ieee754.write(buf, value, offset, littleEndian, 23, 4)
      return offset + 4
    }
    
    Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
      return writeFloat(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
      return writeFloat(this, value, offset, false, noAssert)
    }
    
    function writeDouble (buf, value, offset, littleEndian, noAssert) {
      value = +value
      offset = offset >>> 0
      if (!noAssert) {
        checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
      }
      ieee754.write(buf, value, offset, littleEndian, 52, 8)
      return offset + 8
    }
    
    Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
      return writeDouble(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
      return writeDouble(this, value, offset, false, noAssert)
    }
    
    // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
    Buffer.prototype.copy = function copy (target, targetStart, start, end) {
      if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
      if (!start) start = 0
      if (!end && end !== 0) end = this.length
      if (targetStart >= target.length) targetStart = target.length
      if (!targetStart) targetStart = 0
      if (end > 0 && end < start) end = start
    
      // Copy 0 bytes; we're done
      if (end === start) return 0
      if (target.length === 0 || this.length === 0) return 0
    
      // Fatal error conditions
      if (targetStart < 0) {
        throw new RangeError('targetStart out of bounds')
      }
      if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
      if (end < 0) throw new RangeError('sourceEnd out of bounds')
    
      // Are we oob?
      if (end > this.length) end = this.length
      if (target.length - targetStart < end - start) {
        end = target.length - targetStart + start
      }
    
      const len = end - start
    
      if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
        // Use built-in when available, missing from IE11
        this.copyWithin(targetStart, start, end)
      } else {
        Uint8Array.prototype.set.call(
          target,
          this.subarray(start, end),
          targetStart
        )
      }
    
      return len
    }
    
    // Usage:
    //    buffer.fill(number[, offset[, end]])
    //    buffer.fill(buffer[, offset[, end]])
    //    buffer.fill(string[, offset[, end]][, encoding])
    Buffer.prototype.fill = function fill (val, start, end, encoding) {
      // Handle string cases:
      if (typeof val === 'string') {
        if (typeof start === 'string') {
          encoding = start
          start = 0
          end = this.length
        } else if (typeof end === 'string') {
          encoding = end
          end = this.length
        }
        if (encoding !== undefined && typeof encoding !== 'string') {
          throw new TypeError('encoding must be a string')
        }
        if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
          throw new TypeError('Unknown encoding: ' + encoding)
        }
        if (val.length === 1) {
          const code = val.charCodeAt(0)
          if ((encoding === 'utf8' && code < 128) ||
              encoding === 'latin1') {
            // Fast path: If `val` fits into a single byte, use that numeric value.
            val = code
          }
        }
      } else if (typeof val === 'number') {
        val = val & 255
      } else if (typeof val === 'boolean') {
        val = Number(val)
      }
    
      // Invalid ranges are not set to a default, so can range check early.
      if (start < 0 || this.length < start || this.length < end) {
        throw new RangeError('Out of range index')
      }
    
      if (end <= start) {
        return this
      }
    
      start = start >>> 0
      end = end === undefined ? this.length : end >>> 0
    
      if (!val) val = 0
    
      let i
      if (typeof val === 'number') {
        for (i = start; i < end; ++i) {
          this[i] = val
        }
      } else {
        const bytes = Buffer.isBuffer(val)
          ? val
          : Buffer.from(val, encoding)
        const len = bytes.length
        if (len === 0) {
          throw new TypeError('The value "' + val +
            '" is invalid for argument "value"')
        }
        for (i = 0; i < end - start; ++i) {
          this[i + start] = bytes[i % len]
        }
      }
    
      return this
    }
    
    // CUSTOM ERRORS
    // =============
    
    // Simplified versions from Node, changed for Buffer-only usage
    const errors = {}
    function E (sym, getMessage, Base) {
      errors[sym] = class NodeError extends Base {
        constructor () {
          super()
    
          Object.defineProperty(this, 'message', {
            value: getMessage.apply(this, arguments),
            writable: true,
            configurable: true
          })
    
          // Add the error code to the name to include it in the stack trace.
          this.name = `${this.name} [${sym}]`
          // Access the stack to generate the error message including the error code
          // from the name.
          this.stack // eslint-disable-line no-unused-expressions
          // Reset the name to the actual name.
          delete this.name
        }
    
        get code () {
          return sym
        }
    
        set code (value) {
          Object.defineProperty(this, 'code', {
            configurable: true,
            enumerable: true,
            value,
            writable: true
          })
        }
    
        toString () {
          return `${this.name} [${sym}]: ${this.message}`
        }
      }
    }
    
    E('ERR_BUFFER_OUT_OF_BOUNDS',
      function (name) {
        if (name) {
          return `${name} is outside of buffer bounds`
        }
    
        return 'Attempt to access memory outside buffer bounds'
      }, RangeError)
    E('ERR_INVALID_ARG_TYPE',
      function (name, actual) {
        return `The "${name}" argument must be of type number. Received type ${typeof actual}`
      }, TypeError)
    E('ERR_OUT_OF_RANGE',
      function (str, range, input) {
        let msg = `The value of "${str}" is out of range.`
        let received = input
        if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
          received = addNumericalSeparator(String(input))
        } else if (typeof input === 'bigint') {
          received = String(input)
          if (input > BigInt(2) ** BigInt(32) || input < -(BigInt(2) ** BigInt(32))) {
            received = addNumericalSeparator(received)
          }
          received += 'n'
        }
        msg += ` It must be ${range}. Received ${received}`
        return msg
      }, RangeError)
    
    function addNumericalSeparator (val) {
      let res = ''
      let i = val.length
      const start = val[0] === '-' ? 1 : 0
      for (; i >= start + 4; i -= 3) {
        res = `_${val.slice(i - 3, i)}${res}`
      }
      return `${val.slice(0, i)}${res}`
    }
    
    // CHECK FUNCTIONS
    // ===============
    
    function checkBounds (buf, offset, byteLength) {
      validateNumber(offset, 'offset')
      if (buf[offset] === undefined || buf[offset + byteLength] === undefined) {
        boundsError(offset, buf.length - (byteLength + 1))
      }
    }
    
    function checkIntBI (value, min, max, buf, offset, byteLength) {
      if (value > max || value < min) {
        const n = typeof min === 'bigint' ? 'n' : ''
        let range
        if (byteLength > 3) {
          if (min === 0 || min === BigInt(0)) {
            range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`
          } else {
            range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` +
                    `${(byteLength + 1) * 8 - 1}${n}`
          }
        } else {
          range = `>= ${min}${n} and <= ${max}${n}`
        }
        throw new errors.ERR_OUT_OF_RANGE('value', range, value)
      }
      checkBounds(buf, offset, byteLength)
    }
    
    function validateNumber (value, name) {
      if (typeof value !== 'number') {
        throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value)
      }
    }
    
    function boundsError (value, length, type) {
      if (Math.floor(value) !== value) {
        validateNumber(value, type)
        throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value)
      }
    
      if (length < 0) {
        throw new errors.ERR_BUFFER_OUT_OF_BOUNDS()
      }
    
      throw new errors.ERR_OUT_OF_RANGE(type || 'offset',
                                        `>= ${type ? 1 : 0} and <= ${length}`,
                                        value)
    }
    
    // HELPER FUNCTIONS
    // ================
    
    const INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
    
    function base64clean (str) {
      // Node takes equal signs as end of the Base64 encoding
      str = str.split('=')[0]
      // Node strips out invalid characters like \n and \t from the string, base64-js does not
      str = str.trim().replace(INVALID_BASE64_RE, '')
      // Node converts strings with length < 2 to ''
      if (str.length < 2) return ''
      // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
      while (str.length % 4 !== 0) {
        str = str + '='
      }
      return str
    }
    
    function utf8ToBytes (string, units) {
      units = units || Infinity
      let codePoint
      const length = string.length
      let leadSurrogate = null
      const bytes = []
    
      for (let i = 0; i < length; ++i) {
        codePoint = string.charCodeAt(i)
    
        // is surrogate component
        if (codePoint > 0xD7FF && codePoint < 0xE000) {
          // last char was a lead
          if (!leadSurrogate) {
            // no lead yet
            if (codePoint > 0xDBFF) {
              // unexpected trail
              if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
              continue
            } else if (i + 1 === length) {
              // unpaired lead
              if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
              continue
            }
    
            // valid lead
            leadSurrogate = codePoint
    
            continue
          }
    
          // 2 leads in a row
          if (codePoint < 0xDC00) {
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            leadSurrogate = codePoint
            continue
          }
    
          // valid surrogate pair
          codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
        } else if (leadSurrogate) {
          // valid bmp char, but last char was a lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
        }
    
        leadSurrogate = null
    
        // encode utf8
        if (codePoint < 0x80) {
          if ((units -= 1) < 0) break
          bytes.push(codePoint)
        } else if (codePoint < 0x800) {
          if ((units -= 2) < 0) break
          bytes.push(
            codePoint >> 0x6 | 0xC0,
            codePoint & 0x3F | 0x80
          )
        } else if (codePoint < 0x10000) {
          if ((units -= 3) < 0) break
          bytes.push(
            codePoint >> 0xC | 0xE0,
            codePoint >> 0x6 & 0x3F | 0x80,
            codePoint & 0x3F | 0x80
          )
        } else if (codePoint < 0x110000) {
          if ((units -= 4) < 0) break
          bytes.push(
            codePoint >> 0x12 | 0xF0,
            codePoint >> 0xC & 0x3F | 0x80,
            codePoint >> 0x6 & 0x3F | 0x80,
            codePoint & 0x3F | 0x80
          )
        } else {
          throw new Error('Invalid code point')
        }
      }
    
      return bytes
    }
    
    function asciiToBytes (str) {
      const byteArray = []
      for (let i = 0; i < str.length; ++i) {
        // Node's code seems to be doing this and not & 0x7F..
        byteArray.push(str.charCodeAt(i) & 0xFF)
      }
      return byteArray
    }
    
    function utf16leToBytes (str, units) {
      let c, hi, lo
      const byteArray = []
      for (let i = 0; i < str.length; ++i) {
        if ((units -= 2) < 0) break
    
        c = str.charCodeAt(i)
        hi = c >> 8
        lo = c % 256
        byteArray.push(lo)
        byteArray.push(hi)
      }
    
      return byteArray
    }
    
    function base64ToBytes (str) {
      return base64.toByteArray(base64clean(str))
    }
    
    function blitBuffer (src, dst, offset, length) {
      let i
      for (i = 0; i < length; ++i) {
        if ((i + offset >= dst.length) || (i >= src.length)) break
        dst[i + offset] = src[i]
      }
      return i
    }
    
    // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
    // the `instanceof` check but they should be treated as of that type.
    // See: https://github.com/feross/buffer/issues/166
    function isInstance (obj, type) {
      return obj instanceof type ||
        (obj != null && obj.constructor != null && obj.constructor.name != null &&
          obj.constructor.name === type.name)
    }
    function numberIsNaN (obj) {
      // For IE11 support
      return obj !== obj // eslint-disable-line no-self-compare
    }
    
    // Create lookup table for `toString('hex')`
    // See: https://github.com/feross/buffer/issues/219
    const hexSliceLookupTable = (function () {
      const alphabet = '0123456789abcdef'
      const table = new Array(256)
      for (let i = 0; i < 16; ++i) {
        const i16 = i * 16
        for (let j = 0; j < 16; ++j) {
          table[i16 + j] = alphabet[i] + alphabet[j]
        }
      }
      return table
    })()
    
    // Return not function with Error if BigInt not supported
    function defineBigIntMethod (fn) {
      return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn
    }
    
    function BufferBigIntNotDefined () {
      throw new Error('BigInt not supported')
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"base64-js":31,"buffer":84,"ieee754":180}],88:[function(require,module,exports){
    'use strict';
    
    var GetIntrinsic = require('get-intrinsic');
    
    var callBind = require('./');
    
    var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));
    
    module.exports = function callBoundIntrinsic(name, allowMissing) {
        var intrinsic = GetIntrinsic(name, !!allowMissing);
        if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
            return callBind(intrinsic);
        }
        return intrinsic;
    };
    
    },{"./":89,"get-intrinsic":141}],89:[function(require,module,exports){
    'use strict';
    
    var bind = require('function-bind');
    var GetIntrinsic = require('get-intrinsic');
    
    var $apply = GetIntrinsic('%Function.prototype.apply%');
    var $call = GetIntrinsic('%Function.prototype.call%');
    var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);
    
    var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
    var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
    var $max = GetIntrinsic('%Math.max%');
    
    if ($defineProperty) {
        try {
            $defineProperty({}, 'a', { value: 1 });
        } catch (e) {
            // IE 8 has a broken defineProperty
            $defineProperty = null;
        }
    }
    
    module.exports = function callBind(originalFunction) {
        var func = $reflectApply(bind, $call, arguments);
        if ($gOPD && $defineProperty) {
            var desc = $gOPD(func, 'length');
            if (desc.configurable) {
                // original length, plus the receiver, minus any additional arguments (after the receiver)
                $defineProperty(
                    func,
                    'length',
                    { value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }
                );
            }
        }
        return func;
    };
    
    var applyBind = function applyBind() {
        return $reflectApply(bind, $apply, arguments);
    };
    
    if ($defineProperty) {
        $defineProperty(module.exports, 'apply', { value: applyBind });
    } else {
        module.exports.apply = applyBind;
    }
    
    },{"function-bind":140,"get-intrinsic":141}],90:[function(require,module,exports){
    'use strict';
    const ansiStyles = require('ansi-styles');
    const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color');
    const {
        stringReplaceAll,
        stringEncaseCRLFWithFirstIndex
    } = require('./util');
    
    const {isArray} = Array;
    
    // `supportsColor.level` → `ansiStyles.color[name]` mapping
    const levelMapping = [
        'ansi',
        'ansi',
        'ansi256',
        'ansi16m'
    ];
    
    const styles = Object.create(null);
    
    const applyOptions = (object, options = {}) => {
        if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
            throw new Error('The `level` option should be an integer from 0 to 3');
        }
    
        // Detect level if not set manually
        const colorLevel = stdoutColor ? stdoutColor.level : 0;
        object.level = options.level === undefined ? colorLevel : options.level;
    };
    
    class ChalkClass {
        constructor(options) {
            // eslint-disable-next-line no-constructor-return
            return chalkFactory(options);
        }
    }
    
    const chalkFactory = options => {
        const chalk = {};
        applyOptions(chalk, options);
    
        chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_);
    
        Object.setPrototypeOf(chalk, Chalk.prototype);
        Object.setPrototypeOf(chalk.template, chalk);
    
        chalk.template.constructor = () => {
            throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.');
        };
    
        chalk.template.Instance = ChalkClass;
    
        return chalk.template;
    };
    
    function Chalk(options) {
        return chalkFactory(options);
    }
    
    for (const [styleName, style] of Object.entries(ansiStyles)) {
        styles[styleName] = {
            get() {
                const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty);
                Object.defineProperty(this, styleName, {value: builder});
                return builder;
            }
        };
    }
    
    styles.visible = {
        get() {
            const builder = createBuilder(this, this._styler, true);
            Object.defineProperty(this, 'visible', {value: builder});
            return builder;
        }
    };
    
    const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256'];
    
    for (const model of usedModels) {
        styles[model] = {
            get() {
                const {level} = this;
                return function (...arguments_) {
                    const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler);
                    return createBuilder(this, styler, this._isEmpty);
                };
            }
        };
    }
    
    for (const model of usedModels) {
        const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
        styles[bgModel] = {
            get() {
                const {level} = this;
                return function (...arguments_) {
                    const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler);
                    return createBuilder(this, styler, this._isEmpty);
                };
            }
        };
    }
    
    const proto = Object.defineProperties(() => {}, {
        ...styles,
        level: {
            enumerable: true,
            get() {
                return this._generator.level;
            },
            set(level) {
                this._generator.level = level;
            }
        }
    });
    
    const createStyler = (open, close, parent) => {
        let openAll;
        let closeAll;
        if (parent === undefined) {
            openAll = open;
            closeAll = close;
        } else {
            openAll = parent.openAll + open;
            closeAll = close + parent.closeAll;
        }
    
        return {
            open,
            close,
            openAll,
            closeAll,
            parent
        };
    };
    
    const createBuilder = (self, _styler, _isEmpty) => {
        const builder = (...arguments_) => {
            if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) {
                // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}`
                return applyStyle(builder, chalkTag(builder, ...arguments_));
            }
    
            // Single argument is hot path, implicit coercion is faster than anything
            // eslint-disable-next-line no-implicit-coercion
            return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
        };
    
        // We alter the prototype because we must return a function, but there is
        // no way to create a function with a different prototype
        Object.setPrototypeOf(builder, proto);
    
        builder._generator = self;
        builder._styler = _styler;
        builder._isEmpty = _isEmpty;
    
        return builder;
    };
    
    const applyStyle = (self, string) => {
        if (self.level <= 0 || !string) {
            return self._isEmpty ? '' : string;
        }
    
        let styler = self._styler;
    
        if (styler === undefined) {
            return string;
        }
    
        const {openAll, closeAll} = styler;
        if (string.indexOf('\u001B') !== -1) {
            while (styler !== undefined) {
                // Replace any instances already present with a re-opening code
                // otherwise only the part of the string until said closing code
                // will be colored, and the rest will simply be 'plain'.
                string = stringReplaceAll(string, styler.close, styler.open);
    
                styler = styler.parent;
            }
        }
    
        // We can move both next actions out of loop, because remaining actions in loop won't have
        // any/visible effect on parts we add here. Close the styling before a linebreak and reopen
        // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
        const lfIndex = string.indexOf('\n');
        if (lfIndex !== -1) {
            string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
        }
    
        return openAll + string + closeAll;
    };
    
    let template;
    const chalkTag = (chalk, ...strings) => {
        const [firstString] = strings;
    
        if (!isArray(firstString) || !isArray(firstString.raw)) {
            // If chalk() was called by itself or with a string,
            // return the string itself as a string.
            return strings.join(' ');
        }
    
        const arguments_ = strings.slice(1);
        const parts = [firstString.raw[0]];
    
        for (let i = 1; i < firstString.length; i++) {
            parts.push(
                String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'),
                String(firstString.raw[i])
            );
        }
    
        if (template === undefined) {
            template = require('./templates');
        }
    
        return template(chalk, parts.join(''));
    };
    
    Object.defineProperties(Chalk.prototype, styles);
    
    const chalk = Chalk(); // eslint-disable-line new-cap
    chalk.supportsColor = stdoutColor;
    chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap
    chalk.stderr.supportsColor = stderrColor;
    
    module.exports = chalk;
    
    },{"./templates":91,"./util":92,"ansi-styles":9,"supports-color":366}],91:[function(require,module,exports){
    'use strict';
    const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
    const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
    const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
    const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi;
    
    const ESCAPES = new Map([
        ['n', '\n'],
        ['r', '\r'],
        ['t', '\t'],
        ['b', '\b'],
        ['f', '\f'],
        ['v', '\v'],
        ['0', '\0'],
        ['\\', '\\'],
        ['e', '\u001B'],
        ['a', '\u0007']
    ]);
    
    function unescape(c) {
        const u = c[0] === 'u';
        const bracket = c[1] === '{';
    
        if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
            return String.fromCharCode(parseInt(c.slice(1), 16));
        }
    
        if (u && bracket) {
            return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
        }
    
        return ESCAPES.get(c) || c;
    }
    
    function parseArguments(name, arguments_) {
        const results = [];
        const chunks = arguments_.trim().split(/\s*,\s*/g);
        let matches;
    
        for (const chunk of chunks) {
            const number = Number(chunk);
            if (!Number.isNaN(number)) {
                results.push(number);
            } else if ((matches = chunk.match(STRING_REGEX))) {
                results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character));
            } else {
                throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
            }
        }
    
        return results;
    }
    
    function parseStyle(style) {
        STYLE_REGEX.lastIndex = 0;
    
        const results = [];
        let matches;
    
        while ((matches = STYLE_REGEX.exec(style)) !== null) {
            const name = matches[1];
    
            if (matches[2]) {
                const args = parseArguments(name, matches[2]);
                results.push([name].concat(args));
            } else {
                results.push([name]);
            }
        }
    
        return results;
    }
    
    function buildStyle(chalk, styles) {
        const enabled = {};
    
        for (const layer of styles) {
            for (const style of layer.styles) {
                enabled[style[0]] = layer.inverse ? null : style.slice(1);
            }
        }
    
        let current = chalk;
        for (const [styleName, styles] of Object.entries(enabled)) {
            if (!Array.isArray(styles)) {
                continue;
            }
    
            if (!(styleName in current)) {
                throw new Error(`Unknown Chalk style: ${styleName}`);
            }
    
            current = styles.length > 0 ? current[styleName](...styles) : current[styleName];
        }
    
        return current;
    }
    
    module.exports = (chalk, temporary) => {
        const styles = [];
        const chunks = [];
        let chunk = [];
    
        // eslint-disable-next-line max-params
        temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => {
            if (escapeCharacter) {
                chunk.push(unescape(escapeCharacter));
            } else if (style) {
                const string = chunk.join('');
                chunk = [];
                chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string));
                styles.push({inverse, styles: parseStyle(style)});
            } else if (close) {
                if (styles.length === 0) {
                    throw new Error('Found extraneous } in Chalk template literal');
                }
    
                chunks.push(buildStyle(chalk, styles)(chunk.join('')));
                chunk = [];
                styles.pop();
            } else {
                chunk.push(character);
            }
        });
    
        chunks.push(chunk.join(''));
    
        if (styles.length > 0) {
            const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
            throw new Error(errMessage);
        }
    
        return chunks.join('');
    };
    
    },{}],92:[function(require,module,exports){
    'use strict';
    
    const stringReplaceAll = (string, substring, replacer) => {
        let index = string.indexOf(substring);
        if (index === -1) {
            return string;
        }
    
        const substringLength = substring.length;
        let endIndex = 0;
        let returnValue = '';
        do {
            returnValue += string.substr(endIndex, index - endIndex) + substring + replacer;
            endIndex = index + substringLength;
            index = string.indexOf(substring, endIndex);
        } while (index !== -1);
    
        returnValue += string.substr(endIndex);
        return returnValue;
    };
    
    const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => {
        let endIndex = 0;
        let returnValue = '';
        do {
            const gotCR = string[index - 1] === '\r';
            returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
            endIndex = index + 1;
            index = string.indexOf('\n', endIndex);
        } while (index !== -1);
    
        returnValue += string.substr(endIndex);
        return returnValue;
    };
    
    module.exports = {
        stringReplaceAll,
        stringEncaseCRLFWithFirstIndex
    };
    
    },{}],93:[function(require,module,exports){
    var charenc = {
      // UTF-8 encoding
      utf8: {
        // Convert a string to a byte array
        stringToBytes: function(str) {
          return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
        },
    
        // Convert a byte array to a string
        bytesToString: function(bytes) {
          return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
        }
      },
    
      // Binary encoding
      bin: {
        // Convert a string to a byte array
        stringToBytes: function(str) {
          for (var bytes = [], i = 0; i < str.length; i++)
            bytes.push(str.charCodeAt(i) & 0xFF);
          return bytes;
        },
    
        // Convert a byte array to a string
        bytesToString: function(bytes) {
          for (var str = [], i = 0; i < bytes.length; i++)
            str.push(String.fromCharCode(bytes[i]));
          return str.join('');
        }
      }
    };
    
    module.exports = charenc;
    
    },{}],94:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    var Transform = require('stream').Transform
    var StringDecoder = require('string_decoder').StringDecoder
    var inherits = require('inherits')
    
    function CipherBase (hashMode) {
      Transform.call(this)
      this.hashMode = typeof hashMode === 'string'
      if (this.hashMode) {
        this[hashMode] = this._finalOrDigest
      } else {
        this.final = this._finalOrDigest
      }
      if (this._final) {
        this.__final = this._final
        this._final = null
      }
      this._decoder = null
      this._encoding = null
    }
    inherits(CipherBase, Transform)
    
    CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
      if (typeof data === 'string') {
        data = Buffer.from(data, inputEnc)
      }
    
      var outData = this._update(data)
      if (this.hashMode) return this
    
      if (outputEnc) {
        outData = this._toString(outData, outputEnc)
      }
    
      return outData
    }
    
    CipherBase.prototype.setAutoPadding = function () {}
    CipherBase.prototype.getAuthTag = function () {
      throw new Error('trying to get auth tag in unsupported state')
    }
    
    CipherBase.prototype.setAuthTag = function () {
      throw new Error('trying to set auth tag in unsupported state')
    }
    
    CipherBase.prototype.setAAD = function () {
      throw new Error('trying to set aad in unsupported state')
    }
    
    CipherBase.prototype._transform = function (data, _, next) {
      var err
      try {
        if (this.hashMode) {
          this._update(data)
        } else {
          this.push(this._update(data))
        }
      } catch (e) {
        err = e
      } finally {
        next(err)
      }
    }
    CipherBase.prototype._flush = function (done) {
      var err
      try {
        this.push(this.__final())
      } catch (e) {
        err = e
      }
    
      done(err)
    }
    CipherBase.prototype._finalOrDigest = function (outputEnc) {
      var outData = this.__final() || Buffer.alloc(0)
      if (outputEnc) {
        outData = this._toString(outData, outputEnc, true)
      }
      return outData
    }
    
    CipherBase.prototype._toString = function (value, enc, fin) {
      if (!this._decoder) {
        this._decoder = new StringDecoder(enc)
        this._encoding = enc
      }
    
      if (this._encoding !== enc) throw new Error('can\'t switch encodings')
    
      var out = this._decoder.write(value)
      if (fin) {
        out += this._decoder.end()
      }
    
      return out
    }
    
    module.exports = CipherBase
    
    },{"inherits":182,"safe-buffer":338,"stream":350,"string_decoder":365}],95:[function(require,module,exports){
    /* MIT license */
    /* eslint-disable no-mixed-operators */
    const cssKeywords = require('color-name');
    
    // NOTE: conversions should only return primitive values (i.e. arrays, or
    //       values that give correct `typeof` results).
    //       do not use box values types (i.e. Number(), String(), etc.)
    
    const reverseKeywords = {};
    for (const key of Object.keys(cssKeywords)) {
        reverseKeywords[cssKeywords[key]] = key;
    }
    
    const convert = {
        rgb: {channels: 3, labels: 'rgb'},
        hsl: {channels: 3, labels: 'hsl'},
        hsv: {channels: 3, labels: 'hsv'},
        hwb: {channels: 3, labels: 'hwb'},
        cmyk: {channels: 4, labels: 'cmyk'},
        xyz: {channels: 3, labels: 'xyz'},
        lab: {channels: 3, labels: 'lab'},
        lch: {channels: 3, labels: 'lch'},
        hex: {channels: 1, labels: ['hex']},
        keyword: {channels: 1, labels: ['keyword']},
        ansi16: {channels: 1, labels: ['ansi16']},
        ansi256: {channels: 1, labels: ['ansi256']},
        hcg: {channels: 3, labels: ['h', 'c', 'g']},
        apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
        gray: {channels: 1, labels: ['gray']}
    };
    
    module.exports = convert;
    
    // Hide .channels and .labels properties
    for (const model of Object.keys(convert)) {
        if (!('channels' in convert[model])) {
            throw new Error('missing channels property: ' + model);
        }
    
        if (!('labels' in convert[model])) {
            throw new Error('missing channel labels property: ' + model);
        }
    
        if (convert[model].labels.length !== convert[model].channels) {
            throw new Error('channel and label counts mismatch: ' + model);
        }
    
        const {channels, labels} = convert[model];
        delete convert[model].channels;
        delete convert[model].labels;
        Object.defineProperty(convert[model], 'channels', {value: channels});
        Object.defineProperty(convert[model], 'labels', {value: labels});
    }
    
    convert.rgb.hsl = function (rgb) {
        const r = rgb[0] / 255;
        const g = rgb[1] / 255;
        const b = rgb[2] / 255;
        const min = Math.min(r, g, b);
        const max = Math.max(r, g, b);
        const delta = max - min;
        let h;
        let s;
    
        if (max === min) {
            h = 0;
        } else if (r === max) {
            h = (g - b) / delta;
        } else if (g === max) {
            h = 2 + (b - r) / delta;
        } else if (b === max) {
            h = 4 + (r - g) / delta;
        }
    
        h = Math.min(h * 60, 360);
    
        if (h < 0) {
            h += 360;
        }
    
        const l = (min + max) / 2;
    
        if (max === min) {
            s = 0;
        } else if (l <= 0.5) {
            s = delta / (max + min);
        } else {
            s = delta / (2 - max - min);
        }
    
        return [h, s * 100, l * 100];
    };
    
    convert.rgb.hsv = function (rgb) {
        let rdif;
        let gdif;
        let bdif;
        let h;
        let s;
    
        const r = rgb[0] / 255;
        const g = rgb[1] / 255;
        const b = rgb[2] / 255;
        const v = Math.max(r, g, b);
        const diff = v - Math.min(r, g, b);
        const diffc = function (c) {
            return (v - c) / 6 / diff + 1 / 2;
        };
    
        if (diff === 0) {
            h = 0;
            s = 0;
        } else {
            s = diff / v;
            rdif = diffc(r);
            gdif = diffc(g);
            bdif = diffc(b);
    
            if (r === v) {
                h = bdif - gdif;
            } else if (g === v) {
                h = (1 / 3) + rdif - bdif;
            } else if (b === v) {
                h = (2 / 3) + gdif - rdif;
            }
    
            if (h < 0) {
                h += 1;
            } else if (h > 1) {
                h -= 1;
            }
        }
    
        return [
            h * 360,
            s * 100,
            v * 100
        ];
    };
    
    convert.rgb.hwb = function (rgb) {
        const r = rgb[0];
        const g = rgb[1];
        let b = rgb[2];
        const h = convert.rgb.hsl(rgb)[0];
        const w = 1 / 255 * Math.min(r, Math.min(g, b));
    
        b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
    
        return [h, w * 100, b * 100];
    };
    
    convert.rgb.cmyk = function (rgb) {
        const r = rgb[0] / 255;
        const g = rgb[1] / 255;
        const b = rgb[2] / 255;
    
        const k = Math.min(1 - r, 1 - g, 1 - b);
        const c = (1 - r - k) / (1 - k) || 0;
        const m = (1 - g - k) / (1 - k) || 0;
        const y = (1 - b - k) / (1 - k) || 0;
    
        return [c * 100, m * 100, y * 100, k * 100];
    };
    
    function comparativeDistance(x, y) {
        /*
            See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
        */
        return (
            ((x[0] - y[0]) ** 2) +
            ((x[1] - y[1]) ** 2) +
            ((x[2] - y[2]) ** 2)
        );
    }
    
    convert.rgb.keyword = function (rgb) {
        const reversed = reverseKeywords[rgb];
        if (reversed) {
            return reversed;
        }
    
        let currentClosestDistance = Infinity;
        let currentClosestKeyword;
    
        for (const keyword of Object.keys(cssKeywords)) {
            const value = cssKeywords[keyword];
    
            // Compute comparative distance
            const distance = comparativeDistance(rgb, value);
    
            // Check if its less, if so set as closest
            if (distance < currentClosestDistance) {
                currentClosestDistance = distance;
                currentClosestKeyword = keyword;
            }
        }
    
        return currentClosestKeyword;
    };
    
    convert.keyword.rgb = function (keyword) {
        return cssKeywords[keyword];
    };
    
    convert.rgb.xyz = function (rgb) {
        let r = rgb[0] / 255;
        let g = rgb[1] / 255;
        let b = rgb[2] / 255;
    
        // Assume sRGB
        r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);
        g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);
        b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);
    
        const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
        const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
        const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
    
        return [x * 100, y * 100, z * 100];
    };
    
    convert.rgb.lab = function (rgb) {
        const xyz = convert.rgb.xyz(rgb);
        let x = xyz[0];
        let y = xyz[1];
        let z = xyz[2];
    
        x /= 95.047;
        y /= 100;
        z /= 108.883;
    
        x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
        y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
        z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
    
        const l = (116 * y) - 16;
        const a = 500 * (x - y);
        const b = 200 * (y - z);
    
        return [l, a, b];
    };
    
    convert.hsl.rgb = function (hsl) {
        const h = hsl[0] / 360;
        const s = hsl[1] / 100;
        const l = hsl[2] / 100;
        let t2;
        let t3;
        let val;
    
        if (s === 0) {
            val = l * 255;
            return [val, val, val];
        }
    
        if (l < 0.5) {
            t2 = l * (1 + s);
        } else {
            t2 = l + s - l * s;
        }
    
        const t1 = 2 * l - t2;
    
        const rgb = [0, 0, 0];
        for (let i = 0; i < 3; i++) {
            t3 = h + 1 / 3 * -(i - 1);
            if (t3 < 0) {
                t3++;
            }
    
            if (t3 > 1) {
                t3--;
            }
    
            if (6 * t3 < 1) {
                val = t1 + (t2 - t1) * 6 * t3;
            } else if (2 * t3 < 1) {
                val = t2;
            } else if (3 * t3 < 2) {
                val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
            } else {
                val = t1;
            }
    
            rgb[i] = val * 255;
        }
    
        return rgb;
    };
    
    convert.hsl.hsv = function (hsl) {
        const h = hsl[0];
        let s = hsl[1] / 100;
        let l = hsl[2] / 100;
        let smin = s;
        const lmin = Math.max(l, 0.01);
    
        l *= 2;
        s *= (l <= 1) ? l : 2 - l;
        smin *= lmin <= 1 ? lmin : 2 - lmin;
        const v = (l + s) / 2;
        const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
    
        return [h, sv * 100, v * 100];
    };
    
    convert.hsv.rgb = function (hsv) {
        const h = hsv[0] / 60;
        const s = hsv[1] / 100;
        let v = hsv[2] / 100;
        const hi = Math.floor(h) % 6;
    
        const f = h - Math.floor(h);
        const p = 255 * v * (1 - s);
        const q = 255 * v * (1 - (s * f));
        const t = 255 * v * (1 - (s * (1 - f)));
        v *= 255;
    
        switch (hi) {
            case 0:
                return [v, t, p];
            case 1:
                return [q, v, p];
            case 2:
                return [p, v, t];
            case 3:
                return [p, q, v];
            case 4:
                return [t, p, v];
            case 5:
                return [v, p, q];
        }
    };
    
    convert.hsv.hsl = function (hsv) {
        const h = hsv[0];
        const s = hsv[1] / 100;
        const v = hsv[2] / 100;
        const vmin = Math.max(v, 0.01);
        let sl;
        let l;
    
        l = (2 - s) * v;
        const lmin = (2 - s) * vmin;
        sl = s * vmin;
        sl /= (lmin <= 1) ? lmin : 2 - lmin;
        sl = sl || 0;
        l /= 2;
    
        return [h, sl * 100, l * 100];
    };
    
    // http://dev.w3.org/csswg/css-color/#hwb-to-rgb
    convert.hwb.rgb = function (hwb) {
        const h = hwb[0] / 360;
        let wh = hwb[1] / 100;
        let bl = hwb[2] / 100;
        const ratio = wh + bl;
        let f;
    
        // Wh + bl cant be > 1
        if (ratio > 1) {
            wh /= ratio;
            bl /= ratio;
        }
    
        const i = Math.floor(6 * h);
        const v = 1 - bl;
        f = 6 * h - i;
    
        if ((i & 0x01) !== 0) {
            f = 1 - f;
        }
    
        const n = wh + f * (v - wh); // Linear interpolation
    
        let r;
        let g;
        let b;
        /* eslint-disable max-statements-per-line,no-multi-spaces */
        switch (i) {
            default:
            case 6:
            case 0: r = v;  g = n;  b = wh; break;
            case 1: r = n;  g = v;  b = wh; break;
            case 2: r = wh; g = v;  b = n; break;
            case 3: r = wh; g = n;  b = v; break;
            case 4: r = n;  g = wh; b = v; break;
            case 5: r = v;  g = wh; b = n; break;
        }
        /* eslint-enable max-statements-per-line,no-multi-spaces */
    
        return [r * 255, g * 255, b * 255];
    };
    
    convert.cmyk.rgb = function (cmyk) {
        const c = cmyk[0] / 100;
        const m = cmyk[1] / 100;
        const y = cmyk[2] / 100;
        const k = cmyk[3] / 100;
    
        const r = 1 - Math.min(1, c * (1 - k) + k);
        const g = 1 - Math.min(1, m * (1 - k) + k);
        const b = 1 - Math.min(1, y * (1 - k) + k);
    
        return [r * 255, g * 255, b * 255];
    };
    
    convert.xyz.rgb = function (xyz) {
        const x = xyz[0] / 100;
        const y = xyz[1] / 100;
        const z = xyz[2] / 100;
        let r;
        let g;
        let b;
    
        r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
        g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
        b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
    
        // Assume sRGB
        r = r > 0.0031308
            ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)
            : r * 12.92;
    
        g = g > 0.0031308
            ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)
            : g * 12.92;
    
        b = b > 0.0031308
            ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)
            : b * 12.92;
    
        r = Math.min(Math.max(0, r), 1);
        g = Math.min(Math.max(0, g), 1);
        b = Math.min(Math.max(0, b), 1);
    
        return [r * 255, g * 255, b * 255];
    };
    
    convert.xyz.lab = function (xyz) {
        let x = xyz[0];
        let y = xyz[1];
        let z = xyz[2];
    
        x /= 95.047;
        y /= 100;
        z /= 108.883;
    
        x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
        y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
        z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
    
        const l = (116 * y) - 16;
        const a = 500 * (x - y);
        const b = 200 * (y - z);
    
        return [l, a, b];
    };
    
    convert.lab.xyz = function (lab) {
        const l = lab[0];
        const a = lab[1];
        const b = lab[2];
        let x;
        let y;
        let z;
    
        y = (l + 16) / 116;
        x = a / 500 + y;
        z = y - b / 200;
    
        const y2 = y ** 3;
        const x2 = x ** 3;
        const z2 = z ** 3;
        y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
        x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
        z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
    
        x *= 95.047;
        y *= 100;
        z *= 108.883;
    
        return [x, y, z];
    };
    
    convert.lab.lch = function (lab) {
        const l = lab[0];
        const a = lab[1];
        const b = lab[2];
        let h;
    
        const hr = Math.atan2(b, a);
        h = hr * 360 / 2 / Math.PI;
    
        if (h < 0) {
            h += 360;
        }
    
        const c = Math.sqrt(a * a + b * b);
    
        return [l, c, h];
    };
    
    convert.lch.lab = function (lch) {
        const l = lch[0];
        const c = lch[1];
        const h = lch[2];
    
        const hr = h / 360 * 2 * Math.PI;
        const a = c * Math.cos(hr);
        const b = c * Math.sin(hr);
    
        return [l, a, b];
    };
    
    convert.rgb.ansi16 = function (args, saturation = null) {
        const [r, g, b] = args;
        let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization
    
        value = Math.round(value / 50);
    
        if (value === 0) {
            return 30;
        }
    
        let ansi = 30
            + ((Math.round(b / 255) << 2)
            | (Math.round(g / 255) << 1)
            | Math.round(r / 255));
    
        if (value === 2) {
            ansi += 60;
        }
    
        return ansi;
    };
    
    convert.hsv.ansi16 = function (args) {
        // Optimization here; we already know the value and don't need to get
        // it converted for us.
        return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
    };
    
    convert.rgb.ansi256 = function (args) {
        const r = args[0];
        const g = args[1];
        const b = args[2];
    
        // We use the extended greyscale palette here, with the exception of
        // black and white. normal palette only has 4 greyscale shades.
        if (r === g && g === b) {
            if (r < 8) {
                return 16;
            }
    
            if (r > 248) {
                return 231;
            }
    
            return Math.round(((r - 8) / 247) * 24) + 232;
        }
    
        const ansi = 16
            + (36 * Math.round(r / 255 * 5))
            + (6 * Math.round(g / 255 * 5))
            + Math.round(b / 255 * 5);
    
        return ansi;
    };
    
    convert.ansi16.rgb = function (args) {
        let color = args % 10;
    
        // Handle greyscale
        if (color === 0 || color === 7) {
            if (args > 50) {
                color += 3.5;
            }
    
            color = color / 10.5 * 255;
    
            return [color, color, color];
        }
    
        const mult = (~~(args > 50) + 1) * 0.5;
        const r = ((color & 1) * mult) * 255;
        const g = (((color >> 1) & 1) * mult) * 255;
        const b = (((color >> 2) & 1) * mult) * 255;
    
        return [r, g, b];
    };
    
    convert.ansi256.rgb = function (args) {
        // Handle greyscale
        if (args >= 232) {
            const c = (args - 232) * 10 + 8;
            return [c, c, c];
        }
    
        args -= 16;
    
        let rem;
        const r = Math.floor(args / 36) / 5 * 255;
        const g = Math.floor((rem = args % 36) / 6) / 5 * 255;
        const b = (rem % 6) / 5 * 255;
    
        return [r, g, b];
    };
    
    convert.rgb.hex = function (args) {
        const integer = ((Math.round(args[0]) & 0xFF) << 16)
            + ((Math.round(args[1]) & 0xFF) << 8)
            + (Math.round(args[2]) & 0xFF);
    
        const string = integer.toString(16).toUpperCase();
        return '000000'.substring(string.length) + string;
    };
    
    convert.hex.rgb = function (args) {
        const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
        if (!match) {
            return [0, 0, 0];
        }
    
        let colorString = match[0];
    
        if (match[0].length === 3) {
            colorString = colorString.split('').map(char => {
                return char + char;
            }).join('');
        }
    
        const integer = parseInt(colorString, 16);
        const r = (integer >> 16) & 0xFF;
        const g = (integer >> 8) & 0xFF;
        const b = integer & 0xFF;
    
        return [r, g, b];
    };
    
    convert.rgb.hcg = function (rgb) {
        const r = rgb[0] / 255;
        const g = rgb[1] / 255;
        const b = rgb[2] / 255;
        const max = Math.max(Math.max(r, g), b);
        const min = Math.min(Math.min(r, g), b);
        const chroma = (max - min);
        let grayscale;
        let hue;
    
        if (chroma < 1) {
            grayscale = min / (1 - chroma);
        } else {
            grayscale = 0;
        }
    
        if (chroma <= 0) {
            hue = 0;
        } else
        if (max === r) {
            hue = ((g - b) / chroma) % 6;
        } else
        if (max === g) {
            hue = 2 + (b - r) / chroma;
        } else {
            hue = 4 + (r - g) / chroma;
        }
    
        hue /= 6;
        hue %= 1;
    
        return [hue * 360, chroma * 100, grayscale * 100];
    };
    
    convert.hsl.hcg = function (hsl) {
        const s = hsl[1] / 100;
        const l = hsl[2] / 100;
    
        const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));
    
        let f = 0;
        if (c < 1.0) {
            f = (l - 0.5 * c) / (1.0 - c);
        }
    
        return [hsl[0], c * 100, f * 100];
    };
    
    convert.hsv.hcg = function (hsv) {
        const s = hsv[1] / 100;
        const v = hsv[2] / 100;
    
        const c = s * v;
        let f = 0;
    
        if (c < 1.0) {
            f = (v - c) / (1 - c);
        }
    
        return [hsv[0], c * 100, f * 100];
    };
    
    convert.hcg.rgb = function (hcg) {
        const h = hcg[0] / 360;
        const c = hcg[1] / 100;
        const g = hcg[2] / 100;
    
        if (c === 0.0) {
            return [g * 255, g * 255, g * 255];
        }
    
        const pure = [0, 0, 0];
        const hi = (h % 1) * 6;
        const v = hi % 1;
        const w = 1 - v;
        let mg = 0;
    
        /* eslint-disable max-statements-per-line */
        switch (Math.floor(hi)) {
            case 0:
                pure[0] = 1; pure[1] = v; pure[2] = 0; break;
            case 1:
                pure[0] = w; pure[1] = 1; pure[2] = 0; break;
            case 2:
                pure[0] = 0; pure[1] = 1; pure[2] = v; break;
            case 3:
                pure[0] = 0; pure[1] = w; pure[2] = 1; break;
            case 4:
                pure[0] = v; pure[1] = 0; pure[2] = 1; break;
            default:
                pure[0] = 1; pure[1] = 0; pure[2] = w;
        }
        /* eslint-enable max-statements-per-line */
    
        mg = (1.0 - c) * g;
    
        return [
            (c * pure[0] + mg) * 255,
            (c * pure[1] + mg) * 255,
            (c * pure[2] + mg) * 255
        ];
    };
    
    convert.hcg.hsv = function (hcg) {
        const c = hcg[1] / 100;
        const g = hcg[2] / 100;
    
        const v = c + g * (1.0 - c);
        let f = 0;
    
        if (v > 0.0) {
            f = c / v;
        }
    
        return [hcg[0], f * 100, v * 100];
    };
    
    convert.hcg.hsl = function (hcg) {
        const c = hcg[1] / 100;
        const g = hcg[2] / 100;
    
        const l = g * (1.0 - c) + 0.5 * c;
        let s = 0;
    
        if (l > 0.0 && l < 0.5) {
            s = c / (2 * l);
        } else
        if (l >= 0.5 && l < 1.0) {
            s = c / (2 * (1 - l));
        }
    
        return [hcg[0], s * 100, l * 100];
    };
    
    convert.hcg.hwb = function (hcg) {
        const c = hcg[1] / 100;
        const g = hcg[2] / 100;
        const v = c + g * (1.0 - c);
        return [hcg[0], (v - c) * 100, (1 - v) * 100];
    };
    
    convert.hwb.hcg = function (hwb) {
        const w = hwb[1] / 100;
        const b = hwb[2] / 100;
        const v = 1 - b;
        const c = v - w;
        let g = 0;
    
        if (c < 1) {
            g = (v - c) / (1 - c);
        }
    
        return [hwb[0], c * 100, g * 100];
    };
    
    convert.apple.rgb = function (apple) {
        return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
    };
    
    convert.rgb.apple = function (rgb) {
        return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
    };
    
    convert.gray.rgb = function (args) {
        return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
    };
    
    convert.gray.hsl = function (args) {
        return [0, 0, args[0]];
    };
    
    convert.gray.hsv = convert.gray.hsl;
    
    convert.gray.hwb = function (gray) {
        return [0, 100, gray[0]];
    };
    
    convert.gray.cmyk = function (gray) {
        return [0, 0, 0, gray[0]];
    };
    
    convert.gray.lab = function (gray) {
        return [gray[0], 0, 0];
    };
    
    convert.gray.hex = function (gray) {
        const val = Math.round(gray[0] / 100 * 255) & 0xFF;
        const integer = (val << 16) + (val << 8) + val;
    
        const string = integer.toString(16).toUpperCase();
        return '000000'.substring(string.length) + string;
    };
    
    convert.rgb.gray = function (rgb) {
        const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
        return [val / 255 * 100];
    };
    
    },{"color-name":98}],96:[function(require,module,exports){
    const conversions = require('./conversions');
    const route = require('./route');
    
    const convert = {};
    
    const models = Object.keys(conversions);
    
    function wrapRaw(fn) {
        const wrappedFn = function (...args) {
            const arg0 = args[0];
            if (arg0 === undefined || arg0 === null) {
                return arg0;
            }
    
            if (arg0.length > 1) {
                args = arg0;
            }
    
            return fn(args);
        };
    
        // Preserve .conversion property if there is one
        if ('conversion' in fn) {
            wrappedFn.conversion = fn.conversion;
        }
    
        return wrappedFn;
    }
    
    function wrapRounded(fn) {
        const wrappedFn = function (...args) {
            const arg0 = args[0];
    
            if (arg0 === undefined || arg0 === null) {
                return arg0;
            }
    
            if (arg0.length > 1) {
                args = arg0;
            }
    
            const result = fn(args);
    
            // We're assuming the result is an array here.
            // see notice in conversions.js; don't use box types
            // in conversion functions.
            if (typeof result === 'object') {
                for (let len = result.length, i = 0; i < len; i++) {
                    result[i] = Math.round(result[i]);
                }
            }
    
            return result;
        };
    
        // Preserve .conversion property if there is one
        if ('conversion' in fn) {
            wrappedFn.conversion = fn.conversion;
        }
    
        return wrappedFn;
    }
    
    models.forEach(fromModel => {
        convert[fromModel] = {};
    
        Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
        Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
    
        const routes = route(fromModel);
        const routeModels = Object.keys(routes);
    
        routeModels.forEach(toModel => {
            const fn = routes[toModel];
    
            convert[fromModel][toModel] = wrapRounded(fn);
            convert[fromModel][toModel].raw = wrapRaw(fn);
        });
    });
    
    module.exports = convert;
    
    },{"./conversions":95,"./route":97}],97:[function(require,module,exports){
    const conversions = require('./conversions');
    
    /*
        This function routes a model to all other models.
    
        all functions that are routed have a property `.conversion` attached
        to the returned synthetic function. This property is an array
        of strings, each with the steps in between the 'from' and 'to'
        color models (inclusive).
    
        conversions that are not possible simply are not included.
    */
    
    function buildGraph() {
        const graph = {};
        // https://jsperf.com/object-keys-vs-for-in-with-closure/3
        const models = Object.keys(conversions);
    
        for (let len = models.length, i = 0; i < len; i++) {
            graph[models[i]] = {
                // http://jsperf.com/1-vs-infinity
                // micro-opt, but this is simple.
                distance: -1,
                parent: null
            };
        }
    
        return graph;
    }
    
    // https://en.wikipedia.org/wiki/Breadth-first_search
    function deriveBFS(fromModel) {
        const graph = buildGraph();
        const queue = [fromModel]; // Unshift -> queue -> pop
    
        graph[fromModel].distance = 0;
    
        while (queue.length) {
            const current = queue.pop();
            const adjacents = Object.keys(conversions[current]);
    
            for (let len = adjacents.length, i = 0; i < len; i++) {
                const adjacent = adjacents[i];
                const node = graph[adjacent];
    
                if (node.distance === -1) {
                    node.distance = graph[current].distance + 1;
                    node.parent = current;
                    queue.unshift(adjacent);
                }
            }
        }
    
        return graph;
    }
    
    function link(from, to) {
        return function (args) {
            return to(from(args));
        };
    }
    
    function wrapConversion(toModel, graph) {
        const path = [graph[toModel].parent, toModel];
        let fn = conversions[graph[toModel].parent][toModel];
    
        let cur = graph[toModel].parent;
        while (graph[cur].parent) {
            path.unshift(graph[cur].parent);
            fn = link(conversions[graph[cur].parent][cur], fn);
            cur = graph[cur].parent;
        }
    
        fn.conversion = path;
        return fn;
    }
    
    module.exports = function (fromModel) {
        const graph = deriveBFS(fromModel);
        const conversion = {};
    
        const models = Object.keys(graph);
        for (let len = models.length, i = 0; i < len; i++) {
            const toModel = models[i];
            const node = graph[toModel];
    
            if (node.parent === null) {
                // No possible conversion, or this node is the source model.
                continue;
            }
    
            conversion[toModel] = wrapConversion(toModel, graph);
        }
    
        return conversion;
    };
    
    
    },{"./conversions":95}],98:[function(require,module,exports){
    'use strict'
    
    module.exports = {
        "aliceblue": [240, 248, 255],
        "antiquewhite": [250, 235, 215],
        "aqua": [0, 255, 255],
        "aquamarine": [127, 255, 212],
        "azure": [240, 255, 255],
        "beige": [245, 245, 220],
        "bisque": [255, 228, 196],
        "black": [0, 0, 0],
        "blanchedalmond": [255, 235, 205],
        "blue": [0, 0, 255],
        "blueviolet": [138, 43, 226],
        "brown": [165, 42, 42],
        "burlywood": [222, 184, 135],
        "cadetblue": [95, 158, 160],
        "chartreuse": [127, 255, 0],
        "chocolate": [210, 105, 30],
        "coral": [255, 127, 80],
        "cornflowerblue": [100, 149, 237],
        "cornsilk": [255, 248, 220],
        "crimson": [220, 20, 60],
        "cyan": [0, 255, 255],
        "darkblue": [0, 0, 139],
        "darkcyan": [0, 139, 139],
        "darkgoldenrod": [184, 134, 11],
        "darkgray": [169, 169, 169],
        "darkgreen": [0, 100, 0],
        "darkgrey": [169, 169, 169],
        "darkkhaki": [189, 183, 107],
        "darkmagenta": [139, 0, 139],
        "darkolivegreen": [85, 107, 47],
        "darkorange": [255, 140, 0],
        "darkorchid": [153, 50, 204],
        "darkred": [139, 0, 0],
        "darksalmon": [233, 150, 122],
        "darkseagreen": [143, 188, 143],
        "darkslateblue": [72, 61, 139],
        "darkslategray": [47, 79, 79],
        "darkslategrey": [47, 79, 79],
        "darkturquoise": [0, 206, 209],
        "darkviolet": [148, 0, 211],
        "deeppink": [255, 20, 147],
        "deepskyblue": [0, 191, 255],
        "dimgray": [105, 105, 105],
        "dimgrey": [105, 105, 105],
        "dodgerblue": [30, 144, 255],
        "firebrick": [178, 34, 34],
        "floralwhite": [255, 250, 240],
        "forestgreen": [34, 139, 34],
        "fuchsia": [255, 0, 255],
        "gainsboro": [220, 220, 220],
        "ghostwhite": [248, 248, 255],
        "gold": [255, 215, 0],
        "goldenrod": [218, 165, 32],
        "gray": [128, 128, 128],
        "green": [0, 128, 0],
        "greenyellow": [173, 255, 47],
        "grey": [128, 128, 128],
        "honeydew": [240, 255, 240],
        "hotpink": [255, 105, 180],
        "indianred": [205, 92, 92],
        "indigo": [75, 0, 130],
        "ivory": [255, 255, 240],
        "khaki": [240, 230, 140],
        "lavender": [230, 230, 250],
        "lavenderblush": [255, 240, 245],
        "lawngreen": [124, 252, 0],
        "lemonchiffon": [255, 250, 205],
        "lightblue": [173, 216, 230],
        "lightcoral": [240, 128, 128],
        "lightcyan": [224, 255, 255],
        "lightgoldenrodyellow": [250, 250, 210],
        "lightgray": [211, 211, 211],
        "lightgreen": [144, 238, 144],
        "lightgrey": [211, 211, 211],
        "lightpink": [255, 182, 193],
        "lightsalmon": [255, 160, 122],
        "lightseagreen": [32, 178, 170],
        "lightskyblue": [135, 206, 250],
        "lightslategray": [119, 136, 153],
        "lightslategrey": [119, 136, 153],
        "lightsteelblue": [176, 196, 222],
        "lightyellow": [255, 255, 224],
        "lime": [0, 255, 0],
        "limegreen": [50, 205, 50],
        "linen": [250, 240, 230],
        "magenta": [255, 0, 255],
        "maroon": [128, 0, 0],
        "mediumaquamarine": [102, 205, 170],
        "mediumblue": [0, 0, 205],
        "mediumorchid": [186, 85, 211],
        "mediumpurple": [147, 112, 219],
        "mediumseagreen": [60, 179, 113],
        "mediumslateblue": [123, 104, 238],
        "mediumspringgreen": [0, 250, 154],
        "mediumturquoise": [72, 209, 204],
        "mediumvioletred": [199, 21, 133],
        "midnightblue": [25, 25, 112],
        "mintcream": [245, 255, 250],
        "mistyrose": [255, 228, 225],
        "moccasin": [255, 228, 181],
        "navajowhite": [255, 222, 173],
        "navy": [0, 0, 128],
        "oldlace": [253, 245, 230],
        "olive": [128, 128, 0],
        "olivedrab": [107, 142, 35],
        "orange": [255, 165, 0],
        "orangered": [255, 69, 0],
        "orchid": [218, 112, 214],
        "palegoldenrod": [238, 232, 170],
        "palegreen": [152, 251, 152],
        "paleturquoise": [175, 238, 238],
        "palevioletred": [219, 112, 147],
        "papayawhip": [255, 239, 213],
        "peachpuff": [255, 218, 185],
        "peru": [205, 133, 63],
        "pink": [255, 192, 203],
        "plum": [221, 160, 221],
        "powderblue": [176, 224, 230],
        "purple": [128, 0, 128],
        "rebeccapurple": [102, 51, 153],
        "red": [255, 0, 0],
        "rosybrown": [188, 143, 143],
        "royalblue": [65, 105, 225],
        "saddlebrown": [139, 69, 19],
        "salmon": [250, 128, 114],
        "sandybrown": [244, 164, 96],
        "seagreen": [46, 139, 87],
        "seashell": [255, 245, 238],
        "sienna": [160, 82, 45],
        "silver": [192, 192, 192],
        "skyblue": [135, 206, 235],
        "slateblue": [106, 90, 205],
        "slategray": [112, 128, 144],
        "slategrey": [112, 128, 144],
        "snow": [255, 250, 250],
        "springgreen": [0, 255, 127],
        "steelblue": [70, 130, 180],
        "tan": [210, 180, 140],
        "teal": [0, 128, 128],
        "thistle": [216, 191, 216],
        "tomato": [255, 99, 71],
        "turquoise": [64, 224, 208],
        "violet": [238, 130, 238],
        "wheat": [245, 222, 179],
        "white": [255, 255, 255],
        "whitesmoke": [245, 245, 245],
        "yellow": [255, 255, 0],
        "yellowgreen": [154, 205, 50]
    };
    
    },{}],99:[function(require,module,exports){
    /* global define */
    (function (root, factory) {
      /* istanbul ignore next */
      if (typeof define === 'function' && define.amd) {
        define([], factory);
      } else if (typeof exports === 'object') {
        module.exports = factory();
      } else {
        root.compareVersions = factory();
      }
    }(this, function () {
    
      var semver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+))?(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
    
      function indexOrEnd(str, q) {
        return str.indexOf(q) === -1 ? str.length : str.indexOf(q);
      }
    
      function split(v) {
        var c = v.replace(/^v/, '').replace(/\+.*$/, '');
        var patchIndex = indexOrEnd(c, '-');
        var arr = c.substring(0, patchIndex).split('.');
        arr.push(c.substring(patchIndex + 1));
        return arr;
      }
    
      function tryParse(v) {
        return isNaN(Number(v)) ? v : Number(v);
      }
    
      function validate(version) {
        if (typeof version !== 'string') {
          throw new TypeError('Invalid argument expected string');
        }
        if (!semver.test(version)) {
          throw new Error('Invalid argument not valid semver (\''+version+'\' received)');
        }
      }
    
      function compareVersions(v1, v2) {
        [v1, v2].forEach(validate);
    
        var s1 = split(v1);
        var s2 = split(v2);
    
        for (var i = 0; i < Math.max(s1.length - 1, s2.length - 1); i++) {
          var n1 = parseInt(s1[i] || 0, 10);
          var n2 = parseInt(s2[i] || 0, 10);
    
          if (n1 > n2) return 1;
          if (n2 > n1) return -1;
        }
    
        var sp1 = s1[s1.length - 1];
        var sp2 = s2[s2.length - 1];
    
        if (sp1 && sp2) {
          var p1 = sp1.split('.').map(tryParse);
          var p2 = sp2.split('.').map(tryParse);
    
          for (i = 0; i < Math.max(p1.length, p2.length); i++) {
            if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1;
            if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1;
    
            if (p1[i] > p2[i]) return 1;
            if (p2[i] > p1[i]) return -1;
          }
        } else if (sp1 || sp2) {
          return sp1 ? -1 : 1;
        }
    
        return 0;
      };
    
      var allowedOperators = [
        '>',
        '>=',
        '=',
        '<',
        '<='
      ];
    
      var operatorResMap = {
        '>': [1],
        '>=': [0, 1],
        '=': [0],
        '<=': [-1, 0],
        '<': [-1]
      };
    
      function validateOperator(op) {
        if (typeof op !== 'string') {
          throw new TypeError('Invalid operator type, expected string but got ' + typeof op);
        }
        if (allowedOperators.indexOf(op) === -1) {
          throw new TypeError('Invalid operator, expected one of ' + allowedOperators.join('|'));
        }
      }
    
      compareVersions.validate = function(version) {
        return typeof version === 'string' && semver.test(version);
      }
    
      compareVersions.compare = function (v1, v2, operator) {
        // Validate operator
        validateOperator(operator);
    
        // since result of compareVersions can only be -1 or 0 or 1
        // a simple map can be used to replace switch
        var res = compareVersions(v1, v2);
        return operatorResMap[operator].indexOf(res) > -1;
      }
    
      return compareVersions;
    }));
    
    },{}],100:[function(require,module,exports){
    module.exports = function (xs, fn) {
        var res = [];
        for (var i = 0; i < xs.length; i++) {
            var x = fn(xs[i], i);
            if (isArray(x)) res.push.apply(res, x);
            else res.push(x);
        }
        return res;
    };
    
    var isArray = Array.isArray || function (xs) {
        return Object.prototype.toString.call(xs) === '[object Array]';
    };
    
    },{}],101:[function(require,module,exports){
    (function (Buffer){(function (){
    var elliptic = require('elliptic')
    var BN = require('bn.js')
    
    module.exports = function createECDH (curve) {
      return new ECDH(curve)
    }
    
    var aliases = {
      secp256k1: {
        name: 'secp256k1',
        byteLength: 32
      },
      secp224r1: {
        name: 'p224',
        byteLength: 28
      },
      prime256v1: {
        name: 'p256',
        byteLength: 32
      },
      prime192v1: {
        name: 'p192',
        byteLength: 24
      },
      ed25519: {
        name: 'ed25519',
        byteLength: 32
      },
      secp384r1: {
        name: 'p384',
        byteLength: 48
      },
      secp521r1: {
        name: 'p521',
        byteLength: 66
      }
    }
    
    aliases.p224 = aliases.secp224r1
    aliases.p256 = aliases.secp256r1 = aliases.prime256v1
    aliases.p192 = aliases.secp192r1 = aliases.prime192v1
    aliases.p384 = aliases.secp384r1
    aliases.p521 = aliases.secp521r1
    
    function ECDH (curve) {
      this.curveType = aliases[curve]
      if (!this.curveType) {
        this.curveType = {
          name: curve
        }
      }
      this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap
      this.keys = void 0
    }
    
    ECDH.prototype.generateKeys = function (enc, format) {
      this.keys = this.curve.genKeyPair()
      return this.getPublicKey(enc, format)
    }
    
    ECDH.prototype.computeSecret = function (other, inenc, enc) {
      inenc = inenc || 'utf8'
      if (!Buffer.isBuffer(other)) {
        other = new Buffer(other, inenc)
      }
      var otherPub = this.curve.keyFromPublic(other).getPublic()
      var out = otherPub.mul(this.keys.getPrivate()).getX()
      return formatReturnValue(out, enc, this.curveType.byteLength)
    }
    
    ECDH.prototype.getPublicKey = function (enc, format) {
      var key = this.keys.getPublic(format === 'compressed', true)
      if (format === 'hybrid') {
        if (key[key.length - 1] % 2) {
          key[0] = 7
        } else {
          key[0] = 6
        }
      }
      return formatReturnValue(key, enc)
    }
    
    ECDH.prototype.getPrivateKey = function (enc) {
      return formatReturnValue(this.keys.getPrivate(), enc)
    }
    
    ECDH.prototype.setPublicKey = function (pub, enc) {
      enc = enc || 'utf8'
      if (!Buffer.isBuffer(pub)) {
        pub = new Buffer(pub, enc)
      }
      this.keys._importPublic(pub)
      return this
    }
    
    ECDH.prototype.setPrivateKey = function (priv, enc) {
      enc = enc || 'utf8'
      if (!Buffer.isBuffer(priv)) {
        priv = new Buffer(priv, enc)
      }
    
      var _priv = new BN(priv)
      _priv = _priv.toString(16)
      this.keys = this.curve.genKeyPair()
      this.keys._importPrivate(_priv)
      return this
    }
    
    function formatReturnValue (bn, enc, len) {
      if (!Array.isArray(bn)) {
        bn = bn.toArray()
      }
      var buf = new Buffer(bn)
      if (len && buf.length < len) {
        var zeros = new Buffer(len - buf.length)
        zeros.fill(0)
        buf = Buffer.concat([zeros, buf])
      }
      if (!enc) {
        return buf
      } else {
        return buf.toString(enc)
      }
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"bn.js":33,"buffer":84,"elliptic":118}],102:[function(require,module,exports){
    'use strict'
    var inherits = require('inherits')
    var MD5 = require('md5.js')
    var RIPEMD160 = require('ripemd160')
    var sha = require('sha.js')
    var Base = require('cipher-base')
    
    function Hash (hash) {
      Base.call(this, 'digest')
    
      this._hash = hash
    }
    
    inherits(Hash, Base)
    
    Hash.prototype._update = function (data) {
      this._hash.update(data)
    }
    
    Hash.prototype._final = function () {
      return this._hash.digest()
    }
    
    module.exports = function createHash (alg) {
      alg = alg.toLowerCase()
      if (alg === 'md5') return new MD5()
      if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160()
    
      return new Hash(sha(alg))
    }
    
    },{"cipher-base":94,"inherits":182,"md5.js":191,"ripemd160":337,"sha.js":341}],103:[function(require,module,exports){
    var MD5 = require('md5.js')
    
    module.exports = function (buffer) {
      return new MD5().update(buffer).digest()
    }
    
    },{"md5.js":191}],104:[function(require,module,exports){
    'use strict'
    var inherits = require('inherits')
    var Legacy = require('./legacy')
    var Base = require('cipher-base')
    var Buffer = require('safe-buffer').Buffer
    var md5 = require('create-hash/md5')
    var RIPEMD160 = require('ripemd160')
    
    var sha = require('sha.js')
    
    var ZEROS = Buffer.alloc(128)
    
    function Hmac (alg, key) {
      Base.call(this, 'digest')
      if (typeof key === 'string') {
        key = Buffer.from(key)
      }
    
      var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
    
      this._alg = alg
      this._key = key
      if (key.length > blocksize) {
        var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
        key = hash.update(key).digest()
      } else if (key.length < blocksize) {
        key = Buffer.concat([key, ZEROS], blocksize)
      }
    
      var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
      var opad = this._opad = Buffer.allocUnsafe(blocksize)
    
      for (var i = 0; i < blocksize; i++) {
        ipad[i] = key[i] ^ 0x36
        opad[i] = key[i] ^ 0x5C
      }
      this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)
      this._hash.update(ipad)
    }
    
    inherits(Hmac, Base)
    
    Hmac.prototype._update = function (data) {
      this._hash.update(data)
    }
    
    Hmac.prototype._final = function () {
      var h = this._hash.digest()
      var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg)
      return hash.update(this._opad).update(h).digest()
    }
    
    module.exports = function createHmac (alg, key) {
      alg = alg.toLowerCase()
      if (alg === 'rmd160' || alg === 'ripemd160') {
        return new Hmac('rmd160', key)
      }
      if (alg === 'md5') {
        return new Legacy(md5, key)
      }
      return new Hmac(alg, key)
    }
    
    },{"./legacy":105,"cipher-base":94,"create-hash/md5":103,"inherits":182,"ripemd160":337,"safe-buffer":338,"sha.js":341}],105:[function(require,module,exports){
    'use strict'
    var inherits = require('inherits')
    var Buffer = require('safe-buffer').Buffer
    
    var Base = require('cipher-base')
    
    var ZEROS = Buffer.alloc(128)
    var blocksize = 64
    
    function Hmac (alg, key) {
      Base.call(this, 'digest')
      if (typeof key === 'string') {
        key = Buffer.from(key)
      }
    
      this._alg = alg
      this._key = key
    
      if (key.length > blocksize) {
        key = alg(key)
      } else if (key.length < blocksize) {
        key = Buffer.concat([key, ZEROS], blocksize)
      }
    
      var ipad = this._ipad = Buffer.allocUnsafe(blocksize)
      var opad = this._opad = Buffer.allocUnsafe(blocksize)
    
      for (var i = 0; i < blocksize; i++) {
        ipad[i] = key[i] ^ 0x36
        opad[i] = key[i] ^ 0x5C
      }
    
      this._hash = [ipad]
    }
    
    inherits(Hmac, Base)
    
    Hmac.prototype._update = function (data) {
      this._hash.push(data)
    }
    
    Hmac.prototype._final = function () {
      var h = this._alg(Buffer.concat(this._hash))
      return this._alg(Buffer.concat([this._opad, h]))
    }
    module.exports = Hmac
    
    },{"cipher-base":94,"inherits":182,"safe-buffer":338}],106:[function(require,module,exports){
    (function() {
      var base64map
          = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
    
      crypt = {
        // Bit-wise rotation left
        rotl: function(n, b) {
          return (n << b) | (n >>> (32 - b));
        },
    
        // Bit-wise rotation right
        rotr: function(n, b) {
          return (n << (32 - b)) | (n >>> b);
        },
    
        // Swap big-endian to little-endian and vice versa
        endian: function(n) {
          // If number given, swap endian
          if (n.constructor == Number) {
            return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
          }
    
          // Else, assume array and swap all items
          for (var i = 0; i < n.length; i++)
            n[i] = crypt.endian(n[i]);
          return n;
        },
    
        // Generate an array of any length of random bytes
        randomBytes: function(n) {
          for (var bytes = []; n > 0; n--)
            bytes.push(Math.floor(Math.random() * 256));
          return bytes;
        },
    
        // Convert a byte array to big-endian 32-bit words
        bytesToWords: function(bytes) {
          for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
            words[b >>> 5] |= bytes[i] << (24 - b % 32);
          return words;
        },
    
        // Convert big-endian 32-bit words to a byte array
        wordsToBytes: function(words) {
          for (var bytes = [], b = 0; b < words.length * 32; b += 8)
            bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
          return bytes;
        },
    
        // Convert a byte array to a hex string
        bytesToHex: function(bytes) {
          for (var hex = [], i = 0; i < bytes.length; i++) {
            hex.push((bytes[i] >>> 4).toString(16));
            hex.push((bytes[i] & 0xF).toString(16));
          }
          return hex.join('');
        },
    
        // Convert a hex string to a byte array
        hexToBytes: function(hex) {
          for (var bytes = [], c = 0; c < hex.length; c += 2)
            bytes.push(parseInt(hex.substr(c, 2), 16));
          return bytes;
        },
    
        // Convert a byte array to a base-64 string
        bytesToBase64: function(bytes) {
          for (var base64 = [], i = 0; i < bytes.length; i += 3) {
            var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
            for (var j = 0; j < 4; j++)
              if (i * 8 + j * 6 <= bytes.length * 8)
                base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
              else
                base64.push('=');
          }
          return base64.join('');
        },
    
        // Convert a base-64 string to a byte array
        base64ToBytes: function(base64) {
          // Remove non-base-64 characters
          base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');
    
          for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
              imod4 = ++i % 4) {
            if (imod4 == 0) continue;
            bytes.push(((base64map.indexOf(base64.charAt(i - 1))
                & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
                | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
          }
          return bytes;
        }
      };
    
      module.exports = crypt;
    })();
    
    },{}],107:[function(require,module,exports){
    'use strict'
    
    exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes')
    exports.createHash = exports.Hash = require('create-hash')
    exports.createHmac = exports.Hmac = require('create-hmac')
    
    var algos = require('browserify-sign/algos')
    var algoKeys = Object.keys(algos)
    var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(algoKeys)
    exports.getHashes = function () {
      return hashes
    }
    
    var p = require('pbkdf2')
    exports.pbkdf2 = p.pbkdf2
    exports.pbkdf2Sync = p.pbkdf2Sync
    
    var aes = require('browserify-cipher')
    
    exports.Cipher = aes.Cipher
    exports.createCipher = aes.createCipher
    exports.Cipheriv = aes.Cipheriv
    exports.createCipheriv = aes.createCipheriv
    exports.Decipher = aes.Decipher
    exports.createDecipher = aes.createDecipher
    exports.Decipheriv = aes.Decipheriv
    exports.createDecipheriv = aes.createDecipheriv
    exports.getCiphers = aes.getCiphers
    exports.listCiphers = aes.listCiphers
    
    var dh = require('diffie-hellman')
    
    exports.DiffieHellmanGroup = dh.DiffieHellmanGroup
    exports.createDiffieHellmanGroup = dh.createDiffieHellmanGroup
    exports.getDiffieHellman = dh.getDiffieHellman
    exports.createDiffieHellman = dh.createDiffieHellman
    exports.DiffieHellman = dh.DiffieHellman
    
    var sign = require('browserify-sign')
    
    exports.createSign = sign.createSign
    exports.Sign = sign.Sign
    exports.createVerify = sign.createVerify
    exports.Verify = sign.Verify
    
    exports.createECDH = require('create-ecdh')
    
    var publicEncrypt = require('public-encrypt')
    
    exports.publicEncrypt = publicEncrypt.publicEncrypt
    exports.privateEncrypt = publicEncrypt.privateEncrypt
    exports.publicDecrypt = publicEncrypt.publicDecrypt
    exports.privateDecrypt = publicEncrypt.privateDecrypt
    
    // the least I can do is make error messages for the rest of the node.js/crypto api.
    // ;[
    //   'createCredentials'
    // ].forEach(function (name) {
    //   exports[name] = function () {
    //     throw new Error([
    //       'sorry, ' + name + ' is not implemented yet',
    //       'we accept pull requests',
    //       'https://github.com/crypto-browserify/crypto-browserify'
    //     ].join('\n'))
    //   }
    // })
    
    var rf = require('randomfill')
    
    exports.randomFill = rf.randomFill
    exports.randomFillSync = rf.randomFillSync
    
    exports.createCredentials = function () {
      throw new Error([
        'sorry, createCredentials is not implemented yet',
        'we accept pull requests',
        'https://github.com/crypto-browserify/crypto-browserify'
      ].join('\n'))
    }
    
    exports.constants = {
      'DH_CHECK_P_NOT_SAFE_PRIME': 2,
      'DH_CHECK_P_NOT_PRIME': 1,
      'DH_UNABLE_TO_CHECK_GENERATOR': 4,
      'DH_NOT_SUITABLE_GENERATOR': 8,
      'NPN_ENABLED': 1,
      'ALPN_ENABLED': 1,
      'RSA_PKCS1_PADDING': 1,
      'RSA_SSLV23_PADDING': 2,
      'RSA_NO_PADDING': 3,
      'RSA_PKCS1_OAEP_PADDING': 4,
      'RSA_X931_PADDING': 5,
      'RSA_PKCS1_PSS_PADDING': 6,
      'POINT_CONVERSION_COMPRESSED': 2,
      'POINT_CONVERSION_UNCOMPRESSED': 4,
      'POINT_CONVERSION_HYBRID': 6
    }
    
    },{"browserify-cipher":54,"browserify-sign":62,"browserify-sign/algos":59,"create-ecdh":101,"create-hash":102,"create-hmac":104,"diffie-hellman":114,"pbkdf2":315,"public-encrypt":322,"randombytes":334,"randomfill":335}],108:[function(require,module,exports){
    'use strict';
    
    exports.utils = require('./des/utils');
    exports.Cipher = require('./des/cipher');
    exports.DES = require('./des/des');
    exports.CBC = require('./des/cbc');
    exports.EDE = require('./des/ede');
    
    },{"./des/cbc":109,"./des/cipher":110,"./des/des":111,"./des/ede":112,"./des/utils":113}],109:[function(require,module,exports){
    'use strict';
    
    var assert = require('minimalistic-assert');
    var inherits = require('inherits');
    
    var proto = {};
    
    function CBCState(iv) {
      assert.equal(iv.length, 8, 'Invalid IV length');
    
      this.iv = new Array(8);
      for (var i = 0; i < this.iv.length; i++)
        this.iv[i] = iv[i];
    }
    
    function instantiate(Base) {
      function CBC(options) {
        Base.call(this, options);
        this._cbcInit();
      }
      inherits(CBC, Base);
    
      var keys = Object.keys(proto);
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        CBC.prototype[key] = proto[key];
      }
    
      CBC.create = function create(options) {
        return new CBC(options);
      };
    
      return CBC;
    }
    
    exports.instantiate = instantiate;
    
    proto._cbcInit = function _cbcInit() {
      var state = new CBCState(this.options.iv);
      this._cbcState = state;
    };
    
    proto._update = function _update(inp, inOff, out, outOff) {
      var state = this._cbcState;
      var superProto = this.constructor.super_.prototype;
    
      var iv = state.iv;
      if (this.type === 'encrypt') {
        for (var i = 0; i < this.blockSize; i++)
          iv[i] ^= inp[inOff + i];
    
        superProto._update.call(this, iv, 0, out, outOff);
    
        for (var i = 0; i < this.blockSize; i++)
          iv[i] = out[outOff + i];
      } else {
        superProto._update.call(this, inp, inOff, out, outOff);
    
        for (var i = 0; i < this.blockSize; i++)
          out[outOff + i] ^= iv[i];
    
        for (var i = 0; i < this.blockSize; i++)
          iv[i] = inp[inOff + i];
      }
    };
    
    },{"inherits":182,"minimalistic-assert":194}],110:[function(require,module,exports){
    'use strict';
    
    var assert = require('minimalistic-assert');
    
    function Cipher(options) {
      this.options = options;
    
      this.type = this.options.type;
      this.blockSize = 8;
      this._init();
    
      this.buffer = new Array(this.blockSize);
      this.bufferOff = 0;
      this.padding = options.padding !== false
    }
    module.exports = Cipher;
    
    Cipher.prototype._init = function _init() {
      // Might be overrided
    };
    
    Cipher.prototype.update = function update(data) {
      if (data.length === 0)
        return [];
    
      if (this.type === 'decrypt')
        return this._updateDecrypt(data);
      else
        return this._updateEncrypt(data);
    };
    
    Cipher.prototype._buffer = function _buffer(data, off) {
      // Append data to buffer
      var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);
      for (var i = 0; i < min; i++)
        this.buffer[this.bufferOff + i] = data[off + i];
      this.bufferOff += min;
    
      // Shift next
      return min;
    };
    
    Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {
      this._update(this.buffer, 0, out, off);
      this.bufferOff = 0;
      return this.blockSize;
    };
    
    Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {
      var inputOff = 0;
      var outputOff = 0;
    
      var count = ((this.bufferOff + data.length) / this.blockSize) | 0;
      var out = new Array(count * this.blockSize);
    
      if (this.bufferOff !== 0) {
        inputOff += this._buffer(data, inputOff);
    
        if (this.bufferOff === this.buffer.length)
          outputOff += this._flushBuffer(out, outputOff);
      }
    
      // Write blocks
      var max = data.length - ((data.length - inputOff) % this.blockSize);
      for (; inputOff < max; inputOff += this.blockSize) {
        this._update(data, inputOff, out, outputOff);
        outputOff += this.blockSize;
      }
    
      // Queue rest
      for (; inputOff < data.length; inputOff++, this.bufferOff++)
        this.buffer[this.bufferOff] = data[inputOff];
    
      return out;
    };
    
    Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {
      var inputOff = 0;
      var outputOff = 0;
    
      var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;
      var out = new Array(count * this.blockSize);
    
      // TODO(indutny): optimize it, this is far from optimal
      for (; count > 0; count--) {
        inputOff += this._buffer(data, inputOff);
        outputOff += this._flushBuffer(out, outputOff);
      }
    
      // Buffer rest of the input
      inputOff += this._buffer(data, inputOff);
    
      return out;
    };
    
    Cipher.prototype.final = function final(buffer) {
      var first;
      if (buffer)
        first = this.update(buffer);
    
      var last;
      if (this.type === 'encrypt')
        last = this._finalEncrypt();
      else
        last = this._finalDecrypt();
    
      if (first)
        return first.concat(last);
      else
        return last;
    };
    
    Cipher.prototype._pad = function _pad(buffer, off) {
      if (off === 0)
        return false;
    
      while (off < buffer.length)
        buffer[off++] = 0;
    
      return true;
    };
    
    Cipher.prototype._finalEncrypt = function _finalEncrypt() {
      if (!this._pad(this.buffer, this.bufferOff))
        return [];
    
      var out = new Array(this.blockSize);
      this._update(this.buffer, 0, out, 0);
      return out;
    };
    
    Cipher.prototype._unpad = function _unpad(buffer) {
      return buffer;
    };
    
    Cipher.prototype._finalDecrypt = function _finalDecrypt() {
      assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');
      var out = new Array(this.blockSize);
      this._flushBuffer(out, 0);
    
      return this._unpad(out);
    };
    
    },{"minimalistic-assert":194}],111:[function(require,module,exports){
    'use strict';
    
    var assert = require('minimalistic-assert');
    var inherits = require('inherits');
    
    var utils = require('./utils');
    var Cipher = require('./cipher');
    
    function DESState() {
      this.tmp = new Array(2);
      this.keys = null;
    }
    
    function DES(options) {
      Cipher.call(this, options);
    
      var state = new DESState();
      this._desState = state;
    
      this.deriveKeys(state, options.key);
    }
    inherits(DES, Cipher);
    module.exports = DES;
    
    DES.create = function create(options) {
      return new DES(options);
    };
    
    var shiftTable = [
      1, 1, 2, 2, 2, 2, 2, 2,
      1, 2, 2, 2, 2, 2, 2, 1
    ];
    
    DES.prototype.deriveKeys = function deriveKeys(state, key) {
      state.keys = new Array(16 * 2);
    
      assert.equal(key.length, this.blockSize, 'Invalid key length');
    
      var kL = utils.readUInt32BE(key, 0);
      var kR = utils.readUInt32BE(key, 4);
    
      utils.pc1(kL, kR, state.tmp, 0);
      kL = state.tmp[0];
      kR = state.tmp[1];
      for (var i = 0; i < state.keys.length; i += 2) {
        var shift = shiftTable[i >>> 1];
        kL = utils.r28shl(kL, shift);
        kR = utils.r28shl(kR, shift);
        utils.pc2(kL, kR, state.keys, i);
      }
    };
    
    DES.prototype._update = function _update(inp, inOff, out, outOff) {
      var state = this._desState;
    
      var l = utils.readUInt32BE(inp, inOff);
      var r = utils.readUInt32BE(inp, inOff + 4);
    
      // Initial Permutation
      utils.ip(l, r, state.tmp, 0);
      l = state.tmp[0];
      r = state.tmp[1];
    
      if (this.type === 'encrypt')
        this._encrypt(state, l, r, state.tmp, 0);
      else
        this._decrypt(state, l, r, state.tmp, 0);
    
      l = state.tmp[0];
      r = state.tmp[1];
    
      utils.writeUInt32BE(out, l, outOff);
      utils.writeUInt32BE(out, r, outOff + 4);
    };
    
    DES.prototype._pad = function _pad(buffer, off) {
      if (this.padding === false) {
        return false;
      }
    
      var value = buffer.length - off;
      for (var i = off; i < buffer.length; i++)
        buffer[i] = value;
    
      return true;
    };
    
    DES.prototype._unpad = function _unpad(buffer) {
      if (this.padding === false) {
        return buffer;
      }
    
      var pad = buffer[buffer.length - 1];
      for (var i = buffer.length - pad; i < buffer.length; i++)
        assert.equal(buffer[i], pad);
    
      return buffer.slice(0, buffer.length - pad);
    };
    
    DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
      var l = lStart;
      var r = rStart;
    
      // Apply f() x16 times
      for (var i = 0; i < state.keys.length; i += 2) {
        var keyL = state.keys[i];
        var keyR = state.keys[i + 1];
    
        // f(r, k)
        utils.expand(r, state.tmp, 0);
    
        keyL ^= state.tmp[0];
        keyR ^= state.tmp[1];
        var s = utils.substitute(keyL, keyR);
        var f = utils.permute(s);
    
        var t = r;
        r = (l ^ f) >>> 0;
        l = t;
      }
    
      // Reverse Initial Permutation
      utils.rip(r, l, out, off);
    };
    
    DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
      var l = rStart;
      var r = lStart;
    
      // Apply f() x16 times
      for (var i = state.keys.length - 2; i >= 0; i -= 2) {
        var keyL = state.keys[i];
        var keyR = state.keys[i + 1];
    
        // f(r, k)
        utils.expand(l, state.tmp, 0);
    
        keyL ^= state.tmp[0];
        keyR ^= state.tmp[1];
        var s = utils.substitute(keyL, keyR);
        var f = utils.permute(s);
    
        var t = l;
        l = (r ^ f) >>> 0;
        r = t;
      }
    
      // Reverse Initial Permutation
      utils.rip(l, r, out, off);
    };
    
    },{"./cipher":110,"./utils":113,"inherits":182,"minimalistic-assert":194}],112:[function(require,module,exports){
    'use strict';
    
    var assert = require('minimalistic-assert');
    var inherits = require('inherits');
    
    var Cipher = require('./cipher');
    var DES = require('./des');
    
    function EDEState(type, key) {
      assert.equal(key.length, 24, 'Invalid key length');
    
      var k1 = key.slice(0, 8);
      var k2 = key.slice(8, 16);
      var k3 = key.slice(16, 24);
    
      if (type === 'encrypt') {
        this.ciphers = [
          DES.create({ type: 'encrypt', key: k1 }),
          DES.create({ type: 'decrypt', key: k2 }),
          DES.create({ type: 'encrypt', key: k3 })
        ];
      } else {
        this.ciphers = [
          DES.create({ type: 'decrypt', key: k3 }),
          DES.create({ type: 'encrypt', key: k2 }),
          DES.create({ type: 'decrypt', key: k1 })
        ];
      }
    }
    
    function EDE(options) {
      Cipher.call(this, options);
    
      var state = new EDEState(this.type, this.options.key);
      this._edeState = state;
    }
    inherits(EDE, Cipher);
    
    module.exports = EDE;
    
    EDE.create = function create(options) {
      return new EDE(options);
    };
    
    EDE.prototype._update = function _update(inp, inOff, out, outOff) {
      var state = this._edeState;
    
      state.ciphers[0]._update(inp, inOff, out, outOff);
      state.ciphers[1]._update(out, outOff, out, outOff);
      state.ciphers[2]._update(out, outOff, out, outOff);
    };
    
    EDE.prototype._pad = DES.prototype._pad;
    EDE.prototype._unpad = DES.prototype._unpad;
    
    },{"./cipher":110,"./des":111,"inherits":182,"minimalistic-assert":194}],113:[function(require,module,exports){
    'use strict';
    
    exports.readUInt32BE = function readUInt32BE(bytes, off) {
      var res =  (bytes[0 + off] << 24) |
                 (bytes[1 + off] << 16) |
                 (bytes[2 + off] << 8) |
                 bytes[3 + off];
      return res >>> 0;
    };
    
    exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) {
      bytes[0 + off] = value >>> 24;
      bytes[1 + off] = (value >>> 16) & 0xff;
      bytes[2 + off] = (value >>> 8) & 0xff;
      bytes[3 + off] = value & 0xff;
    };
    
    exports.ip = function ip(inL, inR, out, off) {
      var outL = 0;
      var outR = 0;
    
      for (var i = 6; i >= 0; i -= 2) {
        for (var j = 0; j <= 24; j += 8) {
          outL <<= 1;
          outL |= (inR >>> (j + i)) & 1;
        }
        for (var j = 0; j <= 24; j += 8) {
          outL <<= 1;
          outL |= (inL >>> (j + i)) & 1;
        }
      }
    
      for (var i = 6; i >= 0; i -= 2) {
        for (var j = 1; j <= 25; j += 8) {
          outR <<= 1;
          outR |= (inR >>> (j + i)) & 1;
        }
        for (var j = 1; j <= 25; j += 8) {
          outR <<= 1;
          outR |= (inL >>> (j + i)) & 1;
        }
      }
    
      out[off + 0] = outL >>> 0;
      out[off + 1] = outR >>> 0;
    };
    
    exports.rip = function rip(inL, inR, out, off) {
      var outL = 0;
      var outR = 0;
    
      for (var i = 0; i < 4; i++) {
        for (var j = 24; j >= 0; j -= 8) {
          outL <<= 1;
          outL |= (inR >>> (j + i)) & 1;
          outL <<= 1;
          outL |= (inL >>> (j + i)) & 1;
        }
      }
      for (var i = 4; i < 8; i++) {
        for (var j = 24; j >= 0; j -= 8) {
          outR <<= 1;
          outR |= (inR >>> (j + i)) & 1;
          outR <<= 1;
          outR |= (inL >>> (j + i)) & 1;
        }
      }
    
      out[off + 0] = outL >>> 0;
      out[off + 1] = outR >>> 0;
    };
    
    exports.pc1 = function pc1(inL, inR, out, off) {
      var outL = 0;
      var outR = 0;
    
      // 7, 15, 23, 31, 39, 47, 55, 63
      // 6, 14, 22, 30, 39, 47, 55, 63
      // 5, 13, 21, 29, 39, 47, 55, 63
      // 4, 12, 20, 28
      for (var i = 7; i >= 5; i--) {
        for (var j = 0; j <= 24; j += 8) {
          outL <<= 1;
          outL |= (inR >> (j + i)) & 1;
        }
        for (var j = 0; j <= 24; j += 8) {
          outL <<= 1;
          outL |= (inL >> (j + i)) & 1;
        }
      }
      for (var j = 0; j <= 24; j += 8) {
        outL <<= 1;
        outL |= (inR >> (j + i)) & 1;
      }
    
      // 1, 9, 17, 25, 33, 41, 49, 57
      // 2, 10, 18, 26, 34, 42, 50, 58
      // 3, 11, 19, 27, 35, 43, 51, 59
      // 36, 44, 52, 60
      for (var i = 1; i <= 3; i++) {
        for (var j = 0; j <= 24; j += 8) {
          outR <<= 1;
          outR |= (inR >> (j + i)) & 1;
        }
        for (var j = 0; j <= 24; j += 8) {
          outR <<= 1;
          outR |= (inL >> (j + i)) & 1;
        }
      }
      for (var j = 0; j <= 24; j += 8) {
        outR <<= 1;
        outR |= (inL >> (j + i)) & 1;
      }
    
      out[off + 0] = outL >>> 0;
      out[off + 1] = outR >>> 0;
    };
    
    exports.r28shl = function r28shl(num, shift) {
      return ((num << shift) & 0xfffffff) | (num >>> (28 - shift));
    };
    
    var pc2table = [
      // inL => outL
      14, 11, 17, 4, 27, 23, 25, 0,
      13, 22, 7, 18, 5, 9, 16, 24,
      2, 20, 12, 21, 1, 8, 15, 26,
    
      // inR => outR
      15, 4, 25, 19, 9, 1, 26, 16,
      5, 11, 23, 8, 12, 7, 17, 0,
      22, 3, 10, 14, 6, 20, 27, 24
    ];
    
    exports.pc2 = function pc2(inL, inR, out, off) {
      var outL = 0;
      var outR = 0;
    
      var len = pc2table.length >>> 1;
      for (var i = 0; i < len; i++) {
        outL <<= 1;
        outL |= (inL >>> pc2table[i]) & 0x1;
      }
      for (var i = len; i < pc2table.length; i++) {
        outR <<= 1;
        outR |= (inR >>> pc2table[i]) & 0x1;
      }
    
      out[off + 0] = outL >>> 0;
      out[off + 1] = outR >>> 0;
    };
    
    exports.expand = function expand(r, out, off) {
      var outL = 0;
      var outR = 0;
    
      outL = ((r & 1) << 5) | (r >>> 27);
      for (var i = 23; i >= 15; i -= 4) {
        outL <<= 6;
        outL |= (r >>> i) & 0x3f;
      }
      for (var i = 11; i >= 3; i -= 4) {
        outR |= (r >>> i) & 0x3f;
        outR <<= 6;
      }
      outR |= ((r & 0x1f) << 1) | (r >>> 31);
    
      out[off + 0] = outL >>> 0;
      out[off + 1] = outR >>> 0;
    };
    
    var sTable = [
      14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
      3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
      4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
      15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,
    
      15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
      9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
      0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
      5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,
    
      10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
      1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
      13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
      11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,
    
      7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
      1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
      10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
      15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,
    
      2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
      8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
      4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
      15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,
    
      12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
      0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
      9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
      7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,
    
      4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
      3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
      1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
      10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,
    
      13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
      10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
      7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
      0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
    ];
    
    exports.substitute = function substitute(inL, inR) {
      var out = 0;
      for (var i = 0; i < 4; i++) {
        var b = (inL >>> (18 - i * 6)) & 0x3f;
        var sb = sTable[i * 0x40 + b];
    
        out <<= 4;
        out |= sb;
      }
      for (var i = 0; i < 4; i++) {
        var b = (inR >>> (18 - i * 6)) & 0x3f;
        var sb = sTable[4 * 0x40 + i * 0x40 + b];
    
        out <<= 4;
        out |= sb;
      }
      return out >>> 0;
    };
    
    var permuteTable = [
      16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,
      30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7
    ];
    
    exports.permute = function permute(num) {
      var out = 0;
      for (var i = 0; i < permuteTable.length; i++) {
        out <<= 1;
        out |= (num >>> permuteTable[i]) & 0x1;
      }
      return out >>> 0;
    };
    
    exports.padSplit = function padSplit(num, size, group) {
      var str = num.toString(2);
      while (str.length < size)
        str = '0' + str;
    
      var out = [];
      for (var i = 0; i < size; i += group)
        out.push(str.slice(i, i + group));
      return out.join(' ');
    };
    
    },{}],114:[function(require,module,exports){
    (function (Buffer){(function (){
    var generatePrime = require('./lib/generatePrime')
    var primes = require('./lib/primes.json')
    
    var DH = require('./lib/dh')
    
    function getDiffieHellman (mod) {
      var prime = new Buffer(primes[mod].prime, 'hex')
      var gen = new Buffer(primes[mod].gen, 'hex')
    
      return new DH(prime, gen)
    }
    
    var ENCODINGS = {
      'binary': true, 'hex': true, 'base64': true
    }
    
    function createDiffieHellman (prime, enc, generator, genc) {
      if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
        return createDiffieHellman(prime, 'binary', enc, generator)
      }
    
      enc = enc || 'binary'
      genc = genc || 'binary'
      generator = generator || new Buffer([2])
    
      if (!Buffer.isBuffer(generator)) {
        generator = new Buffer(generator, genc)
      }
    
      if (typeof prime === 'number') {
        return new DH(generatePrime(prime, generator), generator, true)
      }
    
      if (!Buffer.isBuffer(prime)) {
        prime = new Buffer(prime, enc)
      }
    
      return new DH(prime, generator, true)
    }
    
    exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
    exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./lib/dh":115,"./lib/generatePrime":116,"./lib/primes.json":117,"buffer":84}],115:[function(require,module,exports){
    (function (Buffer){(function (){
    var BN = require('bn.js');
    var MillerRabin = require('miller-rabin');
    var millerRabin = new MillerRabin();
    var TWENTYFOUR = new BN(24);
    var ELEVEN = new BN(11);
    var TEN = new BN(10);
    var THREE = new BN(3);
    var SEVEN = new BN(7);
    var primes = require('./generatePrime');
    var randomBytes = require('randombytes');
    module.exports = DH;
    
    function setPublicKey(pub, enc) {
      enc = enc || 'utf8';
      if (!Buffer.isBuffer(pub)) {
        pub = new Buffer(pub, enc);
      }
      this._pub = new BN(pub);
      return this;
    }
    
    function setPrivateKey(priv, enc) {
      enc = enc || 'utf8';
      if (!Buffer.isBuffer(priv)) {
        priv = new Buffer(priv, enc);
      }
      this._priv = new BN(priv);
      return this;
    }
    
    var primeCache = {};
    function checkPrime(prime, generator) {
      var gen = generator.toString('hex');
      var hex = [gen, prime.toString(16)].join('_');
      if (hex in primeCache) {
        return primeCache[hex];
      }
      var error = 0;
    
      if (prime.isEven() ||
        !primes.simpleSieve ||
        !primes.fermatTest(prime) ||
        !millerRabin.test(prime)) {
        //not a prime so +1
        error += 1;
    
        if (gen === '02' || gen === '05') {
          // we'd be able to check the generator
          // it would fail so +8
          error += 8;
        } else {
          //we wouldn't be able to test the generator
          // so +4
          error += 4;
        }
        primeCache[hex] = error;
        return error;
      }
      if (!millerRabin.test(prime.shrn(1))) {
        //not a safe prime
        error += 2;
      }
      var rem;
      switch (gen) {
        case '02':
          if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
            // unsuidable generator
            error += 8;
          }
          break;
        case '05':
          rem = prime.mod(TEN);
          if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
            // prime mod 10 needs to equal 3 or 7
            error += 8;
          }
          break;
        default:
          error += 4;
      }
      primeCache[hex] = error;
      return error;
    }
    
    function DH(prime, generator, malleable) {
      this.setGenerator(generator);
      this.__prime = new BN(prime);
      this._prime = BN.mont(this.__prime);
      this._primeLen = prime.length;
      this._pub = undefined;
      this._priv = undefined;
      this._primeCode = undefined;
      if (malleable) {
        this.setPublicKey = setPublicKey;
        this.setPrivateKey = setPrivateKey;
      } else {
        this._primeCode = 8;
      }
    }
    Object.defineProperty(DH.prototype, 'verifyError', {
      enumerable: true,
      get: function () {
        if (typeof this._primeCode !== 'number') {
          this._primeCode = checkPrime(this.__prime, this.__gen);
        }
        return this._primeCode;
      }
    });
    DH.prototype.generateKeys = function () {
      if (!this._priv) {
        this._priv = new BN(randomBytes(this._primeLen));
      }
      this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
      return this.getPublicKey();
    };
    
    DH.prototype.computeSecret = function (other) {
      other = new BN(other);
      other = other.toRed(this._prime);
      var secret = other.redPow(this._priv).fromRed();
      var out = new Buffer(secret.toArray());
      var prime = this.getPrime();
      if (out.length < prime.length) {
        var front = new Buffer(prime.length - out.length);
        front.fill(0);
        out = Buffer.concat([front, out]);
      }
      return out;
    };
    
    DH.prototype.getPublicKey = function getPublicKey(enc) {
      return formatReturnValue(this._pub, enc);
    };
    
    DH.prototype.getPrivateKey = function getPrivateKey(enc) {
      return formatReturnValue(this._priv, enc);
    };
    
    DH.prototype.getPrime = function (enc) {
      return formatReturnValue(this.__prime, enc);
    };
    
    DH.prototype.getGenerator = function (enc) {
      return formatReturnValue(this._gen, enc);
    };
    
    DH.prototype.setGenerator = function (gen, enc) {
      enc = enc || 'utf8';
      if (!Buffer.isBuffer(gen)) {
        gen = new Buffer(gen, enc);
      }
      this.__gen = gen;
      this._gen = new BN(gen);
      return this;
    };
    
    function formatReturnValue(bn, enc) {
      var buf = new Buffer(bn.toArray());
      if (!enc) {
        return buf;
      } else {
        return buf.toString(enc);
      }
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./generatePrime":116,"bn.js":33,"buffer":84,"miller-rabin":193,"randombytes":334}],116:[function(require,module,exports){
    var randomBytes = require('randombytes');
    module.exports = findPrime;
    findPrime.simpleSieve = simpleSieve;
    findPrime.fermatTest = fermatTest;
    var BN = require('bn.js');
    var TWENTYFOUR = new BN(24);
    var MillerRabin = require('miller-rabin');
    var millerRabin = new MillerRabin();
    var ONE = new BN(1);
    var TWO = new BN(2);
    var FIVE = new BN(5);
    var SIXTEEN = new BN(16);
    var EIGHT = new BN(8);
    var TEN = new BN(10);
    var THREE = new BN(3);
    var SEVEN = new BN(7);
    var ELEVEN = new BN(11);
    var FOUR = new BN(4);
    var TWELVE = new BN(12);
    var primes = null;
    
    function _getPrimes() {
      if (primes !== null)
        return primes;
    
      var limit = 0x100000;
      var res = [];
      res[0] = 2;
      for (var i = 1, k = 3; k < limit; k += 2) {
        var sqrt = Math.ceil(Math.sqrt(k));
        for (var j = 0; j < i && res[j] <= sqrt; j++)
          if (k % res[j] === 0)
            break;
    
        if (i !== j && res[j] <= sqrt)
          continue;
    
        res[i++] = k;
      }
      primes = res;
      return res;
    }
    
    function simpleSieve(p) {
      var primes = _getPrimes();
    
      for (var i = 0; i < primes.length; i++)
        if (p.modn(primes[i]) === 0) {
          if (p.cmpn(primes[i]) === 0) {
            return true;
          } else {
            return false;
          }
        }
    
      return true;
    }
    
    function fermatTest(p) {
      var red = BN.mont(p);
      return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
    }
    
    function findPrime(bits, gen) {
      if (bits < 16) {
        // this is what openssl does
        if (gen === 2 || gen === 5) {
          return new BN([0x8c, 0x7b]);
        } else {
          return new BN([0x8c, 0x27]);
        }
      }
      gen = new BN(gen);
    
      var num, n2;
    
      while (true) {
        num = new BN(randomBytes(Math.ceil(bits / 8)));
        while (num.bitLength() > bits) {
          num.ishrn(1);
        }
        if (num.isEven()) {
          num.iadd(ONE);
        }
        if (!num.testn(1)) {
          num.iadd(TWO);
        }
        if (!gen.cmp(TWO)) {
          while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
            num.iadd(FOUR);
          }
        } else if (!gen.cmp(FIVE)) {
          while (num.mod(TEN).cmp(THREE)) {
            num.iadd(FOUR);
          }
        }
        n2 = num.shrn(1);
        if (simpleSieve(n2) && simpleSieve(num) &&
          fermatTest(n2) && fermatTest(num) &&
          millerRabin.test(n2) && millerRabin.test(num)) {
          return num;
        }
      }
    
    }
    
    },{"bn.js":33,"miller-rabin":193,"randombytes":334}],117:[function(require,module,exports){
    module.exports={
        "modp1": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"
        },
        "modp2": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"
        },
        "modp5": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"
        },
        "modp14": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"
        },
        "modp15": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"
        },
        "modp16": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"
        },
        "modp17": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"
        },
        "modp18": {
            "gen": "02",
            "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"
        }
    }
    },{}],118:[function(require,module,exports){
    'use strict';
    
    var elliptic = exports;
    
    elliptic.version = require('../package.json').version;
    elliptic.utils = require('./elliptic/utils');
    elliptic.rand = require('brorand');
    elliptic.curve = require('./elliptic/curve');
    elliptic.curves = require('./elliptic/curves');
    
    // Protocols
    elliptic.ec = require('./elliptic/ec');
    elliptic.eddsa = require('./elliptic/eddsa');
    
    },{"../package.json":133,"./elliptic/curve":121,"./elliptic/curves":124,"./elliptic/ec":125,"./elliptic/eddsa":128,"./elliptic/utils":132,"brorand":35}],119:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    var utils = require('../utils');
    var getNAF = utils.getNAF;
    var getJSF = utils.getJSF;
    var assert = utils.assert;
    
    function BaseCurve(type, conf) {
      this.type = type;
      this.p = new BN(conf.p, 16);
    
      // Use Montgomery, when there is no fast reduction for the prime
      this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
    
      // Useful for many curves
      this.zero = new BN(0).toRed(this.red);
      this.one = new BN(1).toRed(this.red);
      this.two = new BN(2).toRed(this.red);
    
      // Curve configuration, optional
      this.n = conf.n && new BN(conf.n, 16);
      this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
    
      // Temporary arrays
      this._wnafT1 = new Array(4);
      this._wnafT2 = new Array(4);
      this._wnafT3 = new Array(4);
      this._wnafT4 = new Array(4);
    
      this._bitLength = this.n ? this.n.bitLength() : 0;
    
      // Generalized Greg Maxwell's trick
      var adjustCount = this.n && this.p.div(this.n);
      if (!adjustCount || adjustCount.cmpn(100) > 0) {
        this.redN = null;
      } else {
        this._maxwellTrick = true;
        this.redN = this.n.toRed(this.red);
      }
    }
    module.exports = BaseCurve;
    
    BaseCurve.prototype.point = function point() {
      throw new Error('Not implemented');
    };
    
    BaseCurve.prototype.validate = function validate() {
      throw new Error('Not implemented');
    };
    
    BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
      assert(p.precomputed);
      var doubles = p._getDoubles();
    
      var naf = getNAF(k, 1, this._bitLength);
      var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
      I /= 3;
    
      // Translate into more windowed form
      var repr = [];
      var j;
      var nafW;
      for (j = 0; j < naf.length; j += doubles.step) {
        nafW = 0;
        for (var l = j + doubles.step - 1; l >= j; l--)
          nafW = (nafW << 1) + naf[l];
        repr.push(nafW);
      }
    
      var a = this.jpoint(null, null, null);
      var b = this.jpoint(null, null, null);
      for (var i = I; i > 0; i--) {
        for (j = 0; j < repr.length; j++) {
          nafW = repr[j];
          if (nafW === i)
            b = b.mixedAdd(doubles.points[j]);
          else if (nafW === -i)
            b = b.mixedAdd(doubles.points[j].neg());
        }
        a = a.add(b);
      }
      return a.toP();
    };
    
    BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
      var w = 4;
    
      // Precompute window
      var nafPoints = p._getNAFPoints(w);
      w = nafPoints.wnd;
      var wnd = nafPoints.points;
    
      // Get NAF form
      var naf = getNAF(k, w, this._bitLength);
    
      // Add `this`*(N+1) for every w-NAF index
      var acc = this.jpoint(null, null, null);
      for (var i = naf.length - 1; i >= 0; i--) {
        // Count zeroes
        for (var l = 0; i >= 0 && naf[i] === 0; i--)
          l++;
        if (i >= 0)
          l++;
        acc = acc.dblp(l);
    
        if (i < 0)
          break;
        var z = naf[i];
        assert(z !== 0);
        if (p.type === 'affine') {
          // J +- P
          if (z > 0)
            acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
          else
            acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
        } else {
          // J +- J
          if (z > 0)
            acc = acc.add(wnd[(z - 1) >> 1]);
          else
            acc = acc.add(wnd[(-z - 1) >> 1].neg());
        }
      }
      return p.type === 'affine' ? acc.toP() : acc;
    };
    
    BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
      points,
      coeffs,
      len,
      jacobianResult) {
      var wndWidth = this._wnafT1;
      var wnd = this._wnafT2;
      var naf = this._wnafT3;
    
      // Fill all arrays
      var max = 0;
      var i;
      var j;
      var p;
      for (i = 0; i < len; i++) {
        p = points[i];
        var nafPoints = p._getNAFPoints(defW);
        wndWidth[i] = nafPoints.wnd;
        wnd[i] = nafPoints.points;
      }
    
      // Comb small window NAFs
      for (i = len - 1; i >= 1; i -= 2) {
        var a = i - 1;
        var b = i;
        if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
          naf[a] = getNAF(coeffs[a], wndWidth[a], this._bitLength);
          naf[b] = getNAF(coeffs[b], wndWidth[b], this._bitLength);
          max = Math.max(naf[a].length, max);
          max = Math.max(naf[b].length, max);
          continue;
        }
    
        var comb = [
          points[a], /* 1 */
          null, /* 3 */
          null, /* 5 */
          points[b], /* 7 */
        ];
    
        // Try to avoid Projective points, if possible
        if (points[a].y.cmp(points[b].y) === 0) {
          comb[1] = points[a].add(points[b]);
          comb[2] = points[a].toJ().mixedAdd(points[b].neg());
        } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
          comb[1] = points[a].toJ().mixedAdd(points[b]);
          comb[2] = points[a].add(points[b].neg());
        } else {
          comb[1] = points[a].toJ().mixedAdd(points[b]);
          comb[2] = points[a].toJ().mixedAdd(points[b].neg());
        }
    
        var index = [
          -3, /* -1 -1 */
          -1, /* -1 0 */
          -5, /* -1 1 */
          -7, /* 0 -1 */
          0, /* 0 0 */
          7, /* 0 1 */
          5, /* 1 -1 */
          1, /* 1 0 */
          3,  /* 1 1 */
        ];
    
        var jsf = getJSF(coeffs[a], coeffs[b]);
        max = Math.max(jsf[0].length, max);
        naf[a] = new Array(max);
        naf[b] = new Array(max);
        for (j = 0; j < max; j++) {
          var ja = jsf[0][j] | 0;
          var jb = jsf[1][j] | 0;
    
          naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
          naf[b][j] = 0;
          wnd[a] = comb;
        }
      }
    
      var acc = this.jpoint(null, null, null);
      var tmp = this._wnafT4;
      for (i = max; i >= 0; i--) {
        var k = 0;
    
        while (i >= 0) {
          var zero = true;
          for (j = 0; j < len; j++) {
            tmp[j] = naf[j][i] | 0;
            if (tmp[j] !== 0)
              zero = false;
          }
          if (!zero)
            break;
          k++;
          i--;
        }
        if (i >= 0)
          k++;
        acc = acc.dblp(k);
        if (i < 0)
          break;
    
        for (j = 0; j < len; j++) {
          var z = tmp[j];
          p;
          if (z === 0)
            continue;
          else if (z > 0)
            p = wnd[j][(z - 1) >> 1];
          else if (z < 0)
            p = wnd[j][(-z - 1) >> 1].neg();
    
          if (p.type === 'affine')
            acc = acc.mixedAdd(p);
          else
            acc = acc.add(p);
        }
      }
      // Zeroify references
      for (i = 0; i < len; i++)
        wnd[i] = null;
    
      if (jacobianResult)
        return acc;
      else
        return acc.toP();
    };
    
    function BasePoint(curve, type) {
      this.curve = curve;
      this.type = type;
      this.precomputed = null;
    }
    BaseCurve.BasePoint = BasePoint;
    
    BasePoint.prototype.eq = function eq(/*other*/) {
      throw new Error('Not implemented');
    };
    
    BasePoint.prototype.validate = function validate() {
      return this.curve.validate(this);
    };
    
    BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
      bytes = utils.toArray(bytes, enc);
    
      var len = this.p.byteLength();
    
      // uncompressed, hybrid-odd, hybrid-even
      if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
          bytes.length - 1 === 2 * len) {
        if (bytes[0] === 0x06)
          assert(bytes[bytes.length - 1] % 2 === 0);
        else if (bytes[0] === 0x07)
          assert(bytes[bytes.length - 1] % 2 === 1);
    
        var res =  this.point(bytes.slice(1, 1 + len),
          bytes.slice(1 + len, 1 + 2 * len));
    
        return res;
      } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
                  bytes.length - 1 === len) {
        return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
      }
      throw new Error('Unknown point format');
    };
    
    BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
      return this.encode(enc, true);
    };
    
    BasePoint.prototype._encode = function _encode(compact) {
      var len = this.curve.p.byteLength();
      var x = this.getX().toArray('be', len);
    
      if (compact)
        return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
    
      return [ 0x04 ].concat(x, this.getY().toArray('be', len));
    };
    
    BasePoint.prototype.encode = function encode(enc, compact) {
      return utils.encode(this._encode(compact), enc);
    };
    
    BasePoint.prototype.precompute = function precompute(power) {
      if (this.precomputed)
        return this;
    
      var precomputed = {
        doubles: null,
        naf: null,
        beta: null,
      };
      precomputed.naf = this._getNAFPoints(8);
      precomputed.doubles = this._getDoubles(4, power);
      precomputed.beta = this._getBeta();
      this.precomputed = precomputed;
    
      return this;
    };
    
    BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
      if (!this.precomputed)
        return false;
    
      var doubles = this.precomputed.doubles;
      if (!doubles)
        return false;
    
      return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
    };
    
    BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
      if (this.precomputed && this.precomputed.doubles)
        return this.precomputed.doubles;
    
      var doubles = [ this ];
      var acc = this;
      for (var i = 0; i < power; i += step) {
        for (var j = 0; j < step; j++)
          acc = acc.dbl();
        doubles.push(acc);
      }
      return {
        step: step,
        points: doubles,
      };
    };
    
    BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
      if (this.precomputed && this.precomputed.naf)
        return this.precomputed.naf;
    
      var res = [ this ];
      var max = (1 << wnd) - 1;
      var dbl = max === 1 ? null : this.dbl();
      for (var i = 1; i < max; i++)
        res[i] = res[i - 1].add(dbl);
      return {
        wnd: wnd,
        points: res,
      };
    };
    
    BasePoint.prototype._getBeta = function _getBeta() {
      return null;
    };
    
    BasePoint.prototype.dblp = function dblp(k) {
      var r = this;
      for (var i = 0; i < k; i++)
        r = r.dbl();
      return r;
    };
    
    },{"../utils":132,"bn.js":33}],120:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var BN = require('bn.js');
    var inherits = require('inherits');
    var Base = require('./base');
    
    var assert = utils.assert;
    
    function EdwardsCurve(conf) {
      // NOTE: Important as we are creating point in Base.call()
      this.twisted = (conf.a | 0) !== 1;
      this.mOneA = this.twisted && (conf.a | 0) === -1;
      this.extended = this.mOneA;
    
      Base.call(this, 'edwards', conf);
    
      this.a = new BN(conf.a, 16).umod(this.red.m);
      this.a = this.a.toRed(this.red);
      this.c = new BN(conf.c, 16).toRed(this.red);
      this.c2 = this.c.redSqr();
      this.d = new BN(conf.d, 16).toRed(this.red);
      this.dd = this.d.redAdd(this.d);
    
      assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
      this.oneC = (conf.c | 0) === 1;
    }
    inherits(EdwardsCurve, Base);
    module.exports = EdwardsCurve;
    
    EdwardsCurve.prototype._mulA = function _mulA(num) {
      if (this.mOneA)
        return num.redNeg();
      else
        return this.a.redMul(num);
    };
    
    EdwardsCurve.prototype._mulC = function _mulC(num) {
      if (this.oneC)
        return num;
      else
        return this.c.redMul(num);
    };
    
    // Just for compatibility with Short curve
    EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
      return this.point(x, y, z, t);
    };
    
    EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
      x = new BN(x, 16);
      if (!x.red)
        x = x.toRed(this.red);
    
      var x2 = x.redSqr();
      var rhs = this.c2.redSub(this.a.redMul(x2));
      var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
    
      var y2 = rhs.redMul(lhs.redInvm());
      var y = y2.redSqrt();
      if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
        throw new Error('invalid point');
    
      var isOdd = y.fromRed().isOdd();
      if (odd && !isOdd || !odd && isOdd)
        y = y.redNeg();
    
      return this.point(x, y);
    };
    
    EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
      y = new BN(y, 16);
      if (!y.red)
        y = y.toRed(this.red);
    
      // x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
      var y2 = y.redSqr();
      var lhs = y2.redSub(this.c2);
      var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
      var x2 = lhs.redMul(rhs.redInvm());
    
      if (x2.cmp(this.zero) === 0) {
        if (odd)
          throw new Error('invalid point');
        else
          return this.point(this.zero, y);
      }
    
      var x = x2.redSqrt();
      if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
        throw new Error('invalid point');
    
      if (x.fromRed().isOdd() !== odd)
        x = x.redNeg();
    
      return this.point(x, y);
    };
    
    EdwardsCurve.prototype.validate = function validate(point) {
      if (point.isInfinity())
        return true;
    
      // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
      point.normalize();
    
      var x2 = point.x.redSqr();
      var y2 = point.y.redSqr();
      var lhs = x2.redMul(this.a).redAdd(y2);
      var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
    
      return lhs.cmp(rhs) === 0;
    };
    
    function Point(curve, x, y, z, t) {
      Base.BasePoint.call(this, curve, 'projective');
      if (x === null && y === null && z === null) {
        this.x = this.curve.zero;
        this.y = this.curve.one;
        this.z = this.curve.one;
        this.t = this.curve.zero;
        this.zOne = true;
      } else {
        this.x = new BN(x, 16);
        this.y = new BN(y, 16);
        this.z = z ? new BN(z, 16) : this.curve.one;
        this.t = t && new BN(t, 16);
        if (!this.x.red)
          this.x = this.x.toRed(this.curve.red);
        if (!this.y.red)
          this.y = this.y.toRed(this.curve.red);
        if (!this.z.red)
          this.z = this.z.toRed(this.curve.red);
        if (this.t && !this.t.red)
          this.t = this.t.toRed(this.curve.red);
        this.zOne = this.z === this.curve.one;
    
        // Use extended coordinates
        if (this.curve.extended && !this.t) {
          this.t = this.x.redMul(this.y);
          if (!this.zOne)
            this.t = this.t.redMul(this.z.redInvm());
        }
      }
    }
    inherits(Point, Base.BasePoint);
    
    EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
      return Point.fromJSON(this, obj);
    };
    
    EdwardsCurve.prototype.point = function point(x, y, z, t) {
      return new Point(this, x, y, z, t);
    };
    
    Point.fromJSON = function fromJSON(curve, obj) {
      return new Point(curve, obj[0], obj[1], obj[2]);
    };
    
    Point.prototype.inspect = function inspect() {
      if (this.isInfinity())
        return '<EC Point Infinity>';
      return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
          ' y: ' + this.y.fromRed().toString(16, 2) +
          ' z: ' + this.z.fromRed().toString(16, 2) + '>';
    };
    
    Point.prototype.isInfinity = function isInfinity() {
      // XXX This code assumes that zero is always zero in red
      return this.x.cmpn(0) === 0 &&
        (this.y.cmp(this.z) === 0 ||
        (this.zOne && this.y.cmp(this.curve.c) === 0));
    };
    
    Point.prototype._extDbl = function _extDbl() {
      // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
      //     #doubling-dbl-2008-hwcd
      // 4M + 4S
    
      // A = X1^2
      var a = this.x.redSqr();
      // B = Y1^2
      var b = this.y.redSqr();
      // C = 2 * Z1^2
      var c = this.z.redSqr();
      c = c.redIAdd(c);
      // D = a * A
      var d = this.curve._mulA(a);
      // E = (X1 + Y1)^2 - A - B
      var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
      // G = D + B
      var g = d.redAdd(b);
      // F = G - C
      var f = g.redSub(c);
      // H = D - B
      var h = d.redSub(b);
      // X3 = E * F
      var nx = e.redMul(f);
      // Y3 = G * H
      var ny = g.redMul(h);
      // T3 = E * H
      var nt = e.redMul(h);
      // Z3 = F * G
      var nz = f.redMul(g);
      return this.curve.point(nx, ny, nz, nt);
    };
    
    Point.prototype._projDbl = function _projDbl() {
      // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
      //     #doubling-dbl-2008-bbjlp
      //     #doubling-dbl-2007-bl
      // and others
      // Generally 3M + 4S or 2M + 4S
    
      // B = (X1 + Y1)^2
      var b = this.x.redAdd(this.y).redSqr();
      // C = X1^2
      var c = this.x.redSqr();
      // D = Y1^2
      var d = this.y.redSqr();
    
      var nx;
      var ny;
      var nz;
      var e;
      var h;
      var j;
      if (this.curve.twisted) {
        // E = a * C
        e = this.curve._mulA(c);
        // F = E + D
        var f = e.redAdd(d);
        if (this.zOne) {
          // X3 = (B - C - D) * (F - 2)
          nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
          // Y3 = F * (E - D)
          ny = f.redMul(e.redSub(d));
          // Z3 = F^2 - 2 * F
          nz = f.redSqr().redSub(f).redSub(f);
        } else {
          // H = Z1^2
          h = this.z.redSqr();
          // J = F - 2 * H
          j = f.redSub(h).redISub(h);
          // X3 = (B-C-D)*J
          nx = b.redSub(c).redISub(d).redMul(j);
          // Y3 = F * (E - D)
          ny = f.redMul(e.redSub(d));
          // Z3 = F * J
          nz = f.redMul(j);
        }
      } else {
        // E = C + D
        e = c.redAdd(d);
        // H = (c * Z1)^2
        h = this.curve._mulC(this.z).redSqr();
        // J = E - 2 * H
        j = e.redSub(h).redSub(h);
        // X3 = c * (B - E) * J
        nx = this.curve._mulC(b.redISub(e)).redMul(j);
        // Y3 = c * E * (C - D)
        ny = this.curve._mulC(e).redMul(c.redISub(d));
        // Z3 = E * J
        nz = e.redMul(j);
      }
      return this.curve.point(nx, ny, nz);
    };
    
    Point.prototype.dbl = function dbl() {
      if (this.isInfinity())
        return this;
    
      // Double in extended coordinates
      if (this.curve.extended)
        return this._extDbl();
      else
        return this._projDbl();
    };
    
    Point.prototype._extAdd = function _extAdd(p) {
      // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
      //     #addition-add-2008-hwcd-3
      // 8M
    
      // A = (Y1 - X1) * (Y2 - X2)
      var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
      // B = (Y1 + X1) * (Y2 + X2)
      var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
      // C = T1 * k * T2
      var c = this.t.redMul(this.curve.dd).redMul(p.t);
      // D = Z1 * 2 * Z2
      var d = this.z.redMul(p.z.redAdd(p.z));
      // E = B - A
      var e = b.redSub(a);
      // F = D - C
      var f = d.redSub(c);
      // G = D + C
      var g = d.redAdd(c);
      // H = B + A
      var h = b.redAdd(a);
      // X3 = E * F
      var nx = e.redMul(f);
      // Y3 = G * H
      var ny = g.redMul(h);
      // T3 = E * H
      var nt = e.redMul(h);
      // Z3 = F * G
      var nz = f.redMul(g);
      return this.curve.point(nx, ny, nz, nt);
    };
    
    Point.prototype._projAdd = function _projAdd(p) {
      // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
      //     #addition-add-2008-bbjlp
      //     #addition-add-2007-bl
      // 10M + 1S
    
      // A = Z1 * Z2
      var a = this.z.redMul(p.z);
      // B = A^2
      var b = a.redSqr();
      // C = X1 * X2
      var c = this.x.redMul(p.x);
      // D = Y1 * Y2
      var d = this.y.redMul(p.y);
      // E = d * C * D
      var e = this.curve.d.redMul(c).redMul(d);
      // F = B - E
      var f = b.redSub(e);
      // G = B + E
      var g = b.redAdd(e);
      // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
      var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
      var nx = a.redMul(f).redMul(tmp);
      var ny;
      var nz;
      if (this.curve.twisted) {
        // Y3 = A * G * (D - a * C)
        ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
        // Z3 = F * G
        nz = f.redMul(g);
      } else {
        // Y3 = A * G * (D - C)
        ny = a.redMul(g).redMul(d.redSub(c));
        // Z3 = c * F * G
        nz = this.curve._mulC(f).redMul(g);
      }
      return this.curve.point(nx, ny, nz);
    };
    
    Point.prototype.add = function add(p) {
      if (this.isInfinity())
        return p;
      if (p.isInfinity())
        return this;
    
      if (this.curve.extended)
        return this._extAdd(p);
      else
        return this._projAdd(p);
    };
    
    Point.prototype.mul = function mul(k) {
      if (this._hasDoubles(k))
        return this.curve._fixedNafMul(this, k);
      else
        return this.curve._wnafMul(this, k);
    };
    
    Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
      return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
    };
    
    Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
      return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
    };
    
    Point.prototype.normalize = function normalize() {
      if (this.zOne)
        return this;
    
      // Normalize coordinates
      var zi = this.z.redInvm();
      this.x = this.x.redMul(zi);
      this.y = this.y.redMul(zi);
      if (this.t)
        this.t = this.t.redMul(zi);
      this.z = this.curve.one;
      this.zOne = true;
      return this;
    };
    
    Point.prototype.neg = function neg() {
      return this.curve.point(this.x.redNeg(),
        this.y,
        this.z,
        this.t && this.t.redNeg());
    };
    
    Point.prototype.getX = function getX() {
      this.normalize();
      return this.x.fromRed();
    };
    
    Point.prototype.getY = function getY() {
      this.normalize();
      return this.y.fromRed();
    };
    
    Point.prototype.eq = function eq(other) {
      return this === other ||
             this.getX().cmp(other.getX()) === 0 &&
             this.getY().cmp(other.getY()) === 0;
    };
    
    Point.prototype.eqXToP = function eqXToP(x) {
      var rx = x.toRed(this.curve.red).redMul(this.z);
      if (this.x.cmp(rx) === 0)
        return true;
    
      var xc = x.clone();
      var t = this.curve.redN.redMul(this.z);
      for (;;) {
        xc.iadd(this.curve.n);
        if (xc.cmp(this.curve.p) >= 0)
          return false;
    
        rx.redIAdd(t);
        if (this.x.cmp(rx) === 0)
          return true;
      }
    };
    
    // Compatibility with BaseCurve
    Point.prototype.toP = Point.prototype.normalize;
    Point.prototype.mixedAdd = Point.prototype.add;
    
    },{"../utils":132,"./base":119,"bn.js":33,"inherits":182}],121:[function(require,module,exports){
    'use strict';
    
    var curve = exports;
    
    curve.base = require('./base');
    curve.short = require('./short');
    curve.mont = require('./mont');
    curve.edwards = require('./edwards');
    
    },{"./base":119,"./edwards":120,"./mont":122,"./short":123}],122:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    var inherits = require('inherits');
    var Base = require('./base');
    
    var utils = require('../utils');
    
    function MontCurve(conf) {
      Base.call(this, 'mont', conf);
    
      this.a = new BN(conf.a, 16).toRed(this.red);
      this.b = new BN(conf.b, 16).toRed(this.red);
      this.i4 = new BN(4).toRed(this.red).redInvm();
      this.two = new BN(2).toRed(this.red);
      this.a24 = this.i4.redMul(this.a.redAdd(this.two));
    }
    inherits(MontCurve, Base);
    module.exports = MontCurve;
    
    MontCurve.prototype.validate = function validate(point) {
      var x = point.normalize().x;
      var x2 = x.redSqr();
      var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
      var y = rhs.redSqrt();
    
      return y.redSqr().cmp(rhs) === 0;
    };
    
    function Point(curve, x, z) {
      Base.BasePoint.call(this, curve, 'projective');
      if (x === null && z === null) {
        this.x = this.curve.one;
        this.z = this.curve.zero;
      } else {
        this.x = new BN(x, 16);
        this.z = new BN(z, 16);
        if (!this.x.red)
          this.x = this.x.toRed(this.curve.red);
        if (!this.z.red)
          this.z = this.z.toRed(this.curve.red);
      }
    }
    inherits(Point, Base.BasePoint);
    
    MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
      return this.point(utils.toArray(bytes, enc), 1);
    };
    
    MontCurve.prototype.point = function point(x, z) {
      return new Point(this, x, z);
    };
    
    MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
      return Point.fromJSON(this, obj);
    };
    
    Point.prototype.precompute = function precompute() {
      // No-op
    };
    
    Point.prototype._encode = function _encode() {
      return this.getX().toArray('be', this.curve.p.byteLength());
    };
    
    Point.fromJSON = function fromJSON(curve, obj) {
      return new Point(curve, obj[0], obj[1] || curve.one);
    };
    
    Point.prototype.inspect = function inspect() {
      if (this.isInfinity())
        return '<EC Point Infinity>';
      return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
          ' z: ' + this.z.fromRed().toString(16, 2) + '>';
    };
    
    Point.prototype.isInfinity = function isInfinity() {
      // XXX This code assumes that zero is always zero in red
      return this.z.cmpn(0) === 0;
    };
    
    Point.prototype.dbl = function dbl() {
      // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
      // 2M + 2S + 4A
    
      // A = X1 + Z1
      var a = this.x.redAdd(this.z);
      // AA = A^2
      var aa = a.redSqr();
      // B = X1 - Z1
      var b = this.x.redSub(this.z);
      // BB = B^2
      var bb = b.redSqr();
      // C = AA - BB
      var c = aa.redSub(bb);
      // X3 = AA * BB
      var nx = aa.redMul(bb);
      // Z3 = C * (BB + A24 * C)
      var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
      return this.curve.point(nx, nz);
    };
    
    Point.prototype.add = function add() {
      throw new Error('Not supported on Montgomery curve');
    };
    
    Point.prototype.diffAdd = function diffAdd(p, diff) {
      // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
      // 4M + 2S + 6A
    
      // A = X2 + Z2
      var a = this.x.redAdd(this.z);
      // B = X2 - Z2
      var b = this.x.redSub(this.z);
      // C = X3 + Z3
      var c = p.x.redAdd(p.z);
      // D = X3 - Z3
      var d = p.x.redSub(p.z);
      // DA = D * A
      var da = d.redMul(a);
      // CB = C * B
      var cb = c.redMul(b);
      // X5 = Z1 * (DA + CB)^2
      var nx = diff.z.redMul(da.redAdd(cb).redSqr());
      // Z5 = X1 * (DA - CB)^2
      var nz = diff.x.redMul(da.redISub(cb).redSqr());
      return this.curve.point(nx, nz);
    };
    
    Point.prototype.mul = function mul(k) {
      var t = k.clone();
      var a = this; // (N / 2) * Q + Q
      var b = this.curve.point(null, null); // (N / 2) * Q
      var c = this; // Q
    
      for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
        bits.push(t.andln(1));
    
      for (var i = bits.length - 1; i >= 0; i--) {
        if (bits[i] === 0) {
          // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
          a = a.diffAdd(b, c);
          // N * Q = 2 * ((N / 2) * Q + Q))
          b = b.dbl();
        } else {
          // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
          b = a.diffAdd(b, c);
          // N * Q + Q = 2 * ((N / 2) * Q + Q)
          a = a.dbl();
        }
      }
      return b;
    };
    
    Point.prototype.mulAdd = function mulAdd() {
      throw new Error('Not supported on Montgomery curve');
    };
    
    Point.prototype.jumlAdd = function jumlAdd() {
      throw new Error('Not supported on Montgomery curve');
    };
    
    Point.prototype.eq = function eq(other) {
      return this.getX().cmp(other.getX()) === 0;
    };
    
    Point.prototype.normalize = function normalize() {
      this.x = this.x.redMul(this.z.redInvm());
      this.z = this.curve.one;
      return this;
    };
    
    Point.prototype.getX = function getX() {
      // Normalize coordinates
      this.normalize();
    
      return this.x.fromRed();
    };
    
    },{"../utils":132,"./base":119,"bn.js":33,"inherits":182}],123:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var BN = require('bn.js');
    var inherits = require('inherits');
    var Base = require('./base');
    
    var assert = utils.assert;
    
    function ShortCurve(conf) {
      Base.call(this, 'short', conf);
    
      this.a = new BN(conf.a, 16).toRed(this.red);
      this.b = new BN(conf.b, 16).toRed(this.red);
      this.tinv = this.two.redInvm();
    
      this.zeroA = this.a.fromRed().cmpn(0) === 0;
      this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
    
      // If the curve is endomorphic, precalculate beta and lambda
      this.endo = this._getEndomorphism(conf);
      this._endoWnafT1 = new Array(4);
      this._endoWnafT2 = new Array(4);
    }
    inherits(ShortCurve, Base);
    module.exports = ShortCurve;
    
    ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
      // No efficient endomorphism
      if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
        return;
    
      // Compute beta and lambda, that lambda * P = (beta * Px; Py)
      var beta;
      var lambda;
      if (conf.beta) {
        beta = new BN(conf.beta, 16).toRed(this.red);
      } else {
        var betas = this._getEndoRoots(this.p);
        // Choose the smallest beta
        beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
        beta = beta.toRed(this.red);
      }
      if (conf.lambda) {
        lambda = new BN(conf.lambda, 16);
      } else {
        // Choose the lambda that is matching selected beta
        var lambdas = this._getEndoRoots(this.n);
        if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
          lambda = lambdas[0];
        } else {
          lambda = lambdas[1];
          assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
        }
      }
    
      // Get basis vectors, used for balanced length-two representation
      var basis;
      if (conf.basis) {
        basis = conf.basis.map(function(vec) {
          return {
            a: new BN(vec.a, 16),
            b: new BN(vec.b, 16),
          };
        });
      } else {
        basis = this._getEndoBasis(lambda);
      }
    
      return {
        beta: beta,
        lambda: lambda,
        basis: basis,
      };
    };
    
    ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
      // Find roots of for x^2 + x + 1 in F
      // Root = (-1 +- Sqrt(-3)) / 2
      //
      var red = num === this.p ? this.red : BN.mont(num);
      var tinv = new BN(2).toRed(red).redInvm();
      var ntinv = tinv.redNeg();
    
      var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
    
      var l1 = ntinv.redAdd(s).fromRed();
      var l2 = ntinv.redSub(s).fromRed();
      return [ l1, l2 ];
    };
    
    ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
      // aprxSqrt >= sqrt(this.n)
      var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
    
      // 3.74
      // Run EGCD, until r(L + 1) < aprxSqrt
      var u = lambda;
      var v = this.n.clone();
      var x1 = new BN(1);
      var y1 = new BN(0);
      var x2 = new BN(0);
      var y2 = new BN(1);
    
      // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
      var a0;
      var b0;
      // First vector
      var a1;
      var b1;
      // Second vector
      var a2;
      var b2;
    
      var prevR;
      var i = 0;
      var r;
      var x;
      while (u.cmpn(0) !== 0) {
        var q = v.div(u);
        r = v.sub(q.mul(u));
        x = x2.sub(q.mul(x1));
        var y = y2.sub(q.mul(y1));
    
        if (!a1 && r.cmp(aprxSqrt) < 0) {
          a0 = prevR.neg();
          b0 = x1;
          a1 = r.neg();
          b1 = x;
        } else if (a1 && ++i === 2) {
          break;
        }
        prevR = r;
    
        v = u;
        u = r;
        x2 = x1;
        x1 = x;
        y2 = y1;
        y1 = y;
      }
      a2 = r.neg();
      b2 = x;
    
      var len1 = a1.sqr().add(b1.sqr());
      var len2 = a2.sqr().add(b2.sqr());
      if (len2.cmp(len1) >= 0) {
        a2 = a0;
        b2 = b0;
      }
    
      // Normalize signs
      if (a1.negative) {
        a1 = a1.neg();
        b1 = b1.neg();
      }
      if (a2.negative) {
        a2 = a2.neg();
        b2 = b2.neg();
      }
    
      return [
        { a: a1, b: b1 },
        { a: a2, b: b2 },
      ];
    };
    
    ShortCurve.prototype._endoSplit = function _endoSplit(k) {
      var basis = this.endo.basis;
      var v1 = basis[0];
      var v2 = basis[1];
    
      var c1 = v2.b.mul(k).divRound(this.n);
      var c2 = v1.b.neg().mul(k).divRound(this.n);
    
      var p1 = c1.mul(v1.a);
      var p2 = c2.mul(v2.a);
      var q1 = c1.mul(v1.b);
      var q2 = c2.mul(v2.b);
    
      // Calculate answer
      var k1 = k.sub(p1).sub(p2);
      var k2 = q1.add(q2).neg();
      return { k1: k1, k2: k2 };
    };
    
    ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
      x = new BN(x, 16);
      if (!x.red)
        x = x.toRed(this.red);
    
      var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
      var y = y2.redSqrt();
      if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
        throw new Error('invalid point');
    
      // XXX Is there any way to tell if the number is odd without converting it
      // to non-red form?
      var isOdd = y.fromRed().isOdd();
      if (odd && !isOdd || !odd && isOdd)
        y = y.redNeg();
    
      return this.point(x, y);
    };
    
    ShortCurve.prototype.validate = function validate(point) {
      if (point.inf)
        return true;
    
      var x = point.x;
      var y = point.y;
    
      var ax = this.a.redMul(x);
      var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
      return y.redSqr().redISub(rhs).cmpn(0) === 0;
    };
    
    ShortCurve.prototype._endoWnafMulAdd =
        function _endoWnafMulAdd(points, coeffs, jacobianResult) {
          var npoints = this._endoWnafT1;
          var ncoeffs = this._endoWnafT2;
          for (var i = 0; i < points.length; i++) {
            var split = this._endoSplit(coeffs[i]);
            var p = points[i];
            var beta = p._getBeta();
    
            if (split.k1.negative) {
              split.k1.ineg();
              p = p.neg(true);
            }
            if (split.k2.negative) {
              split.k2.ineg();
              beta = beta.neg(true);
            }
    
            npoints[i * 2] = p;
            npoints[i * 2 + 1] = beta;
            ncoeffs[i * 2] = split.k1;
            ncoeffs[i * 2 + 1] = split.k2;
          }
          var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
    
          // Clean-up references to points and coefficients
          for (var j = 0; j < i * 2; j++) {
            npoints[j] = null;
            ncoeffs[j] = null;
          }
          return res;
        };
    
    function Point(curve, x, y, isRed) {
      Base.BasePoint.call(this, curve, 'affine');
      if (x === null && y === null) {
        this.x = null;
        this.y = null;
        this.inf = true;
      } else {
        this.x = new BN(x, 16);
        this.y = new BN(y, 16);
        // Force redgomery representation when loading from JSON
        if (isRed) {
          this.x.forceRed(this.curve.red);
          this.y.forceRed(this.curve.red);
        }
        if (!this.x.red)
          this.x = this.x.toRed(this.curve.red);
        if (!this.y.red)
          this.y = this.y.toRed(this.curve.red);
        this.inf = false;
      }
    }
    inherits(Point, Base.BasePoint);
    
    ShortCurve.prototype.point = function point(x, y, isRed) {
      return new Point(this, x, y, isRed);
    };
    
    ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
      return Point.fromJSON(this, obj, red);
    };
    
    Point.prototype._getBeta = function _getBeta() {
      if (!this.curve.endo)
        return;
    
      var pre = this.precomputed;
      if (pre && pre.beta)
        return pre.beta;
    
      var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
      if (pre) {
        var curve = this.curve;
        var endoMul = function(p) {
          return curve.point(p.x.redMul(curve.endo.beta), p.y);
        };
        pre.beta = beta;
        beta.precomputed = {
          beta: null,
          naf: pre.naf && {
            wnd: pre.naf.wnd,
            points: pre.naf.points.map(endoMul),
          },
          doubles: pre.doubles && {
            step: pre.doubles.step,
            points: pre.doubles.points.map(endoMul),
          },
        };
      }
      return beta;
    };
    
    Point.prototype.toJSON = function toJSON() {
      if (!this.precomputed)
        return [ this.x, this.y ];
    
      return [ this.x, this.y, this.precomputed && {
        doubles: this.precomputed.doubles && {
          step: this.precomputed.doubles.step,
          points: this.precomputed.doubles.points.slice(1),
        },
        naf: this.precomputed.naf && {
          wnd: this.precomputed.naf.wnd,
          points: this.precomputed.naf.points.slice(1),
        },
      } ];
    };
    
    Point.fromJSON = function fromJSON(curve, obj, red) {
      if (typeof obj === 'string')
        obj = JSON.parse(obj);
      var res = curve.point(obj[0], obj[1], red);
      if (!obj[2])
        return res;
    
      function obj2point(obj) {
        return curve.point(obj[0], obj[1], red);
      }
    
      var pre = obj[2];
      res.precomputed = {
        beta: null,
        doubles: pre.doubles && {
          step: pre.doubles.step,
          points: [ res ].concat(pre.doubles.points.map(obj2point)),
        },
        naf: pre.naf && {
          wnd: pre.naf.wnd,
          points: [ res ].concat(pre.naf.points.map(obj2point)),
        },
      };
      return res;
    };
    
    Point.prototype.inspect = function inspect() {
      if (this.isInfinity())
        return '<EC Point Infinity>';
      return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
          ' y: ' + this.y.fromRed().toString(16, 2) + '>';
    };
    
    Point.prototype.isInfinity = function isInfinity() {
      return this.inf;
    };
    
    Point.prototype.add = function add(p) {
      // O + P = P
      if (this.inf)
        return p;
    
      // P + O = P
      if (p.inf)
        return this;
    
      // P + P = 2P
      if (this.eq(p))
        return this.dbl();
    
      // P + (-P) = O
      if (this.neg().eq(p))
        return this.curve.point(null, null);
    
      // P + Q = O
      if (this.x.cmp(p.x) === 0)
        return this.curve.point(null, null);
    
      var c = this.y.redSub(p.y);
      if (c.cmpn(0) !== 0)
        c = c.redMul(this.x.redSub(p.x).redInvm());
      var nx = c.redSqr().redISub(this.x).redISub(p.x);
      var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
      return this.curve.point(nx, ny);
    };
    
    Point.prototype.dbl = function dbl() {
      if (this.inf)
        return this;
    
      // 2P = O
      var ys1 = this.y.redAdd(this.y);
      if (ys1.cmpn(0) === 0)
        return this.curve.point(null, null);
    
      var a = this.curve.a;
    
      var x2 = this.x.redSqr();
      var dyinv = ys1.redInvm();
      var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
    
      var nx = c.redSqr().redISub(this.x.redAdd(this.x));
      var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
      return this.curve.point(nx, ny);
    };
    
    Point.prototype.getX = function getX() {
      return this.x.fromRed();
    };
    
    Point.prototype.getY = function getY() {
      return this.y.fromRed();
    };
    
    Point.prototype.mul = function mul(k) {
      k = new BN(k, 16);
      if (this.isInfinity())
        return this;
      else if (this._hasDoubles(k))
        return this.curve._fixedNafMul(this, k);
      else if (this.curve.endo)
        return this.curve._endoWnafMulAdd([ this ], [ k ]);
      else
        return this.curve._wnafMul(this, k);
    };
    
    Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
      var points = [ this, p2 ];
      var coeffs = [ k1, k2 ];
      if (this.curve.endo)
        return this.curve._endoWnafMulAdd(points, coeffs);
      else
        return this.curve._wnafMulAdd(1, points, coeffs, 2);
    };
    
    Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
      var points = [ this, p2 ];
      var coeffs = [ k1, k2 ];
      if (this.curve.endo)
        return this.curve._endoWnafMulAdd(points, coeffs, true);
      else
        return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
    };
    
    Point.prototype.eq = function eq(p) {
      return this === p ||
             this.inf === p.inf &&
                 (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
    };
    
    Point.prototype.neg = function neg(_precompute) {
      if (this.inf)
        return this;
    
      var res = this.curve.point(this.x, this.y.redNeg());
      if (_precompute && this.precomputed) {
        var pre = this.precomputed;
        var negate = function(p) {
          return p.neg();
        };
        res.precomputed = {
          naf: pre.naf && {
            wnd: pre.naf.wnd,
            points: pre.naf.points.map(negate),
          },
          doubles: pre.doubles && {
            step: pre.doubles.step,
            points: pre.doubles.points.map(negate),
          },
        };
      }
      return res;
    };
    
    Point.prototype.toJ = function toJ() {
      if (this.inf)
        return this.curve.jpoint(null, null, null);
    
      var res = this.curve.jpoint(this.x, this.y, this.curve.one);
      return res;
    };
    
    function JPoint(curve, x, y, z) {
      Base.BasePoint.call(this, curve, 'jacobian');
      if (x === null && y === null && z === null) {
        this.x = this.curve.one;
        this.y = this.curve.one;
        this.z = new BN(0);
      } else {
        this.x = new BN(x, 16);
        this.y = new BN(y, 16);
        this.z = new BN(z, 16);
      }
      if (!this.x.red)
        this.x = this.x.toRed(this.curve.red);
      if (!this.y.red)
        this.y = this.y.toRed(this.curve.red);
      if (!this.z.red)
        this.z = this.z.toRed(this.curve.red);
    
      this.zOne = this.z === this.curve.one;
    }
    inherits(JPoint, Base.BasePoint);
    
    ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
      return new JPoint(this, x, y, z);
    };
    
    JPoint.prototype.toP = function toP() {
      if (this.isInfinity())
        return this.curve.point(null, null);
    
      var zinv = this.z.redInvm();
      var zinv2 = zinv.redSqr();
      var ax = this.x.redMul(zinv2);
      var ay = this.y.redMul(zinv2).redMul(zinv);
    
      return this.curve.point(ax, ay);
    };
    
    JPoint.prototype.neg = function neg() {
      return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
    };
    
    JPoint.prototype.add = function add(p) {
      // O + P = P
      if (this.isInfinity())
        return p;
    
      // P + O = P
      if (p.isInfinity())
        return this;
    
      // 12M + 4S + 7A
      var pz2 = p.z.redSqr();
      var z2 = this.z.redSqr();
      var u1 = this.x.redMul(pz2);
      var u2 = p.x.redMul(z2);
      var s1 = this.y.redMul(pz2.redMul(p.z));
      var s2 = p.y.redMul(z2.redMul(this.z));
    
      var h = u1.redSub(u2);
      var r = s1.redSub(s2);
      if (h.cmpn(0) === 0) {
        if (r.cmpn(0) !== 0)
          return this.curve.jpoint(null, null, null);
        else
          return this.dbl();
      }
    
      var h2 = h.redSqr();
      var h3 = h2.redMul(h);
      var v = u1.redMul(h2);
    
      var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
      var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
      var nz = this.z.redMul(p.z).redMul(h);
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype.mixedAdd = function mixedAdd(p) {
      // O + P = P
      if (this.isInfinity())
        return p.toJ();
    
      // P + O = P
      if (p.isInfinity())
        return this;
    
      // 8M + 3S + 7A
      var z2 = this.z.redSqr();
      var u1 = this.x;
      var u2 = p.x.redMul(z2);
      var s1 = this.y;
      var s2 = p.y.redMul(z2).redMul(this.z);
    
      var h = u1.redSub(u2);
      var r = s1.redSub(s2);
      if (h.cmpn(0) === 0) {
        if (r.cmpn(0) !== 0)
          return this.curve.jpoint(null, null, null);
        else
          return this.dbl();
      }
    
      var h2 = h.redSqr();
      var h3 = h2.redMul(h);
      var v = u1.redMul(h2);
    
      var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
      var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
      var nz = this.z.redMul(h);
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype.dblp = function dblp(pow) {
      if (pow === 0)
        return this;
      if (this.isInfinity())
        return this;
      if (!pow)
        return this.dbl();
    
      var i;
      if (this.curve.zeroA || this.curve.threeA) {
        var r = this;
        for (i = 0; i < pow; i++)
          r = r.dbl();
        return r;
      }
    
      // 1M + 2S + 1A + N * (4S + 5M + 8A)
      // N = 1 => 6M + 6S + 9A
      var a = this.curve.a;
      var tinv = this.curve.tinv;
    
      var jx = this.x;
      var jy = this.y;
      var jz = this.z;
      var jz4 = jz.redSqr().redSqr();
    
      // Reuse results
      var jyd = jy.redAdd(jy);
      for (i = 0; i < pow; i++) {
        var jx2 = jx.redSqr();
        var jyd2 = jyd.redSqr();
        var jyd4 = jyd2.redSqr();
        var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
    
        var t1 = jx.redMul(jyd2);
        var nx = c.redSqr().redISub(t1.redAdd(t1));
        var t2 = t1.redISub(nx);
        var dny = c.redMul(t2);
        dny = dny.redIAdd(dny).redISub(jyd4);
        var nz = jyd.redMul(jz);
        if (i + 1 < pow)
          jz4 = jz4.redMul(jyd4);
    
        jx = nx;
        jz = nz;
        jyd = dny;
      }
    
      return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
    };
    
    JPoint.prototype.dbl = function dbl() {
      if (this.isInfinity())
        return this;
    
      if (this.curve.zeroA)
        return this._zeroDbl();
      else if (this.curve.threeA)
        return this._threeDbl();
      else
        return this._dbl();
    };
    
    JPoint.prototype._zeroDbl = function _zeroDbl() {
      var nx;
      var ny;
      var nz;
      // Z = 1
      if (this.zOne) {
        // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
        //     #doubling-mdbl-2007-bl
        // 1M + 5S + 14A
    
        // XX = X1^2
        var xx = this.x.redSqr();
        // YY = Y1^2
        var yy = this.y.redSqr();
        // YYYY = YY^2
        var yyyy = yy.redSqr();
        // S = 2 * ((X1 + YY)^2 - XX - YYYY)
        var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
        s = s.redIAdd(s);
        // M = 3 * XX + a; a = 0
        var m = xx.redAdd(xx).redIAdd(xx);
        // T = M ^ 2 - 2*S
        var t = m.redSqr().redISub(s).redISub(s);
    
        // 8 * YYYY
        var yyyy8 = yyyy.redIAdd(yyyy);
        yyyy8 = yyyy8.redIAdd(yyyy8);
        yyyy8 = yyyy8.redIAdd(yyyy8);
    
        // X3 = T
        nx = t;
        // Y3 = M * (S - T) - 8 * YYYY
        ny = m.redMul(s.redISub(t)).redISub(yyyy8);
        // Z3 = 2*Y1
        nz = this.y.redAdd(this.y);
      } else {
        // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
        //     #doubling-dbl-2009-l
        // 2M + 5S + 13A
    
        // A = X1^2
        var a = this.x.redSqr();
        // B = Y1^2
        var b = this.y.redSqr();
        // C = B^2
        var c = b.redSqr();
        // D = 2 * ((X1 + B)^2 - A - C)
        var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
        d = d.redIAdd(d);
        // E = 3 * A
        var e = a.redAdd(a).redIAdd(a);
        // F = E^2
        var f = e.redSqr();
    
        // 8 * C
        var c8 = c.redIAdd(c);
        c8 = c8.redIAdd(c8);
        c8 = c8.redIAdd(c8);
    
        // X3 = F - 2 * D
        nx = f.redISub(d).redISub(d);
        // Y3 = E * (D - X3) - 8 * C
        ny = e.redMul(d.redISub(nx)).redISub(c8);
        // Z3 = 2 * Y1 * Z1
        nz = this.y.redMul(this.z);
        nz = nz.redIAdd(nz);
      }
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype._threeDbl = function _threeDbl() {
      var nx;
      var ny;
      var nz;
      // Z = 1
      if (this.zOne) {
        // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
        //     #doubling-mdbl-2007-bl
        // 1M + 5S + 15A
    
        // XX = X1^2
        var xx = this.x.redSqr();
        // YY = Y1^2
        var yy = this.y.redSqr();
        // YYYY = YY^2
        var yyyy = yy.redSqr();
        // S = 2 * ((X1 + YY)^2 - XX - YYYY)
        var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
        s = s.redIAdd(s);
        // M = 3 * XX + a
        var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
        // T = M^2 - 2 * S
        var t = m.redSqr().redISub(s).redISub(s);
        // X3 = T
        nx = t;
        // Y3 = M * (S - T) - 8 * YYYY
        var yyyy8 = yyyy.redIAdd(yyyy);
        yyyy8 = yyyy8.redIAdd(yyyy8);
        yyyy8 = yyyy8.redIAdd(yyyy8);
        ny = m.redMul(s.redISub(t)).redISub(yyyy8);
        // Z3 = 2 * Y1
        nz = this.y.redAdd(this.y);
      } else {
        // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
        // 3M + 5S
    
        // delta = Z1^2
        var delta = this.z.redSqr();
        // gamma = Y1^2
        var gamma = this.y.redSqr();
        // beta = X1 * gamma
        var beta = this.x.redMul(gamma);
        // alpha = 3 * (X1 - delta) * (X1 + delta)
        var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
        alpha = alpha.redAdd(alpha).redIAdd(alpha);
        // X3 = alpha^2 - 8 * beta
        var beta4 = beta.redIAdd(beta);
        beta4 = beta4.redIAdd(beta4);
        var beta8 = beta4.redAdd(beta4);
        nx = alpha.redSqr().redISub(beta8);
        // Z3 = (Y1 + Z1)^2 - gamma - delta
        nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
        // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
        var ggamma8 = gamma.redSqr();
        ggamma8 = ggamma8.redIAdd(ggamma8);
        ggamma8 = ggamma8.redIAdd(ggamma8);
        ggamma8 = ggamma8.redIAdd(ggamma8);
        ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
      }
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype._dbl = function _dbl() {
      var a = this.curve.a;
    
      // 4M + 6S + 10A
      var jx = this.x;
      var jy = this.y;
      var jz = this.z;
      var jz4 = jz.redSqr().redSqr();
    
      var jx2 = jx.redSqr();
      var jy2 = jy.redSqr();
    
      var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
    
      var jxd4 = jx.redAdd(jx);
      jxd4 = jxd4.redIAdd(jxd4);
      var t1 = jxd4.redMul(jy2);
      var nx = c.redSqr().redISub(t1.redAdd(t1));
      var t2 = t1.redISub(nx);
    
      var jyd8 = jy2.redSqr();
      jyd8 = jyd8.redIAdd(jyd8);
      jyd8 = jyd8.redIAdd(jyd8);
      jyd8 = jyd8.redIAdd(jyd8);
      var ny = c.redMul(t2).redISub(jyd8);
      var nz = jy.redAdd(jy).redMul(jz);
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype.trpl = function trpl() {
      if (!this.curve.zeroA)
        return this.dbl().add(this);
    
      // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
      // 5M + 10S + ...
    
      // XX = X1^2
      var xx = this.x.redSqr();
      // YY = Y1^2
      var yy = this.y.redSqr();
      // ZZ = Z1^2
      var zz = this.z.redSqr();
      // YYYY = YY^2
      var yyyy = yy.redSqr();
      // M = 3 * XX + a * ZZ2; a = 0
      var m = xx.redAdd(xx).redIAdd(xx);
      // MM = M^2
      var mm = m.redSqr();
      // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
      var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
      e = e.redIAdd(e);
      e = e.redAdd(e).redIAdd(e);
      e = e.redISub(mm);
      // EE = E^2
      var ee = e.redSqr();
      // T = 16*YYYY
      var t = yyyy.redIAdd(yyyy);
      t = t.redIAdd(t);
      t = t.redIAdd(t);
      t = t.redIAdd(t);
      // U = (M + E)^2 - MM - EE - T
      var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
      // X3 = 4 * (X1 * EE - 4 * YY * U)
      var yyu4 = yy.redMul(u);
      yyu4 = yyu4.redIAdd(yyu4);
      yyu4 = yyu4.redIAdd(yyu4);
      var nx = this.x.redMul(ee).redISub(yyu4);
      nx = nx.redIAdd(nx);
      nx = nx.redIAdd(nx);
      // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
      var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
      ny = ny.redIAdd(ny);
      ny = ny.redIAdd(ny);
      ny = ny.redIAdd(ny);
      // Z3 = (Z1 + E)^2 - ZZ - EE
      var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
    
      return this.curve.jpoint(nx, ny, nz);
    };
    
    JPoint.prototype.mul = function mul(k, kbase) {
      k = new BN(k, kbase);
    
      return this.curve._wnafMul(this, k);
    };
    
    JPoint.prototype.eq = function eq(p) {
      if (p.type === 'affine')
        return this.eq(p.toJ());
    
      if (this === p)
        return true;
    
      // x1 * z2^2 == x2 * z1^2
      var z2 = this.z.redSqr();
      var pz2 = p.z.redSqr();
      if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
        return false;
    
      // y1 * z2^3 == y2 * z1^3
      var z3 = z2.redMul(this.z);
      var pz3 = pz2.redMul(p.z);
      return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
    };
    
    JPoint.prototype.eqXToP = function eqXToP(x) {
      var zs = this.z.redSqr();
      var rx = x.toRed(this.curve.red).redMul(zs);
      if (this.x.cmp(rx) === 0)
        return true;
    
      var xc = x.clone();
      var t = this.curve.redN.redMul(zs);
      for (;;) {
        xc.iadd(this.curve.n);
        if (xc.cmp(this.curve.p) >= 0)
          return false;
    
        rx.redIAdd(t);
        if (this.x.cmp(rx) === 0)
          return true;
      }
    };
    
    JPoint.prototype.inspect = function inspect() {
      if (this.isInfinity())
        return '<EC JPoint Infinity>';
      return '<EC JPoint x: ' + this.x.toString(16, 2) +
          ' y: ' + this.y.toString(16, 2) +
          ' z: ' + this.z.toString(16, 2) + '>';
    };
    
    JPoint.prototype.isInfinity = function isInfinity() {
      // XXX This code assumes that zero is always zero in red
      return this.z.cmpn(0) === 0;
    };
    
    },{"../utils":132,"./base":119,"bn.js":33,"inherits":182}],124:[function(require,module,exports){
    'use strict';
    
    var curves = exports;
    
    var hash = require('hash.js');
    var curve = require('./curve');
    var utils = require('./utils');
    
    var assert = utils.assert;
    
    function PresetCurve(options) {
      if (options.type === 'short')
        this.curve = new curve.short(options);
      else if (options.type === 'edwards')
        this.curve = new curve.edwards(options);
      else
        this.curve = new curve.mont(options);
      this.g = this.curve.g;
      this.n = this.curve.n;
      this.hash = options.hash;
    
      assert(this.g.validate(), 'Invalid curve');
      assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
    }
    curves.PresetCurve = PresetCurve;
    
    function defineCurve(name, options) {
      Object.defineProperty(curves, name, {
        configurable: true,
        enumerable: true,
        get: function() {
          var curve = new PresetCurve(options);
          Object.defineProperty(curves, name, {
            configurable: true,
            enumerable: true,
            value: curve,
          });
          return curve;
        },
      });
    }
    
    defineCurve('p192', {
      type: 'short',
      prime: 'p192',
      p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
      a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
      b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
      n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
      hash: hash.sha256,
      gRed: false,
      g: [
        '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
        '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811',
      ],
    });
    
    defineCurve('p224', {
      type: 'short',
      prime: 'p224',
      p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
      a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
      b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
      n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
      hash: hash.sha256,
      gRed: false,
      g: [
        'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
        'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34',
      ],
    });
    
    defineCurve('p256', {
      type: 'short',
      prime: null,
      p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
      a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
      b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
      n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
      hash: hash.sha256,
      gRed: false,
      g: [
        '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
        '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5',
      ],
    });
    
    defineCurve('p384', {
      type: 'short',
      prime: null,
      p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'fffffffe ffffffff 00000000 00000000 ffffffff',
      a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'fffffffe ffffffff 00000000 00000000 fffffffc',
      b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
         '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
      n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
         'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
      hash: hash.sha384,
      gRed: false,
      g: [
        'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
        '5502f25d bf55296c 3a545e38 72760ab7',
        '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
        '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f',
      ],
    });
    
    defineCurve('p521', {
      type: 'short',
      prime: null,
      p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'ffffffff ffffffff ffffffff ffffffff ffffffff',
      a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'ffffffff ffffffff ffffffff ffffffff fffffffc',
      b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
         '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
         '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
      n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
         'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
         'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
      hash: hash.sha512,
      gRed: false,
      g: [
        '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
        '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
        'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
        '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
        '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
        '3fad0761 353c7086 a272c240 88be9476 9fd16650',
      ],
    });
    
    defineCurve('curve25519', {
      type: 'mont',
      prime: 'p25519',
      p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
      a: '76d06',
      b: '1',
      n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
      hash: hash.sha256,
      gRed: false,
      g: [
        '9',
      ],
    });
    
    defineCurve('ed25519', {
      type: 'edwards',
      prime: 'p25519',
      p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
      a: '-1',
      c: '1',
      // -121665 * (121666^(-1)) (mod P)
      d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
      n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
      hash: hash.sha256,
      gRed: false,
      g: [
        '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
    
        // 4/5
        '6666666666666666666666666666666666666666666666666666666666666658',
      ],
    });
    
    var pre;
    try {
      pre = require('./precomputed/secp256k1');
    } catch (e) {
      pre = undefined;
    }
    
    defineCurve('secp256k1', {
      type: 'short',
      prime: 'k256',
      p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
      a: '0',
      b: '7',
      n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
      h: '1',
      hash: hash.sha256,
    
      // Precomputed endomorphism
      beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
      lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
      basis: [
        {
          a: '3086d221a7d46bcde86c90e49284eb15',
          b: '-e4437ed6010e88286f547fa90abfe4c3',
        },
        {
          a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
          b: '3086d221a7d46bcde86c90e49284eb15',
        },
      ],
    
      gRed: false,
      g: [
        '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
        '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
        pre,
      ],
    });
    
    },{"./curve":121,"./precomputed/secp256k1":131,"./utils":132,"hash.js":167}],125:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    var HmacDRBG = require('hmac-drbg');
    var utils = require('../utils');
    var curves = require('../curves');
    var rand = require('brorand');
    var assert = utils.assert;
    
    var KeyPair = require('./key');
    var Signature = require('./signature');
    
    function EC(options) {
      if (!(this instanceof EC))
        return new EC(options);
    
      // Shortcut `elliptic.ec(curve-name)`
      if (typeof options === 'string') {
        assert(Object.prototype.hasOwnProperty.call(curves, options),
          'Unknown curve ' + options);
    
        options = curves[options];
      }
    
      // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
      if (options instanceof curves.PresetCurve)
        options = { curve: options };
    
      this.curve = options.curve.curve;
      this.n = this.curve.n;
      this.nh = this.n.ushrn(1);
      this.g = this.curve.g;
    
      // Point on curve
      this.g = options.curve.g;
      this.g.precompute(options.curve.n.bitLength() + 1);
    
      // Hash for function for DRBG
      this.hash = options.hash || options.curve.hash;
    }
    module.exports = EC;
    
    EC.prototype.keyPair = function keyPair(options) {
      return new KeyPair(this, options);
    };
    
    EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
      return KeyPair.fromPrivate(this, priv, enc);
    };
    
    EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
      return KeyPair.fromPublic(this, pub, enc);
    };
    
    EC.prototype.genKeyPair = function genKeyPair(options) {
      if (!options)
        options = {};
    
      // Instantiate Hmac_DRBG
      var drbg = new HmacDRBG({
        hash: this.hash,
        pers: options.pers,
        persEnc: options.persEnc || 'utf8',
        entropy: options.entropy || rand(this.hash.hmacStrength),
        entropyEnc: options.entropy && options.entropyEnc || 'utf8',
        nonce: this.n.toArray(),
      });
    
      var bytes = this.n.byteLength();
      var ns2 = this.n.sub(new BN(2));
      for (;;) {
        var priv = new BN(drbg.generate(bytes));
        if (priv.cmp(ns2) > 0)
          continue;
    
        priv.iaddn(1);
        return this.keyFromPrivate(priv);
      }
    };
    
    EC.prototype._truncateToN = function _truncateToN(msg, truncOnly) {
      var delta = msg.byteLength() * 8 - this.n.bitLength();
      if (delta > 0)
        msg = msg.ushrn(delta);
      if (!truncOnly && msg.cmp(this.n) >= 0)
        return msg.sub(this.n);
      else
        return msg;
    };
    
    EC.prototype.sign = function sign(msg, key, enc, options) {
      if (typeof enc === 'object') {
        options = enc;
        enc = null;
      }
      if (!options)
        options = {};
    
      key = this.keyFromPrivate(key, enc);
      msg = this._truncateToN(new BN(msg, 16));
    
      // Zero-extend key to provide enough entropy
      var bytes = this.n.byteLength();
      var bkey = key.getPrivate().toArray('be', bytes);
    
      // Zero-extend nonce to have the same byte size as N
      var nonce = msg.toArray('be', bytes);
    
      // Instantiate Hmac_DRBG
      var drbg = new HmacDRBG({
        hash: this.hash,
        entropy: bkey,
        nonce: nonce,
        pers: options.pers,
        persEnc: options.persEnc || 'utf8',
      });
    
      // Number of bytes to generate
      var ns1 = this.n.sub(new BN(1));
    
      for (var iter = 0; ; iter++) {
        var k = options.k ?
          options.k(iter) :
          new BN(drbg.generate(this.n.byteLength()));
        k = this._truncateToN(k, true);
        if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
          continue;
    
        var kp = this.g.mul(k);
        if (kp.isInfinity())
          continue;
    
        var kpX = kp.getX();
        var r = kpX.umod(this.n);
        if (r.cmpn(0) === 0)
          continue;
    
        var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
        s = s.umod(this.n);
        if (s.cmpn(0) === 0)
          continue;
    
        var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
                            (kpX.cmp(r) !== 0 ? 2 : 0);
    
        // Use complement of `s`, if it is > `n / 2`
        if (options.canonical && s.cmp(this.nh) > 0) {
          s = this.n.sub(s);
          recoveryParam ^= 1;
        }
    
        return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
      }
    };
    
    EC.prototype.verify = function verify(msg, signature, key, enc) {
      msg = this._truncateToN(new BN(msg, 16));
      key = this.keyFromPublic(key, enc);
      signature = new Signature(signature, 'hex');
    
      // Perform primitive values validation
      var r = signature.r;
      var s = signature.s;
      if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
        return false;
      if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
        return false;
    
      // Validate signature
      var sinv = s.invm(this.n);
      var u1 = sinv.mul(msg).umod(this.n);
      var u2 = sinv.mul(r).umod(this.n);
      var p;
    
      if (!this.curve._maxwellTrick) {
        p = this.g.mulAdd(u1, key.getPublic(), u2);
        if (p.isInfinity())
          return false;
    
        return p.getX().umod(this.n).cmp(r) === 0;
      }
    
      // NOTE: Greg Maxwell's trick, inspired by:
      // https://git.io/vad3K
    
      p = this.g.jmulAdd(u1, key.getPublic(), u2);
      if (p.isInfinity())
        return false;
    
      // Compare `p.x` of Jacobian point with `r`,
      // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
      // inverse of `p.z^2`
      return p.eqXToP(r);
    };
    
    EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
      assert((3 & j) === j, 'The recovery param is more than two bits');
      signature = new Signature(signature, enc);
    
      var n = this.n;
      var e = new BN(msg);
      var r = signature.r;
      var s = signature.s;
    
      // A set LSB signifies that the y-coordinate is odd
      var isYOdd = j & 1;
      var isSecondKey = j >> 1;
      if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
        throw new Error('Unable to find sencond key candinate');
    
      // 1.1. Let x = r + jn.
      if (isSecondKey)
        r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
      else
        r = this.curve.pointFromX(r, isYOdd);
    
      var rInv = signature.r.invm(n);
      var s1 = n.sub(e).mul(rInv).umod(n);
      var s2 = s.mul(rInv).umod(n);
    
      // 1.6.1 Compute Q = r^-1 (sR -  eG)
      //               Q = r^-1 (sR + -eG)
      return this.g.mulAdd(s1, r, s2);
    };
    
    EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
      signature = new Signature(signature, enc);
      if (signature.recoveryParam !== null)
        return signature.recoveryParam;
    
      for (var i = 0; i < 4; i++) {
        var Qprime;
        try {
          Qprime = this.recoverPubKey(e, signature, i);
        } catch (e) {
          continue;
        }
    
        if (Qprime.eq(Q))
          return i;
      }
      throw new Error('Unable to find valid recovery factor');
    };
    
    },{"../curves":124,"../utils":132,"./key":126,"./signature":127,"bn.js":33,"brorand":35,"hmac-drbg":179}],126:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    var utils = require('../utils');
    var assert = utils.assert;
    
    function KeyPair(ec, options) {
      this.ec = ec;
      this.priv = null;
      this.pub = null;
    
      // KeyPair(ec, { priv: ..., pub: ... })
      if (options.priv)
        this._importPrivate(options.priv, options.privEnc);
      if (options.pub)
        this._importPublic(options.pub, options.pubEnc);
    }
    module.exports = KeyPair;
    
    KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
      if (pub instanceof KeyPair)
        return pub;
    
      return new KeyPair(ec, {
        pub: pub,
        pubEnc: enc,
      });
    };
    
    KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
      if (priv instanceof KeyPair)
        return priv;
    
      return new KeyPair(ec, {
        priv: priv,
        privEnc: enc,
      });
    };
    
    KeyPair.prototype.validate = function validate() {
      var pub = this.getPublic();
    
      if (pub.isInfinity())
        return { result: false, reason: 'Invalid public key' };
      if (!pub.validate())
        return { result: false, reason: 'Public key is not a point' };
      if (!pub.mul(this.ec.curve.n).isInfinity())
        return { result: false, reason: 'Public key * N != O' };
    
      return { result: true, reason: null };
    };
    
    KeyPair.prototype.getPublic = function getPublic(compact, enc) {
      // compact is optional argument
      if (typeof compact === 'string') {
        enc = compact;
        compact = null;
      }
    
      if (!this.pub)
        this.pub = this.ec.g.mul(this.priv);
    
      if (!enc)
        return this.pub;
    
      return this.pub.encode(enc, compact);
    };
    
    KeyPair.prototype.getPrivate = function getPrivate(enc) {
      if (enc === 'hex')
        return this.priv.toString(16, 2);
      else
        return this.priv;
    };
    
    KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
      this.priv = new BN(key, enc || 16);
    
      // Ensure that the priv won't be bigger than n, otherwise we may fail
      // in fixed multiplication method
      this.priv = this.priv.umod(this.ec.curve.n);
    };
    
    KeyPair.prototype._importPublic = function _importPublic(key, enc) {
      if (key.x || key.y) {
        // Montgomery points only have an `x` coordinate.
        // Weierstrass/Edwards points on the other hand have both `x` and
        // `y` coordinates.
        if (this.ec.curve.type === 'mont') {
          assert(key.x, 'Need x coordinate');
        } else if (this.ec.curve.type === 'short' ||
                   this.ec.curve.type === 'edwards') {
          assert(key.x && key.y, 'Need both x and y coordinate');
        }
        this.pub = this.ec.curve.point(key.x, key.y);
        return;
      }
      this.pub = this.ec.curve.decodePoint(key, enc);
    };
    
    // ECDH
    KeyPair.prototype.derive = function derive(pub) {
      if(!pub.validate()) {
        assert(pub.validate(), 'public point not validated');
      }
      return pub.mul(this.priv).getX();
    };
    
    // ECDSA
    KeyPair.prototype.sign = function sign(msg, enc, options) {
      return this.ec.sign(msg, this, enc, options);
    };
    
    KeyPair.prototype.verify = function verify(msg, signature) {
      return this.ec.verify(msg, signature, this);
    };
    
    KeyPair.prototype.inspect = function inspect() {
      return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
             ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
    };
    
    },{"../utils":132,"bn.js":33}],127:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    
    var utils = require('../utils');
    var assert = utils.assert;
    
    function Signature(options, enc) {
      if (options instanceof Signature)
        return options;
    
      if (this._importDER(options, enc))
        return;
    
      assert(options.r && options.s, 'Signature without r or s');
      this.r = new BN(options.r, 16);
      this.s = new BN(options.s, 16);
      if (options.recoveryParam === undefined)
        this.recoveryParam = null;
      else
        this.recoveryParam = options.recoveryParam;
    }
    module.exports = Signature;
    
    function Position() {
      this.place = 0;
    }
    
    function getLength(buf, p) {
      var initial = buf[p.place++];
      if (!(initial & 0x80)) {
        return initial;
      }
      var octetLen = initial & 0xf;
    
      // Indefinite length or overflow
      if (octetLen === 0 || octetLen > 4) {
        return false;
      }
    
      var val = 0;
      for (var i = 0, off = p.place; i < octetLen; i++, off++) {
        val <<= 8;
        val |= buf[off];
        val >>>= 0;
      }
    
      // Leading zeroes
      if (val <= 0x7f) {
        return false;
      }
    
      p.place = off;
      return val;
    }
    
    function rmPadding(buf) {
      var i = 0;
      var len = buf.length - 1;
      while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
        i++;
      }
      if (i === 0) {
        return buf;
      }
      return buf.slice(i);
    }
    
    Signature.prototype._importDER = function _importDER(data, enc) {
      data = utils.toArray(data, enc);
      var p = new Position();
      if (data[p.place++] !== 0x30) {
        return false;
      }
      var len = getLength(data, p);
      if (len === false) {
        return false;
      }
      if ((len + p.place) !== data.length) {
        return false;
      }
      if (data[p.place++] !== 0x02) {
        return false;
      }
      var rlen = getLength(data, p);
      if (rlen === false) {
        return false;
      }
      var r = data.slice(p.place, rlen + p.place);
      p.place += rlen;
      if (data[p.place++] !== 0x02) {
        return false;
      }
      var slen = getLength(data, p);
      if (slen === false) {
        return false;
      }
      if (data.length !== slen + p.place) {
        return false;
      }
      var s = data.slice(p.place, slen + p.place);
      if (r[0] === 0) {
        if (r[1] & 0x80) {
          r = r.slice(1);
        } else {
          // Leading zeroes
          return false;
        }
      }
      if (s[0] === 0) {
        if (s[1] & 0x80) {
          s = s.slice(1);
        } else {
          // Leading zeroes
          return false;
        }
      }
    
      this.r = new BN(r);
      this.s = new BN(s);
      this.recoveryParam = null;
    
      return true;
    };
    
    function constructLength(arr, len) {
      if (len < 0x80) {
        arr.push(len);
        return;
      }
      var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
      arr.push(octets | 0x80);
      while (--octets) {
        arr.push((len >>> (octets << 3)) & 0xff);
      }
      arr.push(len);
    }
    
    Signature.prototype.toDER = function toDER(enc) {
      var r = this.r.toArray();
      var s = this.s.toArray();
    
      // Pad values
      if (r[0] & 0x80)
        r = [ 0 ].concat(r);
      // Pad values
      if (s[0] & 0x80)
        s = [ 0 ].concat(s);
    
      r = rmPadding(r);
      s = rmPadding(s);
    
      while (!s[0] && !(s[1] & 0x80)) {
        s = s.slice(1);
      }
      var arr = [ 0x02 ];
      constructLength(arr, r.length);
      arr = arr.concat(r);
      arr.push(0x02);
      constructLength(arr, s.length);
      var backHalf = arr.concat(s);
      var res = [ 0x30 ];
      constructLength(res, backHalf.length);
      res = res.concat(backHalf);
      return utils.encode(res, enc);
    };
    
    },{"../utils":132,"bn.js":33}],128:[function(require,module,exports){
    'use strict';
    
    var hash = require('hash.js');
    var curves = require('../curves');
    var utils = require('../utils');
    var assert = utils.assert;
    var parseBytes = utils.parseBytes;
    var KeyPair = require('./key');
    var Signature = require('./signature');
    
    function EDDSA(curve) {
      assert(curve === 'ed25519', 'only tested with ed25519 so far');
    
      if (!(this instanceof EDDSA))
        return new EDDSA(curve);
    
      curve = curves[curve].curve;
      this.curve = curve;
      this.g = curve.g;
      this.g.precompute(curve.n.bitLength() + 1);
    
      this.pointClass = curve.point().constructor;
      this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
      this.hash = hash.sha512;
    }
    
    module.exports = EDDSA;
    
    /**
    * @param {Array|String} message - message bytes
    * @param {Array|String|KeyPair} secret - secret bytes or a keypair
    * @returns {Signature} - signature
    */
    EDDSA.prototype.sign = function sign(message, secret) {
      message = parseBytes(message);
      var key = this.keyFromSecret(secret);
      var r = this.hashInt(key.messagePrefix(), message);
      var R = this.g.mul(r);
      var Rencoded = this.encodePoint(R);
      var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
        .mul(key.priv());
      var S = r.add(s_).umod(this.curve.n);
      return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
    };
    
    /**
    * @param {Array} message - message bytes
    * @param {Array|String|Signature} sig - sig bytes
    * @param {Array|String|Point|KeyPair} pub - public key
    * @returns {Boolean} - true if public key matches sig of message
    */
    EDDSA.prototype.verify = function verify(message, sig, pub) {
      message = parseBytes(message);
      sig = this.makeSignature(sig);
      var key = this.keyFromPublic(pub);
      var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
      var SG = this.g.mul(sig.S());
      var RplusAh = sig.R().add(key.pub().mul(h));
      return RplusAh.eq(SG);
    };
    
    EDDSA.prototype.hashInt = function hashInt() {
      var hash = this.hash();
      for (var i = 0; i < arguments.length; i++)
        hash.update(arguments[i]);
      return utils.intFromLE(hash.digest()).umod(this.curve.n);
    };
    
    EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
      return KeyPair.fromPublic(this, pub);
    };
    
    EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
      return KeyPair.fromSecret(this, secret);
    };
    
    EDDSA.prototype.makeSignature = function makeSignature(sig) {
      if (sig instanceof Signature)
        return sig;
      return new Signature(this, sig);
    };
    
    /**
    * * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
    *
    * EDDSA defines methods for encoding and decoding points and integers. These are
    * helper convenience methods, that pass along to utility functions implied
    * parameters.
    *
    */
    EDDSA.prototype.encodePoint = function encodePoint(point) {
      var enc = point.getY().toArray('le', this.encodingLength);
      enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
      return enc;
    };
    
    EDDSA.prototype.decodePoint = function decodePoint(bytes) {
      bytes = utils.parseBytes(bytes);
    
      var lastIx = bytes.length - 1;
      var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
      var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
    
      var y = utils.intFromLE(normed);
      return this.curve.pointFromY(y, xIsOdd);
    };
    
    EDDSA.prototype.encodeInt = function encodeInt(num) {
      return num.toArray('le', this.encodingLength);
    };
    
    EDDSA.prototype.decodeInt = function decodeInt(bytes) {
      return utils.intFromLE(bytes);
    };
    
    EDDSA.prototype.isPoint = function isPoint(val) {
      return val instanceof this.pointClass;
    };
    
    },{"../curves":124,"../utils":132,"./key":129,"./signature":130,"hash.js":167}],129:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var assert = utils.assert;
    var parseBytes = utils.parseBytes;
    var cachedProperty = utils.cachedProperty;
    
    /**
    * @param {EDDSA} eddsa - instance
    * @param {Object} params - public/private key parameters
    *
    * @param {Array<Byte>} [params.secret] - secret seed bytes
    * @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
    * @param {Array<Byte>} [params.pub] - public key point encoded as bytes
    *
    */
    function KeyPair(eddsa, params) {
      this.eddsa = eddsa;
      this._secret = parseBytes(params.secret);
      if (eddsa.isPoint(params.pub))
        this._pub = params.pub;
      else
        this._pubBytes = parseBytes(params.pub);
    }
    
    KeyPair.fromPublic = function fromPublic(eddsa, pub) {
      if (pub instanceof KeyPair)
        return pub;
      return new KeyPair(eddsa, { pub: pub });
    };
    
    KeyPair.fromSecret = function fromSecret(eddsa, secret) {
      if (secret instanceof KeyPair)
        return secret;
      return new KeyPair(eddsa, { secret: secret });
    };
    
    KeyPair.prototype.secret = function secret() {
      return this._secret;
    };
    
    cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
      return this.eddsa.encodePoint(this.pub());
    });
    
    cachedProperty(KeyPair, 'pub', function pub() {
      if (this._pubBytes)
        return this.eddsa.decodePoint(this._pubBytes);
      return this.eddsa.g.mul(this.priv());
    });
    
    cachedProperty(KeyPair, 'privBytes', function privBytes() {
      var eddsa = this.eddsa;
      var hash = this.hash();
      var lastIx = eddsa.encodingLength - 1;
    
      var a = hash.slice(0, eddsa.encodingLength);
      a[0] &= 248;
      a[lastIx] &= 127;
      a[lastIx] |= 64;
    
      return a;
    });
    
    cachedProperty(KeyPair, 'priv', function priv() {
      return this.eddsa.decodeInt(this.privBytes());
    });
    
    cachedProperty(KeyPair, 'hash', function hash() {
      return this.eddsa.hash().update(this.secret()).digest();
    });
    
    cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
      return this.hash().slice(this.eddsa.encodingLength);
    });
    
    KeyPair.prototype.sign = function sign(message) {
      assert(this._secret, 'KeyPair can only verify');
      return this.eddsa.sign(message, this);
    };
    
    KeyPair.prototype.verify = function verify(message, sig) {
      return this.eddsa.verify(message, sig, this);
    };
    
    KeyPair.prototype.getSecret = function getSecret(enc) {
      assert(this._secret, 'KeyPair is public only');
      return utils.encode(this.secret(), enc);
    };
    
    KeyPair.prototype.getPublic = function getPublic(enc) {
      return utils.encode(this.pubBytes(), enc);
    };
    
    module.exports = KeyPair;
    
    },{"../utils":132}],130:[function(require,module,exports){
    'use strict';
    
    var BN = require('bn.js');
    var utils = require('../utils');
    var assert = utils.assert;
    var cachedProperty = utils.cachedProperty;
    var parseBytes = utils.parseBytes;
    
    /**
    * @param {EDDSA} eddsa - eddsa instance
    * @param {Array<Bytes>|Object} sig -
    * @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
    * @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
    * @param {Array<Bytes>} [sig.Rencoded] - R point encoded
    * @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
    */
    function Signature(eddsa, sig) {
      this.eddsa = eddsa;
    
      if (typeof sig !== 'object')
        sig = parseBytes(sig);
    
      if (Array.isArray(sig)) {
        sig = {
          R: sig.slice(0, eddsa.encodingLength),
          S: sig.slice(eddsa.encodingLength),
        };
      }
    
      assert(sig.R && sig.S, 'Signature without R or S');
    
      if (eddsa.isPoint(sig.R))
        this._R = sig.R;
      if (sig.S instanceof BN)
        this._S = sig.S;
    
      this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
      this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
    }
    
    cachedProperty(Signature, 'S', function S() {
      return this.eddsa.decodeInt(this.Sencoded());
    });
    
    cachedProperty(Signature, 'R', function R() {
      return this.eddsa.decodePoint(this.Rencoded());
    });
    
    cachedProperty(Signature, 'Rencoded', function Rencoded() {
      return this.eddsa.encodePoint(this.R());
    });
    
    cachedProperty(Signature, 'Sencoded', function Sencoded() {
      return this.eddsa.encodeInt(this.S());
    });
    
    Signature.prototype.toBytes = function toBytes() {
      return this.Rencoded().concat(this.Sencoded());
    };
    
    Signature.prototype.toHex = function toHex() {
      return utils.encode(this.toBytes(), 'hex').toUpperCase();
    };
    
    module.exports = Signature;
    
    },{"../utils":132,"bn.js":33}],131:[function(require,module,exports){
    module.exports = {
      doubles: {
        step: 4,
        points: [
          [
            'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
            'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821',
          ],
          [
            '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
            '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf',
          ],
          [
            '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
            'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695',
          ],
          [
            '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
            '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9',
          ],
          [
            '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
            '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36',
          ],
          [
            '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
            '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f',
          ],
          [
            'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
            '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999',
          ],
          [
            '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
            'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09',
          ],
          [
            'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
            '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d',
          ],
          [
            'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
            'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088',
          ],
          [
            'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
            '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d',
          ],
          [
            '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
            '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8',
          ],
          [
            '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
            '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a',
          ],
          [
            '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
            '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453',
          ],
          [
            '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
            '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160',
          ],
          [
            '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
            '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0',
          ],
          [
            '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
            '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6',
          ],
          [
            '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
            '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589',
          ],
          [
            '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
            'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17',
          ],
          [
            'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
            '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda',
          ],
          [
            'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
            '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd',
          ],
          [
            '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
            '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2',
          ],
          [
            '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
            '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6',
          ],
          [
            'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
            '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f',
          ],
          [
            '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
            'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01',
          ],
          [
            'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
            '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3',
          ],
          [
            'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
            'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f',
          ],
          [
            'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
            '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7',
          ],
          [
            'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
            'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78',
          ],
          [
            'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
            '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1',
          ],
          [
            '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
            'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150',
          ],
          [
            '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
            '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82',
          ],
          [
            'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
            '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc',
          ],
          [
            '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
            'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b',
          ],
          [
            'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
            '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51',
          ],
          [
            'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
            '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45',
          ],
          [
            'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
            'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120',
          ],
          [
            '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
            '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84',
          ],
          [
            '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
            '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d',
          ],
          [
            '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
            'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d',
          ],
          [
            '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
            '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8',
          ],
          [
            'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
            '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8',
          ],
          [
            '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
            '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac',
          ],
          [
            '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
            'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f',
          ],
          [
            '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
            '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962',
          ],
          [
            'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
            '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907',
          ],
          [
            '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
            'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec',
          ],
          [
            'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
            'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d',
          ],
          [
            'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
            '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414',
          ],
          [
            '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
            'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd',
          ],
          [
            '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
            'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0',
          ],
          [
            'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
            '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811',
          ],
          [
            'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
            '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1',
          ],
          [
            'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
            '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c',
          ],
          [
            '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
            'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73',
          ],
          [
            '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
            '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd',
          ],
          [
            'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
            'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405',
          ],
          [
            '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
            'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589',
          ],
          [
            '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
            '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e',
          ],
          [
            '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
            '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27',
          ],
          [
            'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
            'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1',
          ],
          [
            '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
            '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482',
          ],
          [
            '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
            '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945',
          ],
          [
            'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
            '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573',
          ],
          [
            'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
            'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82',
          ],
        ],
      },
      naf: {
        wnd: 7,
        points: [
          [
            'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
            '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672',
          ],
          [
            '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
            'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6',
          ],
          [
            '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
            '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da',
          ],
          [
            'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
            'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37',
          ],
          [
            '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
            'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b',
          ],
          [
            'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
            'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81',
          ],
          [
            'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
            '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58',
          ],
          [
            'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
            '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77',
          ],
          [
            '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
            '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a',
          ],
          [
            '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
            '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c',
          ],
          [
            '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
            '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67',
          ],
          [
            '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
            '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402',
          ],
          [
            'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
            'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55',
          ],
          [
            'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
            '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482',
          ],
          [
            '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
            'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82',
          ],
          [
            '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
            'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396',
          ],
          [
            '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
            '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49',
          ],
          [
            '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
            '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf',
          ],
          [
            '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
            '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a',
          ],
          [
            '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
            'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7',
          ],
          [
            'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
            'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933',
          ],
          [
            '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
            '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a',
          ],
          [
            '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
            '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6',
          ],
          [
            'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
            'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37',
          ],
          [
            '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
            '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e',
          ],
          [
            'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
            'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6',
          ],
          [
            'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
            'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476',
          ],
          [
            '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
            '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40',
          ],
          [
            '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
            '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61',
          ],
          [
            '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
            '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683',
          ],
          [
            'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
            '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5',
          ],
          [
            '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
            '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b',
          ],
          [
            'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
            '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417',
          ],
          [
            '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
            'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868',
          ],
          [
            '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
            'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a',
          ],
          [
            'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
            'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6',
          ],
          [
            '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
            '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996',
          ],
          [
            '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
            'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e',
          ],
          [
            'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
            'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d',
          ],
          [
            '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
            '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2',
          ],
          [
            '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
            'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e',
          ],
          [
            '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
            '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437',
          ],
          [
            '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
            'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311',
          ],
          [
            'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
            '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4',
          ],
          [
            '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
            '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575',
          ],
          [
            '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
            'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d',
          ],
          [
            '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
            'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d',
          ],
          [
            'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
            'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629',
          ],
          [
            'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
            'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06',
          ],
          [
            '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
            '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374',
          ],
          [
            '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
            '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee',
          ],
          [
            'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
            '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1',
          ],
          [
            'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
            'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b',
          ],
          [
            '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
            '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661',
          ],
          [
            '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
            '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6',
          ],
          [
            'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
            '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e',
          ],
          [
            '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
            '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d',
          ],
          [
            'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
            'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc',
          ],
          [
            '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
            'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4',
          ],
          [
            '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
            '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c',
          ],
          [
            'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
            '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b',
          ],
          [
            'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
            '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913',
          ],
          [
            '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
            '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154',
          ],
          [
            '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
            '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865',
          ],
          [
            '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
            'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc',
          ],
          [
            '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
            'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224',
          ],
          [
            '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
            '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e',
          ],
          [
            '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
            '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6',
          ],
          [
            '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
            '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511',
          ],
          [
            '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
            'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b',
          ],
          [
            'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
            'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2',
          ],
          [
            '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
            'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c',
          ],
          [
            'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
            '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3',
          ],
          [
            'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
            '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d',
          ],
          [
            'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
            '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700',
          ],
          [
            'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
            '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4',
          ],
          [
            '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
            'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196',
          ],
          [
            '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
            '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4',
          ],
          [
            '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
            'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257',
          ],
          [
            'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
            'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13',
          ],
          [
            'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
            '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096',
          ],
          [
            'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
            'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38',
          ],
          [
            'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
            '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f',
          ],
          [
            '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
            '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448',
          ],
          [
            'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
            '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a',
          ],
          [
            'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
            '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4',
          ],
          [
            '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
            '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437',
          ],
          [
            '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
            'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7',
          ],
          [
            'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
            '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d',
          ],
          [
            'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
            '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a',
          ],
          [
            'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
            '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54',
          ],
          [
            '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
            '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77',
          ],
          [
            'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
            'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517',
          ],
          [
            '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
            'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10',
          ],
          [
            'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
            'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125',
          ],
          [
            'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
            '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e',
          ],
          [
            '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
            'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1',
          ],
          [
            'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
            '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2',
          ],
          [
            'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
            '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423',
          ],
          [
            'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
            '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8',
          ],
          [
            '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
            'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758',
          ],
          [
            '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
            'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375',
          ],
          [
            'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
            '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d',
          ],
          [
            '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
            'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec',
          ],
          [
            '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
            '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0',
          ],
          [
            '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
            'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c',
          ],
          [
            'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
            'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4',
          ],
          [
            '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
            'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f',
          ],
          [
            '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
            '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649',
          ],
          [
            '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
            'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826',
          ],
          [
            '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
            '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5',
          ],
          [
            'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
            'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87',
          ],
          [
            '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
            '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b',
          ],
          [
            'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
            '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc',
          ],
          [
            '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
            '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c',
          ],
          [
            'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
            'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f',
          ],
          [
            'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
            '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a',
          ],
          [
            'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
            'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46',
          ],
          [
            '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
            'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f',
          ],
          [
            '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
            '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03',
          ],
          [
            '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
            'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08',
          ],
          [
            '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
            '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8',
          ],
          [
            '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
            '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373',
          ],
          [
            '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
            'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3',
          ],
          [
            '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
            '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8',
          ],
          [
            '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
            '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1',
          ],
          [
            '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
            '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9',
          ],
        ],
      },
    };
    
    },{}],132:[function(require,module,exports){
    'use strict';
    
    var utils = exports;
    var BN = require('bn.js');
    var minAssert = require('minimalistic-assert');
    var minUtils = require('minimalistic-crypto-utils');
    
    utils.assert = minAssert;
    utils.toArray = minUtils.toArray;
    utils.zero2 = minUtils.zero2;
    utils.toHex = minUtils.toHex;
    utils.encode = minUtils.encode;
    
    // Represent num in a w-NAF form
    function getNAF(num, w, bits) {
      var naf = new Array(Math.max(num.bitLength(), bits) + 1);
      naf.fill(0);
    
      var ws = 1 << (w + 1);
      var k = num.clone();
    
      for (var i = 0; i < naf.length; i++) {
        var z;
        var mod = k.andln(ws - 1);
        if (k.isOdd()) {
          if (mod > (ws >> 1) - 1)
            z = (ws >> 1) - mod;
          else
            z = mod;
          k.isubn(z);
        } else {
          z = 0;
        }
    
        naf[i] = z;
        k.iushrn(1);
      }
    
      return naf;
    }
    utils.getNAF = getNAF;
    
    // Represent k1, k2 in a Joint Sparse Form
    function getJSF(k1, k2) {
      var jsf = [
        [],
        [],
      ];
    
      k1 = k1.clone();
      k2 = k2.clone();
      var d1 = 0;
      var d2 = 0;
      var m8;
      while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
        // First phase
        var m14 = (k1.andln(3) + d1) & 3;
        var m24 = (k2.andln(3) + d2) & 3;
        if (m14 === 3)
          m14 = -1;
        if (m24 === 3)
          m24 = -1;
        var u1;
        if ((m14 & 1) === 0) {
          u1 = 0;
        } else {
          m8 = (k1.andln(7) + d1) & 7;
          if ((m8 === 3 || m8 === 5) && m24 === 2)
            u1 = -m14;
          else
            u1 = m14;
        }
        jsf[0].push(u1);
    
        var u2;
        if ((m24 & 1) === 0) {
          u2 = 0;
        } else {
          m8 = (k2.andln(7) + d2) & 7;
          if ((m8 === 3 || m8 === 5) && m14 === 2)
            u2 = -m24;
          else
            u2 = m24;
        }
        jsf[1].push(u2);
    
        // Second phase
        if (2 * d1 === u1 + 1)
          d1 = 1 - d1;
        if (2 * d2 === u2 + 1)
          d2 = 1 - d2;
        k1.iushrn(1);
        k2.iushrn(1);
      }
    
      return jsf;
    }
    utils.getJSF = getJSF;
    
    function cachedProperty(obj, name, computer) {
      var key = '_' + name;
      obj.prototype[name] = function cachedProperty() {
        return this[key] !== undefined ? this[key] :
          this[key] = computer.call(this);
      };
    }
    utils.cachedProperty = cachedProperty;
    
    function parseBytes(bytes) {
      return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
        bytes;
    }
    utils.parseBytes = parseBytes;
    
    function intFromLE(bytes) {
      return new BN(bytes, 'hex', 'le');
    }
    utils.intFromLE = intFromLE;
    
    
    },{"bn.js":33,"minimalistic-assert":194,"minimalistic-crypto-utils":195}],133:[function(require,module,exports){
    module.exports={
      "name": "elliptic",
      "version": "6.5.4",
      "description": "EC cryptography",
      "main": "lib/elliptic.js",
      "files": [
        "lib"
      ],
      "scripts": {
        "lint": "eslint lib test",
        "lint:fix": "npm run lint -- --fix",
        "unit": "istanbul test _mocha --reporter=spec test/index.js",
        "test": "npm run lint && npm run unit",
        "version": "grunt dist && git add dist/"
      },
      "repository": {
        "type": "git",
        "url": "git@github.com:indutny/elliptic"
      },
      "keywords": [
        "EC",
        "Elliptic",
        "curve",
        "Cryptography"
      ],
      "author": "Fedor Indutny <fedor@indutny.com>",
      "license": "MIT",
      "bugs": {
        "url": "https://github.com/indutny/elliptic/issues"
      },
      "homepage": "https://github.com/indutny/elliptic",
      "devDependencies": {
        "brfs": "^2.0.2",
        "coveralls": "^3.1.0",
        "eslint": "^7.6.0",
        "grunt": "^1.2.1",
        "grunt-browserify": "^5.3.0",
        "grunt-cli": "^1.3.2",
        "grunt-contrib-connect": "^3.0.0",
        "grunt-contrib-copy": "^1.0.0",
        "grunt-contrib-uglify": "^5.0.0",
        "grunt-mocha-istanbul": "^5.0.2",
        "grunt-saucelabs": "^9.0.1",
        "istanbul": "^0.4.5",
        "mocha": "^8.0.1"
      },
      "dependencies": {
        "bn.js": "^4.11.9",
        "brorand": "^1.1.0",
        "hash.js": "^1.0.0",
        "hmac-drbg": "^1.0.1",
        "inherits": "^2.0.4",
        "minimalistic-assert": "^1.0.1",
        "minimalistic-crypto-utils": "^1.0.1"
      }
    }
    
    },{}],134:[function(require,module,exports){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    var R = typeof Reflect === 'object' ? Reflect : null
    var ReflectApply = R && typeof R.apply === 'function'
      ? R.apply
      : function ReflectApply(target, receiver, args) {
        return Function.prototype.apply.call(target, receiver, args);
      }
    
    var ReflectOwnKeys
    if (R && typeof R.ownKeys === 'function') {
      ReflectOwnKeys = R.ownKeys
    } else if (Object.getOwnPropertySymbols) {
      ReflectOwnKeys = function ReflectOwnKeys(target) {
        return Object.getOwnPropertyNames(target)
          .concat(Object.getOwnPropertySymbols(target));
      };
    } else {
      ReflectOwnKeys = function ReflectOwnKeys(target) {
        return Object.getOwnPropertyNames(target);
      };
    }
    
    function ProcessEmitWarning(warning) {
      if (console && console.warn) console.warn(warning);
    }
    
    var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
      return value !== value;
    }
    
    function EventEmitter() {
      EventEmitter.init.call(this);
    }
    module.exports = EventEmitter;
    module.exports.once = once;
    
    // Backwards-compat with node 0.10.x
    EventEmitter.EventEmitter = EventEmitter;
    
    EventEmitter.prototype._events = undefined;
    EventEmitter.prototype._eventsCount = 0;
    EventEmitter.prototype._maxListeners = undefined;
    
    // By default EventEmitters will print a warning if more than 10 listeners are
    // added to it. This is a useful default which helps finding memory leaks.
    var defaultMaxListeners = 10;
    
    function checkListener(listener) {
      if (typeof listener !== 'function') {
        throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
      }
    }
    
    Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
      enumerable: true,
      get: function() {
        return defaultMaxListeners;
      },
      set: function(arg) {
        if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
          throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
        }
        defaultMaxListeners = arg;
      }
    });
    
    EventEmitter.init = function() {
    
      if (this._events === undefined ||
          this._events === Object.getPrototypeOf(this)._events) {
        this._events = Object.create(null);
        this._eventsCount = 0;
      }
    
      this._maxListeners = this._maxListeners || undefined;
    };
    
    // Obviously not all Emitters should be limited to 10. This function allows
    // that to be increased. Set to zero for unlimited.
    EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
      if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
        throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
      }
      this._maxListeners = n;
      return this;
    };
    
    function _getMaxListeners(that) {
      if (that._maxListeners === undefined)
        return EventEmitter.defaultMaxListeners;
      return that._maxListeners;
    }
    
    EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
      return _getMaxListeners(this);
    };
    
    EventEmitter.prototype.emit = function emit(type) {
      var args = [];
      for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
      var doError = (type === 'error');
    
      var events = this._events;
      if (events !== undefined)
        doError = (doError && events.error === undefined);
      else if (!doError)
        return false;
    
      // If there is no 'error' event listener then throw.
      if (doError) {
        var er;
        if (args.length > 0)
          er = args[0];
        if (er instanceof Error) {
          // Note: The comments on the `throw` lines are intentional, they show
          // up in Node's output if this results in an unhandled exception.
          throw er; // Unhandled 'error' event
        }
        // At least give some kind of context to the user
        var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
        err.context = er;
        throw err; // Unhandled 'error' event
      }
    
      var handler = events[type];
    
      if (handler === undefined)
        return false;
    
      if (typeof handler === 'function') {
        ReflectApply(handler, this, args);
      } else {
        var len = handler.length;
        var listeners = arrayClone(handler, len);
        for (var i = 0; i < len; ++i)
          ReflectApply(listeners[i], this, args);
      }
    
      return true;
    };
    
    function _addListener(target, type, listener, prepend) {
      var m;
      var events;
      var existing;
    
      checkListener(listener);
    
      events = target._events;
      if (events === undefined) {
        events = target._events = Object.create(null);
        target._eventsCount = 0;
      } else {
        // To avoid recursion in the case that type === "newListener"! Before
        // adding it to the listeners, first emit "newListener".
        if (events.newListener !== undefined) {
          target.emit('newListener', type,
                      listener.listener ? listener.listener : listener);
    
          // Re-assign `events` because a newListener handler could have caused the
          // this._events to be assigned to a new object
          events = target._events;
        }
        existing = events[type];
      }
    
      if (existing === undefined) {
        // Optimize the case of one listener. Don't need the extra array object.
        existing = events[type] = listener;
        ++target._eventsCount;
      } else {
        if (typeof existing === 'function') {
          // Adding the second element, need to change to array.
          existing = events[type] =
            prepend ? [listener, existing] : [existing, listener];
          // If we've already got an array, just append.
        } else if (prepend) {
          existing.unshift(listener);
        } else {
          existing.push(listener);
        }
    
        // Check for listener leak
        m = _getMaxListeners(target);
        if (m > 0 && existing.length > m && !existing.warned) {
          existing.warned = true;
          // No error code for this since it is a Warning
          // eslint-disable-next-line no-restricted-syntax
          var w = new Error('Possible EventEmitter memory leak detected. ' +
                              existing.length + ' ' + String(type) + ' listeners ' +
                              'added. Use emitter.setMaxListeners() to ' +
                              'increase limit');
          w.name = 'MaxListenersExceededWarning';
          w.emitter = target;
          w.type = type;
          w.count = existing.length;
          ProcessEmitWarning(w);
        }
      }
    
      return target;
    }
    
    EventEmitter.prototype.addListener = function addListener(type, listener) {
      return _addListener(this, type, listener, false);
    };
    
    EventEmitter.prototype.on = EventEmitter.prototype.addListener;
    
    EventEmitter.prototype.prependListener =
        function prependListener(type, listener) {
          return _addListener(this, type, listener, true);
        };
    
    function onceWrapper() {
      if (!this.fired) {
        this.target.removeListener(this.type, this.wrapFn);
        this.fired = true;
        if (arguments.length === 0)
          return this.listener.call(this.target);
        return this.listener.apply(this.target, arguments);
      }
    }
    
    function _onceWrap(target, type, listener) {
      var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
      var wrapped = onceWrapper.bind(state);
      wrapped.listener = listener;
      state.wrapFn = wrapped;
      return wrapped;
    }
    
    EventEmitter.prototype.once = function once(type, listener) {
      checkListener(listener);
      this.on(type, _onceWrap(this, type, listener));
      return this;
    };
    
    EventEmitter.prototype.prependOnceListener =
        function prependOnceListener(type, listener) {
          checkListener(listener);
          this.prependListener(type, _onceWrap(this, type, listener));
          return this;
        };
    
    // Emits a 'removeListener' event if and only if the listener was removed.
    EventEmitter.prototype.removeListener =
        function removeListener(type, listener) {
          var list, events, position, i, originalListener;
    
          checkListener(listener);
    
          events = this._events;
          if (events === undefined)
            return this;
    
          list = events[type];
          if (list === undefined)
            return this;
    
          if (list === listener || list.listener === listener) {
            if (--this._eventsCount === 0)
              this._events = Object.create(null);
            else {
              delete events[type];
              if (events.removeListener)
                this.emit('removeListener', type, list.listener || listener);
            }
          } else if (typeof list !== 'function') {
            position = -1;
    
            for (i = list.length - 1; i >= 0; i--) {
              if (list[i] === listener || list[i].listener === listener) {
                originalListener = list[i].listener;
                position = i;
                break;
              }
            }
    
            if (position < 0)
              return this;
    
            if (position === 0)
              list.shift();
            else {
              spliceOne(list, position);
            }
    
            if (list.length === 1)
              events[type] = list[0];
    
            if (events.removeListener !== undefined)
              this.emit('removeListener', type, originalListener || listener);
          }
    
          return this;
        };
    
    EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
    
    EventEmitter.prototype.removeAllListeners =
        function removeAllListeners(type) {
          var listeners, events, i;
    
          events = this._events;
          if (events === undefined)
            return this;
    
          // not listening for removeListener, no need to emit
          if (events.removeListener === undefined) {
            if (arguments.length === 0) {
              this._events = Object.create(null);
              this._eventsCount = 0;
            } else if (events[type] !== undefined) {
              if (--this._eventsCount === 0)
                this._events = Object.create(null);
              else
                delete events[type];
            }
            return this;
          }
    
          // emit removeListener for all listeners on all events
          if (arguments.length === 0) {
            var keys = Object.keys(events);
            var key;
            for (i = 0; i < keys.length; ++i) {
              key = keys[i];
              if (key === 'removeListener') continue;
              this.removeAllListeners(key);
            }
            this.removeAllListeners('removeListener');
            this._events = Object.create(null);
            this._eventsCount = 0;
            return this;
          }
    
          listeners = events[type];
    
          if (typeof listeners === 'function') {
            this.removeListener(type, listeners);
          } else if (listeners !== undefined) {
            // LIFO order
            for (i = listeners.length - 1; i >= 0; i--) {
              this.removeListener(type, listeners[i]);
            }
          }
    
          return this;
        };
    
    function _listeners(target, type, unwrap) {
      var events = target._events;
    
      if (events === undefined)
        return [];
    
      var evlistener = events[type];
      if (evlistener === undefined)
        return [];
    
      if (typeof evlistener === 'function')
        return unwrap ? [evlistener.listener || evlistener] : [evlistener];
    
      return unwrap ?
        unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
    }
    
    EventEmitter.prototype.listeners = function listeners(type) {
      return _listeners(this, type, true);
    };
    
    EventEmitter.prototype.rawListeners = function rawListeners(type) {
      return _listeners(this, type, false);
    };
    
    EventEmitter.listenerCount = function(emitter, type) {
      if (typeof emitter.listenerCount === 'function') {
        return emitter.listenerCount(type);
      } else {
        return listenerCount.call(emitter, type);
      }
    };
    
    EventEmitter.prototype.listenerCount = listenerCount;
    function listenerCount(type) {
      var events = this._events;
    
      if (events !== undefined) {
        var evlistener = events[type];
    
        if (typeof evlistener === 'function') {
          return 1;
        } else if (evlistener !== undefined) {
          return evlistener.length;
        }
      }
    
      return 0;
    }
    
    EventEmitter.prototype.eventNames = function eventNames() {
      return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
    };
    
    function arrayClone(arr, n) {
      var copy = new Array(n);
      for (var i = 0; i < n; ++i)
        copy[i] = arr[i];
      return copy;
    }
    
    function spliceOne(list, index) {
      for (; index + 1 < list.length; index++)
        list[index] = list[index + 1];
      list.pop();
    }
    
    function unwrapListeners(arr) {
      var ret = new Array(arr.length);
      for (var i = 0; i < ret.length; ++i) {
        ret[i] = arr[i].listener || arr[i];
      }
      return ret;
    }
    
    function once(emitter, name) {
      return new Promise(function (resolve, reject) {
        function errorListener(err) {
          emitter.removeListener(name, resolver);
          reject(err);
        }
    
        function resolver() {
          if (typeof emitter.removeListener === 'function') {
            emitter.removeListener('error', errorListener);
          }
          resolve([].slice.call(arguments));
        };
    
        eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
        if (name !== 'error') {
          addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
        }
      });
    }
    
    function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
      if (typeof emitter.on === 'function') {
        eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
      }
    }
    
    function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
      if (typeof emitter.on === 'function') {
        if (flags.once) {
          emitter.once(name, listener);
        } else {
          emitter.on(name, listener);
        }
      } else if (typeof emitter.addEventListener === 'function') {
        // EventTarget does not have `error` event semantics like Node
        // EventEmitters, we do not listen for `error` events here.
        emitter.addEventListener(name, function wrapListener(arg) {
          // IE does not have builtin `{ once: true }` support so we
          // have to do it manually.
          if (flags.once) {
            emitter.removeEventListener(name, wrapListener);
          }
          listener(arg);
        });
      } else {
        throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
      }
    }
    
    },{}],135:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    var MD5 = require('md5.js')
    
    /* eslint-disable camelcase */
    function EVP_BytesToKey (password, salt, keyBits, ivLen) {
      if (!Buffer.isBuffer(password)) password = Buffer.from(password, 'binary')
      if (salt) {
        if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, 'binary')
        if (salt.length !== 8) throw new RangeError('salt should be Buffer with 8 byte length')
      }
    
      var keyLen = keyBits / 8
      var key = Buffer.alloc(keyLen)
      var iv = Buffer.alloc(ivLen || 0)
      var tmp = Buffer.alloc(0)
    
      while (keyLen > 0 || ivLen > 0) {
        var hash = new MD5()
        hash.update(tmp)
        hash.update(password)
        if (salt) hash.update(salt)
        tmp = hash.digest()
    
        var used = 0
    
        if (keyLen > 0) {
          var keyStart = key.length - keyLen
          used = Math.min(keyLen, tmp.length)
          tmp.copy(key, keyStart, 0, used)
          keyLen -= used
        }
    
        if (used < tmp.length && ivLen > 0) {
          var ivStart = iv.length - ivLen
          var length = Math.min(ivLen, tmp.length - used)
          tmp.copy(iv, ivStart, used, used + length)
          ivLen -= length
        }
      }
    
      tmp.fill(0)
      return { key: key, iv: iv }
    }
    
    module.exports = EVP_BytesToKey
    
    },{"md5.js":191,"safe-buffer":338}],136:[function(require,module,exports){
    'use strict';
    
    var isCallable = require('is-callable');
    
    var toStr = Object.prototype.toString;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    
    var forEachArray = function forEachArray(array, iterator, receiver) {
        for (var i = 0, len = array.length; i < len; i++) {
            if (hasOwnProperty.call(array, i)) {
                if (receiver == null) {
                    iterator(array[i], i, array);
                } else {
                    iterator.call(receiver, array[i], i, array);
                }
            }
        }
    };
    
    var forEachString = function forEachString(string, iterator, receiver) {
        for (var i = 0, len = string.length; i < len; i++) {
            // no such thing as a sparse string.
            if (receiver == null) {
                iterator(string.charAt(i), i, string);
            } else {
                iterator.call(receiver, string.charAt(i), i, string);
            }
        }
    };
    
    var forEachObject = function forEachObject(object, iterator, receiver) {
        for (var k in object) {
            if (hasOwnProperty.call(object, k)) {
                if (receiver == null) {
                    iterator(object[k], k, object);
                } else {
                    iterator.call(receiver, object[k], k, object);
                }
            }
        }
    };
    
    var forEach = function forEach(list, iterator, thisArg) {
        if (!isCallable(iterator)) {
            throw new TypeError('iterator must be a function');
        }
    
        var receiver;
        if (arguments.length >= 3) {
            receiver = thisArg;
        }
    
        if (toStr.call(list) === '[object Array]') {
            forEachArray(list, iterator, receiver);
        } else if (typeof list === 'string') {
            forEachString(list, iterator, receiver);
        } else {
            forEachObject(list, iterator, receiver);
        }
    };
    
    module.exports = forEach;
    
    },{"is-callable":185}],137:[function(require,module,exports){
    (function (process){(function (){
    module.exports = realpath
    realpath.realpath = realpath
    realpath.sync = realpathSync
    realpath.realpathSync = realpathSync
    realpath.monkeypatch = monkeypatch
    realpath.unmonkeypatch = unmonkeypatch
    
    var fs = require('fs')
    var origRealpath = fs.realpath
    var origRealpathSync = fs.realpathSync
    
    var version = process.version
    var ok = /^v[0-5]\./.test(version)
    var old = require('./old.js')
    
    function newError (er) {
      return er && er.syscall === 'realpath' && (
        er.code === 'ELOOP' ||
        er.code === 'ENOMEM' ||
        er.code === 'ENAMETOOLONG'
      )
    }
    
    function realpath (p, cache, cb) {
      if (ok) {
        return origRealpath(p, cache, cb)
      }
    
      if (typeof cache === 'function') {
        cb = cache
        cache = null
      }
      origRealpath(p, cache, function (er, result) {
        if (newError(er)) {
          old.realpath(p, cache, cb)
        } else {
          cb(er, result)
        }
      })
    }
    
    function realpathSync (p, cache) {
      if (ok) {
        return origRealpathSync(p, cache)
      }
    
      try {
        return origRealpathSync(p, cache)
      } catch (er) {
        if (newError(er)) {
          return old.realpathSync(p, cache)
        } else {
          throw er
        }
      }
    }
    
    function monkeypatch () {
      fs.realpath = realpath
      fs.realpathSync = realpathSync
    }
    
    function unmonkeypatch () {
      fs.realpath = origRealpath
      fs.realpathSync = origRealpathSync
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./old.js":138,"_process":321,"fs":83}],138:[function(require,module,exports){
    (function (process){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    var pathModule = require('path');
    var isWindows = process.platform === 'win32';
    var fs = require('fs');
    
    // JavaScript implementation of realpath, ported from node pre-v6
    
    var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
    
    function rethrow() {
      // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
      // is fairly slow to generate.
      var callback;
      if (DEBUG) {
        var backtrace = new Error;
        callback = debugCallback;
      } else
        callback = missingCallback;
    
      return callback;
    
      function debugCallback(err) {
        if (err) {
          backtrace.message = err.message;
          err = backtrace;
          missingCallback(err);
        }
      }
    
      function missingCallback(err) {
        if (err) {
          if (process.throwDeprecation)
            throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
          else if (!process.noDeprecation) {
            var msg = 'fs: missing callback ' + (err.stack || err.message);
            if (process.traceDeprecation)
              console.trace(msg);
            else
              console.error(msg);
          }
        }
      }
    }
    
    function maybeCallback(cb) {
      return typeof cb === 'function' ? cb : rethrow();
    }
    
    var normalize = pathModule.normalize;
    
    // Regexp that finds the next partion of a (partial) path
    // result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
    if (isWindows) {
      var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
    } else {
      var nextPartRe = /(.*?)(?:[\/]+|$)/g;
    }
    
    // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
    if (isWindows) {
      var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
    } else {
      var splitRootRe = /^[\/]*/;
    }
    
    exports.realpathSync = function realpathSync(p, cache) {
      // make p is absolute
      p = pathModule.resolve(p);
    
      if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
        return cache[p];
      }
    
      var original = p,
          seenLinks = {},
          knownHard = {};
    
      // current character position in p
      var pos;
      // the partial path so far, including a trailing slash if any
      var current;
      // the partial path without a trailing slash (except when pointing at a root)
      var base;
      // the partial path scanned in the previous round, with slash
      var previous;
    
      start();
    
      function start() {
        // Skip over roots
        var m = splitRootRe.exec(p);
        pos = m[0].length;
        current = m[0];
        base = m[0];
        previous = '';
    
        // On windows, check that the root exists. On unix there is no need.
        if (isWindows && !knownHard[base]) {
          fs.lstatSync(base);
          knownHard[base] = true;
        }
      }
    
      // walk down the path, swapping out linked pathparts for their real
      // values
      // NB: p.length changes.
      while (pos < p.length) {
        // find the next part
        nextPartRe.lastIndex = pos;
        var result = nextPartRe.exec(p);
        previous = current;
        current += result[0];
        base = previous + result[1];
        pos = nextPartRe.lastIndex;
    
        // continue if not a symlink
        if (knownHard[base] || (cache && cache[base] === base)) {
          continue;
        }
    
        var resolvedLink;
        if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
          // some known symbolic link.  no need to stat again.
          resolvedLink = cache[base];
        } else {
          var stat = fs.lstatSync(base);
          if (!stat.isSymbolicLink()) {
            knownHard[base] = true;
            if (cache) cache[base] = base;
            continue;
          }
    
          // read the link if it wasn't read before
          // dev/ino always return 0 on windows, so skip the check.
          var linkTarget = null;
          if (!isWindows) {
            var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
            if (seenLinks.hasOwnProperty(id)) {
              linkTarget = seenLinks[id];
            }
          }
          if (linkTarget === null) {
            fs.statSync(base);
            linkTarget = fs.readlinkSync(base);
          }
          resolvedLink = pathModule.resolve(previous, linkTarget);
          // track this, if given a cache.
          if (cache) cache[base] = resolvedLink;
          if (!isWindows) seenLinks[id] = linkTarget;
        }
    
        // resolve the link, then start over
        p = pathModule.resolve(resolvedLink, p.slice(pos));
        start();
      }
    
      if (cache) cache[original] = p;
    
      return p;
    };
    
    
    exports.realpath = function realpath(p, cache, cb) {
      if (typeof cb !== 'function') {
        cb = maybeCallback(cache);
        cache = null;
      }
    
      // make p is absolute
      p = pathModule.resolve(p);
    
      if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
        return process.nextTick(cb.bind(null, null, cache[p]));
      }
    
      var original = p,
          seenLinks = {},
          knownHard = {};
    
      // current character position in p
      var pos;
      // the partial path so far, including a trailing slash if any
      var current;
      // the partial path without a trailing slash (except when pointing at a root)
      var base;
      // the partial path scanned in the previous round, with slash
      var previous;
    
      start();
    
      function start() {
        // Skip over roots
        var m = splitRootRe.exec(p);
        pos = m[0].length;
        current = m[0];
        base = m[0];
        previous = '';
    
        // On windows, check that the root exists. On unix there is no need.
        if (isWindows && !knownHard[base]) {
          fs.lstat(base, function(err) {
            if (err) return cb(err);
            knownHard[base] = true;
            LOOP();
          });
        } else {
          process.nextTick(LOOP);
        }
      }
    
      // walk down the path, swapping out linked pathparts for their real
      // values
      function LOOP() {
        // stop if scanned past end of path
        if (pos >= p.length) {
          if (cache) cache[original] = p;
          return cb(null, p);
        }
    
        // find the next part
        nextPartRe.lastIndex = pos;
        var result = nextPartRe.exec(p);
        previous = current;
        current += result[0];
        base = previous + result[1];
        pos = nextPartRe.lastIndex;
    
        // continue if not a symlink
        if (knownHard[base] || (cache && cache[base] === base)) {
          return process.nextTick(LOOP);
        }
    
        if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
          // known symbolic link.  no need to stat again.
          return gotResolvedLink(cache[base]);
        }
    
        return fs.lstat(base, gotStat);
      }
    
      function gotStat(err, stat) {
        if (err) return cb(err);
    
        // if not a symlink, skip to the next path part
        if (!stat.isSymbolicLink()) {
          knownHard[base] = true;
          if (cache) cache[base] = base;
          return process.nextTick(LOOP);
        }
    
        // stat & read the link if not read before
        // call gotTarget as soon as the link target is known
        // dev/ino always return 0 on windows, so skip the check.
        if (!isWindows) {
          var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
          if (seenLinks.hasOwnProperty(id)) {
            return gotTarget(null, seenLinks[id], base);
          }
        }
        fs.stat(base, function(err) {
          if (err) return cb(err);
    
          fs.readlink(base, function(err, target) {
            if (!isWindows) seenLinks[id] = target;
            gotTarget(err, target);
          });
        });
      }
    
      function gotTarget(err, target, base) {
        if (err) return cb(err);
    
        var resolvedLink = pathModule.resolve(previous, target);
        if (cache) cache[base] = resolvedLink;
        gotResolvedLink(resolvedLink);
      }
    
      function gotResolvedLink(resolvedLink) {
        // resolve the link, then start over
        p = pathModule.resolve(resolvedLink, p.slice(pos));
        start();
      }
    };
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321,"fs":83,"path":313}],139:[function(require,module,exports){
    'use strict';
    
    /* eslint no-invalid-this: 1 */
    
    var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
    var slice = Array.prototype.slice;
    var toStr = Object.prototype.toString;
    var funcType = '[object Function]';
    
    module.exports = function bind(that) {
        var target = this;
        if (typeof target !== 'function' || toStr.call(target) !== funcType) {
            throw new TypeError(ERROR_MESSAGE + target);
        }
        var args = slice.call(arguments, 1);
    
        var bound;
        var binder = function () {
            if (this instanceof bound) {
                var result = target.apply(
                    this,
                    args.concat(slice.call(arguments))
                );
                if (Object(result) === result) {
                    return result;
                }
                return this;
            } else {
                return target.apply(
                    that,
                    args.concat(slice.call(arguments))
                );
            }
        };
    
        var boundLength = Math.max(0, target.length - args.length);
        var boundArgs = [];
        for (var i = 0; i < boundLength; i++) {
            boundArgs.push('$' + i);
        }
    
        bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
    
        if (target.prototype) {
            var Empty = function Empty() {};
            Empty.prototype = target.prototype;
            bound.prototype = new Empty();
            Empty.prototype = null;
        }
    
        return bound;
    };
    
    },{}],140:[function(require,module,exports){
    'use strict';
    
    var implementation = require('./implementation');
    
    module.exports = Function.prototype.bind || implementation;
    
    },{"./implementation":139}],141:[function(require,module,exports){
    'use strict';
    
    var undefined;
    
    var $SyntaxError = SyntaxError;
    var $Function = Function;
    var $TypeError = TypeError;
    
    // eslint-disable-next-line consistent-return
    var getEvalledConstructor = function (expressionSyntax) {
        try {
            return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
        } catch (e) {}
    };
    
    var $gOPD = Object.getOwnPropertyDescriptor;
    if ($gOPD) {
        try {
            $gOPD({}, '');
        } catch (e) {
            $gOPD = null; // this is IE 8, which has a broken gOPD
        }
    }
    
    var throwTypeError = function () {
        throw new $TypeError();
    };
    var ThrowTypeError = $gOPD
        ? (function () {
            try {
                // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
                arguments.callee; // IE 8 does not throw here
                return throwTypeError;
            } catch (calleeThrows) {
                try {
                    // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
                    return $gOPD(arguments, 'callee').get;
                } catch (gOPDthrows) {
                    return throwTypeError;
                }
            }
        }())
        : throwTypeError;
    
    var hasSymbols = require('has-symbols')();
    var hasProto = require('has-proto')();
    
    var getProto = Object.getPrototypeOf || (
        hasProto
            ? function (x) { return x.__proto__; } // eslint-disable-line no-proto
            : null
    );
    
    var needsEval = {};
    
    var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);
    
    var INTRINSICS = {
        '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
        '%Array%': Array,
        '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
        '%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
        '%AsyncFromSyncIteratorPrototype%': undefined,
        '%AsyncFunction%': needsEval,
        '%AsyncGenerator%': needsEval,
        '%AsyncGeneratorFunction%': needsEval,
        '%AsyncIteratorPrototype%': needsEval,
        '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
        '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
        '%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
        '%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
        '%Boolean%': Boolean,
        '%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
        '%Date%': Date,
        '%decodeURI%': decodeURI,
        '%decodeURIComponent%': decodeURIComponent,
        '%encodeURI%': encodeURI,
        '%encodeURIComponent%': encodeURIComponent,
        '%Error%': Error,
        '%eval%': eval, // eslint-disable-line no-eval
        '%EvalError%': EvalError,
        '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
        '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
        '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
        '%Function%': $Function,
        '%GeneratorFunction%': needsEval,
        '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
        '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
        '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
        '%isFinite%': isFinite,
        '%isNaN%': isNaN,
        '%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
        '%JSON%': typeof JSON === 'object' ? JSON : undefined,
        '%Map%': typeof Map === 'undefined' ? undefined : Map,
        '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
        '%Math%': Math,
        '%Number%': Number,
        '%Object%': Object,
        '%parseFloat%': parseFloat,
        '%parseInt%': parseInt,
        '%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
        '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
        '%RangeError%': RangeError,
        '%ReferenceError%': ReferenceError,
        '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
        '%RegExp%': RegExp,
        '%Set%': typeof Set === 'undefined' ? undefined : Set,
        '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
        '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
        '%String%': String,
        '%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
        '%Symbol%': hasSymbols ? Symbol : undefined,
        '%SyntaxError%': $SyntaxError,
        '%ThrowTypeError%': ThrowTypeError,
        '%TypedArray%': TypedArray,
        '%TypeError%': $TypeError,
        '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
        '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
        '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
        '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
        '%URIError%': URIError,
        '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
        '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
        '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
    };
    
    if (getProto) {
        try {
            null.error; // eslint-disable-line no-unused-expressions
        } catch (e) {
            // https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
            var errorProto = getProto(getProto(e));
            INTRINSICS['%Error.prototype%'] = errorProto;
        }
    }
    
    var doEval = function doEval(name) {
        var value;
        if (name === '%AsyncFunction%') {
            value = getEvalledConstructor('async function () {}');
        } else if (name === '%GeneratorFunction%') {
            value = getEvalledConstructor('function* () {}');
        } else if (name === '%AsyncGeneratorFunction%') {
            value = getEvalledConstructor('async function* () {}');
        } else if (name === '%AsyncGenerator%') {
            var fn = doEval('%AsyncGeneratorFunction%');
            if (fn) {
                value = fn.prototype;
            }
        } else if (name === '%AsyncIteratorPrototype%') {
            var gen = doEval('%AsyncGenerator%');
            if (gen && getProto) {
                value = getProto(gen.prototype);
            }
        }
    
        INTRINSICS[name] = value;
    
        return value;
    };
    
    var LEGACY_ALIASES = {
        '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
        '%ArrayPrototype%': ['Array', 'prototype'],
        '%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
        '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
        '%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
        '%ArrayProto_values%': ['Array', 'prototype', 'values'],
        '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
        '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
        '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
        '%BooleanPrototype%': ['Boolean', 'prototype'],
        '%DataViewPrototype%': ['DataView', 'prototype'],
        '%DatePrototype%': ['Date', 'prototype'],
        '%ErrorPrototype%': ['Error', 'prototype'],
        '%EvalErrorPrototype%': ['EvalError', 'prototype'],
        '%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
        '%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
        '%FunctionPrototype%': ['Function', 'prototype'],
        '%Generator%': ['GeneratorFunction', 'prototype'],
        '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
        '%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
        '%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
        '%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
        '%JSONParse%': ['JSON', 'parse'],
        '%JSONStringify%': ['JSON', 'stringify'],
        '%MapPrototype%': ['Map', 'prototype'],
        '%NumberPrototype%': ['Number', 'prototype'],
        '%ObjectPrototype%': ['Object', 'prototype'],
        '%ObjProto_toString%': ['Object', 'prototype', 'toString'],
        '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
        '%PromisePrototype%': ['Promise', 'prototype'],
        '%PromiseProto_then%': ['Promise', 'prototype', 'then'],
        '%Promise_all%': ['Promise', 'all'],
        '%Promise_reject%': ['Promise', 'reject'],
        '%Promise_resolve%': ['Promise', 'resolve'],
        '%RangeErrorPrototype%': ['RangeError', 'prototype'],
        '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
        '%RegExpPrototype%': ['RegExp', 'prototype'],
        '%SetPrototype%': ['Set', 'prototype'],
        '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
        '%StringPrototype%': ['String', 'prototype'],
        '%SymbolPrototype%': ['Symbol', 'prototype'],
        '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
        '%TypedArrayPrototype%': ['TypedArray', 'prototype'],
        '%TypeErrorPrototype%': ['TypeError', 'prototype'],
        '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
        '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
        '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
        '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
        '%URIErrorPrototype%': ['URIError', 'prototype'],
        '%WeakMapPrototype%': ['WeakMap', 'prototype'],
        '%WeakSetPrototype%': ['WeakSet', 'prototype']
    };
    
    var bind = require('function-bind');
    var hasOwn = require('has');
    var $concat = bind.call(Function.call, Array.prototype.concat);
    var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
    var $replace = bind.call(Function.call, String.prototype.replace);
    var $strSlice = bind.call(Function.call, String.prototype.slice);
    var $exec = bind.call(Function.call, RegExp.prototype.exec);
    
    /* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
    var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
    var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
    var stringToPath = function stringToPath(string) {
        var first = $strSlice(string, 0, 1);
        var last = $strSlice(string, -1);
        if (first === '%' && last !== '%') {
            throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
        } else if (last === '%' && first !== '%') {
            throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
        }
        var result = [];
        $replace(string, rePropName, function (match, number, quote, subString) {
            result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
        });
        return result;
    };
    /* end adaptation */
    
    var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
        var intrinsicName = name;
        var alias;
        if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
            alias = LEGACY_ALIASES[intrinsicName];
            intrinsicName = '%' + alias[0] + '%';
        }
    
        if (hasOwn(INTRINSICS, intrinsicName)) {
            var value = INTRINSICS[intrinsicName];
            if (value === needsEval) {
                value = doEval(intrinsicName);
            }
            if (typeof value === 'undefined' && !allowMissing) {
                throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
            }
    
            return {
                alias: alias,
                name: intrinsicName,
                value: value
            };
        }
    
        throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
    };
    
    module.exports = function GetIntrinsic(name, allowMissing) {
        if (typeof name !== 'string' || name.length === 0) {
            throw new $TypeError('intrinsic name must be a non-empty string');
        }
        if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
            throw new $TypeError('"allowMissing" argument must be a boolean');
        }
    
        if ($exec(/^%?[^%]*%?$/, name) === null) {
            throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
        }
        var parts = stringToPath(name);
        var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
    
        var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
        var intrinsicRealName = intrinsic.name;
        var value = intrinsic.value;
        var skipFurtherCaching = false;
    
        var alias = intrinsic.alias;
        if (alias) {
            intrinsicBaseName = alias[0];
            $spliceApply(parts, $concat([0, 1], alias));
        }
    
        for (var i = 1, isOwn = true; i < parts.length; i += 1) {
            var part = parts[i];
            var first = $strSlice(part, 0, 1);
            var last = $strSlice(part, -1);
            if (
                (
                    (first === '"' || first === "'" || first === '`')
                    || (last === '"' || last === "'" || last === '`')
                )
                && first !== last
            ) {
                throw new $SyntaxError('property names with quotes must have matching quotes');
            }
            if (part === 'constructor' || !isOwn) {
                skipFurtherCaching = true;
            }
    
            intrinsicBaseName += '.' + part;
            intrinsicRealName = '%' + intrinsicBaseName + '%';
    
            if (hasOwn(INTRINSICS, intrinsicRealName)) {
                value = INTRINSICS[intrinsicRealName];
            } else if (value != null) {
                if (!(part in value)) {
                    if (!allowMissing) {
                        throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
                    }
                    return void undefined;
                }
                if ($gOPD && (i + 1) >= parts.length) {
                    var desc = $gOPD(value, part);
                    isOwn = !!desc;
    
                    // By convention, when a data property is converted to an accessor
                    // property to emulate a data property that does not suffer from
                    // the override mistake, that accessor's getter is marked with
                    // an `originalValue` property. Here, when we detect this, we
                    // uphold the illusion by pretending to see that original data
                    // property, i.e., returning the value rather than the getter
                    // itself.
                    if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
                        value = desc.get;
                    } else {
                        value = value[part];
                    }
                } else {
                    isOwn = hasOwn(value, part);
                    value = value[part];
                }
    
                if (isOwn && !skipFurtherCaching) {
                    INTRINSICS[intrinsicRealName] = value;
                }
            }
        }
        return value;
    };
    
    },{"function-bind":140,"has":150,"has-proto":146,"has-symbols":147}],142:[function(require,module,exports){
    (function (process){(function (){
    exports.setopts = setopts
    exports.ownProp = ownProp
    exports.makeAbs = makeAbs
    exports.finish = finish
    exports.mark = mark
    exports.isIgnored = isIgnored
    exports.childrenIgnored = childrenIgnored
    
    function ownProp (obj, field) {
      return Object.prototype.hasOwnProperty.call(obj, field)
    }
    
    var fs = require("fs")
    var path = require("path")
    var minimatch = require("minimatch")
    var isAbsolute = require("path-is-absolute")
    var Minimatch = minimatch.Minimatch
    
    function alphasort (a, b) {
      return a.localeCompare(b, 'en')
    }
    
    function setupIgnores (self, options) {
      self.ignore = options.ignore || []
    
      if (!Array.isArray(self.ignore))
        self.ignore = [self.ignore]
    
      if (self.ignore.length) {
        self.ignore = self.ignore.map(ignoreMap)
      }
    }
    
    // ignore patterns are always in dot:true mode.
    function ignoreMap (pattern) {
      var gmatcher = null
      if (pattern.slice(-3) === '/**') {
        var gpattern = pattern.replace(/(\/\*\*)+$/, '')
        gmatcher = new Minimatch(gpattern, { dot: true })
      }
    
      return {
        matcher: new Minimatch(pattern, { dot: true }),
        gmatcher: gmatcher
      }
    }
    
    function setopts (self, pattern, options) {
      if (!options)
        options = {}
    
      // base-matching: just use globstar for that.
      if (options.matchBase && -1 === pattern.indexOf("/")) {
        if (options.noglobstar) {
          throw new Error("base matching requires globstar")
        }
        pattern = "**/" + pattern
      }
    
      self.silent = !!options.silent
      self.pattern = pattern
      self.strict = options.strict !== false
      self.realpath = !!options.realpath
      self.realpathCache = options.realpathCache || Object.create(null)
      self.follow = !!options.follow
      self.dot = !!options.dot
      self.mark = !!options.mark
      self.nodir = !!options.nodir
      if (self.nodir)
        self.mark = true
      self.sync = !!options.sync
      self.nounique = !!options.nounique
      self.nonull = !!options.nonull
      self.nosort = !!options.nosort
      self.nocase = !!options.nocase
      self.stat = !!options.stat
      self.noprocess = !!options.noprocess
      self.absolute = !!options.absolute
      self.fs = options.fs || fs
    
      self.maxLength = options.maxLength || Infinity
      self.cache = options.cache || Object.create(null)
      self.statCache = options.statCache || Object.create(null)
      self.symlinks = options.symlinks || Object.create(null)
    
      setupIgnores(self, options)
    
      self.changedCwd = false
      var cwd = process.cwd()
      if (!ownProp(options, "cwd"))
        self.cwd = cwd
      else {
        self.cwd = path.resolve(options.cwd)
        self.changedCwd = self.cwd !== cwd
      }
    
      self.root = options.root || path.resolve(self.cwd, "/")
      self.root = path.resolve(self.root)
      if (process.platform === "win32")
        self.root = self.root.replace(/\\/g, "/")
    
      // TODO: is an absolute `cwd` supposed to be resolved against `root`?
      // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
      self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
      if (process.platform === "win32")
        self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
      self.nomount = !!options.nomount
    
      // disable comments and negation in Minimatch.
      // Note that they are not supported in Glob itself anyway.
      options.nonegate = true
      options.nocomment = true
      // always treat \ in patterns as escapes, not path separators
      options.allowWindowsEscape = false
    
      self.minimatch = new Minimatch(pattern, options)
      self.options = self.minimatch.options
    }
    
    function finish (self) {
      var nou = self.nounique
      var all = nou ? [] : Object.create(null)
    
      for (var i = 0, l = self.matches.length; i < l; i ++) {
        var matches = self.matches[i]
        if (!matches || Object.keys(matches).length === 0) {
          if (self.nonull) {
            // do like the shell, and spit out the literal glob
            var literal = self.minimatch.globSet[i]
            if (nou)
              all.push(literal)
            else
              all[literal] = true
          }
        } else {
          // had matches
          var m = Object.keys(matches)
          if (nou)
            all.push.apply(all, m)
          else
            m.forEach(function (m) {
              all[m] = true
            })
        }
      }
    
      if (!nou)
        all = Object.keys(all)
    
      if (!self.nosort)
        all = all.sort(alphasort)
    
      // at *some* point we statted all of these
      if (self.mark) {
        for (var i = 0; i < all.length; i++) {
          all[i] = self._mark(all[i])
        }
        if (self.nodir) {
          all = all.filter(function (e) {
            var notDir = !(/\/$/.test(e))
            var c = self.cache[e] || self.cache[makeAbs(self, e)]
            if (notDir && c)
              notDir = c !== 'DIR' && !Array.isArray(c)
            return notDir
          })
        }
      }
    
      if (self.ignore.length)
        all = all.filter(function(m) {
          return !isIgnored(self, m)
        })
    
      self.found = all
    }
    
    function mark (self, p) {
      var abs = makeAbs(self, p)
      var c = self.cache[abs]
      var m = p
      if (c) {
        var isDir = c === 'DIR' || Array.isArray(c)
        var slash = p.slice(-1) === '/'
    
        if (isDir && !slash)
          m += '/'
        else if (!isDir && slash)
          m = m.slice(0, -1)
    
        if (m !== p) {
          var mabs = makeAbs(self, m)
          self.statCache[mabs] = self.statCache[abs]
          self.cache[mabs] = self.cache[abs]
        }
      }
    
      return m
    }
    
    // lotta situps...
    function makeAbs (self, f) {
      var abs = f
      if (f.charAt(0) === '/') {
        abs = path.join(self.root, f)
      } else if (isAbsolute(f) || f === '') {
        abs = f
      } else if (self.changedCwd) {
        abs = path.resolve(self.cwd, f)
      } else {
        abs = path.resolve(f)
      }
    
      if (process.platform === 'win32')
        abs = abs.replace(/\\/g, '/')
    
      return abs
    }
    
    
    // Return true, if pattern ends with globstar '**', for the accompanying parent directory.
    // Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
    function isIgnored (self, path) {
      if (!self.ignore.length)
        return false
    
      return self.ignore.some(function(item) {
        return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
      })
    }
    
    function childrenIgnored (self, path) {
      if (!self.ignore.length)
        return false
    
      return self.ignore.some(function(item) {
        return !!(item.gmatcher && item.gmatcher.match(path))
      })
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321,"fs":83,"minimatch":196,"path":313,"path-is-absolute":314}],143:[function(require,module,exports){
    (function (process){(function (){
    // Approach:
    //
    // 1. Get the minimatch set
    // 2. For each pattern in the set, PROCESS(pattern, false)
    // 3. Store matches per-set, then uniq them
    //
    // PROCESS(pattern, inGlobStar)
    // Get the first [n] items from pattern that are all strings
    // Join these together.  This is PREFIX.
    //   If there is no more remaining, then stat(PREFIX) and
    //   add to matches if it succeeds.  END.
    //
    // If inGlobStar and PREFIX is symlink and points to dir
    //   set ENTRIES = []
    // else readdir(PREFIX) as ENTRIES
    //   If fail, END
    //
    // with ENTRIES
    //   If pattern[n] is GLOBSTAR
    //     // handle the case where the globstar match is empty
    //     // by pruning it out, and testing the resulting pattern
    //     PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
    //     // handle other cases.
    //     for ENTRY in ENTRIES (not dotfiles)
    //       // attach globstar + tail onto the entry
    //       // Mark that this entry is a globstar match
    //       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
    //
    //   else // not globstar
    //     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
    //       Test ENTRY against pattern[n]
    //       If fails, continue
    //       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
    //
    // Caveat:
    //   Cache all stats and readdirs results to minimize syscall.  Since all
    //   we ever care about is existence and directory-ness, we can just keep
    //   `true` for files, and [children,...] for directories, or `false` for
    //   things that don't exist.
    
    module.exports = glob
    
    var rp = require('fs.realpath')
    var minimatch = require('minimatch')
    var Minimatch = minimatch.Minimatch
    var inherits = require('inherits')
    var EE = require('events').EventEmitter
    var path = require('path')
    var assert = require('assert')
    var isAbsolute = require('path-is-absolute')
    var globSync = require('./sync.js')
    var common = require('./common.js')
    var setopts = common.setopts
    var ownProp = common.ownProp
    var inflight = require('inflight')
    var util = require('util')
    var childrenIgnored = common.childrenIgnored
    var isIgnored = common.isIgnored
    
    var once = require('once')
    
    function glob (pattern, options, cb) {
      if (typeof options === 'function') cb = options, options = {}
      if (!options) options = {}
    
      if (options.sync) {
        if (cb)
          throw new TypeError('callback provided to sync glob')
        return globSync(pattern, options)
      }
    
      return new Glob(pattern, options, cb)
    }
    
    glob.sync = globSync
    var GlobSync = glob.GlobSync = globSync.GlobSync
    
    // old api surface
    glob.glob = glob
    
    function extend (origin, add) {
      if (add === null || typeof add !== 'object') {
        return origin
      }
    
      var keys = Object.keys(add)
      var i = keys.length
      while (i--) {
        origin[keys[i]] = add[keys[i]]
      }
      return origin
    }
    
    glob.hasMagic = function (pattern, options_) {
      var options = extend({}, options_)
      options.noprocess = true
    
      var g = new Glob(pattern, options)
      var set = g.minimatch.set
    
      if (!pattern)
        return false
    
      if (set.length > 1)
        return true
    
      for (var j = 0; j < set[0].length; j++) {
        if (typeof set[0][j] !== 'string')
          return true
      }
    
      return false
    }
    
    glob.Glob = Glob
    inherits(Glob, EE)
    function Glob (pattern, options, cb) {
      if (typeof options === 'function') {
        cb = options
        options = null
      }
    
      if (options && options.sync) {
        if (cb)
          throw new TypeError('callback provided to sync glob')
        return new GlobSync(pattern, options)
      }
    
      if (!(this instanceof Glob))
        return new Glob(pattern, options, cb)
    
      setopts(this, pattern, options)
      this._didRealPath = false
    
      // process each pattern in the minimatch set
      var n = this.minimatch.set.length
    
      // The matches are stored as {<filename>: true,...} so that
      // duplicates are automagically pruned.
      // Later, we do an Object.keys() on these.
      // Keep them as a list so we can fill in when nonull is set.
      this.matches = new Array(n)
    
      if (typeof cb === 'function') {
        cb = once(cb)
        this.on('error', cb)
        this.on('end', function (matches) {
          cb(null, matches)
        })
      }
    
      var self = this
      this._processing = 0
    
      this._emitQueue = []
      this._processQueue = []
      this.paused = false
    
      if (this.noprocess)
        return this
    
      if (n === 0)
        return done()
    
      var sync = true
      for (var i = 0; i < n; i ++) {
        this._process(this.minimatch.set[i], i, false, done)
      }
      sync = false
    
      function done () {
        --self._processing
        if (self._processing <= 0) {
          if (sync) {
            process.nextTick(function () {
              self._finish()
            })
          } else {
            self._finish()
          }
        }
      }
    }
    
    Glob.prototype._finish = function () {
      assert(this instanceof Glob)
      if (this.aborted)
        return
    
      if (this.realpath && !this._didRealpath)
        return this._realpath()
    
      common.finish(this)
      this.emit('end', this.found)
    }
    
    Glob.prototype._realpath = function () {
      if (this._didRealpath)
        return
    
      this._didRealpath = true
    
      var n = this.matches.length
      if (n === 0)
        return this._finish()
    
      var self = this
      for (var i = 0; i < this.matches.length; i++)
        this._realpathSet(i, next)
    
      function next () {
        if (--n === 0)
          self._finish()
      }
    }
    
    Glob.prototype._realpathSet = function (index, cb) {
      var matchset = this.matches[index]
      if (!matchset)
        return cb()
    
      var found = Object.keys(matchset)
      var self = this
      var n = found.length
    
      if (n === 0)
        return cb()
    
      var set = this.matches[index] = Object.create(null)
      found.forEach(function (p, i) {
        // If there's a problem with the stat, then it means that
        // one or more of the links in the realpath couldn't be
        // resolved.  just return the abs value in that case.
        p = self._makeAbs(p)
        rp.realpath(p, self.realpathCache, function (er, real) {
          if (!er)
            set[real] = true
          else if (er.syscall === 'stat')
            set[p] = true
          else
            self.emit('error', er) // srsly wtf right here
    
          if (--n === 0) {
            self.matches[index] = set
            cb()
          }
        })
      })
    }
    
    Glob.prototype._mark = function (p) {
      return common.mark(this, p)
    }
    
    Glob.prototype._makeAbs = function (f) {
      return common.makeAbs(this, f)
    }
    
    Glob.prototype.abort = function () {
      this.aborted = true
      this.emit('abort')
    }
    
    Glob.prototype.pause = function () {
      if (!this.paused) {
        this.paused = true
        this.emit('pause')
      }
    }
    
    Glob.prototype.resume = function () {
      if (this.paused) {
        this.emit('resume')
        this.paused = false
        if (this._emitQueue.length) {
          var eq = this._emitQueue.slice(0)
          this._emitQueue.length = 0
          for (var i = 0; i < eq.length; i ++) {
            var e = eq[i]
            this._emitMatch(e[0], e[1])
          }
        }
        if (this._processQueue.length) {
          var pq = this._processQueue.slice(0)
          this._processQueue.length = 0
          for (var i = 0; i < pq.length; i ++) {
            var p = pq[i]
            this._processing--
            this._process(p[0], p[1], p[2], p[3])
          }
        }
      }
    }
    
    Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
      assert(this instanceof Glob)
      assert(typeof cb === 'function')
    
      if (this.aborted)
        return
    
      this._processing++
      if (this.paused) {
        this._processQueue.push([pattern, index, inGlobStar, cb])
        return
      }
    
      //console.error('PROCESS %d', this._processing, pattern)
    
      // Get the first [n] parts of pattern that are all strings.
      var n = 0
      while (typeof pattern[n] === 'string') {
        n ++
      }
      // now n is the index of the first one that is *not* a string.
    
      // see if there's anything else
      var prefix
      switch (n) {
        // if not, then this is rather simple
        case pattern.length:
          this._processSimple(pattern.join('/'), index, cb)
          return
    
        case 0:
          // pattern *starts* with some non-trivial item.
          // going to readdir(cwd), but not include the prefix in matches.
          prefix = null
          break
    
        default:
          // pattern has some string bits in the front.
          // whatever it starts with, whether that's 'absolute' like /foo/bar,
          // or 'relative' like '../baz'
          prefix = pattern.slice(0, n).join('/')
          break
      }
    
      var remain = pattern.slice(n)
    
      // get the list of entries.
      var read
      if (prefix === null)
        read = '.'
      else if (isAbsolute(prefix) ||
          isAbsolute(pattern.map(function (p) {
            return typeof p === 'string' ? p : '[*]'
          }).join('/'))) {
        if (!prefix || !isAbsolute(prefix))
          prefix = '/' + prefix
        read = prefix
      } else
        read = prefix
    
      var abs = this._makeAbs(read)
    
      //if ignored, skip _processing
      if (childrenIgnored(this, read))
        return cb()
    
      var isGlobStar = remain[0] === minimatch.GLOBSTAR
      if (isGlobStar)
        this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)
      else
        this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)
    }
    
    Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
      var self = this
      this._readdir(abs, inGlobStar, function (er, entries) {
        return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
      })
    }
    
    Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
    
      // if the abs isn't a dir, then nothing can match!
      if (!entries)
        return cb()
    
      // It will only match dot entries if it starts with a dot, or if
      // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
      var pn = remain[0]
      var negate = !!this.minimatch.negate
      var rawGlob = pn._glob
      var dotOk = this.dot || rawGlob.charAt(0) === '.'
    
      var matchedEntries = []
      for (var i = 0; i < entries.length; i++) {
        var e = entries[i]
        if (e.charAt(0) !== '.' || dotOk) {
          var m
          if (negate && !prefix) {
            m = !e.match(pn)
          } else {
            m = e.match(pn)
          }
          if (m)
            matchedEntries.push(e)
        }
      }
    
      //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
    
      var len = matchedEntries.length
      // If there are no matched entries, then nothing matches.
      if (len === 0)
        return cb()
    
      // if this is the last remaining pattern bit, then no need for
      // an additional stat *unless* the user has specified mark or
      // stat explicitly.  We know they exist, since readdir returned
      // them.
    
      if (remain.length === 1 && !this.mark && !this.stat) {
        if (!this.matches[index])
          this.matches[index] = Object.create(null)
    
        for (var i = 0; i < len; i ++) {
          var e = matchedEntries[i]
          if (prefix) {
            if (prefix !== '/')
              e = prefix + '/' + e
            else
              e = prefix + e
          }
    
          if (e.charAt(0) === '/' && !this.nomount) {
            e = path.join(this.root, e)
          }
          this._emitMatch(index, e)
        }
        // This was the last one, and no stats were needed
        return cb()
      }
    
      // now test all matched entries as stand-ins for that part
      // of the pattern.
      remain.shift()
      for (var i = 0; i < len; i ++) {
        var e = matchedEntries[i]
        var newPattern
        if (prefix) {
          if (prefix !== '/')
            e = prefix + '/' + e
          else
            e = prefix + e
        }
        this._process([e].concat(remain), index, inGlobStar, cb)
      }
      cb()
    }
    
    Glob.prototype._emitMatch = function (index, e) {
      if (this.aborted)
        return
    
      if (isIgnored(this, e))
        return
    
      if (this.paused) {
        this._emitQueue.push([index, e])
        return
      }
    
      var abs = isAbsolute(e) ? e : this._makeAbs(e)
    
      if (this.mark)
        e = this._mark(e)
    
      if (this.absolute)
        e = abs
    
      if (this.matches[index][e])
        return
    
      if (this.nodir) {
        var c = this.cache[abs]
        if (c === 'DIR' || Array.isArray(c))
          return
      }
    
      this.matches[index][e] = true
    
      var st = this.statCache[abs]
      if (st)
        this.emit('stat', e, st)
    
      this.emit('match', e)
    }
    
    Glob.prototype._readdirInGlobStar = function (abs, cb) {
      if (this.aborted)
        return
    
      // follow all symlinked directories forever
      // just proceed as if this is a non-globstar situation
      if (this.follow)
        return this._readdir(abs, false, cb)
    
      var lstatkey = 'lstat\0' + abs
      var self = this
      var lstatcb = inflight(lstatkey, lstatcb_)
    
      if (lstatcb)
        self.fs.lstat(abs, lstatcb)
    
      function lstatcb_ (er, lstat) {
        if (er && er.code === 'ENOENT')
          return cb()
    
        var isSym = lstat && lstat.isSymbolicLink()
        self.symlinks[abs] = isSym
    
        // If it's not a symlink or a dir, then it's definitely a regular file.
        // don't bother doing a readdir in that case.
        if (!isSym && lstat && !lstat.isDirectory()) {
          self.cache[abs] = 'FILE'
          cb()
        } else
          self._readdir(abs, false, cb)
      }
    }
    
    Glob.prototype._readdir = function (abs, inGlobStar, cb) {
      if (this.aborted)
        return
    
      cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb)
      if (!cb)
        return
    
      //console.error('RD %j %j', +inGlobStar, abs)
      if (inGlobStar && !ownProp(this.symlinks, abs))
        return this._readdirInGlobStar(abs, cb)
    
      if (ownProp(this.cache, abs)) {
        var c = this.cache[abs]
        if (!c || c === 'FILE')
          return cb()
    
        if (Array.isArray(c))
          return cb(null, c)
      }
    
      var self = this
      self.fs.readdir(abs, readdirCb(this, abs, cb))
    }
    
    function readdirCb (self, abs, cb) {
      return function (er, entries) {
        if (er)
          self._readdirError(abs, er, cb)
        else
          self._readdirEntries(abs, entries, cb)
      }
    }
    
    Glob.prototype._readdirEntries = function (abs, entries, cb) {
      if (this.aborted)
        return
    
      // if we haven't asked to stat everything, then just
      // assume that everything in there exists, so we can avoid
      // having to stat it a second time.
      if (!this.mark && !this.stat) {
        for (var i = 0; i < entries.length; i ++) {
          var e = entries[i]
          if (abs === '/')
            e = abs + e
          else
            e = abs + '/' + e
          this.cache[e] = true
        }
      }
    
      this.cache[abs] = entries
      return cb(null, entries)
    }
    
    Glob.prototype._readdirError = function (f, er, cb) {
      if (this.aborted)
        return
    
      // handle errors, and cache the information
      switch (er.code) {
        case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
        case 'ENOTDIR': // totally normal. means it *does* exist.
          var abs = this._makeAbs(f)
          this.cache[abs] = 'FILE'
          if (abs === this.cwdAbs) {
            var error = new Error(er.code + ' invalid cwd ' + this.cwd)
            error.path = this.cwd
            error.code = er.code
            this.emit('error', error)
            this.abort()
          }
          break
    
        case 'ENOENT': // not terribly unusual
        case 'ELOOP':
        case 'ENAMETOOLONG':
        case 'UNKNOWN':
          this.cache[this._makeAbs(f)] = false
          break
    
        default: // some unusual error.  Treat as failure.
          this.cache[this._makeAbs(f)] = false
          if (this.strict) {
            this.emit('error', er)
            // If the error is handled, then we abort
            // if not, we threw out of here
            this.abort()
          }
          if (!this.silent)
            console.error('glob error', er)
          break
      }
    
      return cb()
    }
    
    Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
      var self = this
      this._readdir(abs, inGlobStar, function (er, entries) {
        self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
      })
    }
    
    
    Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
      //console.error('pgs2', prefix, remain[0], entries)
    
      // no entries means not a dir, so it can never have matches
      // foo.txt/** doesn't match foo.txt
      if (!entries)
        return cb()
    
      // test without the globstar, and with every child both below
      // and replacing the globstar.
      var remainWithoutGlobStar = remain.slice(1)
      var gspref = prefix ? [ prefix ] : []
      var noGlobStar = gspref.concat(remainWithoutGlobStar)
    
      // the noGlobStar pattern exits the inGlobStar state
      this._process(noGlobStar, index, false, cb)
    
      var isSym = this.symlinks[abs]
      var len = entries.length
    
      // If it's a symlink, and we're in a globstar, then stop
      if (isSym && inGlobStar)
        return cb()
    
      for (var i = 0; i < len; i++) {
        var e = entries[i]
        if (e.charAt(0) === '.' && !this.dot)
          continue
    
        // these two cases enter the inGlobStar state
        var instead = gspref.concat(entries[i], remainWithoutGlobStar)
        this._process(instead, index, true, cb)
    
        var below = gspref.concat(entries[i], remain)
        this._process(below, index, true, cb)
      }
    
      cb()
    }
    
    Glob.prototype._processSimple = function (prefix, index, cb) {
      // XXX review this.  Shouldn't it be doing the mounting etc
      // before doing stat?  kinda weird?
      var self = this
      this._stat(prefix, function (er, exists) {
        self._processSimple2(prefix, index, er, exists, cb)
      })
    }
    Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {
    
      //console.error('ps2', prefix, exists)
    
      if (!this.matches[index])
        this.matches[index] = Object.create(null)
    
      // If it doesn't exist, then just mark the lack of results
      if (!exists)
        return cb()
    
      if (prefix && isAbsolute(prefix) && !this.nomount) {
        var trail = /[\/\\]$/.test(prefix)
        if (prefix.charAt(0) === '/') {
          prefix = path.join(this.root, prefix)
        } else {
          prefix = path.resolve(this.root, prefix)
          if (trail)
            prefix += '/'
        }
      }
    
      if (process.platform === 'win32')
        prefix = prefix.replace(/\\/g, '/')
    
      // Mark this as a match
      this._emitMatch(index, prefix)
      cb()
    }
    
    // Returns either 'DIR', 'FILE', or false
    Glob.prototype._stat = function (f, cb) {
      var abs = this._makeAbs(f)
      var needDir = f.slice(-1) === '/'
    
      if (f.length > this.maxLength)
        return cb()
    
      if (!this.stat && ownProp(this.cache, abs)) {
        var c = this.cache[abs]
    
        if (Array.isArray(c))
          c = 'DIR'
    
        // It exists, but maybe not how we need it
        if (!needDir || c === 'DIR')
          return cb(null, c)
    
        if (needDir && c === 'FILE')
          return cb()
    
        // otherwise we have to stat, because maybe c=true
        // if we know it exists, but not what it is.
      }
    
      var exists
      var stat = this.statCache[abs]
      if (stat !== undefined) {
        if (stat === false)
          return cb(null, stat)
        else {
          var type = stat.isDirectory() ? 'DIR' : 'FILE'
          if (needDir && type === 'FILE')
            return cb()
          else
            return cb(null, type, stat)
        }
      }
    
      var self = this
      var statcb = inflight('stat\0' + abs, lstatcb_)
      if (statcb)
        self.fs.lstat(abs, statcb)
    
      function lstatcb_ (er, lstat) {
        if (lstat && lstat.isSymbolicLink()) {
          // If it's a symlink, then treat it as the target, unless
          // the target does not exist, then treat it as a file.
          return self.fs.stat(abs, function (er, stat) {
            if (er)
              self._stat2(f, abs, null, lstat, cb)
            else
              self._stat2(f, abs, er, stat, cb)
          })
        } else {
          self._stat2(f, abs, er, lstat, cb)
        }
      }
    }
    
    Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
      if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
        this.statCache[abs] = false
        return cb()
      }
    
      var needDir = f.slice(-1) === '/'
      this.statCache[abs] = stat
    
      if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
        return cb(null, false, stat)
    
      var c = true
      if (stat)
        c = stat.isDirectory() ? 'DIR' : 'FILE'
      this.cache[abs] = this.cache[abs] || c
    
      if (needDir && c === 'FILE')
        return cb()
    
      return cb(null, c, stat)
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./common.js":142,"./sync.js":144,"_process":321,"assert":24,"events":134,"fs.realpath":137,"inflight":181,"inherits":182,"minimatch":196,"once":295,"path":313,"path-is-absolute":314,"util":372}],144:[function(require,module,exports){
    (function (process){(function (){
    module.exports = globSync
    globSync.GlobSync = GlobSync
    
    var rp = require('fs.realpath')
    var minimatch = require('minimatch')
    var Minimatch = minimatch.Minimatch
    var Glob = require('./glob.js').Glob
    var util = require('util')
    var path = require('path')
    var assert = require('assert')
    var isAbsolute = require('path-is-absolute')
    var common = require('./common.js')
    var setopts = common.setopts
    var ownProp = common.ownProp
    var childrenIgnored = common.childrenIgnored
    var isIgnored = common.isIgnored
    
    function globSync (pattern, options) {
      if (typeof options === 'function' || arguments.length === 3)
        throw new TypeError('callback provided to sync glob\n'+
                            'See: https://github.com/isaacs/node-glob/issues/167')
    
      return new GlobSync(pattern, options).found
    }
    
    function GlobSync (pattern, options) {
      if (!pattern)
        throw new Error('must provide pattern')
    
      if (typeof options === 'function' || arguments.length === 3)
        throw new TypeError('callback provided to sync glob\n'+
                            'See: https://github.com/isaacs/node-glob/issues/167')
    
      if (!(this instanceof GlobSync))
        return new GlobSync(pattern, options)
    
      setopts(this, pattern, options)
    
      if (this.noprocess)
        return this
    
      var n = this.minimatch.set.length
      this.matches = new Array(n)
      for (var i = 0; i < n; i ++) {
        this._process(this.minimatch.set[i], i, false)
      }
      this._finish()
    }
    
    GlobSync.prototype._finish = function () {
      assert.ok(this instanceof GlobSync)
      if (this.realpath) {
        var self = this
        this.matches.forEach(function (matchset, index) {
          var set = self.matches[index] = Object.create(null)
          for (var p in matchset) {
            try {
              p = self._makeAbs(p)
              var real = rp.realpathSync(p, self.realpathCache)
              set[real] = true
            } catch (er) {
              if (er.syscall === 'stat')
                set[self._makeAbs(p)] = true
              else
                throw er
            }
          }
        })
      }
      common.finish(this)
    }
    
    
    GlobSync.prototype._process = function (pattern, index, inGlobStar) {
      assert.ok(this instanceof GlobSync)
    
      // Get the first [n] parts of pattern that are all strings.
      var n = 0
      while (typeof pattern[n] === 'string') {
        n ++
      }
      // now n is the index of the first one that is *not* a string.
    
      // See if there's anything else
      var prefix
      switch (n) {
        // if not, then this is rather simple
        case pattern.length:
          this._processSimple(pattern.join('/'), index)
          return
    
        case 0:
          // pattern *starts* with some non-trivial item.
          // going to readdir(cwd), but not include the prefix in matches.
          prefix = null
          break
    
        default:
          // pattern has some string bits in the front.
          // whatever it starts with, whether that's 'absolute' like /foo/bar,
          // or 'relative' like '../baz'
          prefix = pattern.slice(0, n).join('/')
          break
      }
    
      var remain = pattern.slice(n)
    
      // get the list of entries.
      var read
      if (prefix === null)
        read = '.'
      else if (isAbsolute(prefix) ||
          isAbsolute(pattern.map(function (p) {
            return typeof p === 'string' ? p : '[*]'
          }).join('/'))) {
        if (!prefix || !isAbsolute(prefix))
          prefix = '/' + prefix
        read = prefix
      } else
        read = prefix
    
      var abs = this._makeAbs(read)
    
      //if ignored, skip processing
      if (childrenIgnored(this, read))
        return
    
      var isGlobStar = remain[0] === minimatch.GLOBSTAR
      if (isGlobStar)
        this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
      else
        this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
    }
    
    
    GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
      var entries = this._readdir(abs, inGlobStar)
    
      // if the abs isn't a dir, then nothing can match!
      if (!entries)
        return
    
      // It will only match dot entries if it starts with a dot, or if
      // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
      var pn = remain[0]
      var negate = !!this.minimatch.negate
      var rawGlob = pn._glob
      var dotOk = this.dot || rawGlob.charAt(0) === '.'
    
      var matchedEntries = []
      for (var i = 0; i < entries.length; i++) {
        var e = entries[i]
        if (e.charAt(0) !== '.' || dotOk) {
          var m
          if (negate && !prefix) {
            m = !e.match(pn)
          } else {
            m = e.match(pn)
          }
          if (m)
            matchedEntries.push(e)
        }
      }
    
      var len = matchedEntries.length
      // If there are no matched entries, then nothing matches.
      if (len === 0)
        return
    
      // if this is the last remaining pattern bit, then no need for
      // an additional stat *unless* the user has specified mark or
      // stat explicitly.  We know they exist, since readdir returned
      // them.
    
      if (remain.length === 1 && !this.mark && !this.stat) {
        if (!this.matches[index])
          this.matches[index] = Object.create(null)
    
        for (var i = 0; i < len; i ++) {
          var e = matchedEntries[i]
          if (prefix) {
            if (prefix.slice(-1) !== '/')
              e = prefix + '/' + e
            else
              e = prefix + e
          }
    
          if (e.charAt(0) === '/' && !this.nomount) {
            e = path.join(this.root, e)
          }
          this._emitMatch(index, e)
        }
        // This was the last one, and no stats were needed
        return
      }
    
      // now test all matched entries as stand-ins for that part
      // of the pattern.
      remain.shift()
      for (var i = 0; i < len; i ++) {
        var e = matchedEntries[i]
        var newPattern
        if (prefix)
          newPattern = [prefix, e]
        else
          newPattern = [e]
        this._process(newPattern.concat(remain), index, inGlobStar)
      }
    }
    
    
    GlobSync.prototype._emitMatch = function (index, e) {
      if (isIgnored(this, e))
        return
    
      var abs = this._makeAbs(e)
    
      if (this.mark)
        e = this._mark(e)
    
      if (this.absolute) {
        e = abs
      }
    
      if (this.matches[index][e])
        return
    
      if (this.nodir) {
        var c = this.cache[abs]
        if (c === 'DIR' || Array.isArray(c))
          return
      }
    
      this.matches[index][e] = true
    
      if (this.stat)
        this._stat(e)
    }
    
    
    GlobSync.prototype._readdirInGlobStar = function (abs) {
      // follow all symlinked directories forever
      // just proceed as if this is a non-globstar situation
      if (this.follow)
        return this._readdir(abs, false)
    
      var entries
      var lstat
      var stat
      try {
        lstat = this.fs.lstatSync(abs)
      } catch (er) {
        if (er.code === 'ENOENT') {
          // lstat failed, doesn't exist
          return null
        }
      }
    
      var isSym = lstat && lstat.isSymbolicLink()
      this.symlinks[abs] = isSym
    
      // If it's not a symlink or a dir, then it's definitely a regular file.
      // don't bother doing a readdir in that case.
      if (!isSym && lstat && !lstat.isDirectory())
        this.cache[abs] = 'FILE'
      else
        entries = this._readdir(abs, false)
    
      return entries
    }
    
    GlobSync.prototype._readdir = function (abs, inGlobStar) {
      var entries
    
      if (inGlobStar && !ownProp(this.symlinks, abs))
        return this._readdirInGlobStar(abs)
    
      if (ownProp(this.cache, abs)) {
        var c = this.cache[abs]
        if (!c || c === 'FILE')
          return null
    
        if (Array.isArray(c))
          return c
      }
    
      try {
        return this._readdirEntries(abs, this.fs.readdirSync(abs))
      } catch (er) {
        this._readdirError(abs, er)
        return null
      }
    }
    
    GlobSync.prototype._readdirEntries = function (abs, entries) {
      // if we haven't asked to stat everything, then just
      // assume that everything in there exists, so we can avoid
      // having to stat it a second time.
      if (!this.mark && !this.stat) {
        for (var i = 0; i < entries.length; i ++) {
          var e = entries[i]
          if (abs === '/')
            e = abs + e
          else
            e = abs + '/' + e
          this.cache[e] = true
        }
      }
    
      this.cache[abs] = entries
    
      // mark and cache dir-ness
      return entries
    }
    
    GlobSync.prototype._readdirError = function (f, er) {
      // handle errors, and cache the information
      switch (er.code) {
        case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
        case 'ENOTDIR': // totally normal. means it *does* exist.
          var abs = this._makeAbs(f)
          this.cache[abs] = 'FILE'
          if (abs === this.cwdAbs) {
            var error = new Error(er.code + ' invalid cwd ' + this.cwd)
            error.path = this.cwd
            error.code = er.code
            throw error
          }
          break
    
        case 'ENOENT': // not terribly unusual
        case 'ELOOP':
        case 'ENAMETOOLONG':
        case 'UNKNOWN':
          this.cache[this._makeAbs(f)] = false
          break
    
        default: // some unusual error.  Treat as failure.
          this.cache[this._makeAbs(f)] = false
          if (this.strict)
            throw er
          if (!this.silent)
            console.error('glob error', er)
          break
      }
    }
    
    GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
    
      var entries = this._readdir(abs, inGlobStar)
    
      // no entries means not a dir, so it can never have matches
      // foo.txt/** doesn't match foo.txt
      if (!entries)
        return
    
      // test without the globstar, and with every child both below
      // and replacing the globstar.
      var remainWithoutGlobStar = remain.slice(1)
      var gspref = prefix ? [ prefix ] : []
      var noGlobStar = gspref.concat(remainWithoutGlobStar)
    
      // the noGlobStar pattern exits the inGlobStar state
      this._process(noGlobStar, index, false)
    
      var len = entries.length
      var isSym = this.symlinks[abs]
    
      // If it's a symlink, and we're in a globstar, then stop
      if (isSym && inGlobStar)
        return
    
      for (var i = 0; i < len; i++) {
        var e = entries[i]
        if (e.charAt(0) === '.' && !this.dot)
          continue
    
        // these two cases enter the inGlobStar state
        var instead = gspref.concat(entries[i], remainWithoutGlobStar)
        this._process(instead, index, true)
    
        var below = gspref.concat(entries[i], remain)
        this._process(below, index, true)
      }
    }
    
    GlobSync.prototype._processSimple = function (prefix, index) {
      // XXX review this.  Shouldn't it be doing the mounting etc
      // before doing stat?  kinda weird?
      var exists = this._stat(prefix)
    
      if (!this.matches[index])
        this.matches[index] = Object.create(null)
    
      // If it doesn't exist, then just mark the lack of results
      if (!exists)
        return
    
      if (prefix && isAbsolute(prefix) && !this.nomount) {
        var trail = /[\/\\]$/.test(prefix)
        if (prefix.charAt(0) === '/') {
          prefix = path.join(this.root, prefix)
        } else {
          prefix = path.resolve(this.root, prefix)
          if (trail)
            prefix += '/'
        }
      }
    
      if (process.platform === 'win32')
        prefix = prefix.replace(/\\/g, '/')
    
      // Mark this as a match
      this._emitMatch(index, prefix)
    }
    
    // Returns either 'DIR', 'FILE', or false
    GlobSync.prototype._stat = function (f) {
      var abs = this._makeAbs(f)
      var needDir = f.slice(-1) === '/'
    
      if (f.length > this.maxLength)
        return false
    
      if (!this.stat && ownProp(this.cache, abs)) {
        var c = this.cache[abs]
    
        if (Array.isArray(c))
          c = 'DIR'
    
        // It exists, but maybe not how we need it
        if (!needDir || c === 'DIR')
          return c
    
        if (needDir && c === 'FILE')
          return false
    
        // otherwise we have to stat, because maybe c=true
        // if we know it exists, but not what it is.
      }
    
      var exists
      var stat = this.statCache[abs]
      if (!stat) {
        var lstat
        try {
          lstat = this.fs.lstatSync(abs)
        } catch (er) {
          if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
            this.statCache[abs] = false
            return false
          }
        }
    
        if (lstat && lstat.isSymbolicLink()) {
          try {
            stat = this.fs.statSync(abs)
          } catch (er) {
            stat = lstat
          }
        } else {
          stat = lstat
        }
      }
    
      this.statCache[abs] = stat
    
      var c = true
      if (stat)
        c = stat.isDirectory() ? 'DIR' : 'FILE'
    
      this.cache[abs] = this.cache[abs] || c
    
      if (needDir && c === 'FILE')
        return false
    
      return c
    }
    
    GlobSync.prototype._mark = function (p) {
      return common.mark(this, p)
    }
    
    GlobSync.prototype._makeAbs = function (f) {
      return common.makeAbs(this, f)
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./common.js":142,"./glob.js":143,"_process":321,"assert":24,"fs.realpath":137,"minimatch":196,"path":313,"path-is-absolute":314,"util":372}],145:[function(require,module,exports){
    'use strict';
    
    var GetIntrinsic = require('get-intrinsic');
    
    var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
    
    if ($gOPD) {
        try {
            $gOPD([], 'length');
        } catch (e) {
            // IE 8 has a broken gOPD
            $gOPD = null;
        }
    }
    
    module.exports = $gOPD;
    
    },{"get-intrinsic":141}],146:[function(require,module,exports){
    'use strict';
    
    var test = {
        foo: {}
    };
    
    var $Object = Object;
    
    module.exports = function hasProto() {
        return { __proto__: test }.foo === test.foo && !({ __proto__: null } instanceof $Object);
    };
    
    },{}],147:[function(require,module,exports){
    'use strict';
    
    var origSymbol = typeof Symbol !== 'undefined' && Symbol;
    var hasSymbolSham = require('./shams');
    
    module.exports = function hasNativeSymbols() {
        if (typeof origSymbol !== 'function') { return false; }
        if (typeof Symbol !== 'function') { return false; }
        if (typeof origSymbol('foo') !== 'symbol') { return false; }
        if (typeof Symbol('bar') !== 'symbol') { return false; }
    
        return hasSymbolSham();
    };
    
    },{"./shams":148}],148:[function(require,module,exports){
    'use strict';
    
    /* eslint complexity: [2, 18], max-statements: [2, 33] */
    module.exports = function hasSymbols() {
        if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
        if (typeof Symbol.iterator === 'symbol') { return true; }
    
        var obj = {};
        var sym = Symbol('test');
        var symObj = Object(sym);
        if (typeof sym === 'string') { return false; }
    
        if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }
        if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }
    
        // temp disabled per https://github.com/ljharb/object.assign/issues/17
        // if (sym instanceof Symbol) { return false; }
        // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
        // if (!(symObj instanceof Symbol)) { return false; }
    
        // if (typeof Symbol.prototype.toString !== 'function') { return false; }
        // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }
    
        var symVal = 42;
        obj[sym] = symVal;
        for (sym in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
        if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
    
        if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
    
        var syms = Object.getOwnPropertySymbols(obj);
        if (syms.length !== 1 || syms[0] !== sym) { return false; }
    
        if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
    
        if (typeof Object.getOwnPropertyDescriptor === 'function') {
            var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
            if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
        }
    
        return true;
    };
    
    },{}],149:[function(require,module,exports){
    'use strict';
    
    var hasSymbols = require('has-symbols/shams');
    
    module.exports = function hasToStringTagShams() {
        return hasSymbols() && !!Symbol.toStringTag;
    };
    
    },{"has-symbols/shams":148}],150:[function(require,module,exports){
    'use strict';
    
    var hasOwnProperty = {}.hasOwnProperty;
    var call = Function.prototype.call;
    
    module.exports = call.bind ? call.bind(hasOwnProperty) : function (O, P) {
      return call.call(hasOwnProperty, O, P);
    };
    
    },{}],151:[function(require,module,exports){
    'use strict'
    var Buffer = require('safe-buffer').Buffer
    var Transform = require('readable-stream').Transform
    var inherits = require('inherits')
    
    function throwIfNotStringOrBuffer (val, prefix) {
      if (!Buffer.isBuffer(val) && typeof val !== 'string') {
        throw new TypeError(prefix + ' must be a string or a buffer')
      }
    }
    
    function HashBase (blockSize) {
      Transform.call(this)
    
      this._block = Buffer.allocUnsafe(blockSize)
      this._blockSize = blockSize
      this._blockOffset = 0
      this._length = [0, 0, 0, 0]
    
      this._finalized = false
    }
    
    inherits(HashBase, Transform)
    
    HashBase.prototype._transform = function (chunk, encoding, callback) {
      var error = null
      try {
        this.update(chunk, encoding)
      } catch (err) {
        error = err
      }
    
      callback(error)
    }
    
    HashBase.prototype._flush = function (callback) {
      var error = null
      try {
        this.push(this.digest())
      } catch (err) {
        error = err
      }
    
      callback(error)
    }
    
    HashBase.prototype.update = function (data, encoding) {
      throwIfNotStringOrBuffer(data, 'Data')
      if (this._finalized) throw new Error('Digest already called')
      if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding)
    
      // consume data
      var block = this._block
      var offset = 0
      while (this._blockOffset + data.length - offset >= this._blockSize) {
        for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++]
        this._update()
        this._blockOffset = 0
      }
      while (offset < data.length) block[this._blockOffset++] = data[offset++]
    
      // update length
      for (var j = 0, carry = data.length * 8; carry > 0; ++j) {
        this._length[j] += carry
        carry = (this._length[j] / 0x0100000000) | 0
        if (carry > 0) this._length[j] -= 0x0100000000 * carry
      }
    
      return this
    }
    
    HashBase.prototype._update = function () {
      throw new Error('_update is not implemented')
    }
    
    HashBase.prototype.digest = function (encoding) {
      if (this._finalized) throw new Error('Digest already called')
      this._finalized = true
    
      var digest = this._digest()
      if (encoding !== undefined) digest = digest.toString(encoding)
    
      // reset state
      this._block.fill(0)
      this._blockOffset = 0
      for (var i = 0; i < 4; ++i) this._length[i] = 0
    
      return digest
    }
    
    HashBase.prototype._digest = function () {
      throw new Error('_digest is not implemented')
    }
    
    module.exports = HashBase
    
    },{"inherits":182,"readable-stream":166,"safe-buffer":338}],152:[function(require,module,exports){
    arguments[4][66][0].apply(exports,arguments)
    },{"dup":66}],153:[function(require,module,exports){
    (function (process){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // a duplex stream is just a stream that is both readable and writable.
    // Since JS doesn't have multiple prototypal inheritance, this class
    // prototypally inherits from Readable, and then parasitically from
    // Writable.
    
    'use strict';
    
    /*<replacement>*/
    var objectKeys = Object.keys || function (obj) {
      var keys = [];
      for (var key in obj) keys.push(key);
      return keys;
    };
    /*</replacement>*/
    
    module.exports = Duplex;
    var Readable = require('./_stream_readable');
    var Writable = require('./_stream_writable');
    require('inherits')(Duplex, Readable);
    {
      // Allow the keys array to be GC'ed.
      var keys = objectKeys(Writable.prototype);
      for (var v = 0; v < keys.length; v++) {
        var method = keys[v];
        if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
      }
    }
    function Duplex(options) {
      if (!(this instanceof Duplex)) return new Duplex(options);
      Readable.call(this, options);
      Writable.call(this, options);
      this.allowHalfOpen = true;
      if (options) {
        if (options.readable === false) this.readable = false;
        if (options.writable === false) this.writable = false;
        if (options.allowHalfOpen === false) {
          this.allowHalfOpen = false;
          this.once('end', onend);
        }
      }
    }
    Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    
    // the no-half-open enforcer
    function onend() {
      // If the writable side ended, then we're ok.
      if (this._writableState.ended) return;
    
      // no more data can be written.
      // But allow more writes to happen in this tick.
      process.nextTick(onEndNT, this);
    }
    function onEndNT(self) {
      self.end();
    }
    Object.defineProperty(Duplex.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined || this._writableState === undefined) {
          return false;
        }
        return this._readableState.destroyed && this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (this._readableState === undefined || this._writableState === undefined) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
        this._writableState.destroyed = value;
      }
    });
    }).call(this)}).call(this,require('_process'))
    
    },{"./_stream_readable":155,"./_stream_writable":157,"_process":321,"inherits":182}],154:[function(require,module,exports){
    arguments[4][68][0].apply(exports,arguments)
    },{"./_stream_transform":156,"dup":68,"inherits":182}],155:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    module.exports = Readable;
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Readable.ReadableState = ReadableState;
    
    /*<replacement>*/
    var EE = require('events').EventEmitter;
    var EElistenerCount = function EElistenerCount(emitter, type) {
      return emitter.listeners(type).length;
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    
    /*<replacement>*/
    var debugUtil = require('util');
    var debug;
    if (debugUtil && debugUtil.debuglog) {
      debug = debugUtil.debuglog('stream');
    } else {
      debug = function debug() {};
    }
    /*</replacement>*/
    
    var BufferList = require('./internal/streams/buffer_list');
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;
    
    // Lazy loaded to improve the startup performance.
    var StringDecoder;
    var createReadableStreamAsyncIterator;
    var from;
    require('inherits')(Readable, Stream);
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
    function prependListener(emitter, event, fn) {
      // Sadly this is not cacheable as some libraries bundle their own
      // event emitter implementation with them.
      if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
    
      // This is a hack to make sure that our error handler is attached before any
      // userland ones.  NEVER DO THIS. This is here only because this code needs
      // to continue to work with older versions of Node.js that do not include
      // the prependListener() method. The goal is to eventually remove this hack.
      if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
    }
    function ReadableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream.
      // These options can be provided separately as readableXXX and writableXXX.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag. Used to make read(n) ignore n and to
      // make all the buffer merging and length checks go away
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
    
      // the point at which it stops calling _read() to fill the buffer
      // Note: 0 is a valid value, means "don't call _read preemptively ever"
      this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex);
    
      // A linked list is used to store data chunks instead of an array because the
      // linked list can remove elements from the beginning faster than
      // array.shift()
      this.buffer = new BufferList();
      this.length = 0;
      this.pipes = null;
      this.pipesCount = 0;
      this.flowing = null;
      this.ended = false;
      this.endEmitted = false;
      this.reading = false;
    
      // a flag to be able to tell if the event 'readable'/'data' is emitted
      // immediately, or on a later tick.  We set this to true at first, because
      // any actions that shouldn't happen until "later" should generally also
      // not happen before the first read call.
      this.sync = true;
    
      // whenever we return null, then we set a flag to say
      // that we're awaiting a 'readable' event emission.
      this.needReadable = false;
      this.emittedReadable = false;
      this.readableListening = false;
      this.resumeScheduled = false;
      this.paused = true;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'end' (and potentially 'finish')
      this.autoDestroy = !!options.autoDestroy;
    
      // has it been destroyed
      this.destroyed = false;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // the number of writers that are awaiting a drain event in .pipe()s
      this.awaitDrain = 0;
    
      // if true, a maybeReadMore has been scheduled
      this.readingMore = false;
      this.decoder = null;
      this.encoding = null;
      if (options.encoding) {
        if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
        this.decoder = new StringDecoder(options.encoding);
        this.encoding = options.encoding;
      }
    }
    function Readable(options) {
      Duplex = Duplex || require('./_stream_duplex');
      if (!(this instanceof Readable)) return new Readable(options);
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the ReadableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      this._readableState = new ReadableState(options, this, isDuplex);
    
      // legacy
      this.readable = true;
      if (options) {
        if (typeof options.read === 'function') this._read = options.read;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
      }
      Stream.call(this);
    }
    Object.defineProperty(Readable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined) {
          return false;
        }
        return this._readableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._readableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
      }
    });
    Readable.prototype.destroy = destroyImpl.destroy;
    Readable.prototype._undestroy = destroyImpl.undestroy;
    Readable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    
    // Manually shove something into the read() buffer.
    // This returns true if the highWaterMark has not been hit yet,
    // similar to how Writable.write() returns true if you should
    // write() some more.
    Readable.prototype.push = function (chunk, encoding) {
      var state = this._readableState;
      var skipChunkCheck;
      if (!state.objectMode) {
        if (typeof chunk === 'string') {
          encoding = encoding || state.defaultEncoding;
          if (encoding !== state.encoding) {
            chunk = Buffer.from(chunk, encoding);
            encoding = '';
          }
          skipChunkCheck = true;
        }
      } else {
        skipChunkCheck = true;
      }
      return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
    };
    
    // Unshift should *always* be something directly out of read()
    Readable.prototype.unshift = function (chunk) {
      return readableAddChunk(this, chunk, null, true, false);
    };
    function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
      debug('readableAddChunk', chunk);
      var state = stream._readableState;
      if (chunk === null) {
        state.reading = false;
        onEofChunk(stream, state);
      } else {
        var er;
        if (!skipChunkCheck) er = chunkInvalid(state, chunk);
        if (er) {
          errorOrDestroy(stream, er);
        } else if (state.objectMode || chunk && chunk.length > 0) {
          if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
            chunk = _uint8ArrayToBuffer(chunk);
          }
          if (addToFront) {
            if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
          } else if (state.ended) {
            errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
          } else if (state.destroyed) {
            return false;
          } else {
            state.reading = false;
            if (state.decoder && !encoding) {
              chunk = state.decoder.write(chunk);
              if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
            } else {
              addChunk(stream, state, chunk, false);
            }
          }
        } else if (!addToFront) {
          state.reading = false;
          maybeReadMore(stream, state);
        }
      }
    
      // We can push more data if we are below the highWaterMark.
      // Also, if we have no data yet, we can stand some more bytes.
      // This is to work around cases where hwm=0, such as the repl.
      return !state.ended && (state.length < state.highWaterMark || state.length === 0);
    }
    function addChunk(stream, state, chunk, addToFront) {
      if (state.flowing && state.length === 0 && !state.sync) {
        state.awaitDrain = 0;
        stream.emit('data', chunk);
      } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
        if (state.needReadable) emitReadable(stream);
      }
      maybeReadMore(stream, state);
    }
    function chunkInvalid(state, chunk) {
      var er;
      if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
      }
      return er;
    }
    Readable.prototype.isPaused = function () {
      return this._readableState.flowing === false;
    };
    
    // backwards compatibility.
    Readable.prototype.setEncoding = function (enc) {
      if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
      var decoder = new StringDecoder(enc);
      this._readableState.decoder = decoder;
      // If setEncoding(null), decoder.encoding equals utf8
      this._readableState.encoding = this._readableState.decoder.encoding;
    
      // Iterate over current buffer to convert already stored Buffers:
      var p = this._readableState.buffer.head;
      var content = '';
      while (p !== null) {
        content += decoder.write(p.data);
        p = p.next;
      }
      this._readableState.buffer.clear();
      if (content !== '') this._readableState.buffer.push(content);
      this._readableState.length = content.length;
      return this;
    };
    
    // Don't raise the hwm > 1GB
    var MAX_HWM = 0x40000000;
    function computeNewHighWaterMark(n) {
      if (n >= MAX_HWM) {
        // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
        n = MAX_HWM;
      } else {
        // Get the next highest power of 2 to prevent increasing hwm excessively in
        // tiny amounts
        n--;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        n++;
      }
      return n;
    }
    
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function howMuchToRead(n, state) {
      if (n <= 0 || state.length === 0 && state.ended) return 0;
      if (state.objectMode) return 1;
      if (n !== n) {
        // Only flow one buffer at a time
        if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
      }
      // If we're asking for more than the current hwm, then raise the hwm.
      if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
      if (n <= state.length) return n;
      // Don't have enough
      if (!state.ended) {
        state.needReadable = true;
        return 0;
      }
      return state.length;
    }
    
    // you can override either this method, or the async _read(n) below.
    Readable.prototype.read = function (n) {
      debug('read', n);
      n = parseInt(n, 10);
      var state = this._readableState;
      var nOrig = n;
      if (n !== 0) state.emittedReadable = false;
    
      // if we're doing read(0) to trigger a readable event, but we
      // already have a bunch of data in the buffer, then just trigger
      // the 'readable' event and move on.
      if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
        debug('read: emitReadable', state.length, state.ended);
        if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
        return null;
      }
      n = howMuchToRead(n, state);
    
      // if we've ended, and we're now clear, then finish it up.
      if (n === 0 && state.ended) {
        if (state.length === 0) endReadable(this);
        return null;
      }
    
      // All the actual chunk generation logic needs to be
      // *below* the call to _read.  The reason is that in certain
      // synthetic stream cases, such as passthrough streams, _read
      // may be a completely synchronous operation which may change
      // the state of the read buffer, providing enough data when
      // before there was *not* enough.
      //
      // So, the steps are:
      // 1. Figure out what the state of things will be after we do
      // a read from the buffer.
      //
      // 2. If that resulting state will trigger a _read, then call _read.
      // Note that this may be asynchronous, or synchronous.  Yes, it is
      // deeply ugly to write APIs this way, but that still doesn't mean
      // that the Readable class should behave improperly, as streams are
      // designed to be sync/async agnostic.
      // Take note if the _read call is sync or async (ie, if the read call
      // has returned yet), so that we know whether or not it's safe to emit
      // 'readable' etc.
      //
      // 3. Actually pull the requested chunks out of the buffer and return.
    
      // if we need a readable event, then we need to do some reading.
      var doRead = state.needReadable;
      debug('need readable', doRead);
    
      // if we currently have less than the highWaterMark, then also read some
      if (state.length === 0 || state.length - n < state.highWaterMark) {
        doRead = true;
        debug('length less than watermark', doRead);
      }
    
      // however, if we've ended, then there's no point, and if we're already
      // reading, then it's unnecessary.
      if (state.ended || state.reading) {
        doRead = false;
        debug('reading or ended', doRead);
      } else if (doRead) {
        debug('do read');
        state.reading = true;
        state.sync = true;
        // if the length is currently zero, then we *need* a readable event.
        if (state.length === 0) state.needReadable = true;
        // call internal read method
        this._read(state.highWaterMark);
        state.sync = false;
        // If _read pushed data synchronously, then `reading` will be false,
        // and we need to re-evaluate how much data we can return to the user.
        if (!state.reading) n = howMuchToRead(nOrig, state);
      }
      var ret;
      if (n > 0) ret = fromList(n, state);else ret = null;
      if (ret === null) {
        state.needReadable = state.length <= state.highWaterMark;
        n = 0;
      } else {
        state.length -= n;
        state.awaitDrain = 0;
      }
      if (state.length === 0) {
        // If we have nothing in the buffer, then we want to know
        // as soon as we *do* get something into the buffer.
        if (!state.ended) state.needReadable = true;
    
        // If we tried to read() past the EOF, then emit end on the next tick.
        if (nOrig !== n && state.ended) endReadable(this);
      }
      if (ret !== null) this.emit('data', ret);
      return ret;
    };
    function onEofChunk(stream, state) {
      debug('onEofChunk');
      if (state.ended) return;
      if (state.decoder) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length) {
          state.buffer.push(chunk);
          state.length += state.objectMode ? 1 : chunk.length;
        }
      }
      state.ended = true;
      if (state.sync) {
        // if we are sync, wait until next tick to emit the data.
        // Otherwise we risk emitting data in the flow()
        // the readable code triggers during a read() call
        emitReadable(stream);
      } else {
        // emit 'readable' now to make sure it gets picked up.
        state.needReadable = false;
        if (!state.emittedReadable) {
          state.emittedReadable = true;
          emitReadable_(stream);
        }
      }
    }
    
    // Don't emit readable right away in sync mode, because this can trigger
    // another read() call => stack overflow.  This way, it might trigger
    // a nextTick recursion warning, but that's not so bad.
    function emitReadable(stream) {
      var state = stream._readableState;
      debug('emitReadable', state.needReadable, state.emittedReadable);
      state.needReadable = false;
      if (!state.emittedReadable) {
        debug('emitReadable', state.flowing);
        state.emittedReadable = true;
        process.nextTick(emitReadable_, stream);
      }
    }
    function emitReadable_(stream) {
      var state = stream._readableState;
      debug('emitReadable_', state.destroyed, state.length, state.ended);
      if (!state.destroyed && (state.length || state.ended)) {
        stream.emit('readable');
        state.emittedReadable = false;
      }
    
      // The stream needs another readable event if
      // 1. It is not flowing, as the flow mechanism will take
      //    care of it.
      // 2. It is not ended.
      // 3. It is below the highWaterMark, so we can schedule
      //    another readable later.
      state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
      flow(stream);
    }
    
    // at this point, the user has presumably seen the 'readable' event,
    // and called read() to consume some data.  that may have triggered
    // in turn another _read(n) call, in which case reading = true if
    // it's in progress.
    // However, if we're not ended, or reading, and the length < hwm,
    // then go ahead and try to read some more preemptively.
    function maybeReadMore(stream, state) {
      if (!state.readingMore) {
        state.readingMore = true;
        process.nextTick(maybeReadMore_, stream, state);
      }
    }
    function maybeReadMore_(stream, state) {
      // Attempt to read more data if we should.
      //
      // The conditions for reading more data are (one of):
      // - Not enough data buffered (state.length < state.highWaterMark). The loop
      //   is responsible for filling the buffer with enough data if such data
      //   is available. If highWaterMark is 0 and we are not in the flowing mode
      //   we should _not_ attempt to buffer any extra data. We'll get more data
      //   when the stream consumer calls read() instead.
      // - No data in the buffer, and the stream is in flowing mode. In this mode
      //   the loop below is responsible for ensuring read() is called. Failing to
      //   call read here would abort the flow and there's no other mechanism for
      //   continuing the flow if the stream consumer has just subscribed to the
      //   'data' event.
      //
      // In addition to the above conditions to keep reading data, the following
      // conditions prevent the data from being read:
      // - The stream has ended (state.ended).
      // - There is already a pending 'read' operation (state.reading). This is a
      //   case where the the stream has called the implementation defined _read()
      //   method, but they are processing the call asynchronously and have _not_
      //   called push() with new data. In this case we skip performing more
      //   read()s. The execution ends in this method again after the _read() ends
      //   up calling push() with more data.
      while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
        var len = state.length;
        debug('maybeReadMore read 0');
        stream.read(0);
        if (len === state.length)
          // didn't get any data, stop spinning.
          break;
      }
      state.readingMore = false;
    }
    
    // abstract method.  to be overridden in specific implementation classes.
    // call cb(er, data) where data is <= n in length.
    // for virtual (non-string, non-buffer) streams, "length" is somewhat
    // arbitrary, and perhaps not very meaningful.
    Readable.prototype._read = function (n) {
      errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
    };
    Readable.prototype.pipe = function (dest, pipeOpts) {
      var src = this;
      var state = this._readableState;
      switch (state.pipesCount) {
        case 0:
          state.pipes = dest;
          break;
        case 1:
          state.pipes = [state.pipes, dest];
          break;
        default:
          state.pipes.push(dest);
          break;
      }
      state.pipesCount += 1;
      debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
      var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
      var endFn = doEnd ? onend : unpipe;
      if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
      dest.on('unpipe', onunpipe);
      function onunpipe(readable, unpipeInfo) {
        debug('onunpipe');
        if (readable === src) {
          if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
            unpipeInfo.hasUnpiped = true;
            cleanup();
          }
        }
      }
      function onend() {
        debug('onend');
        dest.end();
      }
    
      // when the dest drains, it reduces the awaitDrain counter
      // on the source.  This would be more elegant with a .once()
      // handler in flow(), but adding and removing repeatedly is
      // too slow.
      var ondrain = pipeOnDrain(src);
      dest.on('drain', ondrain);
      var cleanedUp = false;
      function cleanup() {
        debug('cleanup');
        // cleanup event handlers once the pipe is broken
        dest.removeListener('close', onclose);
        dest.removeListener('finish', onfinish);
        dest.removeListener('drain', ondrain);
        dest.removeListener('error', onerror);
        dest.removeListener('unpipe', onunpipe);
        src.removeListener('end', onend);
        src.removeListener('end', unpipe);
        src.removeListener('data', ondata);
        cleanedUp = true;
    
        // if the reader is waiting for a drain event from this
        // specific writer, then it would cause it to never start
        // flowing again.
        // So, if this is awaiting a drain, then we just call it now.
        // If we don't know, then assume that we are waiting for one.
        if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
      }
      src.on('data', ondata);
      function ondata(chunk) {
        debug('ondata');
        var ret = dest.write(chunk);
        debug('dest.write', ret);
        if (ret === false) {
          // If the user unpiped during `dest.write()`, it is possible
          // to get stuck in a permanently paused state if that write
          // also returned false.
          // => Check whether `dest` is still a piping destination.
          if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
            debug('false write response, pause', state.awaitDrain);
            state.awaitDrain++;
          }
          src.pause();
        }
      }
    
      // if the dest has an error, then stop piping into it.
      // however, don't suppress the throwing behavior for this.
      function onerror(er) {
        debug('onerror', er);
        unpipe();
        dest.removeListener('error', onerror);
        if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
      }
    
      // Make sure our error handler is attached before userland ones.
      prependListener(dest, 'error', onerror);
    
      // Both close and finish should trigger unpipe, but only once.
      function onclose() {
        dest.removeListener('finish', onfinish);
        unpipe();
      }
      dest.once('close', onclose);
      function onfinish() {
        debug('onfinish');
        dest.removeListener('close', onclose);
        unpipe();
      }
      dest.once('finish', onfinish);
      function unpipe() {
        debug('unpipe');
        src.unpipe(dest);
      }
    
      // tell the dest that it's being piped to
      dest.emit('pipe', src);
    
      // start the flow if it hasn't been started already.
      if (!state.flowing) {
        debug('pipe resume');
        src.resume();
      }
      return dest;
    };
    function pipeOnDrain(src) {
      return function pipeOnDrainFunctionResult() {
        var state = src._readableState;
        debug('pipeOnDrain', state.awaitDrain);
        if (state.awaitDrain) state.awaitDrain--;
        if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
          state.flowing = true;
          flow(src);
        }
      };
    }
    Readable.prototype.unpipe = function (dest) {
      var state = this._readableState;
      var unpipeInfo = {
        hasUnpiped: false
      };
    
      // if we're not piping anywhere, then do nothing.
      if (state.pipesCount === 0) return this;
    
      // just one destination.  most common case.
      if (state.pipesCount === 1) {
        // passed in one, but it's not the right one.
        if (dest && dest !== state.pipes) return this;
        if (!dest) dest = state.pipes;
    
        // got a match.
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        if (dest) dest.emit('unpipe', this, unpipeInfo);
        return this;
      }
    
      // slow case. multiple pipe destinations.
    
      if (!dest) {
        // remove all.
        var dests = state.pipes;
        var len = state.pipesCount;
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, {
          hasUnpiped: false
        });
        return this;
      }
    
      // try to find the right one.
      var index = indexOf(state.pipes, dest);
      if (index === -1) return this;
      state.pipes.splice(index, 1);
      state.pipesCount -= 1;
      if (state.pipesCount === 1) state.pipes = state.pipes[0];
      dest.emit('unpipe', this, unpipeInfo);
      return this;
    };
    
    // set up data events if they are asked for
    // Ensure readable listeners eventually get something
    Readable.prototype.on = function (ev, fn) {
      var res = Stream.prototype.on.call(this, ev, fn);
      var state = this._readableState;
      if (ev === 'data') {
        // update readableListening so that resume() may be a no-op
        // a few lines down. This is needed to support once('readable').
        state.readableListening = this.listenerCount('readable') > 0;
    
        // Try start flowing on next tick if stream isn't explicitly paused
        if (state.flowing !== false) this.resume();
      } else if (ev === 'readable') {
        if (!state.endEmitted && !state.readableListening) {
          state.readableListening = state.needReadable = true;
          state.flowing = false;
          state.emittedReadable = false;
          debug('on readable', state.length, state.reading);
          if (state.length) {
            emitReadable(this);
          } else if (!state.reading) {
            process.nextTick(nReadingNextTick, this);
          }
        }
      }
      return res;
    };
    Readable.prototype.addListener = Readable.prototype.on;
    Readable.prototype.removeListener = function (ev, fn) {
      var res = Stream.prototype.removeListener.call(this, ev, fn);
      if (ev === 'readable') {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    Readable.prototype.removeAllListeners = function (ev) {
      var res = Stream.prototype.removeAllListeners.apply(this, arguments);
      if (ev === 'readable' || ev === undefined) {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    function updateReadableListening(self) {
      var state = self._readableState;
      state.readableListening = self.listenerCount('readable') > 0;
      if (state.resumeScheduled && !state.paused) {
        // flowing needs to be set to true now, otherwise
        // the upcoming resume will not flow.
        state.flowing = true;
    
        // crude way to check if we should resume
      } else if (self.listenerCount('data') > 0) {
        self.resume();
      }
    }
    function nReadingNextTick(self) {
      debug('readable nexttick read 0');
      self.read(0);
    }
    
    // pause() and resume() are remnants of the legacy readable stream API
    // If the user uses them, then switch into old mode.
    Readable.prototype.resume = function () {
      var state = this._readableState;
      if (!state.flowing) {
        debug('resume');
        // we flow only if there is no one listening
        // for readable, but we still have to call
        // resume()
        state.flowing = !state.readableListening;
        resume(this, state);
      }
      state.paused = false;
      return this;
    };
    function resume(stream, state) {
      if (!state.resumeScheduled) {
        state.resumeScheduled = true;
        process.nextTick(resume_, stream, state);
      }
    }
    function resume_(stream, state) {
      debug('resume', state.reading);
      if (!state.reading) {
        stream.read(0);
      }
      state.resumeScheduled = false;
      stream.emit('resume');
      flow(stream);
      if (state.flowing && !state.reading) stream.read(0);
    }
    Readable.prototype.pause = function () {
      debug('call pause flowing=%j', this._readableState.flowing);
      if (this._readableState.flowing !== false) {
        debug('pause');
        this._readableState.flowing = false;
        this.emit('pause');
      }
      this._readableState.paused = true;
      return this;
    };
    function flow(stream) {
      var state = stream._readableState;
      debug('flow', state.flowing);
      while (state.flowing && stream.read() !== null);
    }
    
    // wrap an old-style stream as the async data source.
    // This is *not* part of the readable stream interface.
    // It is an ugly unfortunate mess of history.
    Readable.prototype.wrap = function (stream) {
      var _this = this;
      var state = this._readableState;
      var paused = false;
      stream.on('end', function () {
        debug('wrapped end');
        if (state.decoder && !state.ended) {
          var chunk = state.decoder.end();
          if (chunk && chunk.length) _this.push(chunk);
        }
        _this.push(null);
      });
      stream.on('data', function (chunk) {
        debug('wrapped data');
        if (state.decoder) chunk = state.decoder.write(chunk);
    
        // don't skip over falsy values in objectMode
        if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
        var ret = _this.push(chunk);
        if (!ret) {
          paused = true;
          stream.pause();
        }
      });
    
      // proxy all the other methods.
      // important when wrapping filters and duplexes.
      for (var i in stream) {
        if (this[i] === undefined && typeof stream[i] === 'function') {
          this[i] = function methodWrap(method) {
            return function methodWrapReturnFunction() {
              return stream[method].apply(stream, arguments);
            };
          }(i);
        }
      }
    
      // proxy certain important events.
      for (var n = 0; n < kProxyEvents.length; n++) {
        stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
      }
    
      // when we try to consume some more bytes, simply unpause the
      // underlying stream.
      this._read = function (n) {
        debug('wrapped _read', n);
        if (paused) {
          paused = false;
          stream.resume();
        }
      };
      return this;
    };
    if (typeof Symbol === 'function') {
      Readable.prototype[Symbol.asyncIterator] = function () {
        if (createReadableStreamAsyncIterator === undefined) {
          createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
        }
        return createReadableStreamAsyncIterator(this);
      };
    }
    Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.highWaterMark;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState && this._readableState.buffer;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableFlowing', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.flowing;
      },
      set: function set(state) {
        if (this._readableState) {
          this._readableState.flowing = state;
        }
      }
    });
    
    // exposed for testing purposes only.
    Readable._fromList = fromList;
    Object.defineProperty(Readable.prototype, 'readableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.length;
      }
    });
    
    // Pluck off n bytes from an array of buffers.
    // Length is the combined lengths of all the buffers in the list.
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function fromList(n, state) {
      // nothing buffered
      if (state.length === 0) return null;
      var ret;
      if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
        // read it all, truncate the list
        if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
        state.buffer.clear();
      } else {
        // read part of list
        ret = state.buffer.consume(n, state.decoder);
      }
      return ret;
    }
    function endReadable(stream) {
      var state = stream._readableState;
      debug('endReadable', state.endEmitted);
      if (!state.endEmitted) {
        state.ended = true;
        process.nextTick(endReadableNT, state, stream);
      }
    }
    function endReadableNT(state, stream) {
      debug('endReadableNT', state.endEmitted, state.length);
    
      // Check that we didn't get one last unshift.
      if (!state.endEmitted && state.length === 0) {
        state.endEmitted = true;
        stream.readable = false;
        stream.emit('end');
        if (state.autoDestroy) {
          // In case of duplex streams we need a way to detect
          // if the writable side is ready for autoDestroy as well
          var wState = stream._writableState;
          if (!wState || wState.autoDestroy && wState.finished) {
            stream.destroy();
          }
        }
      }
    }
    if (typeof Symbol === 'function') {
      Readable.from = function (iterable, opts) {
        if (from === undefined) {
          from = require('./internal/streams/from');
        }
        return from(Readable, iterable, opts);
      };
    }
    function indexOf(xs, x) {
      for (var i = 0, l = xs.length; i < l; i++) {
        if (xs[i] === x) return i;
      }
      return -1;
    }
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":152,"./_stream_duplex":153,"./internal/streams/async_iterator":158,"./internal/streams/buffer_list":159,"./internal/streams/destroy":160,"./internal/streams/from":162,"./internal/streams/state":164,"./internal/streams/stream":165,"_process":321,"buffer":84,"events":134,"inherits":182,"string_decoder/":365,"util":36}],156:[function(require,module,exports){
    arguments[4][70][0].apply(exports,arguments)
    },{"../errors":152,"./_stream_duplex":153,"dup":70,"inherits":182}],157:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // A bit simpler than readable streams.
    // Implement an async ._write(chunk, encoding, cb), and it'll handle all
    // the drain event emission and buffering.
    
    'use strict';
    
    module.exports = Writable;
    
    /* <replacement> */
    function WriteReq(chunk, encoding, cb) {
      this.chunk = chunk;
      this.encoding = encoding;
      this.callback = cb;
      this.next = null;
    }
    
    // It seems a linked list but it is not
    // there will be only 2 of these for each stream
    function CorkedRequest(state) {
      var _this = this;
      this.next = null;
      this.entry = null;
      this.finish = function () {
        onCorkedFinish(_this, state);
      };
    }
    /* </replacement> */
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Writable.WritableState = WritableState;
    
    /*<replacement>*/
    var internalUtil = {
      deprecate: require('util-deprecate')
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
      ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
      ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
      ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
      ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
      ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    require('inherits')(Writable, Stream);
    function nop() {}
    function WritableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream,
      // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag to indicate whether or not this stream
      // contains buffers or objects.
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
    
      // the point at which write() starts returning false
      // Note: 0 is a valid value, means that we always return false if
      // the entire buffer is not flushed immediately on write()
      this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex);
    
      // if _final has been called
      this.finalCalled = false;
    
      // drain event flag.
      this.needDrain = false;
      // at the start of calling end()
      this.ending = false;
      // when end() has been called, and returned
      this.ended = false;
      // when 'finish' is emitted
      this.finished = false;
    
      // has it been destroyed
      this.destroyed = false;
    
      // should we decode strings into buffers before passing to _write?
      // this is here so that some node-core streams can optimize string
      // handling at a lower level.
      var noDecode = options.decodeStrings === false;
      this.decodeStrings = !noDecode;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // not an actual buffer we keep track of, but a measurement
      // of how much we're waiting to get pushed to some underlying
      // socket or file.
      this.length = 0;
    
      // a flag to see when we're in the middle of a write.
      this.writing = false;
    
      // when true all writes will be buffered until .uncork() call
      this.corked = 0;
    
      // a flag to be able to tell if the onwrite cb is called immediately,
      // or on a later tick.  We set this to true at first, because any
      // actions that shouldn't happen until "later" should generally also
      // not happen before the first write call.
      this.sync = true;
    
      // a flag to know if we're processing previously buffered items, which
      // may call the _write() callback in the same tick, so that we don't
      // end up in an overlapped onwrite situation.
      this.bufferProcessing = false;
    
      // the callback that's passed to _write(chunk,cb)
      this.onwrite = function (er) {
        onwrite(stream, er);
      };
    
      // the callback that the user supplies to write(chunk,encoding,cb)
      this.writecb = null;
    
      // the amount that is being written when _write is called.
      this.writelen = 0;
      this.bufferedRequest = null;
      this.lastBufferedRequest = null;
    
      // number of pending user-supplied write callbacks
      // this must be 0 before 'finish' can be emitted
      this.pendingcb = 0;
    
      // emit prefinish if the only thing we're waiting for is _write cbs
      // This is relevant for synchronous Transform streams
      this.prefinished = false;
    
      // True if the error was already emitted and should not be thrown again
      this.errorEmitted = false;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'finish' (and potentially 'end')
      this.autoDestroy = !!options.autoDestroy;
    
      // count buffered requests
      this.bufferedRequestCount = 0;
    
      // allocate the first CorkedRequest, there is always
      // one allocated and free to use, and we maintain at most two
      this.corkedRequestsFree = new CorkedRequest(this);
    }
    WritableState.prototype.getBuffer = function getBuffer() {
      var current = this.bufferedRequest;
      var out = [];
      while (current) {
        out.push(current);
        current = current.next;
      }
      return out;
    };
    (function () {
      try {
        Object.defineProperty(WritableState.prototype, 'buffer', {
          get: internalUtil.deprecate(function writableStateBufferGetter() {
            return this.getBuffer();
          }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
        });
      } catch (_) {}
    })();
    
    // Test _writableState for inheritance to account for Duplex streams,
    // whose prototype chain only points to Readable.
    var realHasInstance;
    if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
      realHasInstance = Function.prototype[Symbol.hasInstance];
      Object.defineProperty(Writable, Symbol.hasInstance, {
        value: function value(object) {
          if (realHasInstance.call(this, object)) return true;
          if (this !== Writable) return false;
          return object && object._writableState instanceof WritableState;
        }
      });
    } else {
      realHasInstance = function realHasInstance(object) {
        return object instanceof this;
      };
    }
    function Writable(options) {
      Duplex = Duplex || require('./_stream_duplex');
    
      // Writable ctor is applied to Duplexes, too.
      // `realHasInstance` is necessary because using plain `instanceof`
      // would return false, as no `_writableState` property is attached.
    
      // Trying to use the custom `instanceof` for Writable here will also break the
      // Node.js LazyTransform implementation, which has a non-trivial getter for
      // `_writableState` that would lead to infinite recursion.
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the WritableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
      this._writableState = new WritableState(options, this, isDuplex);
    
      // legacy.
      this.writable = true;
      if (options) {
        if (typeof options.write === 'function') this._write = options.write;
        if (typeof options.writev === 'function') this._writev = options.writev;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
        if (typeof options.final === 'function') this._final = options.final;
      }
      Stream.call(this);
    }
    
    // Otherwise people can pipe Writable streams, which is just wrong.
    Writable.prototype.pipe = function () {
      errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
    };
    function writeAfterEnd(stream, cb) {
      var er = new ERR_STREAM_WRITE_AFTER_END();
      // TODO: defer error events consistently everywhere, not just the cb
      errorOrDestroy(stream, er);
      process.nextTick(cb, er);
    }
    
    // Checks that a user-supplied chunk is valid, especially for the particular
    // mode the stream is in. Currently this means that `null` is never accepted
    // and undefined/non-string values are only allowed in object mode.
    function validChunk(stream, state, chunk, cb) {
      var er;
      if (chunk === null) {
        er = new ERR_STREAM_NULL_VALUES();
      } else if (typeof chunk !== 'string' && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
      }
      if (er) {
        errorOrDestroy(stream, er);
        process.nextTick(cb, er);
        return false;
      }
      return true;
    }
    Writable.prototype.write = function (chunk, encoding, cb) {
      var state = this._writableState;
      var ret = false;
      var isBuf = !state.objectMode && _isUint8Array(chunk);
      if (isBuf && !Buffer.isBuffer(chunk)) {
        chunk = _uint8ArrayToBuffer(chunk);
      }
      if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
      if (typeof cb !== 'function') cb = nop;
      if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
        state.pendingcb++;
        ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
      }
      return ret;
    };
    Writable.prototype.cork = function () {
      this._writableState.corked++;
    };
    Writable.prototype.uncork = function () {
      var state = this._writableState;
      if (state.corked) {
        state.corked--;
        if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
      }
    };
    Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
      // node::ParseEncoding() requires lower case.
      if (typeof encoding === 'string') encoding = encoding.toLowerCase();
      if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
      this._writableState.defaultEncoding = encoding;
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    function decodeChunk(state, chunk, encoding) {
      if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
        chunk = Buffer.from(chunk, encoding);
      }
      return chunk;
    }
    Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    
    // if we're already writing something, then just put this
    // in the queue, and wait our turn.  Otherwise, call _write
    // If we return false, then we need a drain event, so set that flag.
    function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
      if (!isBuf) {
        var newChunk = decodeChunk(state, chunk, encoding);
        if (chunk !== newChunk) {
          isBuf = true;
          encoding = 'buffer';
          chunk = newChunk;
        }
      }
      var len = state.objectMode ? 1 : chunk.length;
      state.length += len;
      var ret = state.length < state.highWaterMark;
      // we must ensure that previous needDrain will not be reset to false.
      if (!ret) state.needDrain = true;
      if (state.writing || state.corked) {
        var last = state.lastBufferedRequest;
        state.lastBufferedRequest = {
          chunk: chunk,
          encoding: encoding,
          isBuf: isBuf,
          callback: cb,
          next: null
        };
        if (last) {
          last.next = state.lastBufferedRequest;
        } else {
          state.bufferedRequest = state.lastBufferedRequest;
        }
        state.bufferedRequestCount += 1;
      } else {
        doWrite(stream, state, false, len, chunk, encoding, cb);
      }
      return ret;
    }
    function doWrite(stream, state, writev, len, chunk, encoding, cb) {
      state.writelen = len;
      state.writecb = cb;
      state.writing = true;
      state.sync = true;
      if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
      state.sync = false;
    }
    function onwriteError(stream, state, sync, er, cb) {
      --state.pendingcb;
      if (sync) {
        // defer the callback if we are being called synchronously
        // to avoid piling up things on the stack
        process.nextTick(cb, er);
        // this can emit finish, and it will always happen
        // after error
        process.nextTick(finishMaybe, stream, state);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
      } else {
        // the caller expect this to happen before if
        // it is async
        cb(er);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
        // this can emit finish, but finish must
        // always follow error
        finishMaybe(stream, state);
      }
    }
    function onwriteStateUpdate(state) {
      state.writing = false;
      state.writecb = null;
      state.length -= state.writelen;
      state.writelen = 0;
    }
    function onwrite(stream, er) {
      var state = stream._writableState;
      var sync = state.sync;
      var cb = state.writecb;
      if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
      onwriteStateUpdate(state);
      if (er) onwriteError(stream, state, sync, er, cb);else {
        // Check if we're actually ready to finish, but don't emit yet
        var finished = needFinish(state) || stream.destroyed;
        if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
          clearBuffer(stream, state);
        }
        if (sync) {
          process.nextTick(afterWrite, stream, state, finished, cb);
        } else {
          afterWrite(stream, state, finished, cb);
        }
      }
    }
    function afterWrite(stream, state, finished, cb) {
      if (!finished) onwriteDrain(stream, state);
      state.pendingcb--;
      cb();
      finishMaybe(stream, state);
    }
    
    // Must force callback to be called on nextTick, so that we don't
    // emit 'drain' before the write() consumer gets the 'false' return
    // value, and has a chance to attach a 'drain' listener.
    function onwriteDrain(stream, state) {
      if (state.length === 0 && state.needDrain) {
        state.needDrain = false;
        stream.emit('drain');
      }
    }
    
    // if there's something in the buffer waiting, then process it
    function clearBuffer(stream, state) {
      state.bufferProcessing = true;
      var entry = state.bufferedRequest;
      if (stream._writev && entry && entry.next) {
        // Fast case, write everything using _writev()
        var l = state.bufferedRequestCount;
        var buffer = new Array(l);
        var holder = state.corkedRequestsFree;
        holder.entry = entry;
        var count = 0;
        var allBuffers = true;
        while (entry) {
          buffer[count] = entry;
          if (!entry.isBuf) allBuffers = false;
          entry = entry.next;
          count += 1;
        }
        buffer.allBuffers = allBuffers;
        doWrite(stream, state, true, state.length, buffer, '', holder.finish);
    
        // doWrite is almost always async, defer these to save a bit of time
        // as the hot path ends with doWrite
        state.pendingcb++;
        state.lastBufferedRequest = null;
        if (holder.next) {
          state.corkedRequestsFree = holder.next;
          holder.next = null;
        } else {
          state.corkedRequestsFree = new CorkedRequest(state);
        }
        state.bufferedRequestCount = 0;
      } else {
        // Slow case, write chunks one-by-one
        while (entry) {
          var chunk = entry.chunk;
          var encoding = entry.encoding;
          var cb = entry.callback;
          var len = state.objectMode ? 1 : chunk.length;
          doWrite(stream, state, false, len, chunk, encoding, cb);
          entry = entry.next;
          state.bufferedRequestCount--;
          // if we didn't call the onwrite immediately, then
          // it means that we need to wait until it does.
          // also, that means that the chunk and cb are currently
          // being processed, so move the buffer counter past them.
          if (state.writing) {
            break;
          }
        }
        if (entry === null) state.lastBufferedRequest = null;
      }
      state.bufferedRequest = entry;
      state.bufferProcessing = false;
    }
    Writable.prototype._write = function (chunk, encoding, cb) {
      cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
    };
    Writable.prototype._writev = null;
    Writable.prototype.end = function (chunk, encoding, cb) {
      var state = this._writableState;
      if (typeof chunk === 'function') {
        cb = chunk;
        chunk = null;
        encoding = null;
      } else if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
    
      // .end() fully uncorks
      if (state.corked) {
        state.corked = 1;
        this.uncork();
      }
    
      // ignore unnecessary end() calls.
      if (!state.ending) endWritable(this, state, cb);
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    function needFinish(state) {
      return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
    }
    function callFinal(stream, state) {
      stream._final(function (err) {
        state.pendingcb--;
        if (err) {
          errorOrDestroy(stream, err);
        }
        state.prefinished = true;
        stream.emit('prefinish');
        finishMaybe(stream, state);
      });
    }
    function prefinish(stream, state) {
      if (!state.prefinished && !state.finalCalled) {
        if (typeof stream._final === 'function' && !state.destroyed) {
          state.pendingcb++;
          state.finalCalled = true;
          process.nextTick(callFinal, stream, state);
        } else {
          state.prefinished = true;
          stream.emit('prefinish');
        }
      }
    }
    function finishMaybe(stream, state) {
      var need = needFinish(state);
      if (need) {
        prefinish(stream, state);
        if (state.pendingcb === 0) {
          state.finished = true;
          stream.emit('finish');
          if (state.autoDestroy) {
            // In case of duplex streams we need a way to detect
            // if the readable side is ready for autoDestroy as well
            var rState = stream._readableState;
            if (!rState || rState.autoDestroy && rState.endEmitted) {
              stream.destroy();
            }
          }
        }
      }
      return need;
    }
    function endWritable(stream, state, cb) {
      state.ending = true;
      finishMaybe(stream, state);
      if (cb) {
        if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
      }
      state.ended = true;
      stream.writable = false;
    }
    function onCorkedFinish(corkReq, state, err) {
      var entry = corkReq.entry;
      corkReq.entry = null;
      while (entry) {
        var cb = entry.callback;
        state.pendingcb--;
        cb(err);
        entry = entry.next;
      }
    
      // reuse the free corkReq.
      state.corkedRequestsFree.next = corkReq;
    }
    Object.defineProperty(Writable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._writableState === undefined) {
          return false;
        }
        return this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._writableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._writableState.destroyed = value;
      }
    });
    Writable.prototype.destroy = destroyImpl.destroy;
    Writable.prototype._undestroy = destroyImpl.undestroy;
    Writable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":152,"./_stream_duplex":153,"./internal/streams/destroy":160,"./internal/streams/state":164,"./internal/streams/stream":165,"_process":321,"buffer":84,"inherits":182,"util-deprecate":369}],158:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    var _Object$setPrototypeO;
    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
    function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
    function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
    var finished = require('./end-of-stream');
    var kLastResolve = Symbol('lastResolve');
    var kLastReject = Symbol('lastReject');
    var kError = Symbol('error');
    var kEnded = Symbol('ended');
    var kLastPromise = Symbol('lastPromise');
    var kHandlePromise = Symbol('handlePromise');
    var kStream = Symbol('stream');
    function createIterResult(value, done) {
      return {
        value: value,
        done: done
      };
    }
    function readAndResolve(iter) {
      var resolve = iter[kLastResolve];
      if (resolve !== null) {
        var data = iter[kStream].read();
        // we defer if data is null
        // we can be expecting either 'end' or
        // 'error'
        if (data !== null) {
          iter[kLastPromise] = null;
          iter[kLastResolve] = null;
          iter[kLastReject] = null;
          resolve(createIterResult(data, false));
        }
      }
    }
    function onReadable(iter) {
      // we wait for the next tick, because it might
      // emit an error with process.nextTick
      process.nextTick(readAndResolve, iter);
    }
    function wrapForNext(lastPromise, iter) {
      return function (resolve, reject) {
        lastPromise.then(function () {
          if (iter[kEnded]) {
            resolve(createIterResult(undefined, true));
            return;
          }
          iter[kHandlePromise](resolve, reject);
        }, reject);
      };
    }
    var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
    var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
      get stream() {
        return this[kStream];
      },
      next: function next() {
        var _this = this;
        // if we have detected an error in the meanwhile
        // reject straight away
        var error = this[kError];
        if (error !== null) {
          return Promise.reject(error);
        }
        if (this[kEnded]) {
          return Promise.resolve(createIterResult(undefined, true));
        }
        if (this[kStream].destroyed) {
          // We need to defer via nextTick because if .destroy(err) is
          // called, the error will be emitted via nextTick, and
          // we cannot guarantee that there is no error lingering around
          // waiting to be emitted.
          return new Promise(function (resolve, reject) {
            process.nextTick(function () {
              if (_this[kError]) {
                reject(_this[kError]);
              } else {
                resolve(createIterResult(undefined, true));
              }
            });
          });
        }
    
        // if we have multiple next() calls
        // we will wait for the previous Promise to finish
        // this logic is optimized to support for await loops,
        // where next() is only called once at a time
        var lastPromise = this[kLastPromise];
        var promise;
        if (lastPromise) {
          promise = new Promise(wrapForNext(lastPromise, this));
        } else {
          // fast path needed to support multiple this.push()
          // without triggering the next() queue
          var data = this[kStream].read();
          if (data !== null) {
            return Promise.resolve(createIterResult(data, false));
          }
          promise = new Promise(this[kHandlePromise]);
        }
        this[kLastPromise] = promise;
        return promise;
      }
    }, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
      return this;
    }), _defineProperty(_Object$setPrototypeO, "return", function _return() {
      var _this2 = this;
      // destroy(err, cb) is a private API
      // we can guarantee we have that here, because we control the
      // Readable class this is attached to
      return new Promise(function (resolve, reject) {
        _this2[kStream].destroy(null, function (err) {
          if (err) {
            reject(err);
            return;
          }
          resolve(createIterResult(undefined, true));
        });
      });
    }), _Object$setPrototypeO), AsyncIteratorPrototype);
    var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
      var _Object$create;
      var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
        value: stream,
        writable: true
      }), _defineProperty(_Object$create, kLastResolve, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kLastReject, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kError, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kEnded, {
        value: stream._readableState.endEmitted,
        writable: true
      }), _defineProperty(_Object$create, kHandlePromise, {
        value: function value(resolve, reject) {
          var data = iterator[kStream].read();
          if (data) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            resolve(createIterResult(data, false));
          } else {
            iterator[kLastResolve] = resolve;
            iterator[kLastReject] = reject;
          }
        },
        writable: true
      }), _Object$create));
      iterator[kLastPromise] = null;
      finished(stream, function (err) {
        if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
          var reject = iterator[kLastReject];
          // reject if we are waiting for data in the Promise
          // returned by next() and store the error
          if (reject !== null) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            reject(err);
          }
          iterator[kError] = err;
          return;
        }
        var resolve = iterator[kLastResolve];
        if (resolve !== null) {
          iterator[kLastPromise] = null;
          iterator[kLastResolve] = null;
          iterator[kLastReject] = null;
          resolve(createIterResult(undefined, true));
        }
        iterator[kEnded] = true;
      });
      stream.on('readable', onReadable.bind(null, iterator));
      return iterator;
    };
    module.exports = createReadableStreamAsyncIterator;
    }).call(this)}).call(this,require('_process'))
    
    },{"./end-of-stream":161,"_process":321}],159:[function(require,module,exports){
    arguments[4][73][0].apply(exports,arguments)
    },{"buffer":84,"dup":73,"util":36}],160:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    // undocumented cb() API, needed for core, not for public API
    function destroy(err, cb) {
      var _this = this;
      var readableDestroyed = this._readableState && this._readableState.destroyed;
      var writableDestroyed = this._writableState && this._writableState.destroyed;
      if (readableDestroyed || writableDestroyed) {
        if (cb) {
          cb(err);
        } else if (err) {
          if (!this._writableState) {
            process.nextTick(emitErrorNT, this, err);
          } else if (!this._writableState.errorEmitted) {
            this._writableState.errorEmitted = true;
            process.nextTick(emitErrorNT, this, err);
          }
        }
        return this;
      }
    
      // we set destroyed to true before firing error callbacks in order
      // to make it re-entrance safe in case destroy() is called within callbacks
    
      if (this._readableState) {
        this._readableState.destroyed = true;
      }
    
      // if this is a duplex stream mark the writable part as destroyed as well
      if (this._writableState) {
        this._writableState.destroyed = true;
      }
      this._destroy(err || null, function (err) {
        if (!cb && err) {
          if (!_this._writableState) {
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else if (!_this._writableState.errorEmitted) {
            _this._writableState.errorEmitted = true;
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else {
            process.nextTick(emitCloseNT, _this);
          }
        } else if (cb) {
          process.nextTick(emitCloseNT, _this);
          cb(err);
        } else {
          process.nextTick(emitCloseNT, _this);
        }
      });
      return this;
    }
    function emitErrorAndCloseNT(self, err) {
      emitErrorNT(self, err);
      emitCloseNT(self);
    }
    function emitCloseNT(self) {
      if (self._writableState && !self._writableState.emitClose) return;
      if (self._readableState && !self._readableState.emitClose) return;
      self.emit('close');
    }
    function undestroy() {
      if (this._readableState) {
        this._readableState.destroyed = false;
        this._readableState.reading = false;
        this._readableState.ended = false;
        this._readableState.endEmitted = false;
      }
      if (this._writableState) {
        this._writableState.destroyed = false;
        this._writableState.ended = false;
        this._writableState.ending = false;
        this._writableState.finalCalled = false;
        this._writableState.prefinished = false;
        this._writableState.finished = false;
        this._writableState.errorEmitted = false;
      }
    }
    function emitErrorNT(self, err) {
      self.emit('error', err);
    }
    function errorOrDestroy(stream, err) {
      // We have tests that rely on errors being emitted
      // in the same tick, so changing this is semver major.
      // For now when you opt-in to autoDestroy we allow
      // the error to be emitted nextTick. In a future
      // semver major update we should change the default to this.
    
      var rState = stream._readableState;
      var wState = stream._writableState;
      if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
    }
    module.exports = {
      destroy: destroy,
      undestroy: undestroy,
      errorOrDestroy: errorOrDestroy
    };
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321}],161:[function(require,module,exports){
    arguments[4][75][0].apply(exports,arguments)
    },{"../../../errors":152,"dup":75}],162:[function(require,module,exports){
    arguments[4][76][0].apply(exports,arguments)
    },{"dup":76}],163:[function(require,module,exports){
    arguments[4][77][0].apply(exports,arguments)
    },{"../../../errors":152,"./end-of-stream":161,"dup":77}],164:[function(require,module,exports){
    arguments[4][78][0].apply(exports,arguments)
    },{"../../../errors":152,"dup":78}],165:[function(require,module,exports){
    arguments[4][79][0].apply(exports,arguments)
    },{"dup":79,"events":134}],166:[function(require,module,exports){
    arguments[4][80][0].apply(exports,arguments)
    },{"./lib/_stream_duplex.js":153,"./lib/_stream_passthrough.js":154,"./lib/_stream_readable.js":155,"./lib/_stream_transform.js":156,"./lib/_stream_writable.js":157,"./lib/internal/streams/end-of-stream.js":161,"./lib/internal/streams/pipeline.js":163,"dup":80}],167:[function(require,module,exports){
    var hash = exports;
    
    hash.utils = require('./hash/utils');
    hash.common = require('./hash/common');
    hash.sha = require('./hash/sha');
    hash.ripemd = require('./hash/ripemd');
    hash.hmac = require('./hash/hmac');
    
    // Proxy hash functions to the main object
    hash.sha1 = hash.sha.sha1;
    hash.sha256 = hash.sha.sha256;
    hash.sha224 = hash.sha.sha224;
    hash.sha384 = hash.sha.sha384;
    hash.sha512 = hash.sha.sha512;
    hash.ripemd160 = hash.ripemd.ripemd160;
    
    },{"./hash/common":168,"./hash/hmac":169,"./hash/ripemd":170,"./hash/sha":171,"./hash/utils":178}],168:[function(require,module,exports){
    'use strict';
    
    var utils = require('./utils');
    var assert = require('minimalistic-assert');
    
    function BlockHash() {
      this.pending = null;
      this.pendingTotal = 0;
      this.blockSize = this.constructor.blockSize;
      this.outSize = this.constructor.outSize;
      this.hmacStrength = this.constructor.hmacStrength;
      this.padLength = this.constructor.padLength / 8;
      this.endian = 'big';
    
      this._delta8 = this.blockSize / 8;
      this._delta32 = this.blockSize / 32;
    }
    exports.BlockHash = BlockHash;
    
    BlockHash.prototype.update = function update(msg, enc) {
      // Convert message to array, pad it, and join into 32bit blocks
      msg = utils.toArray(msg, enc);
      if (!this.pending)
        this.pending = msg;
      else
        this.pending = this.pending.concat(msg);
      this.pendingTotal += msg.length;
    
      // Enough data, try updating
      if (this.pending.length >= this._delta8) {
        msg = this.pending;
    
        // Process pending data in blocks
        var r = msg.length % this._delta8;
        this.pending = msg.slice(msg.length - r, msg.length);
        if (this.pending.length === 0)
          this.pending = null;
    
        msg = utils.join32(msg, 0, msg.length - r, this.endian);
        for (var i = 0; i < msg.length; i += this._delta32)
          this._update(msg, i, i + this._delta32);
      }
    
      return this;
    };
    
    BlockHash.prototype.digest = function digest(enc) {
      this.update(this._pad());
      assert(this.pending === null);
    
      return this._digest(enc);
    };
    
    BlockHash.prototype._pad = function pad() {
      var len = this.pendingTotal;
      var bytes = this._delta8;
      var k = bytes - ((len + this.padLength) % bytes);
      var res = new Array(k + this.padLength);
      res[0] = 0x80;
      for (var i = 1; i < k; i++)
        res[i] = 0;
    
      // Append length
      len <<= 3;
      if (this.endian === 'big') {
        for (var t = 8; t < this.padLength; t++)
          res[i++] = 0;
    
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = (len >>> 24) & 0xff;
        res[i++] = (len >>> 16) & 0xff;
        res[i++] = (len >>> 8) & 0xff;
        res[i++] = len & 0xff;
      } else {
        res[i++] = len & 0xff;
        res[i++] = (len >>> 8) & 0xff;
        res[i++] = (len >>> 16) & 0xff;
        res[i++] = (len >>> 24) & 0xff;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
        res[i++] = 0;
    
        for (t = 8; t < this.padLength; t++)
          res[i++] = 0;
      }
    
      return res;
    };
    
    },{"./utils":178,"minimalistic-assert":194}],169:[function(require,module,exports){
    'use strict';
    
    var utils = require('./utils');
    var assert = require('minimalistic-assert');
    
    function Hmac(hash, key, enc) {
      if (!(this instanceof Hmac))
        return new Hmac(hash, key, enc);
      this.Hash = hash;
      this.blockSize = hash.blockSize / 8;
      this.outSize = hash.outSize / 8;
      this.inner = null;
      this.outer = null;
    
      this._init(utils.toArray(key, enc));
    }
    module.exports = Hmac;
    
    Hmac.prototype._init = function init(key) {
      // Shorten key, if needed
      if (key.length > this.blockSize)
        key = new this.Hash().update(key).digest();
      assert(key.length <= this.blockSize);
    
      // Add padding to key
      for (var i = key.length; i < this.blockSize; i++)
        key.push(0);
    
      for (i = 0; i < key.length; i++)
        key[i] ^= 0x36;
      this.inner = new this.Hash().update(key);
    
      // 0x36 ^ 0x5c = 0x6a
      for (i = 0; i < key.length; i++)
        key[i] ^= 0x6a;
      this.outer = new this.Hash().update(key);
    };
    
    Hmac.prototype.update = function update(msg, enc) {
      this.inner.update(msg, enc);
      return this;
    };
    
    Hmac.prototype.digest = function digest(enc) {
      this.outer.update(this.inner.digest());
      return this.outer.digest(enc);
    };
    
    },{"./utils":178,"minimalistic-assert":194}],170:[function(require,module,exports){
    'use strict';
    
    var utils = require('./utils');
    var common = require('./common');
    
    var rotl32 = utils.rotl32;
    var sum32 = utils.sum32;
    var sum32_3 = utils.sum32_3;
    var sum32_4 = utils.sum32_4;
    var BlockHash = common.BlockHash;
    
    function RIPEMD160() {
      if (!(this instanceof RIPEMD160))
        return new RIPEMD160();
    
      BlockHash.call(this);
    
      this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
      this.endian = 'little';
    }
    utils.inherits(RIPEMD160, BlockHash);
    exports.ripemd160 = RIPEMD160;
    
    RIPEMD160.blockSize = 512;
    RIPEMD160.outSize = 160;
    RIPEMD160.hmacStrength = 192;
    RIPEMD160.padLength = 64;
    
    RIPEMD160.prototype._update = function update(msg, start) {
      var A = this.h[0];
      var B = this.h[1];
      var C = this.h[2];
      var D = this.h[3];
      var E = this.h[4];
      var Ah = A;
      var Bh = B;
      var Ch = C;
      var Dh = D;
      var Eh = E;
      for (var j = 0; j < 80; j++) {
        var T = sum32(
          rotl32(
            sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
            s[j]),
          E);
        A = E;
        E = D;
        D = rotl32(C, 10);
        C = B;
        B = T;
        T = sum32(
          rotl32(
            sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
            sh[j]),
          Eh);
        Ah = Eh;
        Eh = Dh;
        Dh = rotl32(Ch, 10);
        Ch = Bh;
        Bh = T;
      }
      T = sum32_3(this.h[1], C, Dh);
      this.h[1] = sum32_3(this.h[2], D, Eh);
      this.h[2] = sum32_3(this.h[3], E, Ah);
      this.h[3] = sum32_3(this.h[4], A, Bh);
      this.h[4] = sum32_3(this.h[0], B, Ch);
      this.h[0] = T;
    };
    
    RIPEMD160.prototype._digest = function digest(enc) {
      if (enc === 'hex')
        return utils.toHex32(this.h, 'little');
      else
        return utils.split32(this.h, 'little');
    };
    
    function f(j, x, y, z) {
      if (j <= 15)
        return x ^ y ^ z;
      else if (j <= 31)
        return (x & y) | ((~x) & z);
      else if (j <= 47)
        return (x | (~y)) ^ z;
      else if (j <= 63)
        return (x & z) | (y & (~z));
      else
        return x ^ (y | (~z));
    }
    
    function K(j) {
      if (j <= 15)
        return 0x00000000;
      else if (j <= 31)
        return 0x5a827999;
      else if (j <= 47)
        return 0x6ed9eba1;
      else if (j <= 63)
        return 0x8f1bbcdc;
      else
        return 0xa953fd4e;
    }
    
    function Kh(j) {
      if (j <= 15)
        return 0x50a28be6;
      else if (j <= 31)
        return 0x5c4dd124;
      else if (j <= 47)
        return 0x6d703ef3;
      else if (j <= 63)
        return 0x7a6d76e9;
      else
        return 0x00000000;
    }
    
    var r = [
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
      7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
      3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
      1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
      4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
    ];
    
    var rh = [
      5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
      6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
      15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
      8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
      12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
    ];
    
    var s = [
      11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
      7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
      11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
      11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
      9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
    ];
    
    var sh = [
      8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
      9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
      9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
      15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
      8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
    ];
    
    },{"./common":168,"./utils":178}],171:[function(require,module,exports){
    'use strict';
    
    exports.sha1 = require('./sha/1');
    exports.sha224 = require('./sha/224');
    exports.sha256 = require('./sha/256');
    exports.sha384 = require('./sha/384');
    exports.sha512 = require('./sha/512');
    
    },{"./sha/1":172,"./sha/224":173,"./sha/256":174,"./sha/384":175,"./sha/512":176}],172:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var common = require('../common');
    var shaCommon = require('./common');
    
    var rotl32 = utils.rotl32;
    var sum32 = utils.sum32;
    var sum32_5 = utils.sum32_5;
    var ft_1 = shaCommon.ft_1;
    var BlockHash = common.BlockHash;
    
    var sha1_K = [
      0x5A827999, 0x6ED9EBA1,
      0x8F1BBCDC, 0xCA62C1D6
    ];
    
    function SHA1() {
      if (!(this instanceof SHA1))
        return new SHA1();
    
      BlockHash.call(this);
      this.h = [
        0x67452301, 0xefcdab89, 0x98badcfe,
        0x10325476, 0xc3d2e1f0 ];
      this.W = new Array(80);
    }
    
    utils.inherits(SHA1, BlockHash);
    module.exports = SHA1;
    
    SHA1.blockSize = 512;
    SHA1.outSize = 160;
    SHA1.hmacStrength = 80;
    SHA1.padLength = 64;
    
    SHA1.prototype._update = function _update(msg, start) {
      var W = this.W;
    
      for (var i = 0; i < 16; i++)
        W[i] = msg[start + i];
    
      for(; i < W.length; i++)
        W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
    
      var a = this.h[0];
      var b = this.h[1];
      var c = this.h[2];
      var d = this.h[3];
      var e = this.h[4];
    
      for (i = 0; i < W.length; i++) {
        var s = ~~(i / 20);
        var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
        e = d;
        d = c;
        c = rotl32(b, 30);
        b = a;
        a = t;
      }
    
      this.h[0] = sum32(this.h[0], a);
      this.h[1] = sum32(this.h[1], b);
      this.h[2] = sum32(this.h[2], c);
      this.h[3] = sum32(this.h[3], d);
      this.h[4] = sum32(this.h[4], e);
    };
    
    SHA1.prototype._digest = function digest(enc) {
      if (enc === 'hex')
        return utils.toHex32(this.h, 'big');
      else
        return utils.split32(this.h, 'big');
    };
    
    },{"../common":168,"../utils":178,"./common":177}],173:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var SHA256 = require('./256');
    
    function SHA224() {
      if (!(this instanceof SHA224))
        return new SHA224();
    
      SHA256.call(this);
      this.h = [
        0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
        0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
    }
    utils.inherits(SHA224, SHA256);
    module.exports = SHA224;
    
    SHA224.blockSize = 512;
    SHA224.outSize = 224;
    SHA224.hmacStrength = 192;
    SHA224.padLength = 64;
    
    SHA224.prototype._digest = function digest(enc) {
      // Just truncate output
      if (enc === 'hex')
        return utils.toHex32(this.h.slice(0, 7), 'big');
      else
        return utils.split32(this.h.slice(0, 7), 'big');
    };
    
    
    },{"../utils":178,"./256":174}],174:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var common = require('../common');
    var shaCommon = require('./common');
    var assert = require('minimalistic-assert');
    
    var sum32 = utils.sum32;
    var sum32_4 = utils.sum32_4;
    var sum32_5 = utils.sum32_5;
    var ch32 = shaCommon.ch32;
    var maj32 = shaCommon.maj32;
    var s0_256 = shaCommon.s0_256;
    var s1_256 = shaCommon.s1_256;
    var g0_256 = shaCommon.g0_256;
    var g1_256 = shaCommon.g1_256;
    
    var BlockHash = common.BlockHash;
    
    var sha256_K = [
      0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
      0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
      0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
      0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
      0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
      0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
      0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
      0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
      0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
      0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
      0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
      0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
      0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
      0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
      0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
      0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
    ];
    
    function SHA256() {
      if (!(this instanceof SHA256))
        return new SHA256();
    
      BlockHash.call(this);
      this.h = [
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
        0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
      ];
      this.k = sha256_K;
      this.W = new Array(64);
    }
    utils.inherits(SHA256, BlockHash);
    module.exports = SHA256;
    
    SHA256.blockSize = 512;
    SHA256.outSize = 256;
    SHA256.hmacStrength = 192;
    SHA256.padLength = 64;
    
    SHA256.prototype._update = function _update(msg, start) {
      var W = this.W;
    
      for (var i = 0; i < 16; i++)
        W[i] = msg[start + i];
      for (; i < W.length; i++)
        W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
    
      var a = this.h[0];
      var b = this.h[1];
      var c = this.h[2];
      var d = this.h[3];
      var e = this.h[4];
      var f = this.h[5];
      var g = this.h[6];
      var h = this.h[7];
    
      assert(this.k.length === W.length);
      for (i = 0; i < W.length; i++) {
        var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
        var T2 = sum32(s0_256(a), maj32(a, b, c));
        h = g;
        g = f;
        f = e;
        e = sum32(d, T1);
        d = c;
        c = b;
        b = a;
        a = sum32(T1, T2);
      }
    
      this.h[0] = sum32(this.h[0], a);
      this.h[1] = sum32(this.h[1], b);
      this.h[2] = sum32(this.h[2], c);
      this.h[3] = sum32(this.h[3], d);
      this.h[4] = sum32(this.h[4], e);
      this.h[5] = sum32(this.h[5], f);
      this.h[6] = sum32(this.h[6], g);
      this.h[7] = sum32(this.h[7], h);
    };
    
    SHA256.prototype._digest = function digest(enc) {
      if (enc === 'hex')
        return utils.toHex32(this.h, 'big');
      else
        return utils.split32(this.h, 'big');
    };
    
    },{"../common":168,"../utils":178,"./common":177,"minimalistic-assert":194}],175:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    
    var SHA512 = require('./512');
    
    function SHA384() {
      if (!(this instanceof SHA384))
        return new SHA384();
    
      SHA512.call(this);
      this.h = [
        0xcbbb9d5d, 0xc1059ed8,
        0x629a292a, 0x367cd507,
        0x9159015a, 0x3070dd17,
        0x152fecd8, 0xf70e5939,
        0x67332667, 0xffc00b31,
        0x8eb44a87, 0x68581511,
        0xdb0c2e0d, 0x64f98fa7,
        0x47b5481d, 0xbefa4fa4 ];
    }
    utils.inherits(SHA384, SHA512);
    module.exports = SHA384;
    
    SHA384.blockSize = 1024;
    SHA384.outSize = 384;
    SHA384.hmacStrength = 192;
    SHA384.padLength = 128;
    
    SHA384.prototype._digest = function digest(enc) {
      if (enc === 'hex')
        return utils.toHex32(this.h.slice(0, 12), 'big');
      else
        return utils.split32(this.h.slice(0, 12), 'big');
    };
    
    },{"../utils":178,"./512":176}],176:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var common = require('../common');
    var assert = require('minimalistic-assert');
    
    var rotr64_hi = utils.rotr64_hi;
    var rotr64_lo = utils.rotr64_lo;
    var shr64_hi = utils.shr64_hi;
    var shr64_lo = utils.shr64_lo;
    var sum64 = utils.sum64;
    var sum64_hi = utils.sum64_hi;
    var sum64_lo = utils.sum64_lo;
    var sum64_4_hi = utils.sum64_4_hi;
    var sum64_4_lo = utils.sum64_4_lo;
    var sum64_5_hi = utils.sum64_5_hi;
    var sum64_5_lo = utils.sum64_5_lo;
    
    var BlockHash = common.BlockHash;
    
    var sha512_K = [
      0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
      0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
      0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
      0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
      0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
      0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
      0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
      0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
      0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
      0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
      0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
      0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
      0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
      0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
      0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
      0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
      0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
      0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
      0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
      0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
      0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
      0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
      0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
      0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
      0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
      0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
      0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
      0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
      0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
      0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
      0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
      0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
      0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
      0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
      0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
      0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
      0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
      0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
      0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
      0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
    ];
    
    function SHA512() {
      if (!(this instanceof SHA512))
        return new SHA512();
    
      BlockHash.call(this);
      this.h = [
        0x6a09e667, 0xf3bcc908,
        0xbb67ae85, 0x84caa73b,
        0x3c6ef372, 0xfe94f82b,
        0xa54ff53a, 0x5f1d36f1,
        0x510e527f, 0xade682d1,
        0x9b05688c, 0x2b3e6c1f,
        0x1f83d9ab, 0xfb41bd6b,
        0x5be0cd19, 0x137e2179 ];
      this.k = sha512_K;
      this.W = new Array(160);
    }
    utils.inherits(SHA512, BlockHash);
    module.exports = SHA512;
    
    SHA512.blockSize = 1024;
    SHA512.outSize = 512;
    SHA512.hmacStrength = 192;
    SHA512.padLength = 128;
    
    SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
      var W = this.W;
    
      // 32 x 32bit words
      for (var i = 0; i < 32; i++)
        W[i] = msg[start + i];
      for (; i < W.length; i += 2) {
        var c0_hi = g1_512_hi(W[i - 4], W[i - 3]);  // i - 2
        var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
        var c1_hi = W[i - 14];  // i - 7
        var c1_lo = W[i - 13];
        var c2_hi = g0_512_hi(W[i - 30], W[i - 29]);  // i - 15
        var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
        var c3_hi = W[i - 32];  // i - 16
        var c3_lo = W[i - 31];
    
        W[i] = sum64_4_hi(
          c0_hi, c0_lo,
          c1_hi, c1_lo,
          c2_hi, c2_lo,
          c3_hi, c3_lo);
        W[i + 1] = sum64_4_lo(
          c0_hi, c0_lo,
          c1_hi, c1_lo,
          c2_hi, c2_lo,
          c3_hi, c3_lo);
      }
    };
    
    SHA512.prototype._update = function _update(msg, start) {
      this._prepareBlock(msg, start);
    
      var W = this.W;
    
      var ah = this.h[0];
      var al = this.h[1];
      var bh = this.h[2];
      var bl = this.h[3];
      var ch = this.h[4];
      var cl = this.h[5];
      var dh = this.h[6];
      var dl = this.h[7];
      var eh = this.h[8];
      var el = this.h[9];
      var fh = this.h[10];
      var fl = this.h[11];
      var gh = this.h[12];
      var gl = this.h[13];
      var hh = this.h[14];
      var hl = this.h[15];
    
      assert(this.k.length === W.length);
      for (var i = 0; i < W.length; i += 2) {
        var c0_hi = hh;
        var c0_lo = hl;
        var c1_hi = s1_512_hi(eh, el);
        var c1_lo = s1_512_lo(eh, el);
        var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
        var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
        var c3_hi = this.k[i];
        var c3_lo = this.k[i + 1];
        var c4_hi = W[i];
        var c4_lo = W[i + 1];
    
        var T1_hi = sum64_5_hi(
          c0_hi, c0_lo,
          c1_hi, c1_lo,
          c2_hi, c2_lo,
          c3_hi, c3_lo,
          c4_hi, c4_lo);
        var T1_lo = sum64_5_lo(
          c0_hi, c0_lo,
          c1_hi, c1_lo,
          c2_hi, c2_lo,
          c3_hi, c3_lo,
          c4_hi, c4_lo);
    
        c0_hi = s0_512_hi(ah, al);
        c0_lo = s0_512_lo(ah, al);
        c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
        c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
    
        var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
        var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
    
        hh = gh;
        hl = gl;
    
        gh = fh;
        gl = fl;
    
        fh = eh;
        fl = el;
    
        eh = sum64_hi(dh, dl, T1_hi, T1_lo);
        el = sum64_lo(dl, dl, T1_hi, T1_lo);
    
        dh = ch;
        dl = cl;
    
        ch = bh;
        cl = bl;
    
        bh = ah;
        bl = al;
    
        ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
        al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
      }
    
      sum64(this.h, 0, ah, al);
      sum64(this.h, 2, bh, bl);
      sum64(this.h, 4, ch, cl);
      sum64(this.h, 6, dh, dl);
      sum64(this.h, 8, eh, el);
      sum64(this.h, 10, fh, fl);
      sum64(this.h, 12, gh, gl);
      sum64(this.h, 14, hh, hl);
    };
    
    SHA512.prototype._digest = function digest(enc) {
      if (enc === 'hex')
        return utils.toHex32(this.h, 'big');
      else
        return utils.split32(this.h, 'big');
    };
    
    function ch64_hi(xh, xl, yh, yl, zh) {
      var r = (xh & yh) ^ ((~xh) & zh);
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function ch64_lo(xh, xl, yh, yl, zh, zl) {
      var r = (xl & yl) ^ ((~xl) & zl);
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function maj64_hi(xh, xl, yh, yl, zh) {
      var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function maj64_lo(xh, xl, yh, yl, zh, zl) {
      var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function s0_512_hi(xh, xl) {
      var c0_hi = rotr64_hi(xh, xl, 28);
      var c1_hi = rotr64_hi(xl, xh, 2);  // 34
      var c2_hi = rotr64_hi(xl, xh, 7);  // 39
    
      var r = c0_hi ^ c1_hi ^ c2_hi;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function s0_512_lo(xh, xl) {
      var c0_lo = rotr64_lo(xh, xl, 28);
      var c1_lo = rotr64_lo(xl, xh, 2);  // 34
      var c2_lo = rotr64_lo(xl, xh, 7);  // 39
    
      var r = c0_lo ^ c1_lo ^ c2_lo;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function s1_512_hi(xh, xl) {
      var c0_hi = rotr64_hi(xh, xl, 14);
      var c1_hi = rotr64_hi(xh, xl, 18);
      var c2_hi = rotr64_hi(xl, xh, 9);  // 41
    
      var r = c0_hi ^ c1_hi ^ c2_hi;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function s1_512_lo(xh, xl) {
      var c0_lo = rotr64_lo(xh, xl, 14);
      var c1_lo = rotr64_lo(xh, xl, 18);
      var c2_lo = rotr64_lo(xl, xh, 9);  // 41
    
      var r = c0_lo ^ c1_lo ^ c2_lo;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function g0_512_hi(xh, xl) {
      var c0_hi = rotr64_hi(xh, xl, 1);
      var c1_hi = rotr64_hi(xh, xl, 8);
      var c2_hi = shr64_hi(xh, xl, 7);
    
      var r = c0_hi ^ c1_hi ^ c2_hi;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function g0_512_lo(xh, xl) {
      var c0_lo = rotr64_lo(xh, xl, 1);
      var c1_lo = rotr64_lo(xh, xl, 8);
      var c2_lo = shr64_lo(xh, xl, 7);
    
      var r = c0_lo ^ c1_lo ^ c2_lo;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function g1_512_hi(xh, xl) {
      var c0_hi = rotr64_hi(xh, xl, 19);
      var c1_hi = rotr64_hi(xl, xh, 29);  // 61
      var c2_hi = shr64_hi(xh, xl, 6);
    
      var r = c0_hi ^ c1_hi ^ c2_hi;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    function g1_512_lo(xh, xl) {
      var c0_lo = rotr64_lo(xh, xl, 19);
      var c1_lo = rotr64_lo(xl, xh, 29);  // 61
      var c2_lo = shr64_lo(xh, xl, 6);
    
      var r = c0_lo ^ c1_lo ^ c2_lo;
      if (r < 0)
        r += 0x100000000;
      return r;
    }
    
    },{"../common":168,"../utils":178,"minimalistic-assert":194}],177:[function(require,module,exports){
    'use strict';
    
    var utils = require('../utils');
    var rotr32 = utils.rotr32;
    
    function ft_1(s, x, y, z) {
      if (s === 0)
        return ch32(x, y, z);
      if (s === 1 || s === 3)
        return p32(x, y, z);
      if (s === 2)
        return maj32(x, y, z);
    }
    exports.ft_1 = ft_1;
    
    function ch32(x, y, z) {
      return (x & y) ^ ((~x) & z);
    }
    exports.ch32 = ch32;
    
    function maj32(x, y, z) {
      return (x & y) ^ (x & z) ^ (y & z);
    }
    exports.maj32 = maj32;
    
    function p32(x, y, z) {
      return x ^ y ^ z;
    }
    exports.p32 = p32;
    
    function s0_256(x) {
      return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
    }
    exports.s0_256 = s0_256;
    
    function s1_256(x) {
      return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
    }
    exports.s1_256 = s1_256;
    
    function g0_256(x) {
      return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
    }
    exports.g0_256 = g0_256;
    
    function g1_256(x) {
      return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
    }
    exports.g1_256 = g1_256;
    
    },{"../utils":178}],178:[function(require,module,exports){
    'use strict';
    
    var assert = require('minimalistic-assert');
    var inherits = require('inherits');
    
    exports.inherits = inherits;
    
    function isSurrogatePair(msg, i) {
      if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {
        return false;
      }
      if (i < 0 || i + 1 >= msg.length) {
        return false;
      }
      return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;
    }
    
    function toArray(msg, enc) {
      if (Array.isArray(msg))
        return msg.slice();
      if (!msg)
        return [];
      var res = [];
      if (typeof msg === 'string') {
        if (!enc) {
          // Inspired by stringToUtf8ByteArray() in closure-library by Google
          // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
          // Apache License 2.0
          // https://github.com/google/closure-library/blob/master/LICENSE
          var p = 0;
          for (var i = 0; i < msg.length; i++) {
            var c = msg.charCodeAt(i);
            if (c < 128) {
              res[p++] = c;
            } else if (c < 2048) {
              res[p++] = (c >> 6) | 192;
              res[p++] = (c & 63) | 128;
            } else if (isSurrogatePair(msg, i)) {
              c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);
              res[p++] = (c >> 18) | 240;
              res[p++] = ((c >> 12) & 63) | 128;
              res[p++] = ((c >> 6) & 63) | 128;
              res[p++] = (c & 63) | 128;
            } else {
              res[p++] = (c >> 12) | 224;
              res[p++] = ((c >> 6) & 63) | 128;
              res[p++] = (c & 63) | 128;
            }
          }
        } else if (enc === 'hex') {
          msg = msg.replace(/[^a-z0-9]+/ig, '');
          if (msg.length % 2 !== 0)
            msg = '0' + msg;
          for (i = 0; i < msg.length; i += 2)
            res.push(parseInt(msg[i] + msg[i + 1], 16));
        }
      } else {
        for (i = 0; i < msg.length; i++)
          res[i] = msg[i] | 0;
      }
      return res;
    }
    exports.toArray = toArray;
    
    function toHex(msg) {
      var res = '';
      for (var i = 0; i < msg.length; i++)
        res += zero2(msg[i].toString(16));
      return res;
    }
    exports.toHex = toHex;
    
    function htonl(w) {
      var res = (w >>> 24) |
                ((w >>> 8) & 0xff00) |
                ((w << 8) & 0xff0000) |
                ((w & 0xff) << 24);
      return res >>> 0;
    }
    exports.htonl = htonl;
    
    function toHex32(msg, endian) {
      var res = '';
      for (var i = 0; i < msg.length; i++) {
        var w = msg[i];
        if (endian === 'little')
          w = htonl(w);
        res += zero8(w.toString(16));
      }
      return res;
    }
    exports.toHex32 = toHex32;
    
    function zero2(word) {
      if (word.length === 1)
        return '0' + word;
      else
        return word;
    }
    exports.zero2 = zero2;
    
    function zero8(word) {
      if (word.length === 7)
        return '0' + word;
      else if (word.length === 6)
        return '00' + word;
      else if (word.length === 5)
        return '000' + word;
      else if (word.length === 4)
        return '0000' + word;
      else if (word.length === 3)
        return '00000' + word;
      else if (word.length === 2)
        return '000000' + word;
      else if (word.length === 1)
        return '0000000' + word;
      else
        return word;
    }
    exports.zero8 = zero8;
    
    function join32(msg, start, end, endian) {
      var len = end - start;
      assert(len % 4 === 0);
      var res = new Array(len / 4);
      for (var i = 0, k = start; i < res.length; i++, k += 4) {
        var w;
        if (endian === 'big')
          w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
        else
          w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
        res[i] = w >>> 0;
      }
      return res;
    }
    exports.join32 = join32;
    
    function split32(msg, endian) {
      var res = new Array(msg.length * 4);
      for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
        var m = msg[i];
        if (endian === 'big') {
          res[k] = m >>> 24;
          res[k + 1] = (m >>> 16) & 0xff;
          res[k + 2] = (m >>> 8) & 0xff;
          res[k + 3] = m & 0xff;
        } else {
          res[k + 3] = m >>> 24;
          res[k + 2] = (m >>> 16) & 0xff;
          res[k + 1] = (m >>> 8) & 0xff;
          res[k] = m & 0xff;
        }
      }
      return res;
    }
    exports.split32 = split32;
    
    function rotr32(w, b) {
      return (w >>> b) | (w << (32 - b));
    }
    exports.rotr32 = rotr32;
    
    function rotl32(w, b) {
      return (w << b) | (w >>> (32 - b));
    }
    exports.rotl32 = rotl32;
    
    function sum32(a, b) {
      return (a + b) >>> 0;
    }
    exports.sum32 = sum32;
    
    function sum32_3(a, b, c) {
      return (a + b + c) >>> 0;
    }
    exports.sum32_3 = sum32_3;
    
    function sum32_4(a, b, c, d) {
      return (a + b + c + d) >>> 0;
    }
    exports.sum32_4 = sum32_4;
    
    function sum32_5(a, b, c, d, e) {
      return (a + b + c + d + e) >>> 0;
    }
    exports.sum32_5 = sum32_5;
    
    function sum64(buf, pos, ah, al) {
      var bh = buf[pos];
      var bl = buf[pos + 1];
    
      var lo = (al + bl) >>> 0;
      var hi = (lo < al ? 1 : 0) + ah + bh;
      buf[pos] = hi >>> 0;
      buf[pos + 1] = lo;
    }
    exports.sum64 = sum64;
    
    function sum64_hi(ah, al, bh, bl) {
      var lo = (al + bl) >>> 0;
      var hi = (lo < al ? 1 : 0) + ah + bh;
      return hi >>> 0;
    }
    exports.sum64_hi = sum64_hi;
    
    function sum64_lo(ah, al, bh, bl) {
      var lo = al + bl;
      return lo >>> 0;
    }
    exports.sum64_lo = sum64_lo;
    
    function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
      var carry = 0;
      var lo = al;
      lo = (lo + bl) >>> 0;
      carry += lo < al ? 1 : 0;
      lo = (lo + cl) >>> 0;
      carry += lo < cl ? 1 : 0;
      lo = (lo + dl) >>> 0;
      carry += lo < dl ? 1 : 0;
    
      var hi = ah + bh + ch + dh + carry;
      return hi >>> 0;
    }
    exports.sum64_4_hi = sum64_4_hi;
    
    function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
      var lo = al + bl + cl + dl;
      return lo >>> 0;
    }
    exports.sum64_4_lo = sum64_4_lo;
    
    function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
      var carry = 0;
      var lo = al;
      lo = (lo + bl) >>> 0;
      carry += lo < al ? 1 : 0;
      lo = (lo + cl) >>> 0;
      carry += lo < cl ? 1 : 0;
      lo = (lo + dl) >>> 0;
      carry += lo < dl ? 1 : 0;
      lo = (lo + el) >>> 0;
      carry += lo < el ? 1 : 0;
    
      var hi = ah + bh + ch + dh + eh + carry;
      return hi >>> 0;
    }
    exports.sum64_5_hi = sum64_5_hi;
    
    function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
      var lo = al + bl + cl + dl + el;
    
      return lo >>> 0;
    }
    exports.sum64_5_lo = sum64_5_lo;
    
    function rotr64_hi(ah, al, num) {
      var r = (al << (32 - num)) | (ah >>> num);
      return r >>> 0;
    }
    exports.rotr64_hi = rotr64_hi;
    
    function rotr64_lo(ah, al, num) {
      var r = (ah << (32 - num)) | (al >>> num);
      return r >>> 0;
    }
    exports.rotr64_lo = rotr64_lo;
    
    function shr64_hi(ah, al, num) {
      return ah >>> num;
    }
    exports.shr64_hi = shr64_hi;
    
    function shr64_lo(ah, al, num) {
      var r = (ah << (32 - num)) | (al >>> num);
      return r >>> 0;
    }
    exports.shr64_lo = shr64_lo;
    
    },{"inherits":182,"minimalistic-assert":194}],179:[function(require,module,exports){
    'use strict';
    
    var hash = require('hash.js');
    var utils = require('minimalistic-crypto-utils');
    var assert = require('minimalistic-assert');
    
    function HmacDRBG(options) {
      if (!(this instanceof HmacDRBG))
        return new HmacDRBG(options);
      this.hash = options.hash;
      this.predResist = !!options.predResist;
    
      this.outLen = this.hash.outSize;
      this.minEntropy = options.minEntropy || this.hash.hmacStrength;
    
      this._reseed = null;
      this.reseedInterval = null;
      this.K = null;
      this.V = null;
    
      var entropy = utils.toArray(options.entropy, options.entropyEnc || 'hex');
      var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');
      var pers = utils.toArray(options.pers, options.persEnc || 'hex');
      assert(entropy.length >= (this.minEntropy / 8),
             'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
      this._init(entropy, nonce, pers);
    }
    module.exports = HmacDRBG;
    
    HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
      var seed = entropy.concat(nonce).concat(pers);
    
      this.K = new Array(this.outLen / 8);
      this.V = new Array(this.outLen / 8);
      for (var i = 0; i < this.V.length; i++) {
        this.K[i] = 0x00;
        this.V[i] = 0x01;
      }
    
      this._update(seed);
      this._reseed = 1;
      this.reseedInterval = 0x1000000000000;  // 2^48
    };
    
    HmacDRBG.prototype._hmac = function hmac() {
      return new hash.hmac(this.hash, this.K);
    };
    
    HmacDRBG.prototype._update = function update(seed) {
      var kmac = this._hmac()
                     .update(this.V)
                     .update([ 0x00 ]);
      if (seed)
        kmac = kmac.update(seed);
      this.K = kmac.digest();
      this.V = this._hmac().update(this.V).digest();
      if (!seed)
        return;
    
      this.K = this._hmac()
                   .update(this.V)
                   .update([ 0x01 ])
                   .update(seed)
                   .digest();
      this.V = this._hmac().update(this.V).digest();
    };
    
    HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
      // Optional entropy enc
      if (typeof entropyEnc !== 'string') {
        addEnc = add;
        add = entropyEnc;
        entropyEnc = null;
      }
    
      entropy = utils.toArray(entropy, entropyEnc);
      add = utils.toArray(add, addEnc);
    
      assert(entropy.length >= (this.minEntropy / 8),
             'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
    
      this._update(entropy.concat(add || []));
      this._reseed = 1;
    };
    
    HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
      if (this._reseed > this.reseedInterval)
        throw new Error('Reseed is required');
    
      // Optional encoding
      if (typeof enc !== 'string') {
        addEnc = add;
        add = enc;
        enc = null;
      }
    
      // Optional additional data
      if (add) {
        add = utils.toArray(add, addEnc || 'hex');
        this._update(add);
      }
    
      var temp = [];
      while (temp.length < len) {
        this.V = this._hmac().update(this.V).digest();
        temp = temp.concat(this.V);
      }
    
      var res = temp.slice(0, len);
      this._update(add);
      this._reseed++;
      return utils.encode(res, enc);
    };
    
    },{"hash.js":167,"minimalistic-assert":194,"minimalistic-crypto-utils":195}],180:[function(require,module,exports){
    /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
    exports.read = function (buffer, offset, isLE, mLen, nBytes) {
      var e, m
      var eLen = (nBytes * 8) - mLen - 1
      var eMax = (1 << eLen) - 1
      var eBias = eMax >> 1
      var nBits = -7
      var i = isLE ? (nBytes - 1) : 0
      var d = isLE ? -1 : 1
      var s = buffer[offset + i]
    
      i += d
    
      e = s & ((1 << (-nBits)) - 1)
      s >>= (-nBits)
      nBits += eLen
      for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
    
      m = e & ((1 << (-nBits)) - 1)
      e >>= (-nBits)
      nBits += mLen
      for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
    
      if (e === 0) {
        e = 1 - eBias
      } else if (e === eMax) {
        return m ? NaN : ((s ? -1 : 1) * Infinity)
      } else {
        m = m + Math.pow(2, mLen)
        e = e - eBias
      }
      return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
    }
    
    exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
      var e, m, c
      var eLen = (nBytes * 8) - mLen - 1
      var eMax = (1 << eLen) - 1
      var eBias = eMax >> 1
      var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
      var i = isLE ? 0 : (nBytes - 1)
      var d = isLE ? 1 : -1
      var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
    
      value = Math.abs(value)
    
      if (isNaN(value) || value === Infinity) {
        m = isNaN(value) ? 1 : 0
        e = eMax
      } else {
        e = Math.floor(Math.log(value) / Math.LN2)
        if (value * (c = Math.pow(2, -e)) < 1) {
          e--
          c *= 2
        }
        if (e + eBias >= 1) {
          value += rt / c
        } else {
          value += rt * Math.pow(2, 1 - eBias)
        }
        if (value * c >= 2) {
          e++
          c /= 2
        }
    
        if (e + eBias >= eMax) {
          m = 0
          e = eMax
        } else if (e + eBias >= 1) {
          m = ((value * c) - 1) * Math.pow(2, mLen)
          e = e + eBias
        } else {
          m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
          e = 0
        }
      }
    
      for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
    
      e = (e << mLen) | m
      eLen += mLen
      for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
    
      buffer[offset + i - d] |= s * 128
    }
    
    },{}],181:[function(require,module,exports){
    (function (process){(function (){
    var wrappy = require('wrappy')
    var reqs = Object.create(null)
    var once = require('once')
    
    module.exports = wrappy(inflight)
    
    function inflight (key, cb) {
      if (reqs[key]) {
        reqs[key].push(cb)
        return null
      } else {
        reqs[key] = [cb]
        return makeres(key)
      }
    }
    
    function makeres (key) {
      return once(function RES () {
        var cbs = reqs[key]
        var len = cbs.length
        var args = slice(arguments)
    
        // XXX It's somewhat ambiguous whether a new callback added in this
        // pass should be queued for later execution if something in the
        // list of callbacks throws, or if it should just be discarded.
        // However, it's such an edge case that it hardly matters, and either
        // choice is likely as surprising as the other.
        // As it happens, we do go ahead and schedule it for later execution.
        try {
          for (var i = 0; i < len; i++) {
            cbs[i].apply(null, args)
          }
        } finally {
          if (cbs.length > len) {
            // added more in the interim.
            // de-zalgo, just in case, but don't call again.
            cbs.splice(0, len)
            process.nextTick(function () {
              RES.apply(null, args)
            })
          } else {
            delete reqs[key]
          }
        }
      })
    }
    
    function slice (args) {
      var length = args.length
      var array = []
    
      for (var i = 0; i < length; i++) array[i] = args[i]
      return array
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321,"once":295,"wrappy":374}],182:[function(require,module,exports){
    if (typeof Object.create === 'function') {
      // implementation from standard node.js 'util' module
      module.exports = function inherits(ctor, superCtor) {
        if (superCtor) {
          ctor.super_ = superCtor
          ctor.prototype = Object.create(superCtor.prototype, {
            constructor: {
              value: ctor,
              enumerable: false,
              writable: true,
              configurable: true
            }
          })
        }
      };
    } else {
      // old school shim for old browsers
      module.exports = function inherits(ctor, superCtor) {
        if (superCtor) {
          ctor.super_ = superCtor
          var TempCtor = function () {}
          TempCtor.prototype = superCtor.prototype
          ctor.prototype = new TempCtor()
          ctor.prototype.constructor = ctor
        }
      }
    }
    
    },{}],183:[function(require,module,exports){
    'use strict';
    
    var hasToStringTag = require('has-tostringtag/shams')();
    var callBound = require('call-bind/callBound');
    
    var $toString = callBound('Object.prototype.toString');
    
    var isStandardArguments = function isArguments(value) {
        if (hasToStringTag && value && typeof value === 'object' && Symbol.toStringTag in value) {
            return false;
        }
        return $toString(value) === '[object Arguments]';
    };
    
    var isLegacyArguments = function isArguments(value) {
        if (isStandardArguments(value)) {
            return true;
        }
        return value !== null &&
            typeof value === 'object' &&
            typeof value.length === 'number' &&
            value.length >= 0 &&
            $toString(value) !== '[object Array]' &&
            $toString(value.callee) === '[object Function]';
    };
    
    var supportsStandardArguments = (function () {
        return isStandardArguments(arguments);
    }());
    
    isStandardArguments.isLegacyArguments = isLegacyArguments; // for tests
    
    module.exports = supportsStandardArguments ? isStandardArguments : isLegacyArguments;
    
    },{"call-bind/callBound":88,"has-tostringtag/shams":149}],184:[function(require,module,exports){
    /*!
     * Determine if an object is a Buffer
     *
     * @author   Feross Aboukhadijeh <https://feross.org>
     * @license  MIT
     */
    
    // The _isBuffer check is for Safari 5-7 support, because it's missing
    // Object.prototype.constructor. Remove this eventually
    module.exports = function (obj) {
      return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
    }
    
    function isBuffer (obj) {
      return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
    }
    
    // For Node v0.10 support. Remove this eventually.
    function isSlowBuffer (obj) {
      return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
    }
    
    },{}],185:[function(require,module,exports){
    'use strict';
    
    var fnToStr = Function.prototype.toString;
    var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply;
    var badArrayLike;
    var isCallableMarker;
    if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') {
        try {
            badArrayLike = Object.defineProperty({}, 'length', {
                get: function () {
                    throw isCallableMarker;
                }
            });
            isCallableMarker = {};
            // eslint-disable-next-line no-throw-literal
            reflectApply(function () { throw 42; }, null, badArrayLike);
        } catch (_) {
            if (_ !== isCallableMarker) {
                reflectApply = null;
            }
        }
    } else {
        reflectApply = null;
    }
    
    var constructorRegex = /^\s*class\b/;
    var isES6ClassFn = function isES6ClassFunction(value) {
        try {
            var fnStr = fnToStr.call(value);
            return constructorRegex.test(fnStr);
        } catch (e) {
            return false; // not a function
        }
    };
    
    var tryFunctionObject = function tryFunctionToStr(value) {
        try {
            if (isES6ClassFn(value)) { return false; }
            fnToStr.call(value);
            return true;
        } catch (e) {
            return false;
        }
    };
    var toStr = Object.prototype.toString;
    var objectClass = '[object Object]';
    var fnClass = '[object Function]';
    var genClass = '[object GeneratorFunction]';
    var ddaClass = '[object HTMLAllCollection]'; // IE 11
    var ddaClass2 = '[object HTML document.all class]';
    var ddaClass3 = '[object HTMLCollection]'; // IE 9-10
    var hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`
    
    var isIE68 = !(0 in [,]); // eslint-disable-line no-sparse-arrays, comma-spacing
    
    var isDDA = function isDocumentDotAll() { return false; };
    if (typeof document === 'object') {
        // Firefox 3 canonicalizes DDA to undefined when it's not accessed directly
        var all = document.all;
        if (toStr.call(all) === toStr.call(document.all)) {
            isDDA = function isDocumentDotAll(value) {
                /* globals document: false */
                // in IE 6-8, typeof document.all is "object" and it's truthy
                if ((isIE68 || !value) && (typeof value === 'undefined' || typeof value === 'object')) {
                    try {
                        var str = toStr.call(value);
                        return (
                            str === ddaClass
                            || str === ddaClass2
                            || str === ddaClass3 // opera 12.16
                            || str === objectClass // IE 6-8
                        ) && value('') == null; // eslint-disable-line eqeqeq
                    } catch (e) { /**/ }
                }
                return false;
            };
        }
    }
    
    module.exports = reflectApply
        ? function isCallable(value) {
            if (isDDA(value)) { return true; }
            if (!value) { return false; }
            if (typeof value !== 'function' && typeof value !== 'object') { return false; }
            try {
                reflectApply(value, null, badArrayLike);
            } catch (e) {
                if (e !== isCallableMarker) { return false; }
            }
            return !isES6ClassFn(value) && tryFunctionObject(value);
        }
        : function isCallable(value) {
            if (isDDA(value)) { return true; }
            if (!value) { return false; }
            if (typeof value !== 'function' && typeof value !== 'object') { return false; }
            if (hasToStringTag) { return tryFunctionObject(value); }
            if (isES6ClassFn(value)) { return false; }
            var strClass = toStr.call(value);
            if (strClass !== fnClass && strClass !== genClass && !(/^\[object HTML/).test(strClass)) { return false; }
            return tryFunctionObject(value);
        };
    
    },{}],186:[function(require,module,exports){
    'use strict';
    
    var toStr = Object.prototype.toString;
    var fnToStr = Function.prototype.toString;
    var isFnRegex = /^\s*(?:function)?\*/;
    var hasToStringTag = require('has-tostringtag/shams')();
    var getProto = Object.getPrototypeOf;
    var getGeneratorFunc = function () { // eslint-disable-line consistent-return
        if (!hasToStringTag) {
            return false;
        }
        try {
            return Function('return function*() {}')();
        } catch (e) {
        }
    };
    var GeneratorFunction;
    
    module.exports = function isGeneratorFunction(fn) {
        if (typeof fn !== 'function') {
            return false;
        }
        if (isFnRegex.test(fnToStr.call(fn))) {
            return true;
        }
        if (!hasToStringTag) {
            var str = toStr.call(fn);
            return str === '[object GeneratorFunction]';
        }
        if (!getProto) {
            return false;
        }
        if (typeof GeneratorFunction === 'undefined') {
            var generatorFunc = getGeneratorFunc();
            GeneratorFunction = generatorFunc ? getProto(generatorFunc) : false;
        }
        return getProto(fn) === GeneratorFunction;
    };
    
    },{"has-tostringtag/shams":149}],187:[function(require,module,exports){
    'use strict';
    
    var whichTypedArray = require('which-typed-array');
    
    module.exports = function isTypedArray(value) {
        return !!whichTypedArray(value);
    };
    
    },{"which-typed-array":373}],188:[function(require,module,exports){
    var json_stringify = require('./lib/stringify.js').stringify;
    var json_parse     = require('./lib/parse.js');
    
    module.exports = function(options) {
        return  {
            parse: json_parse(options),
            stringify: json_stringify
        }
    };
    //create the default method members with no options applied for backwards compatibility
    module.exports.parse = json_parse();
    module.exports.stringify = json_stringify;
    
    },{"./lib/parse.js":189,"./lib/stringify.js":190}],189:[function(require,module,exports){
    const bignumber_js_1 = require('bignumber.js');
    
    // regexpxs extracted from
    // (c) BSD-3-Clause
    // https://github.com/fastify/secure-json-parse/graphs/contributors and https://github.com/hapijs/bourne/graphs/contributors
    
    const suspectProtoRx = /(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])/;
    const suspectConstructorRx = /(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)/;
    
    /*
        json_parse.js
        2012-06-20
    
        Public Domain.
    
        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
    
        This file creates a json_parse function.
        During create you can (optionally) specify some behavioural switches
    
            require('json-bigint')(options)
    
                The optional options parameter holds switches that drive certain
                aspects of the parsing process:
                * options.strict = true will warn about duplicate-key usage in the json.
                  The default (strict = false) will silently ignore those and overwrite
                  values for keys that are in duplicate use.
    
        The resulting function follows this signature:
            json_parse(text, reviver)
                This method parses a JSON text to produce an object or array.
                It can throw a SyntaxError exception.
    
                The optional reviver parameter is a function that can filter and
                transform the results. It receives each of the keys and values,
                and its return value is used instead of the original value.
                If it returns what it received, then the structure is not modified.
                If it returns undefined then the member is deleted.
    
                Example:
    
                // Parse the text. Values that look like ISO date strings will
                // be converted to Date objects.
    
                myData = json_parse(text, function (key, value) {
                    var a;
                    if (typeof value === 'string') {
                        a =
    /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                        if (a) {
                            return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                                +a[5], +a[6]));
                        }
                    }
                    return value;
                });
    
        This is a reference implementation. You are free to copy, modify, or
        redistribute.
    
        This code should be minified before deployment.
        See http://javascript.crockford.com/jsmin.html
    
        USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
        NOT CONTROL.
    */
    
    /*members "", "\"", "\/", "\\", at, b, call, charAt, f, fromCharCode,
        hasOwnProperty, message, n, name, prototype, push, r, t, text
    */
    
    var json_parse = function (options) {
      'use strict';
    
      // This is a function that can parse a JSON text, producing a JavaScript
      // data structure. It is a simple, recursive descent parser. It does not use
      // eval or regular expressions, so it can be used as a model for implementing
      // a JSON parser in other languages.
    
      // We are defining the function inside of another function to avoid creating
      // global variables.
    
      // Default options one can override by passing options to the parse()
      var _options = {
        strict: false, // not being strict means do not generate syntax errors for "duplicate key"
        storeAsString: false, // toggles whether the values should be stored as BigNumber (default) or a string
        alwaysParseAsBig: false, // toggles whether all numbers should be Big
        useNativeBigInt: false, // toggles whether to use native BigInt instead of bignumber.js
        protoAction: 'error',
        constructorAction: 'error',
      };
    
      // If there are options, then use them to override the default _options
      if (options !== undefined && options !== null) {
        if (options.strict === true) {
          _options.strict = true;
        }
        if (options.storeAsString === true) {
          _options.storeAsString = true;
        }
        _options.alwaysParseAsBig =
          options.alwaysParseAsBig === true ? options.alwaysParseAsBig : false;
        _options.useNativeBigInt =
          options.useNativeBigInt === true ? options.useNativeBigInt : false;
    
        if (typeof options.constructorAction !== 'undefined') {
          if (
            options.constructorAction === 'error' ||
            options.constructorAction === 'ignore' ||
            options.constructorAction === 'preserve'
          ) {
            _options.constructorAction = options.constructorAction;
          } else {
            throw new Error(
              `Incorrect value for constructorAction option, must be "error", "ignore" or undefined but passed ${options.constructorAction}`
            );
          }
        }
    
        if (typeof options.protoAction !== 'undefined') {
          if (
            options.protoAction === 'error' ||
            options.protoAction === 'ignore' ||
            options.protoAction === 'preserve'
          ) {
            _options.protoAction = options.protoAction;
          } else {
            throw new Error(
              `Incorrect value for protoAction option, must be "error", "ignore" or undefined but passed ${options.protoAction}`
            );
          }
        }
      }
    
      var at, // The index of the current character
        ch, // The current character
        escapee = {
          '"': '"',
          '\\': '\\',
          '/': '/',
          b: '\b',
          f: '\f',
          n: '\n',
          r: '\r',
          t: '\t',
        },
        text,
        error = function (m) {
          // Call error when something is wrong.
    
          throw {
            name: 'SyntaxError',
            message: m,
            at: at,
            text: text,
          };
        },
        next = function (c) {
          // If a c parameter is provided, verify that it matches the current character.
    
          if (c && c !== ch) {
            error("Expected '" + c + "' instead of '" + ch + "'");
          }
    
          // Get the next character. When there are no more characters,
          // return the empty string.
    
          ch = text.charAt(at);
          at += 1;
          return ch;
        },
        number = function () {
          // Parse a number value.
    
          var number,
            string = '';
    
          if (ch === '-') {
            string = '-';
            next('-');
          }
          while (ch >= '0' && ch <= '9') {
            string += ch;
            next();
          }
          if (ch === '.') {
            string += '.';
            while (next() && ch >= '0' && ch <= '9') {
              string += ch;
            }
          }
          if (ch === 'e' || ch === 'E') {
            string += ch;
            next();
            if (ch === '-' || ch === '+') {
              string += ch;
              next();
            }
            while (ch >= '0' && ch <= '9') {
              string += ch;
              next();
            }
          }
          number = +string;
          // If the string is too long, this addition operation will return Infinity. 
          // If we want to support infinitely long numbers, we cannot make this judgment.
          if (/*!isFinite(number)*/false) {
            error('Bad number');
          } else {
            //if (number > 9007199254740992 || number < -9007199254740992)
            // Bignumber has stricter check: everything with length > 15 digits disallowed
            if (string.length > 15)
              return _options.storeAsString
                ? string
                : _options.useNativeBigInt
                ? BigInt(string)
                : new bignumber_js_1.default(string);
            else
              return !_options.alwaysParseAsBig
                ? number
                : _options.useNativeBigInt
                ? BigInt(number)
                : new bignumber_js_1.default(number);
          }
        },
        string = function () {
          // Parse a string value.
    
          var hex,
            i,
            string = '',
            uffff;
    
          // When parsing for string values, we must look for " and \ characters.
    
          if (ch === '"') {
            var startAt = at;
            while (next()) {
              if (ch === '"') {
                if (at - 1 > startAt) string += text.substring(startAt, at - 1);
                next();
                return string;
              }
              if (ch === '\\') {
                if (at - 1 > startAt) string += text.substring(startAt, at - 1);
                next();
                if (ch === 'u') {
                  uffff = 0;
                  for (i = 0; i < 4; i += 1) {
                    hex = parseInt(next(), 16);
                    if (!isFinite(hex)) {
                      break;
                    }
                    uffff = uffff * 16 + hex;
                  }
                  string += String.fromCharCode(uffff);
                } else if (typeof escapee[ch] === 'string') {
                  string += escapee[ch];
                } else {
                  break;
                }
                startAt = at;
              }
            }
          }
          error('Bad string');
        },
        white = function () {
          // Skip whitespace.
    
          while (ch && ch <= ' ') {
            next();
          }
        },
        word = function () {
          // true, false, or null.
    
          switch (ch) {
            case 't':
              next('t');
              next('r');
              next('u');
              next('e');
              return true;
            case 'f':
              next('f');
              next('a');
              next('l');
              next('s');
              next('e');
              return false;
            case 'n':
              next('n');
              next('u');
              next('l');
              next('l');
              return null;
          }
          error("Unexpected '" + ch + "'");
        },
        value, // Place holder for the value function.
        array = function () {
          // Parse an array value.
    
          var array = [];
    
          if (ch === '[') {
            next('[');
            white();
            if (ch === ']') {
              next(']');
              return array; // empty array
            }
            while (ch) {
              array.push(value());
              white();
              if (ch === ']') {
                next(']');
                return array;
              }
              next(',');
              white();
            }
          }
          error('Bad array');
        },
        object = function () {
          // Parse an object value.
    
          var key,
            object = Object.create(null);
    
          if (ch === '{') {
            next('{');
            white();
            if (ch === '}') {
              next('}');
              return object; // empty object
            }
            while (ch) {
              key = string();
              white();
              next(':');
              if (
                _options.strict === true &&
                Object.hasOwnProperty.call(object, key)
              ) {
                error('Duplicate key "' + key + '"');
              }
    
              if (suspectProtoRx.test(key) === true) {
                if (_options.protoAction === 'error') {
                  error('Object contains forbidden prototype property');
                } else if (_options.protoAction === 'ignore') {
                  value();
                } else {
                  object[key] = value();
                }
              } else if (suspectConstructorRx.test(key) === true) {
                if (_options.constructorAction === 'error') {
                  error('Object contains forbidden constructor property');
                } else if (_options.constructorAction === 'ignore') {
                  value();
                } else {
                  object[key] = value();
                }
              } else {
                object[key] = value();
              }
    
              white();
              if (ch === '}') {
                next('}');
                return object;
              }
              next(',');
              white();
            }
          }
          error('Bad object');
        };
    
      value = function () {
        // Parse a JSON value. It could be an object, an array, a string, a number,
        // or a word.
    
        white();
        switch (ch) {
          case '{':
            return object();
          case '[':
            return array();
          case '"':
            return string();
          case '-':
            return number();
          default:
            return ch >= '0' && ch <= '9' ? number() : word();
        }
      };
    
      // Return the json_parse function. It will have access to all of the above
      // functions and variables.
    
      return function (source, reviver) {
        var result;
    
        text = source + '';
        at = 0;
        ch = ' ';
        result = value();
        white();
        if (ch) {
          error('Syntax error');
        }
    
        // If there is a reviver function, we recursively walk the new structure,
        // passing each name/value pair to the reviver function for possible
        // transformation, starting with a temporary root object that holds the result
        // in an empty key. If there is not a reviver function, we simply return the
        // result.
    
        return typeof reviver === 'function'
          ? (function walk(holder, key) {
              var k,
                v,
                value = holder[key];
              if (value && typeof value === 'object') {
                Object.keys(value).forEach(function (k) {
                  v = walk(value, k);
                  if (v !== undefined) {
                    value[k] = v;
                  } else {
                    delete value[k];
                  }
                });
              }
              return reviver.call(holder, key, value);
            })({ '': result }, '')
          : result;
      };
    };
    
    module.exports = json_parse;
    
    },{"bignumber.js":32}],190:[function(require,module,exports){
    var BigNumber = require('bignumber.js');
    
    /*
        json2.js
        2013-05-26
    
        Public Domain.
    
        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
    
        See http://www.JSON.org/js.html
    
    
        This code should be minified before deployment.
        See http://javascript.crockford.com/jsmin.html
    
        USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
        NOT CONTROL.
    
    
        This file creates a global JSON object containing two methods: stringify
        and parse.
    
            JSON.stringify(value, replacer, space)
                value       any JavaScript value, usually an object or array.
    
                replacer    an optional parameter that determines how object
                            values are stringified for objects. It can be a
                            function or an array of strings.
    
                space       an optional parameter that specifies the indentation
                            of nested structures. If it is omitted, the text will
                            be packed without extra whitespace. If it is a number,
                            it will specify the number of spaces to indent at each
                            level. If it is a string (such as '\t' or '&nbsp;'),
                            it contains the characters used to indent at each level.
    
                This method produces a JSON text from a JavaScript value.
    
                When an object value is found, if the object contains a toJSON
                method, its toJSON method will be called and the result will be
                stringified. A toJSON method does not serialize: it returns the
                value represented by the name/value pair that should be serialized,
                or undefined if nothing should be serialized. The toJSON method
                will be passed the key associated with the value, and this will be
                bound to the value
    
                For example, this would serialize Dates as ISO strings.
    
                    Date.prototype.toJSON = function (key) {
                        function f(n) {
                            // Format integers to have at least two digits.
                            return n < 10 ? '0' + n : n;
                        }
    
                        return this.getUTCFullYear()   + '-' +
                             f(this.getUTCMonth() + 1) + '-' +
                             f(this.getUTCDate())      + 'T' +
                             f(this.getUTCHours())     + ':' +
                             f(this.getUTCMinutes())   + ':' +
                             f(this.getUTCSeconds())   + 'Z';
                    };
    
                You can provide an optional replacer method. It will be passed the
                key and value of each member, with this bound to the containing
                object. The value that is returned from your method will be
                serialized. If your method returns undefined, then the member will
                be excluded from the serialization.
    
                If the replacer parameter is an array of strings, then it will be
                used to select the members to be serialized. It filters the results
                such that only members with keys listed in the replacer array are
                stringified.
    
                Values that do not have JSON representations, such as undefined or
                functions, will not be serialized. Such values in objects will be
                dropped; in arrays they will be replaced with null. You can use
                a replacer function to replace those with JSON values.
                JSON.stringify(undefined) returns undefined.
    
                The optional space parameter produces a stringification of the
                value that is filled with line breaks and indentation to make it
                easier to read.
    
                If the space parameter is a non-empty string, then that string will
                be used for indentation. If the space parameter is a number, then
                the indentation will be that many spaces.
    
                Example:
    
                text = JSON.stringify(['e', {pluribus: 'unum'}]);
                // text is '["e",{"pluribus":"unum"}]'
    
    
                text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
                // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
    
                text = JSON.stringify([new Date()], function (key, value) {
                    return this[key] instanceof Date ?
                        'Date(' + this[key] + ')' : value;
                });
                // text is '["Date(---current time---)"]'
    
    
            JSON.parse(text, reviver)
                This method parses a JSON text to produce an object or array.
                It can throw a SyntaxError exception.
    
                The optional reviver parameter is a function that can filter and
                transform the results. It receives each of the keys and values,
                and its return value is used instead of the original value.
                If it returns what it received, then the structure is not modified.
                If it returns undefined then the member is deleted.
    
                Example:
    
                // Parse the text. Values that look like ISO date strings will
                // be converted to Date objects.
    
                myData = JSON.parse(text, function (key, value) {
                    var a;
                    if (typeof value === 'string') {
                        a =
    /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
                        if (a) {
                            return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                                +a[5], +a[6]));
                        }
                    }
                    return value;
                });
    
                myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
                    var d;
                    if (typeof value === 'string' &&
                            value.slice(0, 5) === 'Date(' &&
                            value.slice(-1) === ')') {
                        d = new Date(value.slice(5, -1));
                        if (d) {
                            return d;
                        }
                    }
                    return value;
                });
    
    
        This is a reference implementation. You are free to copy, modify, or
        redistribute.
    */
    
    /*jslint evil: true, regexp: true */
    
    /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
        call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
        getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
        lastIndex, length, parse, prototype, push, replace, slice, stringify,
        test, toJSON, toString, valueOf
    */
    
    
    // Create a JSON object only if one does not already exist. We create the
    // methods in a closure to avoid creating global variables.
    
    var JSON = module.exports;
    
    (function () {
        'use strict';
    
        function f(n) {
            // Format integers to have at least two digits.
            return n < 10 ? '0' + n : n;
        }
    
        var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            gap,
            indent,
            meta = {    // table of character substitutions
                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',
                '"' : '\\"',
                '\\': '\\\\'
            },
            rep;
    
    
        function quote(string) {
    
    // If the string contains no control characters, no quote characters, and no
    // backslash characters, then we can safely slap some quotes around it.
    // Otherwise we must also replace the offending characters with safe escape
    // sequences.
    
            escapable.lastIndex = 0;
            return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string'
                    ? c
                    : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' : '"' + string + '"';
        }
    
    
        function str(key, holder) {
    
    // Produce a string from holder[key].
    
            var i,          // The loop counter.
                k,          // The member key.
                v,          // The member value.
                length,
                mind = gap,
                partial,
                value = holder[key],
                isBigNumber = value != null && (value instanceof BigNumber || BigNumber.isBigNumber(value));
    
    // If the value has a toJSON method, call it to obtain a replacement value.
    
            if (value && typeof value === 'object' &&
                    typeof value.toJSON === 'function') {
                value = value.toJSON(key);
            }
    
    // If we were called with a replacer function, then call the replacer to
    // obtain a replacement value.
    
            if (typeof rep === 'function') {
                value = rep.call(holder, key, value);
            }
    
    // What happens next depends on the value's type.
    
            switch (typeof value) {
            case 'string':
                if (isBigNumber) {
                    return value;
                } else {
                    return quote(value);
                }
    
            case 'number':
    
    // JSON numbers must be finite. Encode non-finite numbers as null.
    
                return isFinite(value) ? String(value) : 'null';
    
            case 'boolean':
            case 'null':
            case 'bigint':
    
    // If the value is a boolean or null, convert it to a string. Note:
    // typeof null does not produce 'null'. The case is included here in
    // the remote chance that this gets fixed someday.
    
                return String(value);
    
    // If the type is 'object', we might be dealing with an object or an array or
    // null.
    
            case 'object':
    
    // Due to a specification blunder in ECMAScript, typeof null is 'object',
    // so watch out for that case.
    
                if (!value) {
                    return 'null';
                }
    
    // Make an array to hold the partial results of stringifying this object value.
    
                gap += indent;
                partial = [];
    
    // Is the value an array?
    
                if (Object.prototype.toString.apply(value) === '[object Array]') {
    
    // The value is an array. Stringify every element. Use null as a placeholder
    // for non-JSON values.
    
                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }
    
    // Join all of the elements together, separated with commas, and wrap them in
    // brackets.
    
                    v = partial.length === 0
                        ? '[]'
                        : gap
                        ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                        : '[' + partial.join(',') + ']';
                    gap = mind;
                    return v;
                }
    
    // If the replacer is an array, use it to select the members to be stringified.
    
                if (rep && typeof rep === 'object') {
                    length = rep.length;
                    for (i = 0; i < length; i += 1) {
                        if (typeof rep[i] === 'string') {
                            k = rep[i];
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {
    
    // Otherwise, iterate through all of the keys in the object.
    
                    Object.keys(value).forEach(function(k) {
                        var v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    });
                }
    
    // Join all of the member texts together, separated with commas,
    // and wrap them in braces.
    
                v = partial.length === 0
                    ? '{}'
                    : gap
                    ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                    : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
            }
        }
    
    // If the JSON object does not yet have a stringify method, give it one.
    
        if (typeof JSON.stringify !== 'function') {
            JSON.stringify = function (value, replacer, space) {
    
    // The stringify method takes a value and an optional replacer, and an optional
    // space parameter, and returns a JSON text. The replacer can be a function
    // that can replace values, or an array of strings that will select the keys.
    // A default replacer method can be provided. Use of the space parameter can
    // produce text that is more easily readable.
    
                var i;
                gap = '';
                indent = '';
    
    // If the space parameter is a number, make an indent string containing that
    // many spaces.
    
                if (typeof space === 'number') {
                    for (i = 0; i < space; i += 1) {
                        indent += ' ';
                    }
    
    // If the space parameter is a string, it will be used as the indent string.
    
                } else if (typeof space === 'string') {
                    indent = space;
                }
    
    // If there is a replacer, it must be a function or an array.
    // Otherwise, throw an error.
    
                rep = replacer;
                if (replacer && typeof replacer !== 'function' &&
                        (typeof replacer !== 'object' ||
                        typeof replacer.length !== 'number')) {
                    throw new Error('JSON.stringify');
                }
    
    // Make a fake root object containing our value under the key of ''.
    // Return the result of stringifying the value.
    
                return str('', {'': value});
            };
        }
    }());
    
    },{"bignumber.js":32}],191:[function(require,module,exports){
    'use strict'
    var inherits = require('inherits')
    var HashBase = require('hash-base')
    var Buffer = require('safe-buffer').Buffer
    
    var ARRAY16 = new Array(16)
    
    function MD5 () {
      HashBase.call(this, 64)
    
      // state
      this._a = 0x67452301
      this._b = 0xefcdab89
      this._c = 0x98badcfe
      this._d = 0x10325476
    }
    
    inherits(MD5, HashBase)
    
    MD5.prototype._update = function () {
      var M = ARRAY16
      for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4)
    
      var a = this._a
      var b = this._b
      var c = this._c
      var d = this._d
    
      a = fnF(a, b, c, d, M[0], 0xd76aa478, 7)
      d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12)
      c = fnF(c, d, a, b, M[2], 0x242070db, 17)
      b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22)
      a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7)
      d = fnF(d, a, b, c, M[5], 0x4787c62a, 12)
      c = fnF(c, d, a, b, M[6], 0xa8304613, 17)
      b = fnF(b, c, d, a, M[7], 0xfd469501, 22)
      a = fnF(a, b, c, d, M[8], 0x698098d8, 7)
      d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12)
      c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17)
      b = fnF(b, c, d, a, M[11], 0x895cd7be, 22)
      a = fnF(a, b, c, d, M[12], 0x6b901122, 7)
      d = fnF(d, a, b, c, M[13], 0xfd987193, 12)
      c = fnF(c, d, a, b, M[14], 0xa679438e, 17)
      b = fnF(b, c, d, a, M[15], 0x49b40821, 22)
    
      a = fnG(a, b, c, d, M[1], 0xf61e2562, 5)
      d = fnG(d, a, b, c, M[6], 0xc040b340, 9)
      c = fnG(c, d, a, b, M[11], 0x265e5a51, 14)
      b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20)
      a = fnG(a, b, c, d, M[5], 0xd62f105d, 5)
      d = fnG(d, a, b, c, M[10], 0x02441453, 9)
      c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14)
      b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20)
      a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5)
      d = fnG(d, a, b, c, M[14], 0xc33707d6, 9)
      c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14)
      b = fnG(b, c, d, a, M[8], 0x455a14ed, 20)
      a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5)
      d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9)
      c = fnG(c, d, a, b, M[7], 0x676f02d9, 14)
      b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20)
    
      a = fnH(a, b, c, d, M[5], 0xfffa3942, 4)
      d = fnH(d, a, b, c, M[8], 0x8771f681, 11)
      c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16)
      b = fnH(b, c, d, a, M[14], 0xfde5380c, 23)
      a = fnH(a, b, c, d, M[1], 0xa4beea44, 4)
      d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11)
      c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16)
      b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23)
      a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4)
      d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11)
      c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16)
      b = fnH(b, c, d, a, M[6], 0x04881d05, 23)
      a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4)
      d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11)
      c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16)
      b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23)
    
      a = fnI(a, b, c, d, M[0], 0xf4292244, 6)
      d = fnI(d, a, b, c, M[7], 0x432aff97, 10)
      c = fnI(c, d, a, b, M[14], 0xab9423a7, 15)
      b = fnI(b, c, d, a, M[5], 0xfc93a039, 21)
      a = fnI(a, b, c, d, M[12], 0x655b59c3, 6)
      d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10)
      c = fnI(c, d, a, b, M[10], 0xffeff47d, 15)
      b = fnI(b, c, d, a, M[1], 0x85845dd1, 21)
      a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6)
      d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10)
      c = fnI(c, d, a, b, M[6], 0xa3014314, 15)
      b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21)
      a = fnI(a, b, c, d, M[4], 0xf7537e82, 6)
      d = fnI(d, a, b, c, M[11], 0xbd3af235, 10)
      c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15)
      b = fnI(b, c, d, a, M[9], 0xeb86d391, 21)
    
      this._a = (this._a + a) | 0
      this._b = (this._b + b) | 0
      this._c = (this._c + c) | 0
      this._d = (this._d + d) | 0
    }
    
    MD5.prototype._digest = function () {
      // create padding and handle blocks
      this._block[this._blockOffset++] = 0x80
      if (this._blockOffset > 56) {
        this._block.fill(0, this._blockOffset, 64)
        this._update()
        this._blockOffset = 0
      }
    
      this._block.fill(0, this._blockOffset, 56)
      this._block.writeUInt32LE(this._length[0], 56)
      this._block.writeUInt32LE(this._length[1], 60)
      this._update()
    
      // produce result
      var buffer = Buffer.allocUnsafe(16)
      buffer.writeInt32LE(this._a, 0)
      buffer.writeInt32LE(this._b, 4)
      buffer.writeInt32LE(this._c, 8)
      buffer.writeInt32LE(this._d, 12)
      return buffer
    }
    
    function rotl (x, n) {
      return (x << n) | (x >>> (32 - n))
    }
    
    function fnF (a, b, c, d, m, k, s) {
      return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0
    }
    
    function fnG (a, b, c, d, m, k, s) {
      return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0
    }
    
    function fnH (a, b, c, d, m, k, s) {
      return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0
    }
    
    function fnI (a, b, c, d, m, k, s) {
      return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0
    }
    
    module.exports = MD5
    
    },{"hash-base":151,"inherits":182,"safe-buffer":338}],192:[function(require,module,exports){
    (function(){
      var crypt = require('crypt'),
          utf8 = require('charenc').utf8,
          isBuffer = require('is-buffer'),
          bin = require('charenc').bin,
    
      // The core
      md5 = function (message, options) {
        // Convert to byte array
        if (message.constructor == String)
          if (options && options.encoding === 'binary')
            message = bin.stringToBytes(message);
          else
            message = utf8.stringToBytes(message);
        else if (isBuffer(message))
          message = Array.prototype.slice.call(message, 0);
        else if (!Array.isArray(message) && message.constructor !== Uint8Array)
          message = message.toString();
        // else, assume byte array already
    
        var m = crypt.bytesToWords(message),
            l = message.length * 8,
            a =  1732584193,
            b = -271733879,
            c = -1732584194,
            d =  271733878;
    
        // Swap endian
        for (var i = 0; i < m.length; i++) {
          m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
                 ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
        }
    
        // Padding
        m[l >>> 5] |= 0x80 << (l % 32);
        m[(((l + 64) >>> 9) << 4) + 14] = l;
    
        // Method shortcuts
        var FF = md5._ff,
            GG = md5._gg,
            HH = md5._hh,
            II = md5._ii;
    
        for (var i = 0; i < m.length; i += 16) {
    
          var aa = a,
              bb = b,
              cc = c,
              dd = d;
    
          a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
          d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
          c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
          b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
          a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
          d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
          c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
          b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
          a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
          d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
          c = FF(c, d, a, b, m[i+10], 17, -42063);
          b = FF(b, c, d, a, m[i+11], 22, -1990404162);
          a = FF(a, b, c, d, m[i+12],  7,  1804603682);
          d = FF(d, a, b, c, m[i+13], 12, -40341101);
          c = FF(c, d, a, b, m[i+14], 17, -1502002290);
          b = FF(b, c, d, a, m[i+15], 22,  1236535329);
    
          a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
          d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
          c = GG(c, d, a, b, m[i+11], 14,  643717713);
          b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
          a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
          d = GG(d, a, b, c, m[i+10],  9,  38016083);
          c = GG(c, d, a, b, m[i+15], 14, -660478335);
          b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
          a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
          d = GG(d, a, b, c, m[i+14],  9, -1019803690);
          c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
          b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
          a = GG(a, b, c, d, m[i+13],  5, -1444681467);
          d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
          c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
          b = GG(b, c, d, a, m[i+12], 20, -1926607734);
    
          a = HH(a, b, c, d, m[i+ 5],  4, -378558);
          d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
          c = HH(c, d, a, b, m[i+11], 16,  1839030562);
          b = HH(b, c, d, a, m[i+14], 23, -35309556);
          a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
          d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
          c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
          b = HH(b, c, d, a, m[i+10], 23, -1094730640);
          a = HH(a, b, c, d, m[i+13],  4,  681279174);
          d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
          c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
          b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
          a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
          d = HH(d, a, b, c, m[i+12], 11, -421815835);
          c = HH(c, d, a, b, m[i+15], 16,  530742520);
          b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
    
          a = II(a, b, c, d, m[i+ 0],  6, -198630844);
          d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
          c = II(c, d, a, b, m[i+14], 15, -1416354905);
          b = II(b, c, d, a, m[i+ 5], 21, -57434055);
          a = II(a, b, c, d, m[i+12],  6,  1700485571);
          d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
          c = II(c, d, a, b, m[i+10], 15, -1051523);
          b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
          a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
          d = II(d, a, b, c, m[i+15], 10, -30611744);
          c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
          b = II(b, c, d, a, m[i+13], 21,  1309151649);
          a = II(a, b, c, d, m[i+ 4],  6, -145523070);
          d = II(d, a, b, c, m[i+11], 10, -1120210379);
          c = II(c, d, a, b, m[i+ 2], 15,  718787259);
          b = II(b, c, d, a, m[i+ 9], 21, -343485551);
    
          a = (a + aa) >>> 0;
          b = (b + bb) >>> 0;
          c = (c + cc) >>> 0;
          d = (d + dd) >>> 0;
        }
    
        return crypt.endian([a, b, c, d]);
      };
    
      // Auxiliary functions
      md5._ff  = function (a, b, c, d, x, s, t) {
        var n = a + (b & c | ~b & d) + (x >>> 0) + t;
        return ((n << s) | (n >>> (32 - s))) + b;
      };
      md5._gg  = function (a, b, c, d, x, s, t) {
        var n = a + (b & d | c & ~d) + (x >>> 0) + t;
        return ((n << s) | (n >>> (32 - s))) + b;
      };
      md5._hh  = function (a, b, c, d, x, s, t) {
        var n = a + (b ^ c ^ d) + (x >>> 0) + t;
        return ((n << s) | (n >>> (32 - s))) + b;
      };
      md5._ii  = function (a, b, c, d, x, s, t) {
        var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
        return ((n << s) | (n >>> (32 - s))) + b;
      };
    
      // Package private blocksize
      md5._blocksize = 16;
      md5._digestsize = 16;
    
      module.exports = function (message, options) {
        if (message === undefined || message === null)
          throw new Error('Illegal argument ' + message);
    
        var digestbytes = crypt.wordsToBytes(md5(message, options));
        return options && options.asBytes ? digestbytes :
            options && options.asString ? bin.bytesToString(digestbytes) :
            crypt.bytesToHex(digestbytes);
      };
    
    })();
    
    },{"charenc":93,"crypt":106,"is-buffer":184}],193:[function(require,module,exports){
    var bn = require('bn.js');
    var brorand = require('brorand');
    
    function MillerRabin(rand) {
      this.rand = rand || new brorand.Rand();
    }
    module.exports = MillerRabin;
    
    MillerRabin.create = function create(rand) {
      return new MillerRabin(rand);
    };
    
    MillerRabin.prototype._randbelow = function _randbelow(n) {
      var len = n.bitLength();
      var min_bytes = Math.ceil(len / 8);
    
      // Generage random bytes until a number less than n is found.
      // This ensures that 0..n-1 have an equal probability of being selected.
      do
        var a = new bn(this.rand.generate(min_bytes));
      while (a.cmp(n) >= 0);
    
      return a;
    };
    
    MillerRabin.prototype._randrange = function _randrange(start, stop) {
      // Generate a random number greater than or equal to start and less than stop.
      var size = stop.sub(start);
      return start.add(this._randbelow(size));
    };
    
    MillerRabin.prototype.test = function test(n, k, cb) {
      var len = n.bitLength();
      var red = bn.mont(n);
      var rone = new bn(1).toRed(red);
    
      if (!k)
        k = Math.max(1, (len / 48) | 0);
    
      // Find d and s, (n - 1) = (2 ^ s) * d;
      var n1 = n.subn(1);
      for (var s = 0; !n1.testn(s); s++) {}
      var d = n.shrn(s);
    
      var rn1 = n1.toRed(red);
    
      var prime = true;
      for (; k > 0; k--) {
        var a = this._randrange(new bn(2), n1);
        if (cb)
          cb(a);
    
        var x = a.toRed(red).redPow(d);
        if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
          continue;
    
        for (var i = 1; i < s; i++) {
          x = x.redSqr();
    
          if (x.cmp(rone) === 0)
            return false;
          if (x.cmp(rn1) === 0)
            break;
        }
    
        if (i === s)
          return false;
      }
    
      return prime;
    };
    
    MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
      var len = n.bitLength();
      var red = bn.mont(n);
      var rone = new bn(1).toRed(red);
    
      if (!k)
        k = Math.max(1, (len / 48) | 0);
    
      // Find d and s, (n - 1) = (2 ^ s) * d;
      var n1 = n.subn(1);
      for (var s = 0; !n1.testn(s); s++) {}
      var d = n.shrn(s);
    
      var rn1 = n1.toRed(red);
    
      for (; k > 0; k--) {
        var a = this._randrange(new bn(2), n1);
    
        var g = n.gcd(a);
        if (g.cmpn(1) !== 0)
          return g;
    
        var x = a.toRed(red).redPow(d);
        if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
          continue;
    
        for (var i = 1; i < s; i++) {
          x = x.redSqr();
    
          if (x.cmp(rone) === 0)
            return x.fromRed().subn(1).gcd(n);
          if (x.cmp(rn1) === 0)
            break;
        }
    
        if (i === s) {
          x = x.redSqr();
          return x.fromRed().subn(1).gcd(n);
        }
      }
    
      return false;
    };
    
    },{"bn.js":33,"brorand":35}],194:[function(require,module,exports){
    module.exports = assert;
    
    function assert(val, msg) {
      if (!val)
        throw new Error(msg || 'Assertion failed');
    }
    
    assert.equal = function assertEqual(l, r, msg) {
      if (l != r)
        throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
    };
    
    },{}],195:[function(require,module,exports){
    'use strict';
    
    var utils = exports;
    
    function toArray(msg, enc) {
      if (Array.isArray(msg))
        return msg.slice();
      if (!msg)
        return [];
      var res = [];
      if (typeof msg !== 'string') {
        for (var i = 0; i < msg.length; i++)
          res[i] = msg[i] | 0;
        return res;
      }
      if (enc === 'hex') {
        msg = msg.replace(/[^a-z0-9]+/ig, '');
        if (msg.length % 2 !== 0)
          msg = '0' + msg;
        for (var i = 0; i < msg.length; i += 2)
          res.push(parseInt(msg[i] + msg[i + 1], 16));
      } else {
        for (var i = 0; i < msg.length; i++) {
          var c = msg.charCodeAt(i);
          var hi = c >> 8;
          var lo = c & 0xff;
          if (hi)
            res.push(hi, lo);
          else
            res.push(lo);
        }
      }
      return res;
    }
    utils.toArray = toArray;
    
    function zero2(word) {
      if (word.length === 1)
        return '0' + word;
      else
        return word;
    }
    utils.zero2 = zero2;
    
    function toHex(msg) {
      var res = '';
      for (var i = 0; i < msg.length; i++)
        res += zero2(msg[i].toString(16));
      return res;
    }
    utils.toHex = toHex;
    
    utils.encode = function encode(arr, enc) {
      if (enc === 'hex')
        return toHex(arr);
      else
        return arr;
    };
    
    },{}],196:[function(require,module,exports){
    module.exports = minimatch
    minimatch.Minimatch = Minimatch
    
    var path = (function () { try { return require('path') } catch (e) {}}()) || {
      sep: '/'
    }
    minimatch.sep = path.sep
    
    var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
    var expand = require('brace-expansion')
    
    var plTypes = {
      '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
      '?': { open: '(?:', close: ')?' },
      '+': { open: '(?:', close: ')+' },
      '*': { open: '(?:', close: ')*' },
      '@': { open: '(?:', close: ')' }
    }
    
    // any single thing other than /
    // don't need to escape / when using new RegExp()
    var qmark = '[^/]'
    
    // * => any number of characters
    var star = qmark + '*?'
    
    // ** when dots are allowed.  Anything goes, except .. and .
    // not (^ or / followed by one or two dots followed by $ or /),
    // followed by anything, any number of times.
    var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
    
    // not a ^ or / followed by a dot,
    // followed by anything, any number of times.
    var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
    
    // characters that need to be escaped in RegExp.
    var reSpecials = charSet('().*{}+?[]^$\\!')
    
    // "abc" -> { a:true, b:true, c:true }
    function charSet (s) {
      return s.split('').reduce(function (set, c) {
        set[c] = true
        return set
      }, {})
    }
    
    // normalizes slashes.
    var slashSplit = /\/+/
    
    minimatch.filter = filter
    function filter (pattern, options) {
      options = options || {}
      return function (p, i, list) {
        return minimatch(p, pattern, options)
      }
    }
    
    function ext (a, b) {
      b = b || {}
      var t = {}
      Object.keys(a).forEach(function (k) {
        t[k] = a[k]
      })
      Object.keys(b).forEach(function (k) {
        t[k] = b[k]
      })
      return t
    }
    
    minimatch.defaults = function (def) {
      if (!def || typeof def !== 'object' || !Object.keys(def).length) {
        return minimatch
      }
    
      var orig = minimatch
    
      var m = function minimatch (p, pattern, options) {
        return orig(p, pattern, ext(def, options))
      }
    
      m.Minimatch = function Minimatch (pattern, options) {
        return new orig.Minimatch(pattern, ext(def, options))
      }
      m.Minimatch.defaults = function defaults (options) {
        return orig.defaults(ext(def, options)).Minimatch
      }
    
      m.filter = function filter (pattern, options) {
        return orig.filter(pattern, ext(def, options))
      }
    
      m.defaults = function defaults (options) {
        return orig.defaults(ext(def, options))
      }
    
      m.makeRe = function makeRe (pattern, options) {
        return orig.makeRe(pattern, ext(def, options))
      }
    
      m.braceExpand = function braceExpand (pattern, options) {
        return orig.braceExpand(pattern, ext(def, options))
      }
    
      m.match = function (list, pattern, options) {
        return orig.match(list, pattern, ext(def, options))
      }
    
      return m
    }
    
    Minimatch.defaults = function (def) {
      return minimatch.defaults(def).Minimatch
    }
    
    function minimatch (p, pattern, options) {
      assertValidPattern(pattern)
    
      if (!options) options = {}
    
      // shortcut: comments match nothing.
      if (!options.nocomment && pattern.charAt(0) === '#') {
        return false
      }
    
      return new Minimatch(pattern, options).match(p)
    }
    
    function Minimatch (pattern, options) {
      if (!(this instanceof Minimatch)) {
        return new Minimatch(pattern, options)
      }
    
      assertValidPattern(pattern)
    
      if (!options) options = {}
    
      pattern = pattern.trim()
    
      // windows support: need to use /, not \
      if (!options.allowWindowsEscape && path.sep !== '/') {
        pattern = pattern.split(path.sep).join('/')
      }
    
      this.options = options
      this.set = []
      this.pattern = pattern
      this.regexp = null
      this.negate = false
      this.comment = false
      this.empty = false
      this.partial = !!options.partial
    
      // make the set of regexps etc.
      this.make()
    }
    
    Minimatch.prototype.debug = function () {}
    
    Minimatch.prototype.make = make
    function make () {
      var pattern = this.pattern
      var options = this.options
    
      // empty patterns and comments match nothing.
      if (!options.nocomment && pattern.charAt(0) === '#') {
        this.comment = true
        return
      }
      if (!pattern) {
        this.empty = true
        return
      }
    
      // step 1: figure out negation, etc.
      this.parseNegate()
    
      // step 2: expand braces
      var set = this.globSet = this.braceExpand()
    
      if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) }
    
      this.debug(this.pattern, set)
    
      // step 3: now we have a set, so turn each one into a series of path-portion
      // matching patterns.
      // These will be regexps, except in the case of "**", which is
      // set to the GLOBSTAR object for globstar behavior,
      // and will not contain any / characters
      set = this.globParts = set.map(function (s) {
        return s.split(slashSplit)
      })
    
      this.debug(this.pattern, set)
    
      // glob --> regexps
      set = set.map(function (s, si, set) {
        return s.map(this.parse, this)
      }, this)
    
      this.debug(this.pattern, set)
    
      // filter out everything that didn't compile properly.
      set = set.filter(function (s) {
        return s.indexOf(false) === -1
      })
    
      this.debug(this.pattern, set)
    
      this.set = set
    }
    
    Minimatch.prototype.parseNegate = parseNegate
    function parseNegate () {
      var pattern = this.pattern
      var negate = false
      var options = this.options
      var negateOffset = 0
    
      if (options.nonegate) return
    
      for (var i = 0, l = pattern.length
        ; i < l && pattern.charAt(i) === '!'
        ; i++) {
        negate = !negate
        negateOffset++
      }
    
      if (negateOffset) this.pattern = pattern.substr(negateOffset)
      this.negate = negate
    }
    
    // Brace expansion:
    // a{b,c}d -> abd acd
    // a{b,}c -> abc ac
    // a{0..3}d -> a0d a1d a2d a3d
    // a{b,c{d,e}f}g -> abg acdfg acefg
    // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
    //
    // Invalid sets are not expanded.
    // a{2..}b -> a{2..}b
    // a{b}c -> a{b}c
    minimatch.braceExpand = function (pattern, options) {
      return braceExpand(pattern, options)
    }
    
    Minimatch.prototype.braceExpand = braceExpand
    
    function braceExpand (pattern, options) {
      if (!options) {
        if (this instanceof Minimatch) {
          options = this.options
        } else {
          options = {}
        }
      }
    
      pattern = typeof pattern === 'undefined'
        ? this.pattern : pattern
    
      assertValidPattern(pattern)
    
      // Thanks to Yeting Li <https://github.com/yetingli> for
      // improving this regexp to avoid a ReDOS vulnerability.
      if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
        // shortcut. no need to expand.
        return [pattern]
      }
    
      return expand(pattern)
    }
    
    var MAX_PATTERN_LENGTH = 1024 * 64
    var assertValidPattern = function (pattern) {
      if (typeof pattern !== 'string') {
        throw new TypeError('invalid pattern')
      }
    
      if (pattern.length > MAX_PATTERN_LENGTH) {
        throw new TypeError('pattern is too long')
      }
    }
    
    // parse a component of the expanded set.
    // At this point, no pattern may contain "/" in it
    // so we're going to return a 2d array, where each entry is the full
    // pattern, split on '/', and then turned into a regular expression.
    // A regexp is made at the end which joins each array with an
    // escaped /, and another full one which joins each regexp with |.
    //
    // Following the lead of Bash 4.1, note that "**" only has special meaning
    // when it is the *only* thing in a path portion.  Otherwise, any series
    // of * is equivalent to a single *.  Globstar behavior is enabled by
    // default, and can be disabled by setting options.noglobstar.
    Minimatch.prototype.parse = parse
    var SUBPARSE = {}
    function parse (pattern, isSub) {
      assertValidPattern(pattern)
    
      var options = this.options
    
      // shortcuts
      if (pattern === '**') {
        if (!options.noglobstar)
          return GLOBSTAR
        else
          pattern = '*'
      }
      if (pattern === '') return ''
    
      var re = ''
      var hasMagic = !!options.nocase
      var escaping = false
      // ? => one single character
      var patternListStack = []
      var negativeLists = []
      var stateChar
      var inClass = false
      var reClassStart = -1
      var classStart = -1
      // . and .. never match anything that doesn't start with .,
      // even when options.dot is set.
      var patternStart = pattern.charAt(0) === '.' ? '' // anything
      // not (start or / followed by . or .. followed by / or end)
      : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
      : '(?!\\.)'
      var self = this
    
      function clearStateChar () {
        if (stateChar) {
          // we had some state-tracking character
          // that wasn't consumed by this pass.
          switch (stateChar) {
            case '*':
              re += star
              hasMagic = true
            break
            case '?':
              re += qmark
              hasMagic = true
            break
            default:
              re += '\\' + stateChar
            break
          }
          self.debug('clearStateChar %j %j', stateChar, re)
          stateChar = false
        }
      }
    
      for (var i = 0, len = pattern.length, c
        ; (i < len) && (c = pattern.charAt(i))
        ; i++) {
        this.debug('%s\t%s %s %j', pattern, i, re, c)
    
        // skip over any that are escaped.
        if (escaping && reSpecials[c]) {
          re += '\\' + c
          escaping = false
          continue
        }
    
        switch (c) {
          /* istanbul ignore next */
          case '/': {
            // completely not allowed, even escaped.
            // Should already be path-split by now.
            return false
          }
    
          case '\\':
            clearStateChar()
            escaping = true
          continue
    
          // the various stateChar values
          // for the "extglob" stuff.
          case '?':
          case '*':
          case '+':
          case '@':
          case '!':
            this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
    
            // all of those are literals inside a class, except that
            // the glob [!a] means [^a] in regexp
            if (inClass) {
              this.debug('  in class')
              if (c === '!' && i === classStart + 1) c = '^'
              re += c
              continue
            }
    
            // if we already have a stateChar, then it means
            // that there was something like ** or +? in there.
            // Handle the stateChar, then proceed with this one.
            self.debug('call clearStateChar %j', stateChar)
            clearStateChar()
            stateChar = c
            // if extglob is disabled, then +(asdf|foo) isn't a thing.
            // just clear the statechar *now*, rather than even diving into
            // the patternList stuff.
            if (options.noext) clearStateChar()
          continue
    
          case '(':
            if (inClass) {
              re += '('
              continue
            }
    
            if (!stateChar) {
              re += '\\('
              continue
            }
    
            patternListStack.push({
              type: stateChar,
              start: i - 1,
              reStart: re.length,
              open: plTypes[stateChar].open,
              close: plTypes[stateChar].close
            })
            // negation is (?:(?!js)[^/]*)
            re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
            this.debug('plType %j %j', stateChar, re)
            stateChar = false
          continue
    
          case ')':
            if (inClass || !patternListStack.length) {
              re += '\\)'
              continue
            }
    
            clearStateChar()
            hasMagic = true
            var pl = patternListStack.pop()
            // negation is (?:(?!js)[^/]*)
            // The others are (?:<pattern>)<type>
            re += pl.close
            if (pl.type === '!') {
              negativeLists.push(pl)
            }
            pl.reEnd = re.length
          continue
    
          case '|':
            if (inClass || !patternListStack.length || escaping) {
              re += '\\|'
              escaping = false
              continue
            }
    
            clearStateChar()
            re += '|'
          continue
    
          // these are mostly the same in regexp and glob
          case '[':
            // swallow any state-tracking char before the [
            clearStateChar()
    
            if (inClass) {
              re += '\\' + c
              continue
            }
    
            inClass = true
            classStart = i
            reClassStart = re.length
            re += c
          continue
    
          case ']':
            //  a right bracket shall lose its special
            //  meaning and represent itself in
            //  a bracket expression if it occurs
            //  first in the list.  -- POSIX.2 2.8.3.2
            if (i === classStart + 1 || !inClass) {
              re += '\\' + c
              escaping = false
              continue
            }
    
            // handle the case where we left a class open.
            // "[z-a]" is valid, equivalent to "\[z-a\]"
            // split where the last [ was, make sure we don't have
            // an invalid re. if so, re-walk the contents of the
            // would-be class to re-translate any characters that
            // were passed through as-is
            // TODO: It would probably be faster to determine this
            // without a try/catch and a new RegExp, but it's tricky
            // to do safely.  For now, this is safe and works.
            var cs = pattern.substring(classStart + 1, i)
            try {
              RegExp('[' + cs + ']')
            } catch (er) {
              // not a valid class!
              var sp = this.parse(cs, SUBPARSE)
              re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
              hasMagic = hasMagic || sp[1]
              inClass = false
              continue
            }
    
            // finish up the class.
            hasMagic = true
            inClass = false
            re += c
          continue
    
          default:
            // swallow any state char that wasn't consumed
            clearStateChar()
    
            if (escaping) {
              // no need
              escaping = false
            } else if (reSpecials[c]
              && !(c === '^' && inClass)) {
              re += '\\'
            }
    
            re += c
    
        } // switch
      } // for
    
      // handle the case where we left a class open.
      // "[abc" is valid, equivalent to "\[abc"
      if (inClass) {
        // split where the last [ was, and escape it
        // this is a huge pita.  We now have to re-walk
        // the contents of the would-be class to re-translate
        // any characters that were passed through as-is
        cs = pattern.substr(classStart + 1)
        sp = this.parse(cs, SUBPARSE)
        re = re.substr(0, reClassStart) + '\\[' + sp[0]
        hasMagic = hasMagic || sp[1]
      }
    
      // handle the case where we had a +( thing at the *end*
      // of the pattern.
      // each pattern list stack adds 3 chars, and we need to go through
      // and escape any | chars that were passed through as-is for the regexp.
      // Go through and escape them, taking care not to double-escape any
      // | chars that were already escaped.
      for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
        var tail = re.slice(pl.reStart + pl.open.length)
        this.debug('setting tail', re, pl)
        // maybe some even number of \, then maybe 1 \, followed by a |
        tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
          if (!$2) {
            // the | isn't already escaped, so escape it.
            $2 = '\\'
          }
    
          // need to escape all those slashes *again*, without escaping the
          // one that we need for escaping the | character.  As it works out,
          // escaping an even number of slashes can be done by simply repeating
          // it exactly after itself.  That's why this trick works.
          //
          // I am sorry that you have to see this.
          return $1 + $1 + $2 + '|'
        })
    
        this.debug('tail=%j\n   %s', tail, tail, pl, re)
        var t = pl.type === '*' ? star
          : pl.type === '?' ? qmark
          : '\\' + pl.type
    
        hasMagic = true
        re = re.slice(0, pl.reStart) + t + '\\(' + tail
      }
    
      // handle trailing things that only matter at the very end.
      clearStateChar()
      if (escaping) {
        // trailing \\
        re += '\\\\'
      }
    
      // only need to apply the nodot start if the re starts with
      // something that could conceivably capture a dot
      var addPatternStart = false
      switch (re.charAt(0)) {
        case '[': case '.': case '(': addPatternStart = true
      }
    
      // Hack to work around lack of negative lookbehind in JS
      // A pattern like: *.!(x).!(y|z) needs to ensure that a name
      // like 'a.xyz.yz' doesn't match.  So, the first negative
      // lookahead, has to look ALL the way ahead, to the end of
      // the pattern.
      for (var n = negativeLists.length - 1; n > -1; n--) {
        var nl = negativeLists[n]
    
        var nlBefore = re.slice(0, nl.reStart)
        var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
        var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
        var nlAfter = re.slice(nl.reEnd)
    
        nlLast += nlAfter
    
        // Handle nested stuff like *(*.js|!(*.json)), where open parens
        // mean that we should *not* include the ) in the bit that is considered
        // "after" the negated section.
        var openParensBefore = nlBefore.split('(').length - 1
        var cleanAfter = nlAfter
        for (i = 0; i < openParensBefore; i++) {
          cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
        }
        nlAfter = cleanAfter
    
        var dollar = ''
        if (nlAfter === '' && isSub !== SUBPARSE) {
          dollar = '$'
        }
        var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
        re = newRe
      }
    
      // if the re is not "" at this point, then we need to make sure
      // it doesn't match against an empty path part.
      // Otherwise a/* will match a/, which it should not.
      if (re !== '' && hasMagic) {
        re = '(?=.)' + re
      }
    
      if (addPatternStart) {
        re = patternStart + re
      }
    
      // parsing just a piece of a larger pattern.
      if (isSub === SUBPARSE) {
        return [re, hasMagic]
      }
    
      // skip the regexp for non-magical patterns
      // unescape anything in it, though, so that it'll be
      // an exact match against a file etc.
      if (!hasMagic) {
        return globUnescape(pattern)
      }
    
      var flags = options.nocase ? 'i' : ''
      try {
        var regExp = new RegExp('^' + re + '$', flags)
      } catch (er) /* istanbul ignore next - should be impossible */ {
        // If it was an invalid regular expression, then it can't match
        // anything.  This trick looks for a character after the end of
        // the string, which is of course impossible, except in multi-line
        // mode, but it's not a /m regex.
        return new RegExp('$.')
      }
    
      regExp._glob = pattern
      regExp._src = re
    
      return regExp
    }
    
    minimatch.makeRe = function (pattern, options) {
      return new Minimatch(pattern, options || {}).makeRe()
    }
    
    Minimatch.prototype.makeRe = makeRe
    function makeRe () {
      if (this.regexp || this.regexp === false) return this.regexp
    
      // at this point, this.set is a 2d array of partial
      // pattern strings, or "**".
      //
      // It's better to use .match().  This function shouldn't
      // be used, really, but it's pretty convenient sometimes,
      // when you just want to work with a regex.
      var set = this.set
    
      if (!set.length) {
        this.regexp = false
        return this.regexp
      }
      var options = this.options
    
      var twoStar = options.noglobstar ? star
        : options.dot ? twoStarDot
        : twoStarNoDot
      var flags = options.nocase ? 'i' : ''
    
      var re = set.map(function (pattern) {
        return pattern.map(function (p) {
          return (p === GLOBSTAR) ? twoStar
          : (typeof p === 'string') ? regExpEscape(p)
          : p._src
        }).join('\\\/')
      }).join('|')
    
      // must match entire pattern
      // ending in a * or ** will make it less strict.
      re = '^(?:' + re + ')$'
    
      // can match anything, as long as it's not this.
      if (this.negate) re = '^(?!' + re + ').*$'
    
      try {
        this.regexp = new RegExp(re, flags)
      } catch (ex) /* istanbul ignore next - should be impossible */ {
        this.regexp = false
      }
      return this.regexp
    }
    
    minimatch.match = function (list, pattern, options) {
      options = options || {}
      var mm = new Minimatch(pattern, options)
      list = list.filter(function (f) {
        return mm.match(f)
      })
      if (mm.options.nonull && !list.length) {
        list.push(pattern)
      }
      return list
    }
    
    Minimatch.prototype.match = function match (f, partial) {
      if (typeof partial === 'undefined') partial = this.partial
      this.debug('match', f, this.pattern)
      // short-circuit in the case of busted things.
      // comments, etc.
      if (this.comment) return false
      if (this.empty) return f === ''
    
      if (f === '/' && partial) return true
    
      var options = this.options
    
      // windows: need to use /, not \
      if (path.sep !== '/') {
        f = f.split(path.sep).join('/')
      }
    
      // treat the test path as a set of pathparts.
      f = f.split(slashSplit)
      this.debug(this.pattern, 'split', f)
    
      // just ONE of the pattern sets in this.set needs to match
      // in order for it to be valid.  If negating, then just one
      // match means that we have failed.
      // Either way, return on the first hit.
    
      var set = this.set
      this.debug(this.pattern, 'set', set)
    
      // Find the basename of the path by looking for the last non-empty segment
      var filename
      var i
      for (i = f.length - 1; i >= 0; i--) {
        filename = f[i]
        if (filename) break
      }
    
      for (i = 0; i < set.length; i++) {
        var pattern = set[i]
        var file = f
        if (options.matchBase && pattern.length === 1) {
          file = [filename]
        }
        var hit = this.matchOne(file, pattern, partial)
        if (hit) {
          if (options.flipNegate) return true
          return !this.negate
        }
      }
    
      // didn't get any hits.  this is success if it's a negative
      // pattern, failure otherwise.
      if (options.flipNegate) return false
      return this.negate
    }
    
    // set partial to true to test if, for example,
    // "/a/b" matches the start of "/*/b/*/d"
    // Partial means, if you run out of file before you run
    // out of pattern, then that's fine, as long as all
    // the parts match.
    Minimatch.prototype.matchOne = function (file, pattern, partial) {
      var options = this.options
    
      this.debug('matchOne',
        { 'this': this, file: file, pattern: pattern })
    
      this.debug('matchOne', file.length, pattern.length)
    
      for (var fi = 0,
          pi = 0,
          fl = file.length,
          pl = pattern.length
          ; (fi < fl) && (pi < pl)
          ; fi++, pi++) {
        this.debug('matchOne loop')
        var p = pattern[pi]
        var f = file[fi]
    
        this.debug(pattern, p, f)
    
        // should be impossible.
        // some invalid regexp stuff in the set.
        /* istanbul ignore if */
        if (p === false) return false
    
        if (p === GLOBSTAR) {
          this.debug('GLOBSTAR', [pattern, p, f])
    
          // "**"
          // a/**/b/**/c would match the following:
          // a/b/x/y/z/c
          // a/x/y/z/b/c
          // a/b/x/b/x/c
          // a/b/c
          // To do this, take the rest of the pattern after
          // the **, and see if it would match the file remainder.
          // If so, return success.
          // If not, the ** "swallows" a segment, and try again.
          // This is recursively awful.
          //
          // a/**/b/**/c matching a/b/x/y/z/c
          // - a matches a
          // - doublestar
          //   - matchOne(b/x/y/z/c, b/**/c)
          //     - b matches b
          //     - doublestar
          //       - matchOne(x/y/z/c, c) -> no
          //       - matchOne(y/z/c, c) -> no
          //       - matchOne(z/c, c) -> no
          //       - matchOne(c, c) yes, hit
          var fr = fi
          var pr = pi + 1
          if (pr === pl) {
            this.debug('** at the end')
            // a ** at the end will just swallow the rest.
            // We have found a match.
            // however, it will not swallow /.x, unless
            // options.dot is set.
            // . and .. are *never* matched by **, for explosively
            // exponential reasons.
            for (; fi < fl; fi++) {
              if (file[fi] === '.' || file[fi] === '..' ||
                (!options.dot && file[fi].charAt(0) === '.')) return false
            }
            return true
          }
    
          // ok, let's see if we can swallow whatever we can.
          while (fr < fl) {
            var swallowee = file[fr]
    
            this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
    
            // XXX remove this slice.  Just pass the start index.
            if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
              this.debug('globstar found match!', fr, fl, swallowee)
              // found a match.
              return true
            } else {
              // can't swallow "." or ".." ever.
              // can only swallow ".foo" when explicitly asked.
              if (swallowee === '.' || swallowee === '..' ||
                (!options.dot && swallowee.charAt(0) === '.')) {
                this.debug('dot detected!', file, fr, pattern, pr)
                break
              }
    
              // ** swallows a segment, and continue.
              this.debug('globstar swallow a segment, and continue')
              fr++
            }
          }
    
          // no match was found.
          // However, in partial mode, we can't say this is necessarily over.
          // If there's more *pattern* left, then
          /* istanbul ignore if */
          if (partial) {
            // ran out of file
            this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
            if (fr === fl) return true
          }
          return false
        }
    
        // something other than **
        // non-magic patterns just have to match exactly
        // patterns with magic have been turned into regexps.
        var hit
        if (typeof p === 'string') {
          hit = f === p
          this.debug('string match', p, f, hit)
        } else {
          hit = f.match(p)
          this.debug('pattern match', p, f, hit)
        }
    
        if (!hit) return false
      }
    
      // Note: ending in / means that we'll get a final ""
      // at the end of the pattern.  This can only match a
      // corresponding "" at the end of the file.
      // If the file ends in /, then it can only match a
      // a pattern that ends in /, unless the pattern just
      // doesn't have any more for it. But, a/b/ should *not*
      // match "a/b/*", even though "" matches against the
      // [^/]*? pattern, except in partial mode, where it might
      // simply not be reached yet.
      // However, a/b/ should still satisfy a/*
    
      // now either we fell off the end of the pattern, or we're done.
      if (fi === fl && pi === pl) {
        // ran out of pattern and filename at the same time.
        // an exact hit!
        return true
      } else if (fi === fl) {
        // ran out of file, but still had pattern left.
        // this is ok if we're doing the match as part of
        // a glob fs traversal.
        return partial
      } else /* istanbul ignore else */ if (pi === pl) {
        // ran out of pattern, still have file left.
        // this is only acceptable if we're on the very last
        // empty segment of a file with a trailing slash.
        // a/* should match a/b/
        return (fi === fl - 1) && (file[fi] === '')
      }
    
      // should be unreachable.
      /* istanbul ignore next */
      throw new Error('wtf?')
    }
    
    // replace stuff like \* with *
    function globUnescape (s) {
      return s.replace(/\\(.)/g, '$1')
    }
    
    function regExpEscape (s) {
      return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
    }
    
    },{"brace-expansion":34,"path":313}],197:[function(require,module,exports){
    module.exports = function (args, opts) {
        if (!opts) opts = {};
        
        var flags = { bools : {}, strings : {}, unknownFn: null };
    
        if (typeof opts['unknown'] === 'function') {
            flags.unknownFn = opts['unknown'];
        }
    
        if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
          flags.allBools = true;
        } else {
          [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
              flags.bools[key] = true;
          });
        }
        
        var aliases = {};
        Object.keys(opts.alias || {}).forEach(function (key) {
            aliases[key] = [].concat(opts.alias[key]);
            aliases[key].forEach(function (x) {
                aliases[x] = [key].concat(aliases[key].filter(function (y) {
                    return x !== y;
                }));
            });
        });
    
        [].concat(opts.string).filter(Boolean).forEach(function (key) {
            flags.strings[key] = true;
            if (aliases[key]) {
                flags.strings[aliases[key]] = true;
            }
         });
    
        var defaults = opts['default'] || {};
        
        var argv = { _ : [] };
        Object.keys(flags.bools).forEach(function (key) {
            setArg(key, defaults[key] === undefined ? false : defaults[key]);
        });
        
        var notFlags = [];
    
        if (args.indexOf('--') !== -1) {
            notFlags = args.slice(args.indexOf('--')+1);
            args = args.slice(0, args.indexOf('--'));
        }
    
        function argDefined(key, arg) {
            return (flags.allBools && /^--[^=]+$/.test(arg)) ||
                flags.strings[key] || flags.bools[key] || aliases[key];
        }
    
        function setArg (key, val, arg) {
            if (arg && flags.unknownFn && !argDefined(key, arg)) {
                if (flags.unknownFn(arg) === false) return;
            }
    
            var value = !flags.strings[key] && isNumber(val)
                ? Number(val) : val
            ;
            setKey(argv, key.split('.'), value);
            
            (aliases[key] || []).forEach(function (x) {
                setKey(argv, x.split('.'), value);
            });
        }
    
        function setKey (obj, keys, value) {
            var o = obj;
            for (var i = 0; i < keys.length-1; i++) {
                var key = keys[i];
                if (key === '__proto__') return;
                if (o[key] === undefined) o[key] = {};
                if (o[key] === Object.prototype || o[key] === Number.prototype
                    || o[key] === String.prototype) o[key] = {};
                if (o[key] === Array.prototype) o[key] = [];
                o = o[key];
            }
    
            var key = keys[keys.length - 1];
            if (key === '__proto__') return;
            if (o === Object.prototype || o === Number.prototype
                || o === String.prototype) o = {};
            if (o === Array.prototype) o = [];
            if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
                o[key] = value;
            }
            else if (Array.isArray(o[key])) {
                o[key].push(value);
            }
            else {
                o[key] = [ o[key], value ];
            }
        }
        
        function aliasIsBoolean(key) {
          return aliases[key].some(function (x) {
              return flags.bools[x];
          });
        }
    
        for (var i = 0; i < args.length; i++) {
            var arg = args[i];
            
            if (/^--.+=/.test(arg)) {
                // Using [\s\S] instead of . because js doesn't support the
                // 'dotall' regex modifier. See:
                // http://stackoverflow.com/a/1068308/13216
                var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
                var key = m[1];
                var value = m[2];
                if (flags.bools[key]) {
                    value = value !== 'false';
                }
                setArg(key, value, arg);
            }
            else if (/^--no-.+/.test(arg)) {
                var key = arg.match(/^--no-(.+)/)[1];
                setArg(key, false, arg);
            }
            else if (/^--.+/.test(arg)) {
                var key = arg.match(/^--(.+)/)[1];
                var next = args[i + 1];
                if (next !== undefined && !/^-/.test(next)
                && !flags.bools[key]
                && !flags.allBools
                && (aliases[key] ? !aliasIsBoolean(key) : true)) {
                    setArg(key, next, arg);
                    i++;
                }
                else if (/^(true|false)$/.test(next)) {
                    setArg(key, next === 'true', arg);
                    i++;
                }
                else {
                    setArg(key, flags.strings[key] ? '' : true, arg);
                }
            }
            else if (/^-[^-]+/.test(arg)) {
                var letters = arg.slice(1,-1).split('');
                
                var broken = false;
                for (var j = 0; j < letters.length; j++) {
                    var next = arg.slice(j+2);
                    
                    if (next === '-') {
                        setArg(letters[j], next, arg)
                        continue;
                    }
                    
                    if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
                        setArg(letters[j], next.split('=')[1], arg);
                        broken = true;
                        break;
                    }
                    
                    if (/[A-Za-z]/.test(letters[j])
                    && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
                        setArg(letters[j], next, arg);
                        broken = true;
                        break;
                    }
                    
                    if (letters[j+1] && letters[j+1].match(/\W/)) {
                        setArg(letters[j], arg.slice(j+2), arg);
                        broken = true;
                        break;
                    }
                    else {
                        setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
                    }
                }
                
                var key = arg.slice(-1)[0];
                if (!broken && key !== '-') {
                    if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
                    && !flags.bools[key]
                    && (aliases[key] ? !aliasIsBoolean(key) : true)) {
                        setArg(key, args[i+1], arg);
                        i++;
                    }
                    else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {
                        setArg(key, args[i+1] === 'true', arg);
                        i++;
                    }
                    else {
                        setArg(key, flags.strings[key] ? '' : true, arg);
                    }
                }
            }
            else {
                if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
                    argv._.push(
                        flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
                    );
                }
                if (opts.stopEarly) {
                    argv._.push.apply(argv._, args.slice(i + 1));
                    break;
                }
            }
        }
        
        Object.keys(defaults).forEach(function (key) {
            if (!hasKey(argv, key.split('.'))) {
                setKey(argv, key.split('.'), defaults[key]);
                
                (aliases[key] || []).forEach(function (x) {
                    setKey(argv, x.split('.'), defaults[key]);
                });
            }
        });
        
        if (opts['--']) {
            argv['--'] = new Array();
            notFlags.forEach(function(key) {
                argv['--'].push(key);
            });
        }
        else {
            notFlags.forEach(function(key) {
                argv._.push(key);
            });
        }
    
        return argv;
    };
    
    function hasKey (obj, keys) {
        var o = obj;
        keys.slice(0,-1).forEach(function (key) {
            o = (o[key] || {});
        });
    
        var key = keys[keys.length - 1];
        return key in o;
    }
    
    function isNumber (x) {
        if (typeof x === 'number') return true;
        if (/^0x[0-9a-f]+$/i.test(x)) return true;
        return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
    }
    
    
    },{}],198:[function(require,module,exports){
    module.exports = require('../lib/ecies')
    
    },{"../lib/ecies":216}],199:[function(require,module,exports){
    (function (global,Buffer){(function (){
    'use strict'
    
    var mvc = module.exports
    
    // module information
    mvc.version = 'v' + require('./package.json').version
    mvc.versionGuard = function (version) {
      if (version !== undefined) {
        var message = `
          More than one instance of mvc found.
          Please make sure to require mvc and check that submodules do
          not also include their own mvc dependency.`
        console.warn(message)
      }
    }
    mvc.versionGuard(global._mvc)
    global._mvc = mvc.version
    
    // crypto
    mvc.crypto = {}
    mvc.crypto.BN = require('./lib/crypto/bn')
    mvc.crypto.ECDSA = require('./lib/crypto/ecdsa')
    mvc.crypto.Hash = require('./lib/crypto/hash')
    mvc.crypto.Random = require('./lib/crypto/random')
    mvc.crypto.Point = require('./lib/crypto/point')
    mvc.crypto.Signature = require('./lib/crypto/signature')
    
    // encoding
    mvc.encoding = {}
    mvc.encoding.Base58 = require('./lib/encoding/base58')
    mvc.encoding.Base58Check = require('./lib/encoding/base58check')
    mvc.encoding.BufferReader = require('./lib/encoding/bufferreader')
    mvc.encoding.BufferWriter = require('./lib/encoding/bufferwriter')
    mvc.encoding.Varint = require('./lib/encoding/varint')
    
    // utilities
    mvc.util = {}
    mvc.util.js = require('./lib/util/js')
    mvc.util.preconditions = require('./lib/util/preconditions')
    
    // errors thrown by the library
    mvc.errors = require('./lib/errors')
    
    // main bitcoin library
    mvc.Address = require('./lib/address')
    mvc.Block = require('./lib/block')
    mvc.MerkleBlock = require('./lib/block/merkleblock')
    mvc.BlockHeader = require('./lib/block/blockheader')
    mvc.HDPrivateKey = require('./lib/hdprivatekey.js')
    mvc.HDPublicKey = require('./lib/hdpublickey.js')
    mvc.Networks = require('./lib/networks')
    mvc.Opcode = require('./lib/opcode')
    mvc.PrivateKey = require('./lib/privatekey')
    mvc.PublicKey = require('./lib/publickey')
    mvc.Script = require('./lib/script')
    mvc.Transaction = require('./lib/transaction')
    
    // dependencies, subject to change
    mvc.deps = {}
    mvc.deps.bnjs = require('bn.js')
    mvc.deps.bs58 = require('bs58')
    mvc.deps.Buffer = Buffer
    mvc.deps.elliptic = require('elliptic')
    mvc.deps._ = require('./lib/util/_')
    
    // Internal usage, exposed for testing/advanced tweaking
    mvc.Transaction.sighash = require('./lib/transaction/sighash')
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
    
    },{"./lib/address":200,"./lib/block":203,"./lib/block/blockheader":202,"./lib/block/merkleblock":204,"./lib/crypto/bn":205,"./lib/crypto/ecdsa":206,"./lib/crypto/hash":208,"./lib/crypto/point":210,"./lib/crypto/random":211,"./lib/crypto/signature":212,"./lib/encoding/base58":217,"./lib/encoding/base58check":218,"./lib/encoding/bufferreader":219,"./lib/encoding/bufferwriter":220,"./lib/encoding/varint":226,"./lib/errors":227,"./lib/hdprivatekey.js":229,"./lib/hdpublickey.js":230,"./lib/networks":244,"./lib/opcode":245,"./lib/privatekey":246,"./lib/publickey":247,"./lib/script":248,"./lib/transaction":258,"./lib/transaction/sighash":266,"./lib/util/_":270,"./lib/util/js":271,"./lib/util/preconditions":272,"./package.json":277,"bn.js":275,"bs58":85,"buffer":84,"elliptic":118}],200:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('./util/_')
    var $ = require('./util/preconditions')
    var errors = require('./errors')
    var Base58Check = require('./encoding/base58check')
    var Networks = require('./networks')
    var Hash = require('./crypto/hash')
    var JSUtil = require('./util/js')
    var PublicKey = require('./publickey')
    
    /**
     * Instantiate an address from an address String or Buffer, a public key or script hash Buffer,
     * or an instance of {@link PublicKey} or {@link Script}.
     *
     * This is an immutable class, and if the first parameter provided to this constructor is an
     * `Address` instance, the same argument will be returned.
     *
     * An address has two key properties: `network` and `type`. The type is either
     * `Address.PayToPublicKeyHash` (value is the `'pubkeyhash'` string)
     * or `Address.PayToScriptHash` (the string `'scripthash'`). The network is an instance of {@link Network}.
     * You can quickly check whether an address is of a given kind by using the methods
     * `isPayToPublicKeyHash` and `isPayToScriptHash`
     *
     * @example
     * ```javascript
     * // validate that an input field is valid
     * var error = Address.getValidationError(input, 'testnet');
     * if (!error) {
     *   var address = Address(input, 'testnet');
     * } else {
     *   // invalid network or checksum (typo?)
     *   var message = error.messsage;
     * }
     *
     * // get an address from a public key
     * var address = Address(publicKey, 'testnet').toString();
     * ```
     *
     * @param {*} data - The encoded data in various formats
     * @param {Network|String|number=} network - The network: 'livenet' or 'testnet'
     * @param {string=} type - The type of address: 'script' or 'pubkey'
     * @returns {Address} A new valid and frozen instance of an Address
     * @constructor
     */
    function Address (data, network, type) {
      if (!(this instanceof Address)) {
        return new Address(data, network, type)
      }
    
      if (_.isArray(data) && _.isNumber(network)) {
        return Address.createMultisig(data, network, type)
      }
    
      if (data instanceof Address) {
        // Immutable instance
        return data
      }
    
      $.checkArgument(data, 'First argument is required, please include address data.', 'guide/address.html')
    
      if (network && !Networks.get(network)) {
        throw new TypeError('Second argument must be "livenet", "testnet", or "regtest".')
      }
    
      if (type && (type !== Address.PayToPublicKeyHash && type !== Address.PayToScriptHash)) {
        throw new TypeError('Third argument must be "pubkeyhash" or "scripthash".')
      }
    
      var info = this._classifyArguments(data, network, type)
    
      // set defaults if not set
      info.network = info.network || Networks.get(network) || Networks.defaultNetwork
      info.type = info.type || type || Address.PayToPublicKeyHash
    
      JSUtil.defineImmutable(this, {
        hashBuffer: info.hashBuffer,
        network: info.network,
        type: info.type
      })
    
      return this
    }
    
    /**
     * Internal function used to split different kinds of arguments of the constructor
     * @param {*} data - The encoded data in various formats
     * @param {Network|String|number=} network - The network: 'livenet' or 'testnet'
     * @param {string=} type - The type of address: 'script' or 'pubkey'
     * @returns {Object} An "info" object with "type", "network", and "hashBuffer"
     */
    Address.prototype._classifyArguments = function (data, network, type) {
      // transform and validate input data
      if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 20) {
        return Address._transformHash(data)
      } else if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 21) {
        return Address._transformBuffer(data, network, type)
      } else if (data instanceof PublicKey) {
        return Address._transformPublicKey(data)
      } else if (data instanceof Script) {
        return Address._transformScript(data, network)
      } else if (typeof (data) === 'string') {
        return Address._transformString(data, network, type)
      } else if (_.isObject(data)) {
        return Address._transformObject(data)
      } else {
        throw new TypeError('First argument is an unrecognized data format.')
      }
    }
    
    /** @static */
    Address.PayToPublicKeyHash = 'pubkeyhash'
    /** @static */
    Address.PayToScriptHash = 'scripthash'
    
    /**
     * @param {Buffer} hash - An instance of a hash Buffer
     * @returns {Object} An object with keys: hashBuffer
     * @private
     */
    Address._transformHash = function (hash) {
      var info = {}
      if (!(hash instanceof Buffer) && !(hash instanceof Uint8Array)) {
        throw new TypeError('Address supplied is not a buffer.')
      }
      if (hash.length !== 20) {
        throw new TypeError('Address hashbuffers must be exactly 20 bytes.')
      }
      info.hashBuffer = hash
      return info
    }
    
    /**
     * Deserializes an address serialized through `Address#toObject()`
     * @param {Object} data
     * @param {string} data.hash - the hash that this address encodes
     * @param {string} data.type - either 'pubkeyhash' or 'scripthash'
     * @param {Network=} data.network - the name of the network associated
     * @return {Address}
     */
    Address._transformObject = function (data) {
      $.checkArgument(data.hash || data.hashBuffer, 'Must provide a `hash` or `hashBuffer` property')
      $.checkArgument(data.type, 'Must provide a `type` property')
      return {
        hashBuffer: data.hash ? Buffer.from(data.hash, 'hex') : data.hashBuffer,
        network: Networks.get(data.network) || Networks.defaultNetwork,
        type: data.type
      }
    }
    
    /**
     * Internal function to discover the network and type based on the first data byte
     *
     * @param {Buffer} buffer - An instance of a hex encoded address Buffer
     * @returns {Object} An object with keys: network and type
     * @private
     */
    Address._classifyFromVersion = function (buffer) {
      var version = {}
    
      var pubkeyhashNetwork = Networks.get(buffer[0], 'pubkeyhash')
      var scripthashNetwork = Networks.get(buffer[0], 'scripthash')
    
      if (pubkeyhashNetwork) {
        version.network = pubkeyhashNetwork
        version.type = Address.PayToPublicKeyHash
      } else if (scripthashNetwork) {
        version.network = scripthashNetwork
        version.type = Address.PayToScriptHash
      }
    
      return version
    }
    
    /**
     * Internal function to transform a bitcoin address buffer
     *
     * @param {Buffer} buffer - An instance of a hex encoded address Buffer
     * @param {string=} network - The network: 'livenet' or 'testnet'
     * @param {string=} type - The type: 'pubkeyhash' or 'scripthash'
     * @returns {Object} An object with keys: hashBuffer, network and type
     * @private
     */
    Address._transformBuffer = function (buffer, network, type) {
      var info = {}
      if (!(buffer instanceof Buffer) && !(buffer instanceof Uint8Array)) {
        throw new TypeError('Address supplied is not a buffer.')
      }
      if (buffer.length !== 1 + 20) {
        throw new TypeError('Address buffers must be exactly 21 bytes.')
      }
    
      var networkObj = Networks.get(network)
      var bufferVersion = Address._classifyFromVersion(buffer)
    
      if (network && !networkObj) {
        throw new TypeError('Unknown network')
      }
    
      if (!bufferVersion.network || (networkObj && networkObj !== bufferVersion.network)) {
        // console.log(bufferVersion)
        throw new TypeError('Address has mismatched network type.')
      }
    
      if (!bufferVersion.type || (type && type !== bufferVersion.type)) {
        throw new TypeError('Address has mismatched type.')
      }
    
      info.hashBuffer = buffer.slice(1)
      info.network = bufferVersion.network
      info.type = bufferVersion.type
      return info
    }
    
    /**
     * Internal function to transform a {@link PublicKey}
     *
     * @param {PublicKey} pubkey - An instance of PublicKey
     * @returns {Object} An object with keys: hashBuffer, type
     * @private
     */
    Address._transformPublicKey = function (pubkey) {
      var info = {}
      if (!(pubkey instanceof PublicKey)) {
        throw new TypeError('Address must be an instance of PublicKey.')
      }
      info.hashBuffer = Hash.sha256ripemd160(pubkey.toBuffer())
      info.type = Address.PayToPublicKeyHash
      return info
    }
    
    /**
     * Internal function to transform a {@link Script} into a `info` object.
     *
     * @param {Script} script - An instance of Script
     * @returns {Object} An object with keys: hashBuffer, type
     * @private
     */
    Address._transformScript = function (script, network) {
      $.checkArgument(script instanceof Script, 'script must be a Script instance')
      var info = script.getAddressInfo(network)
      if (!info) {
        throw new errors.Script.CantDeriveAddress(script)
      }
      return info
    }
    
    /**
     * Creates a P2SH address from a set of public keys and a threshold.
     *
     * The addresses will be sorted lexicographically, as that is the trend in bitcoin.
     * To create an address from unsorted public keys, use the {@link Script#buildMultisigOut}
     * interface.
     *
     * @param {Array} publicKeys - a set of public keys to create an address
     * @param {number} threshold - the number of signatures needed to release the funds
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @return {Address}
     */
    Address.createMultisig = function (publicKeys, threshold, network) {
      network = network || publicKeys[0].network || Networks.defaultNetwork
      return Address.payingTo(Script.buildMultisigOut(publicKeys, threshold), network)
    }
    
    /**
     * Internal function to transform a bitcoin cash address string
     *
     * @param {string} data
     * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
     * @param {string=} type - The type: 'pubkeyhash' or 'scripthash'
     * @returns {Object} An object with keys: hashBuffer, network and type
     * @private
     */
    Address._transformString = function (data, network, type) {
      if (typeof (data) !== 'string') {
        throw new TypeError('data parameter supplied is not a string.')
      }
      if (data.length < 27) {
        throw new Error('Invalid Address string provided')
      }
      data = data.trim()
      var networkObj = Networks.get(network)
    
      if (network && !networkObj) {
        throw new TypeError('Unknown network')
      }
    
      var addressBuffer = Base58Check.decode(data)
      return Address._transformBuffer(addressBuffer, network, type)
    }
    
    /**
     * Instantiate an address from a PublicKey instance
     *
     * @param {PublicKey} data
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromPublicKey = function (data, network) {
      var info = Address._transformPublicKey(data)
      network = network || Networks.defaultNetwork
      return new Address(info.hashBuffer, network, info.type)
    }
    
    /**
     * Instantiate an address from a PrivateKey instance
     *
     * @param {PrivateKey} privateKey
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromPrivateKey = function (privateKey, network) {
      let publicKey = PublicKey.fromPrivateKey(privateKey)
      network = network || privateKey.network || Networks.defaultNetwork
      return Address.fromPublicKey(publicKey, network)
    }
    
    /**
     * Instantiate an address from a ripemd160 public key hash
     *
     * @param {Buffer} hash - An instance of buffer of the hash
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromPublicKeyHash = function (hash, network) {
      var info = Address._transformHash(hash)
      return new Address(info.hashBuffer, network, Address.PayToPublicKeyHash)
    }
    
    /**
     * Instantiate an address from a ripemd160 script hash
     *
     * @param {Buffer} hash - An instance of buffer of the hash
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromScriptHash = function (hash, network) {
      $.checkArgument(hash, 'hash parameter is required')
      var info = Address._transformHash(hash)
      return new Address(info.hashBuffer, network, Address.PayToScriptHash)
    }
    
    /**
     * Builds a p2sh address paying to script. This will hash the script and
     * use that to create the address.
     * If you want to extract an address associated with a script instead,
     * see {{Address#fromScript}}
     *
     * @param {Script} script - An instance of Script
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.payingTo = function (script, network) {
      $.checkArgument(script, 'script is required')
      $.checkArgument(script instanceof Script, 'script must be instance of Script')
    
      return Address.fromScriptHash(Hash.sha256ripemd160(script.toBuffer()), network)
    }
    
    /**
     * Extract address from a Script. The script must be of one
     * of the following types: p2pkh input, p2pkh output, p2sh input
     * or p2sh output.
     * This will analyze the script and extract address information from it.
     * If you want to transform any script to a p2sh Address paying
     * to that script's hash instead, use {{Address#payingTo}}
     *
     * @param {Script} script - An instance of Script
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromScript = function (script, network) {
      $.checkArgument(script instanceof Script, 'script must be a Script instance')
      var info = Address._transformScript(script, network)
      return new Address(info.hashBuffer, network, info.type)
    }
    
    /**
     * Instantiate an address from a buffer of the address
     *
     * @param {Buffer} buffer - An instance of buffer of the address
     * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
     * @param {string=} type - The type of address: 'script' or 'pubkey'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromBuffer = function (buffer, network, type) {
      var info = Address._transformBuffer(buffer, network, type)
      return new Address(info.hashBuffer, info.network, info.type)
    }
    
    Address.fromHex = function (hex, network, type) {
      return Address.fromBuffer(Buffer.from(hex, 'hex'), network, type)
    }
    
    /**
     * Instantiate an address from an address string
     *
     * @param {string} str - An string of the bitcoin address
     * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
     * @param {string=} type - The type of address: 'script' or 'pubkey'
     * @returns {Address} A new valid and frozen instance of an Address
     */
    Address.fromString = function (str, network, type) {
      var info = Address._transformString(str, network, type)
      return new Address(info.hashBuffer, info.network, info.type)
    }
    
    /**
     * Instantiate an address from an Object
     *
     * @param {string} json - An JSON string or Object with keys: hash, network and type
     * @returns {Address} A new valid instance of an Address
     */
    Address.fromObject = function fromObject (obj) {
      $.checkState(
        JSUtil.isHexa(obj.hash),
        'Unexpected hash property, "' + obj.hash + '", expected to be hex.'
      )
      var hashBuffer = Buffer.from(obj.hash, 'hex')
      return new Address(hashBuffer, obj.network, obj.type)
    }
    
    /**
     * Will return a validation error if exists
     *
     * @example
     * ```javascript
     * // a network mismatch error
     * var error = Address.getValidationError('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'testnet');
     * ```
     *
     * @param {string} data - The encoded data
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @param {string} type - The type of address: 'script' or 'pubkey'
     * @returns {null|Error} The corresponding error message
     */
    Address.getValidationError = function (data, network, type) {
      var error
      try {
        new Address(data, network, type) // eslint-disable-line
      } catch (e) {
        error = e
      }
      return error
    }
    
    /**
     * Will return a boolean if an address is valid
     *
     * @example
     * ```javascript
     * assert(Address.isValid('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'livenet'));
     * ```
     *
     * @param {string} data - The encoded data
     * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
     * @param {string} type - The type of address: 'script' or 'pubkey'
     * @returns {boolean} The corresponding error message
     */
    Address.isValid = function (data, network, type) {
      return !Address.getValidationError(data, network, type)
    }
    
    /**
     * Returns true if an address is of pay to public key hash type
     * @return boolean
     */
    Address.prototype.isPayToPublicKeyHash = function () {
      return this.type === Address.PayToPublicKeyHash
    }
    
    /**
     * Returns true if an address is of pay to script hash type
     * @return boolean
     */
    Address.prototype.isPayToScriptHash = function () {
      return this.type === Address.PayToScriptHash
    }
    
    /**
     * Will return a buffer representation of the address
     *
     * @returns {Buffer} Bitcoin address buffer
     */
    Address.prototype.toBuffer = function () {
      var version = Buffer.from([this.network[this.type]])
      var buf = Buffer.concat([version, this.hashBuffer])
      return buf
    }
    
    Address.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * @returns {Object} A plain object with the address information
     */
    Address.prototype.toObject = Address.prototype.toJSON = function toObject () {
      return {
        hash: this.hashBuffer.toString('hex'),
        type: this.type,
        network: this.network.toString()
      }
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {string} Bitcoin address
     */
    Address.prototype.inspect = function () {
      return '<Address: ' + this.toString() + ', type: ' + this.type + ', network: ' + this.network + '>'
    }
    
    /**
     * Will return a the base58 string representation of the address
     *
     * @returns {string} Bitcoin address
     */
    Address.prototype.toString = function () {
      return Base58Check.encode(this.toBuffer())
    }
    
    module.exports = Address
    
    var Script = require('./script')
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./crypto/hash":208,"./encoding/base58check":218,"./errors":227,"./networks":244,"./publickey":247,"./script":248,"./util/_":270,"./util/js":271,"./util/preconditions":272,"buffer":84}],201:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var BlockHeader = require('./blockheader')
    var BN = require('../crypto/bn')
    var BufferReader = require('../encoding/bufferreader')
    var BufferWriter = require('../encoding/bufferwriter')
    var Hash = require('../crypto/hash')
    var Transaction = require('../transaction')
    var $ = require('../util/preconditions')
    
    /**
     * Instantiate a Block from a Buffer, JSON object, or Object with
     * the properties of the Block
     *
     * @param {*} - A Buffer, JSON string, or Object
     * @returns {Block}
     * @constructor
     */
    function Block (arg) {
      if (!(this instanceof Block)) {
        return new Block(arg)
      }
      _.extend(this, Block._from(arg))
      return this
    }
    
    Block.MAX_BLOCK_SIZE = 128000000
    
    /**
     * @param {*} - A Buffer, JSON string or Object
     * @returns {Object} - An object representing block data
     * @throws {TypeError} - If the argument was not recognized
     * @private
     */
    Block._from = function _from (arg) {
      var info = {}
      if (Buffer.isBuffer(arg)) {
        info = Block._fromBufferReader(BufferReader(arg))
      } else if (_.isObject(arg)) {
        info = Block._fromObject(arg)
      } else {
        throw new TypeError('Unrecognized argument for Block')
      }
      return info
    }
    
    /**
     * @param {Object} - A plain JavaScript object
     * @returns {Object} - An object representing block data
     * @private
     */
    Block._fromObject = function _fromObject (data) {
      var transactions = []
      data.transactions.forEach(function (tx) {
        if (tx instanceof Transaction) {
          transactions.push(tx)
        } else {
          transactions.push(Transaction().fromObject(tx))
        }
      })
      var info = {
        header: BlockHeader.fromObject(data.header),
        transactions: transactions
      }
      return info
    }
    
    /**
     * @param {Object} - A plain JavaScript object
     * @returns {Block} - An instance of block
     */
    Block.fromObject = function fromObject (obj) {
      var info = Block._fromObject(obj)
      return new Block(info)
    }
    
    /**
     * @param {BufferReader} - Block data
     * @returns {Object} - An object representing the block data
     * @private
     */
    Block._fromBufferReader = function _fromBufferReader (br) {
      var info = {}
      $.checkState(!br.finished(), 'No block data received')
      info.header = BlockHeader.fromBufferReader(br)
      var transactions = br.readVarintNum()
      info.transactions = []
      for (var i = 0; i < transactions; i++) {
        info.transactions.push(Transaction().fromBufferReader(br))
      }
      return info
    }
    
    /**
     * @param {BufferReader} - A buffer reader of the block
     * @returns {Block} - An instance of block
     */
    Block.fromBufferReader = function fromBufferReader (br) {
      $.checkArgument(br, 'br is required')
      var info = Block._fromBufferReader(br)
      return new Block(info)
    }
    
    /**
     * @param {Buffer} - A buffer of the block
     * @returns {Block} - An instance of block
     */
    Block.fromBuffer = function fromBuffer (buf) {
      return Block.fromBufferReader(new BufferReader(buf))
    }
    
    /**
     * @param {string} - str - A hex encoded string of the block
     * @returns {Block} - A hex encoded string of the block
     */
    Block.fromString = function fromString (str) {
      var buf = Buffer.from(str, 'hex')
      return Block.fromBuffer(buf)
    }
    
    /**
     * @param {Binary} - Raw block binary data or buffer
     * @returns {Block} - An instance of block
     */
    Block.fromRawBlock = function fromRawBlock (data) {
      if (!Buffer.isBuffer(data)) {
        data = Buffer.from(data, 'binary')
      }
      var br = BufferReader(data)
      br.pos = Block.Values.START_OF_BLOCK
      var info = Block._fromBufferReader(br)
      return new Block(info)
    }
    
    /**
     * @returns {Object} - A plain object with the block properties
     */
    Block.prototype.toObject = Block.prototype.toJSON = function toObject () {
      var transactions = []
      this.transactions.forEach(function (tx) {
        transactions.push(tx.toObject())
      })
      return {
        header: this.header.toObject(),
        transactions: transactions
      }
    }
    
    /**
     * @returns {Buffer} - A buffer of the block
     */
    Block.prototype.toBuffer = function toBuffer () {
      return this.toBufferWriter().concat()
    }
    
    /**
     * @returns {string} - A hex encoded string of the block
     */
    Block.prototype.toString = function toString () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * @param {BufferWriter} - An existing instance of BufferWriter
     * @returns {BufferWriter} - An instance of BufferWriter representation of the Block
     */
    Block.prototype.toBufferWriter = function toBufferWriter (bw) {
      if (!bw) {
        bw = new BufferWriter()
      }
      bw.write(this.header.toBuffer())
      bw.writeVarintNum(this.transactions.length)
      for (var i = 0; i < this.transactions.length; i++) {
        this.transactions[i].toBufferWriter(bw)
      }
      return bw
    }
    
    /**
     * Will iterate through each transaction and return an array of hashes
     * @returns {Array} - An array with transaction hashes
     */
    Block.prototype.getTransactionHashes = function getTransactionHashes () {
      var hashes = []
      if (this.transactions.length === 0) {
        return [Block.Values.NULL_HASH]
      }
      for (var t = 0; t < this.transactions.length; t++) {
        hashes.push(this.transactions[t]._getHash())
      }
      return hashes
    }
    
    /**
     * Will build a merkle tree of all the transactions, ultimately arriving at
     * a single point, the merkle root.
     * @link https://en.bitcoin.it/wiki/Protocol_specification#Merkle_Trees
     * @returns {Array} - An array with each level of the tree after the other.
     */
    Block.prototype.getMerkleTree = function getMerkleTree () {
      var tree = this.getTransactionHashes()
    
      var j = 0
      for (var size = this.transactions.length; size > 1; size = Math.floor((size + 1) / 2)) {
        for (var i = 0; i < size; i += 2) {
          var i2 = Math.min(i + 1, size - 1)
          var buf = Buffer.concat([tree[j + i], tree[j + i2]])
          tree.push(Hash.sha256sha256(buf))
        }
        j += size
      }
    
      return tree
    }
    
    /**
     * Calculates the merkleRoot from the transactions.
     * @returns {Buffer} - A buffer of the merkle root hash
     */
    Block.prototype.getMerkleRoot = function getMerkleRoot () {
      var tree = this.getMerkleTree()
      return tree[tree.length - 1]
    }
    
    /**
     * Verifies that the transactions in the block match the header merkle root
     * @returns {Boolean} - If the merkle roots match
     */
    Block.prototype.validMerkleRoot = function validMerkleRoot () {
      var h = new BN(this.header.merkleRoot.toString('hex'), 'hex')
      var c = new BN(this.getMerkleRoot().toString('hex'), 'hex')
    
      if (h.cmp(c) !== 0) {
        return false
      }
    
      return true
    }
    
    /**
     * @returns {Buffer} - The little endian hash buffer of the header
     */
    Block.prototype._getHash = function () {
      return this.header._getHash()
    }
    
    var idProperty = {
      configurable: false,
      enumerable: true,
      /**
       * @returns {string} - The big endian hash buffer of the header
       */
      get: function () {
        if (!this._id) {
          this._id = this.header.id
        }
        return this._id
      },
      set: _.noop
    }
    Object.defineProperty(Block.prototype, 'id', idProperty)
    Object.defineProperty(Block.prototype, 'hash', idProperty)
    
    /**
     * @returns {string} - A string formatted for the console
     */
    Block.prototype.inspect = function inspect () {
      return '<Block ' + this.id + '>'
    }
    
    Block.Values = {
      START_OF_BLOCK: 8, // Start of block in raw block data
      NULL_HASH: Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
    }
    
    module.exports = Block
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"../crypto/hash":208,"../encoding/bufferreader":219,"../encoding/bufferwriter":220,"../transaction":258,"../util/_":270,"../util/preconditions":272,"./blockheader":202,"buffer":84}],202:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var BN = require('../crypto/bn')
    var BufferReader = require('../encoding/bufferreader')
    var BufferWriter = require('../encoding/bufferwriter')
    var Hash = require('../crypto/hash')
    var $ = require('../util/preconditions')
    
    var GENESIS_BITS = 0x1d00ffff
    
    /**
     * Instantiate a BlockHeader from a Buffer, JSON object, or Object with
     * the properties of the BlockHeader
     *
     * @param {*} - A Buffer, JSON string, or Object
     * @returns {BlockHeader} - An instance of block header
     * @constructor
     */
    var BlockHeader = function BlockHeader (arg) {
      if (!(this instanceof BlockHeader)) {
        return new BlockHeader(arg)
      }
      var info = BlockHeader._from(arg)
      this.version = info.version
      this.prevHash = info.prevHash
      this.merkleRoot = info.merkleRoot
      this.time = info.time
      this.timestamp = info.time
      this.bits = info.bits
      this.nonce = info.nonce
    
      if (info.hash) {
        $.checkState(
          this.hash === info.hash,
          'Argument object hash property does not match block hash.'
        )
      }
    
      return this
    }
    
    /**
     * @param {*} - A Buffer, JSON string or Object
     * @returns {Object} - An object representing block header data
     * @throws {TypeError} - If the argument was not recognized
     * @private
     */
    BlockHeader._from = function _from (arg) {
      var info = {}
      if (Buffer.isBuffer(arg)) {
        info = BlockHeader._fromBufferReader(BufferReader(arg))
      } else if (_.isObject(arg)) {
        info = BlockHeader._fromObject(arg)
      } else {
        throw new TypeError('Unrecognized argument for BlockHeader')
      }
      return info
    }
    
    /**
     * @param {Object} - A JSON string
     * @returns {Object} - An object representing block header data
     * @private
     */
    BlockHeader._fromObject = function _fromObject (data) {
      $.checkArgument(data, 'data is required')
      var prevHash = data.prevHash
      var merkleRoot = data.merkleRoot
      if (_.isString(data.prevHash)) {
        prevHash = Buffer.from(data.prevHash, 'hex').reverse()
      }
      if (_.isString(data.merkleRoot)) {
        merkleRoot = Buffer.from(data.merkleRoot, 'hex').reverse()
      }
      var info = {
        hash: data.hash,
        version: data.version,
        prevHash: prevHash,
        merkleRoot: merkleRoot,
        time: data.time,
        timestamp: data.time,
        bits: data.bits,
        nonce: data.nonce
      }
      return info
    }
    
    /**
     * @param {Object} - A plain JavaScript object
     * @returns {BlockHeader} - An instance of block header
     */
    BlockHeader.fromObject = function fromObject (obj) {
      var info = BlockHeader._fromObject(obj)
      return new BlockHeader(info)
    }
    
    /**
     * @param {Binary} - Raw block binary data or buffer
     * @returns {BlockHeader} - An instance of block header
     */
    BlockHeader.fromRawBlock = function fromRawBlock (data) {
      if (!Buffer.isBuffer(data)) {
        data = Buffer.from(data, 'binary')
      }
      var br = BufferReader(data)
      br.pos = BlockHeader.Constants.START_OF_HEADER
      var info = BlockHeader._fromBufferReader(br)
      return new BlockHeader(info)
    }
    
    /**
     * @param {Buffer} - A buffer of the block header
     * @returns {BlockHeader} - An instance of block header
     */
    BlockHeader.fromBuffer = function fromBuffer (buf) {
      var info = BlockHeader._fromBufferReader(BufferReader(buf))
      return new BlockHeader(info)
    }
    
    /**
     * @param {string} - A hex encoded buffer of the block header
     * @returns {BlockHeader} - An instance of block header
     */
    BlockHeader.fromString = function fromString (str) {
      var buf = Buffer.from(str, 'hex')
      return BlockHeader.fromBuffer(buf)
    }
    
    /**
     * @param {BufferReader} - A BufferReader of the block header
     * @returns {Object} - An object representing block header data
     * @private
     */
    BlockHeader._fromBufferReader = function _fromBufferReader (br) {
      var info = {}
      info.version = br.readInt32LE()
      info.prevHash = br.read(32)
      info.merkleRoot = br.read(32)
      info.time = br.readUInt32LE()
      info.bits = br.readUInt32LE()
      info.nonce = br.readUInt32LE()
      return info
    }
    
    /**
     * @param {BufferReader} - A BufferReader of the block header
     * @returns {BlockHeader} - An instance of block header
     */
    BlockHeader.fromBufferReader = function fromBufferReader (br) {
      var info = BlockHeader._fromBufferReader(br)
      return new BlockHeader(info)
    }
    
    /**
     * @returns {Object} - A plain object of the BlockHeader
     */
    BlockHeader.prototype.toObject = BlockHeader.prototype.toJSON = function toObject () {
      return {
        hash: this.hash,
        version: this.version,
        prevHash: Buffer.from(this.prevHash).reverse().toString('hex'),
        merkleRoot: Buffer.from(this.merkleRoot).reverse().toString('hex'),
        time: this.time,
        bits: this.bits,
        nonce: this.nonce
      }
    }
    
    /**
     * @returns {Buffer} - A Buffer of the BlockHeader
     */
    BlockHeader.prototype.toBuffer = function toBuffer () {
      return this.toBufferWriter().concat()
    }
    
    /**
     * @returns {string} - A hex encoded string of the BlockHeader
     */
    BlockHeader.prototype.toString = function toString () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * @param {BufferWriter} - An existing instance BufferWriter
     * @returns {BufferWriter} - An instance of BufferWriter representation of the BlockHeader
     */
    BlockHeader.prototype.toBufferWriter = function toBufferWriter (bw) {
      if (!bw) {
        bw = new BufferWriter()
      }
      bw.writeInt32LE(this.version)
      bw.write(this.prevHash)
      bw.write(this.merkleRoot)
      bw.writeUInt32LE(this.time)
      bw.writeUInt32LE(this.bits)
      bw.writeUInt32LE(this.nonce)
      return bw
    }
    
    /**
     * Returns the target difficulty for this block
     * @param {Number} bits
     * @returns {BN} An instance of BN with the decoded difficulty bits
     */
    BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty (bits) {
      bits = bits || this.bits
    
      var target = new BN(bits & 0xffffff)
      var mov = 8 * ((bits >>> 24) - 3)
      while (mov-- > 0) {
        target = target.mul(new BN(2))
      }
      return target
    }
    
    /**
     * @link https://en.bitcoin.it/wiki/Difficulty
     * @return {Number}
     */
    BlockHeader.prototype.getDifficulty = function getDifficulty () {
      var difficulty1TargetBN = this.getTargetDifficulty(GENESIS_BITS).mul(new BN(Math.pow(10, 8)))
      var currentTargetBN = this.getTargetDifficulty()
    
      var difficultyString = difficulty1TargetBN.div(currentTargetBN).toString(10)
      var decimalPos = difficultyString.length - 8
      difficultyString = difficultyString.slice(0, decimalPos) + '.' + difficultyString.slice(decimalPos)
    
      return parseFloat(difficultyString)
    }
    
    /**
     * @returns {Buffer} - The little endian hash buffer of the header
     */
    BlockHeader.prototype._getHash = function hash () {
      var buf = this.toBuffer()
      return Hash.sha256sha256(buf)
    }
    
    var idProperty = {
      configurable: false,
      enumerable: true,
      /**
       * @returns {string} - The big endian hash buffer of the header
       */
      get: function () {
        if (!this._id) {
          this._id = BufferReader(this._getHash()).readReverse().toString('hex')
        }
        return this._id
      },
      set: _.noop
    }
    Object.defineProperty(BlockHeader.prototype, 'id', idProperty)
    Object.defineProperty(BlockHeader.prototype, 'hash', idProperty)
    
    /**
     * @returns {Boolean} - If timestamp is not too far in the future
     */
    BlockHeader.prototype.validTimestamp = function validTimestamp () {
      var currentTime = Math.round(new Date().getTime() / 1000)
      if (this.time > currentTime + BlockHeader.Constants.MAX_TIME_OFFSET) {
        return false
      }
      return true
    }
    
    /**
     * @returns {Boolean} - If the proof-of-work hash satisfies the target difficulty
     */
    BlockHeader.prototype.validProofOfWork = function validProofOfWork () {
      var pow = new BN(this.id, 'hex')
      var target = this.getTargetDifficulty()
    
      if (pow.cmp(target) > 0) {
        return false
      }
      return true
    }
    
    /**
     * @returns {string} - A string formatted for the console
     */
    BlockHeader.prototype.inspect = function inspect () {
      return '<BlockHeader ' + this.id + '>'
    }
    
    BlockHeader.Constants = {
      START_OF_HEADER: 8, // Start buffer position in raw block data
      MAX_TIME_OFFSET: 2 * 60 * 60, // The max a timestamp can be in the future
      LARGEST_HASH: new BN('10000000000000000000000000000000000000000000000000000000000000000', 'hex')
    }
    
    module.exports = BlockHeader
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"../crypto/hash":208,"../encoding/bufferreader":219,"../encoding/bufferwriter":220,"../util/_":270,"../util/preconditions":272,"buffer":84}],203:[function(require,module,exports){
    module.exports = require('./block')
    
    module.exports.BlockHeader = require('./blockheader')
    module.exports.MerkleBlock = require('./merkleblock')
    
    },{"./block":201,"./blockheader":202,"./merkleblock":204}],204:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var BlockHeader = require('./blockheader')
    var BufferReader = require('../encoding/bufferreader')
    var BufferWriter = require('../encoding/bufferwriter')
    var Hash = require('../crypto/hash')
    var Transaction = require('../transaction')
    var errors = require('../errors')
    var $ = require('../util/preconditions')
    
    /**
     * Instantiate a MerkleBlock from a Buffer, JSON object, or Object with
     * the properties of the Block
     *
     * @param {*} - A Buffer, JSON string, or Object representing a MerkleBlock
     * @returns {MerkleBlock}
     * @constructor
     */
    function MerkleBlock (arg) {
      if (!(this instanceof MerkleBlock)) {
        return new MerkleBlock(arg)
      }
    
      var info = {}
      if (Buffer.isBuffer(arg)) {
        info = MerkleBlock._fromBufferReader(BufferReader(arg))
      } else if (_.isObject(arg)) {
        var header
        if (arg.header instanceof BlockHeader) {
          header = arg.header
        } else {
          header = BlockHeader.fromObject(arg.header)
        }
        info = {
          /**
           * @name MerkleBlock#header
           * @type {BlockHeader}
           */
          header: header,
          /**
           * @name MerkleBlock#numTransactions
           * @type {Number}
           */
          numTransactions: arg.numTransactions,
          /**
           * @name MerkleBlock#hashes
           * @type {String[]}
           */
          hashes: arg.hashes,
          /**
           * @name MerkleBlock#flags
           * @type {Number[]}
           */
          flags: arg.flags
        }
      } else {
        throw new TypeError('Unrecognized argument for MerkleBlock')
      }
      _.extend(this, info)
      this._flagBitsUsed = 0
      this._hashesUsed = 0
    
      return this
    }
    
    /**
     * @param {Buffer} - MerkleBlock data in a Buffer object
     * @returns {MerkleBlock} - A MerkleBlock object
     */
    MerkleBlock.fromBuffer = function fromBuffer (buf) {
      return MerkleBlock.fromBufferReader(BufferReader(buf))
    }
    
    /**
     * @param {BufferReader} - MerkleBlock data in a BufferReader object
     * @returns {MerkleBlock} - A MerkleBlock object
     */
    MerkleBlock.fromBufferReader = function fromBufferReader (br) {
      return new MerkleBlock(MerkleBlock._fromBufferReader(br))
    }
    
    /**
     * @returns {Buffer} - A buffer of the block
     */
    MerkleBlock.prototype.toBuffer = function toBuffer () {
      return this.toBufferWriter().concat()
    }
    
    /**
     * @param {BufferWriter} - An existing instance of BufferWriter
     * @returns {BufferWriter} - An instance of BufferWriter representation of the MerkleBlock
     */
    MerkleBlock.prototype.toBufferWriter = function toBufferWriter (bw) {
      if (!bw) {
        bw = new BufferWriter()
      }
      bw.write(this.header.toBuffer())
      bw.writeUInt32LE(this.numTransactions)
      bw.writeVarintNum(this.hashes.length)
      for (var i = 0; i < this.hashes.length; i++) {
        bw.write(Buffer.from(this.hashes[i], 'hex'))
      }
      bw.writeVarintNum(this.flags.length)
      for (i = 0; i < this.flags.length; i++) {
        bw.writeUInt8(this.flags[i])
      }
      return bw
    }
    
    /**
     * @returns {Object} - A plain object with the MerkleBlock properties
     */
    MerkleBlock.prototype.toObject = MerkleBlock.prototype.toJSON = function toObject () {
      return {
        header: this.header.toObject(),
        numTransactions: this.numTransactions,
        hashes: this.hashes,
        flags: this.flags
      }
    }
    
    /**
     * Verify that the MerkleBlock is valid
     * @returns {Boolean} - True/False whether this MerkleBlock is Valid
     */
    MerkleBlock.prototype.validMerkleTree = function validMerkleTree () {
      $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array')
      $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array')
    
      // Can't have more hashes than numTransactions
      if (this.hashes.length > this.numTransactions) {
        return false
      }
    
      // Can't have more flag bits than num hashes
      if (this.flags.length * 8 < this.hashes.length) {
        return false
      }
    
      var height = this._calcTreeHeight()
      var opts = { hashesUsed: 0, flagBitsUsed: 0 }
      var root = this._traverseMerkleTree(height, 0, opts)
      if (opts.hashesUsed !== this.hashes.length) {
        return false
      }
      return root.equals(this.header.merkleRoot)
    }
    
    /**
     * WARNING: This method is deprecated. Use filteredTxsHash instead.
     *
     * Return a list of all the txs hash that match the filter
     * @returns {Array} - txs hash that match the filter
     */
    MerkleBlock.prototype.filterdTxsHash = function filterdTxsHash () {
      throw new Error('filterdTxsHash has been deprecated. use filteredTxsHash.')
    }
    
    /**
     * Return a list of all the txs hash that match the filter
     * @returns {Array} - txs hash that match the filter
     */
    MerkleBlock.prototype.filteredTxsHash = function filteredTxsHash () {
      $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array')
      $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array')
    
      // Can't have more hashes than numTransactions
      if (this.hashes.length > this.numTransactions) {
        throw new errors.MerkleBlock.InvalidMerkleTree()
      }
    
      // Can't have more flag bits than num hashes
      if (this.flags.length * 8 < this.hashes.length) {
        throw new errors.MerkleBlock.InvalidMerkleTree()
      }
    
      // If there is only one hash the filter do not match any txs in the block
      if (this.hashes.length === 1) {
        return []
      };
    
      var height = this._calcTreeHeight()
      var opts = { hashesUsed: 0, flagBitsUsed: 0 }
      var txs = this._traverseMerkleTree(height, 0, opts, true)
      if (opts.hashesUsed !== this.hashes.length) {
        throw new errors.MerkleBlock.InvalidMerkleTree()
      }
      return txs
    }
    
    /**
     * Traverse a the tree in this MerkleBlock, validating it along the way
     * Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract()
     * @param {Number} - depth - Current height
     * @param {Number} - pos - Current position in the tree
     * @param {Object} - opts - Object with values that need to be mutated throughout the traversal
     * @param {Boolean} - checkForTxs - if true return opts.txs else return the Merkle Hash
     * @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0
     * @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0
     * @param {Array} - opts.txs - Will finish populated by transactions found during traversal that match the filter
     * @returns {Buffer|null} - Buffer containing the Merkle Hash for that height
     * @returns {Array} - transactions found during traversal that match the filter
     * @private
     */
    MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree (depth, pos, opts, checkForTxs) {
      opts = opts || {}
      opts.txs = opts.txs || []
      opts.flagBitsUsed = opts.flagBitsUsed || 0
      opts.hashesUsed = opts.hashesUsed || 0
      checkForTxs = checkForTxs || false
    
      if (opts.flagBitsUsed > this.flags.length * 8) {
        return null
      }
      var isParentOfMatch = (this.flags[opts.flagBitsUsed >> 3] >>> (opts.flagBitsUsed++ & 7)) & 1
      if (depth === 0 || !isParentOfMatch) {
        if (opts.hashesUsed >= this.hashes.length) {
          return null
        }
        var hash = this.hashes[opts.hashesUsed++]
        if (depth === 0 && isParentOfMatch) {
          opts.txs.push(hash)
        }
        return Buffer.from(hash, 'hex')
      } else {
        var left = this._traverseMerkleTree(depth - 1, pos * 2, opts)
        var right = left
        if (pos * 2 + 1 < this._calcTreeWidth(depth - 1)) {
          right = this._traverseMerkleTree(depth - 1, pos * 2 + 1, opts)
        }
        if (checkForTxs) {
          return opts.txs
        } else {
          return Hash.sha256sha256(Buffer.concat([left, right]))
        }
      }
    }
    
    /** Calculates the width of a merkle tree at a given height.
     *  Modeled after Bitcoin Core merkleblock.h CalcTreeWidth()
     * @param {Number} - Height at which we want the tree width
     * @returns {Number} - Width of the tree at a given height
     * @private
     */
    MerkleBlock.prototype._calcTreeWidth = function calcTreeWidth (height) {
      return (this.numTransactions + (1 << height) - 1) >> height
    }
    
    /** Calculates the height of the merkle tree in this MerkleBlock
     * @param {Number} - Height at which we want the tree width
     * @returns {Number} - Height of the merkle tree in this MerkleBlock
     * @private
     */
    MerkleBlock.prototype._calcTreeHeight = function calcTreeHeight () {
      var height = 0
      while (this._calcTreeWidth(height) > 1) {
        height++
      }
      return height
    }
    
    /**
     * @param {Transaction|String} - Transaction or Transaction ID Hash
     * @returns {Boolean} - return true/false if this MerkleBlock has the TX or not
     * @private
     */
    MerkleBlock.prototype.hasTransaction = function hasTransaction (tx) {
      $.checkArgument(!_.isUndefined(tx), 'tx cannot be undefined')
      $.checkArgument(tx instanceof Transaction || typeof tx === 'string',
        'Invalid tx given, tx must be a "string" or "Transaction"')
    
      var hash = tx
      if (tx instanceof Transaction) {
        // We need to reverse the id hash for the lookup
        hash = Buffer.from(tx.id, 'hex').reverse().toString('hex')
      }
    
      var txs = []
      var height = this._calcTreeHeight()
      this._traverseMerkleTree(height, 0, { txs: txs })
      return txs.indexOf(hash) !== -1
    }
    
    /**
     * @param {Buffer} - MerkleBlock data
     * @returns {Object} - An Object representing merkleblock data
     * @private
     */
    MerkleBlock._fromBufferReader = function _fromBufferReader (br) {
      $.checkState(!br.finished(), 'No merkleblock data received')
      var info = {}
      info.header = BlockHeader.fromBufferReader(br)
      info.numTransactions = br.readUInt32LE()
      var numHashes = br.readVarintNum()
      info.hashes = []
      for (var i = 0; i < numHashes; i++) {
        info.hashes.push(br.read(32).toString('hex'))
      }
      var numFlags = br.readVarintNum()
      info.flags = []
      for (i = 0; i < numFlags; i++) {
        info.flags.push(br.readUInt8())
      }
      return info
    }
    
    /**
     * @param {Object} - A plain JavaScript object
     * @returns {Block} - An instance of block
     */
    MerkleBlock.fromObject = function fromObject (obj) {
      return new MerkleBlock(obj)
    }
    
    module.exports = MerkleBlock
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/hash":208,"../encoding/bufferreader":219,"../encoding/bufferwriter":220,"../errors":227,"../transaction":258,"../util/_":270,"../util/preconditions":272,"./blockheader":202,"buffer":84}],205:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BN = require('bn.js')
    var $ = require('../util/preconditions')
    var _ = require('../util/_')
    
    var reversebuf = function (buf) {
      var buf2 = Buffer.alloc(buf.length)
      for (var i = 0; i < buf.length; i++) {
        buf2[i] = buf[buf.length - 1 - i]
      }
      return buf2
    }
    
    BN.Zero = new BN(0)
    BN.One = new BN(1)
    BN.Minus1 = new BN(-1)
    
    /**
     * Convert a number into a big number.
     *
     * @param {number} n Any positive or negative integer.
     */
    BN.fromNumber = function (n) {
      $.checkArgument(_.isNumber(n))
      return new BN(n)
    }
    
    /**
     * Convert a string number into a big number.
     *
     * @param {string} str Any positive or negative integer formatted as a string.
     * @param {number} base The base of the number, defaults to 10.
     */
    BN.fromString = function (str, base) {
      $.checkArgument(_.isString(str))
      return new BN(str, base)
    }
    
    /**
     * Convert a buffer (such as a 256 bit binary private key) into a big number.
     * Sometimes these numbers can be formatted either as 'big endian' or 'little
     * endian', and so there is an opts parameter that lets you specify which
     * endianness is specified.
     *
     * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
     * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
     */
    BN.fromBuffer = function (buf, opts) {
      if (typeof opts !== 'undefined' && opts.endian === 'little') {
        buf = reversebuf(buf)
      }
      var hex = buf.toString('hex')
      var bn = new BN(hex, 16)
      return bn
    }
    
    /**
     * Instantiate a BigNumber from a "signed magnitude buffer". (a buffer where the
     * most significant bit represents the sign (0 = positive, 1 = negative)
     *
     * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
     * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
     */
    BN.fromSM = function (buf, opts) {
      var ret
      if (buf.length === 0) {
        return BN.fromBuffer(Buffer.from([0]))
      }
    
      var endian = 'big'
      if (opts) {
        endian = opts.endian
      }
      if (endian === 'little') {
        buf = reversebuf(buf)
      }
    
      if (buf[0] & 0x80) {
        buf[0] = buf[0] & 0x7f
        ret = BN.fromBuffer(buf)
        ret.neg().copy(ret)
      } else {
        ret = BN.fromBuffer(buf)
      }
      return ret
    }
    
    /**
     * Convert a big number into a number.
     */
    BN.prototype.toNumber = function () {
      return parseInt(this.toString(10), 10)
    }
    
    /**
     * Convert a big number into a buffer. This is somewhat ambiguous, so there is
     * an opts parameter that let's you specify the endianness or the size.
     * opts.endian can be either 'big' or 'little' and opts.size can be any
     * sufficiently large number of bytes. If you always want to create a 32 byte
     * big endian number, then specify opts = { endian: 'big', size: 32 }
     *
     * @param {Object} opts Defaults to { endian: 'big', size: 32 }
     */
    BN.prototype.toBuffer = function (opts) {
      var buf, hex
      if (opts && opts.size) {
        hex = this.toString(16, 2)
        var natlen = hex.length / 2
        buf = Buffer.from(hex, 'hex')
    
        if (natlen === opts.size) {
          // buf = buf
        } else if (natlen > opts.size) {
          buf = BN.trim(buf, natlen)
        } else if (natlen < opts.size) {
          buf = BN.pad(buf, natlen, opts.size)
        }
      } else {
        hex = this.toString(16, 2)
        buf = Buffer.from(hex, 'hex')
      }
    
      if (typeof opts !== 'undefined' && opts.endian === 'little') {
        buf = reversebuf(buf)
      }
    
      return buf
    }
    
    /**
     * For big numbers that are either positive or negative, you can convert to
     * "sign magnitude" format whereby the first bit specifies whether the number is
     * positive or negative.
     */
    BN.prototype.toSMBigEndian = function () {
      var buf
      if (this.cmp(BN.Zero) === -1) {
        buf = this.neg().toBuffer()
        if (buf[0] & 0x80) {
          buf = Buffer.concat([Buffer.from([0x80]), buf])
        } else {
          buf[0] = buf[0] | 0x80
        }
      } else {
        buf = this.toBuffer()
        if (buf[0] & 0x80) {
          buf = Buffer.concat([Buffer.from([0x00]), buf])
        }
      }
    
      if (buf.length === 1 & buf[0] === 0) {
        buf = Buffer.from([])
      }
      return buf
    }
    
    /**
     * For big numbers that are either positive or negative, you can convert to
     * "sign magnitude" format whereby the first bit specifies whether the number is
     * positive or negative.
     *
     * @param {Object} opts Defaults to { endian: 'big' }
     */
    BN.prototype.toSM = function (opts) {
      var endian = opts ? opts.endian : 'big'
      var buf = this.toSMBigEndian()
    
      if (endian === 'little') {
        buf = reversebuf(buf)
      }
      return buf
    }
    
    /**
     * Create a BN from a "ScriptNum": This is analogous to the constructor for
     * CScriptNum in bitcoind. Many ops in bitcoind's script interpreter use
     * CScriptNum, which is not really a proper bignum. Instead, an error is thrown
     * if trying to input a number bigger than 4 bytes. We copy that behavior here.
     * A third argument, `size`, is provided to extend the hard limit of 4 bytes, as
     * some usages require more than 4 bytes.
     *
     * @param {Buffer} buf A buffer of a number.
     * @param {boolean} fRequireMinimal Whether to require minimal size encoding.
     * @param {number} size The maximum size.
     */
    BN.fromScriptNumBuffer = function (buf, fRequireMinimal, size) {
      var nMaxNumSize = size || Number.MAX_SAFE_INTEGER
      $.checkArgument(buf.length <= nMaxNumSize, new Error('script number overflow'))
      if (fRequireMinimal && buf.length > 0) {
        // Check that the number is encoded with the minimum possible
        // number of bytes.
        //
        // If the most-significant-byte - excluding the sign bit - is zero
        // then we're not minimal. Note how this test also rejects the
        // negative-zero encoding, 0x80.
        if ((buf[buf.length - 1] & 0x7f) === 0) {
          // One exception: if there's more than one byte and the most
          // significant bit of the second-most-significant-byte is set
          // it would conflict with the sign bit. An example of this case
          // is +-255, which encode to 0xff00 and 0xff80 respectively.
          // (big-endian).
          if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
            throw new Error('non-minimally encoded script number')
          }
        }
      }
      return BN.fromSM(buf, {
        endian: 'little'
      })
    }
    
    /**
     * The corollary to the above, with the notable exception that we do not throw
     * an error if the output is larger than four bytes. (Which can happen if
     * performing a numerical operation that results in an overflow to more than 4
     * bytes).
     */
    BN.prototype.toScriptNumBuffer = function () {
      return this.toSM({
        endian: 'little'
      })
    }
    
    /**
     * Trims a buffer if it starts with zeros.
     *
     * @param {Buffer} buf A buffer formatted number.
     * @param {number} natlen The natural length of the number.
     */
    BN.trim = function (buf, natlen) {
      return buf.slice(natlen - buf.length, buf.length)
    }
    
    /**
     * Adds extra zeros to the start of a number.
     *
     * @param {Buffer} buf A buffer formatted number.
     * @param {number} natlen The natural length of the number.
     * @param {number} size How big to pad the number in bytes.
     */
    BN.pad = function (buf, natlen, size) {
      var rbuf = Buffer.alloc(size)
      for (var i = 0; i < buf.length; i++) {
        rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i]
      }
      for (i = 0; i < size - natlen; i++) {
        rbuf[i] = 0
      }
      return rbuf
    }
    /**
     * Convert a big number into a hex string. This is somewhat ambiguous, so there
     * is an opts parameter that let's you specify the endianness or the size.
     * opts.endian can be either 'big' or 'little' and opts.size can be any
     * sufficiently large number of bytes. If you always want to create a 32 byte
     * big endian number, then specify opts = { endian: 'big', size: 32 }
     *
     * @param {Object} opts Defaults to { endian: 'big', size: 32 }
     */
    BN.prototype.toHex = function (...args) {
      return this.toBuffer(...args).toString('hex')
    }
    
    /**
     * Convert a hex string (such as a 256 bit binary private key) into a big
     * number. Sometimes these numbers can be formatted either as 'big endian' or
     * 'little endian', and so there is an opts parameter that lets you specify
     * which endianness is specified.
     *
     * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
     * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
     */
    BN.fromHex = function (hex, ...args) {
      return BN.fromBuffer(Buffer.from(hex, 'hex'), ...args)
    }
    
    module.exports = BN
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/_":270,"../util/preconditions":272,"bn.js":275,"buffer":84}],206:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BN = require('./bn')
    var Point = require('./point')
    var Signature = require('./signature')
    var PublicKey = require('../publickey')
    var Random = require('./random')
    var Hash = require('./hash')
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    
    var ECDSA = function ECDSA (obj) {
      if (!(this instanceof ECDSA)) {
        return new ECDSA(obj)
      }
      if (obj) {
        this.set(obj)
      }
    }
    
    ECDSA.prototype.set = function (obj) {
      this.hashbuf = obj.hashbuf || this.hashbuf
      this.endian = obj.endian || this.endian // the endianness of hashbuf
      this.privkey = obj.privkey || this.privkey
      this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey)
      this.sig = obj.sig || this.sig
      this.k = obj.k || this.k
      this.verified = obj.verified || this.verified
      return this
    }
    
    ECDSA.prototype.privkey2pubkey = function () {
      this.pubkey = this.privkey.toPublicKey()
    }
    
    ECDSA.prototype.calci = function () {
      for (var i = 0; i < 4; i++) {
        this.sig.i = i
        var Qprime
        try {
          Qprime = this.toPublicKey()
        } catch (e) {
          console.error(e)
          continue
        }
    
        if (Qprime.point.eq(this.pubkey.point)) {
          this.sig.compressed = this.pubkey.compressed
          return this
        }
      }
    
      this.sig.i = undefined
      throw new Error('Unable to find valid recovery factor')
    }
    
    ECDSA.fromString = function (str) {
      var obj = JSON.parse(str)
      return new ECDSA(obj)
    }
    
    ECDSA.prototype.randomK = function () {
      var N = Point.getN()
      var k
      do {
        k = BN.fromBuffer(Random.getRandomBuffer(32))
      } while (!(k.lt(N) && k.gt(BN.Zero)))
      this.k = k
      return this
    }
    
    // https://tools.ietf.org/html/rfc6979#section-3.2
    ECDSA.prototype.deterministicK = function (badrs) {
      // if r or s were invalid when this function was used in signing,
      // we do not want to actually compute r, s here for efficiency, so,
      // we can increment badrs. explained at end of RFC 6979 section 3.2
      if (_.isUndefined(badrs)) {
        badrs = 0
      }
      var v = Buffer.alloc(32)
      v.fill(0x01)
      var k = Buffer.alloc(32)
      k.fill(0x00)
      var x = this.privkey.bn.toBuffer({
        size: 32
      })
      var hashbuf = this.endian === 'little' ? Buffer.from(this.hashbuf).reverse() : this.hashbuf
      k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00]), x, hashbuf]), k)
      v = Hash.sha256hmac(v, k)
      k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x01]), x, hashbuf]), k)
      v = Hash.sha256hmac(v, k)
      v = Hash.sha256hmac(v, k)
      var T = BN.fromBuffer(v)
      var N = Point.getN()
    
      // also explained in 3.2, we must ensure T is in the proper range (0, N)
      for (var i = 0; i < badrs || !(T.lt(N) && T.gt(BN.Zero)); i++) {
        k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00])]), k)
        v = Hash.sha256hmac(v, k)
        v = Hash.sha256hmac(v, k)
        T = BN.fromBuffer(v)
      }
    
      this.k = T
      return this
    }
    
    // Information about public key recovery:
    // https://bitcointalk.org/index.php?topic=6430.0
    // http://stackoverflow.com/questions/19665491/how-do-i-get-an-ecdsa-public-key-from-just-a-bitcoin-signature-sec1-4-1-6-k
    ECDSA.prototype.toPublicKey = function () {
      var i = this.sig.i
      $.checkArgument(i === 0 || i === 1 || i === 2 || i === 3, new Error('i must be equal to 0, 1, 2, or 3'))
    
      var e = BN.fromBuffer(this.hashbuf)
      var r = this.sig.r
      var s = this.sig.s
    
      // A set LSB signifies that the y-coordinate is odd
      var isYOdd = i & 1
    
      // The more significant bit specifies whether we should use the
      // first or second candidate key.
      var isSecondKey = i >> 1
    
      var n = Point.getN()
      var G = Point.getG()
    
      // 1.1 Let x = r + jn
      var x = isSecondKey ? r.add(n) : r
      var R = Point.fromX(isYOdd, x)
    
      // 1.4 Check that nR is at infinity
      var nR = R.mul(n)
    
      if (!nR.isInfinity()) {
        throw new Error('nR is not a valid curve point')
      }
    
      // Compute -e from e
      var eNeg = e.neg().umod(n)
    
      // 1.6.1 Compute Q = r^-1 (sR - eG)
      // Q = r^-1 (sR + -eG)
      var rInv = r.invm(n)
    
      // var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
      var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv)
    
      var pubkey = PublicKey.fromPoint(Q, this.sig.compressed)
    
      return pubkey
    }
    
    ECDSA.prototype.sigError = function () {
      if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
        return 'hashbuf must be a 32 byte buffer'
      }
    
      var r = this.sig.r
      var s = this.sig.s
      if (!(r.gt(BN.Zero) && r.lt(Point.getN())) || !(s.gt(BN.Zero) && s.lt(Point.getN()))) {
        return 'r and s not in range'
      }
    
      var e = BN.fromBuffer(this.hashbuf, this.endian ? {
        endian: this.endian
      } : undefined)
      var n = Point.getN()
      var sinv = s.invm(n)
      var u1 = sinv.mul(e).umod(n)
      var u2 = sinv.mul(r).umod(n)
    
      var p = Point.getG().mulAdd(u1, this.pubkey.point, u2)
      if (p.isInfinity()) {
        return 'p is infinity'
      }
    
      if (p.getX().umod(n).cmp(r) !== 0) {
        return 'Invalid signature'
      } else {
        return false
      }
    }
    
    ECDSA.toLowS = function (s) {
      // enforce low s
      // see BIP 62, "low S values in signatures"
      if (s.gt(BN.fromBuffer(Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')))) {
        s = Point.getN().sub(s)
      }
      return s
    }
    
    ECDSA.prototype._findSignature = function (d, e) {
      var N = Point.getN()
      var G = Point.getG()
      // try different values of k until r, s are valid
      var badrs = 0
      var k, Q, r, s
      do {
        if (!this.k || badrs > 0) {
          this.deterministicK(badrs)
        }
        badrs++
        k = this.k
        Q = G.mul(k)
        r = new BN(1).mul(Q.x.umod(N))
        s = k.invm(N).mul(e.add(d.mul(r))).umod(N)
      } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0)
    
      s = ECDSA.toLowS(s)
      return {
        s: s,
        r: r
      }
    }
    
    ECDSA.prototype.sign = function () {
      var hashbuf = this.hashbuf
      var privkey = this.privkey
      var d = privkey.bn
    
      $.checkState(hashbuf && privkey && d, new Error('invalid parameters'))
      $.checkState(Buffer.isBuffer(hashbuf) && hashbuf.length === 32, new Error('hashbuf must be a 32 byte buffer'))
    
      var e = BN.fromBuffer(hashbuf, this.endian ? {
        endian: this.endian
      } : undefined)
    
      var obj = this._findSignature(d, e)
      obj.compressed = this.pubkey.compressed
    
      this.sig = new Signature(obj)
      return this
    }
    
    ECDSA.prototype.signRandomK = function () {
      this.randomK()
      return this.sign()
    }
    
    ECDSA.prototype.toString = function () {
      var obj = {}
      if (this.hashbuf) {
        obj.hashbuf = this.hashbuf.toString('hex')
      }
      if (this.privkey) {
        obj.privkey = this.privkey.toString()
      }
      if (this.pubkey) {
        obj.pubkey = this.pubkey.toString()
      }
      if (this.sig) {
        obj.sig = this.sig.toString()
      }
      if (this.k) {
        obj.k = this.k.toString()
      }
      return JSON.stringify(obj)
    }
    
    ECDSA.prototype.verify = function () {
      if (!this.sigError()) {
        this.verified = true
      } else {
        this.verified = false
      }
      return this
    }
    
    ECDSA.sign = function (hashbuf, privkey, endian) {
      return ECDSA().set({
        hashbuf: hashbuf,
        endian: endian,
        privkey: privkey
      }).sign().sig
    }
    
    ECDSA.signWithCalcI = function (hashbuf, privkey, endian) {
      return ECDSA().set({
        hashbuf: hashbuf,
        endian: endian,
        privkey: privkey
      }).sign().calci().sig
    }
    
    ECDSA.signRandomK = function (hashbuf, privkey, endian) {
      return ECDSA().set({
        hashbuf: hashbuf,
        endian: endian,
        privkey: privkey
      }).signRandomK().sig
    }
    
    ECDSA.verify = function (hashbuf, sig, pubkey, endian) {
      return ECDSA().set({
        hashbuf: hashbuf,
        endian: endian,
        sig: sig,
        pubkey: pubkey
      }).verify().verified
    }
    
    module.exports = ECDSA
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../publickey":247,"../util/_":270,"../util/preconditions":272,"./bn":205,"./hash":208,"./point":210,"./random":211,"./signature":212,"buffer":84}],207:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var hash = require('hash.js')
    var $ = require('../util/preconditions')
    
    var Hash = module.exports
    
    /**
     * A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/SHA-1
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha1 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Buffer.from(hash.sha1().update(buf).digest('hex'), 'hex')
    }
    
    Hash.sha1.blocksize = 512
    
    /**
     * A SHA256 hash, which is always 256 bits or 32 bytes long.
     *
     * See:
     * https://www.movable-type.co.uk/scripts/sha256.html
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Buffer.from(hash.sha256().update(buf).digest('hex'), 'hex')
    }
    
    Hash.sha256.blocksize = 512
    
    /**
     * A double SHA256 hash, which is always 256 bits or 32 bytes bytes long. This
     * hash function is commonly used inside Bitcoin, particularly for the hash of a
     * block and the hash of a transaction.
     *
     * See:
     * https://www.movable-type.co.uk/scripts/sha256.html
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256sha256 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Hash.sha256(Hash.sha256(buf))
    }
    
    /**
     * A RIPEMD160 hash, which is always 160 bits or 20 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/RIPEMD
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.ripemd160 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Buffer.from(hash.ripemd160().update(buf).digest('hex'), 'hex')
    }
    /**
     * A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
     * This value is commonly used inside Bitcoin, particularly for Bitcoin
     * addresses.
     *
     * See:
     * https://en.wikipedia.org/wiki/RIPEMD
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256ripemd160 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Hash.ripemd160(Hash.sha256(buf))
    }
    
    /**
     * A SHA512 hash, which is always 512 bits or 64 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/SHA-2
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha512 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Buffer.from(hash.sha512().update(buf).digest('hex'), 'hex')
    }
    
    Hash.sha512.blocksize = 1024
    
    /**
     * A way to do HMAC using any underlying hash function. If you ever find that
     * you want to hash two pieces of data together, you should use HMAC instead of
     * just using a hash function. Rather than doing hash(data1 + data2) you should
     * do HMAC(data1, data2). Actually, rather than use HMAC directly, we recommend
     * you use either sha256hmac or sha515hmac provided below.
     *
     * See:
     * https://en.wikipedia.org/wiki/Length_extension_attack
     * https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks
     *
     * @param {function} hashf Which hash function to use.
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.hmac = function (hashf, data, key) {
      // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
      // http://tools.ietf.org/html/rfc4868#section-2
      $.checkArgument(Buffer.isBuffer(data))
      $.checkArgument(Buffer.isBuffer(key))
      $.checkArgument(hashf.blocksize)
    
      var blocksize = hashf.blocksize / 8
    
      if (key.length > blocksize) {
        key = hashf(key)
      } else if (key < blocksize) {
        var fill = Buffer.alloc(blocksize)
        fill.fill(0)
        key.copy(fill)
        key = fill
      }
    
      var oKey = Buffer.alloc(blocksize)
      oKey.fill(0x5c)
    
      var iKey = Buffer.alloc(blocksize)
      iKey.fill(0x36)
    
      var oKeyPad = Buffer.alloc(blocksize)
      var iKeyPad = Buffer.alloc(blocksize)
      for (var i = 0; i < blocksize; i++) {
        oKeyPad[i] = oKey[i] ^ key[i]
        iKeyPad[i] = iKey[i] ^ key[i]
      }
    
      return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]))
    }
    
    /**
     * A SHA256 HMAC.
     *
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.sha256hmac = function (data, key) {
      return Hash.hmac(Hash.sha256, data, key)
    }
    
    /**
     * A SHA512 HMAC.
     *
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.sha512hmac = function (data, key) {
      return Hash.hmac(Hash.sha512, data, key)
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/preconditions":272,"buffer":84,"hash.js":167}],208:[function(require,module,exports){
    (function (process){(function (){
    if (process.browser) module.exports = require('./hash.browser')
    else module.exports = require('./hash.node')
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./hash.browser":207,"./hash.node":209,"_process":321}],209:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var crypto = require('crypto')
    var $ = require('../util/preconditions')
    
    var Hash = module.exports
    
    /**
     * A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/SHA-1
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha1 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return crypto.createHash('sha1').update(buf).digest()
    }
    
    Hash.sha1.blocksize = 512
    
    /**
     * A SHA256 hash, which is always 256 bits or 32 bytes long.
     *
     * See:
     * https://www.movable-type.co.uk/scripts/sha256.html
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return crypto.createHash('sha256').update(buf).digest()
    }
    
    Hash.sha256.blocksize = 512
    
    /**
     * A double SHA256 hash, which is always 256 bits or 32 bytes bytes long. This
     * hash function is commonly used inside Bitcoin, particularly for the hash of a
     * block and the hash of a transaction.
     *
     * See:
     * https://www.movable-type.co.uk/scripts/sha256.html
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256sha256 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Hash.sha256(Hash.sha256(buf))
    }
    
    /**
     * A RIPEMD160 hash, which is always 160 bits or 20 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/RIPEMD
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.ripemd160 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return crypto.createHash('ripemd160').update(buf).digest()
    }
    /**
     * A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
     * This value is commonly used inside Bitcoin, particularly for Bitcoin
     * addresses.
     *
     * See:
     * https://en.wikipedia.org/wiki/RIPEMD
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha256ripemd160 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return Hash.ripemd160(Hash.sha256(buf))
    }
    
    /**
     * A SHA512 hash, which is always 512 bits or 64 bytes long.
     *
     * See:
     * https://en.wikipedia.org/wiki/SHA-2
     *
     * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
     * @returns {Buffer} The hash in the form of a buffer.
     */
    Hash.sha512 = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return crypto.createHash('sha512').update(buf).digest()
    }
    
    Hash.sha512.blocksize = 1024
    
    /**
     * A way to do HMAC using any underlying hash function. If you ever find that
     * you want to hash two pieces of data together, you should use HMAC instead of
     * just using a hash function. Rather than doing hash(data1 + data2) you should
     * do HMAC(data1, data2). Actually, rather than use HMAC directly, we recommend
     * you use either sha256hmac or sha515hmac provided below.
     *
     * See:
     * https://en.wikipedia.org/wiki/Length_extension_attack
     * https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks
     *
     * @param {function} hashf Which hash function to use.
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.hmac = function (hashf, data, key) {
      // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
      // http://tools.ietf.org/html/rfc4868#section-2
      $.checkArgument(Buffer.isBuffer(data))
      $.checkArgument(Buffer.isBuffer(key))
      $.checkArgument(hashf.blocksize)
    
      var blocksize = hashf.blocksize / 8
    
      if (key.length > blocksize) {
        key = hashf(key)
      } else if (key < blocksize) {
        var fill = Buffer.alloc(blocksize)
        fill.fill(0)
        key.copy(fill)
        key = fill
      }
    
      var oKey = Buffer.alloc(blocksize)
      oKey.fill(0x5c)
    
      var iKey = Buffer.alloc(blocksize)
      iKey.fill(0x36)
    
      var oKeyPad = Buffer.alloc(blocksize)
      var iKeyPad = Buffer.alloc(blocksize)
      for (var i = 0; i < blocksize; i++) {
        oKeyPad[i] = oKey[i] ^ key[i]
        iKeyPad[i] = iKey[i] ^ key[i]
      }
    
      return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]))
    }
    
    /**
     * A SHA256 HMAC.
     *
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.sha256hmac = function (data, key) {
      return Hash.hmac(Hash.sha256, data, key)
    }
    
    /**
     * A SHA512 HMAC.
     *
     * @param {Buffer} data Data, which can be any size.
     * @param {Buffer} key Key, which can be any size.
     * @returns {Buffer} The HMAC in the form of a buffer.
     */
    Hash.sha512hmac = function (data, key) {
      return Hash.hmac(Hash.sha512, data, key)
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/preconditions":272,"buffer":84,"crypto":107}],210:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BN = require('./bn')
    
    var EC = require('elliptic').ec
    var ec = new EC('secp256k1')
    var ecPoint = ec.curve.point.bind(ec.curve)
    var ecPointFromX = ec.curve.pointFromX.bind(ec.curve)
    
    /**
     * Instantiate a valid secp256k1 Point from the X and Y coordinates. This class
     * is just an extension of the secp256k1 code from the library "elliptic" by
     * Fedor Indutny. It includes a few extra features that are useful in Bitcoin.
     *
     * @param {BN|String} x - The X coordinate
     * @param {BN|String} y - The Y coordinate
     * @link https://github.com/indutny/elliptic
     * @augments elliptic.curve.point
     * @throws {Error} A validation error if exists
     * @returns {Point} An instance of Point
     * @constructor
     */
    var Point = function Point (x, y, isRed) {
      try {
        var point = ecPoint(x, y, isRed)
      } catch (e) {
        throw new Error('Invalid Point')
      }
      point.validate()
      return point
    }
    
    Point.prototype = Object.getPrototypeOf(ec.curve.point())
    
    /**
     *
     * Instantiate a valid secp256k1 Point from only the X coordinate. This is
     * useful to rederive a full point from the compressed form of a point.
     *
     * @param {boolean} odd - If the Y coordinate is odd
     * @param {BN|String} x - The X coordinate
     * @throws {Error} A validation error if exists
     * @returns {Point} An instance of Point
     */
    Point.fromX = function fromX (odd, x) {
      try {
        var point = ecPointFromX(x, odd)
      } catch (e) {
        throw new Error('Invalid X')
      }
      point.validate()
      return point
    }
    
    /**
     *
     * Will return a secp256k1 ECDSA base point.
     *
     * @link https://en.bitcoin.it/wiki/Secp256k1
     * @returns {Point} An instance of the base point.
     */
    Point.getG = function getG () {
      return ec.curve.g
    }
    
    /**
     *
     * Will return the max of range of valid private keys as governed by the
     * secp256k1 ECDSA standard.
     *
     * @link https://en.bitcoin.it/wiki/Private_key#Range_of_valid_ECDSA_private_keys
     * @returns {BN} A BN instance of the number of points on the curve
     */
    Point.getN = function getN () {
      return new BN(ec.curve.n.toArray())
    }
    
    if (!Point.prototype._getX) { Point.prototype._getX = Point.prototype.getX }
    
    /**
     * Will return the X coordinate of the Point.
     *
     * @returns {BN} A BN instance of the X coordinate
     */
    Point.prototype.getX = function getX () {
      return new BN(this._getX().toArray())
    }
    
    if (!Point.prototype._getY) { Point.prototype._getY = Point.prototype.getY }
    
    /**
     * Will return the Y coordinate of the Point.
     *
     * @returns {BN} A BN instance of the Y coordinate
     */
    Point.prototype.getY = function getY () {
      return new BN(this._getY().toArray())
    }
    
    /**
     * Will determine if the point is valid.
     *
     * @link https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
     * @throws {Error} A validation error if exists
     * @returns {Point} An instance of the same Point
     */
    Point.prototype.validate = function validate () {
      if (this.isInfinity()) {
        throw new Error('Point cannot be equal to Infinity')
      }
    
      var p2
      try {
        p2 = ecPointFromX(this.getX(), this.getY().isOdd())
      } catch (e) {
        throw new Error('Point does not lie on the curve')
      }
    
      if (p2.y.cmp(this.y) !== 0) {
        throw new Error('Invalid y value for curve.')
      }
    
      // todo: needs test case
      if (!(this.mul(Point.getN()).isInfinity())) {
        throw new Error('Point times N must be infinity')
      }
    
      return this
    }
    
    /**
     * A "compressed" format point is the X part of the (X, Y) point plus an extra
     * bit (which takes an entire byte) to indicate whether the Y value is odd or
     * not. Storing points this way takes a bit less space, but requires a bit more
     * computation to rederive the full point.
     *
     * @param {Point} point An instance of Point.
     * @returns {Buffer} A compressed point in the form of a buffer.
     */
    Point.pointToCompressed = function pointToCompressed (point) {
      var xbuf = point.getX().toBuffer({ size: 32 })
      var ybuf = point.getY().toBuffer({ size: 32 })
    
      var prefix
      var odd = ybuf[ybuf.length - 1] % 2
      if (odd) {
        prefix = Buffer.from([0x03])
      } else {
        prefix = Buffer.from([0x02])
      }
      return Buffer.concat([prefix, xbuf])
    }
    
    /**
     * Converts a compressed buffer into a point.
     *
     * @param {Buffer} buf A compressed point.
     * @returns {Point} A Point.
     */
    Point.pointFromCompressed = function (buf) {
      if (buf.length !== 33) {
        throw new Error('invalid buffer length')
      }
      let prefix = buf[0]
      let odd
      if (prefix === 0x03) {
        odd = true
      } else if (prefix === 0x02) {
        odd = false
      } else {
        throw new Error('invalid value of compressed prefix')
      }
    
      let xbuf = buf.slice(1, 33)
      let x = BN.fromBuffer(xbuf)
      return Point.fromX(odd, x)
    }
    
    /**
     * Convert point to a compressed buffer.
     *
     * @returns {Buffer} A compressed point.
     */
    Point.prototype.toBuffer = function () {
      return Point.pointToCompressed(this)
    }
    
    /**
     * Convert point to a compressed hex string.
     *
     * @returns {string} A compressed point as a hex string.
     */
    Point.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * Converts a compressed buffer into a point.
     *
     * @param {Buffer} buf A compressed point.
     * @returns {Point} A Point.
     */
    Point.fromBuffer = function (buf) {
      return Point.pointFromCompressed(buf)
    }
    
    /**
     * Converts a compressed buffer into a point.
     *
     * @param {Buffer} hex A compressed point as a hex string.
     * @returns {Point} A Point.
     */
    Point.fromHex = function (hex) {
      return Point.fromBuffer(Buffer.from(hex, 'hex'))
    }
    
    module.exports = Point
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./bn":205,"buffer":84,"elliptic":118}],211:[function(require,module,exports){
    (function (process,Buffer){(function (){
    'use strict'
    
    function Random () {
    }
    
    /* secure random bytes that sometimes throws an error due to lack of entropy */
    Random.getRandomBuffer = function (size) {
      if (process.browser) { return Random.getRandomBufferBrowser(size) } else { return Random.getRandomBufferNode(size) }
    }
    
    Random.getRandomBufferNode = function (size) {
      var crypto = require('crypto')
      return crypto.randomBytes(size)
    }
    
    Random.getRandomBufferBrowser = function (size) {
      if (!window.crypto && !window.msCrypto) {
        throw new Error('window.crypto not available')
      }
      var crypto
    
      if (window.crypto && window.crypto.getRandomValues) {
        crypto = window.crypto
      } else if (window.msCrypto && window.msCrypto.getRandomValues) { // internet explorer
        crypto = window.msCrypto
      } else {
        throw new Error('window.crypto.getRandomValues not available')
      }
    
      var bbuf = new Uint8Array(size)
      crypto.getRandomValues(bbuf)
      var buf = Buffer.from(bbuf)
    
      return buf
    }
    
    module.exports = Random
    
    }).call(this)}).call(this,require('_process'),require("buffer").Buffer)
    
    },{"_process":321,"buffer":84,"crypto":107}],212:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BN = require('./bn')
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    var JSUtil = require('../util/js')
    
    var Signature = function Signature (r, s) {
      if (!(this instanceof Signature)) {
        return new Signature(r, s)
      }
      if (r instanceof BN) {
        this.set({
          r: r,
          s: s
        })
      } else if (r) {
        var obj = r
        this.set(obj)
      }
    }
    
    Signature.prototype.set = function (obj) {
      this.r = obj.r || this.r || undefined
      this.s = obj.s || this.s || undefined
    
      this.i = typeof obj.i !== 'undefined' ? obj.i : this.i // public key recovery parameter in range [0, 3]
      this.compressed = typeof obj.compressed !== 'undefined'
        ? obj.compressed : this.compressed // whether the recovered pubkey is compressed
      this.nhashtype = obj.nhashtype || this.nhashtype || undefined
      return this
    }
    
    Signature.fromCompact = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf), 'Argument is expected to be a Buffer')
    
      var sig = new Signature()
    
      var compressed = true
      var i = buf.slice(0, 1)[0] - 27 - 4
      if (i < 0) {
        compressed = false
        i = i + 4
      }
    
      var b2 = buf.slice(1, 33)
      var b3 = buf.slice(33, 65)
    
      $.checkArgument(i === 0 || i === 1 || i === 2 || i === 3, new Error('i must be 0, 1, 2, or 3'))
      $.checkArgument(b2.length === 32, new Error('r must be 32 bytes'))
      $.checkArgument(b3.length === 32, new Error('s must be 32 bytes'))
    
      sig.compressed = compressed
      sig.i = i
      sig.r = BN.fromBuffer(b2)
      sig.s = BN.fromBuffer(b3)
    
      return sig
    }
    
    Signature.fromDER = Signature.fromBuffer = function (buf, strict) {
      var obj = Signature.parseDER(buf, strict)
      var sig = new Signature()
    
      sig.r = obj.r
      sig.s = obj.s
    
      return sig
    }
    
    // The format used in a tx
    Signature.fromTxFormat = function (buf) {
      var nhashtype = buf.readUInt8(buf.length - 1)
      var derbuf = buf.slice(0, buf.length - 1)
      var sig = Signature.fromDER(derbuf, false)
      sig.nhashtype = nhashtype
      return sig
    }
    
    Signature.fromString = function (str) {
      var buf = Buffer.from(str, 'hex')
      return Signature.fromDER(buf)
    }
    
    /**
     * In order to mimic the non-strict DER encoding of OpenSSL, set strict = false.
     */
    Signature.parseDER = function (buf, strict) {
      $.checkArgument(Buffer.isBuffer(buf), new Error('DER formatted signature should be a buffer'))
      if (_.isUndefined(strict)) {
        strict = true
      }
    
      var header = buf[0]
      $.checkArgument(header === 0x30, new Error('Header byte should be 0x30'))
    
      var length = buf[1]
      var buflength = buf.slice(2).length
      $.checkArgument(!strict || length === buflength, new Error('Length byte should length of what follows'))
    
      length = length < buflength ? length : buflength
    
      var rheader = buf[2 + 0]
      $.checkArgument(rheader === 0x02, new Error('Integer byte for r should be 0x02'))
    
      var rlength = buf[2 + 1]
      var rbuf = buf.slice(2 + 2, 2 + 2 + rlength)
      var r = BN.fromBuffer(rbuf)
      var rneg = buf[2 + 1 + 1] === 0x00
      $.checkArgument(rlength === rbuf.length, new Error('Length of r incorrect'))
    
      var sheader = buf[2 + 2 + rlength + 0]
      $.checkArgument(sheader === 0x02, new Error('Integer byte for s should be 0x02'))
    
      var slength = buf[2 + 2 + rlength + 1]
      var sbuf = buf.slice(2 + 2 + rlength + 2, 2 + 2 + rlength + 2 + slength)
      var s = BN.fromBuffer(sbuf)
      var sneg = buf[2 + 2 + rlength + 2 + 2] === 0x00
      $.checkArgument(slength === sbuf.length, new Error('Length of s incorrect'))
    
      var sumlength = 2 + 2 + rlength + 2 + slength
      $.checkArgument(length === sumlength - 2, new Error('Length of signature incorrect'))
    
      var obj = {
        header: header,
        length: length,
        rheader: rheader,
        rlength: rlength,
        rneg: rneg,
        rbuf: rbuf,
        r: r,
        sheader: sheader,
        slength: slength,
        sneg: sneg,
        sbuf: sbuf,
        s: s
      }
    
      return obj
    }
    
    Signature.prototype.toCompact = function (i, compressed) {
      i = typeof i === 'number' ? i : this.i
      compressed = typeof compressed === 'boolean' ? compressed : this.compressed
    
      if (!(i === 0 || i === 1 || i === 2 || i === 3)) {
        throw new Error('i must be equal to 0, 1, 2, or 3')
      }
    
      var val = i + 27 + 4
      if (compressed === false) {
        val = val - 4
      }
      var b1 = Buffer.from([val])
      var b2 = this.r.toBuffer({
        size: 32
      })
      var b3 = this.s.toBuffer({
        size: 32
      })
      return Buffer.concat([b1, b2, b3])
    }
    
    Signature.prototype.toBuffer = Signature.prototype.toDER = function () {
      var rnbuf = this.r.toBuffer()
      var snbuf = this.s.toBuffer()
    
      var rneg = !!(rnbuf[0] & 0x80)
      var sneg = !!(snbuf[0] & 0x80)
    
      var rbuf = rneg ? Buffer.concat([Buffer.from([0x00]), rnbuf]) : rnbuf
      var sbuf = sneg ? Buffer.concat([Buffer.from([0x00]), snbuf]) : snbuf
    
      var rlength = rbuf.length
      var slength = sbuf.length
      var length = 2 + rlength + 2 + slength
      var rheader = 0x02
      var sheader = 0x02
      var header = 0x30
    
      var der = Buffer.concat([Buffer.from([header, length, rheader, rlength]), rbuf, Buffer.from([sheader, slength]), sbuf])
      return der
    }
    
    Signature.prototype.toString = function () {
      var buf = this.toDER()
      return buf.toString('hex')
    }
    
    /**
     * This function is translated from bitcoind's IsDERSignature and is used in
     * the script interpreter.  This "DER" format actually includes an extra byte,
     * the nhashtype, at the end. It is really the tx format, not DER format.
     *
     * A canonical signature exists of: [30] [total len] [02] [len R] [R] [02] [len S] [S] [hashtype]
     * Where R and S are not negative (their first byte has its highest bit not set), and not
     * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
     * in which case a single 0 byte is necessary and even required).
     *
     * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
     */
    Signature.isTxDER = function (buf) {
      if (buf.length < 9) {
        //  Non-canonical signature: too short
        return false
      }
      if (buf.length > 73) {
        // Non-canonical signature: too long
        return false
      }
      if (buf[0] !== 0x30) {
        //  Non-canonical signature: wrong type
        return false
      }
      if (buf[1] !== buf.length - 3) {
        //  Non-canonical signature: wrong length marker
        return false
      }
      var nLenR = buf[3]
      if (5 + nLenR >= buf.length) {
        //  Non-canonical signature: S length misplaced
        return false
      }
      var nLenS = buf[5 + nLenR]
      if ((nLenR + nLenS + 7) !== buf.length) {
        //  Non-canonical signature: R+S length mismatch
        return false
      }
    
      var R = buf.slice(4)
      if (buf[4 - 2] !== 0x02) {
        //  Non-canonical signature: R value type mismatch
        return false
      }
      if (nLenR === 0) {
        //  Non-canonical signature: R length is zero
        return false
      }
      if (R[0] & 0x80) {
        //  Non-canonical signature: R value negative
        return false
      }
      if (nLenR > 1 && (R[0] === 0x00) && !(R[1] & 0x80)) {
        //  Non-canonical signature: R value excessively padded
        return false
      }
    
      var S = buf.slice(6 + nLenR)
      if (buf[6 + nLenR - 2] !== 0x02) {
        //  Non-canonical signature: S value type mismatch
        return false
      }
      if (nLenS === 0) {
        //  Non-canonical signature: S length is zero
        return false
      }
      if (S[0] & 0x80) {
        //  Non-canonical signature: S value negative
        return false
      }
      if (nLenS > 1 && (S[0] === 0x00) && !(S[1] & 0x80)) {
        //  Non-canonical signature: S value excessively padded
        return false
      }
      return true
    }
    
    /**
     * Compares to bitcoind's IsLowDERSignature
     * See also ECDSA signature algorithm which enforces this.
     * See also BIP 62, "low S values in signatures"
     */
    Signature.prototype.hasLowS = function () {
      if (this.s.lt(new BN(1)) ||
        this.s.gt(new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex'))) {
        return false
      }
      return true
    }
    
    /**
     * @returns true if the nhashtype is exactly equal to one of the standard options or combinations thereof.
     * Translated from bitcoind's IsDefinedHashtypeSignature
     */
    Signature.prototype.hasDefinedHashtype = function () {
      if (!JSUtil.isNaturalNumber(this.nhashtype)) {
        return false
      }
      // accept with or without Signature.SIGHASH_ANYONECANPAY by ignoring the bit
      var temp = this.nhashtype & 0x1F
      if (temp < Signature.SIGHASH_ALL || temp > Signature.SIGHASH_SINGLE) {
        return false
      }
      return true
    }
    
    Signature.prototype.toTxFormat = function () {
      var derbuf = this.toDER()
      var buf = Buffer.alloc(1)
      buf.writeUInt8(this.nhashtype, 0)
      return Buffer.concat([derbuf, buf])
    }
    
    Signature.SIGHASH_ALL = 0x01
    Signature.SIGHASH_NONE = 0x02
    Signature.SIGHASH_SINGLE = 0x03
    Signature.SIGHASH_FORKID = 0x40
    Signature.SIGHASH_ANYONECANPAY = 0x80
    
    module.exports = Signature
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/_":270,"../util/js":271,"../util/preconditions":272,"./bn":205,"buffer":84}],213:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var bsv = require('../../')
    
    var PublicKey = bsv.PublicKey
    var Hash = bsv.crypto.Hash
    var $ = bsv.util.preconditions
    var aesjs = require('aes-js')
    var CBC = aesjs.ModeOfOperation.cbc
    var Random = bsv.crypto.Random
    
    var AESCBC = function AESCBC () {}
    
    AESCBC.encrypt = function (messagebuf, cipherkeybuf, ivbuf) {
      $.checkArgument(messagebuf)
      $.checkArgument(cipherkeybuf)
      $.checkArgument(ivbuf)
      ivbuf = ivbuf || Random.getRandomBuffer(128 / 8)
      messagebuf = aesjs.padding.pkcs7.pad(messagebuf)
      var aesCbc = new CBC(cipherkeybuf, ivbuf)
      var ctbuf = aesCbc.encrypt(messagebuf)
      var encbuf = Buffer.concat([ivbuf, ctbuf])
      return encbuf
    }
    
    AESCBC.decrypt = function (encbuf, cipherkeybuf) {
      $.checkArgument(encbuf)
      $.checkArgument(cipherkeybuf)
      var ivbuf = encbuf.slice(0, 128 / 8)
      var ctbuf = encbuf.slice(128 / 8)
      var aesCbc = new CBC(cipherkeybuf, ivbuf)
      var messagebuf = aesCbc.decrypt(ctbuf)
      messagebuf = aesjs.padding.pkcs7.strip(messagebuf)
      return Buffer.from(messagebuf)
    }
    
    // http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
    var ECIES = function ECIES (opts) {
      if (!(this instanceof ECIES)) {
        return new ECIES()
      }
      this.opts = opts || {}
    }
    
    ECIES.prototype.privateKey = function (privateKey) {
      $.checkArgument(privateKey, 'no private key provided')
    
      this._privateKey = privateKey || null
    
      return this
    }
    
    ECIES.prototype.publicKey = function (publicKey) {
      $.checkArgument(publicKey, 'no public key provided')
    
      this._publicKey = publicKey || null
    
      return this
    }
    
    var cachedProperty = function (name, getter) {
      var cachedName = '_' + name
      Object.defineProperty(ECIES.prototype, name, {
        configurable: false,
        enumerable: true,
        get: function () {
          var value = this[cachedName]
          if (!value) {
            value = this[cachedName] = getter.apply(this)
          }
          return value
        }
      })
    }
    
    cachedProperty('Rbuf', function () {
      return this._privateKey.publicKey.toDER(true)
    })
    
    cachedProperty('kEkM', function () {
      var r = this._privateKey.bn
      var KB = this._publicKey.point
      var P = KB.mul(r)
      var S = P.getX()
      var Sbuf = S.toBuffer({ size: 32 })
      return Hash.sha512(Sbuf)
    })
    
    cachedProperty('kE', function () {
      return this.kEkM.slice(0, 32)
    })
    
    cachedProperty('kM', function () {
      return this.kEkM.slice(32, 64)
    })
    
    // Encrypts the message (String or Buffer).
    // Optional `ivbuf` contains 16-byte Buffer to be used in AES-CBC.
    // By default, `ivbuf` is computed deterministically from message and private key using HMAC-SHA256.
    // Deterministic IV enables end-to-end test vectors for alternative implementations.
    // Note that identical messages have identical ciphertexts. If your protocol does not include some
    // kind of a sequence identifier inside the message *and* it is important to not allow attacker to learn
    // that message is repeated, then you should use custom IV.
    // For random IV, pass `Random.getRandomBuffer(16)` for the second argument.
    ECIES.prototype.encrypt = function (message, ivbuf) {
      if (!Buffer.isBuffer(message)) message = Buffer.from(message)
      if (ivbuf === undefined) {
        ivbuf = Hash.sha256hmac(message, this._privateKey.toBuffer()).slice(0, 16)
      }
      var c = AESCBC.encrypt(message, this.kE, ivbuf)
      var d = Hash.sha256hmac(c, this.kM)
      if (this.opts.shortTag) d = d.slice(0, 4)
      var encbuf
      if (this.opts.noKey) {
        encbuf = Buffer.concat([c, d])
      } else {
        encbuf = Buffer.concat([this.Rbuf, c, d])
      }
      return encbuf
    }
    
    ECIES.prototype.decrypt = function (encbuf) {
      $.checkArgument(encbuf)
      var offset = 0
      var tagLength = 32
      if (this.opts.shortTag) {
        tagLength = 4
      }
      if (!this.opts.noKey) {
        var pub
        switch (encbuf[0]) {
          case 4:
            pub = encbuf.slice(0, 65)
            break
          case 3:
          case 2:
            pub = encbuf.slice(0, 33)
            break
          default:
            throw new Error('Invalid type: ' + encbuf[0])
        }
        this._publicKey = PublicKey.fromDER(pub)
        offset += pub.length
      }
    
      var c = encbuf.slice(offset, encbuf.length - tagLength)
      var d = encbuf.slice(encbuf.length - tagLength, encbuf.length)
    
      var d2 = Hash.sha256hmac(c, this.kM)
      if (this.opts.shortTag) d2 = d2.slice(0, 4)
    
      var equal = true
      for (var i = 0; i < d.length; i++) {
        equal &= (d[i] === d2[i])
      }
      if (!equal) {
        throw new Error('Invalid checksum')
      }
    
      return AESCBC.decrypt(c, this.kE)
    }
    
    module.exports = ECIES
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../":199,"aes-js":8,"buffer":84}],214:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var bsv = require('../../')
    
    var PublicKey = bsv.PublicKey
    var PrivateKey = bsv.PrivateKey
    var Hash = bsv.crypto.Hash
    var $ = bsv.util.preconditions
    var bitcoreECIES = require('./bitcore-ecies')
    var errors = require('./errors')
    var aesjs = require('aes-js')
    var CBC = aesjs.ModeOfOperation.cbc
    
    var AESCBC = function AESCBC () {}
    
    AESCBC.encrypt = function (messagebuf, keybuf, ivbuf) {
      $.checkArgument(messagebuf)
      $.checkArgument(keybuf)
      $.checkArgument(ivbuf)
      $.checkArgument(keybuf.length === 16, 'keybuf length must be 16')
      $.checkArgument(ivbuf.length === 16, 'ivbuf length must be 16')
      messagebuf = aesjs.padding.pkcs7.pad(messagebuf)
      var aesCbc = new CBC(keybuf, ivbuf)
      var encryptedBytes = aesCbc.encrypt(messagebuf)
      return Buffer.from(encryptedBytes)
    }
    
    AESCBC.decrypt = function (encbuf, keybuf, ivbuf) {
      $.checkArgument(encbuf)
      $.checkArgument(keybuf)
      $.checkArgument(ivbuf)
      $.checkArgument(keybuf.length === 16, 'keybuf length must be 16')
      $.checkArgument(ivbuf.length === 16, 'ivbuf length must be 16')
      var aesCbc = new CBC(keybuf, ivbuf)
      var decryptedBytes = aesCbc.decrypt(encbuf)
      return Buffer.from(aesjs.padding.pkcs7.strip(decryptedBytes))
    }
    
    // Electrum BIE1 ECIES
    // Difference from Original Bitcore ECIES:
    //  BIE1:
    //      1.Secret S is compressed P(33 bytes), while Bitcore's Secret is Px(32 bytes). See ivkEkM.
    //      2.use AES-128-CBC instead of AES-256-CBC.
    //      3.IV is retrived from first 16 bytes of Hashed Secret Buffer. See iv
    //      4.key Encryption(kE) is retrived from 17-32 bytes of Hashed Secret Buffer, instead of 1-32 bytes. See kE
    //      5.a magic word 'BIE1' is used to identify message type.
    //      6.ephemeral key is introduced, so you can encrypt messages only with public key.
    //      7.HMAC is whole message.
    //  Notice:
    //      Electrum does not support shortTag nor noKey
    //      Do NOT use those 2 options if you are to send a message to Electrum
    //      Encrypted message is NOT recoverable if you use ephemeral key
    //  Security:
    //
    
    // Default algorithm is set to BIE1, however original Bitcore ECIES is still preserved.
    var ECIES = function ECIES (opts, algorithm = 'BIE1') {
      if (algorithm !== 'BIE1') throw new errors.UnsupportAlgorithm(algorithm)
      if (!(this instanceof ECIES)) {
        return new ECIES(opts, algorithm)
      }
      // use ephemeral key if privateKey is not set.
      this._privateKey = new bsv.PrivateKey()
      this.opts = opts || {}
      this.opts.ephemeralKey = true
    }
    
    ECIES.prototype.privateKey = function (privateKey) {
      $.checkArgument(PrivateKey.isValid(privateKey), 'no private key provided')
    
      this._privateKey = PrivateKey(privateKey.toHex()) || null
      this.opts.ephemeralKey = false
    
      return this
    }
    
    ECIES.prototype.publicKey = function (publicKey) {
      $.checkArgument(PublicKey.isValid(publicKey), 'no public key provided')
    
      this._publicKey = PublicKey(publicKey.toString()) || null
      if (this._publicKey != null) this.opts.fixedPublicKey = true
    
      return this
    }
    
    var defineProperty = function (name, getter) {
      var cachedName = '_' + name
      Object.defineProperty(ECIES.prototype, name, {
        configurable: false,
        enumerable: true,
        get: function () {
          var value = this[cachedName]
          value = this[cachedName] = getter.apply(this)
          return value
        }
      })
    }
    
    defineProperty('Rbuf', function () {
      return this._privateKey.publicKey.toDER(true)
    })
    
    defineProperty('ivkEkM', function () {
      var r = this._privateKey.bn
      var KB = this._publicKey.point
      var P = KB.mul(r)
      var S = PublicKey(P)
      var Sbuf = S.toBuffer()
      return Hash.sha512(Sbuf)
    })
    
    defineProperty('iv', function () {
      return this.ivkEkM.slice(0, 16)
    })
    
    defineProperty('kE', function () {
      return this.ivkEkM.slice(16, 32)
    })
    
    defineProperty('kM', function () {
      return this.ivkEkM.slice(32, 64)
    })
    
    // Encrypts the message (String or Buffer).
    ECIES.prototype.encrypt = function (message) {
      if (!Buffer.isBuffer(message)) message = Buffer.from(message)
      var ciphertext = AESCBC.encrypt(message, this.kE, this.iv)
      var encbuf
      var BIE1 = Buffer.from('BIE1')
      if (this.opts.noKey && !this.opts.ephemeralKey) {
        encbuf = Buffer.concat([BIE1, ciphertext])
      } else {
        encbuf = Buffer.concat([BIE1, this.Rbuf, ciphertext])
      }
      var hmac = Hash.sha256hmac(encbuf, this.kM)
      if (this.opts.shortTag) hmac = hmac.slice(0, 4)
      return Buffer.concat([encbuf, hmac])
    }
    
    ECIES.prototype.decrypt = function (encbuf) {
      $.checkArgument(Buffer.isBuffer(encbuf), 'ciphetext must be a buffer')
      var tagLength = 32
      var offset = 4
      if (this.opts.shortTag) {
        tagLength = 4
      }
      var magic = encbuf.slice(0, 4)
      if (!magic.equals(Buffer.from('BIE1'))) {
        throw new errors.DecryptionError('Invalid Magic')
      }
      if (!this.opts.noKey) {
        var pub
        // BIE1 use compressed public key, length is always 33.
        pub = encbuf.slice(4, 37)
        if (this.opts.fixedPublicKey) console.log('Notice: Overriding PublicKey in message. Consider use "noKey" option if you are not sending message to electrum and do not want to use ephemeral key')
        else this._publicKey = PublicKey.fromDER(pub)
        offset = 37
      }
    
      var ciphertext = encbuf.slice(offset, encbuf.length - tagLength)
      var hmac = encbuf.slice(encbuf.length - tagLength, encbuf.length)
    
      var hmac2 = Hash.sha256hmac(encbuf.slice(0, encbuf.length - tagLength), this.kM)
      if (this.opts.shortTag) hmac2 = hmac2.slice(0, 4)
    
      if (!hmac.equals(hmac2)) {
        throw new errors.DecryptionError('Invalid checksum')
      }
    
      return AESCBC.decrypt(ciphertext, this.kE, this.iv)
    }
    
    ECIES.bitcoreECIES = bitcoreECIES
    
    module.exports = ECIES
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../":199,"./bitcore-ecies":213,"./errors":215,"aes-js":8,"buffer":84}],215:[function(require,module,exports){
    'use strict'
    
    var spec = {
      name: 'ECIES',
      message: 'Internal Error on bsv-ecies Module {0}',
      errors: [{
        name: 'DecryptionError',
        message: 'Invalid Message: {0}'
      },
      {
        name: 'UnsupportAlgorithm',
        message: 'Unsupport Algorithm: {0}'
      }]
    }
    
    module.exports = require('../../').errors.extend(spec)
    
    },{"../../":199}],216:[function(require,module,exports){
    module.exports = require('./electrum-ecies')
    
    },{"./electrum-ecies":214}],217:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var bs58 = require('bs58')
    var buffer = require('buffer')
    
    /**
     * The alphabet for the Bitcoin-specific Base 58 encoding distinguishes between
     * lower case L and upper case i - neither of those characters are allowed to
     * prevent accidentaly miscopying of letters.
     */
    var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split('')
    
    /**
     * A Base58 object can encode/decoded Base 58, which is used primarily for
     * string-formatted Bitcoin addresses and private keys. Addresses and private
     * keys actually use an additional checksum, and so they actually use the
     * Base58Check class.
     *
     * @param {object} obj Can be a string or buffer.
     */
    var Base58 = function Base58 (obj) {
      if (!(this instanceof Base58)) {
        return new Base58(obj)
      }
      if (Buffer.isBuffer(obj)) {
        var buf = obj
        this.fromBuffer(buf)
      } else if (typeof obj === 'string') {
        var str = obj
        this.fromString(str)
      }
    }
    
    Base58.validCharacters = function validCharacters (chars) {
      if (buffer.Buffer.isBuffer(chars)) {
        chars = chars.toString()
      }
      return _.every(_.map(chars, function (char) { return _.includes(ALPHABET, char) }))
    }
    
    Base58.prototype.set = function (obj) {
      this.buf = obj.buf || this.buf || undefined
      return this
    }
    
    /**
     * Encode a buffer to Bsae 58.
     *
     * @param {Buffer} buf Any buffer to be encoded.
     * @returns {string} A Base 58 encoded string.
     */
    Base58.encode = function (buf) {
      if (!buffer.Buffer.isBuffer(buf)) {
        throw new Error('Input should be a buffer')
      }
      return bs58.encode(buf)
    }
    
    /**
     * Decode a Base 58 string to a buffer.
     *
     * @param {string} str A Base 58 encoded string.
     * @returns {Buffer} The decoded buffer.
     */
    Base58.decode = function (str) {
      if (typeof str !== 'string') {
        throw new Error('Input should be a string')
      }
      return Buffer.from(bs58.decode(str))
    }
    
    Base58.prototype.fromBuffer = function (buf) {
      this.buf = buf
      return this
    }
    
    Base58.fromBuffer = function (buf) {
      return new Base58().fromBuffer(buf)
    }
    
    Base58.fromHex = function (hex) {
      return Base58.fromBuffer(Buffer.from(hex, 'hex'))
    }
    
    Base58.prototype.fromString = function (str) {
      var buf = Base58.decode(str)
      this.buf = buf
      return this
    }
    
    Base58.fromString = function (str) {
      return new Base58().fromString(str)
    }
    
    Base58.prototype.toBuffer = function () {
      return this.buf
    }
    
    Base58.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    Base58.prototype.toString = function () {
      return Base58.encode(this.buf)
    }
    
    module.exports = Base58
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/_":270,"bs58":85,"buffer":84}],218:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var Base58 = require('./base58')
    var buffer = require('buffer')
    var sha256sha256 = require('../crypto/hash').sha256sha256
    
    /**
     * A Base58check object can encode/decodd Base 58, which is used primarily for
     * string-formatted Bitcoin addresses and private keys. This is the same as
     * Base58, except that it includes a checksum to prevent accidental mistypings.
     *
     * @param {object} obj Can be a string or buffer.
     */
    var Base58Check = function Base58Check (obj) {
      if (!(this instanceof Base58Check)) { return new Base58Check(obj) }
      if (Buffer.isBuffer(obj)) {
        var buf = obj
        this.fromBuffer(buf)
      } else if (typeof obj === 'string') {
        var str = obj
        this.fromString(str)
      }
    }
    
    Base58Check.prototype.set = function (obj) {
      this.buf = obj.buf || this.buf || undefined
      return this
    }
    
    Base58Check.validChecksum = function validChecksum (data, checksum) {
      if (_.isString(data)) {
        data = buffer.Buffer.from(Base58.decode(data))
      }
      if (_.isString(checksum)) {
        checksum = buffer.Buffer.from(Base58.decode(checksum))
      }
      if (!checksum) {
        checksum = data.slice(-4)
        data = data.slice(0, -4)
      }
      return Base58Check.checksum(data).toString('hex') === checksum.toString('hex')
    }
    
    Base58Check.decode = function (s) {
      if (typeof s !== 'string') { throw new Error('Input must be a string') }
    
      var buf = Buffer.from(Base58.decode(s))
    
      if (buf.length < 4) { throw new Error('Input string too short') }
    
      var data = buf.slice(0, -4)
      var csum = buf.slice(-4)
    
      var hash = sha256sha256(data)
      var hash4 = hash.slice(0, 4)
    
      if (csum.toString('hex') !== hash4.toString('hex')) { throw new Error('Checksum mismatch') }
    
      return data
    }
    
    Base58Check.checksum = function (buffer) {
      return sha256sha256(buffer).slice(0, 4)
    }
    
    Base58Check.encode = function (buf) {
      if (!Buffer.isBuffer(buf)) { throw new Error('Input must be a buffer') }
      var checkedBuf = Buffer.alloc(buf.length + 4)
      var hash = Base58Check.checksum(buf)
      buf.copy(checkedBuf)
      hash.copy(checkedBuf, buf.length)
      return Base58.encode(checkedBuf)
    }
    
    Base58Check.prototype.fromBuffer = function (buf) {
      this.buf = buf
      return this
    }
    
    Base58Check.fromBuffer = function (buf) {
      return new Base58Check().fromBuffer(buf)
    }
    
    Base58Check.fromHex = function (hex) {
      return Base58Check.fromBuffer(Buffer.from(hex, 'hex'))
    }
    
    Base58Check.prototype.fromString = function (str) {
      var buf = Base58Check.decode(str)
      this.buf = buf
      return this
    }
    
    Base58Check.fromString = function (str) {
      var buf = Base58Check.decode(str)
      return new Base58(buf)
    }
    
    Base58Check.prototype.toBuffer = function () {
      return this.buf
    }
    
    Base58Check.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    Base58Check.prototype.toString = function () {
      return Base58Check.encode(this.buf)
    }
    
    module.exports = Base58Check
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/hash":208,"../util/_":270,"./base58":217,"buffer":84}],219:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    var BN = require('../crypto/bn')
    
    var BufferReader = function BufferReader (buf) {
      if (!(this instanceof BufferReader)) {
        return new BufferReader(buf)
      }
      if (_.isUndefined(buf)) {
        return
      }
      if (Buffer.isBuffer(buf)) {
        this.set({
          buf: buf
        })
      } else if (_.isString(buf)) {
        var b = Buffer.from(buf, 'hex')
        if (b.length * 2 !== buf.length) { throw new TypeError('Invalid hex string') }
    
        this.set({
          buf: b
        })
      } else if (_.isObject(buf)) {
        var obj = buf
        this.set(obj)
      } else {
        throw new TypeError('Unrecognized argument for BufferReader')
      }
    }
    
    BufferReader.prototype.set = function (obj) {
      this.buf = obj.buf || this.buf || undefined
      this.pos = obj.pos || this.pos || 0
      return this
    }
    
    BufferReader.prototype.eof = function () {
      return this.pos >= this.buf.length
    }
    
    BufferReader.prototype.finished = BufferReader.prototype.eof
    
    BufferReader.prototype.read = function (len) {
      $.checkArgument(!_.isUndefined(len), 'Must specify a length')
      var buf = this.buf.slice(this.pos, this.pos + len)
      this.pos = this.pos + len
      return buf
    }
    
    BufferReader.prototype.readAll = function () {
      var buf = this.buf.slice(this.pos, this.buf.length)
      this.pos = this.buf.length
      return buf
    }
    
    BufferReader.prototype.readUInt8 = function () {
      var val = this.buf.readUInt8(this.pos)
      this.pos = this.pos + 1
      return val
    }
    
    BufferReader.prototype.readUInt16BE = function () {
      var val = this.buf.readUInt16BE(this.pos)
      this.pos = this.pos + 2
      return val
    }
    
    BufferReader.prototype.readUInt16LE = function () {
      var val = this.buf.readUInt16LE(this.pos)
      this.pos = this.pos + 2
      return val
    }
    
    BufferReader.prototype.readUInt32BE = function () {
      var val = this.buf.readUInt32BE(this.pos)
      this.pos = this.pos + 4
      return val
    }
    
    BufferReader.prototype.readUInt32LE = function () {
      var val = this.buf.readUInt32LE(this.pos)
      this.pos = this.pos + 4
      return val
    }
    
    BufferReader.prototype.readInt32LE = function () {
      var val = this.buf.readInt32LE(this.pos)
      this.pos = this.pos + 4
      return val
    }
    
    BufferReader.prototype.readUInt64BEBN = function () {
      var buf = this.buf.slice(this.pos, this.pos + 8)
      var bn = BN.fromBuffer(buf)
      this.pos = this.pos + 8
      return bn
    }
    
    BufferReader.prototype.readUInt64LEBN = function () {
      var second = this.buf.readUInt32LE(this.pos)
      var first = this.buf.readUInt32LE(this.pos + 4)
      var combined = (first * 0x100000000) + second
      // Instantiating an instance of BN with a number is faster than with an
      // array or string. However, the maximum safe number for a double precision
      // floating point is 2 ^ 52 - 1 (0x1fffffffffffff), thus we can safely use
      // non-floating point numbers less than this amount (52 bits). And in the case
      // that the number is larger, we can instatiate an instance of BN by passing
      // an array from the buffer (slower) and specifying the endianness.
      var bn
      if (combined <= 0x1fffffffffffff) {
        bn = new BN(combined)
      } else {
        var data = Array.prototype.slice.call(this.buf, this.pos, this.pos + 8)
        bn = new BN(data, 10, 'le')
      }
      this.pos = this.pos + 8
      return bn
    }
    
    BufferReader.prototype.readVarintNum = function () {
      var first = this.readUInt8()
      switch (first) {
        case 0xFD:
          return this.readUInt16LE()
        case 0xFE:
          return this.readUInt32LE()
        case 0xFF:
          var bn = this.readUInt64LEBN()
          var n = bn.toNumber()
          if (n <= Math.pow(2, 53)) {
            return n
          } else {
            throw new Error('number too large to retain precision - use readVarintBN')
          }
          // break // unreachable
        default:
          return first
      }
    }
    
    /**
     * reads a length prepended buffer
     */
    BufferReader.prototype.readVarLengthBuffer = function () {
      var len = this.readVarintNum()
      var buf = this.read(len)
      $.checkState(buf.length === len, 'Invalid length while reading varlength buffer. ' +
        'Expected to read: ' + len + ' and read ' + buf.length)
      return buf
    }
    
    BufferReader.prototype.readVarintBuf = function () {
      var first = this.buf.readUInt8(this.pos)
      switch (first) {
        case 0xFD:
          return this.read(1 + 2)
        case 0xFE:
          return this.read(1 + 4)
        case 0xFF:
          return this.read(1 + 8)
        default:
          return this.read(1)
      }
    }
    
    BufferReader.prototype.readVarintBN = function () {
      var first = this.readUInt8()
      switch (first) {
        case 0xFD:
          return new BN(this.readUInt16LE())
        case 0xFE:
          return new BN(this.readUInt32LE())
        case 0xFF:
          return this.readUInt64LEBN()
        default:
          return new BN(first)
      }
    }
    
    BufferReader.prototype.reverse = function () {
      var buf = Buffer.alloc(this.buf.length)
      for (var i = 0; i < buf.length; i++) {
        buf[i] = this.buf[this.buf.length - 1 - i]
      }
      this.buf = buf
      return this
    }
    
    BufferReader.prototype.readReverse = function (len) {
      if (_.isUndefined(len)) {
        len = this.buf.length
      }
      var buf = this.buf.slice(this.pos, this.pos + len)
      this.pos = this.pos + len
      return Buffer.from(buf).reverse()
    }
    
    module.exports = BufferReader
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"../util/_":270,"../util/preconditions":272,"buffer":84}],220:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var assert = require('assert')
    
    const writeU8LE = require('../script/write-u8-le')
    const writeU16LE = require('../script/write-u16-le')
    const writeU32LE = require('../script/write-u32-le')
    const writeI32LE = require('../script/write-i32-le')
    const writeVarint = require('../script/write-varint')
    
    class BufferWriter {
      constructor (obj) {
        if (obj) { this.set(obj) } else {
          this.buffers = []
          this.length = 0
        }
      }
    
      write (buffer) {
        this.buffers.push(buffer)
        this.length += buffer.length
        return this
      }
    
      set (obj) {
        this.buffers = obj.buffers || obj.bufs || this.buffers || []
        this.length = this.buffers.reduce(function (prev, buf) { return prev + buf.length }, 0)
        return this
      }
    
      concat () {
        return this.toBuffer()
      }
    
      toBuffer () {
        if (this.buffers.length === 1) {
          return Buffer.from(this.buffers[0])
        }
    
        const whole = new Uint8Array(this.length)
    
        let offset = 0
        this.buffers.forEach(part => {
          whole.set(part, offset)
          offset += part.length
        })
    
        return Buffer.from(whole)
      }
    
      writeReverse (buf) {
        assert(Buffer.isBuffer(buf))
        this.write(Buffer.from(buf).reverse())
        return this
      }
    
      writeUInt16LE (n) {
        writeU16LE(this, n)
        return this
      }
    
      writeUInt16BE (n) {
        var bw = new BufferWriter()
        bw.writeUInt16LE(n)
        this.writeReverse(bw.toBuffer())
        return this
      }
    
      writeUInt32LE (n) {
        writeU32LE(this, n)
        return this
      }
    
      writeUInt32BE (n) {
        var bw = new BufferWriter()
        bw.writeUInt32LE(n)
        this.writeReverse(bw.toBuffer())
        return this
      }
    
      writeUInt8 (n) {
        writeU8LE(this, n)
        return this
      }
    
      writeUInt64LEBN (bn) {
        var buf = bn.toBuffer({ size: 8 })
        this.writeReverse(buf)
        return this
      }
    
      writeUInt64BEBN (bn) {
        var bw = new BufferWriter()
        bw.writeUInt64LEBN(bn)
        this.writeReverse(bw.toBuffer())
        return this
      }
    
      writeVarintNum (n) {
        writeVarint(this, n)
        return this
      }
    
      writeInt32LE (n) {
        writeI32LE(this, n)
        return this
      }
    
      static varintBufNum (n) {
        var bw = new BufferWriter()
        bw.writeVarintNum(n)
        return bw.toBuffer()
      }
    
      writeVarintBN (bn) {
        var n = bn.toNumber()
        if (n < 253) {
          writeU8LE(this, n)
        } else if (n < 0x10000) {
          writeU8LE(this, 253)
          writeU16LE(this, n)
        } else if (n < 0x100000000) {
          writeU8LE(this, 254)
          writeU32LE(this, n)
        } else {
          var bw = new BufferWriter()
          bw.writeUInt8(255)
          bw.writeUInt64LEBN(bn)
          var buf = bw.toBuffer()
          this.write(buf)
        }
        return this
      }
    }
    
    module.exports = BufferWriter
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../script/write-i32-le":252,"../script/write-u16-le":254,"../script/write-u32-le":255,"../script/write-u8-le":256,"../script/write-varint":257,"assert":24,"buffer":84}],221:[function(require,module,exports){
    const decodeHex = require('./decode-hex')
    const opcodes = require('../opcode')
    const BufferWriter = require('./bufferwriter')
    const writePushData = require('../script/write-push-data')
    
    function decodeASM (script) {
      const parts = script.split(' ')
      const writer = new BufferWriter()
      parts.forEach(part => {
        if (part in opcodes) {
          writer.write([opcodes[part]])
        } else if (part === '0') {
          writer.write([opcodes.OP_0])
        } else if (part === '-1') {
          writer.write([opcodes.OP_1NEGATE])
        } else {
          const buf = decodeHex(part)
          writePushData(writer, buf)
        }
      })
      return writer.toBuffer()
    }
    
    module.exports = decodeASM
    
    },{"../opcode":245,"../script/write-push-data":253,"./bufferwriter":220,"./decode-hex":222}],222:[function(require,module,exports){
    (function (Buffer){(function (){
    /* global VARIANT */
    
    const isHex = require('./is-hex')
    
    // Prefer our implementation of decodeHex over Buffer when we don't know the VARIANT
    // to avoid accidentally importing the Buffer shim in the browser.
    
    function decodeHex (hex) {
      if (typeof hex !== 'string') throw new Error('not a string')
    
      if (hex.startsWith('0x')) hex = hex.slice(2)
    
      if (hex.length % 2 === 1) hex = '0' + hex
    
      if (!isHex(hex)) throw new Error('invalid hex string in script')
    
      if (typeof VARIANT === 'undefined' || VARIANT === 'browser') {
        const length = hex.length / 2
        const arr = new Uint8Array(length)
        const isNaN = x => x !== x // eslint-disable-line no-self-compare
        for (let i = 0; i < length; ++i) {
          const byte = parseInt(hex.substr(i * 2, 2), 16)
          if (isNaN(byte)) throw new Error('bad hex char')
          arr[i] = byte
        }
        return arr
      } else {
        return Buffer.from(hex, 'hex')
      }
    }
    
    module.exports = decodeHex
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./is-hex":225,"buffer":84}],223:[function(require,module,exports){
    function decodeScriptChunks (script) {
      const chunks = []
      let i = 0
      let len = 0
      while (i < script.length) {
        const opcodenum = script[i]
        i += 1
        if (opcodenum === 0) {
          len = opcodenum
          chunks.push({ opcodenum: opcodenum, len })
        } else if (opcodenum < 76) { // OP_PUSHDATA1
          len = opcodenum
          chunks.push({ opcodenum: opcodenum, buf: script.slice(i, i + opcodenum), len })
          i += opcodenum
        } else if (opcodenum === 76) { // OP_PUSHDATA1
          len = script[i]
          i += 1
          chunks.push({ opcodenum: opcodenum, buf: script.slice(i, i + len), len })
          i += len
        } else if (opcodenum === 77) { // OP_PUSHDATA2
          len = script[i] | script[i + 1] << 8
          i += 2
          chunks.push({ opcodenum: opcodenum, buf: script.slice(i, i + len), len })
          i += len
        } else if (opcodenum === 78) { // OP_PUSHDATA4
          len = script[i] + script[i + 1] * 0x0100 + script[i + 2] * 0x010000 + script[i + 3] * 0x01000000
          i += 4
          chunks.push({ opcodenum: opcodenum, buf: script.slice(i, i + len), len })
          i += len
        } else {
          chunks.push({ opcodenum: opcodenum })
        }
      }
      // if (i !== script.length) throw new Error('bad script')
      return chunks
    }
    
    module.exports = decodeScriptChunks
    
    },{}],224:[function(require,module,exports){
    (function (Buffer){(function (){
    /* global VARIANT */
    
    let encodeHex = null
    
    // Prefer our implementation of encodeHex over Buffer when we don't know the VARIANT
    // to avoid accidentally importing the Buffer shim in the browser.
    
    if (typeof VARIANT === 'undefined' || VARIANT === 'browser') {
      // In the browser, a lookup table is fastest, and faster than the Buffer toString shim.
      const HEX = [
        '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f',
        '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f',
        '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f',
        '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f',
        '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f',
        '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f',
        '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f',
        '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f',
        '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f',
        '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f',
        'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af',
        'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf',
        'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf',
        'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df',
        'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef',
        'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff'
      ]
    
      encodeHex = function (buffer) {
        const len = buffer.length
        const out = new Array(len)
        for (let i = 0; i < len; ++i) {
          out[i] = HEX[buffer[i]]
        }
        return out.join('')
      }
    } else {
      // Buffer toString('hex') in Node is faster than any JavaScript we could write
      encodeHex = function (buffer) {
        return buffer instanceof Buffer ? buffer.toString('hex') : Buffer.from(buffer).toString('hex')
      }
    }
    
    module.exports = encodeHex
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84}],225:[function(require,module,exports){
    const HEX_REGEX = /^(?:[a-fA-F0-9][a-fA-F0-9])*$/
    
    function isHex (s) {
      return HEX_REGEX.test(s)
    }
    
    module.exports = isHex
    
    },{}],226:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BufferWriter = require('./bufferwriter')
    var BufferReader = require('./bufferreader')
    var BN = require('../crypto/bn')
    
    var Varint = function Varint (buf) {
      if (!(this instanceof Varint)) { return new Varint(buf) }
      if (Buffer.isBuffer(buf)) {
        this.buf = buf
      } else if (typeof buf === 'number') {
        var num = buf
        this.fromNumber(num)
      } else if (buf instanceof BN) {
        var bn = buf
        this.fromBN(bn)
      } else if (buf) {
        var obj = buf
        this.set(obj)
      }
    }
    
    Varint.prototype.set = function (obj) {
      this.buf = obj.buf || this.buf
      return this
    }
    
    Varint.prototype.fromString = function (str) {
      this.set({
        buf: Buffer.from(str, 'hex')
      })
      return this
    }
    
    Varint.prototype.toString = function () {
      return this.buf.toString('hex')
    }
    
    Varint.prototype.fromBuffer = function (buf) {
      this.buf = buf
      return this
    }
    
    Varint.prototype.fromBufferReader = function (br) {
      this.buf = br.readVarintBuf()
      return this
    }
    
    Varint.prototype.fromBN = function (bn) {
      var bw = new BufferWriter()
      this.buf = bw.writeVarintBN(bn).toBuffer()
      return this
    }
    
    Varint.prototype.fromNumber = function (num) {
      var bw = new BufferWriter()
      this.buf = bw.writeVarintNum(num).toBuffer()
      return this
    }
    
    Varint.prototype.toBuffer = function () {
      return this.buf
    }
    
    Varint.prototype.toBN = function () {
      return BufferReader(this.buf).readVarintBN()
    }
    
    Varint.prototype.toNumber = function () {
      return BufferReader(this.buf).readVarintNum()
    }
    
    module.exports = Varint
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"./bufferreader":219,"./bufferwriter":220,"buffer":84}],227:[function(require,module,exports){
    'use strict'
    
    var _ = require('../util/_')
    
    function format (message, args) {
      return message
        .replace('{0}', args[0])
        .replace('{1}', args[1])
        .replace('{2}', args[2])
    }
    var traverseNode = function (parent, errorDefinition) {
      var NodeError = function () {
        if (_.isString(errorDefinition.message)) {
          this.message = format(errorDefinition.message, arguments)
        } else if (_.isFunction(errorDefinition.message)) {
          this.message = errorDefinition.message.apply(null, arguments)
        } else {
          throw new Error('Invalid error definition for ' + errorDefinition.name)
        }
        this.stack = this.message + '\n' + (new Error()).stack
      }
      NodeError.prototype = Object.create(parent.prototype)
      NodeError.prototype.name = parent.prototype.name + errorDefinition.name
      parent[errorDefinition.name] = NodeError
      if (errorDefinition.errors) {
        childDefinitions(NodeError, errorDefinition.errors)
      }
      return NodeError
    }
    
    var childDefinitions = function (parent, childDefinitions) {
      _.each(childDefinitions, function (childDefinition) {
        traverseNode(parent, childDefinition)
      })
    }
    
    var traverseRoot = function (parent, errorsDefinition) {
      childDefinitions(parent, errorsDefinition)
      return parent
    }
    
    var bsv = {}
    bsv.Error = function () {
      this.message = 'Internal error'
      this.stack = this.message + '\n' + (new Error()).stack
    }
    bsv.Error.prototype = Object.create(Error.prototype)
    bsv.Error.prototype.name = 'bsv.Error'
    
    var data = require('./spec')
    traverseRoot(bsv.Error, data)
    
    module.exports = bsv.Error
    
    module.exports.extend = function (spec) {
      return traverseNode(bsv.Error, spec)
    }
    
    },{"../util/_":270,"./spec":228}],228:[function(require,module,exports){
    'use strict'
    
    var docsURL = 'https://docs.moneybutton.com/'
    
    module.exports = [{
      name: 'InvalidB58Char',
      message: 'Invalid Base58 character: {0} in {1}'
    }, {
      name: 'InvalidB58Checksum',
      message: 'Invalid Base58 checksum for {0}'
    }, {
      name: 'InvalidNetwork',
      message: 'Invalid version for network: got {0}'
    }, {
      name: 'InvalidState',
      message: 'Invalid state: {0}'
    }, {
      name: 'NotImplemented',
      message: 'Function {0} was not implemented yet'
    }, {
      name: 'InvalidNetworkArgument',
      message: 'Invalid network: must be "livenet" or "testnet", got {0}'
    }, {
      name: 'InvalidArgument',
      message: function () {
        return 'Invalid Argument' + (arguments[0] ? (': ' + arguments[0]) : '') +
          (arguments[1] ? (' Documentation: ' + docsURL + arguments[1]) : '')
      }
    }, {
      name: 'AbstractMethodInvoked',
      message: 'Abstract Method Invocation: {0}'
    }, {
      name: 'InvalidArgumentType',
      message: function () {
        return 'Invalid Argument for ' + arguments[2] + ', expected ' + arguments[1] + ' but got ' + typeof arguments[0]
      }
    }, {
      name: 'Unit',
      message: 'Internal Error on Unit {0}',
      errors: [{
        'name': 'UnknownCode',
        'message': 'Unrecognized unit code: {0}'
      }, {
        'name': 'InvalidRate',
        'message': 'Invalid exchange rate: {0}'
      }]
    }, {
      name: 'MerkleBlock',
      message: 'Internal Error on MerkleBlock {0}',
      errors: [{
        'name': 'InvalidMerkleTree',
        'message': 'This MerkleBlock contain an invalid Merkle Tree'
      }]
    }, {
      name: 'Transaction',
      message: 'Internal Error on Transaction {0}',
      errors: [{
        name: 'Input',
        message: 'Internal Error on Input {0}',
        errors: [{
          name: 'MissingScript',
          message: 'Need a script to create an input'
        }, {
          name: 'UnsupportedScript',
          message: 'Unsupported input script type: {0}'
        }, {
          name: 'MissingPreviousOutput',
          message: 'No previous output information.'
        }]
      }, {
        name: 'NeedMoreInfo',
        message: '{0}'
      }, {
        name: 'InvalidSorting',
        message: 'The sorting function provided did not return the change output as one of the array elements'
      }, {
        name: 'InvalidOutputAmountSum',
        message: '{0}'
      }, {
        name: 'MissingSignatures',
        message: 'Some inputs have not been fully signed'
      }, {
        name: 'InvalidIndex',
        message: 'Invalid index: {0} is not between 0, {1}'
      }, {
        name: 'UnableToVerifySignature',
        message: 'Unable to verify signature: {0}'
      }, {
        name: 'DustOutputs',
        message: 'Dust amount detected in one output'
      }, {
        name: 'InvalidSatoshis',
        message: 'Output satoshis are invalid'
      }, {
        name: 'FeeError',
        message: 'Internal Error on Fee {0}',
        errors: [{
          name: 'TooSmall',
          message: 'Fee is too small: {0}'
        }, {
          name: 'TooLarge',
          message: 'Fee is too large: {0}'
        }, {
          name: 'Different',
          message: 'Unspent value is different from specified fee: {0}'
        }]
      }, {
        name: 'ChangeAddressMissing',
        message: 'Change address is missing'
      }, {
        name: 'BlockHeightTooHigh',
        message: 'Block Height can be at most 2^32 -1'
      }, {
        name: 'NLockTimeOutOfRange',
        message: 'Block Height can only be between 0 and 499 999 999'
      }, {
        name: 'LockTimeTooEarly',
        message: 'Lock Time can\'t be earlier than UNIX date 500 000 000'
      }, {
        name: 'TransactionAlreadySealed',
        message: 'Cannot update sealed transaction'
      }]
    }, {
      name: 'Script',
      message: 'Internal Error on Script {0}',
      errors: [{
        name: 'UnrecognizedAddress',
        message: 'Expected argument {0} to be an address'
      }, {
        name: 'CantDeriveAddress',
        message: 'Can\'t derive address associated with script {0}, needs to be p2pkh in, p2pkh out, p2sh in, or p2sh out.'
      }, {
        name: 'InvalidBuffer',
        message: 'Invalid script buffer: can\'t parse valid script from given buffer {0}'
      }, {
        name: 'InvalidOpcode',
        message: 'Invalid Opcode: got "{0}"'
      }]
    }, {
      name: 'HDPrivateKey',
      message: 'Internal Error on HDPrivateKey {0}',
      errors: [{
        name: 'InvalidDerivationArgument',
        message: 'Invalid derivation argument {0}, expected string, or number and boolean'
      }, {
        name: 'InvalidEntropyArgument',
        message: 'Invalid entropy: must be an hexa string or binary buffer, got {0}',
        errors: [{
          name: 'TooMuchEntropy',
          message: 'Invalid entropy: more than 512 bits is non standard, got "{0}"'
        }, {
          name: 'NotEnoughEntropy',
          message: 'Invalid entropy: at least 128 bits needed, got "{0}"'
        }]
      }, {
        name: 'InvalidLength',
        message: 'Invalid length for xprivkey string in {0}'
      }, {
        name: 'InvalidPath',
        message: 'Invalid derivation path: {0}'
      }, {
        name: 'UnrecognizedArgument',
        message: 'Invalid argument: creating a HDPrivateKey requires a string, buffer, json or object, got "{0}"'
      }]
    }, {
      name: 'HDPublicKey',
      message: 'Internal Error on HDPublicKey {0}',
      errors: [{
        name: 'ArgumentIsPrivateExtended',
        message: 'Argument is an extended private key: {0}'
      }, {
        name: 'InvalidDerivationArgument',
        message: 'Invalid derivation argument: got {0}'
      }, {
        name: 'InvalidLength',
        message: 'Invalid length for xpubkey: got "{0}"'
      }, {
        name: 'InvalidPath',
        message: 'Invalid derivation path, it should look like: "m/1/100", got "{0}"'
      }, {
        name: 'InvalidIndexCantDeriveHardened',
        message: 'Invalid argument: creating a hardened path requires an HDPrivateKey'
      }, {
        name: 'MustSupplyArgument',
        message: 'Must supply an argument to create a HDPublicKey'
      }, {
        name: 'UnrecognizedArgument',
        message: 'Invalid argument for creation, must be string, json, buffer, or object'
      }]
    }]
    
    },{}],229:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var assert = require('assert')
    var buffer = require('buffer')
    var _ = require('./util/_')
    var $ = require('./util/preconditions')
    
    var BN = require('./crypto/bn')
    var Base58 = require('./encoding/base58')
    var Base58Check = require('./encoding/base58check')
    var Hash = require('./crypto/hash')
    var Network = require('./networks')
    var Point = require('./crypto/point')
    var PrivateKey = require('./privatekey')
    var Random = require('./crypto/random')
    
    var errors = require('./errors')
    var hdErrors = errors.HDPrivateKey
    var JSUtil = require('./util/js')
    
    var MINIMUM_ENTROPY_BITS = 128
    var BITS_TO_BYTES = 1 / 8
    var MAXIMUM_ENTROPY_BITS = 512
    
    /**
     * Represents an instance of an hierarchically derived private key.
     *
     * More info on https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
     *
     * @constructor
     * @param {string|Buffer|Object} arg
     */
    function HDPrivateKey (arg) {
      if (arg instanceof HDPrivateKey) {
        return arg
      }
      if (!(this instanceof HDPrivateKey)) {
        return new HDPrivateKey(arg)
      }
      if (!arg) {
        return this._generateRandomly()
      }
    
      if (Network.get(arg)) {
        return this._generateRandomly(arg)
      } else if (_.isString(arg) || Buffer.isBuffer(arg)) {
        if (HDPrivateKey.isValidSerialized(arg)) {
          this._buildFromSerialized(arg)
        } else if (JSUtil.isValidJSON(arg)) {
          this._buildFromJSON(arg)
        } else if (Buffer.isBuffer(arg) && HDPrivateKey.isValidSerialized(arg.toString())) {
          this._buildFromSerialized(arg.toString())
        } else {
          throw HDPrivateKey.getSerializedError(arg)
        }
      } else if (_.isObject(arg)) {
        this._buildFromObject(arg)
      } else {
        throw new hdErrors.UnrecognizedArgument(arg)
      }
    }
    
    HDPrivateKey.fromRandom = function () {
      return new HDPrivateKey()
    }
    
    /**
     * Verifies that a given path is valid.
     *
     * @param {string|number} arg
     * @param {boolean?} hardened
     * @return {boolean}
     */
    HDPrivateKey.isValidPath = function (arg, hardened) {
      if (_.isString(arg)) {
        var indexes = HDPrivateKey._getDerivationIndexes(arg)
        return indexes !== null && _.every(indexes, HDPrivateKey.isValidPath)
      }
    
      if (_.isNumber(arg)) {
        if (arg < HDPrivateKey.Hardened && hardened === true) {
          arg += HDPrivateKey.Hardened
        }
        return arg >= 0 && arg < HDPrivateKey.MaxIndex
      }
    
      return false
    }
    
    /**
     * Internal function that splits a string path into a derivation index array.
     * It will return null if the string path is malformed.
     * It does not validate if indexes are in bounds.
     *
     * @param {string} path
     * @return {Array}
     */
    HDPrivateKey._getDerivationIndexes = function (path) {
      var steps = path.split('/')
    
      // Special cases:
      if (_.includes(HDPrivateKey.RootElementAlias, path)) {
        return []
      }
    
      if (!_.includes(HDPrivateKey.RootElementAlias, steps[0])) {
        return null
      }
    
      var indexes = steps.slice(1).map(function (step) {
        var isHardened = step.slice(-1) === '\''
        if (isHardened) {
          step = step.slice(0, -1)
        }
        if (!step || step[0] === '-') {
          return NaN
        }
        var index = +step // cast to number
        if (isHardened) {
          index += HDPrivateKey.Hardened
        }
    
        return index
      })
    
      return _.some(indexes, isNaN) ? null : indexes
    }
    
    /**
     * WARNING: This method is deprecated. Use deriveChild or deriveNonCompliantChild instead. This is not BIP32 compliant
     *
     *
     * Get a derived child based on a string or number.
     *
     * If the first argument is a string, it's parsed as the full path of
     * derivation. Valid values for this argument include "m" (which returns the
     * same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
     * derivation.
     *
     * If the first argument is a number, the child with that index will be
     * derived. If the second argument is truthy, the hardened version will be
     * derived. See the example usage for clarification.
     *
     * @example
     * ```javascript
     * var parent = new HDPrivateKey('xprv...');
     * var child_0_1_2h = parent.derive(0).derive(1).derive(2, true);
     * var copy_of_child_0_1_2h = parent.derive("m/0/1/2'");
     * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
     * ```
     *
     * @param {string|number} arg
     * @param {boolean?} hardened
     */
    HDPrivateKey.prototype.derive = function () {
      throw new Error('derive has been deprecated. use deriveChild or, for the old way, deriveNonCompliantChild.')
    }
    
    /**
     * WARNING: This method will not be officially supported until v1.0.0.
     *
     *
     * Get a derived child based on a string or number.
     *
     * If the first argument is a string, it's parsed as the full path of
     * derivation. Valid values for this argument include "m" (which returns the
     * same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
     * derivation.
     *
     * If the first argument is a number, the child with that index will be
     * derived. If the second argument is truthy, the hardened version will be
     * derived. See the example usage for clarification.
     *
     * WARNING: The `nonCompliant` option should NOT be used, except for older implementation
     * that used a derivation strategy that used a non-zero padded private key.
     *
     * @example
     * ```javascript
     * var parent = new HDPrivateKey('xprv...');
     * var child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true);
     * var copy_of_child_0_1_2h = parent.deriveChild("m/0/1/2'");
     * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
     * ```
     *
     * @param {string|number} arg
     * @param {boolean?} hardened
     */
    HDPrivateKey.prototype.deriveChild = function (arg, hardened) {
      if (_.isNumber(arg)) {
        return this._deriveWithNumber(arg, hardened)
      } else if (_.isString(arg)) {
        return this._deriveFromString(arg)
      } else {
        throw new hdErrors.InvalidDerivationArgument(arg)
      }
    }
    
    /**
     * WARNING: This method will not be officially supported until v1.0.0
     *
     *
     * WARNING: If this is a new implementation you should NOT use this method, you should be using
     * `derive` instead.
     *
     * This method is explicitly for use and compatibility with an implementation that
     * was not compliant with BIP32 regarding the derivation algorithm. The private key
     * must be 32 bytes hashing, and this implementation will use the non-zero padded
     * serialization of a private key, such that it's still possible to derive the privateKey
     * to recover those funds.
     *
     * @param {string|number} arg
     * @param {boolean?} hardened
     */
    HDPrivateKey.prototype.deriveNonCompliantChild = function (arg, hardened) {
      if (_.isNumber(arg)) {
        return this._deriveWithNumber(arg, hardened, true)
      } else if (_.isString(arg)) {
        return this._deriveFromString(arg, true)
      } else {
        throw new hdErrors.InvalidDerivationArgument(arg)
      }
    }
    
    HDPrivateKey.prototype._deriveWithNumber = function (index, hardened, nonCompliant) {
      if (!HDPrivateKey.isValidPath(index, hardened)) {
        throw new hdErrors.InvalidPath(index)
      }
    
      hardened = index >= HDPrivateKey.Hardened ? true : hardened
      if (index < HDPrivateKey.Hardened && hardened === true) {
        index += HDPrivateKey.Hardened
      }
    
      var indexBuffer = JSUtil.integerAsBuffer(index)
      var data
      if (hardened && nonCompliant) {
        // The private key serialization in this case will not be exactly 32 bytes and can be
        // any value less, and the value is not zero-padded.
        var nonZeroPadded = this.privateKey.bn.toBuffer()
        data = Buffer.concat([buffer.Buffer.from([0]), nonZeroPadded, indexBuffer])
      } else if (hardened) {
        // This will use a 32 byte zero padded serialization of the private key
        var privateKeyBuffer = this.privateKey.bn.toBuffer({ size: 32 })
        assert(privateKeyBuffer.length === 32, 'length of private key buffer is expected to be 32 bytes')
        data = Buffer.concat([buffer.Buffer.from([0]), privateKeyBuffer, indexBuffer])
      } else {
        data = Buffer.concat([this.publicKey.toBuffer(), indexBuffer])
      }
      var hash = Hash.sha512hmac(data, this._buffers.chainCode)
      var leftPart = BN.fromBuffer(hash.slice(0, 32), {
        size: 32
      })
      var chainCode = hash.slice(32, 64)
    
      var privateKey = leftPart.add(this.privateKey.toBigNumber()).umod(Point.getN()).toBuffer({
        size: 32
      })
    
      if (!PrivateKey.isValid(privateKey)) {
        // Index at this point is already hardened, we can pass null as the hardened arg
        return this._deriveWithNumber(index + 1, null, nonCompliant)
      }
    
      var derived = new HDPrivateKey({
        network: this.network,
        depth: this.depth + 1,
        parentFingerPrint: this.fingerPrint,
        childIndex: index,
        chainCode: chainCode,
        privateKey: privateKey
      })
    
      return derived
    }
    
    HDPrivateKey.prototype._deriveFromString = function (path, nonCompliant) {
      if (!HDPrivateKey.isValidPath(path)) {
        throw new hdErrors.InvalidPath(path)
      }
    
      var indexes = HDPrivateKey._getDerivationIndexes(path)
      var derived = indexes.reduce(function (prev, index) {
        return prev._deriveWithNumber(index, null, nonCompliant)
      }, this)
    
      return derived
    }
    
    /**
     * Verifies that a given serialized private key in base58 with checksum format
     * is valid.
     *
     * @param {string|Buffer} data - the serialized private key
     * @param {string|Network=} network - optional, if present, checks that the
     *     network provided matches the network serialized.
     * @return {boolean}
     */
    HDPrivateKey.isValidSerialized = function (data, network) {
      return !HDPrivateKey.getSerializedError(data, network)
    }
    
    /**
     * Checks what's the error that causes the validation of a serialized private key
     * in base58 with checksum to fail.
     *
     * @param {string|Buffer} data - the serialized private key
     * @param {string|Network=} network - optional, if present, checks that the
     *     network provided matches the network serialized.
     * @return {errors.InvalidArgument|null}
     */
    HDPrivateKey.getSerializedError = function (data, network) {
      if (!(_.isString(data) || Buffer.isBuffer(data))) {
        return new hdErrors.UnrecognizedArgument('Expected string or buffer')
      }
      if (!Base58.validCharacters(data)) {
        return new errors.InvalidB58Char('(unknown)', data)
      }
      try {
        data = Base58Check.decode(data)
      } catch (e) {
        return new errors.InvalidB58Checksum(data)
      }
      if (data.length !== HDPrivateKey.DataLength) {
        return new hdErrors.InvalidLength(data)
      }
      if (!_.isUndefined(network)) {
        var error = HDPrivateKey._validateNetwork(data, network)
        if (error) {
          return error
        }
      }
      return null
    }
    
    HDPrivateKey._validateNetwork = function (data, networkArg) {
      var network = Network.get(networkArg)
      if (!network) {
        return new errors.InvalidNetworkArgument(networkArg)
      }
      var version = data.slice(0, 4)
      if (version.readUInt32BE(0) !== network.xprivkey) {
        return new errors.InvalidNetwork(version)
      }
      return null
    }
    
    HDPrivateKey.fromString = function (arg) {
      $.checkArgument(_.isString(arg), 'No valid string was provided')
      return new HDPrivateKey(arg)
    }
    
    HDPrivateKey.fromObject = function (arg) {
      $.checkArgument(_.isObject(arg), 'No valid argument was provided')
      return new HDPrivateKey(arg)
    }
    
    HDPrivateKey.prototype._buildFromJSON = function (arg) {
      return this._buildFromObject(JSON.parse(arg))
    }
    
    HDPrivateKey.prototype._buildFromObject = function (arg) {
      // TODO: Type validation
      var buffers = {
        version: arg.network ? JSUtil.integerAsBuffer(Network.get(arg.network).xprivkey) : arg.version,
        depth: _.isNumber(arg.depth) ? Buffer.from([arg.depth & 0xff]) : arg.depth,
        parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? JSUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
        childIndex: _.isNumber(arg.childIndex) ? JSUtil.integerAsBuffer(arg.childIndex) : arg.childIndex,
        chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode,
        privateKey: (_.isString(arg.privateKey) && JSUtil.isHexa(arg.privateKey)) ? Buffer.from(arg.privateKey, 'hex') : arg.privateKey,
        checksum: arg.checksum ? (arg.checksum.length ? arg.checksum : JSUtil.integerAsBuffer(arg.checksum)) : undefined
      }
      return this._buildFromBuffers(buffers)
    }
    
    HDPrivateKey.prototype._buildFromSerialized = function (arg) {
      var decoded = Base58Check.decode(arg)
      var buffers = {
        version: decoded.slice(HDPrivateKey.VersionStart, HDPrivateKey.VersionEnd),
        depth: decoded.slice(HDPrivateKey.DepthStart, HDPrivateKey.DepthEnd),
        parentFingerPrint: decoded.slice(HDPrivateKey.ParentFingerPrintStart,
          HDPrivateKey.ParentFingerPrintEnd),
        childIndex: decoded.slice(HDPrivateKey.ChildIndexStart, HDPrivateKey.ChildIndexEnd),
        chainCode: decoded.slice(HDPrivateKey.ChainCodeStart, HDPrivateKey.ChainCodeEnd),
        privateKey: decoded.slice(HDPrivateKey.PrivateKeyStart, HDPrivateKey.PrivateKeyEnd),
        checksum: decoded.slice(HDPrivateKey.ChecksumStart, HDPrivateKey.ChecksumEnd),
        xprivkey: arg
      }
      return this._buildFromBuffers(buffers)
    }
    
    HDPrivateKey.prototype._generateRandomly = function (network) {
      return HDPrivateKey.fromSeed(Random.getRandomBuffer(64), network)
    }
    
    /**
     * Generate a private key from a seed, as described in BIP32
     *
     * @param {string|Buffer} hexa
     * @param {*} network
     * @return HDPrivateKey
     */
    HDPrivateKey.fromSeed = function (hexa, network) {
      if (JSUtil.isHexaString(hexa)) {
        hexa = Buffer.from(hexa, 'hex')
      }
      if (!Buffer.isBuffer(hexa)) {
        throw new hdErrors.InvalidEntropyArgument(hexa)
      }
      if (hexa.length < MINIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
        throw new hdErrors.InvalidEntropyArgument.NotEnoughEntropy(hexa)
      }
      if (hexa.length > MAXIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
        throw new hdErrors.InvalidEntropyArgument.TooMuchEntropy(hexa)
      }
      var hash = Hash.sha512hmac(hexa, buffer.Buffer.from('Bitcoin seed'))
    
      return new HDPrivateKey({
        network: Network.get(network) || Network.defaultNetwork,
        depth: 0,
        parentFingerPrint: 0,
        childIndex: 0,
        privateKey: hash.slice(0, 32),
        chainCode: hash.slice(32, 64)
      })
    }
    
    HDPrivateKey.prototype._calcHDPublicKey = function () {
      if (!this._hdPublicKey) {
        var HDPublicKey = require('./hdpublickey')
        this._hdPublicKey = new HDPublicKey(this)
      }
    }
    
    /**
     * Receives a object with buffers in all the properties and populates the
     * internal structure
     *
     * @param {Object} arg
     * @param {buffer.Buffer} arg.version
     * @param {buffer.Buffer} arg.depth
     * @param {buffer.Buffer} arg.parentFingerPrint
     * @param {buffer.Buffer} arg.childIndex
     * @param {buffer.Buffer} arg.chainCode
     * @param {buffer.Buffer} arg.privateKey
     * @param {buffer.Buffer} arg.checksum
     * @param {string=} arg.xprivkey - if set, don't recalculate the base58
     *      representation
     * @return {HDPrivateKey} this
     */
    HDPrivateKey.prototype._buildFromBuffers = function (arg) {
      HDPrivateKey._validateBufferArguments(arg)
    
      JSUtil.defineImmutable(this, {
        _buffers: arg
      })
    
      var sequence = [
        arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
        Buffer.alloc(1), arg.privateKey
      ]
      var concat = buffer.Buffer.concat(sequence)
      if (!arg.checksum || !arg.checksum.length) {
        arg.checksum = Base58Check.checksum(concat)
      } else {
        if (arg.checksum.toString() !== Base58Check.checksum(concat).toString()) {
          throw new errors.InvalidB58Checksum(concat)
        }
      }
    
      var network = Network.get(arg.version.readUInt32BE(0))
      var xprivkey
      xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence))
      arg.xprivkey = Buffer.from(xprivkey)
    
      var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network)
      var publicKey = privateKey.toPublicKey()
      var size = HDPrivateKey.ParentFingerPrintSize
      var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size)
    
      JSUtil.defineImmutable(this, {
        xprivkey: xprivkey,
        network: network,
        depth: arg.depth[0],
        privateKey: privateKey,
        publicKey: publicKey,
        fingerPrint: fingerPrint
      })
    
      this._hdPublicKey = null
    
      Object.defineProperty(this, 'hdPublicKey', {
        configurable: false,
        enumerable: true,
        get: function () {
          this._calcHDPublicKey()
          return this._hdPublicKey
        }
      })
      Object.defineProperty(this, 'xpubkey', {
        configurable: false,
        enumerable: true,
        get: function () {
          this._calcHDPublicKey()
          return this._hdPublicKey.xpubkey
        }
      })
      return this
    }
    
    HDPrivateKey._validateBufferArguments = function (arg) {
      var checkBuffer = function (name, size) {
        var buff = arg[name]
        assert(Buffer.isBuffer(buff), name + ' argument is not a buffer')
        assert(
          buff.length === size,
          name + ' has not the expected size: found ' + buff.length + ', expected ' + size
        )
      }
      checkBuffer('version', HDPrivateKey.VersionSize)
      checkBuffer('depth', HDPrivateKey.DepthSize)
      checkBuffer('parentFingerPrint', HDPrivateKey.ParentFingerPrintSize)
      checkBuffer('childIndex', HDPrivateKey.ChildIndexSize)
      checkBuffer('chainCode', HDPrivateKey.ChainCodeSize)
      checkBuffer('privateKey', HDPrivateKey.PrivateKeySize)
      if (arg.checksum && arg.checksum.length) {
        checkBuffer('checksum', HDPrivateKey.CheckSumSize)
      }
    }
    
    /**
     * Returns the string representation of this private key (a string starting
     * with "xprv..."
     *
     * @return string
     */
    HDPrivateKey.prototype.toString = function () {
      return this.xprivkey
    }
    
    /**
     * Returns the console representation of this extended private key.
     * @return string
     */
    HDPrivateKey.prototype.inspect = function () {
      return '<HDPrivateKey: ' + this.xprivkey + '>'
    }
    
    /**
     * Returns a plain object with a representation of this private key.
     *
     * Fields include:<ul>
     * <li> network: either 'livenet' or 'testnet'
     * <li> depth: a number ranging from 0 to 255
     * <li> fingerPrint: a number ranging from 0 to 2^32-1, taken from the hash of the
     * <li>     associated public key
     * <li> parentFingerPrint: a number ranging from 0 to 2^32-1, taken from the hash
     * <li>     of this parent's associated public key or zero.
     * <li> childIndex: the index from which this child was derived (or zero)
     * <li> chainCode: an hexa string representing a number used in the derivation
     * <li> privateKey: the private key associated, in hexa representation
     * <li> xprivkey: the representation of this extended private key in checksum
     * <li>     base58 format
     * <li> checksum: the base58 checksum of xprivkey
     * </ul>
     *  @return {Object}
     */
    HDPrivateKey.prototype.toObject = HDPrivateKey.prototype.toJSON = function toObject () {
      return {
        network: Network.get(this._buffers.version.readUInt32BE(0), 'xprivkey').name,
        depth: this._buffers.depth[0],
        fingerPrint: this.fingerPrint.readUInt32BE(0),
        parentFingerPrint: this._buffers.parentFingerPrint.readUInt32BE(0),
        childIndex: this._buffers.childIndex.readUInt32BE(0),
        chainCode: this._buffers.chainCode.toString('hex'),
        privateKey: this.privateKey.toBuffer().toString('hex'),
        checksum: this._buffers.checksum.readUInt32BE(0),
        xprivkey: this.xprivkey
      }
    }
    
    /**
     * Build a HDPrivateKey from a buffer
     *
     * @param {Buffer} arg
     * @return {HDPrivateKey}
     */
    HDPrivateKey.fromBuffer = function (buf) {
      return new HDPrivateKey(buf.toString())
    }
    
    /**
     * Build a HDPrivateKey from a hex string
     *
     * @param {string} hex
     * @return {HDPrivateKey}
     */
    HDPrivateKey.fromHex = function (hex) {
      return HDPrivateKey.fromBuffer(Buffer.from(hex, 'hex'))
    }
    
    /**
     * Returns a buffer representation of the HDPrivateKey
     *
     * @return {string}
     */
    HDPrivateKey.prototype.toBuffer = function () {
      return Buffer.from(this.toString())
    }
    
    /**
     * Returns a hex string representation of the HDPrivateKey
     *
     * @return {string}
     */
    HDPrivateKey.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    HDPrivateKey.DefaultDepth = 0
    HDPrivateKey.DefaultFingerprint = 0
    HDPrivateKey.DefaultChildIndex = 0
    HDPrivateKey.Hardened = 0x80000000
    HDPrivateKey.MaxIndex = 2 * HDPrivateKey.Hardened
    
    HDPrivateKey.RootElementAlias = ['m', 'M', 'm\'', 'M\'']
    
    HDPrivateKey.VersionSize = 4
    HDPrivateKey.DepthSize = 1
    HDPrivateKey.ParentFingerPrintSize = 4
    HDPrivateKey.ChildIndexSize = 4
    HDPrivateKey.ChainCodeSize = 32
    HDPrivateKey.PrivateKeySize = 32
    HDPrivateKey.CheckSumSize = 4
    
    HDPrivateKey.DataLength = 78
    HDPrivateKey.SerializedByteSize = 82
    
    HDPrivateKey.VersionStart = 0
    HDPrivateKey.VersionEnd = HDPrivateKey.VersionStart + HDPrivateKey.VersionSize
    HDPrivateKey.DepthStart = HDPrivateKey.VersionEnd
    HDPrivateKey.DepthEnd = HDPrivateKey.DepthStart + HDPrivateKey.DepthSize
    HDPrivateKey.ParentFingerPrintStart = HDPrivateKey.DepthEnd
    HDPrivateKey.ParentFingerPrintEnd = HDPrivateKey.ParentFingerPrintStart + HDPrivateKey.ParentFingerPrintSize
    HDPrivateKey.ChildIndexStart = HDPrivateKey.ParentFingerPrintEnd
    HDPrivateKey.ChildIndexEnd = HDPrivateKey.ChildIndexStart + HDPrivateKey.ChildIndexSize
    HDPrivateKey.ChainCodeStart = HDPrivateKey.ChildIndexEnd
    HDPrivateKey.ChainCodeEnd = HDPrivateKey.ChainCodeStart + HDPrivateKey.ChainCodeSize
    HDPrivateKey.PrivateKeyStart = HDPrivateKey.ChainCodeEnd + 1
    HDPrivateKey.PrivateKeyEnd = HDPrivateKey.PrivateKeyStart + HDPrivateKey.PrivateKeySize
    HDPrivateKey.ChecksumStart = HDPrivateKey.PrivateKeyEnd
    HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.CheckSumSize
    
    assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize)
    
    module.exports = HDPrivateKey
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./crypto/bn":205,"./crypto/hash":208,"./crypto/point":210,"./crypto/random":211,"./encoding/base58":217,"./encoding/base58check":218,"./errors":227,"./hdpublickey":230,"./networks":244,"./privatekey":246,"./util/_":270,"./util/js":271,"./util/preconditions":272,"assert":24,"buffer":84}],230:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('./util/_')
    var $ = require('./util/preconditions')
    
    var BN = require('./crypto/bn')
    var Base58 = require('./encoding/base58')
    var Base58Check = require('./encoding/base58check')
    var Hash = require('./crypto/hash')
    var HDPrivateKey = require('./hdprivatekey')
    var Network = require('./networks')
    var Point = require('./crypto/point')
    var PublicKey = require('./publickey')
    
    var bsvErrors = require('./errors')
    var errors = bsvErrors
    var hdErrors = bsvErrors.HDPublicKey
    var assert = require('assert')
    
    var JSUtil = require('./util/js')
    
    /**
     * The representation of an hierarchically derived public key.
     *
     * See https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
     *
     * @constructor
     * @param {Object|string|Buffer} arg
     */
    function HDPublicKey (arg) {
      if (arg instanceof HDPublicKey) {
        return arg
      }
      if (!(this instanceof HDPublicKey)) {
        return new HDPublicKey(arg)
      }
      if (arg) {
        if (_.isString(arg) || Buffer.isBuffer(arg)) {
          var error = HDPublicKey.getSerializedError(arg)
          if (!error) {
            return this._buildFromSerialized(arg)
          } else if (Buffer.isBuffer(arg) && !HDPublicKey.getSerializedError(arg.toString())) {
            return this._buildFromSerialized(arg.toString())
          } else {
            if (error instanceof hdErrors.ArgumentIsPrivateExtended) {
              return new HDPrivateKey(arg).hdPublicKey
            }
            throw error
          }
        } else {
          if (_.isObject(arg)) {
            if (arg instanceof HDPrivateKey) {
              return this._buildFromPrivate(arg)
            } else {
              return this._buildFromObject(arg)
            }
          } else {
            throw new hdErrors.UnrecognizedArgument(arg)
          }
        }
      } else {
        throw new hdErrors.MustSupplyArgument()
      }
    }
    
    HDPublicKey.fromHDPrivateKey = function (hdPrivateKey) {
      return new HDPublicKey(hdPrivateKey)
    }
    
    /**
     * Verifies that a given path is valid.
     *
     * @param {string|number} arg
     * @return {boolean}
     */
    HDPublicKey.isValidPath = function (arg) {
      if (_.isString(arg)) {
        var indexes = HDPrivateKey._getDerivationIndexes(arg)
        return indexes !== null && _.every(indexes, HDPublicKey.isValidPath)
      }
    
      if (_.isNumber(arg)) {
        return arg >= 0 && arg < HDPublicKey.Hardened
      }
    
      return false
    }
    
    /**
     * WARNING: This method is deprecated. Use deriveChild instead.
     *
     *
     * Get a derivated child based on a string or number.
     *
     * If the first argument is a string, it's parsed as the full path of
     * derivation. Valid values for this argument include "m" (which returns the
     * same public key), "m/0/1/40/2/1000".
     *
     * Note that hardened keys can't be derived from a public extended key.
     *
     * If the first argument is a number, the child with that index will be
     * derived. See the example usage for clarification.
     *
     * @example
     * ```javascript
     * var parent = new HDPublicKey('xpub...');
     * var child_0_1_2 = parent.derive(0).derive(1).derive(2);
     * var copy_of_child_0_1_2 = parent.derive("m/0/1/2");
     * assert(child_0_1_2.xprivkey === copy_of_child_0_1_2);
     * ```
     *
     * @param {string|number} arg
     */
    HDPublicKey.prototype.derive = function () {
      throw new Error('derive has been deprecated. use deriveChild or, for the old way, deriveNonCompliantChild.')
    }
    
    /**
     * WARNING: This method will not be officially supported until v1.0.0.
     *
     *
     * Get a derivated child based on a string or number.
     *
     * If the first argument is a string, it's parsed as the full path of
     * derivation. Valid values for this argument include "m" (which returns the
     * same public key), "m/0/1/40/2/1000".
     *
     * Note that hardened keys can't be derived from a public extended key.
     *
     * If the first argument is a number, the child with that index will be
     * derived. See the example usage for clarification.
     *
     * @example
     * ```javascript
     * var parent = new HDPublicKey('xpub...');
     * var child_0_1_2 = parent.deriveChild(0).deriveChild(1).deriveChild(2);
     * var copy_of_child_0_1_2 = parent.deriveChild("m/0/1/2");
     * assert(child_0_1_2.xprivkey === copy_of_child_0_1_2);
     * ```
     *
     * @param {string|number} arg
     */
    HDPublicKey.prototype.deriveChild = function (arg, hardened) {
      if (_.isNumber(arg)) {
        return this._deriveWithNumber(arg, hardened)
      } else if (_.isString(arg)) {
        return this._deriveFromString(arg)
      } else {
        throw new hdErrors.InvalidDerivationArgument(arg)
      }
    }
    
    HDPublicKey.prototype._deriveWithNumber = function (index, hardened) {
      if (index >= HDPublicKey.Hardened || hardened) {
        throw new hdErrors.InvalidIndexCantDeriveHardened()
      }
      if (index < 0) {
        throw new hdErrors.InvalidPath(index)
      }
    
      var indexBuffer = JSUtil.integerAsBuffer(index)
      var data = Buffer.concat([this.publicKey.toBuffer(), indexBuffer])
      var hash = Hash.sha512hmac(data, this._buffers.chainCode)
      var leftPart = BN.fromBuffer(hash.slice(0, 32), { size: 32 })
      var chainCode = hash.slice(32, 64)
    
      var publicKey
      try {
        publicKey = PublicKey.fromPoint(Point.getG().mul(leftPart).add(this.publicKey.point))
      } catch (e) {
        return this._deriveWithNumber(index + 1)
      }
    
      var derived = new HDPublicKey({
        network: this.network,
        depth: this.depth + 1,
        parentFingerPrint: this.fingerPrint,
        childIndex: index,
        chainCode: chainCode,
        publicKey: publicKey
      })
    
      return derived
    }
    
    HDPublicKey.prototype._deriveFromString = function (path) {
      if (_.includes(path, "'")) {
        throw new hdErrors.InvalidIndexCantDeriveHardened()
      } else if (!HDPublicKey.isValidPath(path)) {
        throw new hdErrors.InvalidPath(path)
      }
    
      var indexes = HDPrivateKey._getDerivationIndexes(path)
      var derived = indexes.reduce(function (prev, index) {
        return prev._deriveWithNumber(index)
      }, this)
    
      return derived
    }
    
    /**
     * Verifies that a given serialized public key in base58 with checksum format
     * is valid.
     *
     * @param {string|Buffer} data - the serialized public key
     * @param {string|Network=} network - optional, if present, checks that the
     *     network provided matches the network serialized.
     * @return {boolean}
     */
    HDPublicKey.isValidSerialized = function (data, network) {
      return _.isNull(HDPublicKey.getSerializedError(data, network))
    }
    
    /**
     * Checks what's the error that causes the validation of a serialized public key
     * in base58 with checksum to fail.
     *
     * @param {string|Buffer} data - the serialized public key
     * @param {string|Network=} network - optional, if present, checks that the
     *     network provided matches the network serialized.
     * @return {errors|null}
     */
    HDPublicKey.getSerializedError = function (data, network) {
      if (!(_.isString(data) || Buffer.isBuffer(data))) {
        return new hdErrors.UnrecognizedArgument('expected buffer or string')
      }
      if (!Base58.validCharacters(data)) {
        return new errors.InvalidB58Char('(unknown)', data)
      }
      try {
        data = Base58Check.decode(data)
      } catch (e) {
        return new errors.InvalidB58Checksum(data)
      }
      if (data.length !== HDPublicKey.DataSize) {
        return new hdErrors.InvalidLength(data)
      }
      if (!_.isUndefined(network)) {
        var error = HDPublicKey._validateNetwork(data, network)
        if (error) {
          return error
        }
      }
      var version = data.readUInt32BE(0)
      if (version === Network.livenet.xprivkey || version === Network.testnet.xprivkey) {
        return new hdErrors.ArgumentIsPrivateExtended()
      }
      return null
    }
    
    HDPublicKey._validateNetwork = function (data, networkArg) {
      var network = Network.get(networkArg)
      if (!network) {
        return new errors.InvalidNetworkArgument(networkArg)
      }
      var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd)
      if (version.readUInt32BE(0) !== network.xpubkey) {
        return new errors.InvalidNetwork(version)
      }
      return null
    }
    
    HDPublicKey.prototype._buildFromPrivate = function (arg) {
      var args = _.clone(arg._buffers)
      var point = Point.getG().mul(BN.fromBuffer(args.privateKey))
      args.publicKey = Point.pointToCompressed(point)
      args.version = JSUtil.integerAsBuffer(Network.get(args.version.readUInt32BE(0)).xpubkey)
      args.privateKey = undefined
      args.checksum = undefined
      args.xprivkey = undefined
      return this._buildFromBuffers(args)
    }
    
    HDPublicKey.prototype._buildFromObject = function (arg) {
      // TODO: Type validation
      var buffers = {
        version: arg.network ? JSUtil.integerAsBuffer(Network.get(arg.network).xpubkey) : arg.version,
        depth: _.isNumber(arg.depth) ? Buffer.from([arg.depth & 0xff]) : arg.depth,
        parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? JSUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
        childIndex: _.isNumber(arg.childIndex) ? JSUtil.integerAsBuffer(arg.childIndex) : arg.childIndex,
        chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode,
        publicKey: _.isString(arg.publicKey) ? Buffer.from(arg.publicKey, 'hex')
          : Buffer.isBuffer(arg.publicKey) ? arg.publicKey : arg.publicKey.toBuffer(),
        checksum: _.isNumber(arg.checksum) ? JSUtil.integerAsBuffer(arg.checksum) : arg.checksum
      }
      return this._buildFromBuffers(buffers)
    }
    
    HDPublicKey.prototype._buildFromSerialized = function (arg) {
      var decoded = Base58Check.decode(arg)
      var buffers = {
        version: decoded.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd),
        depth: decoded.slice(HDPublicKey.DepthStart, HDPublicKey.DepthEnd),
        parentFingerPrint: decoded.slice(HDPublicKey.ParentFingerPrintStart,
          HDPublicKey.ParentFingerPrintEnd),
        childIndex: decoded.slice(HDPublicKey.ChildIndexStart, HDPublicKey.ChildIndexEnd),
        chainCode: decoded.slice(HDPublicKey.ChainCodeStart, HDPublicKey.ChainCodeEnd),
        publicKey: decoded.slice(HDPublicKey.PublicKeyStart, HDPublicKey.PublicKeyEnd),
        checksum: decoded.slice(HDPublicKey.ChecksumStart, HDPublicKey.ChecksumEnd),
        xpubkey: arg
      }
      return this._buildFromBuffers(buffers)
    }
    
    /**
     * Receives a object with buffers in all the properties and populates the
     * internal structure
     *
     * @param {Object} arg
     * @param {buffer.Buffer} arg.version
     * @param {buffer.Buffer} arg.depth
     * @param {buffer.Buffer} arg.parentFingerPrint
     * @param {buffer.Buffer} arg.childIndex
     * @param {buffer.Buffer} arg.chainCode
     * @param {buffer.Buffer} arg.publicKey
     * @param {buffer.Buffer} arg.checksum
     * @param {string=} arg.xpubkey - if set, don't recalculate the base58
     *      representation
     * @return {HDPublicKey} this
     */
    HDPublicKey.prototype._buildFromBuffers = function (arg) {
      HDPublicKey._validateBufferArguments(arg)
    
      JSUtil.defineImmutable(this, {
        _buffers: arg
      })
    
      var sequence = [
        arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
        arg.publicKey
      ]
      var concat = Buffer.concat(sequence)
      var checksum = Base58Check.checksum(concat)
      if (!arg.checksum || !arg.checksum.length) {
        arg.checksum = checksum
      } else {
        if (arg.checksum.toString('hex') !== checksum.toString('hex')) {
          throw new errors.InvalidB58Checksum(concat, checksum)
        }
      }
      var network = Network.get(arg.version.readUInt32BE(0))
    
      var xpubkey
      xpubkey = Base58Check.encode(Buffer.concat(sequence))
      arg.xpubkey = Buffer.from(xpubkey)
    
      var publicKey = new PublicKey(arg.publicKey, { network: network })
      var size = HDPublicKey.ParentFingerPrintSize
      var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size)
    
      JSUtil.defineImmutable(this, {
        xpubkey: xpubkey,
        network: network,
        depth: arg.depth[0],
        publicKey: publicKey,
        fingerPrint: fingerPrint
      })
    
      return this
    }
    
    HDPublicKey._validateBufferArguments = function (arg) {
      var checkBuffer = function (name, size) {
        var buff = arg[name]
        assert(Buffer.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff)
        assert(
          buff.length === size,
          name + ' has not the expected size: found ' + buff.length + ', expected ' + size
        )
      }
      checkBuffer('version', HDPublicKey.VersionSize)
      checkBuffer('depth', HDPublicKey.DepthSize)
      checkBuffer('parentFingerPrint', HDPublicKey.ParentFingerPrintSize)
      checkBuffer('childIndex', HDPublicKey.ChildIndexSize)
      checkBuffer('chainCode', HDPublicKey.ChainCodeSize)
      checkBuffer('publicKey', HDPublicKey.PublicKeySize)
      if (arg.checksum && arg.checksum.length) {
        checkBuffer('checksum', HDPublicKey.CheckSumSize)
      }
    }
    
    HDPublicKey.fromString = function (arg) {
      $.checkArgument(_.isString(arg), 'No valid string was provided')
      return new HDPublicKey(arg)
    }
    
    HDPublicKey.fromObject = function (arg) {
      $.checkArgument(_.isObject(arg), 'No valid argument was provided')
      return new HDPublicKey(arg)
    }
    
    /**
     * Returns the base58 checked representation of the public key
     * @return {string} a string starting with "xpub..." in livenet
     */
    HDPublicKey.prototype.toString = function () {
      return this.xpubkey
    }
    
    /**
     * Returns the console representation of this extended public key.
     * @return string
     */
    HDPublicKey.prototype.inspect = function () {
      return '<HDPublicKey: ' + this.xpubkey + '>'
    }
    
    /**
     * Returns a plain JavaScript object with information to reconstruct a key.
     *
     * Fields are: <ul>
     *  <li> network: 'livenet' or 'testnet'
     *  <li> depth: a number from 0 to 255, the depth to the master extended key
     *  <li> fingerPrint: a number of 32 bits taken from the hash of the public key
     *  <li> fingerPrint: a number of 32 bits taken from the hash of this key's
     *  <li>     parent's public key
     *  <li> childIndex: index with which this key was derived
     *  <li> chainCode: string in hexa encoding used for derivation
     *  <li> publicKey: string, hexa encoded, in compressed key format
     *  <li> checksum: this._buffers.checksum.readUInt32BE(0),
     *  <li> xpubkey: the string with the base58 representation of this extended key
     *  <li> checksum: the base58 checksum of xpubkey
     * </ul>
     */
    HDPublicKey.prototype.toObject = HDPublicKey.prototype.toJSON = function toObject () {
      return {
        network: Network.get(this._buffers.version.readUInt32BE(0)).name,
        depth: this._buffers.depth[0],
        fingerPrint: this.fingerPrint.readUInt32BE(0),
        parentFingerPrint: this._buffers.parentFingerPrint.readUInt32BE(0),
        childIndex: this._buffers.childIndex.readUInt32BE(0),
        chainCode: this._buffers.chainCode.toString('hex'),
        publicKey: this.publicKey.toString(),
        checksum: this._buffers.checksum.readUInt32BE(0),
        xpubkey: this.xpubkey
      }
    }
    
    /**
     * Create a HDPublicKey from a buffer argument
     *
     * @param {Buffer} arg
     * @return {HDPublicKey}
     */
    HDPublicKey.fromBuffer = function (arg) {
      return new HDPublicKey(arg)
    }
    
    /**
     * Create a HDPublicKey from a hex string argument
     *
     * @param {Buffer} arg
     * @return {HDPublicKey}
     */
    HDPublicKey.fromHex = function (hex) {
      return HDPublicKey.fromBuffer(Buffer.from(hex, 'hex'))
    }
    
    /**
     * Return a buffer representation of the xpubkey
     *
     * @return {Buffer}
     */
    HDPublicKey.prototype.toBuffer = function () {
      return Buffer.from(this._buffers.xpubkey)
    }
    
    /**
     * Return a hex string representation of the xpubkey
     *
     * @return {Buffer}
     */
    HDPublicKey.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    HDPublicKey.Hardened = 0x80000000
    HDPublicKey.RootElementAlias = ['m', 'M']
    
    HDPublicKey.VersionSize = 4
    HDPublicKey.DepthSize = 1
    HDPublicKey.ParentFingerPrintSize = 4
    HDPublicKey.ChildIndexSize = 4
    HDPublicKey.ChainCodeSize = 32
    HDPublicKey.PublicKeySize = 33
    HDPublicKey.CheckSumSize = 4
    
    HDPublicKey.DataSize = 78
    HDPublicKey.SerializedByteSize = 82
    
    HDPublicKey.VersionStart = 0
    HDPublicKey.VersionEnd = HDPublicKey.VersionStart + HDPublicKey.VersionSize
    HDPublicKey.DepthStart = HDPublicKey.VersionEnd
    HDPublicKey.DepthEnd = HDPublicKey.DepthStart + HDPublicKey.DepthSize
    HDPublicKey.ParentFingerPrintStart = HDPublicKey.DepthEnd
    HDPublicKey.ParentFingerPrintEnd = HDPublicKey.ParentFingerPrintStart + HDPublicKey.ParentFingerPrintSize
    HDPublicKey.ChildIndexStart = HDPublicKey.ParentFingerPrintEnd
    HDPublicKey.ChildIndexEnd = HDPublicKey.ChildIndexStart + HDPublicKey.ChildIndexSize
    HDPublicKey.ChainCodeStart = HDPublicKey.ChildIndexEnd
    HDPublicKey.ChainCodeEnd = HDPublicKey.ChainCodeStart + HDPublicKey.ChainCodeSize
    HDPublicKey.PublicKeyStart = HDPublicKey.ChainCodeEnd
    HDPublicKey.PublicKeyEnd = HDPublicKey.PublicKeyStart + HDPublicKey.PublicKeySize
    HDPublicKey.ChecksumStart = HDPublicKey.PublicKeyEnd
    HDPublicKey.ChecksumEnd = HDPublicKey.ChecksumStart + HDPublicKey.CheckSumSize
    
    assert(HDPublicKey.PublicKeyEnd === HDPublicKey.DataSize)
    assert(HDPublicKey.ChecksumEnd === HDPublicKey.SerializedByteSize)
    
    module.exports = HDPublicKey
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./crypto/bn":205,"./crypto/hash":208,"./crypto/point":210,"./encoding/base58":217,"./encoding/base58check":218,"./errors":227,"./hdprivatekey":229,"./networks":244,"./publickey":247,"./util/_":270,"./util/js":271,"./util/preconditions":272,"assert":24,"buffer":84}],231:[function(require,module,exports){
    var bsv = require('../../')
    bsv.Message = require('./message')
    
    module.exports = bsv.Message
    
    },{"../../":199,"./message":232}],232:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var bsv = require('../../')
    var _ = bsv.deps._
    var PrivateKey = bsv.PrivateKey
    var PublicKey = bsv.PublicKey
    var Address = bsv.Address
    var BufferWriter = bsv.encoding.BufferWriter
    var ECDSA = bsv.crypto.ECDSA
    var Signature = bsv.crypto.Signature
    var sha256sha256 = bsv.crypto.Hash.sha256sha256
    var JSUtil = bsv.util.js
    var $ = bsv.util.preconditions
    
    /**
     * constructs a new message to sign and verify.
     *
     * @param {String} message
     * @returns {Message}
     */
    var Message = function Message (message) {
      if (!(this instanceof Message)) {
        return new Message(message)
      }
    
      $.checkArgument(_.isString(message) || Buffer.isBuffer(message), 'First argument should be a string or Buffer')
    
      if (_.isString(message)) {
        this.messageBuffer = Buffer.from(message)
      }
    
      if (Buffer.isBuffer(message)) {
        this.messageBuffer = message
      }
      return this
    }
    
    Message.sign = function (message, privateKey) {
      return new Message(message).sign(privateKey)
    }
    
    Message.verify = function (message, address, signature) {
      return new Message(message).verify(address, signature)
    }
    
    Message.MAGIC_BYTES = Buffer.from('Bitcoin Signed Message:\n')
    
    Message.prototype.magicHash = function magicHash () {
      var prefix1 = BufferWriter.varintBufNum(Message.MAGIC_BYTES.length)
      var prefix2 = BufferWriter.varintBufNum(this.messageBuffer.length)
      var buf = Buffer.concat([prefix1, Message.MAGIC_BYTES, prefix2, this.messageBuffer])
      var hash = sha256sha256(buf)
      return hash
    }
    
    Message.prototype._sign = function _sign (privateKey) {
      $.checkArgument(privateKey instanceof PrivateKey,
        'First argument should be an instance of PrivateKey')
      var hash = this.magicHash()
      return ECDSA.signWithCalcI(hash, privateKey)
    }
    
    /**
     * Will sign a message with a given bitcoin private key.
     *
     * @param {PrivateKey} privateKey - An instance of PrivateKey
     * @returns {String} A base64 encoded compact signature
     */
    Message.prototype.sign = function sign (privateKey) {
      var signature = this._sign(privateKey)
      return signature.toCompact().toString('base64')
    }
    
    Message.prototype._verify = function _verify (publicKey, signature) {
      $.checkArgument(publicKey instanceof PublicKey, 'First argument should be an instance of PublicKey')
      $.checkArgument(signature instanceof Signature, 'Second argument should be an instance of Signature')
      var hash = this.magicHash()
      var verified = ECDSA.verify(hash, signature, publicKey)
      if (!verified) {
        this.error = 'The signature was invalid'
      }
      return verified
    }
    
    /**
     * Will return a boolean of the signature is valid for a given bitcoin address.
     * If it isn't the specific reason is accessible via the "error" member.
     *
     * @param {Address|String} bitcoinAddress - A bitcoin address
     * @param {String} signatureString - A base64 encoded compact signature
     * @returns {Boolean}
     */
    Message.prototype.verify = function verify (bitcoinAddress, signatureString) {
      $.checkArgument(bitcoinAddress)
      $.checkArgument(signatureString && _.isString(signatureString))
    
      if (_.isString(bitcoinAddress)) {
        bitcoinAddress = Address.fromString(bitcoinAddress)
      }
      var signature = Signature.fromCompact(Buffer.from(signatureString, 'base64'))
    
      // recover the public key
      var ecdsa = new ECDSA()
      ecdsa.hashbuf = this.magicHash()
      ecdsa.sig = signature
      var publicKey = ecdsa.toPublicKey()
    
      var signatureAddress = Address.fromPublicKey(publicKey, bitcoinAddress.network)
    
      // check that the recovered address and specified address match
      if (bitcoinAddress.toString() !== signatureAddress.toString()) {
        this.error = 'The signature did not match the message digest'
        return false
      }
    
      return this._verify(publicKey, signature)
    }
    
    /**
     * Instantiate a message from a message string
     *
     * @param {String} str - A string of the message
     * @returns {Message} A new instance of a Message
     */
    Message.fromString = function (str) {
      return new Message(str)
    }
    
    /**
     * Instantiate a message from JSON
     *
     * @param {String} json - An JSON string or Object with keys: message
     * @returns {Message} A new instance of a Message
     */
    Message.fromJSON = function fromJSON (json) {
      if (JSUtil.isValidJSON(json)) {
        json = JSON.parse(json)
      }
      return Message.fromObject(json)
    }
    
    /**
     * @returns {Object} A plain object with the message information
     */
    Message.prototype.toObject = function toObject () {
      return {
        messageHex: this.messageBuffer.toString('hex')
      }
    }
    
    Message.fromObject = function (obj) {
      let messageBuffer = Buffer.from(obj.messageHex, 'hex')
      return new Message(messageBuffer)
    }
    
    /**
     * @returns {String} A JSON representation of the message information
     */
    Message.prototype.toJSON = function toJSON () {
      return JSON.stringify(this.toObject())
    }
    
    /**
     * Will return a the string representation of the message
     *
     * @returns {String} Message
     */
    Message.prototype.toString = function () {
      return this.messageBuffer.toString()
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {String} Message
     */
    Message.prototype.inspect = function () {
      return '<Message: ' + this.toString() + '>'
    }
    
    module.exports = Message
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../":199,"buffer":84}],233:[function(require,module,exports){
    'use strict'
    
    var spec = {
      name: 'Mnemonic',
      message: 'Internal Error on bsv-mnemonic module {0}',
      errors: [{
        name: 'InvalidEntropy',
        message: 'Entropy length must be an even multiple of 11 bits: {0}'
      }, {
        name: 'UnknownWordlist',
        message: 'Could not detect the used word list: {0}'
      }, {
        name: 'InvalidMnemonic',
        message: 'Mnemonic string is invalid: {0}'
      }]
    }
    
    module.exports = require('../../').errors.extend(spec)
    
    },{"../../":199}],234:[function(require,module,exports){
    var bsv = require('../../')
    bsv.Mnemonic = require('./mnemonic')
    
    module.exports = bsv.Mnemonic
    
    },{"../../":199,"./mnemonic":235}],235:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var bsv = require('../../')
    var BN = bsv.crypto.BN
    var unorm = require('unorm')
    var _ = bsv.deps._
    
    var pbkdf2 = require('./pbkdf2')
    var errors = require('./errors')
    
    var Hash = bsv.crypto.Hash
    var Random = bsv.crypto.Random
    
    var $ = bsv.util.preconditions
    
    /**
     * This is an immutable class that represents a BIP39 Mnemonic code.
     * See BIP39 specification for more info: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
     * A Mnemonic code is a a group of easy to remember words used for the generation
     * of deterministic wallets. A Mnemonic can be used to generate a seed using
     * an optional passphrase, for later generate a HDPrivateKey.
     *
     * @example
     * // generate a random mnemonic
     * var mnemonic = new Mnemonic();
     * var phrase = mnemonic.phrase;
     *
     * // use a different language
     * var mnemonic = new Mnemonic(Mnemonic.Words.SPANISH);
     * var xprivkey = mnemonic.toHDPrivateKey();
     *
     * @param {*=} data - a seed, phrase, or entropy to initialize (can be skipped)
     * @param {Array=} wordlist - the wordlist to generate mnemonics from
     * @returns {Mnemonic} A new instance of Mnemonic
     * @constructor
     */
    var Mnemonic = function (data, wordlist) {
      if (!(this instanceof Mnemonic)) {
        return new Mnemonic(data, wordlist)
      }
    
      if (_.isArray(data)) {
        wordlist = data
        data = null
      }
    
      // handle data overloading
      var ent, phrase, seed
      if (Buffer.isBuffer(data)) {
        seed = data
      } else if (_.isString(data)) {
        phrase = unorm.nfkd(data)
      } else if (_.isNumber(data)) {
        ent = data
      } else if (data) {
        throw new bsv.errors.InvalidArgument('data', 'Must be a Buffer, a string or an integer')
      }
      ent = ent || 128
    
      // check and detect wordlist
      wordlist = wordlist || Mnemonic._getDictionary(phrase)
      if (phrase && !wordlist) {
        throw new errors.UnknownWordlist(phrase)
      }
      wordlist = wordlist || Mnemonic.Words.ENGLISH
    
      if (seed) {
        phrase = Mnemonic._entropy2mnemonic(seed, wordlist)
      }
    
      // validate phrase and ent
      if (phrase && !Mnemonic.isValid(phrase, wordlist)) {
        throw new errors.InvalidMnemonic(phrase)
      }
      if (ent % 32 !== 0 || ent < 128) {
        throw new bsv.errors.InvalidArgument('ENT', 'Values must be ENT > 128 and ENT % 32 == 0')
      }
    
      phrase = phrase || Mnemonic._mnemonic(ent, wordlist)
    
      Object.defineProperty(this, 'wordlist', {
        configurable: false,
        value: wordlist
      })
    
      Object.defineProperty(this, 'phrase', {
        configurable: false,
        value: phrase
      })
    }
    
    Mnemonic.fromRandom = function (wordlist = Mnemonic.Words.ENGLISH) {
      return new Mnemonic(wordlist)
    }
    
    Mnemonic.fromString = function (mnemonic, wordlist = Mnemonic.Words.ENGLISH) {
      return new Mnemonic(mnemonic, wordlist)
    }
    
    Mnemonic.Words = require('./words')
    
    /**
     * Will return a boolean if the mnemonic is valid
     *
     * @example
     *
     * var valid = Mnemonic.isValid('lab rescue lunch elbow recall phrase perfect donkey biology guess moment husband');
     * // true
     *
     * @param {String} mnemonic - The mnemonic string
     * @param {String} [wordlist] - The wordlist used
     * @returns {boolean}
     */
    Mnemonic.isValid = function (mnemonic, wordlist) {
      mnemonic = unorm.nfkd(mnemonic)
      wordlist = wordlist || Mnemonic._getDictionary(mnemonic)
    
      if (!wordlist) {
        return false
      }
    
      var words = mnemonic.split(' ')
      var bin = ''
      for (var i = 0; i < words.length; i++) {
        var ind = wordlist.indexOf(words[i])
        if (ind < 0) return false
        bin = bin + ('00000000000' + ind.toString(2)).slice(-11)
      }
    
      var cs = bin.length / 33
      var hashBits = bin.slice(-cs)
      var nonhashBits = bin.slice(0, bin.length - cs)
      var buf = Buffer.alloc(nonhashBits.length / 8)
      for (i = 0; i < nonhashBits.length / 8; i++) {
        buf.writeUInt8(parseInt(bin.slice(i * 8, (i + 1) * 8), 2), i)
      }
      var expectedHashBits = Mnemonic._entropyChecksum(buf)
      return expectedHashBits === hashBits
    }
    
    /**
     * Internal function to check if a mnemonic belongs to a wordlist.
     *
     * @param {String} mnemonic - The mnemonic string
     * @param {String} wordlist - The wordlist
     * @returns {boolean}
     */
    Mnemonic._belongsToWordlist = function (mnemonic, wordlist) {
      var words = unorm.nfkd(mnemonic).split(' ')
      for (var i = 0; i < words.length; i++) {
        var ind = wordlist.indexOf(words[i])
        if (ind < 0) return false
      }
      return true
    }
    
    /**
     * Internal function to detect the wordlist used to generate the mnemonic.
     *
     * @param {String} mnemonic - The mnemonic string
     * @returns {Array} the wordlist or null
     */
    Mnemonic._getDictionary = function (mnemonic) {
      if (!mnemonic) return null
    
      var dicts = Object.keys(Mnemonic.Words)
      for (var i = 0; i < dicts.length; i++) {
        var key = dicts[i]
        if (Mnemonic._belongsToWordlist(mnemonic, Mnemonic.Words[key])) {
          return Mnemonic.Words[key]
        }
      }
      return null
    }
    
    /**
     * Will generate a seed based on the mnemonic and optional passphrase. Note that
     * this seed is absolutely NOT the seed that is output by .toSeed(). These are
     * two different seeds. The seed you want to put in here, if any, is just some
     * random byte string. Normally you should rely on the .fromRandom() method.
     *
     * @param {String} [passphrase]
     * @returns {Buffer}
     */
    Mnemonic.prototype.toSeed = function (passphrase) {
      passphrase = passphrase || ''
      return pbkdf2(unorm.nfkd(this.phrase), unorm.nfkd('mnemonic' + passphrase), 2048, 64)
    }
    
    /**
     * Will generate a Mnemonic object based on a seed.
     *
     * @param {Buffer} [seed]
     * @param {string} [wordlist]
     * @returns {Mnemonic}
     */
    Mnemonic.fromSeed = function (seed, wordlist) {
      $.checkArgument(Buffer.isBuffer(seed), 'seed must be a Buffer.')
      $.checkArgument(_.isArray(wordlist) || _.isString(wordlist), 'wordlist must be a string or an array.')
      return new Mnemonic(seed, wordlist)
    }
    
    /**
     *
     * Generates a HD Private Key from a Mnemonic.
     * Optionally receive a passphrase and bitcoin network.
     *
     * @param {String=} [passphrase]
     * @param {Network|String|number=} [network] - The network: 'livenet' or 'testnet'
     * @returns {HDPrivateKey}
     */
    Mnemonic.prototype.toHDPrivateKey = function (passphrase, network) {
      var seed = this.toSeed(passphrase)
      return bsv.HDPrivateKey.fromSeed(seed, network)
    }
    
    /**
     * Will return a the string representation of the mnemonic
     *
     * @returns {String} Mnemonic
     */
    Mnemonic.prototype.toString = function () {
      return this.phrase
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {String} Mnemonic
     */
    Mnemonic.prototype.inspect = function () {
      return '<Mnemonic: ' + this.toString() + ' >'
    }
    
    /**
     * Internal function to generate a random mnemonic
     *
     * @param {Number} ENT - Entropy size, defaults to 128
     * @param {Array} wordlist - Array of words to generate the mnemonic
     * @returns {String} Mnemonic string
     */
    Mnemonic._mnemonic = function (ENT, wordlist) {
      var buf = Random.getRandomBuffer(ENT / 8)
      return Mnemonic._entropy2mnemonic(buf, wordlist)
    }
    
    /**
     * Internal function to generate mnemonic based on entropy
     *
     * @param {Number} entropy - Entropy buffer
     * @param {Array} wordlist - Array of words to generate the mnemonic
     * @returns {String} Mnemonic string
     */
    Mnemonic._entropy2mnemonic = function (entropy, wordlist) {
      var bin = ''
      for (var i = 0; i < entropy.length; i++) {
        bin = bin + ('00000000' + entropy[i].toString(2)).slice(-8)
      }
    
      bin = bin + Mnemonic._entropyChecksum(entropy)
      if (bin.length % 11 !== 0) {
        throw new errors.InvalidEntropy(bin)
      }
      var mnemonic = []
      for (i = 0; i < bin.length / 11; i++) {
        var wi = parseInt(bin.slice(i * 11, (i + 1) * 11), 2)
        mnemonic.push(wordlist[wi])
      }
      var ret
      if (wordlist === Mnemonic.Words.JAPANESE) {
        ret = mnemonic.join('\u3000')
      } else {
        ret = mnemonic.join(' ')
      }
      return ret
    }
    
    /**
     * Internal function to create checksum of entropy
     *
     * @param entropy
     * @returns {string} Checksum of entropy length / 32
     * @private
     */
    Mnemonic._entropyChecksum = function (entropy) {
      var hash = Hash.sha256(entropy)
      var bits = entropy.length * 8
      var cs = bits / 32
    
      var hashbits = new BN(hash.toString('hex'), 16).toString(2)
    
      // zero pad the hash bits
      while (hashbits.length % 256 !== 0) {
        hashbits = '0' + hashbits
      }
    
      var checksum = hashbits.slice(0, cs)
    
      return checksum
    }
    
    Mnemonic.bsv = bsv
    
    module.exports = Mnemonic
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../":199,"./errors":233,"./pbkdf2":236,"./words":240,"buffer":84,"unorm":367}],236:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var crypto = require('crypto')
    
    /**
     * PDKBF2
     * Credit to: https://github.com/stayradiated/pbkdf2-sha512
     * Copyright (c) 2014, JP Richardson Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
     */
    function pbkdf2 (key, salt, iterations, dkLen) {
      var hLen = 64 // SHA512 Mac length
      if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
        throw Error('Requested key length too long')
      }
    
      if (typeof key !== 'string' && !Buffer.isBuffer(key)) {
        throw new TypeError('key must a string or Buffer')
      }
    
      if (typeof salt !== 'string' && !Buffer.isBuffer(salt)) {
        throw new TypeError('salt must a string or Buffer')
      }
    
      if (typeof key === 'string') {
        key = Buffer.from(key)
      }
    
      if (typeof salt === 'string') {
        salt = Buffer.from(salt)
      }
    
      var DK = Buffer.alloc(dkLen)
    
      var U = Buffer.alloc(hLen)
      var T = Buffer.alloc(hLen)
      var block1 = Buffer.alloc(salt.length + 4)
    
      var l = Math.ceil(dkLen / hLen)
      var r = dkLen - (l - 1) * hLen
    
      salt.copy(block1, 0, 0, salt.length)
      for (var i = 1; i <= l; i++) {
        block1[salt.length + 0] = (i >> 24 & 0xff)
        block1[salt.length + 1] = (i >> 16 & 0xff)
        block1[salt.length + 2] = (i >> 8 & 0xff)
        block1[salt.length + 3] = (i >> 0 & 0xff)
    
        U = crypto.createHmac('sha512', key).update(block1).digest()
    
        U.copy(T, 0, 0, hLen)
    
        for (var j = 1; j < iterations; j++) {
          U = crypto.createHmac('sha512', key).update(U).digest()
    
          for (var k = 0; k < hLen; k++) {
            T[k] ^= U[k]
          }
        }
    
        var destPos = (i - 1) * hLen
        var len = (i === l ? r : hLen)
        T.copy(DK, destPos, 0, len)
      }
    
      return DK
    }
    
    module.exports = pbkdf2
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84,"crypto":107}],237:[function(require,module,exports){
    'use strict'
    
    var chinese = ['的', '一', '是', '在', '不', '了', '有', '和', '人', '这', '中', '大', '为', '上', '个', '国', '我', '以', '要', '他', '时', '来', '用', '们', '生', '到', '作', '地', '于', '出', '就', '分', '对', '成', '会', '可', '主', '发', '年', '动', '同', '工', '也', '能', '下', '过', '子', '说', '产', '种', '面', '而', '方', '后', '多', '定', '行', '学', '法', '所', '民', '得', '经', '十', '三', '之', '进', '着', '等', '部', '度', '家', '电', '力', '里', '如', '水', '化', '高', '自', '二', '理', '起', '小', '物', '现', '实', '加', '量', '都', '两', '体', '制', '机', '当', '使', '点', '从', '业', '本', '去', '把', '性', '好', '应', '开', '它', '合', '还', '因', '由', '其', '些', '然', '前', '外', '天', '政', '四', '日', '那', '社', '义', '事', '平', '形', '相', '全', '表', '间', '样', '与', '关', '各', '重', '新', '线', '内', '数', '正', '心', '反', '你', '明', '看', '原', '又', '么', '利', '比', '或', '但', '质', '气', '第', '向', '道', '命', '此', '变', '条', '只', '没', '结', '解', '问', '意', '建', '月', '公', '无', '系', '军', '很', '情', '者', '最', '立', '代', '想', '已', '通', '并', '提', '直', '题', '党', '程', '展', '五', '果', '料', '象', '员', '革', '位', '入', '常', '文', '总', '次', '品', '式', '活', '设', '及', '管', '特', '件', '长', '求', '老', '头', '基', '资', '边', '流', '路', '级', '少', '图', '山', '统', '接', '知', '较', '将', '组', '见', '计', '别', '她', '手', '角', '期', '根', '论', '运', '农', '指', '几', '九', '区', '强', '放', '决', '西', '被', '干', '做', '必', '战', '先', '回', '则', '任', '取', '据', '处', '队', '南', '给', '色', '光', '门', '即', '保', '治', '北', '造', '百', '规', '热', '领', '七', '海', '口', '东', '导', '器', '压', '志', '世', '金', '增', '争', '济', '阶', '油', '思', '术', '极', '交', '受', '联', '什', '认', '六', '共', '权', '收', '证', '改', '清', '美', '再', '采', '转', '更', '单', '风', '切', '打', '白', '教', '速', '花', '带', '安', '场', '身', '车', '例', '真', '务', '具', '万', '每', '目', '至', '达', '走', '积', '示', '议', '声', '报', '斗', '完', '类', '八', '离', '华', '名', '确', '才', '科', '张', '信', '马', '节', '话', '米', '整', '空', '元', '况', '今', '集', '温', '传', '土', '许', '步', '群', '广', '石', '记', '需', '段', '研', '界', '拉', '林', '律', '叫', '且', '究', '观', '越', '织', '装', '影', '算', '低', '持', '音', '众', '书', '布', '复', '容', '儿', '须', '际', '商', '非', '验', '连', '断', '深', '难', '近', '矿', '千', '周', '委', '素', '技', '备', '半', '办', '青', '省', '列', '习', '响', '约', '支', '般', '史', '感', '劳', '便', '团', '往', '酸', '历', '市', '克', '何', '除', '消', '构', '府', '称', '太', '准', '精', '值', '号', '率', '族', '维', '划', '选', '标', '写', '存', '候', '毛', '亲', '快', '效', '斯', '院', '查', '江', '型', '眼', '王', '按', '格', '养', '易', '置', '派', '层', '片', '始', '却', '专', '状', '育', '厂', '京', '识', '适', '属', '圆', '包', '火', '住', '调', '满', '县', '局', '照', '参', '红', '细', '引', '听', '该', '铁', '价', '严', '首', '底', '液', '官', '德', '随', '病', '苏', '失', '尔', '死', '讲', '配', '女', '黄', '推', '显', '谈', '罪', '神', '艺', '呢', '席', '含', '企', '望', '密', '批', '营', '项', '防', '举', '球', '英', '氧', '势', '告', '李', '台', '落', '木', '帮', '轮', '破', '亚', '师', '围', '注', '远', '字', '材', '排', '供', '河', '态', '封', '另', '施', '减', '树', '溶', '怎', '止', '案', '言', '士', '均', '武', '固', '叶', '鱼', '波', '视', '仅', '费', '紧', '爱', '左', '章', '早', '朝', '害', '续', '轻', '服', '试', '食', '充', '兵', '源', '判', '护', '司', '足', '某', '练', '差', '致', '板', '田', '降', '黑', '犯', '负', '击', '范', '继', '兴', '似', '余', '坚', '曲', '输', '修', '故', '城', '夫', '够', '送', '笔', '船', '占', '右', '财', '吃', '富', '春', '职', '觉', '汉', '画', '功', '巴', '跟', '虽', '杂', '飞', '检', '吸', '助', '升', '阳', '互', '初', '创', '抗', '考', '投', '坏', '策', '古', '径', '换', '未', '跑', '留', '钢', '曾', '端', '责', '站', '简', '述', '钱', '副', '尽', '帝', '射', '草', '冲', '承', '独', '令', '限', '阿', '宣', '环', '双', '请', '超', '微', '让', '控', '州', '良', '轴', '找', '否', '纪', '益', '依', '优', '顶', '础', '载', '倒', '房', '突', '坐', '粉', '敌', '略', '客', '袁', '冷', '胜', '绝', '析', '块', '剂', '测', '丝', '协', '诉', '念', '陈', '仍', '罗', '盐', '友', '洋', '错', '苦', '夜', '刑', '移', '频', '逐', '靠', '混', '母', '短', '皮', '终', '聚', '汽', '村', '云', '哪', '既', '距', '卫', '停', '烈', '央', '察', '烧', '迅', '境', '若', '印', '洲', '刻', '括', '激', '孔', '搞', '甚', '室', '待', '核', '校', '散', '侵', '吧', '甲', '游', '久', '菜', '味', '旧', '模', '湖', '货', '损', '预', '阻', '毫', '普', '稳', '乙', '妈', '植', '息', '扩', '银', '语', '挥', '酒', '守', '拿', '序', '纸', '医', '缺', '雨', '吗', '针', '刘', '啊', '急', '唱', '误', '训', '愿', '审', '附', '获', '茶', '鲜', '粮', '斤', '孩', '脱', '硫', '肥', '善', '龙', '演', '父', '渐', '血', '欢', '械', '掌', '歌', '沙', '刚', '攻', '谓', '盾', '讨', '晚', '粒', '乱', '燃', '矛', '乎', '杀', '药', '宁', '鲁', '贵', '钟', '煤', '读', '班', '伯', '香', '介', '迫', '句', '丰', '培', '握', '兰', '担', '弦', '蛋', '沉', '假', '穿', '执', '答', '乐', '谁', '顺', '烟', '缩', '征', '脸', '喜', '松', '脚', '困', '异', '免', '背', '星', '福', '买', '染', '井', '概', '慢', '怕', '磁', '倍', '祖', '皇', '促', '静', '补', '评', '翻', '肉', '践', '尼', '衣', '宽', '扬', '棉', '希', '伤', '操', '垂', '秋', '宜', '氢', '套', '督', '振', '架', '亮', '末', '宪', '庆', '编', '牛', '触', '映', '雷', '销', '诗', '座', '居', '抓', '裂', '胞', '呼', '娘', '景', '威', '绿', '晶', '厚', '盟', '衡', '鸡', '孙', '延', '危', '胶', '屋', '乡', '临', '陆', '顾', '掉', '呀', '灯', '岁', '措', '束', '耐', '剧', '玉', '赵', '跳', '哥', '季', '课', '凯', '胡', '额', '款', '绍', '卷', '齐', '伟', '蒸', '殖', '永', '宗', '苗', '川', '炉', '岩', '弱', '零', '杨', '奏', '沿', '露', '杆', '探', '滑', '镇', '饭', '浓', '航', '怀', '赶', '库', '夺', '伊', '灵', '税', '途', '灭', '赛', '归', '召', '鼓', '播', '盘', '裁', '险', '康', '唯', '录', '菌', '纯', '借', '糖', '盖', '横', '符', '私', '努', '堂', '域', '枪', '润', '幅', '哈', '竟', '熟', '虫', '泽', '脑', '壤', '碳', '欧', '遍', '侧', '寨', '敢', '彻', '虑', '斜', '薄', '庭', '纳', '弹', '饲', '伸', '折', '麦', '湿', '暗', '荷', '瓦', '塞', '床', '筑', '恶', '户', '访', '塔', '奇', '透', '梁', '刀', '旋', '迹', '卡', '氯', '遇', '份', '毒', '泥', '退', '洗', '摆', '灰', '彩', '卖', '耗', '夏', '择', '忙', '铜', '献', '硬', '予', '繁', '圈', '雪', '函', '亦', '抽', '篇', '阵', '阴', '丁', '尺', '追', '堆', '雄', '迎', '泛', '爸', '楼', '避', '谋', '吨', '野', '猪', '旗', '累', '偏', '典', '馆', '索', '秦', '脂', '潮', '爷', '豆', '忽', '托', '惊', '塑', '遗', '愈', '朱', '替', '纤', '粗', '倾', '尚', '痛', '楚', '谢', '奋', '购', '磨', '君', '池', '旁', '碎', '骨', '监', '捕', '弟', '暴', '割', '贯', '殊', '释', '词', '亡', '壁', '顿', '宝', '午', '尘', '闻', '揭', '炮', '残', '冬', '桥', '妇', '警', '综', '招', '吴', '付', '浮', '遭', '徐', '您', '摇', '谷', '赞', '箱', '隔', '订', '男', '吹', '园', '纷', '唐', '败', '宋', '玻', '巨', '耕', '坦', '荣', '闭', '湾', '键', '凡', '驻', '锅', '救', '恩', '剥', '凝', '碱', '齿', '截', '炼', '麻', '纺', '禁', '废', '盛', '版', '缓', '净', '睛', '昌', '婚', '涉', '筒', '嘴', '插', '岸', '朗', '庄', '街', '藏', '姑', '贸', '腐', '奴', '啦', '惯', '乘', '伙', '恢', '匀', '纱', '扎', '辩', '耳', '彪', '臣', '亿', '璃', '抵', '脉', '秀', '萨', '俄', '网', '舞', '店', '喷', '纵', '寸', '汗', '挂', '洪', '贺', '闪', '柬', '爆', '烯', '津', '稻', '墙', '软', '勇', '像', '滚', '厘', '蒙', '芳', '肯', '坡', '柱', '荡', '腿', '仪', '旅', '尾', '轧', '冰', '贡', '登', '黎', '削', '钻', '勒', '逃', '障', '氨', '郭', '峰', '币', '港', '伏', '轨', '亩', '毕', '擦', '莫', '刺', '浪', '秘', '援', '株', '健', '售', '股', '岛', '甘', '泡', '睡', '童', '铸', '汤', '阀', '休', '汇', '舍', '牧', '绕', '炸', '哲', '磷', '绩', '朋', '淡', '尖', '启', '陷', '柴', '呈', '徒', '颜', '泪', '稍', '忘', '泵', '蓝', '拖', '洞', '授', '镜', '辛', '壮', '锋', '贫', '虚', '弯', '摩', '泰', '幼', '廷', '尊', '窗', '纲', '弄', '隶', '疑', '氏', '宫', '姐', '震', '瑞', '怪', '尤', '琴', '循', '描', '膜', '违', '夹', '腰', '缘', '珠', '穷', '森', '枝', '竹', '沟', '催', '绳', '忆', '邦', '剩', '幸', '浆', '栏', '拥', '牙', '贮', '礼', '滤', '钠', '纹', '罢', '拍', '咱', '喊', '袖', '埃', '勤', '罚', '焦', '潜', '伍', '墨', '欲', '缝', '姓', '刊', '饱', '仿', '奖', '铝', '鬼', '丽', '跨', '默', '挖', '链', '扫', '喝', '袋', '炭', '污', '幕', '诸', '弧', '励', '梅', '奶', '洁', '灾', '舟', '鉴', '苯', '讼', '抱', '毁', '懂', '寒', '智', '埔', '寄', '届', '跃', '渡', '挑', '丹', '艰', '贝', '碰', '拔', '爹', '戴', '码', '梦', '芽', '熔', '赤', '渔', '哭', '敬', '颗', '奔', '铅', '仲', '虎', '稀', '妹', '乏', '珍', '申', '桌', '遵', '允', '隆', '螺', '仓', '魏', '锐', '晓', '氮', '兼', '隐', '碍', '赫', '拨', '忠', '肃', '缸', '牵', '抢', '博', '巧', '壳', '兄', '杜', '讯', '诚', '碧', '祥', '柯', '页', '巡', '矩', '悲', '灌', '龄', '伦', '票', '寻', '桂', '铺', '圣', '恐', '恰', '郑', '趣', '抬', '荒', '腾', '贴', '柔', '滴', '猛', '阔', '辆', '妻', '填', '撤', '储', '签', '闹', '扰', '紫', '砂', '递', '戏', '吊', '陶', '伐', '喂', '疗', '瓶', '婆', '抚', '臂', '摸', '忍', '虾', '蜡', '邻', '胸', '巩', '挤', '偶', '弃', '槽', '劲', '乳', '邓', '吉', '仁', '烂', '砖', '租', '乌', '舰', '伴', '瓜', '浅', '丙', '暂', '燥', '橡', '柳', '迷', '暖', '牌', '秧', '胆', '详', '簧', '踏', '瓷', '谱', '呆', '宾', '糊', '洛', '辉', '愤', '竞', '隙', '怒', '粘', '乃', '绪', '肩', '籍', '敏', '涂', '熙', '皆', '侦', '悬', '掘', '享', '纠', '醒', '狂', '锁', '淀', '恨', '牲', '霸', '爬', '赏', '逆', '玩', '陵', '祝', '秒', '浙', '貌', '役', '彼', '悉', '鸭', '趋', '凤', '晨', '畜', '辈', '秩', '卵', '署', '梯', '炎', '滩', '棋', '驱', '筛', '峡', '冒', '啥', '寿', '译', '浸', '泉', '帽', '迟', '硅', '疆', '贷', '漏', '稿', '冠', '嫩', '胁', '芯', '牢', '叛', '蚀', '奥', '鸣', '岭', '羊', '凭', '串', '塘', '绘', '酵', '融', '盆', '锡', '庙', '筹', '冻', '辅', '摄', '袭', '筋', '拒', '僚', '旱', '钾', '鸟', '漆', '沈', '眉', '疏', '添', '棒', '穗', '硝', '韩', '逼', '扭', '侨', '凉', '挺', '碗', '栽', '炒', '杯', '患', '馏', '劝', '豪', '辽', '勃', '鸿', '旦', '吏', '拜', '狗', '埋', '辊', '掩', '饮', '搬', '骂', '辞', '勾', '扣', '估', '蒋', '绒', '雾', '丈', '朵', '姆', '拟', '宇', '辑', '陕', '雕', '偿', '蓄', '崇', '剪', '倡', '厅', '咬', '驶', '薯', '刷', '斥', '番', '赋', '奉', '佛', '浇', '漫', '曼', '扇', '钙', '桃', '扶', '仔', '返', '俗', '亏', '腔', '鞋', '棱', '覆', '框', '悄', '叔', '撞', '骗', '勘', '旺', '沸', '孤', '吐', '孟', '渠', '屈', '疾', '妙', '惜', '仰', '狠', '胀', '谐', '抛', '霉', '桑', '岗', '嘛', '衰', '盗', '渗', '脏', '赖', '涌', '甜', '曹', '阅', '肌', '哩', '厉', '烃', '纬', '毅', '昨', '伪', '症', '煮', '叹', '钉', '搭', '茎', '笼', '酷', '偷', '弓', '锥', '恒', '杰', '坑', '鼻', '翼', '纶', '叙', '狱', '逮', '罐', '络', '棚', '抑', '膨', '蔬', '寺', '骤', '穆', '冶', '枯', '册', '尸', '凸', '绅', '坯', '牺', '焰', '轰', '欣', '晋', '瘦', '御', '锭', '锦', '丧', '旬', '锻', '垄', '搜', '扑', '邀', '亭', '酯', '迈', '舒', '脆', '酶', '闲', '忧', '酚', '顽', '羽', '涨', '卸', '仗', '陪', '辟', '惩', '杭', '姚', '肚', '捉', '飘', '漂', '昆', '欺', '吾', '郎', '烷', '汁', '呵', '饰', '萧', '雅', '邮', '迁', '燕', '撒', '姻', '赴', '宴', '烦', '债', '帐', '斑', '铃', '旨', '醇', '董', '饼', '雏', '姿', '拌', '傅', '腹', '妥', '揉', '贤', '拆', '歪', '葡', '胺', '丢', '浩', '徽', '昂', '垫', '挡', '览', '贪', '慰', '缴', '汪', '慌', '冯', '诺', '姜', '谊', '凶', '劣', '诬', '耀', '昏', '躺', '盈', '骑', '乔', '溪', '丛', '卢', '抹', '闷', '咨', '刮', '驾', '缆', '悟', '摘', '铒', '掷', '颇', '幻', '柄', '惠', '惨', '佳', '仇', '腊', '窝', '涤', '剑', '瞧', '堡', '泼', '葱', '罩', '霍', '捞', '胎', '苍', '滨', '俩', '捅', '湘', '砍', '霞', '邵', '萄', '疯', '淮', '遂', '熊', '粪', '烘', '宿', '档', '戈', '驳', '嫂', '裕', '徙', '箭', '捐', '肠', '撑', '晒', '辨', '殿', '莲', '摊', '搅', '酱', '屏', '疫', '哀', '蔡', '堵', '沫', '皱', '畅', '叠', '阁', '莱', '敲', '辖', '钩', '痕', '坝', '巷', '饿', '祸', '丘', '玄', '溜', '曰', '逻', '彭', '尝', '卿', '妨', '艇', '吞', '韦', '怨', '矮', '歇']
    
    module.exports = chinese
    
    },{}],238:[function(require,module,exports){
    'use strict'
    
    var english = ['abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access', 'accident', 'account', 'accuse', 'achieve', 'acid', 'acoustic', 'acquire', 'across', 'act', 'action', 'actor', 'actress', 'actual', 'adapt', 'add', 'addict', 'address', 'adjust', 'admit', 'adult', 'advance', 'advice', 'aerobic', 'affair', 'afford', 'afraid', 'again', 'age', 'agent', 'agree', 'ahead', 'aim', 'air', 'airport', 'aisle', 'alarm', 'album', 'alcohol', 'alert', 'alien', 'all', 'alley', 'allow', 'almost', 'alone', 'alpha', 'already', 'also', 'alter', 'always', 'amateur', 'amazing', 'among', 'amount', 'amused', 'analyst', 'anchor', 'ancient', 'anger', 'angle', 'angry', 'animal', 'ankle', 'announce', 'annual', 'another', 'answer', 'antenna', 'antique', 'anxiety', 'any', 'apart', 'apology', 'appear', 'apple', 'approve', 'april', 'arch', 'arctic', 'area', 'arena', 'argue', 'arm', 'armed', 'armor', 'army', 'around', 'arrange', 'arrest', 'arrive', 'arrow', 'art', 'artefact', 'artist', 'artwork', 'ask', 'aspect', 'assault', 'asset', 'assist', 'assume', 'asthma', 'athlete', 'atom', 'attack', 'attend', 'attitude', 'attract', 'auction', 'audit', 'august', 'aunt', 'author', 'auto', 'autumn', 'average', 'avocado', 'avoid', 'awake', 'aware', 'away', 'awesome', 'awful', 'awkward', 'axis', 'baby', 'bachelor', 'bacon', 'badge', 'bag', 'balance', 'balcony', 'ball', 'bamboo', 'banana', 'banner', 'bar', 'barely', 'bargain', 'barrel', 'base', 'basic', 'basket', 'battle', 'beach', 'bean', 'beauty', 'because', 'become', 'beef', 'before', 'begin', 'behave', 'behind', 'believe', 'below', 'belt', 'bench', 'benefit', 'best', 'betray', 'better', 'between', 'beyond', 'bicycle', 'bid', 'bike', 'bind', 'biology', 'bird', 'birth', 'bitter', 'black', 'blade', 'blame', 'blanket', 'blast', 'bleak', 'bless', 'blind', 'blood', 'blossom', 'blouse', 'blue', 'blur', 'blush', 'board', 'boat', 'body', 'boil', 'bomb', 'bone', 'bonus', 'book', 'boost', 'border', 'boring', 'borrow', 'boss', 'bottom', 'bounce', 'box', 'boy', 'bracket', 'brain', 'brand', 'brass', 'brave', 'bread', 'breeze', 'brick', 'bridge', 'brief', 'bright', 'bring', 'brisk', 'broccoli', 'broken', 'bronze', 'broom', 'brother', 'brown', 'brush', 'bubble', 'buddy', 'budget', 'buffalo', 'build', 'bulb', 'bulk', 'bullet', 'bundle', 'bunker', 'burden', 'burger', 'burst', 'bus', 'business', 'busy', 'butter', 'buyer', 'buzz', 'cabbage', 'cabin', 'cable', 'cactus', 'cage', 'cake', 'call', 'calm', 'camera', 'camp', 'can', 'canal', 'cancel', 'candy', 'cannon', 'canoe', 'canvas', 'canyon', 'capable', 'capital', 'captain', 'car', 'carbon', 'card', 'cargo', 'carpet', 'carry', 'cart', 'case', 'cash', 'casino', 'castle', 'casual', 'cat', 'catalog', 'catch', 'category', 'cattle', 'caught', 'cause', 'caution', 'cave', 'ceiling', 'celery', 'cement', 'census', 'century', 'cereal', 'certain', 'chair', 'chalk', 'champion', 'change', 'chaos', 'chapter', 'charge', 'chase', 'chat', 'cheap', 'check', 'cheese', 'chef', 'cherry', 'chest', 'chicken', 'chief', 'child', 'chimney', 'choice', 'choose', 'chronic', 'chuckle', 'chunk', 'churn', 'cigar', 'cinnamon', 'circle', 'citizen', 'city', 'civil', 'claim', 'clap', 'clarify', 'claw', 'clay', 'clean', 'clerk', 'clever', 'click', 'client', 'cliff', 'climb', 'clinic', 'clip', 'clock', 'clog', 'close', 'cloth', 'cloud', 'clown', 'club', 'clump', 'cluster', 'clutch', 'coach', 'coast', 'coconut', 'code', 'coffee', 'coil', 'coin', 'collect', 'color', 'column', 'combine', 'come', 'comfort', 'comic', 'common', 'company', 'concert', 'conduct', 'confirm', 'congress', 'connect', 'consider', 'control', 'convince', 'cook', 'cool', 'copper', 'copy', 'coral', 'core', 'corn', 'correct', 'cost', 'cotton', 'couch', 'country', 'couple', 'course', 'cousin', 'cover', 'coyote', 'crack', 'cradle', 'craft', 'cram', 'crane', 'crash', 'crater', 'crawl', 'crazy', 'cream', 'credit', 'creek', 'crew', 'cricket', 'crime', 'crisp', 'critic', 'crop', 'cross', 'crouch', 'crowd', 'crucial', 'cruel', 'cruise', 'crumble', 'crunch', 'crush', 'cry', 'crystal', 'cube', 'culture', 'cup', 'cupboard', 'curious', 'current', 'curtain', 'curve', 'cushion', 'custom', 'cute', 'cycle', 'dad', 'damage', 'damp', 'dance', 'danger', 'daring', 'dash', 'daughter', 'dawn', 'day', 'deal', 'debate', 'debris', 'decade', 'december', 'decide', 'decline', 'decorate', 'decrease', 'deer', 'defense', 'define', 'defy', 'degree', 'delay', 'deliver', 'demand', 'demise', 'denial', 'dentist', 'deny', 'depart', 'depend', 'deposit', 'depth', 'deputy', 'derive', 'describe', 'desert', 'design', 'desk', 'despair', 'destroy', 'detail', 'detect', 'develop', 'device', 'devote', 'diagram', 'dial', 'diamond', 'diary', 'dice', 'diesel', 'diet', 'differ', 'digital', 'dignity', 'dilemma', 'dinner', 'dinosaur', 'direct', 'dirt', 'disagree', 'discover', 'disease', 'dish', 'dismiss', 'disorder', 'display', 'distance', 'divert', 'divide', 'divorce', 'dizzy', 'doctor', 'document', 'dog', 'doll', 'dolphin', 'domain', 'donate', 'donkey', 'donor', 'door', 'dose', 'double', 'dove', 'draft', 'dragon', 'drama', 'drastic', 'draw', 'dream', 'dress', 'drift', 'drill', 'drink', 'drip', 'drive', 'drop', 'drum', 'dry', 'duck', 'dumb', 'dune', 'during', 'dust', 'dutch', 'duty', 'dwarf', 'dynamic', 'eager', 'eagle', 'early', 'earn', 'earth', 'easily', 'east', 'easy', 'echo', 'ecology', 'economy', 'edge', 'edit', 'educate', 'effort', 'egg', 'eight', 'either', 'elbow', 'elder', 'electric', 'elegant', 'element', 'elephant', 'elevator', 'elite', 'else', 'embark', 'embody', 'embrace', 'emerge', 'emotion', 'employ', 'empower', 'empty', 'enable', 'enact', 'end', 'endless', 'endorse', 'enemy', 'energy', 'enforce', 'engage', 'engine', 'enhance', 'enjoy', 'enlist', 'enough', 'enrich', 'enroll', 'ensure', 'enter', 'entire', 'entry', 'envelope', 'episode', 'equal', 'equip', 'era', 'erase', 'erode', 'erosion', 'error', 'erupt', 'escape', 'essay', 'essence', 'estate', 'eternal', 'ethics', 'evidence', 'evil', 'evoke', 'evolve', 'exact', 'example', 'excess', 'exchange', 'excite', 'exclude', 'excuse', 'execute', 'exercise', 'exhaust', 'exhibit', 'exile', 'exist', 'exit', 'exotic', 'expand', 'expect', 'expire', 'explain', 'expose', 'express', 'extend', 'extra', 'eye', 'eyebrow', 'fabric', 'face', 'faculty', 'fade', 'faint', 'faith', 'fall', 'false', 'fame', 'family', 'famous', 'fan', 'fancy', 'fantasy', 'farm', 'fashion', 'fat', 'fatal', 'father', 'fatigue', 'fault', 'favorite', 'feature', 'february', 'federal', 'fee', 'feed', 'feel', 'female', 'fence', 'festival', 'fetch', 'fever', 'few', 'fiber', 'fiction', 'field', 'figure', 'file', 'film', 'filter', 'final', 'find', 'fine', 'finger', 'finish', 'fire', 'firm', 'first', 'fiscal', 'fish', 'fit', 'fitness', 'fix', 'flag', 'flame', 'flash', 'flat', 'flavor', 'flee', 'flight', 'flip', 'float', 'flock', 'floor', 'flower', 'fluid', 'flush', 'fly', 'foam', 'focus', 'fog', 'foil', 'fold', 'follow', 'food', 'foot', 'force', 'forest', 'forget', 'fork', 'fortune', 'forum', 'forward', 'fossil', 'foster', 'found', 'fox', 'fragile', 'frame', 'frequent', 'fresh', 'friend', 'fringe', 'frog', 'front', 'frost', 'frown', 'frozen', 'fruit', 'fuel', 'fun', 'funny', 'furnace', 'fury', 'future', 'gadget', 'gain', 'galaxy', 'gallery', 'game', 'gap', 'garage', 'garbage', 'garden', 'garlic', 'garment', 'gas', 'gasp', 'gate', 'gather', 'gauge', 'gaze', 'general', 'genius', 'genre', 'gentle', 'genuine', 'gesture', 'ghost', 'giant', 'gift', 'giggle', 'ginger', 'giraffe', 'girl', 'give', 'glad', 'glance', 'glare', 'glass', 'glide', 'glimpse', 'globe', 'gloom', 'glory', 'glove', 'glow', 'glue', 'goat', 'goddess', 'gold', 'good', 'goose', 'gorilla', 'gospel', 'gossip', 'govern', 'gown', 'grab', 'grace', 'grain', 'grant', 'grape', 'grass', 'gravity', 'great', 'green', 'grid', 'grief', 'grit', 'grocery', 'group', 'grow', 'grunt', 'guard', 'guess', 'guide', 'guilt', 'guitar', 'gun', 'gym', 'habit', 'hair', 'half', 'hammer', 'hamster', 'hand', 'happy', 'harbor', 'hard', 'harsh', 'harvest', 'hat', 'have', 'hawk', 'hazard', 'head', 'health', 'heart', 'heavy', 'hedgehog', 'height', 'hello', 'helmet', 'help', 'hen', 'hero', 'hidden', 'high', 'hill', 'hint', 'hip', 'hire', 'history', 'hobby', 'hockey', 'hold', 'hole', 'holiday', 'hollow', 'home', 'honey', 'hood', 'hope', 'horn', 'horror', 'horse', 'hospital', 'host', 'hotel', 'hour', 'hover', 'hub', 'huge', 'human', 'humble', 'humor', 'hundred', 'hungry', 'hunt', 'hurdle', 'hurry', 'hurt', 'husband', 'hybrid', 'ice', 'icon', 'idea', 'identify', 'idle', 'ignore', 'ill', 'illegal', 'illness', 'image', 'imitate', 'immense', 'immune', 'impact', 'impose', 'improve', 'impulse', 'inch', 'include', 'income', 'increase', 'index', 'indicate', 'indoor', 'industry', 'infant', 'inflict', 'inform', 'inhale', 'inherit', 'initial', 'inject', 'injury', 'inmate', 'inner', 'innocent', 'input', 'inquiry', 'insane', 'insect', 'inside', 'inspire', 'install', 'intact', 'interest', 'into', 'invest', 'invite', 'involve', 'iron', 'island', 'isolate', 'issue', 'item', 'ivory', 'jacket', 'jaguar', 'jar', 'jazz', 'jealous', 'jeans', 'jelly', 'jewel', 'job', 'join', 'joke', 'journey', 'joy', 'judge', 'juice', 'jump', 'jungle', 'junior', 'junk', 'just', 'kangaroo', 'keen', 'keep', 'ketchup', 'key', 'kick', 'kid', 'kidney', 'kind', 'kingdom', 'kiss', 'kit', 'kitchen', 'kite', 'kitten', 'kiwi', 'knee', 'knife', 'knock', 'know', 'lab', 'label', 'labor', 'ladder', 'lady', 'lake', 'lamp', 'language', 'laptop', 'large', 'later', 'latin', 'laugh', 'laundry', 'lava', 'law', 'lawn', 'lawsuit', 'layer', 'lazy', 'leader', 'leaf', 'learn', 'leave', 'lecture', 'left', 'leg', 'legal', 'legend', 'leisure', 'lemon', 'lend', 'length', 'lens', 'leopard', 'lesson', 'letter', 'level', 'liar', 'liberty', 'library', 'license', 'life', 'lift', 'light', 'like', 'limb', 'limit', 'link', 'lion', 'liquid', 'list', 'little', 'live', 'lizard', 'load', 'loan', 'lobster', 'local', 'lock', 'logic', 'lonely', 'long', 'loop', 'lottery', 'loud', 'lounge', 'love', 'loyal', 'lucky', 'luggage', 'lumber', 'lunar', 'lunch', 'luxury', 'lyrics', 'machine', 'mad', 'magic', 'magnet', 'maid', 'mail', 'main', 'major', 'make', 'mammal', 'man', 'manage', 'mandate', 'mango', 'mansion', 'manual', 'maple', 'marble', 'march', 'margin', 'marine', 'market', 'marriage', 'mask', 'mass', 'master', 'match', 'material', 'math', 'matrix', 'matter', 'maximum', 'maze', 'meadow', 'mean', 'measure', 'meat', 'mechanic', 'medal', 'media', 'melody', 'melt', 'member', 'memory', 'mention', 'menu', 'mercy', 'merge', 'merit', 'merry', 'mesh', 'message', 'metal', 'method', 'middle', 'midnight', 'milk', 'million', 'mimic', 'mind', 'minimum', 'minor', 'minute', 'miracle', 'mirror', 'misery', 'miss', 'mistake', 'mix', 'mixed', 'mixture', 'mobile', 'model', 'modify', 'mom', 'moment', 'monitor', 'monkey', 'monster', 'month', 'moon', 'moral', 'more', 'morning', 'mosquito', 'mother', 'motion', 'motor', 'mountain', 'mouse', 'move', 'movie', 'much', 'muffin', 'mule', 'multiply', 'muscle', 'museum', 'mushroom', 'music', 'must', 'mutual', 'myself', 'mystery', 'myth', 'naive', 'name', 'napkin', 'narrow', 'nasty', 'nation', 'nature', 'near', 'neck', 'need', 'negative', 'neglect', 'neither', 'nephew', 'nerve', 'nest', 'net', 'network', 'neutral', 'never', 'news', 'next', 'nice', 'night', 'noble', 'noise', 'nominee', 'noodle', 'normal', 'north', 'nose', 'notable', 'note', 'nothing', 'notice', 'novel', 'now', 'nuclear', 'number', 'nurse', 'nut', 'oak', 'obey', 'object', 'oblige', 'obscure', 'observe', 'obtain', 'obvious', 'occur', 'ocean', 'october', 'odor', 'off', 'offer', 'office', 'often', 'oil', 'okay', 'old', 'olive', 'olympic', 'omit', 'once', 'one', 'onion', 'online', 'only', 'open', 'opera', 'opinion', 'oppose', 'option', 'orange', 'orbit', 'orchard', 'order', 'ordinary', 'organ', 'orient', 'original', 'orphan', 'ostrich', 'other', 'outdoor', 'outer', 'output', 'outside', 'oval', 'oven', 'over', 'own', 'owner', 'oxygen', 'oyster', 'ozone', 'pact', 'paddle', 'page', 'pair', 'palace', 'palm', 'panda', 'panel', 'panic', 'panther', 'paper', 'parade', 'parent', 'park', 'parrot', 'party', 'pass', 'patch', 'path', 'patient', 'patrol', 'pattern', 'pause', 'pave', 'payment', 'peace', 'peanut', 'pear', 'peasant', 'pelican', 'pen', 'penalty', 'pencil', 'people', 'pepper', 'perfect', 'permit', 'person', 'pet', 'phone', 'photo', 'phrase', 'physical', 'piano', 'picnic', 'picture', 'piece', 'pig', 'pigeon', 'pill', 'pilot', 'pink', 'pioneer', 'pipe', 'pistol', 'pitch', 'pizza', 'place', 'planet', 'plastic', 'plate', 'play', 'please', 'pledge', 'pluck', 'plug', 'plunge', 'poem', 'poet', 'point', 'polar', 'pole', 'police', 'pond', 'pony', 'pool', 'popular', 'portion', 'position', 'possible', 'post', 'potato', 'pottery', 'poverty', 'powder', 'power', 'practice', 'praise', 'predict', 'prefer', 'prepare', 'present', 'pretty', 'prevent', 'price', 'pride', 'primary', 'print', 'priority', 'prison', 'private', 'prize', 'problem', 'process', 'produce', 'profit', 'program', 'project', 'promote', 'proof', 'property', 'prosper', 'protect', 'proud', 'provide', 'public', 'pudding', 'pull', 'pulp', 'pulse', 'pumpkin', 'punch', 'pupil', 'puppy', 'purchase', 'purity', 'purpose', 'purse', 'push', 'put', 'puzzle', 'pyramid', 'quality', 'quantum', 'quarter', 'question', 'quick', 'quit', 'quiz', 'quote', 'rabbit', 'raccoon', 'race', 'rack', 'radar', 'radio', 'rail', 'rain', 'raise', 'rally', 'ramp', 'ranch', 'random', 'range', 'rapid', 'rare', 'rate', 'rather', 'raven', 'raw', 'razor', 'ready', 'real', 'reason', 'rebel', 'rebuild', 'recall', 'receive', 'recipe', 'record', 'recycle', 'reduce', 'reflect', 'reform', 'refuse', 'region', 'regret', 'regular', 'reject', 'relax', 'release', 'relief', 'rely', 'remain', 'remember', 'remind', 'remove', 'render', 'renew', 'rent', 'reopen', 'repair', 'repeat', 'replace', 'report', 'require', 'rescue', 'resemble', 'resist', 'resource', 'response', 'result', 'retire', 'retreat', 'return', 'reunion', 'reveal', 'review', 'reward', 'rhythm', 'rib', 'ribbon', 'rice', 'rich', 'ride', 'ridge', 'rifle', 'right', 'rigid', 'ring', 'riot', 'ripple', 'risk', 'ritual', 'rival', 'river', 'road', 'roast', 'robot', 'robust', 'rocket', 'romance', 'roof', 'rookie', 'room', 'rose', 'rotate', 'rough', 'round', 'route', 'royal', 'rubber', 'rude', 'rug', 'rule', 'run', 'runway', 'rural', 'sad', 'saddle', 'sadness', 'safe', 'sail', 'salad', 'salmon', 'salon', 'salt', 'salute', 'same', 'sample', 'sand', 'satisfy', 'satoshi', 'sauce', 'sausage', 'save', 'say', 'scale', 'scan', 'scare', 'scatter', 'scene', 'scheme', 'school', 'science', 'scissors', 'scorpion', 'scout', 'scrap', 'screen', 'script', 'scrub', 'sea', 'search', 'season', 'seat', 'second', 'secret', 'section', 'security', 'seed', 'seek', 'segment', 'select', 'sell', 'seminar', 'senior', 'sense', 'sentence', 'series', 'service', 'session', 'settle', 'setup', 'seven', 'shadow', 'shaft', 'shallow', 'share', 'shed', 'shell', 'sheriff', 'shield', 'shift', 'shine', 'ship', 'shiver', 'shock', 'shoe', 'shoot', 'shop', 'short', 'shoulder', 'shove', 'shrimp', 'shrug', 'shuffle', 'shy', 'sibling', 'sick', 'side', 'siege', 'sight', 'sign', 'silent', 'silk', 'silly', 'silver', 'similar', 'simple', 'since', 'sing', 'siren', 'sister', 'situate', 'six', 'size', 'skate', 'sketch', 'ski', 'skill', 'skin', 'skirt', 'skull', 'slab', 'slam', 'sleep', 'slender', 'slice', 'slide', 'slight', 'slim', 'slogan', 'slot', 'slow', 'slush', 'small', 'smart', 'smile', 'smoke', 'smooth', 'snack', 'snake', 'snap', 'sniff', 'snow', 'soap', 'soccer', 'social', 'sock', 'soda', 'soft', 'solar', 'soldier', 'solid', 'solution', 'solve', 'someone', 'song', 'soon', 'sorry', 'sort', 'soul', 'sound', 'soup', 'source', 'south', 'space', 'spare', 'spatial', 'spawn', 'speak', 'special', 'speed', 'spell', 'spend', 'sphere', 'spice', 'spider', 'spike', 'spin', 'spirit', 'split', 'spoil', 'sponsor', 'spoon', 'sport', 'spot', 'spray', 'spread', 'spring', 'spy', 'square', 'squeeze', 'squirrel', 'stable', 'stadium', 'staff', 'stage', 'stairs', 'stamp', 'stand', 'start', 'state', 'stay', 'steak', 'steel', 'stem', 'step', 'stereo', 'stick', 'still', 'sting', 'stock', 'stomach', 'stone', 'stool', 'story', 'stove', 'strategy', 'street', 'strike', 'strong', 'struggle', 'student', 'stuff', 'stumble', 'style', 'subject', 'submit', 'subway', 'success', 'such', 'sudden', 'suffer', 'sugar', 'suggest', 'suit', 'summer', 'sun', 'sunny', 'sunset', 'super', 'supply', 'supreme', 'sure', 'surface', 'surge', 'surprise', 'surround', 'survey', 'suspect', 'sustain', 'swallow', 'swamp', 'swap', 'swarm', 'swear', 'sweet', 'swift', 'swim', 'swing', 'switch', 'sword', 'symbol', 'symptom', 'syrup', 'system', 'table', 'tackle', 'tag', 'tail', 'talent', 'talk', 'tank', 'tape', 'target', 'task', 'taste', 'tattoo', 'taxi', 'teach', 'team', 'tell', 'ten', 'tenant', 'tennis', 'tent', 'term', 'test', 'text', 'thank', 'that', 'theme', 'then', 'theory', 'there', 'they', 'thing', 'this', 'thought', 'three', 'thrive', 'throw', 'thumb', 'thunder', 'ticket', 'tide', 'tiger', 'tilt', 'timber', 'time', 'tiny', 'tip', 'tired', 'tissue', 'title', 'toast', 'tobacco', 'today', 'toddler', 'toe', 'together', 'toilet', 'token', 'tomato', 'tomorrow', 'tone', 'tongue', 'tonight', 'tool', 'tooth', 'top', 'topic', 'topple', 'torch', 'tornado', 'tortoise', 'toss', 'total', 'tourist', 'toward', 'tower', 'town', 'toy', 'track', 'trade', 'traffic', 'tragic', 'train', 'transfer', 'trap', 'trash', 'travel', 'tray', 'treat', 'tree', 'trend', 'trial', 'tribe', 'trick', 'trigger', 'trim', 'trip', 'trophy', 'trouble', 'truck', 'true', 'truly', 'trumpet', 'trust', 'truth', 'try', 'tube', 'tuition', 'tumble', 'tuna', 'tunnel', 'turkey', 'turn', 'turtle', 'twelve', 'twenty', 'twice', 'twin', 'twist', 'two', 'type', 'typical', 'ugly', 'umbrella', 'unable', 'unaware', 'uncle', 'uncover', 'under', 'undo', 'unfair', 'unfold', 'unhappy', 'uniform', 'unique', 'unit', 'universe', 'unknown', 'unlock', 'until', 'unusual', 'unveil', 'update', 'upgrade', 'uphold', 'upon', 'upper', 'upset', 'urban', 'urge', 'usage', 'use', 'used', 'useful', 'useless', 'usual', 'utility', 'vacant', 'vacuum', 'vague', 'valid', 'valley', 'valve', 'van', 'vanish', 'vapor', 'various', 'vast', 'vault', 'vehicle', 'velvet', 'vendor', 'venture', 'venue', 'verb', 'verify', 'version', 'very', 'vessel', 'veteran', 'viable', 'vibrant', 'vicious', 'victory', 'video', 'view', 'village', 'vintage', 'violin', 'virtual', 'virus', 'visa', 'visit', 'visual', 'vital', 'vivid', 'vocal', 'voice', 'void', 'volcano', 'volume', 'vote', 'voyage', 'wage', 'wagon', 'wait', 'walk', 'wall', 'walnut', 'want', 'warfare', 'warm', 'warrior', 'wash', 'wasp', 'waste', 'water', 'wave', 'way', 'wealth', 'weapon', 'wear', 'weasel', 'weather', 'web', 'wedding', 'weekend', 'weird', 'welcome', 'west', 'wet', 'whale', 'what', 'wheat', 'wheel', 'when', 'where', 'whip', 'whisper', 'wide', 'width', 'wife', 'wild', 'will', 'win', 'window', 'wine', 'wing', 'wink', 'winner', 'winter', 'wire', 'wisdom', 'wise', 'wish', 'witness', 'wolf', 'woman', 'wonder', 'wood', 'wool', 'word', 'work', 'world', 'worry', 'worth', 'wrap', 'wreck', 'wrestle', 'wrist', 'write', 'wrong', 'yard', 'year', 'yellow', 'you', 'young', 'youth', 'zebra', 'zero', 'zone', 'zoo']
    
    module.exports = english
    
    },{}],239:[function(require,module,exports){
    'use string'
    
    var french = ['abaisser', 'abandon', 'abdiquer', 'abeille', 'abolir', 'aborder', 'aboutir', 'aboyer', 'abrasif', 'abreuver', 'abriter', 'abroger', 'abrupt', 'absence', 'absolu', 'absurde', 'abusif', 'abyssal', 'académie', 'acajou', 'acarien', 'accabler', 'accepter', 'acclamer', 'accolade', 'accroche', 'accuser', 'acerbe', 'achat', 'acheter', 'aciduler', 'acier', 'acompte', 'acquérir', 'acronyme', 'acteur', 'actif', 'actuel', 'adepte', 'adéquat', 'adhésif', 'adjectif', 'adjuger', 'admettre', 'admirer', 'adopter', 'adorer', 'adoucir', 'adresse', 'adroit', 'adulte', 'adverbe', 'aérer', 'aéronef', 'affaire', 'affecter', 'affiche', 'affreux', 'affubler', 'agacer', 'agencer', 'agile', 'agiter', 'agrafer', 'agréable', 'agrume', 'aider', 'aiguille', 'ailier', 'aimable', 'aisance', 'ajouter', 'ajuster', 'alarmer', 'alchimie', 'alerte', 'algèbre', 'algue', 'aliéner', 'aliment', 'alléger', 'alliage', 'allouer', 'allumer', 'alourdir', 'alpaga', 'altesse', 'alvéole', 'amateur', 'ambigu', 'ambre', 'aménager', 'amertume', 'amidon', 'amiral', 'amorcer', 'amour', 'amovible', 'amphibie', 'ampleur', 'amusant', 'analyse', 'anaphore', 'anarchie', 'anatomie', 'ancien', 'anéantir', 'angle', 'angoisse', 'anguleux', 'animal', 'annexer', 'annonce', 'annuel', 'anodin', 'anomalie', 'anonyme', 'anormal', 'antenne', 'antidote', 'anxieux', 'apaiser', 'apéritif', 'aplanir', 'apologie', 'appareil', 'appeler', 'apporter', 'appuyer', 'aquarium', 'aqueduc', 'arbitre', 'arbuste', 'ardeur', 'ardoise', 'argent', 'arlequin', 'armature', 'armement', 'armoire', 'armure', 'arpenter', 'arracher', 'arriver', 'arroser', 'arsenic', 'artériel', 'article', 'aspect', 'asphalte', 'aspirer', 'assaut', 'asservir', 'assiette', 'associer', 'assurer', 'asticot', 'astre', 'astuce', 'atelier', 'atome', 'atrium', 'atroce', 'attaque', 'attentif', 'attirer', 'attraper', 'aubaine', 'auberge', 'audace', 'audible', 'augurer', 'aurore', 'automne', 'autruche', 'avaler', 'avancer', 'avarice', 'avenir', 'averse', 'aveugle', 'aviateur', 'avide', 'avion', 'aviser', 'avoine', 'avouer', 'avril', 'axial', 'axiome', 'badge', 'bafouer', 'bagage', 'baguette', 'baignade', 'balancer', 'balcon', 'baleine', 'balisage', 'bambin', 'bancaire', 'bandage', 'banlieue', 'bannière', 'banquier', 'barbier', 'baril', 'baron', 'barque', 'barrage', 'bassin', 'bastion', 'bataille', 'bateau', 'batterie', 'baudrier', 'bavarder', 'belette', 'bélier', 'belote', 'bénéfice', 'berceau', 'berger', 'berline', 'bermuda', 'besace', 'besogne', 'bétail', 'beurre', 'biberon', 'bicycle', 'bidule', 'bijou', 'bilan', 'bilingue', 'billard', 'binaire', 'biologie', 'biopsie', 'biotype', 'biscuit', 'bison', 'bistouri', 'bitume', 'bizarre', 'blafard', 'blague', 'blanchir', 'blessant', 'blinder', 'blond', 'bloquer', 'blouson', 'bobard', 'bobine', 'boire', 'boiser', 'bolide', 'bonbon', 'bondir', 'bonheur', 'bonifier', 'bonus', 'bordure', 'borne', 'botte', 'boucle', 'boueux', 'bougie', 'boulon', 'bouquin', 'bourse', 'boussole', 'boutique', 'boxeur', 'branche', 'brasier', 'brave', 'brebis', 'brèche', 'breuvage', 'bricoler', 'brigade', 'brillant', 'brioche', 'brique', 'brochure', 'broder', 'bronzer', 'brousse', 'broyeur', 'brume', 'brusque', 'brutal', 'bruyant', 'buffle', 'buisson', 'bulletin', 'bureau', 'burin', 'bustier', 'butiner', 'butoir', 'buvable', 'buvette', 'cabanon', 'cabine', 'cachette', 'cadeau', 'cadre', 'caféine', 'caillou', 'caisson', 'calculer', 'calepin', 'calibre', 'calmer', 'calomnie', 'calvaire', 'camarade', 'caméra', 'camion', 'campagne', 'canal', 'caneton', 'canon', 'cantine', 'canular', 'capable', 'caporal', 'caprice', 'capsule', 'capter', 'capuche', 'carabine', 'carbone', 'caresser', 'caribou', 'carnage', 'carotte', 'carreau', 'carton', 'cascade', 'casier', 'casque', 'cassure', 'causer', 'caution', 'cavalier', 'caverne', 'caviar', 'cédille', 'ceinture', 'céleste', 'cellule', 'cendrier', 'censurer', 'central', 'cercle', 'cérébral', 'cerise', 'cerner', 'cerveau', 'cesser', 'chagrin', 'chaise', 'chaleur', 'chambre', 'chance', 'chapitre', 'charbon', 'chasseur', 'chaton', 'chausson', 'chavirer', 'chemise', 'chenille', 'chéquier', 'chercher', 'cheval', 'chien', 'chiffre', 'chignon', 'chimère', 'chiot', 'chlorure', 'chocolat', 'choisir', 'chose', 'chouette', 'chrome', 'chute', 'cigare', 'cigogne', 'cimenter', 'cinéma', 'cintrer', 'circuler', 'cirer', 'cirque', 'citerne', 'citoyen', 'citron', 'civil', 'clairon', 'clameur', 'claquer', 'classe', 'clavier', 'client', 'cligner', 'climat', 'clivage', 'cloche', 'clonage', 'cloporte', 'cobalt', 'cobra', 'cocasse', 'cocotier', 'coder', 'codifier', 'coffre', 'cogner', 'cohésion', 'coiffer', 'coincer', 'colère', 'colibri', 'colline', 'colmater', 'colonel', 'combat', 'comédie', 'commande', 'compact', 'concert', 'conduire', 'confier', 'congeler', 'connoter', 'consonne', 'contact', 'convexe', 'copain', 'copie', 'corail', 'corbeau', 'cordage', 'corniche', 'corpus', 'correct', 'cortège', 'cosmique', 'costume', 'coton', 'coude', 'coupure', 'courage', 'couteau', 'couvrir', 'coyote', 'crabe', 'crainte', 'cravate', 'crayon', 'créature', 'créditer', 'crémeux', 'creuser', 'crevette', 'cribler', 'crier', 'cristal', 'critère', 'croire', 'croquer', 'crotale', 'crucial', 'cruel', 'crypter', 'cubique', 'cueillir', 'cuillère', 'cuisine', 'cuivre', 'culminer', 'cultiver', 'cumuler', 'cupide', 'curatif', 'curseur', 'cyanure', 'cycle', 'cylindre', 'cynique', 'daigner', 'damier', 'danger', 'danseur', 'dauphin', 'débattre', 'débiter', 'déborder', 'débrider', 'débutant', 'décaler', 'décembre', 'déchirer', 'décider', 'déclarer', 'décorer', 'décrire', 'décupler', 'dédale', 'déductif', 'déesse', 'défensif', 'défiler', 'défrayer', 'dégager', 'dégivrer', 'déglutir', 'dégrafer', 'déjeuner', 'délice', 'déloger', 'demander', 'demeurer', 'démolir', 'dénicher', 'dénouer', 'dentelle', 'dénuder', 'départ', 'dépenser', 'déphaser', 'déplacer', 'déposer', 'déranger', 'dérober', 'désastre', 'descente', 'désert', 'désigner', 'désobéir', 'dessiner', 'destrier', 'détacher', 'détester', 'détourer', 'détresse', 'devancer', 'devenir', 'deviner', 'devoir', 'diable', 'dialogue', 'diamant', 'dicter', 'différer', 'digérer', 'digital', 'digne', 'diluer', 'dimanche', 'diminuer', 'dioxyde', 'directif', 'diriger', 'discuter', 'disposer', 'dissiper', 'distance', 'divertir', 'diviser', 'docile', 'docteur', 'dogme', 'doigt', 'domaine', 'domicile', 'dompter', 'donateur', 'donjon', 'donner', 'dopamine', 'dortoir', 'dorure', 'dosage', 'doseur', 'dossier', 'dotation', 'douanier', 'double', 'douceur', 'douter', 'doyen', 'dragon', 'draper', 'dresser', 'dribbler', 'droiture', 'duperie', 'duplexe', 'durable', 'durcir', 'dynastie', 'éblouir', 'écarter', 'écharpe', 'échelle', 'éclairer', 'éclipse', 'éclore', 'écluse', 'école', 'économie', 'écorce', 'écouter', 'écraser', 'écrémer', 'écrivain', 'écrou', 'écume', 'écureuil', 'édifier', 'éduquer', 'effacer', 'effectif', 'effigie', 'effort', 'effrayer', 'effusion', 'égaliser', 'égarer', 'éjecter', 'élaborer', 'élargir', 'électron', 'élégant', 'éléphant', 'élève', 'éligible', 'élitisme', 'éloge', 'élucider', 'éluder', 'emballer', 'embellir', 'embryon', 'émeraude', 'émission', 'emmener', 'émotion', 'émouvoir', 'empereur', 'employer', 'emporter', 'emprise', 'émulsion', 'encadrer', 'enchère', 'enclave', 'encoche', 'endiguer', 'endosser', 'endroit', 'enduire', 'énergie', 'enfance', 'enfermer', 'enfouir', 'engager', 'engin', 'englober', 'énigme', 'enjamber', 'enjeu', 'enlever', 'ennemi', 'ennuyeux', 'enrichir', 'enrobage', 'enseigne', 'entasser', 'entendre', 'entier', 'entourer', 'entraver', 'énumérer', 'envahir', 'enviable', 'envoyer', 'enzyme', 'éolien', 'épaissir', 'épargne', 'épatant', 'épaule', 'épicerie', 'épidémie', 'épier', 'épilogue', 'épine', 'épisode', 'épitaphe', 'époque', 'épreuve', 'éprouver', 'épuisant', 'équerre', 'équipe', 'ériger', 'érosion', 'erreur', 'éruption', 'escalier', 'espadon', 'espèce', 'espiègle', 'espoir', 'esprit', 'esquiver', 'essayer', 'essence', 'essieu', 'essorer', 'estime', 'estomac', 'estrade', 'étagère', 'étaler', 'étanche', 'étatique', 'éteindre', 'étendoir', 'éternel', 'éthanol', 'éthique', 'ethnie', 'étirer', 'étoffer', 'étoile', 'étonnant', 'étourdir', 'étrange', 'étroit', 'étude', 'euphorie', 'évaluer', 'évasion', 'éventail', 'évidence', 'éviter', 'évolutif', 'évoquer', 'exact', 'exagérer', 'exaucer', 'exceller', 'excitant', 'exclusif', 'excuse', 'exécuter', 'exemple', 'exercer', 'exhaler', 'exhorter', 'exigence', 'exiler', 'exister', 'exotique', 'expédier', 'explorer', 'exposer', 'exprimer', 'exquis', 'extensif', 'extraire', 'exulter', 'fable', 'fabuleux', 'facette', 'facile', 'facture', 'faiblir', 'falaise', 'fameux', 'famille', 'farceur', 'farfelu', 'farine', 'farouche', 'fasciner', 'fatal', 'fatigue', 'faucon', 'fautif', 'faveur', 'favori', 'fébrile', 'féconder', 'fédérer', 'félin', 'femme', 'fémur', 'fendoir', 'féodal', 'fermer', 'féroce', 'ferveur', 'festival', 'feuille', 'feutre', 'février', 'fiasco', 'ficeler', 'fictif', 'fidèle', 'figure', 'filature', 'filetage', 'filière', 'filleul', 'filmer', 'filou', 'filtrer', 'financer', 'finir', 'fiole', 'firme', 'fissure', 'fixer', 'flairer', 'flamme', 'flasque', 'flatteur', 'fléau', 'flèche', 'fleur', 'flexion', 'flocon', 'flore', 'fluctuer', 'fluide', 'fluvial', 'folie', 'fonderie', 'fongible', 'fontaine', 'forcer', 'forgeron', 'formuler', 'fortune', 'fossile', 'foudre', 'fougère', 'fouiller', 'foulure', 'fourmi', 'fragile', 'fraise', 'franchir', 'frapper', 'frayeur', 'frégate', 'freiner', 'frelon', 'frémir', 'frénésie', 'frère', 'friable', 'friction', 'frisson', 'frivole', 'froid', 'fromage', 'frontal', 'frotter', 'fruit', 'fugitif', 'fuite', 'fureur', 'furieux', 'furtif', 'fusion', 'futur', 'gagner', 'galaxie', 'galerie', 'gambader', 'garantir', 'gardien', 'garnir', 'garrigue', 'gazelle', 'gazon', 'géant', 'gélatine', 'gélule', 'gendarme', 'général', 'génie', 'genou', 'gentil', 'géologie', 'géomètre', 'géranium', 'germe', 'gestuel', 'geyser', 'gibier', 'gicler', 'girafe', 'givre', 'glace', 'glaive', 'glisser', 'globe', 'gloire', 'glorieux', 'golfeur', 'gomme', 'gonfler', 'gorge', 'gorille', 'goudron', 'gouffre', 'goulot', 'goupille', 'gourmand', 'goutte', 'graduel', 'graffiti', 'graine', 'grand', 'grappin', 'gratuit', 'gravir', 'grenat', 'griffure', 'griller', 'grimper', 'grogner', 'gronder', 'grotte', 'groupe', 'gruger', 'grutier', 'gruyère', 'guépard', 'guerrier', 'guide', 'guimauve', 'guitare', 'gustatif', 'gymnaste', 'gyrostat', 'habitude', 'hachoir', 'halte', 'hameau', 'hangar', 'hanneton', 'haricot', 'harmonie', 'harpon', 'hasard', 'hélium', 'hématome', 'herbe', 'hérisson', 'hermine', 'héron', 'hésiter', 'heureux', 'hiberner', 'hibou', 'hilarant', 'histoire', 'hiver', 'homard', 'hommage', 'homogène', 'honneur', 'honorer', 'honteux', 'horde', 'horizon', 'horloge', 'hormone', 'horrible', 'houleux', 'housse', 'hublot', 'huileux', 'humain', 'humble', 'humide', 'humour', 'hurler', 'hydromel', 'hygiène', 'hymne', 'hypnose', 'idylle', 'ignorer', 'iguane', 'illicite', 'illusion', 'image', 'imbiber', 'imiter', 'immense', 'immobile', 'immuable', 'impact', 'impérial', 'implorer', 'imposer', 'imprimer', 'imputer', 'incarner', 'incendie', 'incident', 'incliner', 'incolore', 'indexer', 'indice', 'inductif', 'inédit', 'ineptie', 'inexact', 'infini', 'infliger', 'informer', 'infusion', 'ingérer', 'inhaler', 'inhiber', 'injecter', 'injure', 'innocent', 'inoculer', 'inonder', 'inscrire', 'insecte', 'insigne', 'insolite', 'inspirer', 'instinct', 'insulter', 'intact', 'intense', 'intime', 'intrigue', 'intuitif', 'inutile', 'invasion', 'inventer', 'inviter', 'invoquer', 'ironique', 'irradier', 'irréel', 'irriter', 'isoler', 'ivoire', 'ivresse', 'jaguar', 'jaillir', 'jambe', 'janvier', 'jardin', 'jauger', 'jaune', 'javelot', 'jetable', 'jeton', 'jeudi', 'jeunesse', 'joindre', 'joncher', 'jongler', 'joueur', 'jouissif', 'journal', 'jovial', 'joyau', 'joyeux', 'jubiler', 'jugement', 'junior', 'jupon', 'juriste', 'justice', 'juteux', 'juvénile', 'kayak', 'kimono', 'kiosque', 'label', 'labial', 'labourer', 'lacérer', 'lactose', 'lagune', 'laine', 'laisser', 'laitier', 'lambeau', 'lamelle', 'lampe', 'lanceur', 'langage', 'lanterne', 'lapin', 'largeur', 'larme', 'laurier', 'lavabo', 'lavoir', 'lecture', 'légal', 'léger', 'légume', 'lessive', 'lettre', 'levier', 'lexique', 'lézard', 'liasse', 'libérer', 'libre', 'licence', 'licorne', 'liège', 'lièvre', 'ligature', 'ligoter', 'ligue', 'limer', 'limite', 'limonade', 'limpide', 'linéaire', 'lingot', 'lionceau', 'liquide', 'lisière', 'lister', 'lithium', 'litige', 'littoral', 'livreur', 'logique', 'lointain', 'loisir', 'lombric', 'loterie', 'louer', 'lourd', 'loutre', 'louve', 'loyal', 'lubie', 'lucide', 'lucratif', 'lueur', 'lugubre', 'luisant', 'lumière', 'lunaire', 'lundi', 'luron', 'lutter', 'luxueux', 'machine', 'magasin', 'magenta', 'magique', 'maigre', 'maillon', 'maintien', 'mairie', 'maison', 'majorer', 'malaxer', 'maléfice', 'malheur', 'malice', 'mallette', 'mammouth', 'mandater', 'maniable', 'manquant', 'manteau', 'manuel', 'marathon', 'marbre', 'marchand', 'mardi', 'maritime', 'marqueur', 'marron', 'marteler', 'mascotte', 'massif', 'matériel', 'matière', 'matraque', 'maudire', 'maussade', 'mauve', 'maximal', 'méchant', 'méconnu', 'médaille', 'médecin', 'méditer', 'méduse', 'meilleur', 'mélange', 'mélodie', 'membre', 'mémoire', 'menacer', 'mener', 'menhir', 'mensonge', 'mentor', 'mercredi', 'mérite', 'merle', 'messager', 'mesure', 'métal', 'météore', 'méthode', 'métier', 'meuble', 'miauler', 'microbe', 'miette', 'mignon', 'migrer', 'milieu', 'million', 'mimique', 'mince', 'minéral', 'minimal', 'minorer', 'minute', 'miracle', 'miroiter', 'missile', 'mixte', 'mobile', 'moderne', 'moelleux', 'mondial', 'moniteur', 'monnaie', 'monotone', 'monstre', 'montagne', 'monument', 'moqueur', 'morceau', 'morsure', 'mortier', 'moteur', 'motif', 'mouche', 'moufle', 'moulin', 'mousson', 'mouton', 'mouvant', 'multiple', 'munition', 'muraille', 'murène', 'murmure', 'muscle', 'muséum', 'musicien', 'mutation', 'muter', 'mutuel', 'myriade', 'myrtille', 'mystère', 'mythique', 'nageur', 'nappe', 'narquois', 'narrer', 'natation', 'nation', 'nature', 'naufrage', 'nautique', 'navire', 'nébuleux', 'nectar', 'néfaste', 'négation', 'négliger', 'négocier', 'neige', 'nerveux', 'nettoyer', 'neurone', 'neutron', 'neveu', 'niche', 'nickel', 'nitrate', 'niveau', 'noble', 'nocif', 'nocturne', 'noirceur', 'noisette', 'nomade', 'nombreux', 'nommer', 'normatif', 'notable', 'notifier', 'notoire', 'nourrir', 'nouveau', 'novateur', 'novembre', 'novice', 'nuage', 'nuancer', 'nuire', 'nuisible', 'numéro', 'nuptial', 'nuque', 'nutritif', 'obéir', 'objectif', 'obliger', 'obscur', 'observer', 'obstacle', 'obtenir', 'obturer', 'occasion', 'occuper', 'océan', 'octobre', 'octroyer', 'octupler', 'oculaire', 'odeur', 'odorant', 'offenser', 'officier', 'offrir', 'ogive', 'oiseau', 'oisillon', 'olfactif', 'olivier', 'ombrage', 'omettre', 'onctueux', 'onduler', 'onéreux', 'onirique', 'opale', 'opaque', 'opérer', 'opinion', 'opportun', 'opprimer', 'opter', 'optique', 'orageux', 'orange', 'orbite', 'ordonner', 'oreille', 'organe', 'orgueil', 'orifice', 'ornement', 'orque', 'ortie', 'osciller', 'osmose', 'ossature', 'otarie', 'ouragan', 'ourson', 'outil', 'outrager', 'ouvrage', 'ovation', 'oxyde', 'oxygène', 'ozone', 'paisible', 'palace', 'palmarès', 'palourde', 'palper', 'panache', 'panda', 'pangolin', 'paniquer', 'panneau', 'panorama', 'pantalon', 'papaye', 'papier', 'papoter', 'papyrus', 'paradoxe', 'parcelle', 'paresse', 'parfumer', 'parler', 'parole', 'parrain', 'parsemer', 'partager', 'parure', 'parvenir', 'passion', 'pastèque', 'paternel', 'patience', 'patron', 'pavillon', 'pavoiser', 'payer', 'paysage', 'peigne', 'peintre', 'pelage', 'pélican', 'pelle', 'pelouse', 'peluche', 'pendule', 'pénétrer', 'pénible', 'pensif', 'pénurie', 'pépite', 'péplum', 'perdrix', 'perforer', 'période', 'permuter', 'perplexe', 'persil', 'perte', 'peser', 'pétale', 'petit', 'pétrir', 'peuple', 'pharaon', 'phobie', 'phoque', 'photon', 'phrase', 'physique', 'piano', 'pictural', 'pièce', 'pierre', 'pieuvre', 'pilote', 'pinceau', 'pipette', 'piquer', 'pirogue', 'piscine', 'piston', 'pivoter', 'pixel', 'pizza', 'placard', 'plafond', 'plaisir', 'planer', 'plaque', 'plastron', 'plateau', 'pleurer', 'plexus', 'pliage', 'plomb', 'plonger', 'pluie', 'plumage', 'pochette', 'poésie', 'poète', 'pointe', 'poirier', 'poisson', 'poivre', 'polaire', 'policier', 'pollen', 'polygone', 'pommade', 'pompier', 'ponctuel', 'pondérer', 'poney', 'portique', 'position', 'posséder', 'posture', 'potager', 'poteau', 'potion', 'pouce', 'poulain', 'poumon', 'pourpre', 'poussin', 'pouvoir', 'prairie', 'pratique', 'précieux', 'prédire', 'préfixe', 'prélude', 'prénom', 'présence', 'prétexte', 'prévoir', 'primitif', 'prince', 'prison', 'priver', 'problème', 'procéder', 'prodige', 'profond', 'progrès', 'proie', 'projeter', 'prologue', 'promener', 'propre', 'prospère', 'protéger', 'prouesse', 'proverbe', 'prudence', 'pruneau', 'psychose', 'public', 'puceron', 'puiser', 'pulpe', 'pulsar', 'punaise', 'punitif', 'pupitre', 'purifier', 'puzzle', 'pyramide', 'quasar', 'querelle', 'question', 'quiétude', 'quitter', 'quotient', 'racine', 'raconter', 'radieux', 'ragondin', 'raideur', 'raisin', 'ralentir', 'rallonge', 'ramasser', 'rapide', 'rasage', 'ratisser', 'ravager', 'ravin', 'rayonner', 'réactif', 'réagir', 'réaliser', 'réanimer', 'recevoir', 'réciter', 'réclamer', 'récolter', 'recruter', 'reculer', 'recycler', 'rédiger', 'redouter', 'refaire', 'réflexe', 'réformer', 'refrain', 'refuge', 'régalien', 'région', 'réglage', 'régulier', 'réitérer', 'rejeter', 'rejouer', 'relatif', 'relever', 'relief', 'remarque', 'remède', 'remise', 'remonter', 'remplir', 'remuer', 'renard', 'renfort', 'renifler', 'renoncer', 'rentrer', 'renvoi', 'replier', 'reporter', 'reprise', 'reptile', 'requin', 'réserve', 'résineux', 'résoudre', 'respect', 'rester', 'résultat', 'rétablir', 'retenir', 'réticule', 'retomber', 'retracer', 'réunion', 'réussir', 'revanche', 'revivre', 'révolte', 'révulsif', 'richesse', 'rideau', 'rieur', 'rigide', 'rigoler', 'rincer', 'riposter', 'risible', 'risque', 'rituel', 'rival', 'rivière', 'rocheux', 'romance', 'rompre', 'ronce', 'rondin', 'roseau', 'rosier', 'rotatif', 'rotor', 'rotule', 'rouge', 'rouille', 'rouleau', 'routine', 'royaume', 'ruban', 'rubis', 'ruche', 'ruelle', 'rugueux', 'ruiner', 'ruisseau', 'ruser', 'rustique', 'rythme', 'sabler', 'saboter', 'sabre', 'sacoche', 'safari', 'sagesse', 'saisir', 'salade', 'salive', 'salon', 'saluer', 'samedi', 'sanction', 'sanglier', 'sarcasme', 'sardine', 'saturer', 'saugrenu', 'saumon', 'sauter', 'sauvage', 'savant', 'savonner', 'scalpel', 'scandale', 'scélérat', 'scénario', 'sceptre', 'schéma', 'science', 'scinder', 'score', 'scrutin', 'sculpter', 'séance', 'sécable', 'sécher', 'secouer', 'sécréter', 'sédatif', 'séduire', 'seigneur', 'séjour', 'sélectif', 'semaine', 'sembler', 'semence', 'séminal', 'sénateur', 'sensible', 'sentence', 'séparer', 'séquence', 'serein', 'sergent', 'sérieux', 'serrure', 'sérum', 'service', 'sésame', 'sévir', 'sevrage', 'sextuple', 'sidéral', 'siècle', 'siéger', 'siffler', 'sigle', 'signal', 'silence', 'silicium', 'simple', 'sincère', 'sinistre', 'siphon', 'sirop', 'sismique', 'situer', 'skier', 'social', 'socle', 'sodium', 'soigneux', 'soldat', 'soleil', 'solitude', 'soluble', 'sombre', 'sommeil', 'somnoler', 'sonde', 'songeur', 'sonnette', 'sonore', 'sorcier', 'sortir', 'sosie', 'sottise', 'soucieux', 'soudure', 'souffle', 'soulever', 'soupape', 'source', 'soutirer', 'souvenir', 'spacieux', 'spatial', 'spécial', 'sphère', 'spiral', 'stable', 'station', 'sternum', 'stimulus', 'stipuler', 'strict', 'studieux', 'stupeur', 'styliste', 'sublime', 'substrat', 'subtil', 'subvenir', 'succès', 'sucre', 'suffixe', 'suggérer', 'suiveur', 'sulfate', 'superbe', 'supplier', 'surface', 'suricate', 'surmener', 'surprise', 'sursaut', 'survie', 'suspect', 'syllabe', 'symbole', 'symétrie', 'synapse', 'syntaxe', 'système', 'tabac', 'tablier', 'tactile', 'tailler', 'talent', 'talisman', 'talonner', 'tambour', 'tamiser', 'tangible', 'tapis', 'taquiner', 'tarder', 'tarif', 'tartine', 'tasse', 'tatami', 'tatouage', 'taupe', 'taureau', 'taxer', 'témoin', 'temporel', 'tenaille', 'tendre', 'teneur', 'tenir', 'tension', 'terminer', 'terne', 'terrible', 'tétine', 'texte', 'thème', 'théorie', 'thérapie', 'thorax', 'tibia', 'tiède', 'timide', 'tirelire', 'tiroir', 'tissu', 'titane', 'titre', 'tituber', 'toboggan', 'tolérant', 'tomate', 'tonique', 'tonneau', 'toponyme', 'torche', 'tordre', 'tornade', 'torpille', 'torrent', 'torse', 'tortue', 'totem', 'toucher', 'tournage', 'tousser', 'toxine', 'traction', 'trafic', 'tragique', 'trahir', 'train', 'trancher', 'travail', 'trèfle', 'tremper', 'trésor', 'treuil', 'triage', 'tribunal', 'tricoter', 'trilogie', 'triomphe', 'tripler', 'triturer', 'trivial', 'trombone', 'tronc', 'tropical', 'troupeau', 'tuile', 'tulipe', 'tumulte', 'tunnel', 'turbine', 'tuteur', 'tutoyer', 'tuyau', 'tympan', 'typhon', 'typique', 'tyran', 'ubuesque', 'ultime', 'ultrason', 'unanime', 'unifier', 'union', 'unique', 'unitaire', 'univers', 'uranium', 'urbain', 'urticant', 'usage', 'usine', 'usuel', 'usure', 'utile', 'utopie', 'vacarme', 'vaccin', 'vagabond', 'vague', 'vaillant', 'vaincre', 'vaisseau', 'valable', 'valise', 'vallon', 'valve', 'vampire', 'vanille', 'vapeur', 'varier', 'vaseux', 'vassal', 'vaste', 'vecteur', 'vedette', 'végétal', 'véhicule', 'veinard', 'véloce', 'vendredi', 'vénérer', 'venger', 'venimeux', 'ventouse', 'verdure', 'vérin', 'vernir', 'verrou', 'verser', 'vertu', 'veston', 'vétéran', 'vétuste', 'vexant', 'vexer', 'viaduc', 'viande', 'victoire', 'vidange', 'vidéo', 'vignette', 'vigueur', 'vilain', 'village', 'vinaigre', 'violon', 'vipère', 'virement', 'virtuose', 'virus', 'visage', 'viseur', 'vision', 'visqueux', 'visuel', 'vital', 'vitesse', 'viticole', 'vitrine', 'vivace', 'vivipare', 'vocation', 'voguer', 'voile', 'voisin', 'voiture', 'volaille', 'volcan', 'voltiger', 'volume', 'vorace', 'vortex', 'voter', 'vouloir', 'voyage', 'voyelle', 'wagon', 'xénon', 'yacht', 'zèbre', 'zénith', 'zeste', 'zoologie']
    
    module.exports = french
    
    },{}],240:[function(require,module,exports){
    module.exports = {
      'CHINESE': require('./chinese'),
      'ENGLISH': require('./english'),
      'FRENCH': require('./french'),
      'ITALIAN': require('./italian'),
      'JAPANESE': require('./japanese'),
      'SPANISH': require('./spanish')
    }
    
    },{"./chinese":237,"./english":238,"./french":239,"./italian":241,"./japanese":242,"./spanish":243}],241:[function(require,module,exports){
    'use strict'
    
    var italian = ['abaco', 'abbaglio', 'abbinato', 'abete', 'abisso', 'abolire', 'abrasivo', 'abrogato', 'accadere', 'accenno', 'accusato', 'acetone', 'achille', 'acido', 'acqua', 'acre', 'acrilico', 'acrobata', 'acuto', 'adagio', 'addebito', 'addome', 'adeguato', 'aderire', 'adipe', 'adottare', 'adulare', 'affabile', 'affetto', 'affisso', 'affranto', 'aforisma', 'afoso', 'africano', 'agave', 'agente', 'agevole', 'aggancio', 'agire', 'agitare', 'agonismo', 'agricolo', 'agrumeto', 'aguzzo', 'alabarda', 'alato', 'albatro', 'alberato', 'albo', 'albume', 'alce', 'alcolico', 'alettone', 'alfa', 'algebra', 'aliante', 'alibi', 'alimento', 'allagato', 'allegro', 'allievo', 'allodola', 'allusivo', 'almeno', 'alogeno', 'alpaca', 'alpestre', 'altalena', 'alterno', 'alticcio', 'altrove', 'alunno', 'alveolo', 'alzare', 'amalgama', 'amanita', 'amarena', 'ambito', 'ambrato', 'ameba', 'america', 'ametista', 'amico', 'ammasso', 'ammenda', 'ammirare', 'ammonito', 'amore', 'ampio', 'ampliare', 'amuleto', 'anacardo', 'anagrafe', 'analista', 'anarchia', 'anatra', 'anca', 'ancella', 'ancora', 'andare', 'andrea', 'anello', 'angelo', 'angolare', 'angusto', 'anima', 'annegare', 'annidato', 'anno', 'annuncio', 'anonimo', 'anticipo', 'anzi', 'apatico', 'apertura', 'apode', 'apparire', 'appetito', 'appoggio', 'approdo', 'appunto', 'aprile', 'arabica', 'arachide', 'aragosta', 'araldica', 'arancio', 'aratura', 'arazzo', 'arbitro', 'archivio', 'ardito', 'arenile', 'argento', 'argine', 'arguto', 'aria', 'armonia', 'arnese', 'arredato', 'arringa', 'arrosto', 'arsenico', 'arso', 'artefice', 'arzillo', 'asciutto', 'ascolto', 'asepsi', 'asettico', 'asfalto', 'asino', 'asola', 'aspirato', 'aspro', 'assaggio', 'asse', 'assoluto', 'assurdo', 'asta', 'astenuto', 'astice', 'astratto', 'atavico', 'ateismo', 'atomico', 'atono', 'attesa', 'attivare', 'attorno', 'attrito', 'attuale', 'ausilio', 'austria', 'autista', 'autonomo', 'autunno', 'avanzato', 'avere', 'avvenire', 'avviso', 'avvolgere', 'azione', 'azoto', 'azzimo', 'azzurro', 'babele', 'baccano', 'bacino', 'baco', 'badessa', 'badilata', 'bagnato', 'baita', 'balcone', 'baldo', 'balena', 'ballata', 'balzano', 'bambino', 'bandire', 'baraonda', 'barbaro', 'barca', 'baritono', 'barlume', 'barocco', 'basilico', 'basso', 'batosta', 'battuto', 'baule', 'bava', 'bavosa', 'becco', 'beffa', 'belgio', 'belva', 'benda', 'benevole', 'benigno', 'benzina', 'bere', 'berlina', 'beta', 'bibita', 'bici', 'bidone', 'bifido', 'biga', 'bilancia', 'bimbo', 'binocolo', 'biologo', 'bipede', 'bipolare', 'birbante', 'birra', 'biscotto', 'bisesto', 'bisnonno', 'bisonte', 'bisturi', 'bizzarro', 'blando', 'blatta', 'bollito', 'bonifico', 'bordo', 'bosco', 'botanico', 'bottino', 'bozzolo', 'braccio', 'bradipo', 'brama', 'branca', 'bravura', 'bretella', 'brevetto', 'brezza', 'briglia', 'brillante', 'brindare', 'broccolo', 'brodo', 'bronzina', 'brullo', 'bruno', 'bubbone', 'buca', 'budino', 'buffone', 'buio', 'bulbo', 'buono', 'burlone', 'burrasca', 'bussola', 'busta', 'cadetto', 'caduco', 'calamaro', 'calcolo', 'calesse', 'calibro', 'calmo', 'caloria', 'cambusa', 'camerata', 'camicia', 'cammino', 'camola', 'campale', 'canapa', 'candela', 'cane', 'canino', 'canotto', 'cantina', 'capace', 'capello', 'capitolo', 'capogiro', 'cappero', 'capra', 'capsula', 'carapace', 'carcassa', 'cardo', 'carisma', 'carovana', 'carretto', 'cartolina', 'casaccio', 'cascata', 'caserma', 'caso', 'cassone', 'castello', 'casuale', 'catasta', 'catena', 'catrame', 'cauto', 'cavillo', 'cedibile', 'cedrata', 'cefalo', 'celebre', 'cellulare', 'cena', 'cenone', 'centesimo', 'ceramica', 'cercare', 'certo', 'cerume', 'cervello', 'cesoia', 'cespo', 'ceto', 'chela', 'chiaro', 'chicca', 'chiedere', 'chimera', 'china', 'chirurgo', 'chitarra', 'ciao', 'ciclismo', 'cifrare', 'cigno', 'cilindro', 'ciottolo', 'circa', 'cirrosi', 'citrico', 'cittadino', 'ciuffo', 'civetta', 'civile', 'classico', 'clinica', 'cloro', 'cocco', 'codardo', 'codice', 'coerente', 'cognome', 'collare', 'colmato', 'colore', 'colposo', 'coltivato', 'colza', 'coma', 'cometa', 'commando', 'comodo', 'computer', 'comune', 'conciso', 'condurre', 'conferma', 'congelare', 'coniuge', 'connesso', 'conoscere', 'consumo', 'continuo', 'convegno', 'coperto', 'copione', 'coppia', 'copricapo', 'corazza', 'cordata', 'coricato', 'cornice', 'corolla', 'corpo', 'corredo', 'corsia', 'cortese', 'cosmico', 'costante', 'cottura', 'covato', 'cratere', 'cravatta', 'creato', 'credere', 'cremoso', 'crescita', 'creta', 'criceto', 'crinale', 'crisi', 'critico', 'croce', 'cronaca', 'crostata', 'cruciale', 'crusca', 'cucire', 'cuculo', 'cugino', 'cullato', 'cupola', 'curatore', 'cursore', 'curvo', 'cuscino', 'custode', 'dado', 'daino', 'dalmata', 'damerino', 'daniela', 'dannoso', 'danzare', 'datato', 'davanti', 'davvero', 'debutto', 'decennio', 'deciso', 'declino', 'decollo', 'decreto', 'dedicato', 'definito', 'deforme', 'degno', 'delegare', 'delfino', 'delirio', 'delta', 'demenza', 'denotato', 'dentro', 'deposito', 'derapata', 'derivare', 'deroga', 'descritto', 'deserto', 'desiderio', 'desumere', 'detersivo', 'devoto', 'diametro', 'dicembre', 'diedro', 'difeso', 'diffuso', 'digerire', 'digitale', 'diluvio', 'dinamico', 'dinnanzi', 'dipinto', 'diploma', 'dipolo', 'diradare', 'dire', 'dirotto', 'dirupo', 'disagio', 'discreto', 'disfare', 'disgelo', 'disposto', 'distanza', 'disumano', 'dito', 'divano', 'divelto', 'dividere', 'divorato', 'doblone', 'docente', 'doganale', 'dogma', 'dolce', 'domato', 'domenica', 'dominare', 'dondolo', 'dono', 'dormire', 'dote', 'dottore', 'dovuto', 'dozzina', 'drago', 'druido', 'dubbio', 'dubitare', 'ducale', 'duna', 'duomo', 'duplice', 'duraturo', 'ebano', 'eccesso', 'ecco', 'eclissi', 'economia', 'edera', 'edicola', 'edile', 'editoria', 'educare', 'egemonia', 'egli', 'egoismo', 'egregio', 'elaborato', 'elargire', 'elegante', 'elencato', 'eletto', 'elevare', 'elfico', 'elica', 'elmo', 'elsa', 'eluso', 'emanato', 'emblema', 'emesso', 'emiro', 'emotivo', 'emozione', 'empirico', 'emulo', 'endemico', 'enduro', 'energia', 'enfasi', 'enoteca', 'entrare', 'enzima', 'epatite', 'epilogo', 'episodio', 'epocale', 'eppure', 'equatore', 'erario', 'erba', 'erboso', 'erede', 'eremita', 'erigere', 'ermetico', 'eroe', 'erosivo', 'errante', 'esagono', 'esame', 'esanime', 'esaudire', 'esca', 'esempio', 'esercito', 'esibito', 'esigente', 'esistere', 'esito', 'esofago', 'esortato', 'esoso', 'espanso', 'espresso', 'essenza', 'esso', 'esteso', 'estimare', 'estonia', 'estroso', 'esultare', 'etilico', 'etnico', 'etrusco', 'etto', 'euclideo', 'europa', 'evaso', 'evidenza', 'evitato', 'evoluto', 'evviva', 'fabbrica', 'faccenda', 'fachiro', 'falco', 'famiglia', 'fanale', 'fanfara', 'fango', 'fantasma', 'fare', 'farfalla', 'farinoso', 'farmaco', 'fascia', 'fastoso', 'fasullo', 'faticare', 'fato', 'favoloso', 'febbre', 'fecola', 'fede', 'fegato', 'felpa', 'feltro', 'femmina', 'fendere', 'fenomeno', 'fermento', 'ferro', 'fertile', 'fessura', 'festivo', 'fetta', 'feudo', 'fiaba', 'fiducia', 'fifa', 'figurato', 'filo', 'finanza', 'finestra', 'finire', 'fiore', 'fiscale', 'fisico', 'fiume', 'flacone', 'flamenco', 'flebo', 'flemma', 'florido', 'fluente', 'fluoro', 'fobico', 'focaccia', 'focoso', 'foderato', 'foglio', 'folata', 'folclore', 'folgore', 'fondente', 'fonetico', 'fonia', 'fontana', 'forbito', 'forchetta', 'foresta', 'formica', 'fornaio', 'foro', 'fortezza', 'forzare', 'fosfato', 'fosso', 'fracasso', 'frana', 'frassino', 'fratello', 'freccetta', 'frenata', 'fresco', 'frigo', 'frollino', 'fronde', 'frugale', 'frutta', 'fucilata', 'fucsia', 'fuggente', 'fulmine', 'fulvo', 'fumante', 'fumetto', 'fumoso', 'fune', 'funzione', 'fuoco', 'furbo', 'furgone', 'furore', 'fuso', 'futile', 'gabbiano', 'gaffe', 'galateo', 'gallina', 'galoppo', 'gambero', 'gamma', 'garanzia', 'garbo', 'garofano', 'garzone', 'gasdotto', 'gasolio', 'gastrico', 'gatto', 'gaudio', 'gazebo', 'gazzella', 'geco', 'gelatina', 'gelso', 'gemello', 'gemmato', 'gene', 'genitore', 'gennaio', 'genotipo', 'gergo', 'ghepardo', 'ghiaccio', 'ghisa', 'giallo', 'gilda', 'ginepro', 'giocare', 'gioiello', 'giorno', 'giove', 'girato', 'girone', 'gittata', 'giudizio', 'giurato', 'giusto', 'globulo', 'glutine', 'gnomo', 'gobba', 'golf', 'gomito', 'gommone', 'gonfio', 'gonna', 'governo', 'gracile', 'grado', 'grafico', 'grammo', 'grande', 'grattare', 'gravoso', 'grazia', 'greca', 'gregge', 'grifone', 'grigio', 'grinza', 'grotta', 'gruppo', 'guadagno', 'guaio', 'guanto', 'guardare', 'gufo', 'guidare', 'ibernato', 'icona', 'identico', 'idillio', 'idolo', 'idra', 'idrico', 'idrogeno', 'igiene', 'ignaro', 'ignorato', 'ilare', 'illeso', 'illogico', 'illudere', 'imballo', 'imbevuto', 'imbocco', 'imbuto', 'immane', 'immerso', 'immolato', 'impacco', 'impeto', 'impiego', 'importo', 'impronta', 'inalare', 'inarcare', 'inattivo', 'incanto', 'incendio', 'inchino', 'incisivo', 'incluso', 'incontro', 'incrocio', 'incubo', 'indagine', 'india', 'indole', 'inedito', 'infatti', 'infilare', 'inflitto', 'ingaggio', 'ingegno', 'inglese', 'ingordo', 'ingrosso', 'innesco', 'inodore', 'inoltrare', 'inondato', 'insano', 'insetto', 'insieme', 'insonnia', 'insulina', 'intasato', 'intero', 'intonaco', 'intuito', 'inumidire', 'invalido', 'invece', 'invito', 'iperbole', 'ipnotico', 'ipotesi', 'ippica', 'iride', 'irlanda', 'ironico', 'irrigato', 'irrorare', 'isolato', 'isotopo', 'isterico', 'istituto', 'istrice', 'italia', 'iterare', 'labbro', 'labirinto', 'lacca', 'lacerato', 'lacrima', 'lacuna', 'laddove', 'lago', 'lampo', 'lancetta', 'lanterna', 'lardoso', 'larga', 'laringe', 'lastra', 'latenza', 'latino', 'lattuga', 'lavagna', 'lavoro', 'legale', 'leggero', 'lembo', 'lentezza', 'lenza', 'leone', 'lepre', 'lesivo', 'lessato', 'lesto', 'letterale', 'leva', 'levigato', 'libero', 'lido', 'lievito', 'lilla', 'limatura', 'limitare', 'limpido', 'lineare', 'lingua', 'liquido', 'lira', 'lirica', 'lisca', 'lite', 'litigio', 'livrea', 'locanda', 'lode', 'logica', 'lombare', 'londra', 'longevo', 'loquace', 'lorenzo', 'loto', 'lotteria', 'luce', 'lucidato', 'lumaca', 'luminoso', 'lungo', 'lupo', 'luppolo', 'lusinga', 'lusso', 'lutto', 'macabro', 'macchina', 'macero', 'macinato', 'madama', 'magico', 'maglia', 'magnete', 'magro', 'maiolica', 'malafede', 'malgrado', 'malinteso', 'malsano', 'malto', 'malumore', 'mana', 'mancia', 'mandorla', 'mangiare', 'manifesto', 'mannaro', 'manovra', 'mansarda', 'mantide', 'manubrio', 'mappa', 'maratona', 'marcire', 'maretta', 'marmo', 'marsupio', 'maschera', 'massaia', 'mastino', 'materasso', 'matricola', 'mattone', 'maturo', 'mazurca', 'meandro', 'meccanico', 'mecenate', 'medesimo', 'meditare', 'mega', 'melassa', 'melis', 'melodia', 'meninge', 'meno', 'mensola', 'mercurio', 'merenda', 'merlo', 'meschino', 'mese', 'messere', 'mestolo', 'metallo', 'metodo', 'mettere', 'miagolare', 'mica', 'micelio', 'michele', 'microbo', 'midollo', 'miele', 'migliore', 'milano', 'milite', 'mimosa', 'minerale', 'mini', 'minore', 'mirino', 'mirtillo', 'miscela', 'missiva', 'misto', 'misurare', 'mitezza', 'mitigare', 'mitra', 'mittente', 'mnemonico', 'modello', 'modifica', 'modulo', 'mogano', 'mogio', 'mole', 'molosso', 'monastero', 'monco', 'mondina', 'monetario', 'monile', 'monotono', 'monsone', 'montato', 'monviso', 'mora', 'mordere', 'morsicato', 'mostro', 'motivato', 'motosega', 'motto', 'movenza', 'movimento', 'mozzo', 'mucca', 'mucosa', 'muffa', 'mughetto', 'mugnaio', 'mulatto', 'mulinello', 'multiplo', 'mummia', 'munto', 'muovere', 'murale', 'musa', 'muscolo', 'musica', 'mutevole', 'muto', 'nababbo', 'nafta', 'nanometro', 'narciso', 'narice', 'narrato', 'nascere', 'nastrare', 'naturale', 'nautica', 'naviglio', 'nebulosa', 'necrosi', 'negativo', 'negozio', 'nemmeno', 'neofita', 'neretto', 'nervo', 'nessuno', 'nettuno', 'neutrale', 'neve', 'nevrotico', 'nicchia', 'ninfa', 'nitido', 'nobile', 'nocivo', 'nodo', 'nome', 'nomina', 'nordico', 'normale', 'norvegese', 'nostrano', 'notare', 'notizia', 'notturno', 'novella', 'nucleo', 'nulla', 'numero', 'nuovo', 'nutrire', 'nuvola', 'nuziale', 'oasi', 'obbedire', 'obbligo', 'obelisco', 'oblio', 'obolo', 'obsoleto', 'occasione', 'occhio', 'occidente', 'occorrere', 'occultare', 'ocra', 'oculato', 'odierno', 'odorare', 'offerta', 'offrire', 'offuscato', 'oggetto', 'oggi', 'ognuno', 'olandese', 'olfatto', 'oliato', 'oliva', 'ologramma', 'oltre', 'omaggio', 'ombelico', 'ombra', 'omega', 'omissione', 'ondoso', 'onere', 'onice', 'onnivoro', 'onorevole', 'onta', 'operato', 'opinione', 'opposto', 'oracolo', 'orafo', 'ordine', 'orecchino', 'orefice', 'orfano', 'organico', 'origine', 'orizzonte', 'orma', 'ormeggio', 'ornativo', 'orologio', 'orrendo', 'orribile', 'ortensia', 'ortica', 'orzata', 'orzo', 'osare', 'oscurare', 'osmosi', 'ospedale', 'ospite', 'ossa', 'ossidare', 'ostacolo', 'oste', 'otite', 'otre', 'ottagono', 'ottimo', 'ottobre', 'ovale', 'ovest', 'ovino', 'oviparo', 'ovocito', 'ovunque', 'ovviare', 'ozio', 'pacchetto', 'pace', 'pacifico', 'padella', 'padrone', 'paese', 'paga', 'pagina', 'palazzina', 'palesare', 'pallido', 'palo', 'palude', 'pandoro', 'pannello', 'paolo', 'paonazzo', 'paprica', 'parabola', 'parcella', 'parere', 'pargolo', 'pari', 'parlato', 'parola', 'partire', 'parvenza', 'parziale', 'passivo', 'pasticca', 'patacca', 'patologia', 'pattume', 'pavone', 'peccato', 'pedalare', 'pedonale', 'peggio', 'peloso', 'penare', 'pendice', 'penisola', 'pennuto', 'penombra', 'pensare', 'pentola', 'pepe', 'pepita', 'perbene', 'percorso', 'perdonato', 'perforare', 'pergamena', 'periodo', 'permesso', 'perno', 'perplesso', 'persuaso', 'pertugio', 'pervaso', 'pesatore', 'pesista', 'peso', 'pestifero', 'petalo', 'pettine', 'petulante', 'pezzo', 'piacere', 'pianta', 'piattino', 'piccino', 'picozza', 'piega', 'pietra', 'piffero', 'pigiama', 'pigolio', 'pigro', 'pila', 'pilifero', 'pillola', 'pilota', 'pimpante', 'pineta', 'pinna', 'pinolo', 'pioggia', 'piombo', 'piramide', 'piretico', 'pirite', 'pirolisi', 'pitone', 'pizzico', 'placebo', 'planare', 'plasma', 'platano', 'plenario', 'pochezza', 'poderoso', 'podismo', 'poesia', 'poggiare', 'polenta', 'poligono', 'pollice', 'polmonite', 'polpetta', 'polso', 'poltrona', 'polvere', 'pomice', 'pomodoro', 'ponte', 'popoloso', 'porfido', 'poroso', 'porpora', 'porre', 'portata', 'posa', 'positivo', 'possesso', 'postulato', 'potassio', 'potere', 'pranzo', 'prassi', 'pratica', 'precluso', 'predica', 'prefisso', 'pregiato', 'prelievo', 'premere', 'prenotare', 'preparato', 'presenza', 'pretesto', 'prevalso', 'prima', 'principe', 'privato', 'problema', 'procura', 'produrre', 'profumo', 'progetto', 'prolunga', 'promessa', 'pronome', 'proposta', 'proroga', 'proteso', 'prova', 'prudente', 'prugna', 'prurito', 'psiche', 'pubblico', 'pudica', 'pugilato', 'pugno', 'pulce', 'pulito', 'pulsante', 'puntare', 'pupazzo', 'pupilla', 'puro', 'quadro', 'qualcosa', 'quasi', 'querela', 'quota', 'raccolto', 'raddoppio', 'radicale', 'radunato', 'raffica', 'ragazzo', 'ragione', 'ragno', 'ramarro', 'ramingo', 'ramo', 'randagio', 'rantolare', 'rapato', 'rapina', 'rappreso', 'rasatura', 'raschiato', 'rasente', 'rassegna', 'rastrello', 'rata', 'ravveduto', 'reale', 'recepire', 'recinto', 'recluta', 'recondito', 'recupero', 'reddito', 'redimere', 'regalato', 'registro', 'regola', 'regresso', 'relazione', 'remare', 'remoto', 'renna', 'replica', 'reprimere', 'reputare', 'resa', 'residente', 'responso', 'restauro', 'rete', 'retina', 'retorica', 'rettifica', 'revocato', 'riassunto', 'ribadire', 'ribelle', 'ribrezzo', 'ricarica', 'ricco', 'ricevere', 'riciclato', 'ricordo', 'ricreduto', 'ridicolo', 'ridurre', 'rifasare', 'riflesso', 'riforma', 'rifugio', 'rigare', 'rigettato', 'righello', 'rilassato', 'rilevato', 'rimanere', 'rimbalzo', 'rimedio', 'rimorchio', 'rinascita', 'rincaro', 'rinforzo', 'rinnovo', 'rinomato', 'rinsavito', 'rintocco', 'rinuncia', 'rinvenire', 'riparato', 'ripetuto', 'ripieno', 'riportare', 'ripresa', 'ripulire', 'risata', 'rischio', 'riserva', 'risibile', 'riso', 'rispetto', 'ristoro', 'risultato', 'risvolto', 'ritardo', 'ritegno', 'ritmico', 'ritrovo', 'riunione', 'riva', 'riverso', 'rivincita', 'rivolto', 'rizoma', 'roba', 'robotico', 'robusto', 'roccia', 'roco', 'rodaggio', 'rodere', 'roditore', 'rogito', 'rollio', 'romantico', 'rompere', 'ronzio', 'rosolare', 'rospo', 'rotante', 'rotondo', 'rotula', 'rovescio', 'rubizzo', 'rubrica', 'ruga', 'rullino', 'rumine', 'rumoroso', 'ruolo', 'rupe', 'russare', 'rustico', 'sabato', 'sabbiare', 'sabotato', 'sagoma', 'salasso', 'saldatura', 'salgemma', 'salivare', 'salmone', 'salone', 'saltare', 'saluto', 'salvo', 'sapere', 'sapido', 'saporito', 'saraceno', 'sarcasmo', 'sarto', 'sassoso', 'satellite', 'satira', 'satollo', 'saturno', 'savana', 'savio', 'saziato', 'sbadiglio', 'sbalzo', 'sbancato', 'sbarra', 'sbattere', 'sbavare', 'sbendare', 'sbirciare', 'sbloccato', 'sbocciato', 'sbrinare', 'sbruffone', 'sbuffare', 'scabroso', 'scadenza', 'scala', 'scambiare', 'scandalo', 'scapola', 'scarso', 'scatenare', 'scavato', 'scelto', 'scenico', 'scettro', 'scheda', 'schiena', 'sciarpa', 'scienza', 'scindere', 'scippo', 'sciroppo', 'scivolo', 'sclerare', 'scodella', 'scolpito', 'scomparto', 'sconforto', 'scoprire', 'scorta', 'scossone', 'scozzese', 'scriba', 'scrollare', 'scrutinio', 'scuderia', 'scultore', 'scuola', 'scuro', 'scusare', 'sdebitare', 'sdoganare', 'seccatura', 'secondo', 'sedano', 'seggiola', 'segnalato', 'segregato', 'seguito', 'selciato', 'selettivo', 'sella', 'selvaggio', 'semaforo', 'sembrare', 'seme', 'seminato', 'sempre', 'senso', 'sentire', 'sepolto', 'sequenza', 'serata', 'serbato', 'sereno', 'serio', 'serpente', 'serraglio', 'servire', 'sestina', 'setola', 'settimana', 'sfacelo', 'sfaldare', 'sfamato', 'sfarzoso', 'sfaticato', 'sfera', 'sfida', 'sfilato', 'sfinge', 'sfocato', 'sfoderare', 'sfogo', 'sfoltire', 'sforzato', 'sfratto', 'sfruttato', 'sfuggito', 'sfumare', 'sfuso', 'sgabello', 'sgarbato', 'sgonfiare', 'sgorbio', 'sgrassato', 'sguardo', 'sibilo', 'siccome', 'sierra', 'sigla', 'signore', 'silenzio', 'sillaba', 'simbolo', 'simpatico', 'simulato', 'sinfonia', 'singolo', 'sinistro', 'sino', 'sintesi', 'sinusoide', 'sipario', 'sisma', 'sistole', 'situato', 'slitta', 'slogatura', 'sloveno', 'smarrito', 'smemorato', 'smentito', 'smeraldo', 'smilzo', 'smontare', 'smottato', 'smussato', 'snellire', 'snervato', 'snodo', 'sobbalzo', 'sobrio', 'soccorso', 'sociale', 'sodale', 'soffitto', 'sogno', 'soldato', 'solenne', 'solido', 'sollazzo', 'solo', 'solubile', 'solvente', 'somatico', 'somma', 'sonda', 'sonetto', 'sonnifero', 'sopire', 'soppeso', 'sopra', 'sorgere', 'sorpasso', 'sorriso', 'sorso', 'sorteggio', 'sorvolato', 'sospiro', 'sosta', 'sottile', 'spada', 'spalla', 'spargere', 'spatola', 'spavento', 'spazzola', 'specie', 'spedire', 'spegnere', 'spelatura', 'speranza', 'spessore', 'spettrale', 'spezzato', 'spia', 'spigoloso', 'spillato', 'spinoso', 'spirale', 'splendido', 'sportivo', 'sposo', 'spranga', 'sprecare', 'spronato', 'spruzzo', 'spuntino', 'squillo', 'sradicare', 'srotolato', 'stabile', 'stacco', 'staffa', 'stagnare', 'stampato', 'stantio', 'starnuto', 'stasera', 'statuto', 'stelo', 'steppa', 'sterzo', 'stiletto', 'stima', 'stirpe', 'stivale', 'stizzoso', 'stonato', 'storico', 'strappo', 'stregato', 'stridulo', 'strozzare', 'strutto', 'stuccare', 'stufo', 'stupendo', 'subentro', 'succoso', 'sudore', 'suggerito', 'sugo', 'sultano', 'suonare', 'superbo', 'supporto', 'surgelato', 'surrogato', 'sussurro', 'sutura', 'svagare', 'svedese', 'sveglio', 'svelare', 'svenuto', 'svezia', 'sviluppo', 'svista', 'svizzera', 'svolta', 'svuotare', 'tabacco', 'tabulato', 'tacciare', 'taciturno', 'tale', 'talismano', 'tampone', 'tannino', 'tara', 'tardivo', 'targato', 'tariffa', 'tarpare', 'tartaruga', 'tasto', 'tattico', 'taverna', 'tavolata', 'tazza', 'teca', 'tecnico', 'telefono', 'temerario', 'tempo', 'temuto', 'tendone', 'tenero', 'tensione', 'tentacolo', 'teorema', 'terme', 'terrazzo', 'terzetto', 'tesi', 'tesserato', 'testato', 'tetro', 'tettoia', 'tifare', 'tigella', 'timbro', 'tinto', 'tipico', 'tipografo', 'tiraggio', 'tiro', 'titanio', 'titolo', 'titubante', 'tizio', 'tizzone', 'toccare', 'tollerare', 'tolto', 'tombola', 'tomo', 'tonfo', 'tonsilla', 'topazio', 'topologia', 'toppa', 'torba', 'tornare', 'torrone', 'tortora', 'toscano', 'tossire', 'tostatura', 'totano', 'trabocco', 'trachea', 'trafila', 'tragedia', 'tralcio', 'tramonto', 'transito', 'trapano', 'trarre', 'trasloco', 'trattato', 'trave', 'treccia', 'tremolio', 'trespolo', 'tributo', 'tricheco', 'trifoglio', 'trillo', 'trincea', 'trio', 'tristezza', 'triturato', 'trivella', 'tromba', 'trono', 'troppo', 'trottola', 'trovare', 'truccato', 'tubatura', 'tuffato', 'tulipano', 'tumulto', 'tunisia', 'turbare', 'turchino', 'tuta', 'tutela', 'ubicato', 'uccello', 'uccisore', 'udire', 'uditivo', 'uffa', 'ufficio', 'uguale', 'ulisse', 'ultimato', 'umano', 'umile', 'umorismo', 'uncinetto', 'ungere', 'ungherese', 'unicorno', 'unificato', 'unisono', 'unitario', 'unte', 'uovo', 'upupa', 'uragano', 'urgenza', 'urlo', 'usanza', 'usato', 'uscito', 'usignolo', 'usuraio', 'utensile', 'utilizzo', 'utopia', 'vacante', 'vaccinato', 'vagabondo', 'vagliato', 'valanga', 'valgo', 'valico', 'valletta', 'valoroso', 'valutare', 'valvola', 'vampata', 'vangare', 'vanitoso', 'vano', 'vantaggio', 'vanvera', 'vapore', 'varano', 'varcato', 'variante', 'vasca', 'vedetta', 'vedova', 'veduto', 'vegetale', 'veicolo', 'velcro', 'velina', 'velluto', 'veloce', 'venato', 'vendemmia', 'vento', 'verace', 'verbale', 'vergogna', 'verifica', 'vero', 'verruca', 'verticale', 'vescica', 'vessillo', 'vestale', 'veterano', 'vetrina', 'vetusto', 'viandante', 'vibrante', 'vicenda', 'vichingo', 'vicinanza', 'vidimare', 'vigilia', 'vigneto', 'vigore', 'vile', 'villano', 'vimini', 'vincitore', 'viola', 'vipera', 'virgola', 'virologo', 'virulento', 'viscoso', 'visione', 'vispo', 'vissuto', 'visura', 'vita', 'vitello', 'vittima', 'vivanda', 'vivido', 'viziare', 'voce', 'voga', 'volatile', 'volere', 'volpe', 'voragine', 'vulcano', 'zampogna', 'zanna', 'zappato', 'zattera', 'zavorra', 'zefiro', 'zelante', 'zelo', 'zenzero', 'zerbino', 'zibetto', 'zinco', 'zircone', 'zitto', 'zolla', 'zotico', 'zucchero', 'zufolo', 'zulu', 'zuppa']
    
    module.exports = italian
    
    },{}],242:[function(require,module,exports){
    'use strict'
    
    var japanese = ['あいこくしん', 'あいさつ', 'あいだ', 'あおぞら', 'あかちゃん', 'あきる', 'あけがた', 'あける', 'あこがれる', 'あさい', 'あさひ', 'あしあと', 'あじわう', 'あずかる', 'あずき', 'あそぶ', 'あたえる', 'あたためる', 'あたりまえ', 'あたる', 'あつい', 'あつかう', 'あっしゅく', 'あつまり', 'あつめる', 'あてな', 'あてはまる', 'あひる', 'あぶら', 'あぶる', 'あふれる', 'あまい', 'あまど', 'あまやかす', 'あまり', 'あみもの', 'あめりか', 'あやまる', 'あゆむ', 'あらいぐま', 'あらし', 'あらすじ', 'あらためる', 'あらゆる', 'あらわす', 'ありがとう', 'あわせる', 'あわてる', 'あんい', 'あんがい', 'あんこ', 'あんぜん', 'あんてい', 'あんない', 'あんまり', 'いいだす', 'いおん', 'いがい', 'いがく', 'いきおい', 'いきなり', 'いきもの', 'いきる', 'いくじ', 'いくぶん', 'いけばな', 'いけん', 'いこう', 'いこく', 'いこつ', 'いさましい', 'いさん', 'いしき', 'いじゅう', 'いじょう', 'いじわる', 'いずみ', 'いずれ', 'いせい', 'いせえび', 'いせかい', 'いせき', 'いぜん', 'いそうろう', 'いそがしい', 'いだい', 'いだく', 'いたずら', 'いたみ', 'いたりあ', 'いちおう', 'いちじ', 'いちど', 'いちば', 'いちぶ', 'いちりゅう', 'いつか', 'いっしゅん', 'いっせい', 'いっそう', 'いったん', 'いっち', 'いってい', 'いっぽう', 'いてざ', 'いてん', 'いどう', 'いとこ', 'いない', 'いなか', 'いねむり', 'いのち', 'いのる', 'いはつ', 'いばる', 'いはん', 'いびき', 'いひん', 'いふく', 'いへん', 'いほう', 'いみん', 'いもうと', 'いもたれ', 'いもり', 'いやがる', 'いやす', 'いよかん', 'いよく', 'いらい', 'いらすと', 'いりぐち', 'いりょう', 'いれい', 'いれもの', 'いれる', 'いろえんぴつ', 'いわい', 'いわう', 'いわかん', 'いわば', 'いわゆる', 'いんげんまめ', 'いんさつ', 'いんしょう', 'いんよう', 'うえき', 'うえる', 'うおざ', 'うがい', 'うかぶ', 'うかべる', 'うきわ', 'うくらいな', 'うくれれ', 'うけたまわる', 'うけつけ', 'うけとる', 'うけもつ', 'うける', 'うごかす', 'うごく', 'うこん', 'うさぎ', 'うしなう', 'うしろがみ', 'うすい', 'うすぎ', 'うすぐらい', 'うすめる', 'うせつ', 'うちあわせ', 'うちがわ', 'うちき', 'うちゅう', 'うっかり', 'うつくしい', 'うったえる', 'うつる', 'うどん', 'うなぎ', 'うなじ', 'うなずく', 'うなる', 'うねる', 'うのう', 'うぶげ', 'うぶごえ', 'うまれる', 'うめる', 'うもう', 'うやまう', 'うよく', 'うらがえす', 'うらぐち', 'うらない', 'うりあげ', 'うりきれ', 'うるさい', 'うれしい', 'うれゆき', 'うれる', 'うろこ', 'うわき', 'うわさ', 'うんこう', 'うんちん', 'うんてん', 'うんどう', 'えいえん', 'えいが', 'えいきょう', 'えいご', 'えいせい', 'えいぶん', 'えいよう', 'えいわ', 'えおり', 'えがお', 'えがく', 'えきたい', 'えくせる', 'えしゃく', 'えすて', 'えつらん', 'えのぐ', 'えほうまき', 'えほん', 'えまき', 'えもじ', 'えもの', 'えらい', 'えらぶ', 'えりあ', 'えんえん', 'えんかい', 'えんぎ', 'えんげき', 'えんしゅう', 'えんぜつ', 'えんそく', 'えんちょう', 'えんとつ', 'おいかける', 'おいこす', 'おいしい', 'おいつく', 'おうえん', 'おうさま', 'おうじ', 'おうせつ', 'おうたい', 'おうふく', 'おうべい', 'おうよう', 'おえる', 'おおい', 'おおう', 'おおどおり', 'おおや', 'おおよそ', 'おかえり', 'おかず', 'おがむ', 'おかわり', 'おぎなう', 'おきる', 'おくさま', 'おくじょう', 'おくりがな', 'おくる', 'おくれる', 'おこす', 'おこなう', 'おこる', 'おさえる', 'おさない', 'おさめる', 'おしいれ', 'おしえる', 'おじぎ', 'おじさん', 'おしゃれ', 'おそらく', 'おそわる', 'おたがい', 'おたく', 'おだやか', 'おちつく', 'おっと', 'おつり', 'おでかけ', 'おとしもの', 'おとなしい', 'おどり', 'おどろかす', 'おばさん', 'おまいり', 'おめでとう', 'おもいで', 'おもう', 'おもたい', 'おもちゃ', 'おやつ', 'おやゆび', 'およぼす', 'おらんだ', 'おろす', 'おんがく', 'おんけい', 'おんしゃ', 'おんせん', 'おんだん', 'おんちゅう', 'おんどけい', 'かあつ', 'かいが', 'がいき', 'がいけん', 'がいこう', 'かいさつ', 'かいしゃ', 'かいすいよく', 'かいぜん', 'かいぞうど', 'かいつう', 'かいてん', 'かいとう', 'かいふく', 'がいへき', 'かいほう', 'かいよう', 'がいらい', 'かいわ', 'かえる', 'かおり', 'かかえる', 'かがく', 'かがし', 'かがみ', 'かくご', 'かくとく', 'かざる', 'がぞう', 'かたい', 'かたち', 'がちょう', 'がっきゅう', 'がっこう', 'がっさん', 'がっしょう', 'かなざわし', 'かのう', 'がはく', 'かぶか', 'かほう', 'かほご', 'かまう', 'かまぼこ', 'かめれおん', 'かゆい', 'かようび', 'からい', 'かるい', 'かろう', 'かわく', 'かわら', 'がんか', 'かんけい', 'かんこう', 'かんしゃ', 'かんそう', 'かんたん', 'かんち', 'がんばる', 'きあい', 'きあつ', 'きいろ', 'ぎいん', 'きうい', 'きうん', 'きえる', 'きおう', 'きおく', 'きおち', 'きおん', 'きかい', 'きかく', 'きかんしゃ', 'ききて', 'きくばり', 'きくらげ', 'きけんせい', 'きこう', 'きこえる', 'きこく', 'きさい', 'きさく', 'きさま', 'きさらぎ', 'ぎじかがく', 'ぎしき', 'ぎじたいけん', 'ぎじにってい', 'ぎじゅつしゃ', 'きすう', 'きせい', 'きせき', 'きせつ', 'きそう', 'きぞく', 'きぞん', 'きたえる', 'きちょう', 'きつえん', 'ぎっちり', 'きつつき', 'きつね', 'きてい', 'きどう', 'きどく', 'きない', 'きなが', 'きなこ', 'きぬごし', 'きねん', 'きのう', 'きのした', 'きはく', 'きびしい', 'きひん', 'きふく', 'きぶん', 'きぼう', 'きほん', 'きまる', 'きみつ', 'きむずかしい', 'きめる', 'きもだめし', 'きもち', 'きもの', 'きゃく', 'きやく', 'ぎゅうにく', 'きよう', 'きょうりゅう', 'きらい', 'きらく', 'きりん', 'きれい', 'きれつ', 'きろく', 'ぎろん', 'きわめる', 'ぎんいろ', 'きんかくじ', 'きんじょ', 'きんようび', 'ぐあい', 'くいず', 'くうかん', 'くうき', 'くうぐん', 'くうこう', 'ぐうせい', 'くうそう', 'ぐうたら', 'くうふく', 'くうぼ', 'くかん', 'くきょう', 'くげん', 'ぐこう', 'くさい', 'くさき', 'くさばな', 'くさる', 'くしゃみ', 'くしょう', 'くすのき', 'くすりゆび', 'くせげ', 'くせん', 'ぐたいてき', 'くださる', 'くたびれる', 'くちこみ', 'くちさき', 'くつした', 'ぐっすり', 'くつろぐ', 'くとうてん', 'くどく', 'くなん', 'くねくね', 'くのう', 'くふう', 'くみあわせ', 'くみたてる', 'くめる', 'くやくしょ', 'くらす', 'くらべる', 'くるま', 'くれる', 'くろう', 'くわしい', 'ぐんかん', 'ぐんしょく', 'ぐんたい', 'ぐんて', 'けあな', 'けいかく', 'けいけん', 'けいこ', 'けいさつ', 'げいじゅつ', 'けいたい', 'げいのうじん', 'けいれき', 'けいろ', 'けおとす', 'けおりもの', 'げきか', 'げきげん', 'げきだん', 'げきちん', 'げきとつ', 'げきは', 'げきやく', 'げこう', 'げこくじょう', 'げざい', 'けさき', 'げざん', 'けしき', 'けしごむ', 'けしょう', 'げすと', 'けたば', 'けちゃっぷ', 'けちらす', 'けつあつ', 'けつい', 'けつえき', 'けっこん', 'けつじょ', 'けっせき', 'けってい', 'けつまつ', 'げつようび', 'げつれい', 'けつろん', 'げどく', 'けとばす', 'けとる', 'けなげ', 'けなす', 'けなみ', 'けぬき', 'げねつ', 'けねん', 'けはい', 'げひん', 'けぶかい', 'げぼく', 'けまり', 'けみかる', 'けむし', 'けむり', 'けもの', 'けらい', 'けろけろ', 'けわしい', 'けんい', 'けんえつ', 'けんお', 'けんか', 'げんき', 'けんげん', 'けんこう', 'けんさく', 'けんしゅう', 'けんすう', 'げんそう', 'けんちく', 'けんてい', 'けんとう', 'けんない', 'けんにん', 'げんぶつ', 'けんま', 'けんみん', 'けんめい', 'けんらん', 'けんり', 'こあくま', 'こいぬ', 'こいびと', 'ごうい', 'こうえん', 'こうおん', 'こうかん', 'ごうきゅう', 'ごうけい', 'こうこう', 'こうさい', 'こうじ', 'こうすい', 'ごうせい', 'こうそく', 'こうたい', 'こうちゃ', 'こうつう', 'こうてい', 'こうどう', 'こうない', 'こうはい', 'ごうほう', 'ごうまん', 'こうもく', 'こうりつ', 'こえる', 'こおり', 'ごかい', 'ごがつ', 'ごかん', 'こくご', 'こくさい', 'こくとう', 'こくない', 'こくはく', 'こぐま', 'こけい', 'こける', 'ここのか', 'こころ', 'こさめ', 'こしつ', 'こすう', 'こせい', 'こせき', 'こぜん', 'こそだて', 'こたい', 'こたえる', 'こたつ', 'こちょう', 'こっか', 'こつこつ', 'こつばん', 'こつぶ', 'こてい', 'こてん', 'ことがら', 'ことし', 'ことば', 'ことり', 'こなごな', 'こねこね', 'このまま', 'このみ', 'このよ', 'ごはん', 'こひつじ', 'こふう', 'こふん', 'こぼれる', 'ごまあぶら', 'こまかい', 'ごますり', 'こまつな', 'こまる', 'こむぎこ', 'こもじ', 'こもち', 'こもの', 'こもん', 'こやく', 'こやま', 'こゆう', 'こゆび', 'こよい', 'こよう', 'こりる', 'これくしょん', 'ころっけ', 'こわもて', 'こわれる', 'こんいん', 'こんかい', 'こんき', 'こんしゅう', 'こんすい', 'こんだて', 'こんとん', 'こんなん', 'こんびに', 'こんぽん', 'こんまけ', 'こんや', 'こんれい', 'こんわく', 'ざいえき', 'さいかい', 'さいきん', 'ざいげん', 'ざいこ', 'さいしょ', 'さいせい', 'ざいたく', 'ざいちゅう', 'さいてき', 'ざいりょう', 'さうな', 'さかいし', 'さがす', 'さかな', 'さかみち', 'さがる', 'さぎょう', 'さくし', 'さくひん', 'さくら', 'さこく', 'さこつ', 'さずかる', 'ざせき', 'さたん', 'さつえい', 'ざつおん', 'ざっか', 'ざつがく', 'さっきょく', 'ざっし', 'さつじん', 'ざっそう', 'さつたば', 'さつまいも', 'さてい', 'さといも', 'さとう', 'さとおや', 'さとし', 'さとる', 'さのう', 'さばく', 'さびしい', 'さべつ', 'さほう', 'さほど', 'さます', 'さみしい', 'さみだれ', 'さむけ', 'さめる', 'さやえんどう', 'さゆう', 'さよう', 'さよく', 'さらだ', 'ざるそば', 'さわやか', 'さわる', 'さんいん', 'さんか', 'さんきゃく', 'さんこう', 'さんさい', 'ざんしょ', 'さんすう', 'さんせい', 'さんそ', 'さんち', 'さんま', 'さんみ', 'さんらん', 'しあい', 'しあげ', 'しあさって', 'しあわせ', 'しいく', 'しいん', 'しうち', 'しえい', 'しおけ', 'しかい', 'しかく', 'じかん', 'しごと', 'しすう', 'じだい', 'したうけ', 'したぎ', 'したて', 'したみ', 'しちょう', 'しちりん', 'しっかり', 'しつじ', 'しつもん', 'してい', 'してき', 'してつ', 'じてん', 'じどう', 'しなぎれ', 'しなもの', 'しなん', 'しねま', 'しねん', 'しのぐ', 'しのぶ', 'しはい', 'しばかり', 'しはつ', 'しはらい', 'しはん', 'しひょう', 'しふく', 'じぶん', 'しへい', 'しほう', 'しほん', 'しまう', 'しまる', 'しみん', 'しむける', 'じむしょ', 'しめい', 'しめる', 'しもん', 'しゃいん', 'しゃうん', 'しゃおん', 'じゃがいも', 'しやくしょ', 'しゃくほう', 'しゃけん', 'しゃこ', 'しゃざい', 'しゃしん', 'しゃせん', 'しゃそう', 'しゃたい', 'しゃちょう', 'しゃっきん', 'じゃま', 'しゃりん', 'しゃれい', 'じゆう', 'じゅうしょ', 'しゅくはく', 'じゅしん', 'しゅっせき', 'しゅみ', 'しゅらば', 'じゅんばん', 'しょうかい', 'しょくたく', 'しょっけん', 'しょどう', 'しょもつ', 'しらせる', 'しらべる', 'しんか', 'しんこう', 'じんじゃ', 'しんせいじ', 'しんちく', 'しんりん', 'すあげ', 'すあし', 'すあな', 'ずあん', 'すいえい', 'すいか', 'すいとう', 'ずいぶん', 'すいようび', 'すうがく', 'すうじつ', 'すうせん', 'すおどり', 'すきま', 'すくう', 'すくない', 'すける', 'すごい', 'すこし', 'ずさん', 'すずしい', 'すすむ', 'すすめる', 'すっかり', 'ずっしり', 'ずっと', 'すてき', 'すてる', 'すねる', 'すのこ', 'すはだ', 'すばらしい', 'ずひょう', 'ずぶぬれ', 'すぶり', 'すふれ', 'すべて', 'すべる', 'ずほう', 'すぼん', 'すまい', 'すめし', 'すもう', 'すやき', 'すらすら', 'するめ', 'すれちがう', 'すろっと', 'すわる', 'すんぜん', 'すんぽう', 'せあぶら', 'せいかつ', 'せいげん', 'せいじ', 'せいよう', 'せおう', 'せかいかん', 'せきにん', 'せきむ', 'せきゆ', 'せきらんうん', 'せけん', 'せこう', 'せすじ', 'せたい', 'せたけ', 'せっかく', 'せっきゃく', 'ぜっく', 'せっけん', 'せっこつ', 'せっさたくま', 'せつぞく', 'せつだん', 'せつでん', 'せっぱん', 'せつび', 'せつぶん', 'せつめい', 'せつりつ', 'せなか', 'せのび', 'せはば', 'せびろ', 'せぼね', 'せまい', 'せまる', 'せめる', 'せもたれ', 'せりふ', 'ぜんあく', 'せんい', 'せんえい', 'せんか', 'せんきょ', 'せんく', 'せんげん', 'ぜんご', 'せんさい', 'せんしゅ', 'せんすい', 'せんせい', 'せんぞ', 'せんたく', 'せんちょう', 'せんてい', 'せんとう', 'せんぬき', 'せんねん', 'せんぱい', 'ぜんぶ', 'ぜんぽう', 'せんむ', 'せんめんじょ', 'せんもん', 'せんやく', 'せんゆう', 'せんよう', 'ぜんら', 'ぜんりゃく', 'せんれい', 'せんろ', 'そあく', 'そいとげる', 'そいね', 'そうがんきょう', 'そうき', 'そうご', 'そうしん', 'そうだん', 'そうなん', 'そうび', 'そうめん', 'そうり', 'そえもの', 'そえん', 'そがい', 'そげき', 'そこう', 'そこそこ', 'そざい', 'そしな', 'そせい', 'そせん', 'そそぐ', 'そだてる', 'そつう', 'そつえん', 'そっかん', 'そつぎょう', 'そっけつ', 'そっこう', 'そっせん', 'そっと', 'そとがわ', 'そとづら', 'そなえる', 'そなた', 'そふぼ', 'そぼく', 'そぼろ', 'そまつ', 'そまる', 'そむく', 'そむりえ', 'そめる', 'そもそも', 'そよかぜ', 'そらまめ', 'そろう', 'そんかい', 'そんけい', 'そんざい', 'そんしつ', 'そんぞく', 'そんちょう', 'ぞんび', 'ぞんぶん', 'そんみん', 'たあい', 'たいいん', 'たいうん', 'たいえき', 'たいおう', 'だいがく', 'たいき', 'たいぐう', 'たいけん', 'たいこ', 'たいざい', 'だいじょうぶ', 'だいすき', 'たいせつ', 'たいそう', 'だいたい', 'たいちょう', 'たいてい', 'だいどころ', 'たいない', 'たいねつ', 'たいのう', 'たいはん', 'だいひょう', 'たいふう', 'たいへん', 'たいほ', 'たいまつばな', 'たいみんぐ', 'たいむ', 'たいめん', 'たいやき', 'たいよう', 'たいら', 'たいりょく', 'たいる', 'たいわん', 'たうえ', 'たえる', 'たおす', 'たおる', 'たおれる', 'たかい', 'たかね', 'たきび', 'たくさん', 'たこく', 'たこやき', 'たさい', 'たしざん', 'だじゃれ', 'たすける', 'たずさわる', 'たそがれ', 'たたかう', 'たたく', 'ただしい', 'たたみ', 'たちばな', 'だっかい', 'だっきゃく', 'だっこ', 'だっしゅつ', 'だったい', 'たてる', 'たとえる', 'たなばた', 'たにん', 'たぬき', 'たのしみ', 'たはつ', 'たぶん', 'たべる', 'たぼう', 'たまご', 'たまる', 'だむる', 'ためいき', 'ためす', 'ためる', 'たもつ', 'たやすい', 'たよる', 'たらす', 'たりきほんがん', 'たりょう', 'たりる', 'たると', 'たれる', 'たれんと', 'たろっと', 'たわむれる', 'だんあつ', 'たんい', 'たんおん', 'たんか', 'たんき', 'たんけん', 'たんご', 'たんさん', 'たんじょうび', 'だんせい', 'たんそく', 'たんたい', 'だんち', 'たんてい', 'たんとう', 'だんな', 'たんにん', 'だんねつ', 'たんのう', 'たんぴん', 'だんぼう', 'たんまつ', 'たんめい', 'だんれつ', 'だんろ', 'だんわ', 'ちあい', 'ちあん', 'ちいき', 'ちいさい', 'ちえん', 'ちかい', 'ちから', 'ちきゅう', 'ちきん', 'ちけいず', 'ちけん', 'ちこく', 'ちさい', 'ちしき', 'ちしりょう', 'ちせい', 'ちそう', 'ちたい', 'ちたん', 'ちちおや', 'ちつじょ', 'ちてき', 'ちてん', 'ちぬき', 'ちぬり', 'ちのう', 'ちひょう', 'ちへいせん', 'ちほう', 'ちまた', 'ちみつ', 'ちみどろ', 'ちめいど', 'ちゃんこなべ', 'ちゅうい', 'ちゆりょく', 'ちょうし', 'ちょさくけん', 'ちらし', 'ちらみ', 'ちりがみ', 'ちりょう', 'ちるど', 'ちわわ', 'ちんたい', 'ちんもく', 'ついか', 'ついたち', 'つうか', 'つうじょう', 'つうはん', 'つうわ', 'つかう', 'つかれる', 'つくね', 'つくる', 'つけね', 'つける', 'つごう', 'つたえる', 'つづく', 'つつじ', 'つつむ', 'つとめる', 'つながる', 'つなみ', 'つねづね', 'つのる', 'つぶす', 'つまらない', 'つまる', 'つみき', 'つめたい', 'つもり', 'つもる', 'つよい', 'つるぼ', 'つるみく', 'つわもの', 'つわり', 'てあし', 'てあて', 'てあみ', 'ていおん', 'ていか', 'ていき', 'ていけい', 'ていこく', 'ていさつ', 'ていし', 'ていせい', 'ていたい', 'ていど', 'ていねい', 'ていひょう', 'ていへん', 'ていぼう', 'てうち', 'ておくれ', 'てきとう', 'てくび', 'でこぼこ', 'てさぎょう', 'てさげ', 'てすり', 'てそう', 'てちがい', 'てちょう', 'てつがく', 'てつづき', 'でっぱ', 'てつぼう', 'てつや', 'でぬかえ', 'てぬき', 'てぬぐい', 'てのひら', 'てはい', 'てぶくろ', 'てふだ', 'てほどき', 'てほん', 'てまえ', 'てまきずし', 'てみじか', 'てみやげ', 'てらす', 'てれび', 'てわけ', 'てわたし', 'でんあつ', 'てんいん', 'てんかい', 'てんき', 'てんぐ', 'てんけん', 'てんごく', 'てんさい', 'てんし', 'てんすう', 'でんち', 'てんてき', 'てんとう', 'てんない', 'てんぷら', 'てんぼうだい', 'てんめつ', 'てんらんかい', 'でんりょく', 'でんわ', 'どあい', 'といれ', 'どうかん', 'とうきゅう', 'どうぐ', 'とうし', 'とうむぎ', 'とおい', 'とおか', 'とおく', 'とおす', 'とおる', 'とかい', 'とかす', 'ときおり', 'ときどき', 'とくい', 'とくしゅう', 'とくてん', 'とくに', 'とくべつ', 'とけい', 'とける', 'とこや', 'とさか', 'としょかん', 'とそう', 'とたん', 'とちゅう', 'とっきゅう', 'とっくん', 'とつぜん', 'とつにゅう', 'とどける', 'ととのえる', 'とない', 'となえる', 'となり', 'とのさま', 'とばす', 'どぶがわ', 'とほう', 'とまる', 'とめる', 'ともだち', 'ともる', 'どようび', 'とらえる', 'とんかつ', 'どんぶり', 'ないかく', 'ないこう', 'ないしょ', 'ないす', 'ないせん', 'ないそう', 'なおす', 'ながい', 'なくす', 'なげる', 'なこうど', 'なさけ', 'なたでここ', 'なっとう', 'なつやすみ', 'ななおし', 'なにごと', 'なにもの', 'なにわ', 'なのか', 'なふだ', 'なまいき', 'なまえ', 'なまみ', 'なみだ', 'なめらか', 'なめる', 'なやむ', 'ならう', 'ならび', 'ならぶ', 'なれる', 'なわとび', 'なわばり', 'にあう', 'にいがた', 'にうけ', 'におい', 'にかい', 'にがて', 'にきび', 'にくしみ', 'にくまん', 'にげる', 'にさんかたんそ', 'にしき', 'にせもの', 'にちじょう', 'にちようび', 'にっか', 'にっき', 'にっけい', 'にっこう', 'にっさん', 'にっしょく', 'にっすう', 'にっせき', 'にってい', 'になう', 'にほん', 'にまめ', 'にもつ', 'にやり', 'にゅういん', 'にりんしゃ', 'にわとり', 'にんい', 'にんか', 'にんき', 'にんげん', 'にんしき', 'にんずう', 'にんそう', 'にんたい', 'にんち', 'にんてい', 'にんにく', 'にんぷ', 'にんまり', 'にんむ', 'にんめい', 'にんよう', 'ぬいくぎ', 'ぬかす', 'ぬぐいとる', 'ぬぐう', 'ぬくもり', 'ぬすむ', 'ぬまえび', 'ぬめり', 'ぬらす', 'ぬんちゃく', 'ねあげ', 'ねいき', 'ねいる', 'ねいろ', 'ねぐせ', 'ねくたい', 'ねくら', 'ねこぜ', 'ねこむ', 'ねさげ', 'ねすごす', 'ねそべる', 'ねだん', 'ねつい', 'ねっしん', 'ねつぞう', 'ねったいぎょ', 'ねぶそく', 'ねふだ', 'ねぼう', 'ねほりはほり', 'ねまき', 'ねまわし', 'ねみみ', 'ねむい', 'ねむたい', 'ねもと', 'ねらう', 'ねわざ', 'ねんいり', 'ねんおし', 'ねんかん', 'ねんきん', 'ねんぐ', 'ねんざ', 'ねんし', 'ねんちゃく', 'ねんど', 'ねんぴ', 'ねんぶつ', 'ねんまつ', 'ねんりょう', 'ねんれい', 'のいず', 'のおづま', 'のがす', 'のきなみ', 'のこぎり', 'のこす', 'のこる', 'のせる', 'のぞく', 'のぞむ', 'のたまう', 'のちほど', 'のっく', 'のばす', 'のはら', 'のべる', 'のぼる', 'のみもの', 'のやま', 'のらいぬ', 'のらねこ', 'のりもの', 'のりゆき', 'のれん', 'のんき', 'ばあい', 'はあく', 'ばあさん', 'ばいか', 'ばいく', 'はいけん', 'はいご', 'はいしん', 'はいすい', 'はいせん', 'はいそう', 'はいち', 'ばいばい', 'はいれつ', 'はえる', 'はおる', 'はかい', 'ばかり', 'はかる', 'はくしゅ', 'はけん', 'はこぶ', 'はさみ', 'はさん', 'はしご', 'ばしょ', 'はしる', 'はせる', 'ぱそこん', 'はそん', 'はたん', 'はちみつ', 'はつおん', 'はっかく', 'はづき', 'はっきり', 'はっくつ', 'はっけん', 'はっこう', 'はっさん', 'はっしん', 'はったつ', 'はっちゅう', 'はってん', 'はっぴょう', 'はっぽう', 'はなす', 'はなび', 'はにかむ', 'はぶらし', 'はみがき', 'はむかう', 'はめつ', 'はやい', 'はやし', 'はらう', 'はろうぃん', 'はわい', 'はんい', 'はんえい', 'はんおん', 'はんかく', 'はんきょう', 'ばんぐみ', 'はんこ', 'はんしゃ', 'はんすう', 'はんだん', 'ぱんち', 'ぱんつ', 'はんてい', 'はんとし', 'はんのう', 'はんぱ', 'はんぶん', 'はんぺん', 'はんぼうき', 'はんめい', 'はんらん', 'はんろん', 'ひいき', 'ひうん', 'ひえる', 'ひかく', 'ひかり', 'ひかる', 'ひかん', 'ひくい', 'ひけつ', 'ひこうき', 'ひこく', 'ひさい', 'ひさしぶり', 'ひさん', 'びじゅつかん', 'ひしょ', 'ひそか', 'ひそむ', 'ひたむき', 'ひだり', 'ひたる', 'ひつぎ', 'ひっこし', 'ひっし', 'ひつじゅひん', 'ひっす', 'ひつぜん', 'ぴったり', 'ぴっちり', 'ひつよう', 'ひてい', 'ひとごみ', 'ひなまつり', 'ひなん', 'ひねる', 'ひはん', 'ひびく', 'ひひょう', 'ひほう', 'ひまわり', 'ひまん', 'ひみつ', 'ひめい', 'ひめじし', 'ひやけ', 'ひやす', 'ひよう', 'びょうき', 'ひらがな', 'ひらく', 'ひりつ', 'ひりょう', 'ひるま', 'ひるやすみ', 'ひれい', 'ひろい', 'ひろう', 'ひろき', 'ひろゆき', 'ひんかく', 'ひんけつ', 'ひんこん', 'ひんしゅ', 'ひんそう', 'ぴんち', 'ひんぱん', 'びんぼう', 'ふあん', 'ふいうち', 'ふうけい', 'ふうせん', 'ぷうたろう', 'ふうとう', 'ふうふ', 'ふえる', 'ふおん', 'ふかい', 'ふきん', 'ふくざつ', 'ふくぶくろ', 'ふこう', 'ふさい', 'ふしぎ', 'ふじみ', 'ふすま', 'ふせい', 'ふせぐ', 'ふそく', 'ぶたにく', 'ふたん', 'ふちょう', 'ふつう', 'ふつか', 'ふっかつ', 'ふっき', 'ふっこく', 'ぶどう', 'ふとる', 'ふとん', 'ふのう', 'ふはい', 'ふひょう', 'ふへん', 'ふまん', 'ふみん', 'ふめつ', 'ふめん', 'ふよう', 'ふりこ', 'ふりる', 'ふるい', 'ふんいき', 'ぶんがく', 'ぶんぐ', 'ふんしつ', 'ぶんせき', 'ふんそう', 'ぶんぽう', 'へいあん', 'へいおん', 'へいがい', 'へいき', 'へいげん', 'へいこう', 'へいさ', 'へいしゃ', 'へいせつ', 'へいそ', 'へいたく', 'へいてん', 'へいねつ', 'へいわ', 'へきが', 'へこむ', 'べにいろ', 'べにしょうが', 'へらす', 'へんかん', 'べんきょう', 'べんごし', 'へんさい', 'へんたい', 'べんり', 'ほあん', 'ほいく', 'ぼうぎょ', 'ほうこく', 'ほうそう', 'ほうほう', 'ほうもん', 'ほうりつ', 'ほえる', 'ほおん', 'ほかん', 'ほきょう', 'ぼきん', 'ほくろ', 'ほけつ', 'ほけん', 'ほこう', 'ほこる', 'ほしい', 'ほしつ', 'ほしゅ', 'ほしょう', 'ほせい', 'ほそい', 'ほそく', 'ほたて', 'ほたる', 'ぽちぶくろ', 'ほっきょく', 'ほっさ', 'ほったん', 'ほとんど', 'ほめる', 'ほんい', 'ほんき', 'ほんけ', 'ほんしつ', 'ほんやく', 'まいにち', 'まかい', 'まかせる', 'まがる', 'まける', 'まこと', 'まさつ', 'まじめ', 'ますく', 'まぜる', 'まつり', 'まとめ', 'まなぶ', 'まぬけ', 'まねく', 'まほう', 'まもる', 'まゆげ', 'まよう', 'まろやか', 'まわす', 'まわり', 'まわる', 'まんが', 'まんきつ', 'まんぞく', 'まんなか', 'みいら', 'みうち', 'みえる', 'みがく', 'みかた', 'みかん', 'みけん', 'みこん', 'みじかい', 'みすい', 'みすえる', 'みせる', 'みっか', 'みつかる', 'みつける', 'みてい', 'みとめる', 'みなと', 'みなみかさい', 'みねらる', 'みのう', 'みのがす', 'みほん', 'みもと', 'みやげ', 'みらい', 'みりょく', 'みわく', 'みんか', 'みんぞく', 'むいか', 'むえき', 'むえん', 'むかい', 'むかう', 'むかえ', 'むかし', 'むぎちゃ', 'むける', 'むげん', 'むさぼる', 'むしあつい', 'むしば', 'むじゅん', 'むしろ', 'むすう', 'むすこ', 'むすぶ', 'むすめ', 'むせる', 'むせん', 'むちゅう', 'むなしい', 'むのう', 'むやみ', 'むよう', 'むらさき', 'むりょう', 'むろん', 'めいあん', 'めいうん', 'めいえん', 'めいかく', 'めいきょく', 'めいさい', 'めいし', 'めいそう', 'めいぶつ', 'めいれい', 'めいわく', 'めぐまれる', 'めざす', 'めした', 'めずらしい', 'めだつ', 'めまい', 'めやす', 'めんきょ', 'めんせき', 'めんどう', 'もうしあげる', 'もうどうけん', 'もえる', 'もくし', 'もくてき', 'もくようび', 'もちろん', 'もどる', 'もらう', 'もんく', 'もんだい', 'やおや', 'やける', 'やさい', 'やさしい', 'やすい', 'やすたろう', 'やすみ', 'やせる', 'やそう', 'やたい', 'やちん', 'やっと', 'やっぱり', 'やぶる', 'やめる', 'ややこしい', 'やよい', 'やわらかい', 'ゆうき', 'ゆうびんきょく', 'ゆうべ', 'ゆうめい', 'ゆけつ', 'ゆしゅつ', 'ゆせん', 'ゆそう', 'ゆたか', 'ゆちゃく', 'ゆでる', 'ゆにゅう', 'ゆびわ', 'ゆらい', 'ゆれる', 'ようい', 'ようか', 'ようきゅう', 'ようじ', 'ようす', 'ようちえん', 'よかぜ', 'よかん', 'よきん', 'よくせい', 'よくぼう', 'よけい', 'よごれる', 'よさん', 'よしゅう', 'よそう', 'よそく', 'よっか', 'よてい', 'よどがわく', 'よねつ', 'よやく', 'よゆう', 'よろこぶ', 'よろしい', 'らいう', 'らくがき', 'らくご', 'らくさつ', 'らくだ', 'らしんばん', 'らせん', 'らぞく', 'らたい', 'らっか', 'られつ', 'りえき', 'りかい', 'りきさく', 'りきせつ', 'りくぐん', 'りくつ', 'りけん', 'りこう', 'りせい', 'りそう', 'りそく', 'りてん', 'りねん', 'りゆう', 'りゅうがく', 'りよう', 'りょうり', 'りょかん', 'りょくちゃ', 'りょこう', 'りりく', 'りれき', 'りろん', 'りんご', 'るいけい', 'るいさい', 'るいじ', 'るいせき', 'るすばん', 'るりがわら', 'れいかん', 'れいぎ', 'れいせい', 'れいぞうこ', 'れいとう', 'れいぼう', 'れきし', 'れきだい', 'れんあい', 'れんけい', 'れんこん', 'れんさい', 'れんしゅう', 'れんぞく', 'れんらく', 'ろうか', 'ろうご', 'ろうじん', 'ろうそく', 'ろくが', 'ろこつ', 'ろじうら', 'ろしゅつ', 'ろせん', 'ろてん', 'ろめん', 'ろれつ', 'ろんぎ', 'ろんぱ', 'ろんぶん', 'ろんり', 'わかす', 'わかめ', 'わかやま', 'わかれる', 'わしつ', 'わじまし', 'わすれもの', 'わらう', 'われる']
    
    module.exports = japanese
    
    },{}],243:[function(require,module,exports){
    'use strict'
    
    var spanish = ['ábaco', 'abdomen', 'abeja', 'abierto', 'abogado', 'abono', 'aborto', 'abrazo', 'abrir', 'abuelo', 'abuso', 'acabar', 'academia', 'acceso', 'acción', 'aceite', 'acelga', 'acento', 'aceptar', 'ácido', 'aclarar', 'acné', 'acoger', 'acoso', 'activo', 'acto', 'actriz', 'actuar', 'acudir', 'acuerdo', 'acusar', 'adicto', 'admitir', 'adoptar', 'adorno', 'aduana', 'adulto', 'aéreo', 'afectar', 'afición', 'afinar', 'afirmar', 'ágil', 'agitar', 'agonía', 'agosto', 'agotar', 'agregar', 'agrio', 'agua', 'agudo', 'águila', 'aguja', 'ahogo', 'ahorro', 'aire', 'aislar', 'ajedrez', 'ajeno', 'ajuste', 'alacrán', 'alambre', 'alarma', 'alba', 'álbum', 'alcalde', 'aldea', 'alegre', 'alejar', 'alerta', 'aleta', 'alfiler', 'alga', 'algodón', 'aliado', 'aliento', 'alivio', 'alma', 'almeja', 'almíbar', 'altar', 'alteza', 'altivo', 'alto', 'altura', 'alumno', 'alzar', 'amable', 'amante', 'amapola', 'amargo', 'amasar', 'ámbar', 'ámbito', 'ameno', 'amigo', 'amistad', 'amor', 'amparo', 'amplio', 'ancho', 'anciano', 'ancla', 'andar', 'andén', 'anemia', 'ángulo', 'anillo', 'ánimo', 'anís', 'anotar', 'antena', 'antiguo', 'antojo', 'anual', 'anular', 'anuncio', 'añadir', 'añejo', 'año', 'apagar', 'aparato', 'apetito', 'apio', 'aplicar', 'apodo', 'aporte', 'apoyo', 'aprender', 'aprobar', 'apuesta', 'apuro', 'arado', 'araña', 'arar', 'árbitro', 'árbol', 'arbusto', 'archivo', 'arco', 'arder', 'ardilla', 'arduo', 'área', 'árido', 'aries', 'armonía', 'arnés', 'aroma', 'arpa', 'arpón', 'arreglo', 'arroz', 'arruga', 'arte', 'artista', 'asa', 'asado', 'asalto', 'ascenso', 'asegurar', 'aseo', 'asesor', 'asiento', 'asilo', 'asistir', 'asno', 'asombro', 'áspero', 'astilla', 'astro', 'astuto', 'asumir', 'asunto', 'atajo', 'ataque', 'atar', 'atento', 'ateo', 'ático', 'atleta', 'átomo', 'atraer', 'atroz', 'atún', 'audaz', 'audio', 'auge', 'aula', 'aumento', 'ausente', 'autor', 'aval', 'avance', 'avaro', 'ave', 'avellana', 'avena', 'avestruz', 'avión', 'aviso', 'ayer', 'ayuda', 'ayuno', 'azafrán', 'azar', 'azote', 'azúcar', 'azufre', 'azul', 'baba', 'babor', 'bache', 'bahía', 'baile', 'bajar', 'balanza', 'balcón', 'balde', 'bambú', 'banco', 'banda', 'baño', 'barba', 'barco', 'barniz', 'barro', 'báscula', 'bastón', 'basura', 'batalla', 'batería', 'batir', 'batuta', 'baúl', 'bazar', 'bebé', 'bebida', 'bello', 'besar', 'beso', 'bestia', 'bicho', 'bien', 'bingo', 'blanco', 'bloque', 'blusa', 'boa', 'bobina', 'bobo', 'boca', 'bocina', 'boda', 'bodega', 'boina', 'bola', 'bolero', 'bolsa', 'bomba', 'bondad', 'bonito', 'bono', 'bonsái', 'borde', 'borrar', 'bosque', 'bote', 'botín', 'bóveda', 'bozal', 'bravo', 'brazo', 'brecha', 'breve', 'brillo', 'brinco', 'brisa', 'broca', 'broma', 'bronce', 'brote', 'bruja', 'brusco', 'bruto', 'buceo', 'bucle', 'bueno', 'buey', 'bufanda', 'bufón', 'búho', 'buitre', 'bulto', 'burbuja', 'burla', 'burro', 'buscar', 'butaca', 'buzón', 'caballo', 'cabeza', 'cabina', 'cabra', 'cacao', 'cadáver', 'cadena', 'caer', 'café', 'caída', 'caimán', 'caja', 'cajón', 'cal', 'calamar', 'calcio', 'caldo', 'calidad', 'calle', 'calma', 'calor', 'calvo', 'cama', 'cambio', 'camello', 'camino', 'campo', 'cáncer', 'candil', 'canela', 'canguro', 'canica', 'canto', 'caña', 'cañón', 'caoba', 'caos', 'capaz', 'capitán', 'capote', 'captar', 'capucha', 'cara', 'carbón', 'cárcel', 'careta', 'carga', 'cariño', 'carne', 'carpeta', 'carro', 'carta', 'casa', 'casco', 'casero', 'caspa', 'castor', 'catorce', 'catre', 'caudal', 'causa', 'cazo', 'cebolla', 'ceder', 'cedro', 'celda', 'célebre', 'celoso', 'célula', 'cemento', 'ceniza', 'centro', 'cerca', 'cerdo', 'cereza', 'cero', 'cerrar', 'certeza', 'césped', 'cetro', 'chacal', 'chaleco', 'champú', 'chancla', 'chapa', 'charla', 'chico', 'chiste', 'chivo', 'choque', 'choza', 'chuleta', 'chupar', 'ciclón', 'ciego', 'cielo', 'cien', 'cierto', 'cifra', 'cigarro', 'cima', 'cinco', 'cine', 'cinta', 'ciprés', 'circo', 'ciruela', 'cisne', 'cita', 'ciudad', 'clamor', 'clan', 'claro', 'clase', 'clave', 'cliente', 'clima', 'clínica', 'cobre', 'cocción', 'cochino', 'cocina', 'coco', 'código', 'codo', 'cofre', 'coger', 'cohete', 'cojín', 'cojo', 'cola', 'colcha', 'colegio', 'colgar', 'colina', 'collar', 'colmo', 'columna', 'combate', 'comer', 'comida', 'cómodo', 'compra', 'conde', 'conejo', 'conga', 'conocer', 'consejo', 'contar', 'copa', 'copia', 'corazón', 'corbata', 'corcho', 'cordón', 'corona', 'correr', 'coser', 'cosmos', 'costa', 'cráneo', 'cráter', 'crear', 'crecer', 'creído', 'crema', 'cría', 'crimen', 'cripta', 'crisis', 'cromo', 'crónica', 'croqueta', 'crudo', 'cruz', 'cuadro', 'cuarto', 'cuatro', 'cubo', 'cubrir', 'cuchara', 'cuello', 'cuento', 'cuerda', 'cuesta', 'cueva', 'cuidar', 'culebra', 'culpa', 'culto', 'cumbre', 'cumplir', 'cuna', 'cuneta', 'cuota', 'cupón', 'cúpula', 'curar', 'curioso', 'curso', 'curva', 'cutis', 'dama', 'danza', 'dar', 'dardo', 'dátil', 'deber', 'débil', 'década', 'decir', 'dedo', 'defensa', 'definir', 'dejar', 'delfín', 'delgado', 'delito', 'demora', 'denso', 'dental', 'deporte', 'derecho', 'derrota', 'desayuno', 'deseo', 'desfile', 'desnudo', 'destino', 'desvío', 'detalle', 'detener', 'deuda', 'día', 'diablo', 'diadema', 'diamante', 'diana', 'diario', 'dibujo', 'dictar', 'diente', 'dieta', 'diez', 'difícil', 'digno', 'dilema', 'diluir', 'dinero', 'directo', 'dirigir', 'disco', 'diseño', 'disfraz', 'diva', 'divino', 'doble', 'doce', 'dolor', 'domingo', 'don', 'donar', 'dorado', 'dormir', 'dorso', 'dos', 'dosis', 'dragón', 'droga', 'ducha', 'duda', 'duelo', 'dueño', 'dulce', 'dúo', 'duque', 'durar', 'dureza', 'duro', 'ébano', 'ebrio', 'echar', 'eco', 'ecuador', 'edad', 'edición', 'edificio', 'editor', 'educar', 'efecto', 'eficaz', 'eje', 'ejemplo', 'elefante', 'elegir', 'elemento', 'elevar', 'elipse', 'élite', 'elixir', 'elogio', 'eludir', 'embudo', 'emitir', 'emoción', 'empate', 'empeño', 'empleo', 'empresa', 'enano', 'encargo', 'enchufe', 'encía', 'enemigo', 'enero', 'enfado', 'enfermo', 'engaño', 'enigma', 'enlace', 'enorme', 'enredo', 'ensayo', 'enseñar', 'entero', 'entrar', 'envase', 'envío', 'época', 'equipo', 'erizo', 'escala', 'escena', 'escolar', 'escribir', 'escudo', 'esencia', 'esfera', 'esfuerzo', 'espada', 'espejo', 'espía', 'esposa', 'espuma', 'esquí', 'estar', 'este', 'estilo', 'estufa', 'etapa', 'eterno', 'ética', 'etnia', 'evadir', 'evaluar', 'evento', 'evitar', 'exacto', 'examen', 'exceso', 'excusa', 'exento', 'exigir', 'exilio', 'existir', 'éxito', 'experto', 'explicar', 'exponer', 'extremo', 'fábrica', 'fábula', 'fachada', 'fácil', 'factor', 'faena', 'faja', 'falda', 'fallo', 'falso', 'faltar', 'fama', 'familia', 'famoso', 'faraón', 'farmacia', 'farol', 'farsa', 'fase', 'fatiga', 'fauna', 'favor', 'fax', 'febrero', 'fecha', 'feliz', 'feo', 'feria', 'feroz', 'fértil', 'fervor', 'festín', 'fiable', 'fianza', 'fiar', 'fibra', 'ficción', 'ficha', 'fideo', 'fiebre', 'fiel', 'fiera', 'fiesta', 'figura', 'fijar', 'fijo', 'fila', 'filete', 'filial', 'filtro', 'fin', 'finca', 'fingir', 'finito', 'firma', 'flaco', 'flauta', 'flecha', 'flor', 'flota', 'fluir', 'flujo', 'flúor', 'fobia', 'foca', 'fogata', 'fogón', 'folio', 'folleto', 'fondo', 'forma', 'forro', 'fortuna', 'forzar', 'fosa', 'foto', 'fracaso', 'frágil', 'franja', 'frase', 'fraude', 'freír', 'freno', 'fresa', 'frío', 'frito', 'fruta', 'fuego', 'fuente', 'fuerza', 'fuga', 'fumar', 'función', 'funda', 'furgón', 'furia', 'fusil', 'fútbol', 'futuro', 'gacela', 'gafas', 'gaita', 'gajo', 'gala', 'galería', 'gallo', 'gamba', 'ganar', 'gancho', 'ganga', 'ganso', 'garaje', 'garza', 'gasolina', 'gastar', 'gato', 'gavilán', 'gemelo', 'gemir', 'gen', 'género', 'genio', 'gente', 'geranio', 'gerente', 'germen', 'gesto', 'gigante', 'gimnasio', 'girar', 'giro', 'glaciar', 'globo', 'gloria', 'gol', 'golfo', 'goloso', 'golpe', 'goma', 'gordo', 'gorila', 'gorra', 'gota', 'goteo', 'gozar', 'grada', 'gráfico', 'grano', 'grasa', 'gratis', 'grave', 'grieta', 'grillo', 'gripe', 'gris', 'grito', 'grosor', 'grúa', 'grueso', 'grumo', 'grupo', 'guante', 'guapo', 'guardia', 'guerra', 'guía', 'guiño', 'guion', 'guiso', 'guitarra', 'gusano', 'gustar', 'haber', 'hábil', 'hablar', 'hacer', 'hacha', 'hada', 'hallar', 'hamaca', 'harina', 'haz', 'hazaña', 'hebilla', 'hebra', 'hecho', 'helado', 'helio', 'hembra', 'herir', 'hermano', 'héroe', 'hervir', 'hielo', 'hierro', 'hígado', 'higiene', 'hijo', 'himno', 'historia', 'hocico', 'hogar', 'hoguera', 'hoja', 'hombre', 'hongo', 'honor', 'honra', 'hora', 'hormiga', 'horno', 'hostil', 'hoyo', 'hueco', 'huelga', 'huerta', 'hueso', 'huevo', 'huida', 'huir', 'humano', 'húmedo', 'humilde', 'humo', 'hundir', 'huracán', 'hurto', 'icono', 'ideal', 'idioma', 'ídolo', 'iglesia', 'iglú', 'igual', 'ilegal', 'ilusión', 'imagen', 'imán', 'imitar', 'impar', 'imperio', 'imponer', 'impulso', 'incapaz', 'índice', 'inerte', 'infiel', 'informe', 'ingenio', 'inicio', 'inmenso', 'inmune', 'innato', 'insecto', 'instante', 'interés', 'íntimo', 'intuir', 'inútil', 'invierno', 'ira', 'iris', 'ironía', 'isla', 'islote', 'jabalí', 'jabón', 'jamón', 'jarabe', 'jardín', 'jarra', 'jaula', 'jazmín', 'jefe', 'jeringa', 'jinete', 'jornada', 'joroba', 'joven', 'joya', 'juerga', 'jueves', 'juez', 'jugador', 'jugo', 'juguete', 'juicio', 'junco', 'jungla', 'junio', 'juntar', 'júpiter', 'jurar', 'justo', 'juvenil', 'juzgar', 'kilo', 'koala', 'labio', 'lacio', 'lacra', 'lado', 'ladrón', 'lagarto', 'lágrima', 'laguna', 'laico', 'lamer', 'lámina', 'lámpara', 'lana', 'lancha', 'langosta', 'lanza', 'lápiz', 'largo', 'larva', 'lástima', 'lata', 'látex', 'latir', 'laurel', 'lavar', 'lazo', 'leal', 'lección', 'leche', 'lector', 'leer', 'legión', 'legumbre', 'lejano', 'lengua', 'lento', 'leña', 'león', 'leopardo', 'lesión', 'letal', 'letra', 'leve', 'leyenda', 'libertad', 'libro', 'licor', 'líder', 'lidiar', 'lienzo', 'liga', 'ligero', 'lima', 'límite', 'limón', 'limpio', 'lince', 'lindo', 'línea', 'lingote', 'lino', 'linterna', 'líquido', 'liso', 'lista', 'litera', 'litio', 'litro', 'llaga', 'llama', 'llanto', 'llave', 'llegar', 'llenar', 'llevar', 'llorar', 'llover', 'lluvia', 'lobo', 'loción', 'loco', 'locura', 'lógica', 'logro', 'lombriz', 'lomo', 'lonja', 'lote', 'lucha', 'lucir', 'lugar', 'lujo', 'luna', 'lunes', 'lupa', 'lustro', 'luto', 'luz', 'maceta', 'macho', 'madera', 'madre', 'maduro', 'maestro', 'mafia', 'magia', 'mago', 'maíz', 'maldad', 'maleta', 'malla', 'malo', 'mamá', 'mambo', 'mamut', 'manco', 'mando', 'manejar', 'manga', 'maniquí', 'manjar', 'mano', 'manso', 'manta', 'mañana', 'mapa', 'máquina', 'mar', 'marco', 'marea', 'marfil', 'margen', 'marido', 'mármol', 'marrón', 'martes', 'marzo', 'masa', 'máscara', 'masivo', 'matar', 'materia', 'matiz', 'matriz', 'máximo', 'mayor', 'mazorca', 'mecha', 'medalla', 'medio', 'médula', 'mejilla', 'mejor', 'melena', 'melón', 'memoria', 'menor', 'mensaje', 'mente', 'menú', 'mercado', 'merengue', 'mérito', 'mes', 'mesón', 'meta', 'meter', 'método', 'metro', 'mezcla', 'miedo', 'miel', 'miembro', 'miga', 'mil', 'milagro', 'militar', 'millón', 'mimo', 'mina', 'minero', 'mínimo', 'minuto', 'miope', 'mirar', 'misa', 'miseria', 'misil', 'mismo', 'mitad', 'mito', 'mochila', 'moción', 'moda', 'modelo', 'moho', 'mojar', 'molde', 'moler', 'molino', 'momento', 'momia', 'monarca', 'moneda', 'monja', 'monto', 'moño', 'morada', 'morder', 'moreno', 'morir', 'morro', 'morsa', 'mortal', 'mosca', 'mostrar', 'motivo', 'mover', 'móvil', 'mozo', 'mucho', 'mudar', 'mueble', 'muela', 'muerte', 'muestra', 'mugre', 'mujer', 'mula', 'muleta', 'multa', 'mundo', 'muñeca', 'mural', 'muro', 'músculo', 'museo', 'musgo', 'música', 'muslo', 'nácar', 'nación', 'nadar', 'naipe', 'naranja', 'nariz', 'narrar', 'nasal', 'natal', 'nativo', 'natural', 'náusea', 'naval', 'nave', 'navidad', 'necio', 'néctar', 'negar', 'negocio', 'negro', 'neón', 'nervio', 'neto', 'neutro', 'nevar', 'nevera', 'nicho', 'nido', 'niebla', 'nieto', 'niñez', 'niño', 'nítido', 'nivel', 'nobleza', 'noche', 'nómina', 'noria', 'norma', 'norte', 'nota', 'noticia', 'novato', 'novela', 'novio', 'nube', 'nuca', 'núcleo', 'nudillo', 'nudo', 'nuera', 'nueve', 'nuez', 'nulo', 'número', 'nutria', 'oasis', 'obeso', 'obispo', 'objeto', 'obra', 'obrero', 'observar', 'obtener', 'obvio', 'oca', 'ocaso', 'océano', 'ochenta', 'ocho', 'ocio', 'ocre', 'octavo', 'octubre', 'oculto', 'ocupar', 'ocurrir', 'odiar', 'odio', 'odisea', 'oeste', 'ofensa', 'oferta', 'oficio', 'ofrecer', 'ogro', 'oído', 'oír', 'ojo', 'ola', 'oleada', 'olfato', 'olivo', 'olla', 'olmo', 'olor', 'olvido', 'ombligo', 'onda', 'onza', 'opaco', 'opción', 'ópera', 'opinar', 'oponer', 'optar', 'óptica', 'opuesto', 'oración', 'orador', 'oral', 'órbita', 'orca', 'orden', 'oreja', 'órgano', 'orgía', 'orgullo', 'oriente', 'origen', 'orilla', 'oro', 'orquesta', 'oruga', 'osadía', 'oscuro', 'osezno', 'oso', 'ostra', 'otoño', 'otro', 'oveja', 'óvulo', 'óxido', 'oxígeno', 'oyente', 'ozono', 'pacto', 'padre', 'paella', 'página', 'pago', 'país', 'pájaro', 'palabra', 'palco', 'paleta', 'pálido', 'palma', 'paloma', 'palpar', 'pan', 'panal', 'pánico', 'pantera', 'pañuelo', 'papá', 'papel', 'papilla', 'paquete', 'parar', 'parcela', 'pared', 'parir', 'paro', 'párpado', 'parque', 'párrafo', 'parte', 'pasar', 'paseo', 'pasión', 'paso', 'pasta', 'pata', 'patio', 'patria', 'pausa', 'pauta', 'pavo', 'payaso', 'peatón', 'pecado', 'pecera', 'pecho', 'pedal', 'pedir', 'pegar', 'peine', 'pelar', 'peldaño', 'pelea', 'peligro', 'pellejo', 'pelo', 'peluca', 'pena', 'pensar', 'peñón', 'peón', 'peor', 'pepino', 'pequeño', 'pera', 'percha', 'perder', 'pereza', 'perfil', 'perico', 'perla', 'permiso', 'perro', 'persona', 'pesa', 'pesca', 'pésimo', 'pestaña', 'pétalo', 'petróleo', 'pez', 'pezuña', 'picar', 'pichón', 'pie', 'piedra', 'pierna', 'pieza', 'pijama', 'pilar', 'piloto', 'pimienta', 'pino', 'pintor', 'pinza', 'piña', 'piojo', 'pipa', 'pirata', 'pisar', 'piscina', 'piso', 'pista', 'pitón', 'pizca', 'placa', 'plan', 'plata', 'playa', 'plaza', 'pleito', 'pleno', 'plomo', 'pluma', 'plural', 'pobre', 'poco', 'poder', 'podio', 'poema', 'poesía', 'poeta', 'polen', 'policía', 'pollo', 'polvo', 'pomada', 'pomelo', 'pomo', 'pompa', 'poner', 'porción', 'portal', 'posada', 'poseer', 'posible', 'poste', 'potencia', 'potro', 'pozo', 'prado', 'precoz', 'pregunta', 'premio', 'prensa', 'preso', 'previo', 'primo', 'príncipe', 'prisión', 'privar', 'proa', 'probar', 'proceso', 'producto', 'proeza', 'profesor', 'programa', 'prole', 'promesa', 'pronto', 'propio', 'próximo', 'prueba', 'público', 'puchero', 'pudor', 'pueblo', 'puerta', 'puesto', 'pulga', 'pulir', 'pulmón', 'pulpo', 'pulso', 'puma', 'punto', 'puñal', 'puño', 'pupa', 'pupila', 'puré', 'quedar', 'queja', 'quemar', 'querer', 'queso', 'quieto', 'química', 'quince', 'quitar', 'rábano', 'rabia', 'rabo', 'ración', 'radical', 'raíz', 'rama', 'rampa', 'rancho', 'rango', 'rapaz', 'rápido', 'rapto', 'rasgo', 'raspa', 'rato', 'rayo', 'raza', 'razón', 'reacción', 'realidad', 'rebaño', 'rebote', 'recaer', 'receta', 'rechazo', 'recoger', 'recreo', 'recto', 'recurso', 'red', 'redondo', 'reducir', 'reflejo', 'reforma', 'refrán', 'refugio', 'regalo', 'regir', 'regla', 'regreso', 'rehén', 'reino', 'reír', 'reja', 'relato', 'relevo', 'relieve', 'relleno', 'reloj', 'remar', 'remedio', 'remo', 'rencor', 'rendir', 'renta', 'reparto', 'repetir', 'reposo', 'reptil', 'res', 'rescate', 'resina', 'respeto', 'resto', 'resumen', 'retiro', 'retorno', 'retrato', 'reunir', 'revés', 'revista', 'rey', 'rezar', 'rico', 'riego', 'rienda', 'riesgo', 'rifa', 'rígido', 'rigor', 'rincón', 'riñón', 'río', 'riqueza', 'risa', 'ritmo', 'rito', 'rizo', 'roble', 'roce', 'rociar', 'rodar', 'rodeo', 'rodilla', 'roer', 'rojizo', 'rojo', 'romero', 'romper', 'ron', 'ronco', 'ronda', 'ropa', 'ropero', 'rosa', 'rosca', 'rostro', 'rotar', 'rubí', 'rubor', 'rudo', 'rueda', 'rugir', 'ruido', 'ruina', 'ruleta', 'rulo', 'rumbo', 'rumor', 'ruptura', 'ruta', 'rutina', 'sábado', 'saber', 'sabio', 'sable', 'sacar', 'sagaz', 'sagrado', 'sala', 'saldo', 'salero', 'salir', 'salmón', 'salón', 'salsa', 'salto', 'salud', 'salvar', 'samba', 'sanción', 'sandía', 'sanear', 'sangre', 'sanidad', 'sano', 'santo', 'sapo', 'saque', 'sardina', 'sartén', 'sastre', 'satán', 'sauna', 'saxofón', 'sección', 'seco', 'secreto', 'secta', 'sed', 'seguir', 'seis', 'sello', 'selva', 'semana', 'semilla', 'senda', 'sensor', 'señal', 'señor', 'separar', 'sepia', 'sequía', 'ser', 'serie', 'sermón', 'servir', 'sesenta', 'sesión', 'seta', 'setenta', 'severo', 'sexo', 'sexto', 'sidra', 'siesta', 'siete', 'siglo', 'signo', 'sílaba', 'silbar', 'silencio', 'silla', 'símbolo', 'simio', 'sirena', 'sistema', 'sitio', 'situar', 'sobre', 'socio', 'sodio', 'sol', 'solapa', 'soldado', 'soledad', 'sólido', 'soltar', 'solución', 'sombra', 'sondeo', 'sonido', 'sonoro', 'sonrisa', 'sopa', 'soplar', 'soporte', 'sordo', 'sorpresa', 'sorteo', 'sostén', 'sótano', 'suave', 'subir', 'suceso', 'sudor', 'suegra', 'suelo', 'sueño', 'suerte', 'sufrir', 'sujeto', 'sultán', 'sumar', 'superar', 'suplir', 'suponer', 'supremo', 'sur', 'surco', 'sureño', 'surgir', 'susto', 'sutil', 'tabaco', 'tabique', 'tabla', 'tabú', 'taco', 'tacto', 'tajo', 'talar', 'talco', 'talento', 'talla', 'talón', 'tamaño', 'tambor', 'tango', 'tanque', 'tapa', 'tapete', 'tapia', 'tapón', 'taquilla', 'tarde', 'tarea', 'tarifa', 'tarjeta', 'tarot', 'tarro', 'tarta', 'tatuaje', 'tauro', 'taza', 'tazón', 'teatro', 'techo', 'tecla', 'técnica', 'tejado', 'tejer', 'tejido', 'tela', 'teléfono', 'tema', 'temor', 'templo', 'tenaz', 'tender', 'tener', 'tenis', 'tenso', 'teoría', 'terapia', 'terco', 'término', 'ternura', 'terror', 'tesis', 'tesoro', 'testigo', 'tetera', 'texto', 'tez', 'tibio', 'tiburón', 'tiempo', 'tienda', 'tierra', 'tieso', 'tigre', 'tijera', 'tilde', 'timbre', 'tímido', 'timo', 'tinta', 'tío', 'típico', 'tipo', 'tira', 'tirón', 'titán', 'títere', 'título', 'tiza', 'toalla', 'tobillo', 'tocar', 'tocino', 'todo', 'toga', 'toldo', 'tomar', 'tono', 'tonto', 'topar', 'tope', 'toque', 'tórax', 'torero', 'tormenta', 'torneo', 'toro', 'torpedo', 'torre', 'torso', 'tortuga', 'tos', 'tosco', 'toser', 'tóxico', 'trabajo', 'tractor', 'traer', 'tráfico', 'trago', 'traje', 'tramo', 'trance', 'trato', 'trauma', 'trazar', 'trébol', 'tregua', 'treinta', 'tren', 'trepar', 'tres', 'tribu', 'trigo', 'tripa', 'triste', 'triunfo', 'trofeo', 'trompa', 'tronco', 'tropa', 'trote', 'trozo', 'truco', 'trueno', 'trufa', 'tubería', 'tubo', 'tuerto', 'tumba', 'tumor', 'túnel', 'túnica', 'turbina', 'turismo', 'turno', 'tutor', 'ubicar', 'úlcera', 'umbral', 'unidad', 'unir', 'universo', 'uno', 'untar', 'uña', 'urbano', 'urbe', 'urgente', 'urna', 'usar', 'usuario', 'útil', 'utopía', 'uva', 'vaca', 'vacío', 'vacuna', 'vagar', 'vago', 'vaina', 'vajilla', 'vale', 'válido', 'valle', 'valor', 'válvula', 'vampiro', 'vara', 'variar', 'varón', 'vaso', 'vecino', 'vector', 'vehículo', 'veinte', 'vejez', 'vela', 'velero', 'veloz', 'vena', 'vencer', 'venda', 'veneno', 'vengar', 'venir', 'venta', 'venus', 'ver', 'verano', 'verbo', 'verde', 'vereda', 'verja', 'verso', 'verter', 'vía', 'viaje', 'vibrar', 'vicio', 'víctima', 'vida', 'vídeo', 'vidrio', 'viejo', 'viernes', 'vigor', 'vil', 'villa', 'vinagre', 'vino', 'viñedo', 'violín', 'viral', 'virgo', 'virtud', 'visor', 'víspera', 'vista', 'vitamina', 'viudo', 'vivaz', 'vivero', 'vivir', 'vivo', 'volcán', 'volumen', 'volver', 'voraz', 'votar', 'voto', 'voz', 'vuelo', 'vulgar', 'yacer', 'yate', 'yegua', 'yema', 'yerno', 'yeso', 'yodo', 'yoga', 'yogur', 'zafiro', 'zanja', 'zapato', 'zarza', 'zona', 'zorro', 'zumo', 'zurdo']
    
    module.exports = spanish
    
    },{}],244:[function(require,module,exports){
    'use strict'
    var _ = require('./util/_')
    
    var JSUtil = require('./util/js')
    var networks = []
    var networkMaps = {}
    
    /**
     * A network is merely a map containing values that correspond to version
     * numbers for each bitcoin network. Currently only supporting "livenet"
     * (a.k.a. "mainnet"), "testnet", "regtest" and "stn".
     * @constructor
     */
    function Network () {}
    
    Network.prototype.toString = function toString () {
      return this.name
    }
    
    /**
     * @function
     * @member Networks#get
     * Retrieves the network associated with a magic number or string.
     * @param {string|number|Network} arg
     * @param {string|Array} keys - if set, only check if the magic number associated with this name matches
     * @return Network
     */
    function get (arg, keys) {
      if (~networks.indexOf(arg)) {
        return arg
      }
      if (keys) {
        if (!_.isArray(keys)) {
          keys = [keys]
        }
        for (var i = 0; i < networks.length; i++) {
          var network = networks[i]
          var filteredNet = _.pick(network, keys)
          var netValues = _.values(filteredNet)
          if (~netValues.indexOf(arg)) {
            return network
          }
        }
        return undefined
      }
      return networkMaps[arg]
    }
    
    /***
     * Derives an array from the given cashAddrPrefix to be used in the computation
     * of the address' checksum.
     *
     * @param {string} cashAddrPrefix Network cashAddrPrefix. E.g.: 'bitcoincash'.
     */
    function cashAddrPrefixToArray (cashAddrPrefix) {
      var result = []
      for (var i = 0; i < cashAddrPrefix.length; i++) {
        result.push(cashAddrPrefix.charCodeAt(i) & 31)
      }
      return result
    }
    
    /**
     * @function
     * @member Networks#add
     * Will add a custom Network
     * @param {Object} data
     * @param {string} data.name - The name of the network
     * @param {string} data.alias - The aliased name of the network
     * @param {Number} data.pubkeyhash - The publickey hash cashAddrPrefix
     * @param {Number} data.privatekey - The privatekey cashAddrPrefix
     * @param {Number} data.scripthash - The scripthash cashAddrPrefix
     * @param {Number} data.xpubkey - The extended public key magic
     * @param {Number} data.xprivkey - The extended private key magic
     * @param {Number} data.networkMagic - The network magic number
     * @param {Number} data.port - The network port
     * @param {Array}  data.dnsSeeds - An array of dns seeds
     * @return Network
     */
    function addNetwork (data) {
      var network = new Network()
    
      JSUtil.defineImmutable(network, {
        name: data.name,
        alias: data.alias,
        pubkeyhash: data.pubkeyhash,
        privatekey: data.privatekey,
        scripthash: data.scripthash,
        xpubkey: data.xpubkey,
        xprivkey: data.xprivkey
      })
    
      var indexBy = data.indexBy || Object.keys(data)
    
      if (data.cashAddrPrefix) {
        _.extend(network, {
          cashAddrPrefix: data.cashAddrPrefix,
          cashAddrPrefixArray: cashAddrPrefixToArray(data.cashAddrPrefix)
        })
      }
    
      if (data.networkMagic) {
        _.extend(network, {
          networkMagic: JSUtil.integerAsBuffer(data.networkMagic)
        })
      }
    
      if (data.port) {
        _.extend(network, {
          port: data.port
        })
      }
    
      if (data.dnsSeeds) {
        _.extend(network, {
          dnsSeeds: data.dnsSeeds
        })
      }
      networks.push(network)
      indexNetworkBy(network, indexBy)
      return network
    }
    
    function indexNetworkBy (network, keys) {
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i]
        var networkValue = network[key]
        if (!_.isUndefined(networkValue) && !_.isObject(networkValue)) {
          networkMaps[networkValue] = network
        }
      }
    }
    
    function unindexNetworkBy (network, values) {
      for (var index = 0; index < values.length; index++) {
        var value = values[index]
        if (networkMaps[value] === network) {
          delete networkMaps[value]
        }
      }
    }
    
    /**
     * @function
     * @member Networks#remove
     * Will remove a custom network
     * @param {Network} network
     */
    function removeNetwork (network) {
      for (var i = 0; i < networks.length; i++) {
        if (networks[i] === network) {
          networks.splice(i, 1)
        }
      }
      unindexNetworkBy(network, Object.keys(networkMaps))
    }
    
    var networkMagic = {
      livenet: 0xe3e1f3e8,
      testnet: 0xf4e5f3f4,
      regtest: 0xdab5bffa,
      stn: 0xfbcec4f9
    }
    
    var dnsSeeds = [
      'seed.bitcoinsv.org',
      'seed.bitcoinunlimited.info'
    ]
    
    var TESTNET = {
      PORT: 18333,
      NETWORK_MAGIC: networkMagic.testnet,
      DNS_SEEDS: dnsSeeds,
      PREFIX: 'testnet',
      CASHADDRPREFIX: 'bchtest'
    }
    
    var REGTEST = {
      PORT: 18444,
      NETWORK_MAGIC: networkMagic.regtest,
      DNS_SEEDS: [],
      PREFIX: 'regtest',
      CASHADDRPREFIX: 'bchreg'
    }
    
    var STN = {
      PORT: 9333,
      NETWORK_MAGIC: networkMagic.stn,
      DNS_SEEDS: ['stn-seed.bitcoinsv.io'],
      PREFIX: 'stn',
      CASHADDRPREFIX: 'bsvstn'
    }
    
    var liveNetwork = {
      name: 'livenet',
      alias: 'mainnet',
      prefix: 'bitcoin',
      cashAddrPrefix: 'bitcoincash',
      pubkeyhash: 0x00,
      privatekey: 0x80,
      scripthash: 0x05,
      xpubkey: 0x0488b21e,
      xprivkey: 0x0488ade4,
      networkMagic: networkMagic.livenet,
      port: 8333,
      dnsSeeds: dnsSeeds
    }
    
    // network magic, port, cashAddrPrefix, and dnsSeeds are overloaded by enableRegtest
    var testNetwork = {
      name: 'testnet',
      prefix: TESTNET.PREFIX,
      cashAddrPrefix: TESTNET.CASHADDRPREFIX,
      pubkeyhash: 0x6f,
      privatekey: 0xef,
      scripthash: 0xc4,
      xpubkey: 0x043587cf,
      xprivkey: 0x04358394,
      networkMagic: TESTNET.NETWORK_MAGIC
    }
    
    var regtestNetwork = {
      name: 'regtest',
      prefix: REGTEST.PREFIX,
      cashAddrPrefix: REGTEST.CASHADDRPREFIX,
      pubkeyhash: 0x6f,
      privatekey: 0xef,
      scripthash: 0xc4,
      xpubkey: 0x043587cf,
      xprivkey: 0x04358394,
      networkMagic: REGTEST.NETWORK_MAGIC,
      port: REGTEST.PORT,
      dnsSeeds: [],
      indexBy: [
        'port',
        'name',
        'cashAddrPrefix',
        'networkMagic'
      ]
    }
    var stnNetwork = {
      name: 'stn',
      prefix: STN.PREFIX,
      cashAddrPrefix: STN.CASHADDRPREFIX,
      pubkeyhash: 0x6f,
      privatekey: 0xef,
      scripthash: 0xc4,
      xpubkey: 0x043587cf,
      xprivkey: 0x04358394,
      networkMagic: STN.NETWORK_MAGIC,
      indexBy: [
        'port',
        'name',
        'cashAddrPrefix',
        'networkMagic'
      ]
    }
    // Add configurable values for testnet/regtest
    
    addNetwork(testNetwork)
    addNetwork(stnNetwork)
    addNetwork(regtestNetwork)
    addNetwork(liveNetwork)
    
    var livenet = get('livenet')
    var regtest = get('regtest')
    var testnet = get('testnet')
    var stn = get('stn')
    
    Object.defineProperty(testnet, 'port', {
      enumerable: true,
      configurable: false,
      get: function () {
        if (this.regtestEnabled) {
          return REGTEST.PORT
        } else if (this.stnEnabled) {
          return STN.PORT
        } else {
          return TESTNET.PORT
        }
      }
    })
    
    Object.defineProperty(testnet, 'networkMagic', {
      enumerable: true,
      configurable: false,
      get: function () {
        if (this.regtestEnabled) {
          return JSUtil.integerAsBuffer(REGTEST.NETWORK_MAGIC)
        } else if (this.stnEnabled) {
          return JSUtil.integerAsBuffer(STN.NETWORK_MAGIC)
        } else {
          return JSUtil.integerAsBuffer(TESTNET.NETWORK_MAGIC)
        }
      }
    })
    
    Object.defineProperty(testnet, 'dnsSeeds', {
      enumerable: true,
      configurable: false,
      get: function () {
        if (this.regtestEnabled) {
          return REGTEST.DNS_SEEDS
        } else if (this.stnEnabled) {
          return STN.DNS_SEEDS
        } else {
          return TESTNET.DNS_SEEDS
        }
      }
    })
    
    Object.defineProperty(testnet, 'cashAddrPrefix', {
      enumerable: true,
      configurable: false,
      get: function () {
        if (this.regtestEnabled) {
          return REGTEST.CASHADDRPREFIX
        } else if (this.stnEnabled) {
          return STN.CASHADDRPREFIX
        } else {
          return TESTNET.CASHADDRPREFIX
        }
      }
    })
    
    Object.defineProperty(testnet, 'cashAddrPrefixArray', {
      enumerable: true,
      configurable: false,
      get: function () {
        if (this.regtestEnabled) {
          return cashAddrPrefixToArray(REGTEST.CASHADDRPREFIX)
        } else if (this.stnEnabled) {
          return STN.cashAddrPrefixToArray(STN.CASHADDRPREFIX)
        } else {
          return cashAddrPrefixToArray(TESTNET.CASHADDRPREFIX)
        }
      }
    })
    
    /**
     * @function
     * @member Networks#enableRegtest
     * Will enable regtest features for testnet
     */
    function enableRegtest () {
      testnet.regtestEnabled = true
    }
    
    /**
     * @function
     * @member Networks#disableRegtest
     * Will disable regtest features for testnet
     */
    function disableRegtest () {
      testnet.regtestEnabled = false
    }
    /**
     * @function
     * @member Networks#enableStn
     * Will enable stn features for testnet
     */
    function enableStn () {
      testnet.stnEnabled = true
    }
    
    /**
     * @function
     * @member Networks#disableStn
     * Will disable stn features for testnet
     */
    function disableStn () {
      testnet.stnEnabled = false
    }
    
    /**
     * @namespace Networks
     */
    module.exports = {
      add: addNetwork,
      remove: removeNetwork,
      defaultNetwork: livenet,
      livenet: livenet,
      mainnet: livenet,
      testnet: testnet,
      regtest: regtest,
      stn: stn,
      get: get,
      enableRegtest: enableRegtest,
      disableRegtest: disableRegtest,
      enableStn: enableStn,
      disableStn: disableStn
    }
    
    },{"./util/_":270,"./util/js":271}],245:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('./util/_')
    var $ = require('./util/preconditions')
    var JSUtil = require('./util/js')
    
    function Opcode (num) {
      if (!(this instanceof Opcode)) {
        return new Opcode(num)
      }
    
      var value
    
      if (_.isNumber(num)) {
        value = num
      } else if (_.isString(num)) {
        value = Opcode.map[num]
      } else {
        throw new TypeError('Unrecognized num type: "' + typeof (num) + '" for Opcode')
      }
    
      JSUtil.defineImmutable(this, {
        num: value
      })
    
      return this
    }
    
    Opcode.fromBuffer = function (buf) {
      $.checkArgument(Buffer.isBuffer(buf))
      return new Opcode(Number('0x' + buf.toString('hex')))
    }
    
    Opcode.fromNumber = function (num) {
      $.checkArgument(_.isNumber(num))
      return new Opcode(num)
    }
    
    Opcode.fromString = function (str) {
      $.checkArgument(_.isString(str))
      var value = Opcode.map[str]
      if (typeof value === 'undefined') {
        throw new TypeError('Invalid opcodestr')
      }
      return new Opcode(value)
    }
    
    Opcode.prototype.toHex = function () {
      return this.num.toString(16)
    }
    
    Opcode.prototype.toBuffer = function () {
      return Buffer.from(this.toHex(), 'hex')
    }
    
    Opcode.prototype.toNumber = function () {
      return this.num
    }
    
    Opcode.prototype.toString = function () {
      var str = Opcode.reverseMap[this.num]
      if (typeof str === 'undefined') {
        throw new Error('Opcode does not have a string representation')
      }
      return str
    }
    
    Opcode.prototype.toSafeString = function () {
      var str = Opcode.reverseMap[this.num]
      if (typeof str === 'undefined') {
        return this.toHex()
      }
      return str
    }
    
    Opcode.smallInt = function (n) {
      $.checkArgument(_.isNumber(n), 'Invalid Argument: n should be number')
      $.checkArgument(n >= 0 && n <= 16, 'Invalid Argument: n must be between 0 and 16')
      if (n === 0) {
        return Opcode('OP_0')
      }
      return new Opcode(Opcode.map.OP_1 + n - 1)
    }
    
    Opcode.map = {
      // push value
      OP_FALSE: 0,
      OP_0: 0,
      OP_PUSHDATA1: 76,
      OP_PUSHDATA2: 77,
      OP_PUSHDATA4: 78,
      OP_1NEGATE: 79,
      OP_RESERVED: 80,
      OP_TRUE: 81,
      OP_1: 81,
      OP_2: 82,
      OP_3: 83,
      OP_4: 84,
      OP_5: 85,
      OP_6: 86,
      OP_7: 87,
      OP_8: 88,
      OP_9: 89,
      OP_10: 90,
      OP_11: 91,
      OP_12: 92,
      OP_13: 93,
      OP_14: 94,
      OP_15: 95,
      OP_16: 96,
    
      // control
      OP_NOP: 97,
      OP_VER: 98,
      OP_IF: 99,
      OP_NOTIF: 100,
      OP_VERIF: 101,
      OP_VERNOTIF: 102,
      OP_ELSE: 103,
      OP_ENDIF: 104,
      OP_VERIFY: 105,
      OP_RETURN: 106,
    
      // stack ops
      OP_TOALTSTACK: 107,
      OP_FROMALTSTACK: 108,
      OP_2DROP: 109,
      OP_2DUP: 110,
      OP_3DUP: 111,
      OP_2OVER: 112,
      OP_2ROT: 113,
      OP_2SWAP: 114,
      OP_IFDUP: 115,
      OP_DEPTH: 116,
      OP_DROP: 117,
      OP_DUP: 118,
      OP_NIP: 119,
      OP_OVER: 120,
      OP_PICK: 121,
      OP_ROLL: 122,
      OP_ROT: 123,
      OP_SWAP: 124,
      OP_TUCK: 125,
    
      // splice ops
      OP_CAT: 126,
      OP_SPLIT: 127,
      OP_NUM2BIN: 128,
      OP_BIN2NUM: 129,
      OP_SIZE: 130,
    
      // bit logic
      OP_INVERT: 131,
      OP_AND: 132,
      OP_OR: 133,
      OP_XOR: 134,
      OP_EQUAL: 135,
      OP_EQUALVERIFY: 136,
      OP_RESERVED1: 137,
      OP_RESERVED2: 138,
    
      // numeric
      OP_1ADD: 139,
      OP_1SUB: 140,
      OP_2MUL: 141,
      OP_2DIV: 142,
      OP_NEGATE: 143,
      OP_ABS: 144,
      OP_NOT: 145,
      OP_0NOTEQUAL: 146,
    
      OP_ADD: 147,
      OP_SUB: 148,
      OP_MUL: 149,
      OP_DIV: 150,
      OP_MOD: 151,
      OP_LSHIFT: 152,
      OP_RSHIFT: 153,
    
      OP_BOOLAND: 154,
      OP_BOOLOR: 155,
      OP_NUMEQUAL: 156,
      OP_NUMEQUALVERIFY: 157,
      OP_NUMNOTEQUAL: 158,
      OP_LESSTHAN: 159,
      OP_GREATERTHAN: 160,
      OP_LESSTHANOREQUAL: 161,
      OP_GREATERTHANOREQUAL: 162,
      OP_MIN: 163,
      OP_MAX: 164,
    
      OP_WITHIN: 165,
    
      // crypto
      OP_RIPEMD160: 166,
      OP_SHA1: 167,
      OP_SHA256: 168,
      OP_HASH160: 169,
      OP_HASH256: 170,
      OP_CODESEPARATOR: 171,
      OP_CHECKSIG: 172,
      OP_CHECKSIGVERIFY: 173,
      OP_CHECKMULTISIG: 174,
      OP_CHECKMULTISIGVERIFY: 175,
    
      OP_CHECKLOCKTIMEVERIFY: 177,
      OP_CHECKSEQUENCEVERIFY: 178,
    
      // expansion
      OP_NOP1: 176,
      OP_NOP2: 177,
      OP_NOP3: 178,
      OP_NOP4: 179,
      OP_NOP5: 180,
      OP_NOP6: 181,
      OP_NOP7: 182,
      OP_NOP8: 183,
      OP_NOP9: 184,
      OP_NOP10: 185,
    
      // template matching params
      OP_PUBKEYHASH: 253,
      OP_PUBKEY: 254,
      OP_INVALIDOPCODE: 255
    }
    
    Opcode.reverseMap = []
    
    for (var k in Opcode.map) {
      Opcode.reverseMap[Opcode.map[k]] = k
    }
    
    // Easier access to opcodes
    _.extend(Opcode, Opcode.map)
    
    /**
     * @returns true if opcode is one of OP_0, OP_1, ..., OP_16
     */
    Opcode.isSmallIntOp = function (opcode) {
      if (opcode instanceof Opcode) {
        opcode = opcode.toNumber()
      }
      return ((opcode === Opcode.map.OP_0) ||
        ((opcode >= Opcode.map.OP_1) && (opcode <= Opcode.map.OP_16)))
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {string} Script opcode
     */
    Opcode.prototype.inspect = function () {
      return '<Opcode: ' + this.toString() + ', hex: ' + this.toHex() + ', decimal: ' + this.num + '>'
    }
    
    module.exports = Opcode
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./util/_":270,"./util/js":271,"./util/preconditions":272,"buffer":84}],246:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('./util/_')
    var Address = require('./address')
    var Base58Check = require('./encoding/base58check')
    var BN = require('./crypto/bn')
    var JSUtil = require('./util/js')
    var Networks = require('./networks')
    var Point = require('./crypto/point')
    var PublicKey = require('./publickey')
    var Random = require('./crypto/random')
    var $ = require('./util/preconditions')
    
    /**
     * Instantiate a PrivateKey from a BN, Buffer or WIF string.
     *
     * @param {string} data - The encoded data in various formats
     * @param {Network|string=} network - a {@link Network} object, or a string with the network name
     * @returns {PrivateKey} A new valid instance of an PrivateKey
     * @constructor
     */
    function PrivateKey (data, network) {
      if (!(this instanceof PrivateKey)) {
        return new PrivateKey(data, network)
      }
      if (data instanceof PrivateKey) {
        return data
      }
    
      var info = this._classifyArguments(data, network)
    
      // validation
      if (!info.bn || info.bn.cmp(new BN(0)) === 0) {
        throw new TypeError('Number can not be equal to zero, undefined, null or false')
      }
      if (!info.bn.lt(Point.getN())) {
        throw new TypeError('Number must be less than N')
      }
      if (typeof (info.network) === 'undefined') {
        throw new TypeError('Must specify the network ("livenet" or "testnet")')
      }
    
      JSUtil.defineImmutable(this, {
        bn: info.bn,
        compressed: info.compressed,
        network: info.network
      })
    
      Object.defineProperty(this, 'publicKey', {
        configurable: false,
        enumerable: true,
        get: this.toPublicKey.bind(this)
      })
    
      return this
    };
    
    /**
     * Internal helper to instantiate PrivateKey internal `info` object from
     * different kinds of arguments passed to the constructor.
     *
     * @param {*} data
     * @param {Network|string=} network - a {@link Network} object, or a string with the network name
     * @return {Object}
     */
    PrivateKey.prototype._classifyArguments = function (data, network) {
      var info = {
        compressed: true,
        network: network ? Networks.get(network) : Networks.defaultNetwork
      }
    
      // detect type of data
      if (_.isUndefined(data) || _.isNull(data)) {
        info.bn = PrivateKey._getRandomBN()
      } else if (data instanceof BN) {
        info.bn = data
      } else if (data instanceof Buffer || data instanceof Uint8Array) {
        info = PrivateKey._transformBuffer(data, network)
      } else if (data.bn && data.network) {
        info = PrivateKey._transformObject(data)
      } else if (!network && Networks.get(data)) {
        info.bn = PrivateKey._getRandomBN()
        info.network = Networks.get(data)
      } else if (typeof (data) === 'string') {
        if (JSUtil.isHexa(data)) {
          info.bn = new BN(Buffer.from(data, 'hex'))
        } else {
          info = PrivateKey._transformWIF(data, network)
        }
      } else {
        throw new TypeError('First argument is an unrecognized data type.')
      }
      return info
    }
    
    /**
     * Internal function to get a random Big Number (BN)
     *
     * @returns {BN} A new randomly generated BN
     * @private
     */
    PrivateKey._getRandomBN = function () {
      var condition
      var bn
      do {
        var privbuf = Random.getRandomBuffer(32)
        bn = BN.fromBuffer(privbuf)
        condition = bn.lt(Point.getN())
      } while (!condition)
      return bn
    }
    
    /**
     * Internal function to transform a WIF Buffer into a private key
     *
     * @param {Buffer} buf - An WIF string
     * @param {Network|string=} network - a {@link Network} object, or a string with the network name
     * @returns {Object} An object with keys: bn, network and compressed
     * @private
     */
    PrivateKey._transformBuffer = function (buf, network) {
      var info = {}
    
      if (buf.length === 32) {
        return PrivateKey._transformBNBuffer(buf, network)
      }
    
      info.network = Networks.get(buf[0], 'privatekey')
    
      if (!info.network) {
        throw new Error('Invalid network')
      }
    
      if (network && info.network !== Networks.get(network)) {
        throw new TypeError('Private key network mismatch')
      }
    
      if (buf.length === 1 + 32 + 1 && buf[1 + 32 + 1 - 1] === 1) {
        info.compressed = true
      } else if (buf.length === 1 + 32) {
        info.compressed = false
      } else {
        throw new Error('Length of buffer must be 33 (uncompressed) or 34 (compressed)')
      }
    
      info.bn = BN.fromBuffer(buf.slice(1, 32 + 1))
    
      return info
    }
    
    /**
     * Internal function to transform a BN buffer into a private key
     *
     * @param {Buffer} buf
     * @param {Network|string=} network - a {@link Network} object, or a string with the network name
     * @returns {object} an Object with keys: bn, network, and compressed
     * @private
     */
    PrivateKey._transformBNBuffer = function (buf, network) {
      var info = {}
      info.network = Networks.get(network) || Networks.defaultNetwork
      info.bn = BN.fromBuffer(buf)
      info.compressed = false
      return info
    }
    
    /**
     * Internal function to transform a WIF string into a private key
     *
     * @param {string} buf - An WIF string
     * @returns {Object} An object with keys: bn, network and compressed
     * @private
     */
    PrivateKey._transformWIF = function (str, network) {
      return PrivateKey._transformBuffer(Base58Check.decode(str), network)
    }
    
    /**
     * Instantiate a PrivateKey from a Buffer with the DER or WIF representation
     *
     * @param {Buffer} buf
     * @param {Network} network
     * @return {PrivateKey}
     */
    PrivateKey.fromBuffer = function (buf, network) {
      return new PrivateKey(buf, network)
    }
    
    PrivateKey.fromHex = function (hex, network) {
      return PrivateKey.fromBuffer(Buffer.from(hex, 'hex'), network)
    }
    
    /**
     * Internal function to transform a JSON string on plain object into a private key
     * return this.
     *
     * @param {string} json - A JSON string or plain object
     * @returns {Object} An object with keys: bn, network and compressed
     * @private
     */
    PrivateKey._transformObject = function (json) {
      var bn = new BN(json.bn, 'hex')
      var network = Networks.get(json.network)
      return {
        bn: bn,
        network: network,
        compressed: json.compressed
      }
    }
    
    /**
     * Instantiate a PrivateKey from a WIF string
     *
     * @param {string} str - The WIF encoded private key string
     * @returns {PrivateKey} A new valid instance of PrivateKey
     */
    PrivateKey.fromString = PrivateKey.fromWIF = function (str) {
      $.checkArgument(_.isString(str), 'First argument is expected to be a string.')
      return new PrivateKey(str)
    }
    
    /**
     * Instantiate a PrivateKey from a plain JavaScript object
     *
     * @param {Object} obj - The output from privateKey.toObject()
     */
    PrivateKey.fromObject = PrivateKey.fromJSON = function (obj) {
      $.checkArgument(_.isObject(obj), 'First argument is expected to be an object.')
      return new PrivateKey(obj)
    }
    
    /**
     * Instantiate a PrivateKey from random bytes
     *
     * @param {string=} network - Either "livenet" or "testnet"
     * @returns {PrivateKey} A new valid instance of PrivateKey
     */
    PrivateKey.fromRandom = function (network) {
      var bn = PrivateKey._getRandomBN()
      return new PrivateKey(bn, network)
    }
    
    /**
     * Check if there would be any errors when initializing a PrivateKey
     *
     * @param {string} data - The encoded data in various formats
     * @param {string=} network - Either "livenet" or "testnet"
     * @returns {null|Error} An error if exists
     */
    
    PrivateKey.getValidationError = function (data, network) {
      var error
      try {
        new PrivateKey(data, network) // eslint-disable-line
      } catch (e) {
        error = e
      }
      return error
    }
    
    /**
     * Check if the parameters are valid
     *
     * @param {string} data - The encoded data in various formats
     * @param {string=} network - Either "livenet" or "testnet"
     * @returns {Boolean} If the private key is would be valid
     */
    PrivateKey.isValid = function (data, network) {
      if (!data) {
        return false
      }
      return !PrivateKey.getValidationError(data, network)
    }
    
    /**
     * Will output the PrivateKey in WIF
     *
     * @returns {string}
     */
    PrivateKey.prototype.toString = function () {
      return this.toWIF()
    }
    
    /**
     * Will output the PrivateKey to a WIF string
     *
     * @returns {string} A WIP representation of the private key
     */
    PrivateKey.prototype.toWIF = function () {
      var network = this.network
      var compressed = this.compressed
    
      var buf
      if (compressed) {
        buf = Buffer.concat([Buffer.from([network.privatekey]),
          this.bn.toBuffer({ size: 32 }),
          Buffer.from([0x01])])
      } else {
        buf = Buffer.concat([Buffer.from([network.privatekey]),
          this.bn.toBuffer({ size: 32 })])
      }
    
      return Base58Check.encode(buf)
    }
    
    /**
     * Will return the private key as a BN instance
     *
     * @returns {BN} A BN instance of the private key
     */
    PrivateKey.prototype.toBigNumber = function () {
      return this.bn
    }
    
    /**
     * Will return the private key as a BN buffer
     *
     * @returns {Buffer} A buffer of the private key
     */
    PrivateKey.prototype.toBuffer = function () {
      return this.bn.toBuffer({ size: 32 })
    }
    
    PrivateKey.prototype.toHex = function () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * Will return the corresponding public key
     *
     * @returns {PublicKey} A public key generated from the private key
     */
    PrivateKey.prototype.toPublicKey = function () {
      if (!this._pubkey) {
        this._pubkey = PublicKey.fromPrivateKey(this)
      }
      return this._pubkey
    }
    
    /**
     * Will return an address for the private key
     * @param {Network=} network - optional parameter specifying
     * the desired network for the address
     *
     * @returns {Address} An address generated from the private key
     */
    PrivateKey.prototype.toAddress = function (network) {
      var pubkey = this.toPublicKey()
      return Address.fromPublicKey(pubkey, network || this.network)
    }
    
    /**
     * @returns {Object} A plain object representation
     */
    PrivateKey.prototype.toObject = PrivateKey.prototype.toJSON = function toObject () {
      return {
        bn: this.bn.toString('hex'),
        compressed: this.compressed,
        network: this.network.toString()
      }
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {string} Private key
     */
    PrivateKey.prototype.inspect = function () {
      var uncompressed = !this.compressed ? ', uncompressed' : ''
      return '<PrivateKey: ' + this.toHex() + ', network: ' + this.network + uncompressed + '>'
    }
    
    module.exports = PrivateKey
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./address":200,"./crypto/bn":205,"./crypto/point":210,"./crypto/random":211,"./encoding/base58check":218,"./networks":244,"./publickey":247,"./util/_":270,"./util/js":271,"./util/preconditions":272,"buffer":84}],247:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var BN = require('./crypto/bn')
    var Point = require('./crypto/point')
    var Hash = require('./crypto/hash')
    var JSUtil = require('./util/js')
    var Network = require('./networks')
    var _ = require('./util/_')
    var $ = require('./util/preconditions')
    
    /**
     * Instantiate a PublicKey from a {@link PrivateKey}, {@link Point}, `string`, or `Buffer`.
     *
     * There are two internal properties, `network` and `compressed`, that deal with importing
     * a PublicKey from a PrivateKey in WIF format. More details described on {@link PrivateKey}
     *
     * @example
     * ```javascript
     * // instantiate from a private key
     * var key = PublicKey(privateKey, true);
     *
     * // export to as a DER hex encoded string
     * var exported = key.toString();
     *
     * // import the public key
     * var imported = PublicKey.fromString(exported);
     * ```
     *
     * @param {string} data - The encoded data in various formats
     * @param {Object} extra - additional options
     * @param {Network=} extra.network - Which network should the address for this public key be for
     * @param {String=} extra.compressed - If the public key is compressed
     * @returns {PublicKey} A new valid instance of an PublicKey
     * @constructor
     */
    function PublicKey (data, extra) {
      if (!(this instanceof PublicKey)) {
        return new PublicKey(data, extra)
      }
    
      $.checkArgument(data, 'First argument is required, please include public key data.')
    
      if (data instanceof PublicKey) {
        // Return copy, but as it's an immutable object, return same argument
        return data
      }
      extra = extra || {}
    
      var info = this._classifyArgs(data, extra)
    
      // validation
      info.point.validate()
    
      JSUtil.defineImmutable(this, {
        point: info.point,
        compressed: info.compressed,
        network: info.network || Network.defaultNetwork
      })
    
      return this
    };
    
    /**
     * Internal function to differentiate between arguments passed to the constructor
     * @param {*} data
     * @param {Object} extra
     */
    PublicKey.prototype._classifyArgs = function (data, extra) {
      var info = {
        compressed: _.isUndefined(extra.compressed) || extra.compressed
      }
    
      // detect type of data
      if (data instanceof Point) {
        info.point = data
      } else if (data.x && data.y) {
        info = PublicKey._transformObject(data)
      } else if (typeof (data) === 'string') {
        info = PublicKey._transformDER(Buffer.from(data, 'hex'))
      } else if (PublicKey._isBuffer(data)) {
        info = PublicKey._transformDER(data)
      } else if (PublicKey._isPrivateKey(data)) {
        info = PublicKey._transformPrivateKey(data)
      } else {
        throw new TypeError('First argument is an unrecognized data format.')
      }
      if (!info.network) {
        info.network = _.isUndefined(extra.network) ? undefined : Network.get(extra.network)
      }
      return info
    }
    
    /**
     * Internal function to detect if an object is a {@link PrivateKey}
     *
     * @param {*} param - object to test
     * @returns {boolean}
     * @private
     */
    PublicKey._isPrivateKey = function (param) {
      var PrivateKey = require('./privatekey')
      return param instanceof PrivateKey
    }
    
    /**
     * Internal function to detect if an object is a Buffer
     *
     * @param {*} param - object to test
     * @returns {boolean}
     * @private
     */
    PublicKey._isBuffer = function (param) {
      return (param instanceof Buffer) || (param instanceof Uint8Array)
    }
    
    /**
     * Internal function to transform a private key into a public key point
     *
     * @param {PrivateKey} privkey - An instance of PrivateKey
     * @returns {Object} An object with keys: point and compressed
     * @private
     */
    PublicKey._transformPrivateKey = function (privkey) {
      $.checkArgument(PublicKey._isPrivateKey(privkey), 'Must be an instance of PrivateKey')
      var info = {}
      info.point = Point.getG().mul(privkey.bn)
      info.compressed = privkey.compressed
      info.network = privkey.network
      return info
    }
    
    /**
     * Internal function to transform DER into a public key point
     *
     * @param {Buffer} buf - An DER buffer
     * @param {bool=} strict - if set to false, will loosen some conditions
     * @returns {Object} An object with keys: point and compressed
     * @private
     */
    PublicKey._transformDER = function (buf, strict) {
      $.checkArgument(PublicKey._isBuffer(buf), 'Must be a buffer of DER encoded public key')
      var info = {}
    
      strict = _.isUndefined(strict) ? true : strict
    
      var x
      var y
      var xbuf
      var ybuf
    
      if (buf[0] === 0x04 || (!strict && (buf[0] === 0x06 || buf[0] === 0x07))) {
        xbuf = buf.slice(1, 33)
        ybuf = buf.slice(33, 65)
        if (xbuf.length !== 32 || ybuf.length !== 32 || buf.length !== 65) {
          throw new TypeError('Length of x and y must be 32 bytes')
        }
        x = new BN(xbuf)
        y = new BN(ybuf)
        info.point = new Point(x, y)
        info.compressed = false
      } else if (buf[0] === 0x03) {
        xbuf = buf.slice(1)
        x = new BN(xbuf)
        info = PublicKey._transformX(true, x)
        info.compressed = true
      } else if (buf[0] === 0x02) {
        xbuf = buf.slice(1)
        x = new BN(xbuf)
        info = PublicKey._transformX(false, x)
        info.compressed = true
      } else {
        throw new TypeError('Invalid DER format public key')
      }
      return info
    }
    
    /**
     * Internal function to transform X into a public key point
     *
     * @param {Boolean} odd - If the point is above or below the x axis
     * @param {Point} x - The x point
     * @returns {Object} An object with keys: point and compressed
     * @private
     */
    PublicKey._transformX = function (odd, x) {
      $.checkArgument(typeof odd === 'boolean', 'Must specify whether y is odd or not (true or false)')
      var info = {}
      info.point = Point.fromX(odd, x)
      return info
    }
    
    /**
     * Internal function to transform a JSON into a public key point
     *
     * @param {String|Object} json - a JSON string or plain object
     * @returns {Object} An object with keys: point and compressed
     * @private
     */
    PublicKey._transformObject = function (json) {
      var x = new BN(json.x, 'hex')
      var y = new BN(json.y, 'hex')
      var point = new Point(x, y)
      return new PublicKey(point, {
        compressed: json.compressed
      })
    }
    
    /**
     * Instantiate a PublicKey from a PrivateKey
     *
     * @param {PrivateKey} privkey - An instance of PrivateKey
     * @returns {PublicKey} A new valid instance of PublicKey
     */
    PublicKey.fromPrivateKey = function (privkey) {
      $.checkArgument(PublicKey._isPrivateKey(privkey), 'Must be an instance of PrivateKey')
      var info = PublicKey._transformPrivateKey(privkey)
      return new PublicKey(info.point, {
        compressed: info.compressed,
        network: info.network
      })
    }
    
    /**
     * Instantiate a PublicKey from a Buffer
     * @param {Buffer} buf - A DER buffer
     * @param {bool=} strict - if set to false, will loosen some conditions
     * @returns {PublicKey} A new valid instance of PublicKey
     */
    PublicKey.fromDER = PublicKey.fromBuffer = function (buf, strict) {
      $.checkArgument(PublicKey._isBuffer(buf), 'Must be a buffer of DER encoded public key')
      var info = PublicKey._transformDER(buf, strict)
      return new PublicKey(info.point, {
        compressed: info.compressed
      })
    }
    
    /**
     * Instantiate a PublicKey from a Point
     *
     * @param {Point} point - A Point instance
     * @param {boolean=} compressed - whether to store this public key as compressed format
     * @returns {PublicKey} A new valid instance of PublicKey
     */
    PublicKey.fromPoint = function (point, compressed) {
      $.checkArgument(point instanceof Point, 'First argument must be an instance of Point.')
      return new PublicKey(point, {
        compressed: compressed
      })
    }
    
    /**
     * Instantiate a PublicKey from a DER hex encoded string
     *
     * @param {string} str - A DER hex string
     * @param {String=} encoding - The type of string encoding
     * @returns {PublicKey} A new valid instance of PublicKey
     */
    PublicKey.fromHex = PublicKey.fromString = function (str, encoding) {
      var buf = Buffer.from(str, encoding || 'hex')
      var info = PublicKey._transformDER(buf)
      return new PublicKey(info.point, {
        compressed: info.compressed
      })
    }
    
    /**
     * Instantiate a PublicKey from an X Point
     *
     * @param {Boolean} odd - If the point is above or below the x axis
     * @param {Point} x - The x point
     * @returns {PublicKey} A new valid instance of PublicKey
     */
    PublicKey.fromX = function (odd, x) {
      var info = PublicKey._transformX(odd, x)
      return new PublicKey(info.point, {
        compressed: info.compressed
      })
    }
    
    /**
     * Check if there would be any errors when initializing a PublicKey
     *
     * @param {string} data - The encoded data in various formats
     * @returns {null|Error} An error if exists
     */
    PublicKey.getValidationError = function (data) {
      var error
      try {
        new PublicKey(data) // eslint-disable-line
      } catch (e) {
        error = e
      }
      return error
    }
    
    /**
     * Check if the parameters are valid
     *
     * @param {string} data - The encoded data in various formats
     * @returns {Boolean} If the public key would be valid
     */
    PublicKey.isValid = function (data) {
      return !PublicKey.getValidationError(data)
    }
    
    /**
     * @returns {Object} A plain object of the PublicKey
     */
    PublicKey.prototype.toObject = PublicKey.prototype.toJSON = function toObject () {
      return {
        x: this.point.getX().toString('hex', 2),
        y: this.point.getY().toString('hex', 2),
        compressed: this.compressed
      }
    }
    
    /**
     * Will output the PublicKey to a DER Buffer
     *
     * @returns {Buffer} A DER hex encoded buffer
     */
    PublicKey.prototype.toBuffer = PublicKey.prototype.toDER = function () {
      var x = this.point.getX()
      var y = this.point.getY()
    
      var xbuf = x.toBuffer({
        size: 32
      })
      var ybuf = y.toBuffer({
        size: 32
      })
    
      var prefix
      if (!this.compressed) {
        prefix = Buffer.from([0x04])
        return Buffer.concat([prefix, xbuf, ybuf])
      } else {
        var odd = ybuf[ybuf.length - 1] % 2
        if (odd) {
          prefix = Buffer.from([0x03])
        } else {
          prefix = Buffer.from([0x02])
        }
        return Buffer.concat([prefix, xbuf])
      }
    }
    
    /**
     * Will return a sha256 + ripemd160 hash of the serialized public key
     * @see https://github.com/bitcoin/bitcoin/blob/master/src/pubkey.h#L141
     * @returns {Buffer}
     */
    PublicKey.prototype._getID = function _getID () {
      return Hash.sha256ripemd160(this.toBuffer())
    }
    
    /**
     * Will return an address for the public key
     *
     * @param {String|Network=} network - Which network should the address be for
     * @returns {Address} An address generated from the public key
     */
    PublicKey.prototype.toAddress = function (network) {
      var Address = require('./address')
      return Address.fromPublicKey(this, network || this.network)
    }
    
    /**
     * Will output the PublicKey to a DER encoded hex string
     *
     * @returns {string} A DER hex encoded string
     */
    PublicKey.prototype.toString = PublicKey.prototype.toHex = function () {
      return this.toDER().toString('hex')
    }
    
    /**
     * Will return a string formatted for the console
     *
     * @returns {string} Public key
     */
    PublicKey.prototype.inspect = function () {
      return '<PublicKey: ' + this.toHex() +
        (this.compressed ? '' : ', uncompressed') + '>'
    }
    
    module.exports = PublicKey
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./address":200,"./crypto/bn":205,"./crypto/hash":208,"./crypto/point":210,"./networks":244,"./privatekey":246,"./util/_":270,"./util/js":271,"./util/preconditions":272,"buffer":84}],248:[function(require,module,exports){
    module.exports = require('./script')
    
    module.exports.Interpreter = require('./interpreter')
    
    module.exports.Stack = require('./stack')
    
    },{"./interpreter":249,"./script":250,"./stack":251}],249:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    
    var Script = require('./script')
    var Opcode = require('../opcode')
    var BN = require('../crypto/bn')
    var Hash = require('../crypto/hash')
    var Signature = require('../crypto/signature')
    var PublicKey = require('../publickey')
    var Stack = require('./stack')
    /**
     * Bitcoin transactions contain scripts. Each input has a script called the
     * scriptSig, and each output has a script called the scriptPubkey. To validate
     * an input, the input's script is concatenated with the referenced output script,
     * and the result is executed. If at the end of execution the stack contains a
     * "true" value, then the transaction is valid.
     *
     * The primary way to use this class is via the verify function.
     * e.g., Interpreter().verify( ... );
     */
    var Interpreter = function Interpreter (obj) {
      if (!(this instanceof Interpreter)) {
        return new Interpreter(obj)
      }
      if (obj) {
        this.initialize()
        this.set(obj)
      } else {
        this.initialize()
      }
    }
    
    /**
     * Verifies a Script by executing it and returns true if it is valid.
     * This function needs to be provided with the scriptSig and the scriptPubkey
     * separately.
     * @param {Script} scriptSig - the script's first part (corresponding to the tx input)
     * @param {Script} scriptPubkey - the script's last part (corresponding to the tx output)
     * @param {Transaction=} tx - the Transaction containing the scriptSig in one input (used
     *    to check signature validity for some opcodes like OP_CHECKSIG)
     * @param {number} nin - index of the transaction input containing the scriptSig verified.
     * @param {number} flags - evaluation flags. See Interpreter.SCRIPT_* constants
     * @param {number} satoshisBN - amount in satoshis of the input to be verified (when FORKID signhash is used)
     *
     * Translated from bitcoind's VerifyScript
     */
    Interpreter.prototype.verify = function (scriptSig, scriptPubkey, tx, nin, flags, satoshisBN, sighashScript) {
      var Transaction = require('../transaction')
    
      if (_.isUndefined(tx)) {
        tx = new Transaction()
      }
      if (_.isUndefined(nin)) {
        nin = 0
      }
      if (_.isUndefined(flags)) {
        flags = 0
      }
    
      // If FORKID is enabled, we also ensure strict encoding.
      if (flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) {
        flags |= Interpreter.SCRIPT_VERIFY_STRICTENC
    
        // If FORKID is enabled, we need the input amount.
        if (!satoshisBN) {
          throw new Error('internal error - need satoshisBN to verify FORKID transactions')
        }
      }
    
      this.set({
        script: scriptSig,
        tx: tx,
        nin: nin,
        flags: flags,
        satoshisBN: satoshisBN,
        sighashScript: sighashScript
      })
      var stackCopy
    
      if ((flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY) !== 0 && !scriptSig.isPushOnly()) {
        this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
        return false
      }
    
      // evaluate scriptSig
      if (!this.evaluate('scriptSig')) {
        return false
      }
    
      if (flags & Interpreter.SCRIPT_VERIFY_P2SH) {
        stackCopy = this.stack.copy()
      }
    
      var stack = this.stack
      this.initialize()
      this.set({
        script: scriptPubkey,
        stack: stack,
        tx: tx,
        nin: nin,
        flags: flags,
        satoshisBN: satoshisBN,
        sighashScript: sighashScript
      })
    
      // evaluate scriptPubkey
      if (!this.evaluate('scriptPubkey')) {
        return false
      }
    
      if (this.stack.length === 0) {
        this.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_RESULT'
        return false
      }
    
      var buf = this.stack.stacktop(-1)
      if (!Interpreter.castToBool(buf)) {
        this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'
        return false
      }
    
      // Additional validation for spend-to-script-hash transactions:
      if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) && scriptPubkey.isScriptHashOut()) {
        // scriptSig must be literals-only or validation fails
        if (!scriptSig.isPushOnly()) {
          this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'
          return false
        }
    
        // stackCopy cannot be empty here, because if it was the
        // P2SH  HASH <> EQUAL  scriptPubKey would be evaluated with
        // an empty stack and the EvalScript above would return false.
        if (stackCopy.length === 0) {
          throw new Error('internal error - stack copy empty')
        }
    
        var redeemScriptSerialized = stackCopy.stacktop(-1)
        var redeemScript = Script.fromBuffer(redeemScriptSerialized)
        stackCopy.pop()
    
        this.initialize()
        this.set({
          script: redeemScript,
          stack: stackCopy,
          tx: tx,
          nin: nin,
          flags: flags,
          satoshisBN: satoshisBN
        })
    
        // evaluate redeemScript
        if (!this.evaluate()) {
          return false
        }
    
        if (stackCopy.length === 0) {
          this.errstr = 'SCRIPT_ERR_EVAL_FALSE_NO_P2SH_STACK'
          return false
        }
    
        if (!Interpreter.castToBool(stackCopy.stacktop(-1))) {
          this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_P2SH_STACK'
          return false
        }
      }
    
      // The CLEANSTACK check is only performed after potential P2SH evaluation,
      // as the non-P2SH evaluation of a P2SH script will obviously not result in
      // a clean stack (the P2SH inputs remain). The same holds for witness
      // evaluation.
      if ((flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) !== 0) {
        // Disallow CLEANSTACK without P2SH, as otherwise a switch
        // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a
        // softfork (and P2SH should be one).
        // if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) === 0) {
        //   throw new Error('internal error - CLEANSTACK without P2SH')
        // }
    
        if (this.stack.length !== 1) {
          this.errstr = 'SCRIPT_ERR_CLEANSTACK'
          return false
        }
      }
    
      return true
    }
    
    module.exports = Interpreter
    
    Interpreter.prototype.initialize = function (obj) {
      this.stack = new Stack([])
      this.altstack = new Stack([])
      this.pc = 0
      this.pbegincodehash = 0
      this.nOpCount = 0
      this.vfExec = []
      this.errstr = ''
      this.flags = 0
      // if OP_RETURN is found in executed branches after genesis is activated,
      // we still have to check if the rest of the script is valid
      this.nonTopLevelReturnAfterGenesis = false
      this.returned = false
    }
    
    Interpreter.prototype.set = function (obj) {
      this.script = obj.script || this.script
      this.tx = obj.tx || this.tx
      this.nin = typeof obj.nin !== 'undefined' ? obj.nin : this.nin
      this.satoshisBN = obj.satoshisBN || this.satoshisBN
      this.stack = obj.stack || this.stack
      this.altstack = obj.altstack || this.altstack
      this.pc = typeof obj.pc !== 'undefined' ? obj.pc : this.pc
      this.pbegincodehash = typeof obj.pbegincodehash !== 'undefined' ? obj.pbegincodehash : this.pbegincodehash
      this.nOpCount = typeof obj.nOpCount !== 'undefined' ? obj.nOpCount : this.nOpCount
      this.vfExec = obj.vfExec || this.vfExec
      this.errstr = obj.errstr || this.errstr
      this.flags = typeof obj.flags !== 'undefined' ? obj.flags : this.flags
      this.sighashScript = obj.sighashScript || this.sighashScript
    }
    
    Interpreter.prototype.subscript = function () {
      if (this.sighashScript) {
        return this.sighashScript.clone()
      } else {
        // Subset of script starting at the most recent codeseparator
        // CScript scriptCode(pbegincodehash, pend);
        return Script.fromChunks(this.script.chunks.slice(this.pbegincodehash))
      }
    }
    
    Interpreter.getTrue = () => Buffer.from([1])
    Interpreter.getFalse = () => Buffer.from([])
    
    Interpreter.MAX_SCRIPT_ELEMENT_SIZE = 520
    Interpreter.MAXIMUM_ELEMENT_SIZE = 4
    
    Interpreter.LOCKTIME_THRESHOLD = 500000000
    Interpreter.LOCKTIME_THRESHOLD_BN = new BN(Interpreter.LOCKTIME_THRESHOLD)
    
    // flags taken from bitcoind
    // bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
    Interpreter.SCRIPT_VERIFY_NONE = 0
    
    // Evaluate P2SH subscripts (softfork safe, BIP16).
    Interpreter.SCRIPT_VERIFY_P2SH = (1 << 0)
    
    // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
    // Passing a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) to checksig causes that pubkey to be
    // skipped (not softfork safe: this flag can widen the validity of OP_CHECKSIG OP_NOT).
    Interpreter.SCRIPT_VERIFY_STRICTENC = (1 << 1)
    
    // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
    Interpreter.SCRIPT_VERIFY_DERSIG = (1 << 2)
    
    // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
    // (softfork safe, BIP62 rule 5).
    Interpreter.SCRIPT_VERIFY_LOW_S = (1 << 3)
    
    // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
    Interpreter.SCRIPT_VERIFY_NULLDUMMY = (1 << 4)
    
    // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
    Interpreter.SCRIPT_VERIFY_SIGPUSHONLY = (1 << 5)
    
    // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
    // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
    // any other push causes the script to fail (BIP62 rule 3).
    // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
    // (softfork safe)
    Interpreter.SCRIPT_VERIFY_MINIMALDATA = (1 << 6)
    
    // Discourage use of NOPs reserved for upgrades (NOP1-10)
    //
    // Provided so that nodes can avoid accepting or mining transactions
    // containing executed NOP's whose meaning may change after a soft-fork,
    // thus rendering the script invalid; with this flag set executing
    // discouraged NOPs fails the script. This verification flag will never be
    // a mandatory flag applied to scripts in a block. NOPs that are not
    // executed, e.g.  within an unexecuted IF ENDIF block, are *not* rejected.
    Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 7)
    
    // Require that only a single stack element remains after evaluation. This
    // changes the success criterion from "At least one stack element must
    // remain, and when interpreted as a boolean, it must be true" to "Exactly
    // one stack element must remain, and when interpreted as a boolean, it must
    // be true".
    // (softfork safe, BIP62 rule 6)
    // Note: CLEANSTACK should never be used without P2SH or WITNESS.
    Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8)
    
    // CLTV See BIP65 for details.
    Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1 << 9)
    
    // support CHECKSEQUENCEVERIFY opcode
    //
    // See BIP112 for details
    Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1 << 10)
    
    // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly
    // 0x01 or empty vector
    //
    Interpreter.SCRIPT_VERIFY_MINIMALIF = (1 << 13)
    
    // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
    //
    Interpreter.SCRIPT_VERIFY_NULLFAIL = (1 << 14)
    
    // Public keys in scripts must be compressed
    Interpreter.SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = (1 << 15)
    
    // Do we accept signature using SIGHASH_FORKID
    //
    Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID = (1 << 16)
    
    // Do we accept activate replay protection using a different fork id.
    //
    Interpreter.SCRIPT_ENABLE_REPLAY_PROTECTION = (1 << 17)
    
    // Enable new opcodes.
    //
    Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES = (1 << 18)
    
    // Are the Magnetic upgrade opcodes enabled?
    //
    Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES = (1 << 19)
    
    /* Below flags apply in the context of BIP 68 */
    /**
     * If this flag set, CTxIn::nSequence is NOT interpreted as a relative
     * lock-time.
     */
    Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31)
    
    /**
     * If CTxIn::nSequence encodes a relative lock-time and this flag is set,
     * the relative lock-time has units of 512 seconds, otherwise it specifies
     * blocks with a granularity of 1.
     */
    Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22)
    
    /**
     * If CTxIn::nSequence encodes a relative lock-time, this mask is applied to
     * extract that lock-time from the sequence field.
     */
    Interpreter.SEQUENCE_LOCKTIME_MASK = 0x0000ffff
    
    Interpreter.MAX_SCRIPT_SIZE = Number.MAX_SAFE_INTEGER
    
    Interpreter.MAX_OPCODE_COUNT = Number.MAX_SAFE_INTEGER
    
    Interpreter.castToBool = function (buf) {
      for (var i = 0; i < buf.length; i++) {
        if (buf[i] !== 0) {
          // can be negative zero
          if (i === buf.length - 1 && buf[i] === 0x80) {
            return false
          }
          return true
        }
      }
      return false
    }
    
    /**
     * Translated from bitcoind's CheckSignatureEncoding
     */
    Interpreter.prototype.checkSignatureEncoding = function (buf) {
      var sig
    
      // Empty signature. Not strictly DER encoded, but allowed to provide a
      // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
      if (buf.length === 0) {
        return true
      }
    
      if ((this.flags & (Interpreter.SCRIPT_VERIFY_DERSIG | Interpreter.SCRIPT_VERIFY_LOW_S | Interpreter.SCRIPT_VERIFY_STRICTENC)) !== 0 && !Signature.isTxDER(buf)) {
        this.errstr = 'SCRIPT_ERR_SIG_DER_INVALID_FORMAT'
        return false
      } else if ((this.flags & Interpreter.SCRIPT_VERIFY_LOW_S) !== 0) {
        sig = Signature.fromTxFormat(buf)
        if (!sig.hasLowS()) {
          this.errstr = 'SCRIPT_ERR_SIG_DER_HIGH_S'
          return false
        }
      } else if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0) {
        sig = Signature.fromTxFormat(buf)
        if (!sig.hasDefinedHashtype()) {
          this.errstr = 'SCRIPT_ERR_SIG_HASHTYPE'
          return false
        }
    
        if (!(this.flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) &&
          (sig.nhashtype & Signature.SIGHASH_FORKID)) {
          this.errstr = 'SCRIPT_ERR_ILLEGAL_FORKID'
          return false
        }
    
        if ((this.flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID) &&
          !(sig.nhashtype & Signature.SIGHASH_FORKID)) {
          this.errstr = 'SCRIPT_ERR_MUST_USE_FORKID'
          return false
        }
      }
    
      return true
    }
    
    /**
     * Translated from bitcoind's CheckPubKeyEncoding
     */
    Interpreter.prototype.checkPubkeyEncoding = function (buf) {
      if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0 && !PublicKey.isValid(buf)) {
        this.errstr = 'SCRIPT_ERR_PUBKEYTYPE'
        return false
      }
      return true
    }
    
    /**
      *
      * Check the buffer is minimally encoded (see https://github.com/bitcoincashorg/spec/blob/master/may-2018-reenabled-opcodes.md#op_bin2num)
      *
      *
      */
    
    Interpreter._isMinimallyEncoded = function (buf, nMaxNumSize) {
      nMaxNumSize = nMaxNumSize || Interpreter.MAXIMUM_ELEMENT_SIZE
      if (buf.length > nMaxNumSize) {
        return false
      }
    
      if (buf.length > 0) {
        // Check that the number is encoded with the minimum possible number
        // of bytes.
        //
        // If the most-significant-byte - excluding the sign bit - is zero
        // then we're not minimal. Note how this test also rejects the
        // negative-zero encoding, 0x80.
        if ((buf[buf.length - 1] & 0x7f) === 0) {
          // One exception: if there's more than one byte and the most
          // significant bit of the second-most-significant-byte is set it
          // would conflict with the sign bit. An example of this case is
          // +-255, which encode to 0xff00 and 0xff80 respectively.
          // (big-endian).
          if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
            return false
          }
        }
      }
      return true
    }
    
    /**
      *
      * minimally encode the buffer content
      *
      * @param {number} nMaxNumSize (max allowed size)
      */
    Interpreter._minimallyEncode = function (buf) {
      if (buf.length === 0) {
        return buf
      }
    
      // If the last byte is not 0x00 or 0x80, we are minimally encoded.
      var last = buf[buf.length - 1]
      if (last & 0x7f) {
        return buf
      }
    
      // If the script is one byte long, then we have a zero, which encodes as an
      // empty array.
      if (buf.length === 1) {
        return Buffer.from('')
      }
    
      // If the next byte has it sign bit set, then we are minimaly encoded.
      if (buf[buf.length - 2] & 0x80) {
        return buf
      }
    
      // We are not minimally encoded, we need to figure out how much to trim.
      for (var i = buf.length - 1; i > 0; i--) {
        // We found a non zero byte, time to encode.
        if (buf[i - 1] !== 0) {
          if (buf[i - 1] & 0x80) {
            // We found a byte with it sign bit set so we need one more
            // byte.
            buf[i++] = last
          } else {
            // the sign bit is clear, we can use it.
            buf[i - 1] |= last
          }
    
          return buf.slice(0, i)
        }
      }
    
      // If we found the whole thing is zeros, then we have a zero.
      return Buffer.from('')
    }
    
    /**
     * Based on bitcoind's EvalScript function, with the inner loop moved to
     * Interpreter.prototype.step()
     * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
     */
    Interpreter.prototype.evaluate = function (scriptType) {
      // TODO: script size should be configurable. no magic numbers
      if (this.script.toBuffer().length > Interpreter.MAX_SCRIPT_SIZE) {
        this.errstr = 'SCRIPT_ERR_SCRIPT_SIZE'
        return false
      }
    
      try {
        while (!this.returned && this.pc < this.script.chunks.length) {
          // fExec: if the opcode will be executed, i.e., not in a false branch
          let thisStep = { pc: this.pc, fExec: (this.vfExec.indexOf(false) === -1), opcode: Opcode.fromNumber(this.script.chunks[this.pc].opcodenum) }
    
          var fSuccess = this.step(scriptType)
    
          this._callbackStep(thisStep)
    
          if (!fSuccess) {
            return false
          }
        }
    
        // Size limits
        if (this.stack.length + this.altstack.length > 1000) {
          this.errstr = 'SCRIPT_ERR_STACK_SIZE'
          return false
        }
      } catch (e) {
        this.errstr = 'SCRIPT_ERR_UNKNOWN_ERROR: ' + e
        return false
      }
    
      if (this.vfExec.length > 0) {
        this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL'
        return false
      }
    
      return true
    }
    
    Interpreter.prototype._callbackStep = function (thisStep) {
      if (typeof this.stepListener === 'function') {
        try {
          this.stepListener(thisStep)
        } catch (err) {
          console.log(`Error in Step callback:${err}`)
        }
      }
    }
    
    /**
     * call to update stackvar
     * @param {*} stack
     */
    Interpreter.prototype._callbackStack = function (stack, pc, scriptType) {
      if (typeof this.stackListener === 'function') {
        try {
          this.stackListener(stack, pc, scriptType)
        } catch (err) {
          var chunk = this.script.chunks[pc]
          console.error(`Error: ${err} in _updateStack pc: ${pc}, opcode ${Opcode.fromNumber(chunk.opcodenum).toSafeString()}`)
        }
      }
    }
    
    /**
     * Checks a locktime parameter with the transaction's locktime.
     * There are two times of nLockTime: lock-by-blockheight and lock-by-blocktime,
     * distinguished by whether nLockTime < LOCKTIME_THRESHOLD = 500000000
     *
     * See the corresponding code on bitcoin core:
     * https://github.com/bitcoin/bitcoin/blob/ffd75adce01a78b3461b3ff05bcc2b530a9ce994/src/script/interpreter.cpp#L1129
     *
     * @param {BN} nLockTime the locktime read from the script
     * @return {boolean} true if the transaction's locktime is less than or equal to
     *                   the transaction's locktime
     */
    Interpreter.prototype.checkLockTime = function (nLockTime) {
      // We want to compare apples to apples, so fail the script
      // unless the type of nLockTime being tested is the same as
      // the nLockTime in the transaction.
      if (!(
        (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) ||
        (this.tx.nLockTime >= Interpreter.LOCKTIME_THRESHOLD && nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN))
      )) {
        return false
      }
    
      // Now that we know we're comparing apples-to-apples, the
      // comparison is a simple numeric one.
      if (nLockTime.gt(new BN(this.tx.nLockTime))) {
        return false
      }
    
      // Finally the nLockTime feature can be disabled and thus
      // CHECKLOCKTIMEVERIFY bypassed if every txin has been
      // finalized by setting nSequence to maxint. The
      // transaction would be allowed into the blockchain, making
      // the opcode ineffective.
      //
      // Testing if this vin is not final is sufficient to
      // prevent this condition. Alternatively we could test all
      // inputs, but testing just this input minimizes the data
      // required to prove correct CHECKLOCKTIMEVERIFY execution.
      if (this.tx.inputs[this.nin].isFinal()) {
        return false
      }
    
      return true
    }
    
    /**
     * Checks a sequence parameter with the transaction's sequence.
     * @param {BN} nSequence the sequence read from the script
     * @return {boolean} true if the transaction's sequence is less than or equal to
     *                   the transaction's sequence
     */
    Interpreter.prototype.checkSequence = function (nSequence) {
      // Relative lock times are supported by comparing the passed in operand to
      // the sequence number of the input.
      var txToSequence = this.tx.inputs[this.nin].sequenceNumber
    
      // Fail if the transaction's version number is not set high enough to
      // trigger BIP 68 rules.
      if (this.tx.version < 2) {
        return false
      }
    
      // Sequence numbers with their most significant bit set are not consensus
      // constrained. Testing that the transaction's sequence number do not have
      // this bit set prevents using this property to get around a
      // CHECKSEQUENCEVERIFY check.
      if (txToSequence & Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) {
        return false
      }
    
      // Mask off any bits that do not have consensus-enforced meaning before
      // doing the integer comparisons
      var nLockTimeMask =
        Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK
      var txToSequenceMasked = new BN(txToSequence & nLockTimeMask)
      var nSequenceMasked = nSequence.and(nLockTimeMask)
    
      // There are two kinds of nSequence: lock-by-blockheight and
      // lock-by-blocktime, distinguished by whether nSequenceMasked <
      // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG.
      //
      // We want to compare apples to apples, so fail the script unless the type
      // of nSequenceMasked being tested is the same as the nSequenceMasked in the
      // transaction.
      var SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG)
    
      if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) &&
        nSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)) ||
        (txToSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) &&
          nSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)))) {
        return false
      }
    
      // Now that we know we're comparing apples-to-apples, the comparison is a
      // simple numeric one.
      if (nSequenceMasked.gt(txToSequenceMasked)) {
        return false
      }
      return true
    }
    
    function padBufferToSize (buf, len) {
      let b = buf
      while (b.length < len) {
        b = Buffer.concat([Buffer.from([0x00]), b])
      }
      return b
    }
    
    /**
     * Based on the inner loop of bitcoind's EvalScript function
     * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
     */
    Interpreter.prototype.step = function (scriptType) {
      var self = this
    
      function stacktop (i) {
        return self.stack.stacktop(i)
      }
    
      function vartop (i) {
        return self.stack.vartop(i)
      }
    
      function isOpcodeDisabled (opcode) {
        switch (opcode) {
          case Opcode.OP_2MUL:
          case Opcode.OP_2DIV:
    
            // Disabled opcodes.
            return true
    
          case Opcode.OP_INVERT:
          case Opcode.OP_MUL:
          case Opcode.OP_LSHIFT:
          case Opcode.OP_RSHIFT:
            // Opcodes that have been reenabled.
            if ((self.flags & Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES) === 0) {
              return true
            }
            break
          case Opcode.OP_DIV:
          case Opcode.OP_MOD:
          case Opcode.OP_SPLIT:
          case Opcode.OP_CAT:
          case Opcode.OP_AND:
          case Opcode.OP_OR:
          case Opcode.OP_XOR:
          case Opcode.OP_BIN2NUM:
          case Opcode.OP_NUM2BIN:
            // Opcodes that have been reenabled.
            if ((self.flags & Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES) === 0) {
              return true
            }
            break
          default:
            break
        }
    
        return false
      }
    
      var fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0
    
      // bool fExec = !count(vfExec.begin(), vfExec.end(), false);
    
      var buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, subscript
      var sig, pubkey
      var fValue, fSuccess
      var var1, var2, var3
    
      // Read instruction
      var chunk = this.script.chunks[this.pc]
      this.pc++
      var opcodenum = chunk.opcodenum
      if (_.isUndefined(opcodenum)) {
        this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE'
        return false
      }
      if (chunk.buf && chunk.buf.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
        this.errstr = 'SCRIPT_ERR_PUSH_SIZE'
        return false
      }
    
      // Do not execute instructions if Genesis OP_RETURN was found in executed branches.
      var fExec = (this.vfExec.indexOf(false) === -1) && (!this.nonTopLevelReturnAfterGenesis || opcodenum === Opcode.OP_RETURN)
    
      // Note how Opcode.OP_RESERVED does not count towards the opcode limit.
      if (opcodenum > Opcode.OP_16 && ++(this.nOpCount) > Interpreter.MAX_OPCODE_COUNT) {
        this.errstr = 'SCRIPT_ERR_OP_COUNT'
        return false
      }
    
      if (isOpcodeDisabled(opcodenum)) {
        this.errstr = 'SCRIPT_ERR_DISABLED_OPCODE'
        return false
      }
    
      if (fExec && opcodenum >= 0 && opcodenum <= Opcode.OP_PUSHDATA4) {
        if (fRequireMinimal && !this.script.checkMinimalPush(this.pc - 1)) {
          this.errstr = 'SCRIPT_ERR_MINIMALDATA'
          return false
        }
        if (!chunk.buf) {
          this.stack.push(Interpreter.getFalse())
        } else if (chunk.len !== chunk.buf.length) {
          throw new Error(`Length of push value not equal to length of data (${chunk.len},${chunk.buf.length})`)
        } else {
          this.stack.push(chunk.buf)
        }
      } else if (fExec || (Opcode.OP_IF <= opcodenum && opcodenum <= Opcode.OP_ENDIF)) {
        switch (opcodenum) {
          // Push value
          case Opcode.OP_1NEGATE:
          case Opcode.OP_1:
          case Opcode.OP_2:
          case Opcode.OP_3:
          case Opcode.OP_4:
          case Opcode.OP_5:
          case Opcode.OP_6:
          case Opcode.OP_7:
          case Opcode.OP_8:
          case Opcode.OP_9:
          case Opcode.OP_10:
          case Opcode.OP_11:
          case Opcode.OP_12:
          case Opcode.OP_13:
          case Opcode.OP_14:
          case Opcode.OP_15:
          case Opcode.OP_16:
            // ( -- value)
            // ScriptNum bn((int)opcode - (int)(Opcode.OP_1 - 1));
            n = opcodenum - (Opcode.OP_1 - 1)
            buf = new BN(n).toScriptNumBuffer()
            this.stack.push(buf)
            // The result of these opcodes should always be the minimal way to push the data
            // they push, so no need for a CheckMinimalPush here.
            break
    
          //
          // Control
          //
          case Opcode.OP_NOP:
            break
    
          case Opcode.OP_NOP2:
          case Opcode.OP_CHECKLOCKTIMEVERIFY:
    
            if (!(this.flags & Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
              // not enabled; treat as a NOP2
              if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
                this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS'
                return false
              }
              break
            }
    
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            // Note that elsewhere numeric opcodes are limited to
            // operands in the range -2**31+1 to 2**31-1, however it is
            // legal for opcodes to produce results exceeding that
            // range. This limitation is implemented by CScriptNum's
            // default 4-byte limit.
            //
            // If we kept to that limit we'd have a year 2038 problem,
            // even though the nLockTime field in transactions
            // themselves is uint32 which only becomes meaningless
            // after the year 2106.
            //
            // Thus as a special case we tell CScriptNum to accept up
            // to 5-byte bignums, which are good until 2**39-1, well
            // beyond the 2**32-1 limit of the nLockTime field itself.
            var nLockTime = BN.fromScriptNumBuffer(this.stack.stacktop(-1), fRequireMinimal, 5)
    
            // In the rare event that the argument may be < 0 due to
            // some arithmetic being done first, you can always use
            // 0 MAX CHECKLOCKTIMEVERIFY.
            if (nLockTime.lt(new BN(0))) {
              this.errstr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME'
              return false
            }
    
            // Actually compare the specified lock time with the transaction.
            if (!this.checkLockTime(nLockTime)) {
              this.errstr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME'
              return false
            }
            break
    
          case Opcode.OP_NOP3:
          case Opcode.OP_CHECKSEQUENCEVERIFY:
    
            if (!(this.flags & Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
              // not enabled; treat as a NOP3
              if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
                this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS'
                return false
              }
              break
            }
    
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            // nSequence, like nLockTime, is a 32-bit unsigned
            // integer field. See the comment in CHECKLOCKTIMEVERIFY
            // regarding 5-byte numeric operands.
    
            var nSequence = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, 5)
    
            // In the rare event that the argument may be < 0 due to
            // some arithmetic being done first, you can always use
            // 0 MAX CHECKSEQUENCEVERIFY.
            if (nSequence.lt(new BN(0))) {
              this.errstr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME'
              return false
            }
    
            // To provide for future soft-fork extensibility, if the
            // operand has the disabled lock-time flag set,
            // CHECKSEQUENCEVERIFY behaves as a NOP.
            if ((nSequence &
              Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) !== 0) {
              break
            }
    
            // Actually compare the specified lock time with the transaction.
            if (!this.checkSequence(nSequence)) {
              this.errstr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME'
              return false
            }
            break
    
          case Opcode.OP_NOP1:
          case Opcode.OP_NOP4:
          case Opcode.OP_NOP5:
          case Opcode.OP_NOP6:
          case Opcode.OP_NOP7:
          case Opcode.OP_NOP8:
          case Opcode.OP_NOP9:
          case Opcode.OP_NOP10:
            if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
              this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS'
              return false
            }
            break
    
          case Opcode.OP_IF:
          case Opcode.OP_NOTIF:
            // <expression> if [statements] [else [statements]] endif
            // bool fValue = false;
            fValue = false
            if (fExec) {
              if (this.stack.length < 1) {
                this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL'
                return false
              }
              buf = stacktop(-1)
    
              if (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALIF) {
                if (buf.length > 1) {
                  this.errstr = 'SCRIPT_ERR_MINIMALIF'
                  return false
                }
                if (buf.length === 1 && buf[0] !== 1) {
                  this.errstr = 'SCRIPT_ERR_MINIMALIF'
                  return false
                }
              }
              fValue = Interpreter.castToBool(buf)
              if (opcodenum === Opcode.OP_NOTIF) {
                fValue = !fValue
              }
              this.stack.pop()
            }
            this.vfExec.push(fValue)
            break
    
          case Opcode.OP_ELSE:
            if (this.vfExec.length === 0) {
              this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL'
              return false
            }
            this.vfExec[this.vfExec.length - 1] = !this.vfExec[this.vfExec.length - 1]
            break
    
          case Opcode.OP_ENDIF:
            if (this.vfExec.length === 0) {
              this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL'
              return false
            }
            this.vfExec.pop()
            break
    
          case Opcode.OP_VERIFY:
            // (true -- ) or
            // (false -- false) and return
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-1)
            fValue = Interpreter.castToBool(buf)
            if (fValue) {
              this.stack.pop()
            } else {
              this.errstr = 'SCRIPT_ERR_VERIFY'
              return false
            }
            break
    
          case Opcode.OP_RETURN:
    
            if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) === 0) { // utxo_after_genesis
              if (this.vfExec.length === 0) {
                // Terminate the execution as successful. The remaining of the script does not affect the validity (even in
                // presence of unbalanced IFs, invalid opcodes etc)
                this.returned = true
                return true
              }
              // op_return encountered inside if statement after genesis --> check for invalid grammar
              this.nonTopLevelReturnAfterGenesis = true
            } else {
              return false
            }
    
            break
    
          //
          // Stack ops
          //
          case Opcode.OP_TOALTSTACK:
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            var1 = vartop(-1)
            this.altstack.push(this.stack.pop(), var1)
            break
    
          case Opcode.OP_FROMALTSTACK:
            if (this.altstack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_ALTSTACK_OPERATION'
              return false
            }
            const varAlt = this.altstack.vartop(-1)
            this.stack.push(this.altstack.pop(), varAlt)
            break
    
          case Opcode.OP_2DROP:
            // (x1 x2 -- )
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            this.stack.pop()
            this.stack.pop()
            break
    
          case Opcode.OP_2DUP:
            // (x1 x2 -- x1 x2 x1 x2)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-2)
            buf2 = stacktop(-1)
            var1 = vartop(-2)
            var2 = vartop(-1)
            this.stack.push(Buffer.from(buf1), `$${var1}`)
            this.stack.push(Buffer.from(buf2), `$${var2}`)
            break
    
          case Opcode.OP_3DUP:
            // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
            if (this.stack.length < 3) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-3)
            buf2 = stacktop(-2)
            var buf3 = stacktop(-1)
            var1 = vartop(-3)
            var2 = vartop(-2)
            var3 = vartop(-1)
            this.stack.push(Buffer.from(buf1), `$${var1}`)
            this.stack.push(Buffer.from(buf2), `$${var2}`)
            this.stack.push(Buffer.from(buf3), `$${var3}`)
            break
    
          case Opcode.OP_2OVER:
            // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
            if (this.stack.length < 4) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-4)
            buf2 = stacktop(-3)
            var1 = vartop(-4)
            var2 = vartop(-3)
            this.stack.push(Buffer.from(buf1), `$${var1}`)
            this.stack.push(Buffer.from(buf2), `$${var2}`)
            break
    
          case Opcode.OP_2ROT:
            // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
            if (this.stack.length < 6) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            var1 = vartop(-6)
            var2 = vartop(-5)
    
            spliced = this.stack.splice(this.stack.length - 6, 2)
            this.stack.push(spliced[0], var1)
            this.stack.push(spliced[1], var2)
            break
    
          case Opcode.OP_2SWAP:
            // (x1 x2 x3 x4 -- x3 x4 x1 x2)
            if (this.stack.length < 4) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            var1 = vartop(-4)
            var2 = vartop(-3)
            spliced = this.stack.splice(this.stack.length - 4, 2)
            this.stack.push(spliced[0], var1)
            this.stack.push(spliced[1], var2)
            break
    
          case Opcode.OP_IFDUP:
            // (x - 0 | x x)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-1)
            fValue = Interpreter.castToBool(buf)
            if (fValue) {
              var1 = vartop(-1)
              this.stack.push(Buffer.from(buf), `$${var1}`)
            }
            break
    
          case Opcode.OP_DEPTH:
            // -- stacksize
            buf = new BN(this.stack.length).toScriptNumBuffer()
            this.stack.push(buf, '$depth')
            break
    
          case Opcode.OP_DROP:
            // (x -- )
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            this.stack.pop()
            break
    
          case Opcode.OP_DUP:
            // (x -- x x)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            var1 = vartop(-1)
            this.stack.push(Buffer.from(stacktop(-1)), `$${var1}`)
            break
    
          case Opcode.OP_NIP:
            // (x1 x2 -- x2)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            this.stack.splice(this.stack.length - 2, 1)
            break
    
          case Opcode.OP_OVER:
            // (x1 x2 -- x1 x2 x1)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            var2 = vartop(-2)
            this.stack.push(Buffer.from(stacktop(-2)), `$${var2}`)
            break
    
          case Opcode.OP_PICK:
          case Opcode.OP_ROLL:
            // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
            // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-1)
            bn = BN.fromScriptNumBuffer(buf, fRequireMinimal, 4)
            n = bn.toNumber()
            this.stack.pop()
            if (n < 0 || n >= this.stack.length) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-n - 1)
            var1 = vartop(-n - 1)
            if (opcodenum === Opcode.OP_ROLL) {
              this.stack.splice(this.stack.length - n - 1, 1)
              this.stack.push(Buffer.from(buf), var1)
            } else {
              this.stack.push(Buffer.from(buf), `$${var1}`)
            }
    
            break
    
          case Opcode.OP_ROT:
            // (x1 x2 x3 -- x2 x3 x1)
            //  x2 x1 x3  after first swap
            //  x2 x3 x1  after second swap
            if (this.stack.length < 3) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            x1 = stacktop(-3)
            x2 = stacktop(-2)
            var x3 = stacktop(-1)
            var1 = vartop(-3)
            var2 = vartop(-2)
            var3 = vartop(-1)
            this.stack.write(-3, x2)
            this.stack.write(-2, x3)
            this.stack.write(-1, x1)
            this.stack.updateTopVars([var1, var3, var2])
            break
    
          case Opcode.OP_SWAP:
            // (x1 x2 -- x2 x1)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            x1 = stacktop(-2)
            x2 = stacktop(-1)
            var1 = vartop(-2)
            var2 = vartop(-1)
            this.stack.write(-2, x2)
            this.stack.write(-1, x1)
            this.stack.updateTopVars([var1, var2])
            break
    
          case Opcode.OP_TUCK:
            // (x1 x2 -- x2 x1 x2)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            var1 = vartop(-2)
            var2 = vartop(-1)
    
            this.stack.splice(this.stack.length - 2, 0, Buffer.from(stacktop(-1)))
            this.stack.updateTopVars([var2, var1, `$${var2}`])
            break
    
          case Opcode.OP_SIZE:
            // (in -- in size)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            bn = new BN(stacktop(-1).length)
            this.stack.push(bn.toScriptNumBuffer(), `$size`)
            break
    
          //
          // Bitwise logic
          //
          case Opcode.OP_AND:
          case Opcode.OP_OR:
          case Opcode.OP_XOR:
            // (x1 x2 - out)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-2)
            buf2 = stacktop(-1)
    
            // Inputs must be the same size
            if (buf1.length !== buf2.length) {
              this.errstr = 'SCRIPT_ERR_INVALID_OPERAND_SIZE'
              return false
            }
    
            // To avoid allocating, we modify vch1 in place.
            switch (opcodenum) {
              case Opcode.OP_AND:
                for (let i = 0; i < buf1.length; i++) {
                  buf1[i] &= buf2[i]
                }
                break
              case Opcode.OP_OR:
                for (let i = 0; i < buf1.length; i++) {
                  buf1[i] |= buf2[i]
                }
                break
              case Opcode.OP_XOR:
                for (let i = 0; i < buf1.length; i++) {
                  buf1[i] ^= buf2[i]
                }
                break
              default:
                break
            }
    
            // And pop vch2.
            this.stack.pop()
            break
    
          case Opcode.OP_INVERT:
            // (x -- out)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
            }
            buf = stacktop(-1)
            for (let i = 0; i < buf.length; i++) {
              buf[i] = ~buf[i]
            }
            break
    
          case Opcode.OP_LSHIFT:
          case Opcode.OP_RSHIFT:
            // (x n -- out)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-2)
            if (buf1.length === 0) {
              this.stack.pop()
            } else {
              bn1 = new BN(buf1)
              bn2 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, 4)
              n = bn2.toNumber()
              if (n < 0) {
                this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
                return false
              }
              this.stack.pop()
              this.stack.pop()
              let shifted
              if (opcodenum === Opcode.OP_LSHIFT) {
                shifted = bn1.ushln(n)
              }
              if (opcodenum === Opcode.OP_RSHIFT) {
                shifted = bn1.ushrn(n)
              }
              // bitcoin client implementation of l/rshift is unconventional, therefore this implementation is a bit unconventional
              // bn library has shift functions however it expands the carried bits into a new byte
              // in contrast to the bitcoin client implementation which drops off the carried bits
              // in other words, if operand was 1 byte then we put 1 byte back on the stack instead of expanding to more shifted bytes
              let bufShifted = padBufferToSize(Buffer.from(shifted.toArray().slice(buf1.length * -1)), buf1.length)
              this.stack.push(bufShifted)
            }
            break
    
          case Opcode.OP_EQUAL:
          case Opcode.OP_EQUALVERIFY:
            // case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL
            // (x1 x2 - bool)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-2)
            buf2 = stacktop(-1)
            var fEqual = buf1.toString('hex') === buf2.toString('hex')
            this.stack.pop()
            this.stack.pop()
            this.stack.push(fEqual ? Interpreter.getTrue() : Interpreter.getFalse())
            if (opcodenum === Opcode.OP_EQUALVERIFY) {
              if (fEqual) {
                this.stack.pop()
              } else {
                this.errstr = 'SCRIPT_ERR_EQUALVERIFY'
                return false
              }
            }
            break
    
          //
          // Numeric
          //
          case Opcode.OP_1ADD:
          case Opcode.OP_1SUB:
          case Opcode.OP_NEGATE:
          case Opcode.OP_ABS:
          case Opcode.OP_NOT:
          case Opcode.OP_0NOTEQUAL:
            // (in -- out)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-1)
            bn = BN.fromScriptNumBuffer(buf, fRequireMinimal)
            switch (opcodenum) {
              case Opcode.OP_1ADD:
                bn = bn.add(BN.One)
                break
              case Opcode.OP_1SUB:
                bn = bn.sub(BN.One)
                break
              case Opcode.OP_NEGATE:
                bn = bn.neg()
                break
              case Opcode.OP_ABS:
                if (bn.cmp(BN.Zero) < 0) {
                  bn = bn.neg()
                }
                break
              case Opcode.OP_NOT:
                bn = new BN((bn.cmp(BN.Zero) === 0) + 0)
                break
              case Opcode.OP_0NOTEQUAL:
                bn = new BN((bn.cmp(BN.Zero) !== 0) + 0)
                break
              // default:      assert(!'invalid opcode'); break; // TODO: does this ever occur?
            }
            this.stack.pop()
            this.stack.push(bn.toScriptNumBuffer())
            break
    
          case Opcode.OP_ADD:
          case Opcode.OP_SUB:
          case Opcode.OP_MUL:
          case Opcode.OP_MOD:
          case Opcode.OP_DIV:
          case Opcode.OP_BOOLAND:
          case Opcode.OP_BOOLOR:
          case Opcode.OP_NUMEQUAL:
          case Opcode.OP_NUMEQUALVERIFY:
          case Opcode.OP_NUMNOTEQUAL:
          case Opcode.OP_LESSTHAN:
          case Opcode.OP_GREATERTHAN:
          case Opcode.OP_LESSTHANOREQUAL:
          case Opcode.OP_GREATERTHANOREQUAL:
          case Opcode.OP_MIN:
          case Opcode.OP_MAX:
            // (x1 x2 -- out)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            bn1 = BN.fromScriptNumBuffer(stacktop(-2), fRequireMinimal)
            bn2 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal)
            bn = new BN(0)
    
            switch (opcodenum) {
              case Opcode.OP_ADD:
                bn = bn1.add(bn2)
                break
    
              case Opcode.OP_SUB:
                bn = bn1.sub(bn2)
                break
    
              case Opcode.OP_MUL:
                bn = bn1.mul(bn2)
                break
    
              case Opcode.OP_DIV:
                // denominator must not be 0
                if (bn2 === 0) {
                  this.errstr = 'SCRIPT_ERR_DIV_BY_ZERO'
                  return false
                }
                bn = bn1.div(bn2)
                break
    
              case Opcode.OP_MOD:
                // divisor must not be 0
                if (bn2 === 0) {
                  this.errstr = 'SCRIPT_ERR_DIV_BY_ZERO'
                  return false
                }
                bn = bn1.mod(bn2)
                break
    
              case Opcode.OP_BOOLAND:
                bn = new BN(((bn1.cmp(BN.Zero) !== 0) && (bn2.cmp(BN.Zero) !== 0)) + 0)
                break
              // case Opcode.OP_BOOLOR:        bn = (bn1 !== bnZero || bn2 !== bnZero); break;
              case Opcode.OP_BOOLOR:
                bn = new BN(((bn1.cmp(BN.Zero) !== 0) || (bn2.cmp(BN.Zero) !== 0)) + 0)
                break
              // case Opcode.OP_NUMEQUAL:      bn = (bn1 === bn2); break;
              case Opcode.OP_NUMEQUAL:
                bn = new BN((bn1.cmp(bn2) === 0) + 0)
                break
              // case Opcode.OP_NUMEQUALVERIFY:    bn = (bn1 === bn2); break;
              case Opcode.OP_NUMEQUALVERIFY:
                bn = new BN((bn1.cmp(bn2) === 0) + 0)
                break
              // case Opcode.OP_NUMNOTEQUAL:     bn = (bn1 !== bn2); break;
              case Opcode.OP_NUMNOTEQUAL:
                bn = new BN((bn1.cmp(bn2) !== 0) + 0)
                break
              // case Opcode.OP_LESSTHAN:      bn = (bn1 < bn2); break;
              case Opcode.OP_LESSTHAN:
                bn = new BN((bn1.cmp(bn2) < 0) + 0)
                break
              // case Opcode.OP_GREATERTHAN:     bn = (bn1 > bn2); break;
              case Opcode.OP_GREATERTHAN:
                bn = new BN((bn1.cmp(bn2) > 0) + 0)
                break
              // case Opcode.OP_LESSTHANOREQUAL:   bn = (bn1 <= bn2); break;
              case Opcode.OP_LESSTHANOREQUAL:
                bn = new BN((bn1.cmp(bn2) <= 0) + 0)
                break
              // case Opcode.OP_GREATERTHANOREQUAL:  bn = (bn1 >= bn2); break;
              case Opcode.OP_GREATERTHANOREQUAL:
                bn = new BN((bn1.cmp(bn2) >= 0) + 0)
                break
              case Opcode.OP_MIN:
                bn = (bn1.cmp(bn2) < 0 ? bn1 : bn2)
                break
              case Opcode.OP_MAX:
                bn = (bn1.cmp(bn2) > 0 ? bn1 : bn2)
                break
              // default:           assert(!'invalid opcode'); break; //TODO: does this ever occur?
            }
            this.stack.pop()
            this.stack.pop()
            this.stack.push(bn.toScriptNumBuffer())
    
            if (opcodenum === Opcode.OP_NUMEQUALVERIFY) {
              // if (CastToBool(stacktop(-1)))
              if (Interpreter.castToBool(stacktop(-1))) {
                this.stack.pop()
              } else {
                this.errstr = 'SCRIPT_ERR_NUMEQUALVERIFY'
                return false
              }
            }
            break
    
          case Opcode.OP_WITHIN:
            // (x min max -- out)
            if (this.stack.length < 3) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            bn1 = BN.fromScriptNumBuffer(stacktop(-3), fRequireMinimal)
            bn2 = BN.fromScriptNumBuffer(stacktop(-2), fRequireMinimal)
            var bn3 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal)
            // bool fValue = (bn2 <= bn1 && bn1 < bn3);
            fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0)
            this.stack.pop()
            this.stack.pop()
            this.stack.pop()
            this.stack.push(fValue ? Interpreter.getTrue() : Interpreter.getFalse())
            break
    
          //
          // Crypto
          //
          case Opcode.OP_RIPEMD160:
          case Opcode.OP_SHA1:
          case Opcode.OP_SHA256:
          case Opcode.OP_HASH160:
          case Opcode.OP_HASH256:
            // (in -- hash)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf = stacktop(-1)
            // valtype vchHash((opcode === Opcode.OP_RIPEMD160 ||
            //                 opcode === Opcode.OP_SHA1 || opcode === Opcode.OP_HASH160) ? 20 : 32);
            var bufHash
            if (opcodenum === Opcode.OP_RIPEMD160) {
              bufHash = Hash.ripemd160(buf)
            } else if (opcodenum === Opcode.OP_SHA1) {
              bufHash = Hash.sha1(buf)
            } else if (opcodenum === Opcode.OP_SHA256) {
              bufHash = Hash.sha256(buf)
            } else if (opcodenum === Opcode.OP_HASH160) {
              bufHash = Hash.sha256ripemd160(buf)
            } else if (opcodenum === Opcode.OP_HASH256) {
              bufHash = Hash.sha256sha256(buf)
            }
            this.stack.pop()
            this.stack.push(bufHash)
            break
    
          case Opcode.OP_CODESEPARATOR:
            // Hash starts after the code separator
            this.pbegincodehash = this.pc
            break
    
          case Opcode.OP_CHECKSIG:
          case Opcode.OP_CHECKSIGVERIFY:
            // (sig pubkey -- bool)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            bufSig = stacktop(-2)
            bufPubkey = stacktop(-1)
    
            if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) {
              return false
            }
    
            // Subset of script starting at the most recent codeseparator
            // CScript scriptCode(pbegincodehash, pend);
            subscript = this.subscript()
    
            // Drop the signature, since there's no way for a signature to sign itself
            var tmpScript = new Script().add(bufSig)
            subscript.findAndDelete(tmpScript)
    
            try {
              sig = Signature.fromTxFormat(bufSig)
              pubkey = PublicKey.fromBuffer(bufPubkey, false)
    
              fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags)
            } catch (e) {
              // invalid sig or pubkey
              fSuccess = false
            }
    
            if (!fSuccess && (this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL) &&
              bufSig.length) {
              this.errstr = 'SCRIPT_ERR_NULLFAIL'
              return false
            }
    
            this.stack.pop()
            this.stack.pop()
    
            // stack.push_back(fSuccess ? vchTrue : vchFalse);
            this.stack.push(fSuccess ? Interpreter.getTrue() : Interpreter.getFalse())
            if (opcodenum === Opcode.OP_CHECKSIGVERIFY) {
              if (fSuccess) {
                this.stack.pop()
              } else {
                this.errstr = 'SCRIPT_ERR_CHECKSIGVERIFY'
                return false
              }
            }
            break
    
          case Opcode.OP_CHECKMULTISIG:
          case Opcode.OP_CHECKMULTISIGVERIFY:
            // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
    
            var i = 1
            if (this.stack.length < i) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            var nKeysCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal).toNumber()
            // TODO: Keys and opcount are parameterized in client. No magic numbers!
            if (nKeysCount < 0 || nKeysCount > 20) {
              this.errstr = 'SCRIPT_ERR_PUBKEY_COUNT'
              return false
            }
            this.nOpCount += nKeysCount
            if (this.nOpCount > Interpreter.MAX_OPCODE_COUNT) {
              this.errstr = 'SCRIPT_ERR_OP_COUNT'
              return false
            }
            // int ikey = ++i;
            var ikey = ++i
            i += nKeysCount
    
            // ikey2 is the position of last non-signature item in
            // the stack. Top stack item = 1. With
            // SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if
            // operation fails.
            var ikey2 = nKeysCount + 2
    
            if (this.stack.length < i) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            var nSigsCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal).toNumber()
            if (nSigsCount < 0 || nSigsCount > nKeysCount) {
              this.errstr = 'SCRIPT_ERR_SIG_COUNT'
              return false
            }
            // int isig = ++i;
            var isig = ++i
            i += nSigsCount
            if (this.stack.length < i) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            // Subset of script starting at the most recent codeseparator
            subscript = this.subscript()
    
            // Drop the signatures, since there's no way for a signature to sign itself
            for (var k = 0; k < nSigsCount; k++) {
              bufSig = stacktop(-isig - k)
              subscript.findAndDelete(new Script().add(bufSig))
            }
    
            fSuccess = true
            while (fSuccess && nSigsCount > 0) {
              // valtype& vchSig  = stacktop(-isig);
              bufSig = stacktop(-isig)
              // valtype& vchPubKey = stacktop(-ikey);
              bufPubkey = stacktop(-ikey)
    
              if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) {
                return false
              }
    
              var fOk
              try {
                sig = Signature.fromTxFormat(bufSig)
                pubkey = PublicKey.fromBuffer(bufPubkey, false)
                fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags)
              } catch (e) {
                // invalid sig or pubkey
                fOk = false
              }
    
              if (fOk) {
                isig++
                nSigsCount--
              }
              ikey++
              nKeysCount--
    
              // If there are more signatures left than keys left,
              // then too many signatures have failed
              if (nSigsCount > nKeysCount) {
                fSuccess = false
              }
            }
    
            // Clean up stack of actual arguments
            while (i-- > 1) {
              if (!fSuccess && (this.flags & Interpreter.SCRIPT_VERIFY_NULLFAIL) &&
                !ikey2 && stacktop(-1).length) {
                this.errstr = 'SCRIPT_ERR_NULLFAIL'
                return false
              }
    
              if (ikey2 > 0) {
                ikey2--
              }
    
              this.stack.pop()
            }
    
            // A bug causes CHECKMULTISIG to consume one extra argument
            // whose contents were not checked in any way.
            //
            // Unfortunately this is a potential source of mutability,
            // so optionally verify it is exactly equal to zero prior
            // to removing it from the stack.
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            if ((this.flags & Interpreter.SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).length) {
              this.errstr = 'SCRIPT_ERR_SIG_NULLDUMMY'
              return false
            }
            this.stack.pop()
    
            this.stack.push(fSuccess ? Interpreter.getTrue() : Interpreter.getFalse())
    
            if (opcodenum === Opcode.OP_CHECKMULTISIGVERIFY) {
              if (fSuccess) {
                this.stack.pop()
              } else {
                this.errstr = 'SCRIPT_ERR_CHECKMULTISIGVERIFY'
                return false
              }
            }
            break
    
          //
          // Byte string operations
          //
          case Opcode.OP_CAT:
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            buf1 = stacktop(-2)
            buf2 = stacktop(-1)
            if (buf1.length + buf2.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
              this.errstr = 'SCRIPT_ERR_PUSH_SIZE'
              return false
            }
            this.stack.write(-2, Buffer.concat([buf1, buf2]))
            this.stack.pop()
            break
    
          case Opcode.OP_SPLIT:
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
            buf1 = stacktop(-2)
    
            // Make sure the split point is apropriate.
            var position = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber()
            if (position < 0 || position > buf1.length) {
              this.errstr = 'SCRIPT_ERR_INVALID_SPLIT_RANGE'
              return false
            }
    
            // Prepare the results in their own buffer as `data`
            // will be invalidated.
            // Copy buffer data, to slice it before
            var n1 = Buffer.from(buf1)
    
            // Replace existing stack values by the new values.
            this.stack.write(-2, n1.slice(0, position))
            this.stack.write(-1, n1.slice(position))
            break
    
          //
          // Conversion operations
          //
          case Opcode.OP_NUM2BIN:
            // (in -- out)
            if (this.stack.length < 2) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            var size = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber()
            if (size > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) {
              this.errstr = 'SCRIPT_ERR_PUSH_SIZE'
              return false
            }
    
            this.stack.pop()
            var rawnum = stacktop(-1)
    
            // Try to see if we can fit that number in the number of
            // byte requested.
            rawnum = Interpreter._minimallyEncode(rawnum)
    
            if (rawnum.length > size) {
              // We definitively cannot.
              this.errstr = 'SCRIPT_ERR_IMPOSSIBLE_ENCODING'
              return false
            }
    
            // We already have an element of the right size, we
            // don't need to do anything.
            if (rawnum.length === size) {
              this.stack.write(-1, rawnum)
              break
            }
    
            var signbit = 0x00
            if (rawnum.length > 0) {
              signbit = rawnum[rawnum.length - 1] & 0x80
              rawnum[rawnum.length - 1] &= 0x7f
            }
    
            var num = Buffer.alloc(size)
            rawnum.copy(num, 0)
    
            var l = rawnum.length - 1
            while (l++ < size - 2) {
              num[l] = 0x00
            }
    
            num[l] = signbit
    
            this.stack.write(-1, num)
            break
    
          case Opcode.OP_BIN2NUM:
            // (in -- out)
            if (this.stack.length < 1) {
              this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
              return false
            }
    
            buf1 = stacktop(-1)
            buf2 = Interpreter._minimallyEncode(buf1)
    
            this.stack.write(-1, buf2)
    
            // The resulting number must be a valid number.
            if (!Interpreter._isMinimallyEncoded(buf2)) {
              this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
              return false
            }
            break
    
          default:
            this.errstr = 'SCRIPT_ERR_BAD_OPCODE'
            return false
        }
      }
    
      // only when next opcode is evaluate opcode, we update stack
      if (this.vfExec.indexOf(false) === -1) {
        this._callbackStack(this.stack, this.pc, scriptType)
      }
    
      return true
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"../crypto/hash":208,"../crypto/signature":212,"../opcode":245,"../publickey":247,"../transaction":258,"../util/_":270,"./script":250,"./stack":251,"buffer":84}],250:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var Address = require('../address')
    var BufferWriter = require('../encoding/bufferwriter')
    var Hash = require('../crypto/hash')
    var Opcode = require('../opcode')
    var PublicKey = require('../publickey')
    var Signature = require('../crypto/signature')
    var Networks = require('../networks')
    var $ = require('../util/preconditions')
    var _ = require('../util/_')
    var errors = require('../errors')
    var buffer = require('buffer')
    var JSUtil = require('../util/js')
    const decodeScriptChunks = require('../encoding/decode-script-chunks')
    const decodeASM = require('../encoding/decode-asm')
    const encodeHex = require('../encoding/encode-hex')
    
    // These WeakMap caches allow the objects themselves to maintain their immutability
    const SCRIPT_TO_CHUNKS_CACHE = new WeakMap()
    
    /**
     * A bitcoin transaction script. Each transaction's inputs and outputs
     * has a script that is evaluated to validate it's spending.
     *
     * See https://en.bitcoin.it/wiki/Script
     *
     * @constructor
     * @param {Object|string|Buffer=} from optional data to populate script
     */
    var Script = function Script (from) {
      if (!(this instanceof Script)) {
        return new Script(from)
      }
      this.buffer = Buffer.from([])
    
      if (Buffer.isBuffer(from)) {
        return Script.fromBuffer(from)
      } else if (from instanceof Address) {
        return Script.fromAddress(from)
      } else if (from instanceof Script) {
        return Script.fromBuffer(from.toBuffer())
      } else if (_.isString(from)) {
        return Script.fromString(from)
      } else if (_.isObject(from) && _.isArray(from.chunks)) {
        return Script.fromChunks(from.chunks)
      } else if (_.isObject(from) && Buffer.isBuffer(from.buffer)) {
        return Script.fromBuffer(from.buffer)
      }
    }
    
    Script.prototype.set = function (obj) {
      $.checkArgument(_.isObject(obj))
      if (obj.chunks && _.isArray(obj.chunks)) {
        var s = Script.fromChunks(obj.chunks)
        this.buffer = s.buffer
        return this
      }
    
      $.checkArgument(Buffer.isBuffer(obj.buffer))
      this.buffer = obj.buffer
      return this
    }
    
    Script.fromBuffer = function (buffer) {
      $.checkArgument(Buffer.isBuffer(buffer))
      var script = new Script()
      script.buffer = buffer
      return script
    }
    
    Script.fromChunks = function (chunks) {
      var script = new Script()
    
      const bw = new BufferWriter()
    
      for (let index = 0; index < chunks.length; index++) {
        const chunk = chunks[index]
        bw.writeUInt8(chunk.opcodenum)
        if (chunk.buf) {
          if (chunk.opcodenum < Opcode.OP_PUSHDATA1) {
            bw.write(chunk.buf)
          } else if (chunk.opcodenum === Opcode.OP_PUSHDATA1) {
            bw.writeUInt8(chunk.len)
            bw.write(chunk.buf)
          } else if (chunk.opcodenum === Opcode.OP_PUSHDATA2) {
            bw.writeUInt16LE(chunk.len)
            bw.write(chunk.buf)
          } else if (chunk.opcodenum === Opcode.OP_PUSHDATA4) {
            bw.writeUInt32LE(chunk.len)
            bw.write(chunk.buf)
          }
        }
      }
    
      script.buffer = bw.toBuffer()
      return script
    }
    
    Script.prototype.toBuffer = function () {
      return this.buffer
    }
    
    Script.fromASM = function (str) {
      return Script.fromBuffer(decodeASM(str))
    }
    
    Script.fromHex = function (str) {
      return new Script(buffer.Buffer.from(str, 'hex'))
    }
    
    Script.fromString = function (str) {
      if (JSUtil.isHexa(str) || str.length === 0) {
        return new Script(buffer.Buffer.from(str, 'hex'))
      }
    
      var chunks = []
    
      var tokens = str.split(' ')
      var i = 0
      while (i < tokens.length) {
        var token = tokens[i]
        var opcode = Opcode(token)
        var opcodenum = opcode.toNumber()
    
        if (_.isUndefined(opcodenum)) {
          opcodenum = parseInt(token)
          if (opcodenum > 0 && opcodenum < Opcode.OP_PUSHDATA1) {
            var buf = Buffer.from(tokens[i + 1].slice(2), 'hex')
            if (buf.length !== opcodenum) {
              throw new Error('Invalid script buf len: ' + JSON.stringify(str))
            }
            chunks.push({
              buf: Buffer.from(tokens[i + 1].slice(2), 'hex'),
              len: opcodenum,
              opcodenum: opcodenum
            })
            i = i + 2
          } else {
            throw new Error('Invalid script: ' + JSON.stringify(str))
          }
        } else if (opcodenum === Opcode.OP_PUSHDATA1 ||
          opcodenum === Opcode.OP_PUSHDATA2 ||
          opcodenum === Opcode.OP_PUSHDATA4) {
          if (tokens[i + 2].slice(0, 2) !== '0x') {
            throw new Error('Pushdata data must start with 0x')
          }
          chunks.push({
            buf: Buffer.from(tokens[i + 2].slice(2), 'hex'),
            len: parseInt(tokens[i + 1]),
            opcodenum: opcodenum
          })
          i = i + 3
        } else {
          chunks.push({
            opcodenum: opcodenum
          })
          i = i + 1
        }
      }
      return Script.fromChunks(chunks)
    }
    
    Script.prototype.slice = function (start, end) {
      return this.buffer.slice(start, end)
    }
    
    Object.defineProperty(Script.prototype, 'chunks', {
      get () {
        if (SCRIPT_TO_CHUNKS_CACHE.has(this)) return SCRIPT_TO_CHUNKS_CACHE.get(this)
        const chunks = decodeScriptChunks(this.buffer)
        SCRIPT_TO_CHUNKS_CACHE.set(this, chunks)
        return chunks
      }
    })
    
    Object.defineProperty(Script.prototype, 'length', {
      get () {
        return this.buffer.length
      }
    })
    
    Script.prototype._chunkToString = function (chunk, type) {
      var opcodenum = chunk.opcodenum
      var asm = (type === 'asm')
      var str = ''
      if (!chunk.buf) {
        // no data chunk
        if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') {
          if (asm) {
            // A few cases where the opcode name differs from reverseMap
            // aside from 1 to 16 data pushes.
            if (opcodenum === 0) {
              // OP_0 -> 0
              str = str + ' 0'
            } else if (opcodenum === 79) {
              // OP_1NEGATE -> 1
              str = str + ' -1'
            } else {
              str = str + ' ' + Opcode(opcodenum).toString()
            }
          } else {
            str = str + ' ' + Opcode(opcodenum).toString()
          }
        } else {
          var numstr = opcodenum.toString(16)
          if (numstr.length % 2 !== 0) {
            numstr = '0' + numstr
          }
          if (asm) {
            str = str + ' ' + numstr
          } else {
            str = str + ' ' + '0x' + numstr
          }
        }
      } else {
        // data chunk
        if (!asm && (opcodenum === Opcode.OP_PUSHDATA1 ||
          opcodenum === Opcode.OP_PUSHDATA2 ||
          opcodenum === Opcode.OP_PUSHDATA4)) {
          str = str + ' ' + Opcode(opcodenum).toString()
        }
        if (chunk.len > 0) {
          if (asm) {
            str = str + ' ' + chunk.buf.toString('hex')
          } else {
            str = str + ' ' + chunk.len + ' ' + '0x' + chunk.buf.toString('hex')
          }
        }
      }
      return str
    }
    
    Script.prototype.toASM = function () {
      var str = ''
      var chunks = this.chunks
      for (var i = 0; i < chunks.length; i++) {
        var chunk = this.chunks[i]
        str += this._chunkToString(chunk, 'asm')
      }
    
      return str.substr(1)
    }
    
    Script.prototype.toString = function () {
      var str = ''
      for (var i = 0; i < this.chunks.length; i++) {
        var chunk = this.chunks[i]
        str += this._chunkToString(chunk)
      }
    
      return str.substr(1)
    }
    
    Script.prototype.toHex = function () {
      return encodeHex(this.buffer)
    }
    
    Script.prototype.inspect = function () {
      return '<Script: ' + this.toString() + '>'
    }
    
    // script classification methods
    
    /**
     * @returns {boolean} if this is a pay to pubkey hash output script
     */
    Script.prototype.isPublicKeyHashOut = function () {
      return !!(this.chunks.length === 5 &&
        this.chunks[0].opcodenum === Opcode.OP_DUP &&
        this.chunks[1].opcodenum === Opcode.OP_HASH160 &&
        this.chunks[2].buf &&
        this.chunks[2].buf.length === 20 &&
        this.chunks[3].opcodenum === Opcode.OP_EQUALVERIFY &&
        this.chunks[4].opcodenum === Opcode.OP_CHECKSIG)
    }
    
    /**
     * @returns {boolean} if this is a pay to public key hash input script
     */
    Script.prototype.isPublicKeyHashIn = function () {
      if (this.chunks.length === 2) {
        var signatureBuf = this.chunks[0].buf
        var pubkeyBuf = this.chunks[1].buf
        if (signatureBuf &&
          signatureBuf.length &&
          signatureBuf[0] === 0x30 &&
          pubkeyBuf &&
          pubkeyBuf.length
        ) {
          var version = pubkeyBuf[0]
          if ((version === 0x04 ||
            version === 0x06 ||
            version === 0x07) && pubkeyBuf.length === 65) {
            return true
          } else if ((version === 0x03 || version === 0x02) && pubkeyBuf.length === 33) {
            return true
          }
        }
      }
      return false
    }
    
    Script.prototype.getPublicKey = function () {
      $.checkState(this.isPublicKeyOut(), 'Can\'t retrieve PublicKey from a non-PK output')
      return this.chunks[0].buf
    }
    
    Script.prototype.getPublicKeyHash = function () {
      $.checkState(this.isPublicKeyHashOut(), 'Can\'t retrieve PublicKeyHash from a non-PKH output')
      return this.chunks[2].buf
    }
    
    /**
     * @returns {boolean} if this is a public key output script
     */
    Script.prototype.isPublicKeyOut = function () {
      if (this.chunks.length === 2 &&
        this.chunks[0].buf &&
        this.chunks[0].buf.length &&
        this.chunks[1].opcodenum === Opcode.OP_CHECKSIG) {
        var pubkeyBuf = this.chunks[0].buf
        var version = pubkeyBuf[0]
        var isVersion = false
        if ((version === 0x04 ||
          version === 0x06 ||
          version === 0x07) && pubkeyBuf.length === 65) {
          isVersion = true
        } else if ((version === 0x03 || version === 0x02) && pubkeyBuf.length === 33) {
          isVersion = true
        }
        if (isVersion) {
          return PublicKey.isValid(pubkeyBuf)
        }
      }
      return false
    }
    
    /**
     * @returns {boolean} if this is a pay to public key input script
     */
    Script.prototype.isPublicKeyIn = function () {
      if (this.chunks.length === 1) {
        var signatureBuf = this.chunks[0].buf
        if (signatureBuf &&
          signatureBuf.length &&
          signatureBuf[0] === 0x30) {
          return true
        }
      }
      return false
    }
    
    /**
     * @returns {boolean} if this is a p2sh output script
     */
    Script.prototype.isScriptHashOut = function () {
      var buf = this.toBuffer()
      return (buf.length === 23 &&
        buf[0] === Opcode.OP_HASH160 &&
        buf[1] === 0x14 &&
        buf[buf.length - 1] === Opcode.OP_EQUAL)
    }
    
    /**
     * @returns {boolean} if this is a p2sh input script
     * Note that these are frequently indistinguishable from pubkeyhashin
     */
    Script.prototype.isScriptHashIn = function () {
      if (this.chunks.length <= 1) {
        return false
      }
      var redeemChunk = this.chunks[this.chunks.length - 1]
      var redeemBuf = redeemChunk.buf
      if (!redeemBuf) {
        return false
      }
    
      var redeemScript
      try {
        redeemScript = Script.fromBuffer(redeemBuf)
      } catch (e) {
        if (e instanceof errors.Script.InvalidBuffer) {
          return false
        }
        throw e
      }
      var type = redeemScript.classify()
      return type !== Script.types.UNKNOWN
    }
    
    /**
     * @returns {boolean} if this is a mutlsig output script
     */
    Script.prototype.isMultisigOut = function () {
      return (this.chunks.length > 3 &&
        Opcode.isSmallIntOp(this.chunks[0].opcodenum) &&
        this.chunks.slice(1, this.chunks.length - 2).every(function (obj) {
          return obj.buf && Buffer.isBuffer(obj.buf)
        }) &&
        Opcode.isSmallIntOp(this.chunks[this.chunks.length - 2].opcodenum) &&
        this.chunks[this.chunks.length - 1].opcodenum === Opcode.OP_CHECKMULTISIG)
    }
    
    /**
     * @returns {boolean} if this is a multisig input script
     */
    Script.prototype.isMultisigIn = function () {
      return this.chunks.length >= 2 &&
        this.chunks[0].opcodenum === 0 &&
        this.chunks.slice(1, this.chunks.length).every(function (obj) {
          return obj.buf &&
            Buffer.isBuffer(obj.buf) &&
            Signature.isTxDER(obj.buf)
        })
    }
    
    /**
     * @returns {boolean} true if this is a valid standard OP_RETURN output
     */
    Script.prototype.isDataOut = function () {
      var step1 = this.buffer.length >= 1 &&
        this.buffer[0] === Opcode.OP_RETURN
      if (!step1) return false
      var buffer = this.buffer.slice(1)
      var script2 = new Script({ buffer: buffer })
      return script2.isPushOnly()
    }
    
    Script.prototype.isSafeDataOut = function () {
      if (this.buffer.length < 2) {
        return false
      }
      if (this.buffer[0] !== Opcode.OP_FALSE) {
        return false
      }
      var buffer = this.buffer.slice(1)
      var script2 = new Script({ buffer })
      return script2.isDataOut()
    }
    
    /**
     * Retrieve the associated data for this script.
     * In the case of a pay to public key hash or P2SH, return the hash.
     * In the case of safe OP_RETURN data, return an array of buffers
     * In the case of a standard deprecated OP_RETURN, return the data
     * @returns {Buffer}
     */
    Script.prototype.getData = function () {
      if (this.isSafeDataOut()) {
        var chunks = this.chunks.slice(2)
        var buffers = chunks.map(chunk => chunk.buf)
        return buffers
      }
      if (this.isDataOut() || this.isScriptHashOut()) {
        if (_.isUndefined(this.chunks[1])) {
          return Buffer.alloc(0)
        } else {
          return Buffer.from(this.chunks[1].buf)
        }
      }
      if (this.isPublicKeyHashOut()) {
        return Buffer.from(this.chunks[2].buf)
      }
      throw new Error('Unrecognized script type to get data from')
    }
    
    /**
     * @returns {boolean} if the script is only composed of data pushing
     * opcodes or small int opcodes (OP_0, OP_1, ..., OP_16)
     */
    Script.prototype.isPushOnly = function () {
      return _.every(this.chunks, function (chunk) {
        return chunk.opcodenum <= Opcode.OP_16 ||
          chunk.opcodenum === Opcode.OP_PUSHDATA1 ||
          chunk.opcodenum === Opcode.OP_PUSHDATA2 ||
          chunk.opcodenum === Opcode.OP_PUSHDATA4
      })
    }
    
    Script.types = {}
    Script.types.UNKNOWN = 'Unknown'
    Script.types.PUBKEY_OUT = 'Pay to public key'
    Script.types.PUBKEY_IN = 'Spend from public key'
    Script.types.PUBKEYHASH_OUT = 'Pay to public key hash'
    Script.types.PUBKEYHASH_IN = 'Spend from public key hash'
    Script.types.SCRIPTHASH_OUT = 'Pay to script hash'
    Script.types.SCRIPTHASH_IN = 'Spend from script hash'
    Script.types.MULTISIG_OUT = 'Pay to multisig'
    Script.types.MULTISIG_IN = 'Spend from multisig'
    Script.types.DATA_OUT = 'Data push'
    Script.types.SAFE_DATA_OUT = 'Safe data push'
    
    Script.OP_RETURN_STANDARD_SIZE = 220
    
    /**
     * @returns {object} The Script type if it is a known form,
     * or Script.UNKNOWN if it isn't
     */
    Script.prototype.classify = function () {
      if (this._isInput) {
        return this.classifyInput()
      } else if (this._isOutput) {
        return this.classifyOutput()
      } else {
        var outputType = this.classifyOutput()
        return outputType !== Script.types.UNKNOWN ? outputType : this.classifyInput()
      }
    }
    
    Script.outputIdentifiers = {}
    Script.outputIdentifiers.PUBKEY_OUT = Script.prototype.isPublicKeyOut
    Script.outputIdentifiers.PUBKEYHASH_OUT = Script.prototype.isPublicKeyHashOut
    Script.outputIdentifiers.MULTISIG_OUT = Script.prototype.isMultisigOut
    Script.outputIdentifiers.SCRIPTHASH_OUT = Script.prototype.isScriptHashOut
    Script.outputIdentifiers.DATA_OUT = Script.prototype.isDataOut
    Script.outputIdentifiers.SAFE_DATA_OUT = Script.prototype.isSafeDataOut
    
    /**
     * @returns {object} The Script type if it is a known form,
     * or Script.UNKNOWN if it isn't
     */
    Script.prototype.classifyOutput = function () {
      for (var type in Script.outputIdentifiers) {
        if (Script.outputIdentifiers[type].bind(this)()) {
          return Script.types[type]
        }
      }
      return Script.types.UNKNOWN
    }
    
    Script.inputIdentifiers = {}
    Script.inputIdentifiers.PUBKEY_IN = Script.prototype.isPublicKeyIn
    Script.inputIdentifiers.PUBKEYHASH_IN = Script.prototype.isPublicKeyHashIn
    Script.inputIdentifiers.MULTISIG_IN = Script.prototype.isMultisigIn
    Script.inputIdentifiers.SCRIPTHASH_IN = Script.prototype.isScriptHashIn
    
    /**
     * @returns {object} The Script type if it is a known form,
     * or Script.UNKNOWN if it isn't
     */
    Script.prototype.classifyInput = function () {
      for (var type in Script.inputIdentifiers) {
        if (Script.inputIdentifiers[type].bind(this)()) {
          return Script.types[type]
        }
      }
      return Script.types.UNKNOWN
    }
    
    /**
     * @returns {boolean} if script is one of the known types
     */
    Script.prototype.isStandard = function () {
      // TODO: Add BIP62 compliance
      return this.classify() !== Script.types.UNKNOWN
    }
    
    // Script construction methods
    
    /**
     * Adds a script element at the start of the script.
     * @param {*} obj a string, number, Opcode, Buffer, or object to add
     * @returns {Script} this script instance
     */
    Script.prototype.prepend = function (obj) {
      this._addByType(obj, true)
      return this
    }
    
    /**
     * Compares a script with another script
     */
    Script.prototype.equals = function (script) {
      $.checkState(script instanceof Script, 'Must provide another script')
      if (this.buffer.length !== script.buffer.length) {
        return false
      }
      var i
      for (i = 0; i < this.buffer.length; i++) {
        if (this.buffer[i] !== script.buffer[i]) {
          return false
        }
      }
      return true
    }
    
    /**
     * Adds a script element to the end of the script.
     *
     * @param {*} obj a string, number, Opcode, Buffer, or object to add
     * @returns {Script} this script instance
     *
     */
    Script.prototype.add = function (obj) {
      this._addByType(obj, false)
      return this
    }
    
    Script.prototype._addByType = function (obj, prepend) {
      if (typeof obj === 'string') {
        this._addOpcode(obj, prepend)
      } else if (typeof obj === 'number') {
        this._addOpcode(obj, prepend)
      } else if (obj instanceof Opcode) {
        this._addOpcode(obj, prepend)
      } else if (Buffer.isBuffer(obj)) {
        this._addBuffer(obj, prepend)
      } else if (obj instanceof Script) {
        this._insertAtPosition(obj.buffer, prepend)
      } else if (typeof obj === 'object') {
        var s = Script.fromChunks([obj])
        this._insertAtPosition(s.toBuffer(), prepend)
      } else {
        throw new Error('Invalid script chunk')
      }
    }
    
    Script.prototype._insertAtPosition = function (buf, prepend) {
      var bw = new BufferWriter()
    
      if (prepend) {
        bw.write(buf)
        bw.write(this.buffer)
      } else {
        bw.write(this.buffer)
        bw.write(buf)
      }
      this.buffer = bw.toBuffer()
    }
    
    Script.prototype._addOpcode = function (opcode, prepend) {
      var op
      if (typeof opcode === 'number') {
        op = opcode
      } else if (opcode instanceof Opcode) {
        op = opcode.toNumber()
      } else {
        op = Opcode(opcode).toNumber()
      }
    
      // OP_INVALIDOPCODE
      if (op > 255) {
        throw new errors.Script.InvalidOpcode(op)
      }
      this._insertAtPosition(Script.fromChunks([{
        opcodenum: op
      }]).toBuffer(), prepend)
      return this
    }
    
    Script.prototype._addBuffer = function (buf, prepend) {
      var bw = new BufferWriter()
      var opcodenum
      var len = buf.length
      if (len === 0) {
        opcodenum = 0
        bw.writeUInt8(opcodenum)
      } else if (len > 0 && len < Opcode.OP_PUSHDATA1) {
        opcodenum = len
        bw.writeUInt8(opcodenum)
        bw.write(buf)
      } else if (len < Math.pow(2, 8)) {
        opcodenum = Opcode.OP_PUSHDATA1
        bw.writeUInt8(opcodenum)
        bw.writeUInt8(len)
        bw.write(buf)
      } else if (len < Math.pow(2, 16)) {
        opcodenum = Opcode.OP_PUSHDATA2
        bw.writeUInt8(opcodenum)
        bw.writeUInt16LE(len)
        bw.write(buf)
      } else if (len < Math.pow(2, 32)) {
        opcodenum = Opcode.OP_PUSHDATA4
        bw.writeUInt8(opcodenum)
        bw.writeUInt32LE(len)
        bw.write(buf)
      } else {
        throw new Error('You can\'t push that much data')
      }
    
      this._insertAtPosition(bw.toBuffer(), prepend)
      return this
    }
    
    Script.prototype.clone = function () {
      return Script.fromBuffer(this.buffer.slice())
    }
    
    Script.prototype.removeCodeseparators = function () {
      var chunks = []
      for (var i = 0; i < this.chunks.length; i++) {
        if (this.chunks[i].opcodenum !== Opcode.OP_CODESEPARATOR) {
          chunks.push(this.chunks[i])
        }
      }
      SCRIPT_TO_CHUNKS_CACHE.delete(this)
    
      this.buffer = Script.fromChunks(chunks).toBuffer()
      return this
    }
    
    /**
     * If the script does not contain any OP_CODESEPARATOR, Return all scripts
     * If the script contains any OP_CODESEPARATOR, the scriptCode is the script but removing everything up to and including the last executed OP_CODESEPARATOR before the signature checking opcode being executed
     * @param {n} The {n}th codeseparator in the script
     *
     * @returns {Script} Subset of script starting at the {n}th codeseparator
     */
    Script.prototype.subScript = function (n) {
      var idx = 0
    
      for (var i = 0; i < this.chunks.length; i++) {
        if (this.chunks[i].opcodenum === Opcode.OP_CODESEPARATOR) {
          if (idx === n) {
            return Script.fromChunks(this.chunks.slice(i + 1))
          } else {
            idx++
          }
        }
      }
    
      return this
    }
    
    // high level script builder methods
    
    /**
     * @returns {Script} a new Multisig output script for given public keys,
     * requiring m of those public keys to spend
     * @param {PublicKey[]} publicKeys - list of all public keys controlling the output
     * @param {number} threshold - amount of required signatures to spend the output
     * @param {Object=} opts - Several options:
     *        - noSorting: defaults to false, if true, don't sort the given
     *                      public keys before creating the script
     */
    Script.buildMultisigOut = function (publicKeys, threshold, opts) {
      $.checkArgument(threshold <= publicKeys.length,
        'Number of required signatures must be less than or equal to the number of public keys')
      opts = opts || {}
      var script = new Script()
      script.add(Opcode.smallInt(threshold))
      publicKeys = _.map(publicKeys, PublicKey)
      var sorted = publicKeys
      if (!opts.noSorting) {
        sorted = publicKeys.map(k => k.toString('hex')).sort().map(k => new PublicKey(k))
      }
      for (var i = 0; i < sorted.length; i++) {
        var publicKey = sorted[i]
        script.add(publicKey.toBuffer())
      }
      script.add(Opcode.smallInt(publicKeys.length))
      script.add(Opcode.OP_CHECKMULTISIG)
      return script
    }
    
    /**
     * A new Multisig input script for the given public keys, requiring m of those public keys to spend
     *
     * @param {PublicKey[]} pubkeys list of all public keys controlling the output
     * @param {number} threshold amount of required signatures to spend the output
     * @param {Array} signatures and array of signature buffers to append to the script
     * @param {Object=} opts
     * @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default)
     * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript
     *
     * @returns {Script}
     */
    Script.buildMultisigIn = function (pubkeys, threshold, signatures, opts) {
      $.checkArgument(_.isArray(pubkeys))
      $.checkArgument(_.isNumber(threshold))
      $.checkArgument(_.isArray(signatures))
      opts = opts || {}
      var s = new Script()
      s.add(Opcode.OP_0)
      _.each(signatures, function (signature) {
        $.checkArgument(Buffer.isBuffer(signature), 'Signatures must be an array of Buffers')
        // TODO: allow signatures to be an array of Signature objects
        s.add(signature)
      })
      return s
    }
    
    /**
     * A new P2SH Multisig input script for the given public keys, requiring m of those public keys to spend
     *
     * @param {PublicKey[]} pubkeys list of all public keys controlling the output
     * @param {number} threshold amount of required signatures to spend the output
     * @param {Array} signatures and array of signature buffers to append to the script
     * @param {Object=} opts
     * @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default)
     * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript
     *
     * @returns {Script}
     */
    Script.buildP2SHMultisigIn = function (pubkeys, threshold, signatures, opts) {
      $.checkArgument(_.isArray(pubkeys))
      $.checkArgument(_.isNumber(threshold))
      $.checkArgument(_.isArray(signatures))
      opts = opts || {}
      var s = new Script()
      s.add(Opcode.OP_0)
      _.each(signatures, function (signature) {
        $.checkArgument(Buffer.isBuffer(signature), 'Signatures must be an array of Buffers')
        // TODO: allow signatures to be an array of Signature objects
        s.add(signature)
      })
      s.add((opts.cachedMultisig || Script.buildMultisigOut(pubkeys, threshold, opts)).toBuffer())
      return s
    }
    
    /**
     * @returns {Script} a new pay to public key hash output for the given
     * address or public key
     * @param {(Address|PublicKey)} to - destination address or public key
     */
    Script.buildPublicKeyHashOut = function (to) {
      $.checkArgument(!_.isUndefined(to))
      $.checkArgument(to instanceof PublicKey || to instanceof Address || _.isString(to))
      if (to instanceof PublicKey) {
        to = to.toAddress()
      } else if (_.isString(to)) {
        to = new Address(to)
      }
      var s = new Script()
      s.add(Opcode.OP_DUP)
        .add(Opcode.OP_HASH160)
        .add(to.hashBuffer)
        .add(Opcode.OP_EQUALVERIFY)
        .add(Opcode.OP_CHECKSIG)
      s._network = to.network
      return s
    }
    
    /**
     * @returns {Script} a new pay to public key output for the given
     *  public key
     */
    Script.buildPublicKeyOut = function (pubkey) {
      $.checkArgument(pubkey instanceof PublicKey)
      var s = new Script()
      s.add(pubkey.toBuffer())
        .add(Opcode.OP_CHECKSIG)
      return s
    }
    
    /**
     * @returns {Script} a new OP_RETURN script with data
     * @param {(string|Buffer|Array)} data - the data to embed in the output - it is a string, buffer, or array of strings or buffers
     * @param {(string)} encoding - the type of encoding of the string(s)
     */
    Script.buildDataOut = function (data, encoding) {
      $.checkArgument(_.isUndefined(data) || _.isString(data) || _.isArray(data) || Buffer.isBuffer(data))
      var datas = data
      if (!_.isArray(datas)) {
        datas = [data]
      }
      var s = new Script()
      s.add(Opcode.OP_RETURN)
      for (let data of datas) {
        $.checkArgument(_.isUndefined(data) || _.isString(data) || Buffer.isBuffer(data))
        if (_.isString(data)) {
          data = Buffer.from(data, encoding)
        }
        if (!_.isUndefined(data)) {
          s.add(data)
        }
      }
      return s
    }
    
    /**
     * @returns {Script} a new OP_RETURN script with data
     * @param {(string|Buffer|Array)} data - the data to embed in the output - it is a string, buffer, or array of strings or buffers
     * @param {(string)} encoding - the type of encoding of the string(s)
     */
    Script.buildSafeDataOut = function (data, encoding) {
      var s2 = Script.buildDataOut(data, encoding)
      var s1 = new Script()
      s1.add(Opcode.OP_FALSE)
      s1.add(s2)
      return s1
    }
    
    /**
     * @param {Script|Address} script - the redeemScript for the new p2sh output.
     *    It can also be a p2sh address
     * @returns {Script} new pay to script hash script for given script
     */
    Script.buildScriptHashOut = function (script) {
      $.checkArgument(script instanceof Script ||
        (script instanceof Address && script.isPayToScriptHash()))
      var s = new Script()
      s.add(Opcode.OP_HASH160)
        .add(script instanceof Address ? script.hashBuffer : Hash.sha256ripemd160(script.toBuffer()))
        .add(Opcode.OP_EQUAL)
    
      s._network = script._network || script.network
      return s
    }
    
    /**
     * Builds a scriptSig (a script for an input) that signs a public key output script.
     *
     * @param {Signature|Buffer} signature - a Signature object, or the signature in DER canonical encoding
     * @param {number=} sigtype - the type of the signature (defaults to SIGHASH_ALL)
     */
    Script.buildPublicKeyIn = function (signature, sigtype) {
      $.checkArgument(signature instanceof Signature || Buffer.isBuffer(signature))
      $.checkArgument(_.isUndefined(sigtype) || _.isNumber(sigtype))
      if (signature instanceof Signature) {
        signature = signature.toBuffer()
      }
      var script = new Script()
      script.add(Buffer.concat([
        signature,
        Buffer.from([(sigtype || Signature.SIGHASH_ALL) & 0xff])
      ]))
      return script
    }
    
    /**
     * Builds a scriptSig (a script for an input) that signs a public key hash
     * output script.
     *
     * @param {Buffer|string|PublicKey} publicKey
     * @param {Signature|Buffer} signature - a Signature object, or the signature in DER canonical encoding
     * @param {number=} sigtype - the type of the signature (defaults to SIGHASH_ALL)
     */
    Script.buildPublicKeyHashIn = function (publicKey, signature, sigtype) {
      $.checkArgument(signature instanceof Signature || Buffer.isBuffer(signature))
      $.checkArgument(_.isUndefined(sigtype) || _.isNumber(sigtype))
      if (signature instanceof Signature) {
        signature = signature.toBuffer()
      }
      var script = new Script()
        .add(Buffer.concat([
          signature,
          Buffer.from([(sigtype || Signature.SIGHASH_ALL) & 0xff])
        ]))
        .add(new PublicKey(publicKey).toBuffer())
      return script
    }
    
    /**
     * @returns {Script} an empty script
     */
    Script.empty = function () {
      return new Script()
    }
    
    /**
     * @returns {Script} a new pay to script hash script that pays to this script
     */
    Script.prototype.toScriptHashOut = function () {
      return Script.buildScriptHashOut(this)
    }
    
    /**
     * @return {Script} an output script built from the address
     */
    Script.fromAddress = function (address) {
      address = Address(address)
      if (address.isPayToScriptHash()) {
        return Script.buildScriptHashOut(address)
      } else if (address.isPayToPublicKeyHash()) {
        return Script.buildPublicKeyHashOut(address)
      }
      throw new errors.Script.UnrecognizedAddress(address)
    }
    
    /**
     * Will return the associated address information object
     * @return {Address|boolean}
     */
    Script.prototype.getAddressInfo = function (opts) {
      if (this._isInput) {
        return this._getInputAddressInfo()
      } else if (this._isOutput) {
        return this._getOutputAddressInfo()
      } else {
        var info = this._getOutputAddressInfo()
        if (!info) {
          return this._getInputAddressInfo()
        }
        return info
      }
    }
    
    /**
     * Will return the associated output scriptPubKey address information object
     * @return {Address|boolean}
     * @private
     */
    Script.prototype._getOutputAddressInfo = function () {
      var info = {}
      if (this.isScriptHashOut()) {
        info.hashBuffer = this.getData()
        info.type = Address.PayToScriptHash
      } else if (this.isPublicKeyHashOut()) {
        info.hashBuffer = this.getData()
        info.type = Address.PayToPublicKeyHash
      } else {
        return false
      }
      return info
    }
    
    /**
     * Will return the associated input scriptSig address information object
     * @return {Address|boolean}
     * @private
     */
    Script.prototype._getInputAddressInfo = function () {
      var info = {}
      if (this.isPublicKeyHashIn()) {
        // hash the publickey found in the scriptSig
        info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf)
        info.type = Address.PayToPublicKeyHash
      } else if (this.isScriptHashIn()) {
        // hash the redeemscript found at the end of the scriptSig
        info.hashBuffer = Hash.sha256ripemd160(this.chunks[this.chunks.length - 1].buf)
        info.type = Address.PayToScriptHash
      } else {
        return false
      }
      return info
    }
    
    /**
     * @param {Network=} network
     * @return {Address|boolean} the associated address for this script if possible, or false
     */
    Script.prototype.toAddress = function (network) {
      var info = this.getAddressInfo()
      if (!info) {
        return false
      }
      info.network = Networks.get(network) || this._network || Networks.defaultNetwork
      return new Address(info)
    }
    
    /**
     * Analogous to bitcoind's FindAndDelete. Find and delete equivalent chunks,
     * typically used with push data chunks.  Note that this will find and delete
     * not just the same data, but the same data with the same push data op as
     * produced by default. i.e., if a pushdata in a tx does not use the minimal
     * pushdata op, then when you try to remove the data it is pushing, it will not
     * be removed, because they do not use the same pushdata op.
     */
    Script.prototype.findAndDelete = function (script) {
      var buf = script.toBuffer()
      var hex = buf.toString('hex')
      var chunks = this.chunks
      for (var i = 0; i < chunks.length; i++) {
        var script2 = Script.fromChunks([chunks[i]])
        var buf2 = script2.toBuffer()
        var hex2 = buf2.toString('hex')
        if (hex === hex2) {
          chunks.splice(i, 1)
          this.buffer = Script.fromChunks(chunks).toBuffer()
        }
      }
      return this
    }
    
    /**
     * Comes from bitcoind's script interpreter CheckMinimalPush function
     * @returns {boolean} if the chunk {i} is the smallest way to push that particular data.
     */
    Script.prototype.checkMinimalPush = function (i) {
      var chunk = this.chunks[i]
      var buf = chunk.buf
      var opcodenum = chunk.opcodenum
      if (!buf) {
        return true
      }
      if (buf.length === 0) {
        // Could have used OP_0.
        return opcodenum === Opcode.OP_0
      } else if (buf.length === 1 && buf[0] >= 1 && buf[0] <= 16) {
        // Could have used OP_1 .. OP_16.
        return opcodenum === Opcode.OP_1 + (buf[0] - 1)
      } else if (buf.length === 1 && buf[0] === 0x81) {
        // Could have used OP_1NEGATE
        return opcodenum === Opcode.OP_1NEGATE
      } else if (buf.length <= 75) {
        // Could have used a direct push (opcode indicating number of bytes pushed + those bytes).
        return opcodenum === buf.length
      } else if (buf.length <= 255) {
        // Could have used OP_PUSHDATA.
        return opcodenum === Opcode.OP_PUSHDATA1
      } else if (buf.length <= 65535) {
        // Could have used OP_PUSHDATA2.
        return opcodenum === Opcode.OP_PUSHDATA2
      }
      return true
    }
    
    /**
     * Comes from bitcoind's script DecodeOP_N function
     * @param {number} opcode
     * @returns {number} numeric value in range of 0 to 16
     */
    Script.prototype._decodeOP_N = function (opcode) {
      if (opcode === Opcode.OP_0) {
        return 0
      } else if (opcode >= Opcode.OP_1 && opcode <= Opcode.OP_16) {
        return opcode - (Opcode.OP_1 - 1)
      } else {
        throw new Error('Invalid opcode: ' + JSON.stringify(opcode))
      }
    }
    
    /**
     * Comes from bitcoind's script GetSigOpCount(boolean) function
     * @param {boolean} use current (true) or pre-version-0.6 (false) logic
     * @returns {number} number of signature operations required by this script
     */
    Script.prototype.getSignatureOperationsCount = function (accurate) {
      accurate = (_.isUndefined(accurate) ? true : accurate)
      var self = this
      var n = 0
      var lastOpcode = Opcode.OP_INVALIDOPCODE
      _.each(self.chunks, function getChunk (chunk) {
        var opcode = chunk.opcodenum
        if (opcode === Opcode.OP_CHECKSIG || opcode === Opcode.OP_CHECKSIGVERIFY) {
          n++
        } else if (opcode === Opcode.OP_CHECKMULTISIG || opcode === Opcode.OP_CHECKMULTISIGVERIFY) {
          if (accurate && lastOpcode >= Opcode.OP_1 && lastOpcode <= Opcode.OP_16) {
            n += self._decodeOP_N(lastOpcode)
          } else {
            n += 20
          }
        }
        lastOpcode = opcode
      })
      return n
    }
    
    module.exports = Script
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../address":200,"../crypto/hash":208,"../crypto/signature":212,"../encoding/bufferwriter":220,"../encoding/decode-asm":221,"../encoding/decode-script-chunks":223,"../encoding/encode-hex":224,"../errors":227,"../networks":244,"../opcode":245,"../publickey":247,"../util/_":270,"../util/js":271,"../util/preconditions":272,"buffer":84}],251:[function(require,module,exports){
    'use strict'
    
    var Stack = function Stack (rawstack, varStack) {
      this.stack = rawstack
      this.varStack = varStack || []
    }
    
    module.exports = Stack
    
    Stack.prototype.pushVar = function (varName) {
      this.varStack.push(varName || '$tmp')
    }
    
    Stack.prototype.popVar = function () {
      this.varStack.pop()
    }
    
    Stack.prototype.push = function (n, varName) {
      this.pushVar(varName)
      this.stack.push(n)
      this.checkConsistency()
    }
    
    Stack.prototype.pop = function () {
      this.popVar()
      let top = this.stack.pop()
      this.checkConsistency()
      return top
    }
    
    Stack.prototype.updateTopVars = function (vars) {
      if (vars.length > this.varStack.length) {
        throw new Error(`updateTopVars fail, stack: ${this.stack.length},  varStack: ${this.varStack.length}, vars:${vars.length}`)
      }
      vars = vars.reverse()
      this.varStack.splice(this.varStack.length - vars.length, vars.length, ...vars)
    }
    
    Stack.prototype.stacktop = function (i) {
      return this.stack[this.stack.length + i]
    }
    
    Stack.prototype.vartop = function (i) {
      return this.varStack[this.varStack.length + i]
    }
    
    Stack.prototype.slice = function (start, end) {
      return this.stack.slice(start, end)
    }
    
    Stack.prototype.splice = function (start, deleteCount, ...items) {
      this.varStack.splice(start, deleteCount, ...items)
      return this.stack.splice(start, deleteCount, ...items)
    }
    
    Stack.prototype.write = function (i, value) {
      this.stack[this.stack.length + i] = value
    }
    
    Stack.prototype.copy = function () {
      return new Stack(this.stack.slice() || [], this.varStack.slice() || [])
    }
    
    function bytesToHexString (bytearray) {
      return bytearray.reduce(function (o, c) {
        o += ('0' + (c & 0xFF).toString(16)).slice(-2)
        return o
      }, '')
    }
    
    Stack.prototype.printVarStack = function () {
      let array = this.varStack.map((v, i) => ({
        name: v,
        value: bytesToHexString(this.rawstack[i].data)
      }))
      console.log(JSON.stringify(array, null, 4))
    }
    
    Stack.prototype.checkConsistency = function () {
      if (this.stack.length !== this.varStack.length) {
        this.printVarStack()
        throw new Error(`checkConsistency fail, stack: ${this.stack.length}, varStack:${this.varStack.length}`)
      }
    }
    
    Stack.prototype.checkConsistencyWithVars = function (varStack) {
      if (this.stack.length < varStack.length) {
        this.printVarStack()
        throw new Error(`checkConsistencyWithVars fail, stack: ${this.stack.length}, varStack:${varStack.length}`)
      }
    }
    
    Object.defineProperty(Stack.prototype, 'length', {
      get: function () {
        return this.stack.length
      }
    })
    
    Object.defineProperty(Stack.prototype, 'rawstack', {
      get: function () {
        return this.stack
      }
    })
    
    },{}],252:[function(require,module,exports){
    function writeI32LE (writer, n) {
      if (n < -2147483648 || n > 2147483647) throw new Error('Out of range. It must be >= -2147483648 and <= 2147483647.')
    
      const buffer = new Uint8Array(4)
      buffer[0] = n % 256
      n = Math.floor(n / 256)
      buffer[1] = n % 256
      n = n >> 8
      buffer[2] = n % 256
      n = n >> 8
      buffer[3] = n
    
      return writer.write(buffer)
    }
    
    module.exports = writeI32LE
    
    },{}],253:[function(require,module,exports){
    function writePushData (writer, buffer) {
      // It is possible to optimize buffers that only store numbers 1-16, or -1, by using the OP_N opcodes.
      // But we say "push data" is always stored using OP_0 or OP_PUSH(N) so that it's easy to identify and
      // extract, and also because there is some ambiguity around OP_0 if we don't do this.
      if (buffer.length === 0) {
        writer.write([0])
      } else if (buffer.length <= 75) {
        writer.write([buffer.length]) // OP_PUSH(buffer.length)
        writer.write(buffer)
      } else if (buffer.length <= 0xFF) {
        writer.write([76, buffer.length]) // OP_PUSHDATA1
        writer.write(buffer)
      } else if (buffer.length <= 0xFFFF) {
        writer.write([77, buffer.length % 256, buffer.length >> 8]) // OP_PUSHDATA2
        writer.write(buffer)
      } else if (buffer.length <= 0xFFFFFFFF) {
        const prefix = new Uint8Array(5)
        prefix[0] = 78 // OP_PUSHDATA4
        let n = buffer.length
        prefix[1] = n % 256
        n = Math.floor(n / 256)
        prefix[2] = n % 256
        n = Math.floor(n / 256)
        prefix[3] = n % 256
        n = Math.floor(n / 256)
        prefix[4] = n
        writer.write(prefix)
        writer.write(buffer)
      } else {
        throw new Error('data too large')
      }
      return writer
    }
    
    module.exports = writePushData
    
    },{}],254:[function(require,module,exports){
    function writeU16LE (writer, n) {
      if (n > 0xffff) throw new Error('number too large')
    
      const buffer = new Uint8Array(2)
      buffer[0] = n % 256
      n = n >> 8
      buffer[1] = n % 256
    
      return writer.write(buffer)
    }
    
    module.exports = writeU16LE
    
    },{}],255:[function(require,module,exports){
    function writeU32LE (writer, n) {
      if (n > 0xffffffff) throw new Error('number too large')
    
      const buffer = new Uint8Array(4)
      buffer[0] = n % 256
      n = Math.floor(n / 256)
      buffer[1] = n % 256
      n = n >> 8
      buffer[2] = n % 256
      n = n >> 8
      buffer[3] = n
    
      return writer.write(buffer)
    }
    
    module.exports = writeU32LE
    
    },{}],256:[function(require,module,exports){
    function writeU8LE (writer, n) {
      if (n > 0xff) throw new Error('number too large')
      const buffer = new Uint8Array(1)
      buffer[0] = n
      return writer.write(buffer)
    }
    
    module.exports = writeU8LE
    
    },{}],257:[function(require,module,exports){
    function writeVarint (writer, n) {
      if (n > Number.MAX_SAFE_INTEGER) throw new Error('varint too large')
    
      if (n <= 0xfc) {
        return writer.write([n])
      }
    
      if (n <= 0xffff) {
        return writer.write([0xfd, n % 256, Math.floor(n / 256)])
      }
    
      if (n <= 0xffffffff) {
        const buffer = new Uint8Array(5)
        buffer[0] = 0xfe
        buffer[1] = n % 256
        n = Math.floor(n / 256)
        buffer[2] = n % 256
        n = Math.floor(n / 256)
        buffer[3] = n % 256
        n = Math.floor(n / 256)
        buffer[4] = n
        return writer.write(buffer)
      }
    
      // n <= 0xffffffffffffffff
      const buffer = new Uint8Array(9)
      buffer[0] = 0xff
      buffer[1] = n % 256
      n = Math.floor(n / 256)
      buffer[2] = n % 256
      n = Math.floor(n / 256)
      buffer[3] = n % 256
      n = Math.floor(n / 256)
      buffer[4] = n % 256
      n = Math.floor(n / 256)
      buffer[5] = n % 256
      n = Math.floor(n / 256)
      buffer[6] = n % 256
      n = Math.floor(n / 256)
      buffer[7] = n % 256
      n = Math.floor(n / 256)
      buffer[8] = n
      return writer.write(buffer)
    }
    
    module.exports = writeVarint
    
    },{}],258:[function(require,module,exports){
    module.exports = require('./transaction')
    
    module.exports.Input = require('./input')
    module.exports.Output = require('./output')
    module.exports.UnspentOutput = require('./unspentoutput')
    module.exports.Signature = require('./signature')
    module.exports.Sighash = require('./sighash')
    
    },{"./input":259,"./output":265,"./sighash":266,"./signature":267,"./transaction":268,"./unspentoutput":269}],259:[function(require,module,exports){
    module.exports = require('./input')
    
    module.exports.PublicKey = require('./publickey')
    module.exports.PublicKeyHash = require('./publickeyhash')
    module.exports.MultiSig = require('./multisig.js')
    module.exports.MultiSigScriptHash = require('./multisigscripthash.js')
    
    },{"./input":260,"./multisig.js":261,"./multisigscripthash.js":262,"./publickey":263,"./publickeyhash":264}],260:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../../util/_')
    var $ = require('../../util/preconditions')
    var errors = require('../../errors')
    var BufferWriter = require('../../encoding/bufferwriter')
    var buffer = require('buffer')
    var JSUtil = require('../../util/js')
    var Script = require('../../script')
    var Sighash = require('../sighash')
    var Output = require('../output')
    
    var MAXINT = 0xffffffff // Math.pow(2, 32) - 1;
    var DEFAULT_RBF_SEQNUMBER = MAXINT - 2
    var DEFAULT_SEQNUMBER = MAXINT
    var DEFAULT_LOCKTIME_SEQNUMBER = MAXINT - 1
    
    function Input (params) {
      if (!(this instanceof Input)) {
        return new Input(params)
      }
      if (params) {
        return this._fromObject(params)
      }
    }
    
    Input.MAXINT = MAXINT
    Input.DEFAULT_SEQNUMBER = DEFAULT_SEQNUMBER
    Input.DEFAULT_LOCKTIME_SEQNUMBER = DEFAULT_LOCKTIME_SEQNUMBER
    Input.DEFAULT_RBF_SEQNUMBER = DEFAULT_RBF_SEQNUMBER
    // txid + output index + sequence number
    Input.BASE_SIZE = 32 + 4 + 4
    
    Object.defineProperty(Input.prototype, 'script', {
      configurable: false,
      enumerable: true,
      get: function () {
        if (this.isNull()) {
          return null
        }
        if (!this._script) {
          this._script = new Script(this._scriptBuffer)
          this._script._isInput = true
        }
        return this._script
      }
    })
    
    Input.fromObject = function (obj) {
      $.checkArgument(_.isObject(obj))
      var input = new Input()
      return input._fromObject(obj)
    }
    
    Input.prototype._fromObject = function (params) {
      var prevTxId
      if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) {
        prevTxId = buffer.Buffer.from(params.prevTxId, 'hex')
      } else {
        prevTxId = params.prevTxId
      }
      this.output = params.output
        ? (params.output instanceof Output ? params.output : new Output(params.output)) : undefined
      this.prevTxId = prevTxId || params.txidbuf
      this.outputIndex = _.isUndefined(params.outputIndex) ? params.txoutnum : params.outputIndex
      this.sequenceNumber = _.isUndefined(params.sequenceNumber)
        ? (_.isUndefined(params.seqnum) ? DEFAULT_SEQNUMBER : params.seqnum) : params.sequenceNumber
      if (_.isUndefined(params.script) && _.isUndefined(params.scriptBuffer)) {
        throw new errors.Transaction.Input.MissingScript()
      }
      this.setScript(params.scriptBuffer || params.script)
      return this
    }
    
    Input.prototype.toObject = Input.prototype.toJSON = function toObject () {
      var obj = {
        prevTxId: this.prevTxId.toString('hex'),
        outputIndex: this.outputIndex,
        sequenceNumber: this.sequenceNumber,
        script: this._scriptBuffer.toString('hex')
      }
      // add human readable form if input contains valid script
      if (this.script) {
        obj.scriptString = this.script.toString()
      }
      if (this.output) {
        obj.output = this.output.toObject()
      }
      return obj
    }
    
    Input.fromBufferReader = function (br) {
      var input = new Input()
      input.prevTxId = br.readReverse(32)
      input.outputIndex = br.readUInt32LE()
      input._scriptBuffer = br.readVarLengthBuffer()
      input.sequenceNumber = br.readUInt32LE()
      // TODO: return different classes according to which input it is
      // e.g: CoinbaseInput, PublicKeyHashInput, MultiSigScriptHashInput, etc.
      return input
    }
    
    Input.prototype.toBufferWriter = function (writer) {
      if (!writer) {
        writer = new BufferWriter()
      }
      writer.writeReverse(this.prevTxId)
      writer.writeUInt32LE(this.outputIndex)
      var script = this._scriptBuffer
      writer.writeVarintNum(script.length)
      writer.write(script)
      writer.writeUInt32LE(this.sequenceNumber)
      return writer
    }
    
    Input.prototype.setScript = function (script) {
      this._script = null
      if (script instanceof Script) {
        this._script = script
        this._script._isInput = true
        this._scriptBuffer = script.toBuffer()
      } else if (script === null) {
        this._script = Script.empty()
        this._script._isInput = true
        this._scriptBuffer = this._script.toBuffer()
      } else if (JSUtil.isHexa(script)) {
        // hex string script
        this._scriptBuffer = buffer.Buffer.from(script, 'hex')
      } else if (_.isString(script)) {
        // human readable string script
        this._script = new Script(script)
        this._script._isInput = true
        this._scriptBuffer = this._script.toBuffer()
      } else if (Buffer.isBuffer(script)) {
        // buffer script
        this._scriptBuffer = buffer.Buffer.from(script)
      } else {
        throw new TypeError('Invalid argument type: script')
      }
      return this
    }
    
    /**
     * Retrieve signatures for the provided PrivateKey.
     *
     * @param {Transaction} transaction - the transaction to be signed
     * @param {PrivateKey} privateKey - the private key to use when signing
     * @param {number} inputIndex - the index of this input in the provided transaction
     * @param {number} sigType - defaults to Signature.SIGHASH_ALL
     * @param {Buffer} addressHash - if provided, don't calculate the hash of the
     *     public key associated with the private key provided
     * @abstract
     */
    Input.prototype.getSignatures = function () {
      // throw new errors.AbstractMethodInvoked(
      //   'Trying to sign unsupported output type (only P2PKH and P2SH multisig inputs are supported)' +
      //   ' for input: ' + JSON.stringify(this)
      // )
      return []
    }
    
    Input.prototype.isFullySigned = function () {
      throw new errors.AbstractMethodInvoked('Input#isFullySigned')
    }
    
    Input.prototype.isFinal = function () {
      return this.sequenceNumber === Input.MAXINT
    }
    
    Input.prototype.addSignature = function () {
      // throw new errors.AbstractMethodInvoked('Input#addSignature')
    }
    
    Input.prototype.clearSignatures = function () {
      // throw new errors.AbstractMethodInvoked('Input#clearSignatures')
    }
    
    Input.prototype.isValidSignature = function (transaction, signature) {
      // FIXME: Refactor signature so this is not necessary
      signature.signature.nhashtype = signature.sigtype
      return Sighash.verify(
        transaction,
        signature.signature,
        signature.publicKey,
        signature.inputIndex,
        this.output.script,
        this.output.satoshisBN
      )
    }
    
    /**
     * @returns true if this is a coinbase input (represents no input)
     */
    Input.prototype.isNull = function () {
      return this.prevTxId.toString('hex') === '0000000000000000000000000000000000000000000000000000000000000000' &&
        this.outputIndex === 0xffffffff
    }
    
    Input.prototype._estimateSize = function () {
      return this.toBufferWriter().toBuffer().length
    }
    
    module.exports = Input
    
    }).call(this)}).call(this,{"isBuffer":require("../../../../is-buffer/index.js")})
    
    },{"../../../../is-buffer/index.js":184,"../../encoding/bufferwriter":220,"../../errors":227,"../../script":248,"../../util/_":270,"../../util/js":271,"../../util/preconditions":272,"../output":265,"../sighash":266,"buffer":84}],261:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../../util/_')
    var inherits = require('inherits')
    var Input = require('./input')
    var Output = require('../output')
    var $ = require('../../util/preconditions')
    
    var Script = require('../../script')
    var Signature = require('../../crypto/signature')
    var Sighash = require('../sighash')
    var TransactionSignature = require('../signature')
    var PublicKey = require('../../publickey')
    var Varint = require('../../encoding/varint')
    
    /**
     * @constructor
     */
    function MultiSigInput (input, pubkeys, threshold, signatures) {
      Input.apply(this, arguments)
      var self = this
      pubkeys = pubkeys || input.publicKeys
      threshold = threshold || input.threshold
      signatures = signatures || input.signatures
      this.publicKeys = pubkeys.map(k => k.toString('hex')).sort().map(k => new PublicKey(k))
      $.checkState(Script.buildMultisigOut(this.publicKeys, threshold).equals(this.output.script),
        'Provided public keys don\'t match to the provided output script')
      this.publicKeyIndex = {}
      _.each(this.publicKeys, function (publicKey, index) {
        self.publicKeyIndex[publicKey.toString()] = index
      })
      this.threshold = threshold
      // Empty array of signatures
      this.signatures = signatures ? this._deserializeSignatures(signatures) : new Array(this.publicKeys.length)
    }
    inherits(MultiSigInput, Input)
    
    MultiSigInput.prototype.toObject = function () {
      var obj = Input.prototype.toObject.apply(this, arguments)
      obj.threshold = this.threshold
      obj.publicKeys = _.map(this.publicKeys, function (publicKey) { return publicKey.toString() })
      obj.signatures = this._serializeSignatures()
      return obj
    }
    
    MultiSigInput.prototype._deserializeSignatures = function (signatures) {
      return _.map(signatures, function (signature) {
        if (!signature) {
          return undefined
        }
        return new TransactionSignature(signature)
      })
    }
    
    MultiSigInput.prototype._serializeSignatures = function () {
      return _.map(this.signatures, function (signature) {
        if (!signature) {
          return undefined
        }
        return signature.toObject()
      })
    }
    
    MultiSigInput.prototype.getSignatures = function (transaction, privateKey, index, sigtype) {
      $.checkState(this.output instanceof Output)
      sigtype = sigtype || (Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
    
      var self = this
      var results = []
      _.each(this.publicKeys, function (publicKey) {
        if (publicKey.toString() === privateKey.publicKey.toString()) {
          results.push(new TransactionSignature({
            publicKey: privateKey.publicKey,
            prevTxId: self.prevTxId,
            outputIndex: self.outputIndex,
            inputIndex: index,
            signature: Sighash.sign(transaction, privateKey, sigtype, index, self.output.script, self.output.satoshisBN),
            sigtype: sigtype
          }))
        }
      })
    
      return results
    }
    
    MultiSigInput.prototype.addSignature = function (transaction, signature) {
      $.checkState(!this.isFullySigned(), 'All needed signatures have already been added')
      $.checkArgument(!_.isUndefined(this.publicKeyIndex[signature.publicKey.toString()]),
        'Signature has no matching public key')
      $.checkState(this.isValidSignature(transaction, signature))
      this.signatures[this.publicKeyIndex[signature.publicKey.toString()]] = signature
      this._updateScript()
      return this
    }
    
    MultiSigInput.prototype._updateScript = function () {
      this.setScript(Script.buildMultisigIn(
        this.publicKeys,
        this.threshold,
        this._createSignatures()
      ))
      return this
    }
    
    MultiSigInput.prototype._createSignatures = function () {
      return _.map(
        _.filter(this.signatures, function (signature) { return !_.isUndefined(signature) }),
        function (signature) {
          return Buffer.concat([
            signature.signature.toDER(),
            Buffer.from([signature.sigtype & 0xff])
          ])
        }
      )
    }
    
    MultiSigInput.prototype.clearSignatures = function () {
      this.signatures = new Array(this.publicKeys.length)
      this._updateScript()
    }
    
    MultiSigInput.prototype.isFullySigned = function () {
      return this.countSignatures() === this.threshold
    }
    
    MultiSigInput.prototype.countMissingSignatures = function () {
      return this.threshold - this.countSignatures()
    }
    
    MultiSigInput.prototype.countSignatures = function () {
      return _.reduce(this.signatures, function (sum, signature) {
        return sum + (!!signature)
      }, 0)
    }
    
    MultiSigInput.prototype.publicKeysWithoutSignature = function () {
      var self = this
      return _.filter(this.publicKeys, function (publicKey) {
        return !(self.signatures[self.publicKeyIndex[publicKey.toString()]])
      })
    }
    
    MultiSigInput.prototype.isValidSignature = function (transaction, signature) {
      // FIXME: Refactor signature so this is not necessary
      signature.signature.nhashtype = signature.sigtype
      return Sighash.verify(
        transaction,
        signature.signature,
        signature.publicKey,
        signature.inputIndex,
        this.output.script,
        this.output.satoshisBN
      )
    }
    
    /**
     *
     * @param {Buffer[]} signatures
     * @param {PublicKey[]} publicKeys
     * @param {Transaction} transaction
     * @param {Integer} inputIndex
     * @param {Input} input
     * @returns {TransactionSignature[]}
     */
    MultiSigInput.normalizeSignatures = function (transaction, input, inputIndex, signatures, publicKeys) {
      return publicKeys.map(function (pubKey) {
        var signatureMatch = null
        signatures = signatures.filter(function (signatureBuffer) {
          if (signatureMatch) {
            return true
          }
    
          var signature = new TransactionSignature({
            signature: Signature.fromTxFormat(signatureBuffer),
            publicKey: pubKey,
            prevTxId: input.prevTxId,
            outputIndex: input.outputIndex,
            inputIndex: inputIndex,
            sigtype: Signature.SIGHASH_ALL
          })
    
          signature.signature.nhashtype = signature.sigtype
          var isMatch = Sighash.verify(
            transaction,
            signature.signature,
            signature.publicKey,
            signature.inputIndex,
            input.output.script
          )
    
          if (isMatch) {
            signatureMatch = signature
            return false
          }
    
          return true
        })
    
        return signatureMatch || null
      })
    }
    
    // 32   txid
    // 4    output index
    // --- script ---
    // ??? script size (VARINT)
    // 1    OP_0
    // --- signature list ---
    //      1       signature size (OP_PUSHDATA)
    //      <=72    signature (DER + SIGHASH type)
    //
    // 4    sequence number
    MultiSigInput.SIGNATURE_SIZE = 73
    
    MultiSigInput.prototype._estimateSize = function () {
      var scriptSize = 1 + this.threshold * MultiSigInput.SIGNATURE_SIZE
      return Input.BASE_SIZE + Varint(scriptSize).toBuffer().length + scriptSize
    }
    
    module.exports = MultiSigInput
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../crypto/signature":212,"../../encoding/varint":226,"../../publickey":247,"../../script":248,"../../util/_":270,"../../util/preconditions":272,"../output":265,"../sighash":266,"../signature":267,"./input":260,"buffer":84,"inherits":276}],262:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../../util/_')
    var inherits = require('inherits')
    var Input = require('./input')
    var Output = require('../output')
    var $ = require('../../util/preconditions')
    
    var Script = require('../../script')
    var Signature = require('../../crypto/signature')
    var Sighash = require('../sighash')
    var TransactionSignature = require('../signature')
    var PublicKey = require('../../publickey')
    var Varint = require('../../encoding/varint')
    
    /**
     * @constructor
     */
    function MultiSigScriptHashInput (input, pubkeys, threshold, signatures) {
      Input.apply(this, arguments)
      var self = this
      pubkeys = pubkeys || input.publicKeys
      threshold = threshold || input.threshold
      signatures = signatures || input.signatures
      this.publicKeys = pubkeys.map(k => k.toString('hex')).sort().map(k => new PublicKey(k))
      this.redeemScript = Script.buildMultisigOut(this.publicKeys, threshold)
      $.checkState(Script.buildScriptHashOut(this.redeemScript).equals(this.output.script),
        'Provided public keys don\'t hash to the provided output')
      this.publicKeyIndex = {}
      _.each(this.publicKeys, function (publicKey, index) {
        self.publicKeyIndex[publicKey.toString()] = index
      })
      this.threshold = threshold
      // Empty array of signatures
      this.signatures = signatures ? this._deserializeSignatures(signatures) : new Array(this.publicKeys.length)
    }
    inherits(MultiSigScriptHashInput, Input)
    
    MultiSigScriptHashInput.prototype.toObject = function () {
      var obj = Input.prototype.toObject.apply(this, arguments)
      obj.threshold = this.threshold
      obj.publicKeys = _.map(this.publicKeys, function (publicKey) { return publicKey.toString() })
      obj.signatures = this._serializeSignatures()
      return obj
    }
    
    MultiSigScriptHashInput.prototype._deserializeSignatures = function (signatures) {
      return _.map(signatures, function (signature) {
        if (!signature) {
          return undefined
        }
        return new TransactionSignature(signature)
      })
    }
    
    MultiSigScriptHashInput.prototype._serializeSignatures = function () {
      return _.map(this.signatures, function (signature) {
        if (!signature) {
          return undefined
        }
        return signature.toObject()
      })
    }
    
    MultiSigScriptHashInput.prototype.getSignatures = function (transaction, privateKey, index, sigtype) {
      $.checkState(this.output instanceof Output)
      sigtype = sigtype || (Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
    
      var self = this
      var results = []
      _.each(this.publicKeys, function (publicKey) {
        if (publicKey.toString() === privateKey.publicKey.toString()) {
          results.push(new TransactionSignature({
            publicKey: privateKey.publicKey,
            prevTxId: self.prevTxId,
            outputIndex: self.outputIndex,
            inputIndex: index,
            signature: Sighash.sign(transaction, privateKey, sigtype, index, self.redeemScript, self.output.satoshisBN),
            sigtype: sigtype
          }))
        }
      })
      return results
    }
    
    MultiSigScriptHashInput.prototype.addSignature = function (transaction, signature) {
      $.checkState(!this.isFullySigned(), 'All needed signatures have already been added')
      $.checkArgument(!_.isUndefined(this.publicKeyIndex[signature.publicKey.toString()]),
        'Signature has no matching public key')
      $.checkState(this.isValidSignature(transaction, signature))
      this.signatures[this.publicKeyIndex[signature.publicKey.toString()]] = signature
      this._updateScript()
      return this
    }
    
    MultiSigScriptHashInput.prototype._updateScript = function () {
      this.setScript(Script.buildP2SHMultisigIn(
        this.publicKeys,
        this.threshold,
        this._createSignatures(),
        { cachedMultisig: this.redeemScript }
      ))
      return this
    }
    
    MultiSigScriptHashInput.prototype._createSignatures = function () {
      return _.map(
        _.filter(this.signatures, function (signature) { return !_.isUndefined(signature) }),
        function (signature) {
          return Buffer.concat([
            signature.signature.toDER(),
            Buffer.from([signature.sigtype & 0xff])
          ])
        }
      )
    }
    
    MultiSigScriptHashInput.prototype.clearSignatures = function () {
      this.signatures = new Array(this.publicKeys.length)
      this._updateScript()
    }
    
    MultiSigScriptHashInput.prototype.isFullySigned = function () {
      return this.countSignatures() === this.threshold
    }
    
    MultiSigScriptHashInput.prototype.countMissingSignatures = function () {
      return this.threshold - this.countSignatures()
    }
    
    MultiSigScriptHashInput.prototype.countSignatures = function () {
      return _.reduce(this.signatures, function (sum, signature) {
        return sum + (!!signature)
      }, 0)
    }
    
    MultiSigScriptHashInput.prototype.publicKeysWithoutSignature = function () {
      var self = this
      return _.filter(this.publicKeys, function (publicKey) {
        return !(self.signatures[self.publicKeyIndex[publicKey.toString()]])
      })
    }
    
    MultiSigScriptHashInput.prototype.isValidSignature = function (transaction, signature) {
      // FIXME: Refactor signature so this is not necessary
      signature.signature.nhashtype = signature.sigtype
      return Sighash.verify(
        transaction,
        signature.signature,
        signature.publicKey,
        signature.inputIndex,
        this.redeemScript,
        this.output.satoshisBN
      )
    }
    
    // 32   txid
    // 4    output index
    // --- script ---
    // ???  script size (VARINT)
    // 1    OP_0
    // --- signature list ---
    //      1       signature size (OP_PUSHDATA)
    //      <=72    signature (DER + SIGHASH type)
    //
    // ???  redeem script size (OP_PUSHDATA)
    // --- redeem script ---
    //      1       OP_2
    //      --- public key list ---
    //      1       public key size (OP_PUSHDATA)
    //      33      compressed public key
    //
    //      1       OP_3
    //      1       OP_CHECKMULTISIG
    //
    // 4    sequence number
    MultiSigScriptHashInput.SIGNATURE_SIZE = 73
    MultiSigScriptHashInput.PUBKEY_SIZE = 34
    
    MultiSigScriptHashInput.prototype._estimateSize = function () {
      var pubKeysSize = this.publicKeys.length * MultiSigScriptHashInput.PUBKEY_SIZE
      var sigsSize = this.threshold * MultiSigScriptHashInput.SIGNATURE_SIZE
      var redeemScriptSize = 3 + pubKeysSize
      var redeemScriptPushdataSize = redeemScriptSize <= 75 ? 1 : redeemScriptSize <= 255 ? 2 : 3
      var scriptLength = sigsSize + 1 + redeemScriptPushdataSize + redeemScriptSize
      return Input.BASE_SIZE + Varint(scriptLength).toBuffer().length + scriptLength
    }
    
    module.exports = MultiSigScriptHashInput
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../crypto/signature":212,"../../encoding/varint":226,"../../publickey":247,"../../script":248,"../../util/_":270,"../../util/preconditions":272,"../output":265,"../sighash":266,"../signature":267,"./input":260,"buffer":84,"inherits":276}],263:[function(require,module,exports){
    'use strict'
    
    var inherits = require('inherits')
    
    var $ = require('../../util/preconditions')
    
    var Input = require('./input')
    var Output = require('../output')
    var Sighash = require('../sighash')
    var Script = require('../../script')
    var Signature = require('../../crypto/signature')
    var TransactionSignature = require('../signature')
    
    /**
     * Represents a special kind of input of PayToPublicKey kind.
     * @constructor
     */
    function PublicKeyInput () {
      Input.apply(this, arguments)
    }
    inherits(PublicKeyInput, Input)
    
    /**
     * @param {Transaction} transaction - the transaction to be signed
     * @param {PrivateKey} privateKey - the private key with which to sign the transaction
     * @param {number} index - the index of the input in the transaction input vector
     * @param {number=} sigtype - the type of signature, defaults to Signature.SIGHASH_ALL
     * @return {Array} of objects that can be
     */
    PublicKeyInput.prototype.getSignatures = function (transaction, privateKey, index, sigtype) {
      $.checkState(this.output instanceof Output)
      sigtype = sigtype || (Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
      var publicKey = privateKey.toPublicKey()
      if (publicKey.toString() === this.output.script.getPublicKey().toString('hex')) {
        return [new TransactionSignature({
          publicKey: publicKey,
          prevTxId: this.prevTxId,
          outputIndex: this.outputIndex,
          inputIndex: index,
          signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script, this.output.satoshisBN),
          sigtype: sigtype
        })]
      }
      return []
    }
    
    /**
     * Add the provided signature
     *
     * @param {Object} signature
     * @param {PublicKey} signature.publicKey
     * @param {Signature} signature.signature
     * @param {number=} signature.sigtype
     * @return {PublicKeyInput} this, for chaining
     */
    PublicKeyInput.prototype.addSignature = function (transaction, signature) {
      $.checkState(this.isValidSignature(transaction, signature), 'Signature is invalid')
      this.setScript(Script.buildPublicKeyIn(
        signature.signature.toDER(),
        signature.sigtype
      ))
      return this
    }
    
    /**
     * Clear the input's signature
     * @return {PublicKeyHashInput} this, for chaining
     */
    PublicKeyInput.prototype.clearSignatures = function () {
      this.setScript(Script.empty())
      return this
    }
    
    /**
     * Query whether the input is signed
     * @return {boolean}
     */
    PublicKeyInput.prototype.isFullySigned = function () {
      return this.script.isPublicKeyIn()
    }
    
    // 32   txid
    // 4    output index
    // ---
    // 1    script size (VARINT)
    // 1    signature size (OP_PUSHDATA)
    // <=72 signature (DER + SIGHASH type)
    // ---
    // 4    sequence number
    PublicKeyInput.SCRIPT_MAX_SIZE = 74
    
    PublicKeyInput.prototype._estimateSize = function () {
      return Input.BASE_SIZE + PublicKeyInput.SCRIPT_MAX_SIZE
    }
    
    module.exports = PublicKeyInput
    
    },{"../../crypto/signature":212,"../../script":248,"../../util/preconditions":272,"../output":265,"../sighash":266,"../signature":267,"./input":260,"inherits":276}],264:[function(require,module,exports){
    'use strict'
    
    var inherits = require('inherits')
    
    var $ = require('../../util/preconditions')
    
    var Hash = require('../../crypto/hash')
    var Input = require('./input')
    var Output = require('../output')
    var Sighash = require('../sighash')
    var Script = require('../../script')
    var Signature = require('../../crypto/signature')
    var TransactionSignature = require('../signature')
    
    /**
     * Represents a special kind of input of PayToPublicKeyHash kind.
     * @constructor
     */
    function PublicKeyHashInput () {
      Input.apply(this, arguments)
    }
    inherits(PublicKeyHashInput, Input)
    
    /**
     * @param {Transaction} transaction - the transaction to be signed
     * @param {PrivateKey} privateKey - the private key with which to sign the transaction
     * @param {number} index - the index of the input in the transaction input vector
     * @param {number=} sigtype - the type of signature, defaults to Signature.SIGHASH_ALL
     * @param {Buffer=} hashData - the precalculated hash of the public key associated with the privateKey provided
     * @return {Array} of objects that can be
     */
    PublicKeyHashInput.prototype.getSignatures = function (transaction, privateKey, index, sigtype, hashData) {
      $.checkState(this.output instanceof Output)
      hashData = hashData || Hash.sha256ripemd160(privateKey.publicKey.toBuffer())
      sigtype = sigtype || (Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID)
    
      if (hashData.equals(this.output.script.getPublicKeyHash())) {
        return [new TransactionSignature({
          publicKey: privateKey.publicKey,
          prevTxId: this.prevTxId,
          outputIndex: this.outputIndex,
          inputIndex: index,
          signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script, this.output.satoshisBN),
          sigtype: sigtype
        })]
      }
      return []
    }
    
    /**
     * Add the provided signature
     *
     * @param {Object} signature
     * @param {PublicKey} signature.publicKey
     * @param {Signature} signature.signature
     * @param {number=} signature.sigtype
     * @return {PublicKeyHashInput} this, for chaining
     */
    PublicKeyHashInput.prototype.addSignature = function (transaction, signature) {
      $.checkState(this.isValidSignature(transaction, signature), 'Signature is invalid')
    
      this.setScript(Script.buildPublicKeyHashIn(
        signature.publicKey,
        signature.signature.toDER(),
        signature.sigtype
      ))
      return this
    }
    
    /**
     * Clear the input's signature
     * @return {PublicKeyHashInput} this, for chaining
     */
    PublicKeyHashInput.prototype.clearSignatures = function () {
      this.setScript(Script.empty())
      return this
    }
    
    /**
     * Query whether the input is signed
     * @return {boolean}
     */
    PublicKeyHashInput.prototype.isFullySigned = function () {
      return this.script.isPublicKeyHashIn()
    }
    
    // 32   txid
    // 4    output index
    // --- script ---
    // 1    script size (VARINT)
    // 1    signature size (OP_PUSHDATA)
    // <=72 signature (DER + SIGHASH type)
    // 1    public key size (OP_PUSHDATA)
    // 33   compressed public key
    //
    // 4    sequence number
    PublicKeyHashInput.SCRIPT_MAX_SIZE = 108
    
    PublicKeyHashInput.prototype._estimateSize = function () {
      return Input.BASE_SIZE + PublicKeyHashInput.SCRIPT_MAX_SIZE
    }
    
    module.exports = PublicKeyHashInput
    
    },{"../../crypto/hash":208,"../../crypto/signature":212,"../../script":248,"../../util/preconditions":272,"../output":265,"../sighash":266,"../signature":267,"./input":260,"inherits":276}],265:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var BN = require('../crypto/bn')
    var buffer = require('buffer')
    var JSUtil = require('../util/js')
    var BufferWriter = require('../encoding/bufferwriter')
    var Varint = require('../encoding/varint')
    var Script = require('../script')
    var $ = require('../util/preconditions')
    var errors = require('../errors')
    
    var MAX_SAFE_INTEGER = 0x1fffffffffffff
    
    function Output (args) {
      if (!(this instanceof Output)) {
        return new Output(args)
      }
      if (_.isObject(args)) {
        this.satoshis = args.satoshis
        if (Buffer.isBuffer(args.script)) {
          this.setScriptFromBuffer(args.script)
        } else {
          var script
          if (_.isString(args.script) && JSUtil.isHexa(args.script)) {
            script = buffer.Buffer.from(args.script, 'hex')
          } else {
            script = args.script
          }
          this.setScript(script)
        }
      } else {
        throw new TypeError('Unrecognized argument for Output')
      }
    }
    
    Object.defineProperty(Output.prototype, 'script', {
      configurable: false,
      enumerable: true,
      get: function () {
        return this._script
      }
    })
    
    Object.defineProperty(Output.prototype, 'satoshis', {
      configurable: false,
      enumerable: true,
      get: function () {
        return this._satoshis
      },
      set: function (num) {
        if (num instanceof BN) {
          this._satoshisBN = num
          this._satoshis = num.toNumber()
        } else if (_.isString(num)) {
          this._satoshis = parseInt(num)
          this._satoshisBN = BN.fromNumber(this._satoshis)
        } else {
          $.checkArgument(
            JSUtil.isNaturalNumber(num),
            'Output satoshis is not a natural number'
          )
          this._satoshisBN = BN.fromNumber(num)
          this._satoshis = num
        }
        $.checkState(
          JSUtil.isNaturalNumber(this._satoshis),
          'Output satoshis is not a natural number'
        )
      }
    })
    
    Output.prototype.invalidSatoshis = function () {
      if (this._satoshis > MAX_SAFE_INTEGER) {
        return 'transaction txout satoshis greater than max safe integer'
      }
      if (this._satoshis !== this._satoshisBN.toNumber()) {
        return 'transaction txout satoshis has corrupted value'
      }
      if (this._satoshis < 0) {
        return 'transaction txout negative'
      }
      return false
    }
    
    Object.defineProperty(Output.prototype, 'satoshisBN', {
      configurable: false,
      enumerable: true,
      get: function () {
        return this._satoshisBN
      },
      set: function (num) {
        this._satoshisBN = num
        this._satoshis = num.toNumber()
        $.checkState(
          JSUtil.isNaturalNumber(this._satoshis),
          'Output satoshis is not a natural number'
        )
      }
    })
    
    Output.prototype.toObject = Output.prototype.toJSON = function toObject () {
      var obj = {
        satoshis: this.satoshis
      }
      obj.script = this._script.toBuffer().toString('hex')
      return obj
    }
    
    Output.fromObject = function (data) {
      return new Output(data)
    }
    
    Output.prototype.setScriptFromBuffer = function (buffer) {
      try {
        this._script = Script.fromBuffer(buffer)
        this._script._isOutput = true
      } catch (e) {
        if (e instanceof errors.Script.InvalidBuffer) {
          this._script = null
        } else {
          throw e
        }
      }
    }
    
    Output.prototype.setScript = function (script) {
      if (script instanceof Script) {
        this._script = script
        this._script._isOutput = true
      } else if (_.isString(script)) {
        this._script = Script.fromString(script)
        this._script._isOutput = true
      } else if (Buffer.isBuffer(script)) {
        this.setScriptFromBuffer(script)
      } else {
        throw new TypeError('Invalid argument type: script')
      }
      return this
    }
    
    Output.prototype.inspect = function () {
      var scriptStr
      if (this.script) {
        scriptStr = this.script.inspect()
      }
      return '<Output (' + this.satoshis + ' sats) ' + scriptStr + '>'
    }
    
    Output.fromBufferReader = function (br) {
      var obj = {}
      obj.satoshis = br.readUInt64LEBN()
      var size = br.readVarintNum()
      if (size !== 0) {
        obj.script = br.read(size)
      } else {
        obj.script = buffer.Buffer.from([])
      }
      return new Output(obj)
    }
    
    Output.prototype.toBufferWriter = function (writer) {
      if (!writer) {
        writer = new BufferWriter()
      }
      writer.writeUInt64LEBN(this._satoshisBN)
      var script = this._script.toBuffer()
      writer.writeVarintNum(script.length)
      writer.write(script)
      return writer
    }
    
    // 8    value
    // ???  script size (VARINT)
    // ???  script
    Output.prototype.getSize = function () {
      var scriptSize = this.script.toBuffer().length
      var varintSize = Varint(scriptSize).toBuffer().length
      return 8 + varintSize + scriptSize
    }
    
    module.exports = Output
    
    }).call(this)}).call(this,{"isBuffer":require("../../../is-buffer/index.js")})
    
    },{"../../../is-buffer/index.js":184,"../crypto/bn":205,"../encoding/bufferwriter":220,"../encoding/varint":226,"../errors":227,"../script":248,"../util/_":270,"../util/js":271,"../util/preconditions":272,"buffer":84}],266:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var buffer = require('buffer')
    
    var Signature = require('../crypto/signature')
    var Script = require('../script')
    var Output = require('./output')
    var BufferReader = require('../encoding/bufferreader')
    var BufferWriter = require('../encoding/bufferwriter')
    var BN = require('../crypto/bn')
    var Hash = require('../crypto/hash')
    var ECDSA = require('../crypto/ecdsa')
    var $ = require('../util/preconditions')
    var Interpreter = require('../script/interpreter')
    var _ = require('../util/_')
    
    var SIGHASH_SINGLE_BUG = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
    var BITS_64_ON = 'ffffffffffffffff'
    
    // By default, we sign with sighash_forkid
    var DEFAULT_SIGN_FLAGS = Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID
    
    var sighashPreimageForForkId = function (transaction, sighashType, inputNumber, subscript, satoshisBN) {
      var input = transaction.inputs[inputNumber]
      $.checkArgument(
        satoshisBN instanceof BN,
        'For ForkId=0 signatures, satoshis or complete input must be provided'
      )
    
      function GetPrevoutHash (tx) {
        var writer = new BufferWriter()
    
        _.each(tx.inputs, function (input) {
          writer.writeReverse(input.prevTxId)
          writer.writeUInt32LE(input.outputIndex)
        })
    
        var buf = writer.toBuffer()
        var ret = Hash.sha256sha256(buf)
        return ret
      }
    
      function GetSequenceHash (tx) {
        var writer = new BufferWriter()
    
        _.each(tx.inputs, function (input) {
          writer.writeUInt32LE(input.sequenceNumber)
        })
    
        var buf = writer.toBuffer()
        var ret = Hash.sha256sha256(buf)
        return ret
      }
    
      function GetOutputsHash (tx, n) {
        var writer = new BufferWriter()
    
        if (_.isUndefined(n)) {
          _.each(tx.outputs, function (output) {
            output.toBufferWriter(writer)
          })
        } else {
          tx.outputs[n].toBufferWriter(writer)
        }
    
        var buf = writer.toBuffer()
        var ret = Hash.sha256sha256(buf)
        return ret
      }
    
      var hashPrevouts = Buffer.alloc(32)
      var hashSequence = Buffer.alloc(32)
      var hashOutputs = Buffer.alloc(32)
    
      if (!(sighashType & Signature.SIGHASH_ANYONECANPAY)) {
        hashPrevouts = GetPrevoutHash(transaction)
      }
    
      if (!(sighashType & Signature.SIGHASH_ANYONECANPAY) &&
        (sighashType & 31) !== Signature.SIGHASH_SINGLE &&
        (sighashType & 31) !== Signature.SIGHASH_NONE) {
        hashSequence = GetSequenceHash(transaction)
      }
    
      if ((sighashType & 31) !== Signature.SIGHASH_SINGLE && (sighashType & 31) !== Signature.SIGHASH_NONE) {
        hashOutputs = GetOutputsHash(transaction)
      } else if ((sighashType & 31) === Signature.SIGHASH_SINGLE && inputNumber < transaction.outputs.length) {
        hashOutputs = GetOutputsHash(transaction, inputNumber)
      }
    
      var writer = new BufferWriter()
      // Version
      writer.writeUInt32LE(transaction.version)
    
      // Input prevouts/nSequence (none/all, depending on flags)
      writer.write(hashPrevouts)
      writer.write(hashSequence)
    
      //  outpoint (32-byte hash + 4-byte little endian)
      writer.writeReverse(input.prevTxId)
      writer.writeUInt32LE(input.outputIndex)
    
      // scriptCode of the input (serialized as scripts inside CTxOuts)
      var subscriptBuffer = subscript.toBuffer()
      writer.writeVarintNum(subscriptBuffer.length)
      writer.write(subscriptBuffer)
    
      // value of the output spent by this input (8-byte little endian)
      writer.writeUInt64LEBN(satoshisBN)
    
      // nSequence of the input (4-byte little endian)
      var sequenceNumber = input.sequenceNumber
      writer.writeUInt32LE(sequenceNumber)
    
      // Outputs (none/one/all, depending on flags)
      writer.write(hashOutputs)
    
      // Locktime
      writer.writeUInt32LE(transaction.nLockTime)
    
      // sighashType
      writer.writeUInt32LE(sighashType >>> 0)
      var buf = writer.toBuffer()
      return buf
    }
    
    /**
     * Returns a buffer with the which is hashed with sighash that needs to be signed
     * for OP_CHECKSIG.
     *
     * @name Signing.sighash
     * @param {Transaction} transaction the transaction to sign
     * @param {number} sighashType the type of the hash
     * @param {number} inputNumber the input index for the signature
     * @param {Script} subscript the script that will be signed
     * @param {satoshisBN} input's amount (for  ForkId signatures)
     *
     */
    var sighashPreimage = function sighashPreimage (transaction, sighashType, inputNumber, subscript, satoshisBN, flags) {
      var Transaction = require('./transaction')
      var Input = require('./input')
    
      if (_.isUndefined(flags)) {
        flags = DEFAULT_SIGN_FLAGS
      }
    
      if (flags & Interpreter.SCRIPT_ENABLE_REPLAY_PROTECTION) {
        // Legacy chain's value for fork id must be of the form 0xffxxxx.
        // By xoring with 0xdead, we ensure that the value will be different
        // from the original one, even if it already starts with 0xff.
        var forkValue = sighashType >> 8
        var newForkValue = 0xff0000 | (forkValue ^ 0xdead)
        sighashType = (newForkValue << 8) | (sighashType & 0xff)
      }
    
      if ((sighashType & Signature.SIGHASH_FORKID) && (flags & Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID)) {
        return sighashPreimageForForkId(transaction, sighashType, inputNumber, subscript, satoshisBN)
      }
    
      // Copy transaction
      var txcopy = Transaction.shallowCopy(transaction)
    
      // Copy script
      subscript = new Script(subscript)
    
      // For no ForkId sighash, separators need to be removed.
      subscript.removeCodeseparators()
    
      var i
    
      for (i = 0; i < txcopy.inputs.length; i++) {
        // Blank signatures for other inputs
        txcopy.inputs[i] = new Input(txcopy.inputs[i]).setScript(Script.empty())
      }
    
      txcopy.inputs[inputNumber] = new Input(txcopy.inputs[inputNumber]).setScript(subscript)
    
      if ((sighashType & 31) === Signature.SIGHASH_NONE ||
        (sighashType & 31) === Signature.SIGHASH_SINGLE) {
        // clear all sequenceNumbers
        for (i = 0; i < txcopy.inputs.length; i++) {
          if (i !== inputNumber) {
            txcopy.inputs[i].sequenceNumber = 0
          }
        }
      }
    
      if ((sighashType & 31) === Signature.SIGHASH_NONE) {
        txcopy.outputs = []
      } else if ((sighashType & 31) === Signature.SIGHASH_SINGLE) {
        // The SIGHASH_SINGLE bug.
        // https://bitcointalk.org/index.php?topic=260595.0
        if (inputNumber >= txcopy.outputs.length) {
          return SIGHASH_SINGLE_BUG
        }
    
        txcopy.outputs.length = inputNumber + 1
    
        for (i = 0; i < inputNumber; i++) {
          txcopy.outputs[i] = new Output({
            satoshis: BN.fromBuffer(buffer.Buffer.from(BITS_64_ON, 'hex')),
            script: Script.empty()
          })
        }
      }
    
      if (sighashType & Signature.SIGHASH_ANYONECANPAY) {
        txcopy.inputs = [txcopy.inputs[inputNumber]]
      }
    
      var buf = new BufferWriter()
        .write(txcopy.toBuffer())
        .writeInt32LE(sighashType)
        .toBuffer()
      return buf
    }
    
    /**
     * Returns a buffer of length 32 bytes with the hash that needs to be signed
     * for OP_CHECKSIG.
     *
     * @name Signing.sighash
     * @param {Transaction} transaction the transaction to sign
     * @param {number} sighashType the type of the hash
     * @param {number} inputNumber the input index for the signature
     * @param {Script} subscript the script that will be signed
     * @param {satoshisBN} input's amount (for  ForkId signatures)
     *
     */
    var sighash = function sighash (transaction, sighashType, inputNumber, subscript, satoshisBN, flags) {
      var preimage = sighashPreimage(transaction, sighashType, inputNumber, subscript, satoshisBN, flags)
      if (preimage.compare(SIGHASH_SINGLE_BUG) === 0) return preimage
      var ret = Hash.sha256sha256(preimage)
      ret = new BufferReader(ret).readReverse()
      return ret
    }
    
    /**
     * Create a signature
     *
     * @name Signing.sign
     * @param {Transaction} transaction
     * @param {PrivateKey} privateKey
     * @param {number} sighash
     * @param {number} inputIndex
     * @param {Script} subscript
     * @param {satoshisBN} input's amount
     * @return {Signature}
     */
    function sign (transaction, privateKey, sighashType, inputIndex, subscript, satoshisBN, flags) {
      var hashbuf = sighash(transaction, sighashType, inputIndex, subscript, satoshisBN, flags)
    
      var sig = ECDSA.sign(hashbuf, privateKey, 'little').set({
        nhashtype: sighashType
      })
      return sig
    }
    
    /**
     * Verify a signature
     *
     * @name Signing.verify
     * @param {Transaction} transaction
     * @param {Signature} signature
     * @param {PublicKey} publicKey
     * @param {number} inputIndex
     * @param {Script} subscript
     * @param {satoshisBN} input's amount
     * @param {flags} verification flags
     * @return {boolean}
     */
    function verify (transaction, signature, publicKey, inputIndex, subscript, satoshisBN, flags) {
      $.checkArgument(!_.isUndefined(transaction))
      $.checkArgument(!_.isUndefined(signature) && !_.isUndefined(signature.nhashtype))
      var hashbuf = sighash(transaction, signature.nhashtype, inputIndex, subscript, satoshisBN, flags)
      return ECDSA.verify(hashbuf, signature, publicKey, 'little')
    }
    
    /**
     * @namespace Signing
     */
    module.exports = {
      sighashPreimage: sighashPreimage,
      sighash: sighash,
      sign: sign,
      verify: verify
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/bn":205,"../crypto/ecdsa":206,"../crypto/hash":208,"../crypto/signature":212,"../encoding/bufferreader":219,"../encoding/bufferwriter":220,"../script":248,"../script/interpreter":249,"../util/_":270,"../util/preconditions":272,"./input":259,"./output":265,"./transaction":268,"buffer":84}],267:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    var inherits = require('inherits')
    var JSUtil = require('../util/js')
    
    var PublicKey = require('../publickey')
    var errors = require('../errors')
    var Signature = require('../crypto/signature')
    
    /**
     * @desc
     * Wrapper around Signature with fields related to signing a transaction specifically
     *
     * @param {Object|string|TransactionSignature} arg
     * @constructor
     */
    function TransactionSignature (arg) {
      if (!(this instanceof TransactionSignature)) {
        return new TransactionSignature(arg)
      }
      if (arg instanceof TransactionSignature) {
        return arg
      }
      if (_.isObject(arg)) {
        return this._fromObject(arg)
      }
      throw new errors.InvalidArgument('TransactionSignatures must be instantiated from an object')
    }
    inherits(TransactionSignature, Signature)
    
    TransactionSignature.prototype._fromObject = function (arg) {
      this._checkObjectArgs(arg)
      this.publicKey = new PublicKey(arg.publicKey)
      this.prevTxId = Buffer.isBuffer(arg.prevTxId) ? arg.prevTxId : Buffer.from(arg.prevTxId, 'hex')
      this.outputIndex = arg.outputIndex
      this.inputIndex = arg.inputIndex
      this.signature = (arg.signature instanceof Signature) ? arg.signature
        : Buffer.isBuffer(arg.signature) ? Signature.fromBuffer(arg.signature)
          : Signature.fromString(arg.signature)
      this.sigtype = arg.sigtype
      return this
    }
    
    TransactionSignature.prototype._checkObjectArgs = function (arg) {
      $.checkArgument(PublicKey(arg.publicKey), 'publicKey')
      $.checkArgument(!_.isUndefined(arg.inputIndex), 'inputIndex')
      $.checkArgument(!_.isUndefined(arg.outputIndex), 'outputIndex')
      $.checkState(_.isNumber(arg.inputIndex), 'inputIndex must be a number')
      $.checkState(_.isNumber(arg.outputIndex), 'outputIndex must be a number')
      $.checkArgument(arg.signature, 'signature')
      $.checkArgument(arg.prevTxId, 'prevTxId')
      $.checkState(arg.signature instanceof Signature ||
                   Buffer.isBuffer(arg.signature) ||
                   JSUtil.isHexa(arg.signature), 'signature must be a buffer or hexa value')
      $.checkState(Buffer.isBuffer(arg.prevTxId) ||
                   JSUtil.isHexa(arg.prevTxId), 'prevTxId must be a buffer or hexa value')
      $.checkArgument(arg.sigtype, 'sigtype')
      $.checkState(_.isNumber(arg.sigtype), 'sigtype must be a number')
    }
    
    /**
     * Serializes a transaction to a plain JS object
     * @return {Object}
     */
    TransactionSignature.prototype.toObject = TransactionSignature.prototype.toJSON = function toObject () {
      return {
        publicKey: this.publicKey.toString(),
        prevTxId: this.prevTxId.toString('hex'),
        outputIndex: this.outputIndex,
        inputIndex: this.inputIndex,
        signature: this.signature.toString(),
        sigtype: this.sigtype
      }
    }
    
    /**
     * Builds a TransactionSignature from an object
     * @param {Object} object
     * @return {TransactionSignature}
     */
    TransactionSignature.fromObject = function (object) {
      $.checkArgument(object)
      return new TransactionSignature(object)
    }
    
    module.exports = TransactionSignature
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../crypto/signature":212,"../errors":227,"../publickey":247,"../util/_":270,"../util/js":271,"../util/preconditions":272,"buffer":84,"inherits":276}],268:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    var buffer = require('buffer')
    
    var errors = require('../errors')
    var JSUtil = require('../util/js')
    var BufferReader = require('../encoding/bufferreader')
    var BufferWriter = require('../encoding/bufferwriter')
    var Varint = require('../encoding/varint')
    var Hash = require('../crypto/hash')
    var Signature = require('../crypto/signature')
    var Sighash = require('./sighash')
    
    var Address = require('../address')
    var UnspentOutput = require('./unspentoutput')
    var Input = require('./input')
    var PublicKeyHashInput = Input.PublicKeyHash
    var PublicKeyInput = Input.PublicKey
    var MultiSigScriptHashInput = Input.MultiSigScriptHash
    var MultiSigInput = Input.MultiSig
    var Output = require('./output')
    var Script = require('../script')
    var PrivateKey = require('../privatekey')
    var BN = require('../crypto/bn')
    
    /**
     * Represents a transaction, a set of inputs and outputs to change ownership of tokens
     *
     * @param {*} serialized
     * @constructor
     */
    function Transaction(serialized) {
      if (!(this instanceof Transaction)) {
        return new Transaction(serialized)
      }
      this.inputs = []
      this.outputs = []
      this._inputAmount = undefined
      this._outputAmount = undefined
      this.unlockScriptCallbackMap = new Map()
      this.outputCallbackMap = new Map()
      this._privateKey = undefined
      this._sigType = undefined
      this.isSeal = false
      if (serialized) {
        if (serialized instanceof Transaction) {
          return Transaction.shallowCopy(serialized)
        } else if (JSUtil.isHexa(serialized)) {
          this.fromString(serialized)
        } else if (Buffer.isBuffer(serialized)) {
          this.fromBuffer(serialized)
        } else if (_.isObject(serialized)) {
          this.fromObject(serialized)
        } else {
          throw new errors.InvalidArgument('Must provide an object or string to deserialize a transaction')
        }
      } else {
        this._newTransaction()
      }
    }
    
    var CURRENT_VERSION = 1
    var DEFAULT_NLOCKTIME = 0
    var MAX_BLOCK_SIZE = 1000000
    
    // Minimum amount for an output for it not to be considered a dust output
    Transaction.DUST_AMOUNT = 546
    
    // Margin of error to allow fees in the vecinity of the expected value but doesn't allow a big difference
    Transaction.FEE_SECURITY_MARGIN = 150
    
    // max amount of satoshis in circulation
    Transaction.MAX_MONEY = 21000000 * 1e8
    
    // nlocktime limit to be considered block height rather than a timestamp
    Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT = 5e8
    
    // Max value for an unsigned 32 bit value
    Transaction.NLOCKTIME_MAX_VALUE = 4294967295
    
    // Value used for fee estimation (satoshis per kilobyte)
    Transaction.FEE_PER_KB = 500
    
    // Safe upper bound for change address script size in bytes
    Transaction.CHANGE_OUTPUT_MAX_SIZE = 20 + 4 + 34 + 4
    
    /* Constructors and Serialization */
    
    /**
     * Create a 'shallow' copy of the transaction, by serializing and deserializing
     * it dropping any additional information that inputs and outputs may have hold
     *
     * @param {Transaction} transaction
     * @return {Transaction}
     */
    Transaction.shallowCopy = function (transaction) {
      var copy = new Transaction(transaction.toBuffer())
      return copy
    }
    
    var hashProperty = {
      configurable: false,
      enumerable: true,
      get: function () {
        this._hash = new BufferReader(this._getHash()).readReverse().toString('hex')
        return this._hash
      },
    }
    Object.defineProperty(Transaction.prototype, 'hash', hashProperty)
    Object.defineProperty(Transaction.prototype, 'id', hashProperty)
    
    var ioProperty = {
      configurable: false,
      enumerable: true,
      get: function () {
        return this._getInputAmount()
      },
    }
    Object.defineProperty(Transaction.prototype, 'inputAmount', ioProperty)
    ioProperty.get = function () {
      return this._getOutputAmount()
    }
    Object.defineProperty(Transaction.prototype, 'outputAmount', ioProperty)
    
    /**
     * Retrieve the little endian hash of the transaction (used for serialization)
     * @return {Buffer}
     */
    Transaction.prototype._getHash = function () {
      if (this.version >= 10) {
        return Hash.sha256sha256(this.newTxHeader().toBuffer())
      }
      return Hash.sha256sha256(this.toBuffer())
    }
    
    /**
     * Retrieve a hexa string that can be used with bitcoind's CLI interface
     * (decoderawtransaction, sendrawtransaction)
     *
     * @param {Object|boolean=} unsafe if true, skip all tests. if it's an object,
     *   it's expected to contain a set of flags to skip certain tests:
     * * `disableAll`: disable all checks
     * * `disableLargeFees`: disable checking for fees that are too large
     * * `disableIsFullySigned`: disable checking if all inputs are fully signed
     * * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts
     * * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts
     * @return {string}
     */
    Transaction.prototype.serialize = function (unsafe) {
      if (unsafe === true || (unsafe && unsafe.disableAll)) {
        return this.uncheckedSerialize()
      } else {
        return this.checkedSerialize(unsafe)
      }
    }
    
    Transaction.prototype.uncheckedSerialize = Transaction.prototype.toString = function () {
      return this.toBuffer().toString('hex')
    }
    
    /**
     * Retrieve a hexa string that can be used with bitcoind's CLI interface
     * (decoderawtransaction, sendrawtransaction)
     *
     * @param {Object} opts allows to skip certain tests. {@see Transaction#serialize}
     * @return {string}
     */
    Transaction.prototype.checkedSerialize = function (opts) {
      var serializationError = this.getSerializationError(opts)
      if (serializationError) {
        serializationError.message +=
          ' - For more information please see: ' + 'https://bsv.io/api/lib/transaction#serialization-checks'
        throw serializationError
      }
      return this.uncheckedSerialize()
    }
    
    Transaction.prototype.invalidSatoshis = function () {
      var invalid = false
      for (var i = 0; i < this.outputs.length; i++) {
        if (this.outputs[i].invalidSatoshis()) {
          invalid = true
        }
      }
      return invalid
    }
    
    /**
     * Retrieve a possible error that could appear when trying to serialize and
     * broadcast this transaction.
     *
     * @param {Object} opts allows to skip certain tests. {@see Transaction#serialize}
     * @return {bsv.Error}
     */
    Transaction.prototype.getSerializationError = function (opts) {
      opts = opts || {}
    
      if (this.invalidSatoshis()) {
        return new errors.Transaction.InvalidSatoshis()
      }
    
      var unspent = this._getUnspentValue()
      var unspentError
      if (unspent < 0) {
        if (!opts.disableMoreOutputThanInput) {
          unspentError = new errors.Transaction.InvalidOutputAmountSum()
        }
      } else {
        unspentError = this._hasFeeError(opts, unspent)
      }
    
      return unspentError || this._hasDustOutputs(opts) || this._isMissingSignatures(opts)
    }
    
    Transaction.prototype._hasFeeError = function (opts, unspent) {
      if (!_.isUndefined(this._fee) && this._fee !== unspent) {
        return new errors.Transaction.FeeError.Different(
          'Unspent value is ' + unspent + ' but specified fee is ' + this._fee,
        )
      }
    
      if (!opts.disableLargeFees) {
        var maximumFee = Math.floor(Transaction.FEE_SECURITY_MARGIN * this._estimateFee())
        if (unspent > maximumFee) {
          if (this._missingChange()) {
            return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided')
          }
          return new errors.Transaction.FeeError.TooLarge('expected less than ' + maximumFee + ' but got ' + unspent)
        }
      }
    }
    
    Transaction.prototype._missingChange = function () {
      return !this._changeScript
    }
    
    Transaction.prototype._hasDustOutputs = function (opts) {
      if (opts.disableDustOutputs) {
        return
      }
      var index, output
      for (index in this.outputs) {
        output = this.outputs[index]
        if (output.satoshis < Transaction.DUST_AMOUNT && !output.script.isDataOut() && !output.script.isSafeDataOut()) {
          return new errors.Transaction.DustOutputs()
        }
      }
    }
    
    Transaction.prototype._isMissingSignatures = function (opts) {
      if (opts.disableIsFullySigned) {
        return
      }
      if (!this.isFullySigned()) {
        return new errors.Transaction.MissingSignatures()
      }
    }
    
    Transaction.prototype.inspect = function () {
      return '<Transaction: ' + this.uncheckedSerialize() + '>'
    }
    
    Transaction.prototype.toBuffer = function () {
      var writer = new BufferWriter()
      return this.toBufferWriter(writer).toBuffer()
    }
    
    Transaction.prototype.toBufferWriter = function (writer) {
      writer.writeInt32LE(this.version)
      writer.writeVarintNum(this.inputs.length)
      _.each(this.inputs, function (input) {
        input.toBufferWriter(writer)
      })
      writer.writeVarintNum(this.outputs.length)
      _.each(this.outputs, function (output) {
        output.toBufferWriter(writer)
      })
      writer.writeUInt32LE(this.nLockTime)
      return writer
    }
    
    Transaction.prototype.newTxHeader = function () {
      var writer = new BufferWriter()
      writer.writeUInt32LE(this.version)
      writer.writeUInt32LE(this.nLockTime)
      writer.writeInt32LE(this.inputs.length)
      writer.writeInt32LE(this.outputs.length)
    
      const inputWriter = new BufferWriter()
      const inputWriter2 = new BufferWriter()
      for (const input of this.inputs) {
        inputWriter.writeReverse(input.prevTxId)
        inputWriter.writeUInt32LE(input.outputIndex)
        inputWriter.writeUInt32LE(input.sequenceNumber)
    
        inputWriter2.write(Hash.sha256(input.script.toBuffer()))
      }
      writer.write(Hash.sha256(inputWriter.toBuffer()))
      writer.write(Hash.sha256(inputWriter2.toBuffer()))
    
      const outputWriter = new BufferWriter()
      for (const output of this.outputs) {
        outputWriter.writeUInt64LEBN(output.satoshisBN)
        outputWriter.write(Hash.sha256(output.script.toBuffer()))
      }
      writer.write(Hash.sha256(outputWriter.toBuffer()))
      return writer
    }
    
    Transaction.prototype.fromBuffer = function (buffer) {
      var reader = new BufferReader(buffer)
      return this.fromBufferReader(reader)
    }
    
    Transaction.prototype.fromBufferReader = function (reader) {
      $.checkArgument(!reader.finished(), 'No transaction data received')
      var i, sizeTxIns, sizeTxOuts
    
      this.version = reader.readInt32LE()
      sizeTxIns = reader.readVarintNum()
      for (i = 0; i < sizeTxIns; i++) {
        var input = Input.fromBufferReader(reader)
        this.inputs.push(input)
      }
      sizeTxOuts = reader.readVarintNum()
      for (i = 0; i < sizeTxOuts; i++) {
        this.outputs.push(Output.fromBufferReader(reader))
      }
      this.nLockTime = reader.readUInt32LE()
      return this
    }
    
    Transaction.prototype.toObject = Transaction.prototype.toJSON = function toObject() {
      var inputs = []
      this.inputs.forEach(function (input) {
        inputs.push(input.toObject())
      })
      var outputs = []
      this.outputs.forEach(function (output) {
        outputs.push(output.toObject())
      })
      var obj = {
        hash: this.hash,
        version: this.version,
        inputs: inputs,
        outputs: outputs,
        nLockTime: this.nLockTime,
      }
      if (this._changeScript) {
        obj.changeScript = this._changeScript.toString()
      }
      if (!_.isUndefined(this._changeIndex)) {
        obj.changeIndex = this._changeIndex
      }
      if (!_.isUndefined(this._fee)) {
        obj.fee = this._fee
      }
      return obj
    }
    
    Transaction.prototype.fromObject = function fromObject(arg) {
      $.checkArgument(_.isObject(arg) || arg instanceof Transaction)
      var self = this
      var transaction
      if (arg instanceof Transaction) {
        transaction = transaction.toObject()
      } else {
        transaction = arg
      }
      _.each(transaction.inputs, function (input) {
        if (!input.output || !input.output.script) {
          self.uncheckedAddInput(new Input(input))
          return
        }
        var script = new Script(input.output.script)
        var txin
        if (script.isPublicKeyHashOut()) {
          txin = new Input.PublicKeyHash(input)
        } else if (script.isScriptHashOut() && input.publicKeys && input.threshold) {
          txin = new Input.MultiSigScriptHash(input, input.publicKeys, input.threshold, input.signatures)
        } else if (script.isPublicKeyOut()) {
          txin = new Input.PublicKey(input)
        } else {
          throw new errors.Transaction.Input.UnsupportedScript(input.output.script)
        }
        self.addInput(txin)
      })
      _.each(transaction.outputs, function (output) {
        self.addOutput(new Output(output))
      })
      if (transaction.changeIndex) {
        this._changeIndex = transaction.changeIndex
      }
      if (transaction.changeScript) {
        this._changeScript = new Script(transaction.changeScript)
      }
      if (transaction.fee) {
        this._fee = transaction.fee
      }
      this.nLockTime = transaction.nLockTime
      this.version = transaction.version
      this._checkConsistency(arg)
      return this
    }
    
    Transaction.prototype._checkConsistency = function (arg) {
      if (!_.isUndefined(this._changeIndex)) {
        $.checkState(this._changeScript, 'Change script is expected.')
        $.checkState(this.outputs[this._changeIndex], 'Change index points to undefined output.')
        $.checkState(
          this.outputs[this._changeIndex].script.toString() === this._changeScript.toString(),
          'Change output has an unexpected script.',
        )
      }
      if (arg && arg.hash) {
        $.checkState(arg.hash === this.hash, 'Hash in object does not match transaction hash.')
      }
    }
    
    /**
     * Sets nLockTime so that transaction is not valid until the desired date(a
     * timestamp in seconds since UNIX epoch is also accepted)
     *
     * @param {Date | Number} time
     * @return {Transaction} this
     */
    Transaction.prototype.lockUntilDate = function (time) {
      $.checkArgument(time)
      if (_.isNumber(time) && time < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) {
        throw new errors.Transaction.LockTimeTooEarly()
      }
      if (_.isDate(time)) {
        time = time.getTime() / 1000
      }
    
      for (var i = 0; i < this.inputs.length; i++) {
        if (this.inputs[i].sequenceNumber === Input.DEFAULT_SEQNUMBER) {
          this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER
        }
      }
    
      this.nLockTime = time
      return this
    }
    
    /**
     * Sets nLockTime so that transaction is not valid until the desired block
     * height.
     *
     * @param {Number} height
     * @return {Transaction} this
     */
    Transaction.prototype.lockUntilBlockHeight = function (height) {
      $.checkArgument(_.isNumber(height))
      if (height >= Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) {
        throw new errors.Transaction.BlockHeightTooHigh()
      }
      if (height < 0) {
        throw new errors.Transaction.NLockTimeOutOfRange()
      }
    
      for (var i = 0; i < this.inputs.length; i++) {
        if (this.inputs[i].sequenceNumber === Input.DEFAULT_SEQNUMBER) {
          this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER
        }
      }
    
      this.nLockTime = height
      return this
    }
    
    /**
     *  Returns a semantic version of the transaction's nLockTime.
     *  @return {Number|Date}
     *  If nLockTime is 0, it returns null,
     *  if it is < 500000000, it returns a block height (number)
     *  else it returns a Date object.
     */
    Transaction.prototype.getLockTime = function () {
      if (!this.nLockTime) {
        return null
      }
      if (this.nLockTime < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) {
        return this.nLockTime
      }
      return new Date(1000 * this.nLockTime)
    }
    
    Transaction.prototype.fromString = function (string) {
      this.fromBuffer(buffer.Buffer.from(string, 'hex'))
    }
    
    Transaction.prototype._newTransaction = function () {
      this.version = CURRENT_VERSION
      this.nLockTime = DEFAULT_NLOCKTIME
    }
    
    /* Transaction creation interface */
    
    /**
     * @typedef {Object} Transaction~fromObject
     * @property {string} prevTxId
     * @property {number} outputIndex
     * @property {(Buffer|string|Script)} script
     * @property {number} satoshis
     */
    
    /**
     * Add an input to this transaction. This is a high level interface
     * to add an input, for more control, use @{link Transaction#addInput}.
     *
     * Can receive, as output information, the output of bitcoind's `listunspent` command,
     * and a slightly fancier format recognized by bsv:
     *
     * ```
     * {
     *  address: 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1',
     *  txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
     *  outputIndex: 0,
     *  script: Script.empty(),
     *  satoshis: 1020000
     * }
     * ```
     * Where `address` can be either a string or a bsv Address object. The
     * same is true for `script`, which can be a string or a bsv Script.
     *
     * Beware that this resets all the signatures for inputs (in further versions,
     * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).
     *
     * @example
     * ```javascript
     * var transaction = new Transaction();
     *
     * // From a pay to public key hash output from bitcoind's listunspent
     * transaction.from({'txid': '0000...', vout: 0, amount: 0.1, scriptPubKey: 'OP_DUP ...'});
     *
     * // From a pay to public key hash output
     * transaction.from({'txId': '0000...', outputIndex: 0, satoshis: 1000, script: 'OP_DUP ...'});
     *
     * // From a multisig P2SH output
     * transaction.from({'txId': '0000...', inputIndex: 0, satoshis: 1000, script: '... OP_HASH'},
     *                  ['03000...', '02000...'], 2);
     * ```
     *
     * @param {(Array.<Transaction~fromObject>|Transaction~fromObject)} utxo
     * @param {Array=} pubkeys
     * @param {number=} threshold
     */
    Transaction.prototype.from = function (utxo, pubkeys, threshold) {
      if (_.isArray(utxo)) {
        var self = this
        _.each(utxo, function (utxo) {
          self.from(utxo, pubkeys, threshold)
        })
        return this
      }
      var exists = _.some(this.inputs, function (input) {
        // TODO: Maybe prevTxId should be a string? Or defined as read only property?
        return input.prevTxId.toString('hex') === utxo.txId && input.outputIndex === utxo.outputIndex
      })
      if (exists) {
        return this
      }
      if (pubkeys && threshold) {
        this._fromMultisigUtxo(utxo, pubkeys, threshold)
      } else {
        this._fromNonP2SH(utxo)
      }
      return this
    }
    
    Transaction.prototype._fromNonP2SH = function (utxo) {
      var Clazz
      utxo = new UnspentOutput(utxo)
      if (utxo.script.isPublicKeyHashOut()) {
        Clazz = PublicKeyHashInput
      } else if (utxo.script.isPublicKeyOut()) {
        Clazz = PublicKeyInput
      } else {
        Clazz = Input
      }
      this.addInput(
        new Clazz({
          output: new Output({
            script: utxo.script,
            satoshis: utxo.satoshis,
          }),
          prevTxId: utxo.txId,
          outputIndex: utxo.outputIndex,
          script: Script.empty(),
        }),
      )
    }
    
    Transaction.prototype._fromMultisigUtxo = function (utxo, pubkeys, threshold) {
      $.checkArgument(
        threshold <= pubkeys.length,
        'Number of required signatures must be greater than the number of public keys',
      )
      var Clazz
      utxo = new UnspentOutput(utxo)
      if (utxo.script.isMultisigOut()) {
        Clazz = MultiSigInput
      } else if (utxo.script.isScriptHashOut()) {
        Clazz = MultiSigScriptHashInput
      } else {
        throw new Error('@TODO')
      }
      this.addInput(
        new Clazz(
          {
            output: new Output({
              script: utxo.script,
              satoshis: utxo.satoshis,
            }),
            prevTxId: utxo.txId,
            outputIndex: utxo.outputIndex,
            script: Script.empty(),
          },
          pubkeys,
          threshold,
        ),
      )
    }
    
    /**
     * Add an input to this transaction. The input must be an instance of the `Input` class.
     * It should have information about the Output that it's spending, but if it's not already
     * set, two additional parameters, `outputScript` and `satoshis` can be provided.
     *
     * @param {Input} input
     * @param {String|Script} outputScript
     * @param {number} satoshis
     * @return Transaction this, for chaining
     */
    Transaction.prototype.addInput = function (input, outputScript, satoshis) {
      $.checkArgumentType(input, Input, 'input')
      if (!input.output && (_.isUndefined(outputScript) || _.isUndefined(satoshis))) {
        throw new errors.Transaction.NeedMoreInfo('Need information about the UTXO script and satoshis')
      }
      if (!input.output && outputScript && !_.isUndefined(satoshis)) {
        outputScript = outputScript instanceof Script ? outputScript : new Script(outputScript)
        $.checkArgumentType(satoshis, 'number', 'satoshis')
        input.output = new Output({
          script: outputScript,
          satoshis: satoshis,
        })
      }
      return this.uncheckedAddInput(input)
    }
    
    /**
     * Add an input to this transaction, without checking that the input has information about
     * the output that it's spending.
     *
     * @param {Input} input
     * @return Transaction this, for chaining
     */
    Transaction.prototype.uncheckedAddInput = function (input) {
      $.checkArgumentType(input, Input, 'input')
      this.inputs.push(input)
      this._inputAmount = undefined
      this._updateChangeOutput()
      return this
    }
    
    /**
     * Returns true if the transaction has enough info on all inputs to be correctly validated
     *
     * @return {boolean}
     */
    Transaction.prototype.hasAllUtxoInfo = function () {
      return _.every(
        this.inputs.map(function (input) {
          return !!input.output
        }),
      )
    }
    
    /**
     * Manually set the fee for this transaction. Beware that this resets all the signatures
     * for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not
     * be reset).
     *
     * @param {number} amount satoshis to be sent
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.fee = function (amount) {
      $.checkArgument(_.isNumber(amount), 'amount must be a number')
      this._fee = amount
      this._updateChangeOutput()
      return this
    }
    
    /**
     * Manually set the fee per KB for this transaction. Beware that this resets all the signatures
     * for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not
     * be reset).
     *
     * @param {number} amount satoshis per KB to be sent
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.feePerKb = function (amount) {
      $.checkArgument(_.isNumber(amount), 'amount must be a number')
      this._feePerKb = amount
      this._updateChangeOutput()
      return this
    }
    
    /* Output management */
    
    /**
     * Set the change address for this transaction
     *
     * Beware that this resets all the signatures for inputs (in further versions,
     * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).
     *
     * @param {Address} address An address for change to be sent to.
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.change = function (address) {
      $.checkArgument(address, 'address is required')
      this._changeScript = Script.fromAddress(address)
      this._updateChangeOutput()
      return this
    }
    
    /**
     * @return {Output} change output, if it exists
     */
    Transaction.prototype.getChangeOutput = function () {
      if (!_.isUndefined(this._changeIndex)) {
        return this.outputs[this._changeIndex]
      }
      return null
    }
    
    /**
     * @typedef {Object} Transaction~toObject
     * @property {(string|Address)} address
     * @property {number} satoshis
     */
    
    /**
     * Add an output to the transaction.
     *
     * Beware that this resets all the signatures for inputs (in further versions,
     * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).
     *
     * @param {(string|Address|Array.<Transaction~toObject>)} address
     * @param {number} amount in satoshis
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.to = function (address, amount) {
      if (_.isArray(address)) {
        var self = this
        _.each(address, function (to) {
          self.to(to.address, to.satoshis)
        })
        return this
      }
    
      $.checkArgument(JSUtil.isNaturalNumber(amount), 'Amount is expected to be a positive integer')
      this.addOutput(
        new Output({
          script: Script(new Address(address)),
          satoshis: amount,
        }),
      )
      return this
    }
    
    /**
     * Add an OP_RETURN output to the transaction.
     *
     * Beware that this resets all the signatures for inputs (in further versions,
     * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).
     *
     * @param {Buffer|string} value the data to be stored in the OP_RETURN output.
     *    In case of a string, the UTF-8 representation will be stored
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.addData = function (value) {
      this.addOutput(
        new Output({
          script: Script.buildDataOut(value),
          satoshis: 0,
        }),
      )
      return this
    }
    
    /**
     * Add an OP_FALSE | OP_RETURN output to the transaction.
     *
     * Beware that this resets all the signatures for inputs (in further versions,
     * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset).
     *
     * @param {Buffer|string} value the data to be stored in the OP_RETURN output.
     *    In case of a string, the UTF-8 representation will be stored
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.addSafeData = function (value) {
      this.addOutput(
        new Output({
          script: Script.buildSafeDataOut(value),
          satoshis: 0,
        }),
      )
      return this
    }
    
    /**
     * Add an output to the transaction.
     *
     * @param {Output} output the output to add.
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.addOutput = function (output) {
      $.checkArgumentType(output, Output, 'output')
      this._addOutput(output)
      this._updateChangeOutput()
      return this
    }
    
    /**
     * Remove all outputs from the transaction.
     *
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.clearOutputs = function () {
      this.outputs = []
      this._clearSignatures()
      this._outputAmount = undefined
      this._changeIndex = undefined
      this._updateChangeOutput()
      return this
    }
    
    Transaction.prototype._addOutput = function (output) {
      this.outputs.push(output)
      this._outputAmount = undefined
    }
    
    /**
     * Calculates or gets the total output amount in satoshis
     *
     * @return {Number} the transaction total output amount
     */
    Transaction.prototype._getOutputAmount = function () {
      if (_.isUndefined(this._outputAmount)) {
        var self = this
        this._outputAmount = 0
        _.each(this.outputs, function (output) {
          self._outputAmount += output.satoshis
        })
      }
      return this._outputAmount
    }
    
    /**
     * Calculates or gets the total input amount in satoshis
     *
     * @return {Number} the transaction total input amount
     */
    Transaction.prototype._getInputAmount = function () {
      if (_.isUndefined(this._inputAmount)) {
        var self = this
        this._inputAmount = 0
        _.each(this.inputs, function (input) {
          if (_.isUndefined(input.output)) {
            throw new errors.Transaction.Input.MissingPreviousOutput()
          }
          self._inputAmount += input.output.satoshis
        })
      }
      return this._inputAmount
    }
    
    Transaction.prototype._updateChangeOutput = function () {
      if (this.isSeal) {
        throw new errors.Transaction.TransactionAlreadySealed()
      }
    
      if (!this._changeScript) {
        return
      }
      this._clearSignatures()
      if (!_.isUndefined(this._changeIndex)) {
        this._removeOutput(this._changeIndex)
      }
      this._changeIndex = this.outputs.length
      this._addOutput(
        new Output({
          script: this._changeScript,
          satoshis: 0,
        }),
      )
      var available = this._getUnspentValue()
      var fee = this.getFee()
      var changeAmount = available - fee
      this._removeOutput(this._changeIndex)
      this._changeIndex = undefined
      if (changeAmount >= Transaction.DUST_AMOUNT) {
        this._changeIndex = this.outputs.length
        this._addOutput(
          new Output({
            script: this._changeScript,
            satoshis: changeAmount,
          }),
        )
      }
    }
    /**
     * Calculates the fee of the transaction.
     *
     * If there's a fixed fee set, return that.
     *
     * If there is no change output set, the fee is the
     * total value of the outputs minus inputs. Note that
     * a serialized transaction only specifies the value
     * of its outputs. (The value of inputs are recorded
     * in the previous transaction outputs being spent.)
     * This method therefore raises a "MissingPreviousOutput"
     * error when called on a serialized transaction.
     *
     * If there's no fee set and no change address,
     * estimate the fee based on size.
     *
     * @return {Number} fee of this transaction in satoshis
     */
    Transaction.prototype.getFee = function () {
      if (this.isCoinbase()) {
        return 0
      }
      if (!_.isUndefined(this._fee)) {
        return this._fee
      }
      // if no change output is set, fees should equal all the unspent amount
      if (!this._changeScript) {
        return this._getUnspentValue()
      }
      return this._estimateFee()
    }
    
    /**
     * Estimates fee from serialized transaction size in bytes.
     */
    Transaction.prototype._estimateFee = function () {
      var estimatedSize = this._estimateSize()
      return Math.ceil((estimatedSize / 1000) * (this._feePerKb || Transaction.FEE_PER_KB))
    }
    
    Transaction.prototype._getUnspentValue = function () {
      return this._getInputAmount() - this._getOutputAmount()
    }
    
    Transaction.prototype._clearSignatures = function () {
      _.each(this.inputs, function (input) {
        input.clearSignatures()
      })
    }
    
    // 4    version
    // ???  num inputs (VARINT)
    // --- input list ---
    //
    // ???  num outputs (VARINT)
    // --- output list ---
    //      8       value
    //      ???     script size (VARINT)
    //      ???     script
    //
    // 4    locktime
    Transaction.prototype._estimateSize = function () {
      var result = 4 + 4 // size of version + size of locktime
      result += Varint(this.inputs.length).toBuffer().length
      result += Varint(this.outputs.length).toBuffer().length
      _.each(this.inputs, function (input) {
        result += input._estimateSize()
      })
      _.each(this.outputs, function (output) {
        result += output.getSize()
      })
      return result
    }
    
    Transaction.prototype._removeOutput = function (index) {
      var output = this.outputs[index]
      this.outputs = _.without(this.outputs, output)
      this._outputAmount = undefined
    }
    
    Transaction.prototype.removeOutput = function (index) {
      this._removeOutput(index)
      this._updateChangeOutput()
    }
    
    /**
     * Sort a transaction's inputs and outputs according to BIP69
     *
     * @see {https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki}
     * @return {Transaction} this
     */
    Transaction.prototype.sort = function () {
      this.sortInputs(function (inputs) {
        var copy = Array.prototype.concat.apply([], inputs)
        copy.sort(function (first, second) {
          return first.prevTxId.compare(second.prevTxId) || first.outputIndex - second.outputIndex
        })
        return copy
      })
      this.sortOutputs(function (outputs) {
        var copy = Array.prototype.concat.apply([], outputs)
        copy.sort(function (first, second) {
          return first.satoshis - second.satoshis || first.script.toBuffer().compare(second.script.toBuffer())
        })
        return copy
      })
      return this
    }
    
    /**
     * Randomize this transaction's outputs ordering. The shuffling algorithm is a
     * version of the Fisher-Yates shuffle.
     *
     * @return {Transaction} this
     */
    Transaction.prototype.shuffleOutputs = function () {
      return this.sortOutputs(_.shuffle)
    }
    
    /**
     * Sort this transaction's outputs, according to a given sorting function that
     * takes an array as argument and returns a new array, with the same elements
     * but with a different order. The argument function MUST NOT modify the order
     * of the original array
     *
     * @param {Function} sortingFunction
     * @return {Transaction} this
     */
    Transaction.prototype.sortOutputs = function (sortingFunction) {
      var outs = sortingFunction(this.outputs)
      return this._newOutputOrder(outs)
    }
    
    /**
     * Sort this transaction's inputs, according to a given sorting function that
     * takes an array as argument and returns a new array, with the same elements
     * but with a different order.
     *
     * @param {Function} sortingFunction
     * @return {Transaction} this
     */
    Transaction.prototype.sortInputs = function (sortingFunction) {
      this.inputs = sortingFunction(this.inputs)
      this._clearSignatures()
      return this
    }
    
    Transaction.prototype._newOutputOrder = function (newOutputs) {
      var isInvalidSorting =
        this.outputs.length !== newOutputs.length || _.difference(this.outputs, newOutputs).length !== 0
      if (isInvalidSorting) {
        throw new errors.Transaction.InvalidSorting()
      }
    
      if (!_.isUndefined(this._changeIndex)) {
        var changeOutput = this.outputs[this._changeIndex]
        this._changeIndex = newOutputs.indexOf(changeOutput)
      }
    
      this.outputs = newOutputs
      return this
    }
    
    Transaction.prototype.removeInput = function (txId, outputIndex) {
      var index
      if (!outputIndex && _.isNumber(txId)) {
        index = txId
      } else {
        index = _.findIndex(this.inputs, function (input) {
          return input.prevTxId.toString('hex') === txId && input.outputIndex === outputIndex
        })
      }
      if (index < 0 || index >= this.inputs.length) {
        throw new errors.Transaction.InvalidIndex(index, this.inputs.length)
      }
      var input = this.inputs[index]
      this.inputs = _.without(this.inputs, input)
      this._inputAmount = undefined
      this._updateChangeOutput()
    }
    
    /* Signature handling */
    
    /**
     * Sign the transaction using one or more private keys.
     *
     * It tries to sign each input, verifying that the signature will be valid
     * (matches a public key).
     *
     * @param {Array|String|PrivateKey} privateKey
     * @param {number} sigtype
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.sign = function (privateKey, sigtype) {
      $.checkState(this.hasAllUtxoInfo(), 'Not all utxo information is available to sign the transaction.')
      var self = this
      if (_.isArray(privateKey)) {
        _.each(privateKey, function (privateKey) {
          self.sign(privateKey, sigtype)
        })
        return this
      }
      _.each(this.getSignatures(privateKey, sigtype), function (signature) {
        self.applySignature(signature)
      })
    
      this._privateKey = privateKey
      this._sigType = sigtype
      return this
    }
    
    Transaction.prototype.getSignatures = function (privKey, sigtype) {
      privKey = new PrivateKey(privKey)
      // By default, signs using ALL|FORKID
      sigtype = sigtype || Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID
      var transaction = this
      var results = []
      var hashData = Hash.sha256ripemd160(privKey.publicKey.toBuffer())
      _.each(this.inputs, function forEachInput(input, index) {
        _.each(input.getSignatures(transaction, privKey, index, sigtype, hashData), function (signature) {
          results.push(signature)
        })
      })
      return results
    }
    
    /**
     * Add a signature to the transaction
     *
     * @param {Object} signature
     * @param {number} signature.inputIndex
     * @param {number} signature.sigtype
     * @param {PublicKey} signature.publicKey
     * @param {Signature} signature.signature
     * @return {Transaction} this, for chaining
     */
    Transaction.prototype.applySignature = function (signature) {
      this.inputs[signature.inputIndex].addSignature(this, signature)
      return this
    }
    
    Transaction.prototype.isFullySigned = function () {
      _.each(this.inputs, function (input) {
        if (input.isFullySigned === Input.prototype.isFullySigned) {
          throw new errors.Transaction.UnableToVerifySignature(
            'Unrecognized script kind, or not enough information to execute script.' +
              'This usually happens when creating a transaction from a serialized transaction',
          )
        }
      })
      return _.every(
        _.map(this.inputs, function (input) {
          return input.isFullySigned()
        }),
      )
    }
    
    Transaction.prototype.isValidSignature = function (signature) {
      var self = this
      if (this.inputs[signature.inputIndex].isValidSignature === Input.prototype.isValidSignature) {
        throw new errors.Transaction.UnableToVerifySignature(
          'Unrecognized script kind, or not enough information to execute script.' +
            'This usually happens when creating a transaction from a serialized transaction',
        )
      }
      return this.inputs[signature.inputIndex].isValidSignature(self, signature)
    }
    
    /**
     * @returns {bool} whether the signature is valid for this transaction input
     */
    Transaction.prototype.verifySignature = function (sig, pubkey, nin, subscript, satoshisBN, flags) {
      return Sighash.verify(this, sig, pubkey, nin, subscript, satoshisBN, flags)
    }
    
    /**
     * Check that a transaction passes basic sanity tests. If not, return a string
     * describing the error. This function contains the same logic as
     * CheckTransaction in bitcoin core.
     */
    Transaction.prototype.verify = function () {
      // Basic checks that don't depend on any context
      if (this.inputs.length === 0) {
        return 'transaction txins empty'
      }
    
      if (this.outputs.length === 0) {
        return 'transaction txouts empty'
      }
    
      // Check for negative or overflow output values
      var valueoutbn = new BN(0)
      for (var i = 0; i < this.outputs.length; i++) {
        var txout = this.outputs[i]
    
        if (txout.invalidSatoshis()) {
          return 'transaction txout ' + i + ' satoshis is invalid'
        }
        if (txout._satoshisBN.gt(new BN(Transaction.MAX_MONEY, 10))) {
          return 'transaction txout ' + i + ' greater than MAX_MONEY'
        }
        valueoutbn = valueoutbn.add(txout._satoshisBN)
        if (valueoutbn.gt(new BN(Transaction.MAX_MONEY))) {
          return 'transaction txout ' + i + ' total output greater than MAX_MONEY'
        }
      }
    
      // Size limits
      if (this.toBuffer().length > MAX_BLOCK_SIZE) {
        return 'transaction over the maximum block size'
      }
    
      // Check for duplicate inputs
      var txinmap = {}
      for (i = 0; i < this.inputs.length; i++) {
        var txin = this.inputs[i]
    
        var inputid = txin.prevTxId + ':' + txin.outputIndex
        if (!_.isUndefined(txinmap[inputid])) {
          return 'transaction input ' + i + ' duplicate input'
        }
        txinmap[inputid] = true
      }
    
      var isCoinbase = this.isCoinbase()
      if (isCoinbase) {
        var buf = this.inputs[0]._scriptBuffer
        if (buf.length < 2 || buf.length > 100) {
          return 'coinbase transaction script size invalid'
        }
      } else {
        for (i = 0; i < this.inputs.length; i++) {
          if (this.inputs[i].isNull()) {
            return 'transaction input ' + i + ' has null input'
          }
        }
      }
      return true
    }
    
    /**
     * Analogous to bitcoind's IsCoinBase function in transaction.h
     */
    Transaction.prototype.isCoinbase = function () {
      return this.inputs.length === 1 && this.inputs[0].isNull()
    }
    
    /**
     *
     * @param {number} inputIndex
     * @param {Script|(tx, output) => Script} unlockScriptOrCallback  unlockScript or a callback returns unlockScript
     * @returns unlockScript of the special input
     */
    Transaction.prototype.setInputScript = function (inputIndex, unlockScriptOrCallback) {
      if (unlockScriptOrCallback instanceof Function) {
        this.unlockScriptCallbackMap.set(inputIndex, unlockScriptOrCallback)
        this.inputs[inputIndex].setScript(unlockScriptOrCallback(this, this.inputs[inputIndex].output))
      } else {
        this.inputs[inputIndex].setScript(unlockScriptOrCallback)
      }
    
      this._updateChangeOutput()
      return this
    }
    
    Transaction.prototype.setInputSequence = function (inputIndex, sequence) {
      this.inputs[inputIndex].sequenceNumber = sequence
      return this
    }
    
    /**
     *
     * @param {number} outputIndex
     * @param {Output|(tx) => Output} outputOrcb  output or a callback returns output
     * @returns output
     */
    Transaction.prototype.setOutput = function (outputIndex, outputOrcb) {
      if (outputOrcb instanceof Function) {
        this.outputCallbackMap.set(outputIndex, outputOrcb)
        this.outputs[outputIndex] = outputOrcb(this)
      } else {
        this.outputs[outputIndex] = outputOrcb
      }
    
      this._updateChangeOutput()
      return this
    }
    
    /**
     * Seal a transaction. After the transaction is sealed, except for the unlock script entered,
     * other attributes of the transaction cannot be modified
     */
    Transaction.prototype.seal = function () {
      const self = this
    
      this.outputCallbackMap.forEach(function (outputCallback, key) {
        self.outputs[key] = outputCallback(self)
      })
    
      this.unlockScriptCallbackMap.forEach(function (unlockScriptCallback, key) {
        self.inputs[key].setScript(unlockScriptCallback(self, self.inputs[key].output))
      })
    
      if (this._privateKey) {
        this.sign(this._privateKey, this._sigType)
      }
    
      this.isSeal = true
    
      return this
    }
    
    Transaction.prototype.setLockTime = function (nLockTime) {
      this.nLockTime = nLockTime
      return this
    }
    
    /**
     *
     * @returns satoshis of change output
     */
    Transaction.prototype.getChangeAmount = function () {
      if (_.isUndefined(this._changeIndex)) {
        return 0
      }
    
      return this.outputs[this._changeIndex].satoshis
    }
    
    /**
     *
     * @returns estimate fee by transaction size
     */
    Transaction.prototype.getEstimateFee = function () {
      return this._estimateFee()
    }
    
    /**
     *
     * @param {number} feePerKb the fee per KB for this transaction
     * @returns true or false
     */
    Transaction.prototype.checkFeeRate = function (feePerKb) {
      const fee = this._getUnspentValue()
    
      var estimatedSize = this._estimateSize()
      var expectedFee = Math.ceil((estimatedSize / 1000) * (feePerKb || this._feePerKb || Transaction.FEE_PER_KB))
    
      return fee >= expectedFee
    }
    
    /**
     *
     * @returns the serialization of all input outpoints
     */
    Transaction.prototype.prevouts = function () {
      var writer = new BufferWriter()
    
      _.each(this.inputs, function (input) {
        writer.writeReverse(input.prevTxId)
        writer.writeUInt32LE(input.outputIndex)
      })
    
      var buf = writer.toBuffer()
      return buf.toString('hex')
    }
    
    module.exports = Transaction
    
    }).call(this)}).call(this,{"isBuffer":require("../../../is-buffer/index.js")})
    
    },{"../../../is-buffer/index.js":184,"../address":200,"../crypto/bn":205,"../crypto/hash":208,"../crypto/signature":212,"../encoding/bufferreader":219,"../encoding/bufferwriter":220,"../encoding/varint":226,"../errors":227,"../privatekey":246,"../script":248,"../util/_":270,"../util/js":271,"../util/preconditions":272,"./input":259,"./output":265,"./sighash":266,"./unspentoutput":269,"buffer":84}],269:[function(require,module,exports){
    'use strict'
    
    var _ = require('../util/_')
    var $ = require('../util/preconditions')
    var JSUtil = require('../util/js')
    
    var Script = require('../script')
    var Address = require('../address')
    
    /**
     * Represents an unspent output information: its script, associated amount and address,
     * transaction id and output index.
     *
     * @constructor
     * @param {object} data
     * @param {string} data.txid the previous transaction id
     * @param {string=} data.txId alias for `txid`
     * @param {number} data.vout the index in the transaction
     * @param {number=} data.outputIndex alias for `vout`
     * @param {string|Script} data.scriptPubKey the script that must be resolved to release the funds
     * @param {string|Script=} data.script alias for `scriptPubKey`
     * @param {number} data.amount amount of bitcoins associated
     * @param {number=} data.satoshis alias for `amount`, but expressed in satoshis (1 BSV = 1e8 satoshis)
     * @param {string|Address=} data.address the associated address to the script, if provided
     */
    function UnspentOutput (data) {
      if (!(this instanceof UnspentOutput)) {
        return new UnspentOutput(data)
      }
      $.checkArgument(_.isObject(data), 'Must provide an object from where to extract data')
      var address = data.address ? new Address(data.address) : undefined
      var txId = data.txid ? data.txid : data.txId
      if (!txId || !JSUtil.isHexaString(txId) || txId.length > 64) {
        // TODO: Use the errors library
        throw new Error('Invalid TXID in object', data)
      }
      var outputIndex = _.isUndefined(data.vout) ? data.outputIndex : data.vout
      if (!_.isNumber(outputIndex)) {
        throw new Error('Invalid outputIndex, received ' + outputIndex)
      }
      $.checkArgument(!_.isUndefined(data.scriptPubKey) || !_.isUndefined(data.script),
        'Must provide the scriptPubKey for that output!')
      var script = new Script(data.scriptPubKey || data.script)
      $.checkArgument(!_.isUndefined(data.amount) || !_.isUndefined(data.satoshis),
        'Must provide an amount for the output')
      var amount = !_.isUndefined(data.amount) ? Math.round(data.amount * 1e8) : data.satoshis
      $.checkArgument(_.isNumber(amount), 'Amount must be a number')
      JSUtil.defineImmutable(this, {
        address: address,
        txId: txId,
        outputIndex: outputIndex,
        script: script,
        satoshis: amount
      })
    }
    
    /**
     * Provide an informative output when displaying this object in the console
     * @returns string
     */
    UnspentOutput.prototype.inspect = function () {
      return '<UnspentOutput: ' + this.txId + ':' + this.outputIndex +
             ', satoshis: ' + this.satoshis + ', address: ' + this.address + '>'
    }
    
    /**
     * String representation: just "txid:index"
     * @returns string
     */
    UnspentOutput.prototype.toString = function () {
      return this.txId + ':' + this.outputIndex
    }
    
    /**
     * Deserialize an UnspentOutput from an object
     * @param {object|string} data
     * @return UnspentOutput
     */
    UnspentOutput.fromObject = function (data) {
      return new UnspentOutput(data)
    }
    
    /**
     * Returns a plain object (no prototype or methods) with the associated info for this output
     * @return {object}
     */
    UnspentOutput.prototype.toObject = UnspentOutput.prototype.toJSON = function toObject () {
      return {
        address: this.address ? this.address.toString() : undefined,
        txid: this.txId,
        vout: this.outputIndex,
        scriptPubKey: this.script.toBuffer().toString('hex'),
        amount: Number.parseFloat((this.satoshis / 1e8).toFixed(8))
      }
    }
    
    module.exports = UnspentOutput
    
    },{"../address":200,"../script":248,"../util/_":270,"../util/js":271,"../util/preconditions":272}],270:[function(require,module,exports){
    'use strict'
    
    var _ = {}
    
    _.isArray = t => Array.isArray(t)
    _.isNumber = t => typeof t === 'number'
    _.isObject = t => t && typeof t === 'object'
    _.isString = t => typeof t === 'string'
    _.isUndefined = t => typeof t === 'undefined'
    _.isFunction = t => typeof t === 'function'
    _.isNull = t => t === null
    _.isDate = t => t instanceof Date
    _.extend = (a, b) => Object.assign(a, b)
    _.noop = () => { }
    _.every = (a, f) => a.every(f || (t => t))
    _.map = (a, f) => Array.from(a).map(f || (t => t))
    _.includes = (a, e) => a.includes(e)
    _.each = (a, f) => a.forEach(f)
    _.clone = o => Object.assign({}, o)
    _.pick = (object, keys) => {
      const obj = {}
      keys.forEach(key => {
        if (typeof object[key] !== 'undefined') { obj[key] = object[key] }
      })
      return obj
    }
    _.values = o => Object.values(o)
    _.filter = (a, f) => a.filter(f)
    _.reduce = (a, f, s) => a.reduce(f, s)
    _.without = (a, n) => a.filter(t => t !== n)
    _.shuffle = a => {
      const result = a.slice(0)
      for (let i = result.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [result[i], result[j]] = [result[j], result[i]]
      }
      return result
    }
    _.difference = (a, b) => a.filter(t => !b.includes(t))
    _.findIndex = (a, f) => a.findIndex(f)
    _.some = (a, f) => a.some(f)
    _.range = n => [...Array(n).keys()]
    
    module.exports = _
    
    },{}],271:[function(require,module,exports){
    (function (Buffer){(function (){
    'use strict'
    
    var _ = require('../util/_')
    var $ = require('./preconditions')
    
    /**
     * Determines whether a string contains only hexadecimal values
     *
     * @name JSUtil.isHexa
     * @param {string} value
     * @return {boolean} true if the string is the hexa representation of a number
     */
    var isHexa = function isHexa (value) {
      if (!_.isString(value)) {
        return false
      }
      return /^[0-9a-fA-F]+$/.test(value)
    }
    
    /**
     * @namespace JSUtil
     */
    module.exports = {
      /**
       * Test if an argument is a valid JSON object. If it is, returns a truthy
       * value (the json object decoded), so no double JSON.parse call is necessary
       *
       * @param {string} arg
       * @return {Object|boolean} false if the argument is not a JSON string.
       */
      isValidJSON: function isValidJSON (arg) {
        var parsed
        if (!_.isString(arg)) {
          return false
        }
        try {
          parsed = JSON.parse(arg)
        } catch (e) {
          return false
        }
        if (typeof (parsed) === 'object') {
          return true
        }
        return false
      },
      isHexa: isHexa,
      isHexaString: isHexa,
    
      /**
       * Define immutable properties on a target object
       *
       * @param {Object} target - An object to be extended
       * @param {Object} values - An object of properties
       * @return {Object} The target object
       */
      defineImmutable: function defineImmutable (target, values) {
        Object.keys(values).forEach(function (key) {
          Object.defineProperty(target, key, {
            configurable: false,
            enumerable: true,
            value: values[key]
          })
        })
        return target
      },
      /**
       * Checks that a value is a natural number, a positive integer or zero.
       *
       * @param {*} value
       * @return {Boolean}
       */
      isNaturalNumber: function isNaturalNumber (value) {
        return typeof value === 'number' &&
          isFinite(value) &&
          Math.floor(value) === value &&
          value >= 0
      },
    
      /**
       * Transform a 4-byte integer (unsigned value) into a Buffer of length 4 (Big Endian Byte Order)
       *
       * @param {number} integer
       * @return {Buffer}
       */
      integerAsBuffer: function integerAsBuffer (integer) {
        $.checkArgumentType(integer, 'number', 'integer')
        const buf = Buffer.allocUnsafe(4)
        buf.writeUInt32BE(integer, 0)
        return buf
      }
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../util/_":270,"./preconditions":272,"buffer":84}],272:[function(require,module,exports){
    'use strict'
    
    var errors = require('../errors')
    var _ = require('../util/_')
    
    module.exports = {
      checkState: function (condition, message) {
        if (!condition) {
          throw new errors.InvalidState(message)
        }
      },
      checkArgument: function (condition, argumentName, message, docsPath) {
        if (!condition) {
          throw new errors.InvalidArgument(argumentName, message, docsPath)
        }
      },
      checkArgumentType: function (argument, type, argumentName) {
        argumentName = argumentName || '(unknown name)'
        if (_.isString(type)) {
          if (type === 'Buffer') {
            var buffer = require('buffer') // './buffer' fails on cordova & RN
            if (!buffer.Buffer.isBuffer(argument)) {
              throw new errors.InvalidArgumentType(argument, type, argumentName)
            }
          } else if (typeof argument !== type) { // eslint-disable-line
            throw new errors.InvalidArgumentType(argument, type, argumentName)
          }
        } else {
          if (!(argument instanceof type)) {
            throw new errors.InvalidArgumentType(argument, type.name, argumentName)
          }
        }
      }
    }
    
    },{"../errors":227,"../util/_":270,"buffer":84}],273:[function(require,module,exports){
    module.exports = require('../lib/message')
    
    },{"../lib/message":231}],274:[function(require,module,exports){
    module.exports = require('../lib/mnemonic')
    
    },{"../lib/mnemonic":234}],275:[function(require,module,exports){
    (function (module, exports) {
      'use strict';
    
      // Utils
      function assert (val, msg) {
        if (!val) throw new Error(msg || 'Assertion failed');
      }
    
      // Could use `inherits` module, but don't want to move from single file
      // architecture yet.
      function inherits (ctor, superCtor) {
        ctor.super_ = superCtor;
        var TempCtor = function () {};
        TempCtor.prototype = superCtor.prototype;
        ctor.prototype = new TempCtor();
        ctor.prototype.constructor = ctor;
      }
    
      // BN
    
      function BN (number, base, endian) {
        if (BN.isBN(number)) {
          return number;
        }
    
        this.negative = 0;
        this.words = null;
        this.length = 0;
    
        // Reduction context
        this.red = null;
    
        if (number !== null) {
          if (base === 'le' || base === 'be') {
            endian = base;
            base = 10;
          }
    
          this._init(number || 0, base || 10, endian || 'be');
        }
      }
      if (typeof module === 'object') {
        module.exports = BN;
      } else {
        exports.BN = BN;
      }
    
      BN.BN = BN;
      BN.wordSize = 26;
    
      var Buffer;
      try {
        Buffer = require('buffer').Buffer;
      } catch (e) {
      }
    
      BN.isBN = function isBN (num) {
        if (num instanceof BN) {
          return true;
        }
    
        return num !== null && typeof num === 'object' &&
          num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
      };
    
      BN.max = function max (left, right) {
        if (left.cmp(right) > 0) return left;
        return right;
      };
    
      BN.min = function min (left, right) {
        if (left.cmp(right) < 0) return left;
        return right;
      };
    
      BN.prototype._init = function init (number, base, endian) {
        if (typeof number === 'number') {
          return this._initNumber(number, base, endian);
        }
    
        if (typeof number === 'object') {
          return this._initArray(number, base, endian);
        }
    
        if (base === 'hex') {
          base = 16;
        }
        assert(base === (base | 0) && base >= 2 && base <= 36);
    
        number = number.toString().replace(/\s+/g, '');
        var start = 0;
        if (number[0] === '-') {
          start++;
        }
    
        if (base === 16) {
          this._parseHex(number, start);
        } else {
          this._parseBase(number, base, start);
        }
    
        if (number[0] === '-') {
          this.negative = 1;
        }
    
        this.strip();
    
        if (endian !== 'le') return;
    
        this._initArray(this.toArray(), base, endian);
      };
    
      BN.prototype._initNumber = function _initNumber (number, base, endian) {
        if (number < 0) {
          this.negative = 1;
          number = -number;
        }
        if (number < 0x4000000) {
          this.words = [ number & 0x3ffffff ];
          this.length = 1;
        } else if (number < 0x10000000000000) {
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff
          ];
          this.length = 2;
        } else {
          assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
          this.words = [
            number & 0x3ffffff,
            (number / 0x4000000) & 0x3ffffff,
            1
          ];
          this.length = 3;
        }
    
        if (endian !== 'le') return;
    
        // Reverse the bytes
        this._initArray(this.toArray(), base, endian);
      };
    
      BN.prototype._initArray = function _initArray (number, base, endian) {
        // Perhaps a Uint8Array
        assert(typeof number.length === 'number');
        if (number.length <= 0) {
          this.words = [ 0 ];
          this.length = 1;
          return this;
        }
    
        this.length = Math.ceil(number.length / 3);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        var j, w;
        var off = 0;
        if (endian === 'be') {
          for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
            w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        } else if (endian === 'le') {
          for (i = 0, j = 0; i < number.length; i += 3) {
            w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
            this.words[j] |= (w << off) & 0x3ffffff;
            this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
            off += 24;
            if (off >= 26) {
              off -= 26;
              j++;
            }
          }
        }
        return this.strip();
      };
    
      function parseHex (str, start, end) {
        var r = 0;
        var len = Math.min(str.length, end);
        for (var i = start; i < len; i++) {
          var c = str.charCodeAt(i) - 48;
    
          r <<= 4;
    
          // 'a' - 'f'
          if (c >= 49 && c <= 54) {
            r |= c - 49 + 0xa;
    
          // 'A' - 'F'
          } else if (c >= 17 && c <= 22) {
            r |= c - 17 + 0xa;
    
          // '0' - '9'
          } else {
            r |= c & 0xf;
          }
        }
        return r;
      }
    
      BN.prototype._parseHex = function _parseHex (number, start) {
        // Create possibly bigger array to ensure that it fits the number
        this.length = Math.ceil((number.length - start) / 6);
        this.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          this.words[i] = 0;
        }
    
        var j, w;
        // Scan 24-bit chunks and add them to the number
        var off = 0;
        for (i = number.length - 6, j = 0; i >= start; i -= 6) {
          w = parseHex(number, i, i + 6);
          this.words[j] |= (w << off) & 0x3ffffff;
          // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
          this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
          off += 24;
          if (off >= 26) {
            off -= 26;
            j++;
          }
        }
        if (i + 6 !== start) {
          w = parseHex(number, start, i + 6);
          this.words[j] |= (w << off) & 0x3ffffff;
          this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
        }
        this.strip();
      };
    
      function parseBase (str, start, end, mul) {
        var r = 0;
        var len = Math.min(str.length, end);
        for (var i = start; i < len; i++) {
          var c = str.charCodeAt(i) - 48;
    
          r *= mul;
    
          // 'a'
          if (c >= 49) {
            r += c - 49 + 0xa;
    
          // 'A'
          } else if (c >= 17) {
            r += c - 17 + 0xa;
    
          // '0' - '9'
          } else {
            r += c;
          }
        }
        return r;
      }
    
      BN.prototype._parseBase = function _parseBase (number, base, start) {
        // Initialize as zero
        this.words = [ 0 ];
        this.length = 1;
    
        // Find length of limb in base
        for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
          limbLen++;
        }
        limbLen--;
        limbPow = (limbPow / base) | 0;
    
        var total = number.length - start;
        var mod = total % limbLen;
        var end = Math.min(total, total - mod) + start;
    
        var word = 0;
        for (var i = start; i < end; i += limbLen) {
          word = parseBase(number, i, i + limbLen, base);
    
          this.imuln(limbPow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
    
        if (mod !== 0) {
          var pow = 1;
          word = parseBase(number, i, number.length, base);
    
          for (i = 0; i < mod; i++) {
            pow *= base;
          }
    
          this.imuln(pow);
          if (this.words[0] + word < 0x4000000) {
            this.words[0] += word;
          } else {
            this._iaddn(word);
          }
        }
      };
    
      BN.prototype.copy = function copy (dest) {
        dest.words = new Array(this.length);
        for (var i = 0; i < this.length; i++) {
          dest.words[i] = this.words[i];
        }
        dest.length = this.length;
        dest.negative = this.negative;
        dest.red = this.red;
      };
    
      BN.prototype.clone = function clone () {
        var r = new BN(null);
        this.copy(r);
        return r;
      };
    
      BN.prototype._expand = function _expand (size) {
        while (this.length < size) {
          this.words[this.length++] = 0;
        }
        return this;
      };
    
      // Remove leading `0` from `this`
      BN.prototype.strip = function strip () {
        while (this.length > 1 && this.words[this.length - 1] === 0) {
          this.length--;
        }
        return this._normSign();
      };
    
      BN.prototype._normSign = function _normSign () {
        // -0 = 0
        if (this.length === 1 && this.words[0] === 0) {
          this.negative = 0;
        }
        return this;
      };
    
      BN.prototype.inspect = function inspect () {
        return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
      };
    
      /*
    
      var zeros = [];
      var groupSizes = [];
      var groupBases = [];
    
      var s = '';
      var i = -1;
      while (++i < BN.wordSize) {
        zeros[i] = s;
        s += '0';
      }
      groupSizes[0] = 0;
      groupSizes[1] = 0;
      groupBases[0] = 0;
      groupBases[1] = 0;
      var base = 2 - 1;
      while (++base < 36 + 1) {
        var groupSize = 0;
        var groupBase = 1;
        while (groupBase < (1 << BN.wordSize) / base) {
          groupBase *= base;
          groupSize += 1;
        }
        groupSizes[base] = groupSize;
        groupBases[base] = groupBase;
      }
    
      */
    
      var zeros = [
        '',
        '0',
        '00',
        '000',
        '0000',
        '00000',
        '000000',
        '0000000',
        '00000000',
        '000000000',
        '0000000000',
        '00000000000',
        '000000000000',
        '0000000000000',
        '00000000000000',
        '000000000000000',
        '0000000000000000',
        '00000000000000000',
        '000000000000000000',
        '0000000000000000000',
        '00000000000000000000',
        '000000000000000000000',
        '0000000000000000000000',
        '00000000000000000000000',
        '000000000000000000000000',
        '0000000000000000000000000'
      ];
    
      var groupSizes = [
        0, 0,
        25, 16, 12, 11, 10, 9, 8,
        8, 7, 7, 7, 7, 6, 6,
        6, 6, 6, 6, 6, 5, 5,
        5, 5, 5, 5, 5, 5, 5,
        5, 5, 5, 5, 5, 5, 5
      ];
    
      var groupBases = [
        0, 0,
        33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
        43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
        16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
        6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
        24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
      ];
    
      BN.prototype.toString = function toString (base, padding) {
        base = base || 10;
        padding = padding | 0 || 1;
    
        var out;
        if (base === 16 || base === 'hex') {
          out = '';
          var off = 0;
          var carry = 0;
          for (var i = 0; i < this.length; i++) {
            var w = this.words[i];
            var word = (((w << off) | carry) & 0xffffff).toString(16);
            carry = (w >>> (24 - off)) & 0xffffff;
            if (carry !== 0 || i !== this.length - 1) {
              out = zeros[6 - word.length] + word + out;
            } else {
              out = word + out;
            }
            off += 2;
            if (off >= 26) {
              off -= 26;
              i--;
            }
          }
          if (carry !== 0) {
            out = carry.toString(16) + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        if (base === (base | 0) && base >= 2 && base <= 36) {
          // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
          var groupSize = groupSizes[base];
          // var groupBase = Math.pow(base, groupSize);
          var groupBase = groupBases[base];
          out = '';
          var c = this.clone();
          c.negative = 0;
          while (!c.isZero()) {
            var r = c.modn(groupBase).toString(base);
            c = c.idivn(groupBase);
    
            if (!c.isZero()) {
              out = zeros[groupSize - r.length] + r + out;
            } else {
              out = r + out;
            }
          }
          if (this.isZero()) {
            out = '0' + out;
          }
          while (out.length % padding !== 0) {
            out = '0' + out;
          }
          if (this.negative !== 0) {
            out = '-' + out;
          }
          return out;
        }
    
        assert(false, 'Base should be between 2 and 36');
      };
    
      BN.prototype.toNumber = function toNumber () {
        var ret = this.words[0];
        if (this.length === 2) {
          ret += this.words[1] * 0x4000000;
        } else if (this.length === 3 && this.words[2] === 0x01) {
          // NOTE: at this stage it is known that the top bit is set
          ret += 0x10000000000000 + (this.words[1] * 0x4000000);
        } else if (this.length > 2) {
          assert(false, 'Number can only safely store up to 53 bits');
        }
        return (this.negative !== 0) ? -ret : ret;
      };
    
      BN.prototype.toJSON = function toJSON () {
        return this.toString(16);
      };
    
      BN.prototype.toBuffer = function toBuffer (endian, length) {
        assert(typeof Buffer !== 'undefined');
        return this.toArrayLike(Buffer, endian, length);
      };
    
      BN.prototype.toArray = function toArray (endian, length) {
        return this.toArrayLike(Array, endian, length);
      };
    
      BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
        var byteLength = this.byteLength();
        var reqLength = length || Math.max(1, byteLength);
        assert(byteLength <= reqLength, 'byte array longer than desired length');
        assert(reqLength > 0, 'Requested array length <= 0');
    
        this.strip();
        var littleEndian = endian === 'le';
        var res = new ArrayType(reqLength);
    
        var b, i;
        var q = this.clone();
        if (!littleEndian) {
          // Assume big-endian
          for (i = 0; i < reqLength - byteLength; i++) {
            res[i] = 0;
          }
    
          for (i = 0; !q.isZero(); i++) {
            b = q.andln(0xff);
            q.iushrn(8);
    
            res[reqLength - i - 1] = b;
          }
        } else {
          for (i = 0; !q.isZero(); i++) {
            b = q.andln(0xff);
            q.iushrn(8);
    
            res[i] = b;
          }
    
          for (; i < reqLength; i++) {
            res[i] = 0;
          }
        }
    
        return res;
      };
    
      if (Math.clz32) {
        BN.prototype._countBits = function _countBits (w) {
          return 32 - Math.clz32(w);
        };
      } else {
        BN.prototype._countBits = function _countBits (w) {
          var t = w;
          var r = 0;
          if (t >= 0x1000) {
            r += 13;
            t >>>= 13;
          }
          if (t >= 0x40) {
            r += 7;
            t >>>= 7;
          }
          if (t >= 0x8) {
            r += 4;
            t >>>= 4;
          }
          if (t >= 0x02) {
            r += 2;
            t >>>= 2;
          }
          return r + t;
        };
      }
    
      BN.prototype._zeroBits = function _zeroBits (w) {
        // Short-cut
        if (w === 0) return 26;
    
        var t = w;
        var r = 0;
        if ((t & 0x1fff) === 0) {
          r += 13;
          t >>>= 13;
        }
        if ((t & 0x7f) === 0) {
          r += 7;
          t >>>= 7;
        }
        if ((t & 0xf) === 0) {
          r += 4;
          t >>>= 4;
        }
        if ((t & 0x3) === 0) {
          r += 2;
          t >>>= 2;
        }
        if ((t & 0x1) === 0) {
          r++;
        }
        return r;
      };
    
      // Return number of used bits in a BN
      BN.prototype.bitLength = function bitLength () {
        var w = this.words[this.length - 1];
        var hi = this._countBits(w);
        return (this.length - 1) * 26 + hi;
      };
    
      function toBitArray (num) {
        var w = new Array(num.bitLength());
    
        for (var bit = 0; bit < w.length; bit++) {
          var off = (bit / 26) | 0;
          var wbit = bit % 26;
    
          w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
        }
    
        return w;
      }
    
      // Number of trailing zero bits
      BN.prototype.zeroBits = function zeroBits () {
        if (this.isZero()) return 0;
    
        var r = 0;
        for (var i = 0; i < this.length; i++) {
          var b = this._zeroBits(this.words[i]);
          r += b;
          if (b !== 26) break;
        }
        return r;
      };
    
      BN.prototype.byteLength = function byteLength () {
        return Math.ceil(this.bitLength() / 8);
      };
    
      BN.prototype.toTwos = function toTwos (width) {
        if (this.negative !== 0) {
          return this.abs().inotn(width).iaddn(1);
        }
        return this.clone();
      };
    
      BN.prototype.fromTwos = function fromTwos (width) {
        if (this.testn(width - 1)) {
          return this.notn(width).iaddn(1).ineg();
        }
        return this.clone();
      };
    
      BN.prototype.isNeg = function isNeg () {
        return this.negative !== 0;
      };
    
      // Return negative clone of `this`
      BN.prototype.neg = function neg () {
        return this.clone().ineg();
      };
    
      BN.prototype.ineg = function ineg () {
        if (!this.isZero()) {
          this.negative ^= 1;
        }
    
        return this;
      };
    
      // Or `num` with `this` in-place
      BN.prototype.iuor = function iuor (num) {
        while (this.length < num.length) {
          this.words[this.length++] = 0;
        }
    
        for (var i = 0; i < num.length; i++) {
          this.words[i] = this.words[i] | num.words[i];
        }
    
        return this.strip();
      };
    
      BN.prototype.ior = function ior (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuor(num);
      };
    
      // Or `num` with `this`
      BN.prototype.or = function or (num) {
        if (this.length > num.length) return this.clone().ior(num);
        return num.clone().ior(this);
      };
    
      BN.prototype.uor = function uor (num) {
        if (this.length > num.length) return this.clone().iuor(num);
        return num.clone().iuor(this);
      };
    
      // And `num` with `this` in-place
      BN.prototype.iuand = function iuand (num) {
        // b = min-length(num, this)
        var b;
        if (this.length > num.length) {
          b = num;
        } else {
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = this.words[i] & num.words[i];
        }
    
        this.length = b.length;
    
        return this.strip();
      };
    
      BN.prototype.iand = function iand (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuand(num);
      };
    
      // And `num` with `this`
      BN.prototype.and = function and (num) {
        if (this.length > num.length) return this.clone().iand(num);
        return num.clone().iand(this);
      };
    
      BN.prototype.uand = function uand (num) {
        if (this.length > num.length) return this.clone().iuand(num);
        return num.clone().iuand(this);
      };
    
      // Xor `num` with `this` in-place
      BN.prototype.iuxor = function iuxor (num) {
        // a.length > b.length
        var a;
        var b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        for (var i = 0; i < b.length; i++) {
          this.words[i] = a.words[i] ^ b.words[i];
        }
    
        if (this !== a) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = a.length;
    
        return this.strip();
      };
    
      BN.prototype.ixor = function ixor (num) {
        assert((this.negative | num.negative) === 0);
        return this.iuxor(num);
      };
    
      // Xor `num` with `this`
      BN.prototype.xor = function xor (num) {
        if (this.length > num.length) return this.clone().ixor(num);
        return num.clone().ixor(this);
      };
    
      BN.prototype.uxor = function uxor (num) {
        if (this.length > num.length) return this.clone().iuxor(num);
        return num.clone().iuxor(this);
      };
    
      // Not ``this`` with ``width`` bitwidth
      BN.prototype.inotn = function inotn (width) {
        assert(typeof width === 'number' && width >= 0);
    
        var bytesNeeded = Math.ceil(width / 26) | 0;
        var bitsLeft = width % 26;
    
        // Extend the buffer with leading zeroes
        this._expand(bytesNeeded);
    
        if (bitsLeft > 0) {
          bytesNeeded--;
        }
    
        // Handle complete words
        for (var i = 0; i < bytesNeeded; i++) {
          this.words[i] = ~this.words[i] & 0x3ffffff;
        }
    
        // Handle the residue
        if (bitsLeft > 0) {
          this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
        }
    
        // And remove leading zeroes
        return this.strip();
      };
    
      BN.prototype.notn = function notn (width) {
        return this.clone().inotn(width);
      };
    
      // Set `bit` of `this`
      BN.prototype.setn = function setn (bit, val) {
        assert(typeof bit === 'number' && bit >= 0);
    
        var off = (bit / 26) | 0;
        var wbit = bit % 26;
    
        this._expand(off + 1);
    
        if (val) {
          this.words[off] = this.words[off] | (1 << wbit);
        } else {
          this.words[off] = this.words[off] & ~(1 << wbit);
        }
    
        return this.strip();
      };
    
      // Add `num` to `this` in-place
      BN.prototype.iadd = function iadd (num) {
        var r;
    
        // negative + positive
        if (this.negative !== 0 && num.negative === 0) {
          this.negative = 0;
          r = this.isub(num);
          this.negative ^= 1;
          return this._normSign();
    
        // positive + negative
        } else if (this.negative === 0 && num.negative !== 0) {
          num.negative = 0;
          r = this.isub(num);
          num.negative = 1;
          return r._normSign();
        }
    
        // a.length > b.length
        var a, b;
        if (this.length > num.length) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          this.words[i] = r & 0x3ffffff;
          carry = r >>> 26;
        }
    
        this.length = a.length;
        if (carry !== 0) {
          this.words[this.length] = carry;
          this.length++;
        // Copy the rest of the words
        } else if (a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        return this;
      };
    
      // Add `num` to `this`
      BN.prototype.add = function add (num) {
        var res;
        if (num.negative !== 0 && this.negative === 0) {
          num.negative = 0;
          res = this.sub(num);
          num.negative ^= 1;
          return res;
        } else if (num.negative === 0 && this.negative !== 0) {
          this.negative = 0;
          res = num.sub(this);
          this.negative = 1;
          return res;
        }
    
        if (this.length > num.length) return this.clone().iadd(num);
    
        return num.clone().iadd(this);
      };
    
      // Subtract `num` from `this` in-place
      BN.prototype.isub = function isub (num) {
        // this - (-num) = this + num
        if (num.negative !== 0) {
          num.negative = 0;
          var r = this.iadd(num);
          num.negative = 1;
          return r._normSign();
    
        // -this - num = -(this + num)
        } else if (this.negative !== 0) {
          this.negative = 0;
          this.iadd(num);
          this.negative = 1;
          return this._normSign();
        }
    
        // At this point both numbers are positive
        var cmp = this.cmp(num);
    
        // Optimization - zeroify
        if (cmp === 0) {
          this.negative = 0;
          this.length = 1;
          this.words[0] = 0;
          return this;
        }
    
        // a > b
        var a, b;
        if (cmp > 0) {
          a = this;
          b = num;
        } else {
          a = num;
          b = this;
        }
    
        var carry = 0;
        for (var i = 0; i < b.length; i++) {
          r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
        for (; carry !== 0 && i < a.length; i++) {
          r = (a.words[i] | 0) + carry;
          carry = r >> 26;
          this.words[i] = r & 0x3ffffff;
        }
    
        // Copy rest of the words
        if (carry === 0 && i < a.length && a !== this) {
          for (; i < a.length; i++) {
            this.words[i] = a.words[i];
          }
        }
    
        this.length = Math.max(this.length, i);
    
        if (a !== this) {
          this.negative = 1;
        }
    
        return this.strip();
      };
    
      // Subtract `num` from `this`
      BN.prototype.sub = function sub (num) {
        return this.clone().isub(num);
      };
    
      function smallMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        var len = (self.length + num.length) | 0;
        out.length = len;
        len = (len - 1) | 0;
    
        // Peel one iteration (compiler can't do it, because of code complexity)
        var a = self.words[0] | 0;
        var b = num.words[0] | 0;
        var r = a * b;
    
        var lo = r & 0x3ffffff;
        var carry = (r / 0x4000000) | 0;
        out.words[0] = lo;
    
        for (var k = 1; k < len; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = carry >>> 26;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = (k - j) | 0;
            a = self.words[i] | 0;
            b = num.words[j] | 0;
            r = a * b + rword;
            ncarry += (r / 0x4000000) | 0;
            rword = r & 0x3ffffff;
          }
          out.words[k] = rword | 0;
          carry = ncarry | 0;
        }
        if (carry !== 0) {
          out.words[k] = carry | 0;
        } else {
          out.length--;
        }
    
        return out.strip();
      }
    
      // TODO(indutny): it may be reasonable to omit it for users who don't need
      // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
      // multiplication (like elliptic secp256k1).
      var comb10MulTo = function comb10MulTo (self, num, out) {
        var a = self.words;
        var b = num.words;
        var o = out.words;
        var c = 0;
        var lo;
        var mid;
        var hi;
        var a0 = a[0] | 0;
        var al0 = a0 & 0x1fff;
        var ah0 = a0 >>> 13;
        var a1 = a[1] | 0;
        var al1 = a1 & 0x1fff;
        var ah1 = a1 >>> 13;
        var a2 = a[2] | 0;
        var al2 = a2 & 0x1fff;
        var ah2 = a2 >>> 13;
        var a3 = a[3] | 0;
        var al3 = a3 & 0x1fff;
        var ah3 = a3 >>> 13;
        var a4 = a[4] | 0;
        var al4 = a4 & 0x1fff;
        var ah4 = a4 >>> 13;
        var a5 = a[5] | 0;
        var al5 = a5 & 0x1fff;
        var ah5 = a5 >>> 13;
        var a6 = a[6] | 0;
        var al6 = a6 & 0x1fff;
        var ah6 = a6 >>> 13;
        var a7 = a[7] | 0;
        var al7 = a7 & 0x1fff;
        var ah7 = a7 >>> 13;
        var a8 = a[8] | 0;
        var al8 = a8 & 0x1fff;
        var ah8 = a8 >>> 13;
        var a9 = a[9] | 0;
        var al9 = a9 & 0x1fff;
        var ah9 = a9 >>> 13;
        var b0 = b[0] | 0;
        var bl0 = b0 & 0x1fff;
        var bh0 = b0 >>> 13;
        var b1 = b[1] | 0;
        var bl1 = b1 & 0x1fff;
        var bh1 = b1 >>> 13;
        var b2 = b[2] | 0;
        var bl2 = b2 & 0x1fff;
        var bh2 = b2 >>> 13;
        var b3 = b[3] | 0;
        var bl3 = b3 & 0x1fff;
        var bh3 = b3 >>> 13;
        var b4 = b[4] | 0;
        var bl4 = b4 & 0x1fff;
        var bh4 = b4 >>> 13;
        var b5 = b[5] | 0;
        var bl5 = b5 & 0x1fff;
        var bh5 = b5 >>> 13;
        var b6 = b[6] | 0;
        var bl6 = b6 & 0x1fff;
        var bh6 = b6 >>> 13;
        var b7 = b[7] | 0;
        var bl7 = b7 & 0x1fff;
        var bh7 = b7 >>> 13;
        var b8 = b[8] | 0;
        var bl8 = b8 & 0x1fff;
        var bh8 = b8 >>> 13;
        var b9 = b[9] | 0;
        var bl9 = b9 & 0x1fff;
        var bh9 = b9 >>> 13;
    
        out.negative = self.negative ^ num.negative;
        out.length = 19;
        /* k = 0 */
        lo = Math.imul(al0, bl0);
        mid = Math.imul(al0, bh0);
        mid = (mid + Math.imul(ah0, bl0)) | 0;
        hi = Math.imul(ah0, bh0);
        var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
        w0 &= 0x3ffffff;
        /* k = 1 */
        lo = Math.imul(al1, bl0);
        mid = Math.imul(al1, bh0);
        mid = (mid + Math.imul(ah1, bl0)) | 0;
        hi = Math.imul(ah1, bh0);
        lo = (lo + Math.imul(al0, bl1)) | 0;
        mid = (mid + Math.imul(al0, bh1)) | 0;
        mid = (mid + Math.imul(ah0, bl1)) | 0;
        hi = (hi + Math.imul(ah0, bh1)) | 0;
        var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
        w1 &= 0x3ffffff;
        /* k = 2 */
        lo = Math.imul(al2, bl0);
        mid = Math.imul(al2, bh0);
        mid = (mid + Math.imul(ah2, bl0)) | 0;
        hi = Math.imul(ah2, bh0);
        lo = (lo + Math.imul(al1, bl1)) | 0;
        mid = (mid + Math.imul(al1, bh1)) | 0;
        mid = (mid + Math.imul(ah1, bl1)) | 0;
        hi = (hi + Math.imul(ah1, bh1)) | 0;
        lo = (lo + Math.imul(al0, bl2)) | 0;
        mid = (mid + Math.imul(al0, bh2)) | 0;
        mid = (mid + Math.imul(ah0, bl2)) | 0;
        hi = (hi + Math.imul(ah0, bh2)) | 0;
        var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
        w2 &= 0x3ffffff;
        /* k = 3 */
        lo = Math.imul(al3, bl0);
        mid = Math.imul(al3, bh0);
        mid = (mid + Math.imul(ah3, bl0)) | 0;
        hi = Math.imul(ah3, bh0);
        lo = (lo + Math.imul(al2, bl1)) | 0;
        mid = (mid + Math.imul(al2, bh1)) | 0;
        mid = (mid + Math.imul(ah2, bl1)) | 0;
        hi = (hi + Math.imul(ah2, bh1)) | 0;
        lo = (lo + Math.imul(al1, bl2)) | 0;
        mid = (mid + Math.imul(al1, bh2)) | 0;
        mid = (mid + Math.imul(ah1, bl2)) | 0;
        hi = (hi + Math.imul(ah1, bh2)) | 0;
        lo = (lo + Math.imul(al0, bl3)) | 0;
        mid = (mid + Math.imul(al0, bh3)) | 0;
        mid = (mid + Math.imul(ah0, bl3)) | 0;
        hi = (hi + Math.imul(ah0, bh3)) | 0;
        var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
        w3 &= 0x3ffffff;
        /* k = 4 */
        lo = Math.imul(al4, bl0);
        mid = Math.imul(al4, bh0);
        mid = (mid + Math.imul(ah4, bl0)) | 0;
        hi = Math.imul(ah4, bh0);
        lo = (lo + Math.imul(al3, bl1)) | 0;
        mid = (mid + Math.imul(al3, bh1)) | 0;
        mid = (mid + Math.imul(ah3, bl1)) | 0;
        hi = (hi + Math.imul(ah3, bh1)) | 0;
        lo = (lo + Math.imul(al2, bl2)) | 0;
        mid = (mid + Math.imul(al2, bh2)) | 0;
        mid = (mid + Math.imul(ah2, bl2)) | 0;
        hi = (hi + Math.imul(ah2, bh2)) | 0;
        lo = (lo + Math.imul(al1, bl3)) | 0;
        mid = (mid + Math.imul(al1, bh3)) | 0;
        mid = (mid + Math.imul(ah1, bl3)) | 0;
        hi = (hi + Math.imul(ah1, bh3)) | 0;
        lo = (lo + Math.imul(al0, bl4)) | 0;
        mid = (mid + Math.imul(al0, bh4)) | 0;
        mid = (mid + Math.imul(ah0, bl4)) | 0;
        hi = (hi + Math.imul(ah0, bh4)) | 0;
        var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
        w4 &= 0x3ffffff;
        /* k = 5 */
        lo = Math.imul(al5, bl0);
        mid = Math.imul(al5, bh0);
        mid = (mid + Math.imul(ah5, bl0)) | 0;
        hi = Math.imul(ah5, bh0);
        lo = (lo + Math.imul(al4, bl1)) | 0;
        mid = (mid + Math.imul(al4, bh1)) | 0;
        mid = (mid + Math.imul(ah4, bl1)) | 0;
        hi = (hi + Math.imul(ah4, bh1)) | 0;
        lo = (lo + Math.imul(al3, bl2)) | 0;
        mid = (mid + Math.imul(al3, bh2)) | 0;
        mid = (mid + Math.imul(ah3, bl2)) | 0;
        hi = (hi + Math.imul(ah3, bh2)) | 0;
        lo = (lo + Math.imul(al2, bl3)) | 0;
        mid = (mid + Math.imul(al2, bh3)) | 0;
        mid = (mid + Math.imul(ah2, bl3)) | 0;
        hi = (hi + Math.imul(ah2, bh3)) | 0;
        lo = (lo + Math.imul(al1, bl4)) | 0;
        mid = (mid + Math.imul(al1, bh4)) | 0;
        mid = (mid + Math.imul(ah1, bl4)) | 0;
        hi = (hi + Math.imul(ah1, bh4)) | 0;
        lo = (lo + Math.imul(al0, bl5)) | 0;
        mid = (mid + Math.imul(al0, bh5)) | 0;
        mid = (mid + Math.imul(ah0, bl5)) | 0;
        hi = (hi + Math.imul(ah0, bh5)) | 0;
        var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
        w5 &= 0x3ffffff;
        /* k = 6 */
        lo = Math.imul(al6, bl0);
        mid = Math.imul(al6, bh0);
        mid = (mid + Math.imul(ah6, bl0)) | 0;
        hi = Math.imul(ah6, bh0);
        lo = (lo + Math.imul(al5, bl1)) | 0;
        mid = (mid + Math.imul(al5, bh1)) | 0;
        mid = (mid + Math.imul(ah5, bl1)) | 0;
        hi = (hi + Math.imul(ah5, bh1)) | 0;
        lo = (lo + Math.imul(al4, bl2)) | 0;
        mid = (mid + Math.imul(al4, bh2)) | 0;
        mid = (mid + Math.imul(ah4, bl2)) | 0;
        hi = (hi + Math.imul(ah4, bh2)) | 0;
        lo = (lo + Math.imul(al3, bl3)) | 0;
        mid = (mid + Math.imul(al3, bh3)) | 0;
        mid = (mid + Math.imul(ah3, bl3)) | 0;
        hi = (hi + Math.imul(ah3, bh3)) | 0;
        lo = (lo + Math.imul(al2, bl4)) | 0;
        mid = (mid + Math.imul(al2, bh4)) | 0;
        mid = (mid + Math.imul(ah2, bl4)) | 0;
        hi = (hi + Math.imul(ah2, bh4)) | 0;
        lo = (lo + Math.imul(al1, bl5)) | 0;
        mid = (mid + Math.imul(al1, bh5)) | 0;
        mid = (mid + Math.imul(ah1, bl5)) | 0;
        hi = (hi + Math.imul(ah1, bh5)) | 0;
        lo = (lo + Math.imul(al0, bl6)) | 0;
        mid = (mid + Math.imul(al0, bh6)) | 0;
        mid = (mid + Math.imul(ah0, bl6)) | 0;
        hi = (hi + Math.imul(ah0, bh6)) | 0;
        var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
        w6 &= 0x3ffffff;
        /* k = 7 */
        lo = Math.imul(al7, bl0);
        mid = Math.imul(al7, bh0);
        mid = (mid + Math.imul(ah7, bl0)) | 0;
        hi = Math.imul(ah7, bh0);
        lo = (lo + Math.imul(al6, bl1)) | 0;
        mid = (mid + Math.imul(al6, bh1)) | 0;
        mid = (mid + Math.imul(ah6, bl1)) | 0;
        hi = (hi + Math.imul(ah6, bh1)) | 0;
        lo = (lo + Math.imul(al5, bl2)) | 0;
        mid = (mid + Math.imul(al5, bh2)) | 0;
        mid = (mid + Math.imul(ah5, bl2)) | 0;
        hi = (hi + Math.imul(ah5, bh2)) | 0;
        lo = (lo + Math.imul(al4, bl3)) | 0;
        mid = (mid + Math.imul(al4, bh3)) | 0;
        mid = (mid + Math.imul(ah4, bl3)) | 0;
        hi = (hi + Math.imul(ah4, bh3)) | 0;
        lo = (lo + Math.imul(al3, bl4)) | 0;
        mid = (mid + Math.imul(al3, bh4)) | 0;
        mid = (mid + Math.imul(ah3, bl4)) | 0;
        hi = (hi + Math.imul(ah3, bh4)) | 0;
        lo = (lo + Math.imul(al2, bl5)) | 0;
        mid = (mid + Math.imul(al2, bh5)) | 0;
        mid = (mid + Math.imul(ah2, bl5)) | 0;
        hi = (hi + Math.imul(ah2, bh5)) | 0;
        lo = (lo + Math.imul(al1, bl6)) | 0;
        mid = (mid + Math.imul(al1, bh6)) | 0;
        mid = (mid + Math.imul(ah1, bl6)) | 0;
        hi = (hi + Math.imul(ah1, bh6)) | 0;
        lo = (lo + Math.imul(al0, bl7)) | 0;
        mid = (mid + Math.imul(al0, bh7)) | 0;
        mid = (mid + Math.imul(ah0, bl7)) | 0;
        hi = (hi + Math.imul(ah0, bh7)) | 0;
        var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
        w7 &= 0x3ffffff;
        /* k = 8 */
        lo = Math.imul(al8, bl0);
        mid = Math.imul(al8, bh0);
        mid = (mid + Math.imul(ah8, bl0)) | 0;
        hi = Math.imul(ah8, bh0);
        lo = (lo + Math.imul(al7, bl1)) | 0;
        mid = (mid + Math.imul(al7, bh1)) | 0;
        mid = (mid + Math.imul(ah7, bl1)) | 0;
        hi = (hi + Math.imul(ah7, bh1)) | 0;
        lo = (lo + Math.imul(al6, bl2)) | 0;
        mid = (mid + Math.imul(al6, bh2)) | 0;
        mid = (mid + Math.imul(ah6, bl2)) | 0;
        hi = (hi + Math.imul(ah6, bh2)) | 0;
        lo = (lo + Math.imul(al5, bl3)) | 0;
        mid = (mid + Math.imul(al5, bh3)) | 0;
        mid = (mid + Math.imul(ah5, bl3)) | 0;
        hi = (hi + Math.imul(ah5, bh3)) | 0;
        lo = (lo + Math.imul(al4, bl4)) | 0;
        mid = (mid + Math.imul(al4, bh4)) | 0;
        mid = (mid + Math.imul(ah4, bl4)) | 0;
        hi = (hi + Math.imul(ah4, bh4)) | 0;
        lo = (lo + Math.imul(al3, bl5)) | 0;
        mid = (mid + Math.imul(al3, bh5)) | 0;
        mid = (mid + Math.imul(ah3, bl5)) | 0;
        hi = (hi + Math.imul(ah3, bh5)) | 0;
        lo = (lo + Math.imul(al2, bl6)) | 0;
        mid = (mid + Math.imul(al2, bh6)) | 0;
        mid = (mid + Math.imul(ah2, bl6)) | 0;
        hi = (hi + Math.imul(ah2, bh6)) | 0;
        lo = (lo + Math.imul(al1, bl7)) | 0;
        mid = (mid + Math.imul(al1, bh7)) | 0;
        mid = (mid + Math.imul(ah1, bl7)) | 0;
        hi = (hi + Math.imul(ah1, bh7)) | 0;
        lo = (lo + Math.imul(al0, bl8)) | 0;
        mid = (mid + Math.imul(al0, bh8)) | 0;
        mid = (mid + Math.imul(ah0, bl8)) | 0;
        hi = (hi + Math.imul(ah0, bh8)) | 0;
        var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
        w8 &= 0x3ffffff;
        /* k = 9 */
        lo = Math.imul(al9, bl0);
        mid = Math.imul(al9, bh0);
        mid = (mid + Math.imul(ah9, bl0)) | 0;
        hi = Math.imul(ah9, bh0);
        lo = (lo + Math.imul(al8, bl1)) | 0;
        mid = (mid + Math.imul(al8, bh1)) | 0;
        mid = (mid + Math.imul(ah8, bl1)) | 0;
        hi = (hi + Math.imul(ah8, bh1)) | 0;
        lo = (lo + Math.imul(al7, bl2)) | 0;
        mid = (mid + Math.imul(al7, bh2)) | 0;
        mid = (mid + Math.imul(ah7, bl2)) | 0;
        hi = (hi + Math.imul(ah7, bh2)) | 0;
        lo = (lo + Math.imul(al6, bl3)) | 0;
        mid = (mid + Math.imul(al6, bh3)) | 0;
        mid = (mid + Math.imul(ah6, bl3)) | 0;
        hi = (hi + Math.imul(ah6, bh3)) | 0;
        lo = (lo + Math.imul(al5, bl4)) | 0;
        mid = (mid + Math.imul(al5, bh4)) | 0;
        mid = (mid + Math.imul(ah5, bl4)) | 0;
        hi = (hi + Math.imul(ah5, bh4)) | 0;
        lo = (lo + Math.imul(al4, bl5)) | 0;
        mid = (mid + Math.imul(al4, bh5)) | 0;
        mid = (mid + Math.imul(ah4, bl5)) | 0;
        hi = (hi + Math.imul(ah4, bh5)) | 0;
        lo = (lo + Math.imul(al3, bl6)) | 0;
        mid = (mid + Math.imul(al3, bh6)) | 0;
        mid = (mid + Math.imul(ah3, bl6)) | 0;
        hi = (hi + Math.imul(ah3, bh6)) | 0;
        lo = (lo + Math.imul(al2, bl7)) | 0;
        mid = (mid + Math.imul(al2, bh7)) | 0;
        mid = (mid + Math.imul(ah2, bl7)) | 0;
        hi = (hi + Math.imul(ah2, bh7)) | 0;
        lo = (lo + Math.imul(al1, bl8)) | 0;
        mid = (mid + Math.imul(al1, bh8)) | 0;
        mid = (mid + Math.imul(ah1, bl8)) | 0;
        hi = (hi + Math.imul(ah1, bh8)) | 0;
        lo = (lo + Math.imul(al0, bl9)) | 0;
        mid = (mid + Math.imul(al0, bh9)) | 0;
        mid = (mid + Math.imul(ah0, bl9)) | 0;
        hi = (hi + Math.imul(ah0, bh9)) | 0;
        var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
        w9 &= 0x3ffffff;
        /* k = 10 */
        lo = Math.imul(al9, bl1);
        mid = Math.imul(al9, bh1);
        mid = (mid + Math.imul(ah9, bl1)) | 0;
        hi = Math.imul(ah9, bh1);
        lo = (lo + Math.imul(al8, bl2)) | 0;
        mid = (mid + Math.imul(al8, bh2)) | 0;
        mid = (mid + Math.imul(ah8, bl2)) | 0;
        hi = (hi + Math.imul(ah8, bh2)) | 0;
        lo = (lo + Math.imul(al7, bl3)) | 0;
        mid = (mid + Math.imul(al7, bh3)) | 0;
        mid = (mid + Math.imul(ah7, bl3)) | 0;
        hi = (hi + Math.imul(ah7, bh3)) | 0;
        lo = (lo + Math.imul(al6, bl4)) | 0;
        mid = (mid + Math.imul(al6, bh4)) | 0;
        mid = (mid + Math.imul(ah6, bl4)) | 0;
        hi = (hi + Math.imul(ah6, bh4)) | 0;
        lo = (lo + Math.imul(al5, bl5)) | 0;
        mid = (mid + Math.imul(al5, bh5)) | 0;
        mid = (mid + Math.imul(ah5, bl5)) | 0;
        hi = (hi + Math.imul(ah5, bh5)) | 0;
        lo = (lo + Math.imul(al4, bl6)) | 0;
        mid = (mid + Math.imul(al4, bh6)) | 0;
        mid = (mid + Math.imul(ah4, bl6)) | 0;
        hi = (hi + Math.imul(ah4, bh6)) | 0;
        lo = (lo + Math.imul(al3, bl7)) | 0;
        mid = (mid + Math.imul(al3, bh7)) | 0;
        mid = (mid + Math.imul(ah3, bl7)) | 0;
        hi = (hi + Math.imul(ah3, bh7)) | 0;
        lo = (lo + Math.imul(al2, bl8)) | 0;
        mid = (mid + Math.imul(al2, bh8)) | 0;
        mid = (mid + Math.imul(ah2, bl8)) | 0;
        hi = (hi + Math.imul(ah2, bh8)) | 0;
        lo = (lo + Math.imul(al1, bl9)) | 0;
        mid = (mid + Math.imul(al1, bh9)) | 0;
        mid = (mid + Math.imul(ah1, bl9)) | 0;
        hi = (hi + Math.imul(ah1, bh9)) | 0;
        var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
        w10 &= 0x3ffffff;
        /* k = 11 */
        lo = Math.imul(al9, bl2);
        mid = Math.imul(al9, bh2);
        mid = (mid + Math.imul(ah9, bl2)) | 0;
        hi = Math.imul(ah9, bh2);
        lo = (lo + Math.imul(al8, bl3)) | 0;
        mid = (mid + Math.imul(al8, bh3)) | 0;
        mid = (mid + Math.imul(ah8, bl3)) | 0;
        hi = (hi + Math.imul(ah8, bh3)) | 0;
        lo = (lo + Math.imul(al7, bl4)) | 0;
        mid = (mid + Math.imul(al7, bh4)) | 0;
        mid = (mid + Math.imul(ah7, bl4)) | 0;
        hi = (hi + Math.imul(ah7, bh4)) | 0;
        lo = (lo + Math.imul(al6, bl5)) | 0;
        mid = (mid + Math.imul(al6, bh5)) | 0;
        mid = (mid + Math.imul(ah6, bl5)) | 0;
        hi = (hi + Math.imul(ah6, bh5)) | 0;
        lo = (lo + Math.imul(al5, bl6)) | 0;
        mid = (mid + Math.imul(al5, bh6)) | 0;
        mid = (mid + Math.imul(ah5, bl6)) | 0;
        hi = (hi + Math.imul(ah5, bh6)) | 0;
        lo = (lo + Math.imul(al4, bl7)) | 0;
        mid = (mid + Math.imul(al4, bh7)) | 0;
        mid = (mid + Math.imul(ah4, bl7)) | 0;
        hi = (hi + Math.imul(ah4, bh7)) | 0;
        lo = (lo + Math.imul(al3, bl8)) | 0;
        mid = (mid + Math.imul(al3, bh8)) | 0;
        mid = (mid + Math.imul(ah3, bl8)) | 0;
        hi = (hi + Math.imul(ah3, bh8)) | 0;
        lo = (lo + Math.imul(al2, bl9)) | 0;
        mid = (mid + Math.imul(al2, bh9)) | 0;
        mid = (mid + Math.imul(ah2, bl9)) | 0;
        hi = (hi + Math.imul(ah2, bh9)) | 0;
        var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
        w11 &= 0x3ffffff;
        /* k = 12 */
        lo = Math.imul(al9, bl3);
        mid = Math.imul(al9, bh3);
        mid = (mid + Math.imul(ah9, bl3)) | 0;
        hi = Math.imul(ah9, bh3);
        lo = (lo + Math.imul(al8, bl4)) | 0;
        mid = (mid + Math.imul(al8, bh4)) | 0;
        mid = (mid + Math.imul(ah8, bl4)) | 0;
        hi = (hi + Math.imul(ah8, bh4)) | 0;
        lo = (lo + Math.imul(al7, bl5)) | 0;
        mid = (mid + Math.imul(al7, bh5)) | 0;
        mid = (mid + Math.imul(ah7, bl5)) | 0;
        hi = (hi + Math.imul(ah7, bh5)) | 0;
        lo = (lo + Math.imul(al6, bl6)) | 0;
        mid = (mid + Math.imul(al6, bh6)) | 0;
        mid = (mid + Math.imul(ah6, bl6)) | 0;
        hi = (hi + Math.imul(ah6, bh6)) | 0;
        lo = (lo + Math.imul(al5, bl7)) | 0;
        mid = (mid + Math.imul(al5, bh7)) | 0;
        mid = (mid + Math.imul(ah5, bl7)) | 0;
        hi = (hi + Math.imul(ah5, bh7)) | 0;
        lo = (lo + Math.imul(al4, bl8)) | 0;
        mid = (mid + Math.imul(al4, bh8)) | 0;
        mid = (mid + Math.imul(ah4, bl8)) | 0;
        hi = (hi + Math.imul(ah4, bh8)) | 0;
        lo = (lo + Math.imul(al3, bl9)) | 0;
        mid = (mid + Math.imul(al3, bh9)) | 0;
        mid = (mid + Math.imul(ah3, bl9)) | 0;
        hi = (hi + Math.imul(ah3, bh9)) | 0;
        var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
        w12 &= 0x3ffffff;
        /* k = 13 */
        lo = Math.imul(al9, bl4);
        mid = Math.imul(al9, bh4);
        mid = (mid + Math.imul(ah9, bl4)) | 0;
        hi = Math.imul(ah9, bh4);
        lo = (lo + Math.imul(al8, bl5)) | 0;
        mid = (mid + Math.imul(al8, bh5)) | 0;
        mid = (mid + Math.imul(ah8, bl5)) | 0;
        hi = (hi + Math.imul(ah8, bh5)) | 0;
        lo = (lo + Math.imul(al7, bl6)) | 0;
        mid = (mid + Math.imul(al7, bh6)) | 0;
        mid = (mid + Math.imul(ah7, bl6)) | 0;
        hi = (hi + Math.imul(ah7, bh6)) | 0;
        lo = (lo + Math.imul(al6, bl7)) | 0;
        mid = (mid + Math.imul(al6, bh7)) | 0;
        mid = (mid + Math.imul(ah6, bl7)) | 0;
        hi = (hi + Math.imul(ah6, bh7)) | 0;
        lo = (lo + Math.imul(al5, bl8)) | 0;
        mid = (mid + Math.imul(al5, bh8)) | 0;
        mid = (mid + Math.imul(ah5, bl8)) | 0;
        hi = (hi + Math.imul(ah5, bh8)) | 0;
        lo = (lo + Math.imul(al4, bl9)) | 0;
        mid = (mid + Math.imul(al4, bh9)) | 0;
        mid = (mid + Math.imul(ah4, bl9)) | 0;
        hi = (hi + Math.imul(ah4, bh9)) | 0;
        var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
        w13 &= 0x3ffffff;
        /* k = 14 */
        lo = Math.imul(al9, bl5);
        mid = Math.imul(al9, bh5);
        mid = (mid + Math.imul(ah9, bl5)) | 0;
        hi = Math.imul(ah9, bh5);
        lo = (lo + Math.imul(al8, bl6)) | 0;
        mid = (mid + Math.imul(al8, bh6)) | 0;
        mid = (mid + Math.imul(ah8, bl6)) | 0;
        hi = (hi + Math.imul(ah8, bh6)) | 0;
        lo = (lo + Math.imul(al7, bl7)) | 0;
        mid = (mid + Math.imul(al7, bh7)) | 0;
        mid = (mid + Math.imul(ah7, bl7)) | 0;
        hi = (hi + Math.imul(ah7, bh7)) | 0;
        lo = (lo + Math.imul(al6, bl8)) | 0;
        mid = (mid + Math.imul(al6, bh8)) | 0;
        mid = (mid + Math.imul(ah6, bl8)) | 0;
        hi = (hi + Math.imul(ah6, bh8)) | 0;
        lo = (lo + Math.imul(al5, bl9)) | 0;
        mid = (mid + Math.imul(al5, bh9)) | 0;
        mid = (mid + Math.imul(ah5, bl9)) | 0;
        hi = (hi + Math.imul(ah5, bh9)) | 0;
        var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
        w14 &= 0x3ffffff;
        /* k = 15 */
        lo = Math.imul(al9, bl6);
        mid = Math.imul(al9, bh6);
        mid = (mid + Math.imul(ah9, bl6)) | 0;
        hi = Math.imul(ah9, bh6);
        lo = (lo + Math.imul(al8, bl7)) | 0;
        mid = (mid + Math.imul(al8, bh7)) | 0;
        mid = (mid + Math.imul(ah8, bl7)) | 0;
        hi = (hi + Math.imul(ah8, bh7)) | 0;
        lo = (lo + Math.imul(al7, bl8)) | 0;
        mid = (mid + Math.imul(al7, bh8)) | 0;
        mid = (mid + Math.imul(ah7, bl8)) | 0;
        hi = (hi + Math.imul(ah7, bh8)) | 0;
        lo = (lo + Math.imul(al6, bl9)) | 0;
        mid = (mid + Math.imul(al6, bh9)) | 0;
        mid = (mid + Math.imul(ah6, bl9)) | 0;
        hi = (hi + Math.imul(ah6, bh9)) | 0;
        var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
        w15 &= 0x3ffffff;
        /* k = 16 */
        lo = Math.imul(al9, bl7);
        mid = Math.imul(al9, bh7);
        mid = (mid + Math.imul(ah9, bl7)) | 0;
        hi = Math.imul(ah9, bh7);
        lo = (lo + Math.imul(al8, bl8)) | 0;
        mid = (mid + Math.imul(al8, bh8)) | 0;
        mid = (mid + Math.imul(ah8, bl8)) | 0;
        hi = (hi + Math.imul(ah8, bh8)) | 0;
        lo = (lo + Math.imul(al7, bl9)) | 0;
        mid = (mid + Math.imul(al7, bh9)) | 0;
        mid = (mid + Math.imul(ah7, bl9)) | 0;
        hi = (hi + Math.imul(ah7, bh9)) | 0;
        var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
        w16 &= 0x3ffffff;
        /* k = 17 */
        lo = Math.imul(al9, bl8);
        mid = Math.imul(al9, bh8);
        mid = (mid + Math.imul(ah9, bl8)) | 0;
        hi = Math.imul(ah9, bh8);
        lo = (lo + Math.imul(al8, bl9)) | 0;
        mid = (mid + Math.imul(al8, bh9)) | 0;
        mid = (mid + Math.imul(ah8, bl9)) | 0;
        hi = (hi + Math.imul(ah8, bh9)) | 0;
        var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
        w17 &= 0x3ffffff;
        /* k = 18 */
        lo = Math.imul(al9, bl9);
        mid = Math.imul(al9, bh9);
        mid = (mid + Math.imul(ah9, bl9)) | 0;
        hi = Math.imul(ah9, bh9);
        var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
        c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
        w18 &= 0x3ffffff;
        o[0] = w0;
        o[1] = w1;
        o[2] = w2;
        o[3] = w3;
        o[4] = w4;
        o[5] = w5;
        o[6] = w6;
        o[7] = w7;
        o[8] = w8;
        o[9] = w9;
        o[10] = w10;
        o[11] = w11;
        o[12] = w12;
        o[13] = w13;
        o[14] = w14;
        o[15] = w15;
        o[16] = w16;
        o[17] = w17;
        o[18] = w18;
        if (c !== 0) {
          o[19] = c;
          out.length++;
        }
        return out;
      };
    
      // Polyfill comb
      if (!Math.imul) {
        comb10MulTo = smallMulTo;
      }
    
      function bigMulTo (self, num, out) {
        out.negative = num.negative ^ self.negative;
        out.length = self.length + num.length;
    
        var carry = 0;
        var hncarry = 0;
        for (var k = 0; k < out.length - 1; k++) {
          // Sum all words with the same `i + j = k` and accumulate `ncarry`,
          // note that ncarry could be >= 0x3ffffff
          var ncarry = hncarry;
          hncarry = 0;
          var rword = carry & 0x3ffffff;
          var maxJ = Math.min(k, num.length - 1);
          for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
            var i = k - j;
            var a = self.words[i] | 0;
            var b = num.words[j] | 0;
            var r = a * b;
    
            var lo = r & 0x3ffffff;
            ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
            lo = (lo + rword) | 0;
            rword = lo & 0x3ffffff;
            ncarry = (ncarry + (lo >>> 26)) | 0;
    
            hncarry += ncarry >>> 26;
            ncarry &= 0x3ffffff;
          }
          out.words[k] = rword;
          carry = ncarry;
          ncarry = hncarry;
        }
        if (carry !== 0) {
          out.words[k] = carry;
        } else {
          out.length--;
        }
    
        return out.strip();
      }
    
      function jumboMulTo (self, num, out) {
        var fftm = new FFTM();
        return fftm.mulp(self, num, out);
      }
    
      BN.prototype.mulTo = function mulTo (num, out) {
        var res;
        var len = this.length + num.length;
        if (this.length === 10 && num.length === 10) {
          res = comb10MulTo(this, num, out);
        } else if (len < 63) {
          res = smallMulTo(this, num, out);
        } else if (len < 1024) {
          res = bigMulTo(this, num, out);
        } else {
          res = jumboMulTo(this, num, out);
        }
    
        return res;
      };
    
      // Cooley-Tukey algorithm for FFT
      // slightly revisited to rely on looping instead of recursion
    
      function FFTM (x, y) {
        this.x = x;
        this.y = y;
      }
    
      FFTM.prototype.makeRBT = function makeRBT (N) {
        var t = new Array(N);
        var l = BN.prototype._countBits(N) - 1;
        for (var i = 0; i < N; i++) {
          t[i] = this.revBin(i, l, N);
        }
    
        return t;
      };
    
      // Returns binary-reversed representation of `x`
      FFTM.prototype.revBin = function revBin (x, l, N) {
        if (x === 0 || x === N - 1) return x;
    
        var rb = 0;
        for (var i = 0; i < l; i++) {
          rb |= (x & 1) << (l - i - 1);
          x >>= 1;
        }
    
        return rb;
      };
    
      // Performs "tweedling" phase, therefore 'emulating'
      // behaviour of the recursive algorithm
      FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
        for (var i = 0; i < N; i++) {
          rtws[i] = rws[rbt[i]];
          itws[i] = iws[rbt[i]];
        }
      };
    
      FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
        this.permute(rbt, rws, iws, rtws, itws, N);
    
        for (var s = 1; s < N; s <<= 1) {
          var l = s << 1;
    
          var rtwdf = Math.cos(2 * Math.PI / l);
          var itwdf = Math.sin(2 * Math.PI / l);
    
          for (var p = 0; p < N; p += l) {
            var rtwdf_ = rtwdf;
            var itwdf_ = itwdf;
    
            for (var j = 0; j < s; j++) {
              var re = rtws[p + j];
              var ie = itws[p + j];
    
              var ro = rtws[p + j + s];
              var io = itws[p + j + s];
    
              var rx = rtwdf_ * ro - itwdf_ * io;
    
              io = rtwdf_ * io + itwdf_ * ro;
              ro = rx;
    
              rtws[p + j] = re + ro;
              itws[p + j] = ie + io;
    
              rtws[p + j + s] = re - ro;
              itws[p + j + s] = ie - io;
    
              /* jshint maxdepth : false */
              if (j !== l) {
                rx = rtwdf * rtwdf_ - itwdf * itwdf_;
    
                itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
                rtwdf_ = rx;
              }
            }
          }
        }
      };
    
      FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
        var N = Math.max(m, n) | 1;
        var odd = N & 1;
        var i = 0;
        for (N = N / 2 | 0; N; N = N >>> 1) {
          i++;
        }
    
        return 1 << i + 1 + odd;
      };
    
      FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
        if (N <= 1) return;
    
        for (var i = 0; i < N / 2; i++) {
          var t = rws[i];
    
          rws[i] = rws[N - i - 1];
          rws[N - i - 1] = t;
    
          t = iws[i];
    
          iws[i] = -iws[N - i - 1];
          iws[N - i - 1] = -t;
        }
      };
    
      FFTM.prototype.normalize13b = function normalize13b (ws, N) {
        var carry = 0;
        for (var i = 0; i < N / 2; i++) {
          var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
            Math.round(ws[2 * i] / N) +
            carry;
    
          ws[i] = w & 0x3ffffff;
    
          if (w < 0x4000000) {
            carry = 0;
          } else {
            carry = w / 0x4000000 | 0;
          }
        }
    
        return ws;
      };
    
      FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
        var carry = 0;
        for (var i = 0; i < len; i++) {
          carry = carry + (ws[i] | 0);
    
          rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
          rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
        }
    
        // Pad with zeroes
        for (i = 2 * len; i < N; ++i) {
          rws[i] = 0;
        }
    
        assert(carry === 0);
        assert((carry & ~0x1fff) === 0);
      };
    
      FFTM.prototype.stub = function stub (N) {
        var ph = new Array(N);
        for (var i = 0; i < N; i++) {
          ph[i] = 0;
        }
    
        return ph;
      };
    
      FFTM.prototype.mulp = function mulp (x, y, out) {
        var N = 2 * this.guessLen13b(x.length, y.length);
    
        var rbt = this.makeRBT(N);
    
        var _ = this.stub(N);
    
        var rws = new Array(N);
        var rwst = new Array(N);
        var iwst = new Array(N);
    
        var nrws = new Array(N);
        var nrwst = new Array(N);
        var niwst = new Array(N);
    
        var rmws = out.words;
        rmws.length = N;
    
        this.convert13b(x.words, x.length, rws, N);
        this.convert13b(y.words, y.length, nrws, N);
    
        this.transform(rws, _, rwst, iwst, N, rbt);
        this.transform(nrws, _, nrwst, niwst, N, rbt);
    
        for (var i = 0; i < N; i++) {
          var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
          iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
          rwst[i] = rx;
        }
    
        this.conjugate(rwst, iwst, N);
        this.transform(rwst, iwst, rmws, _, N, rbt);
        this.conjugate(rmws, _, N);
        this.normalize13b(rmws, N);
    
        out.negative = x.negative ^ y.negative;
        out.length = x.length + y.length;
        return out.strip();
      };
    
      // Multiply `this` by `num`
      BN.prototype.mul = function mul (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return this.mulTo(num, out);
      };
    
      // Multiply employing FFT
      BN.prototype.mulf = function mulf (num) {
        var out = new BN(null);
        out.words = new Array(this.length + num.length);
        return jumboMulTo(this, num, out);
      };
    
      // In-place Multiplication
      BN.prototype.imul = function imul (num) {
        return this.clone().mulTo(num, this);
      };
    
      BN.prototype.imuln = function imuln (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
    
        // Carry
        var carry = 0;
        for (var i = 0; i < this.length; i++) {
          var w = (this.words[i] | 0) * num;
          var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
          carry >>= 26;
          carry += (w / 0x4000000) | 0;
          // NOTE: lo is 27bit maximum
          carry += lo >>> 26;
          this.words[i] = lo & 0x3ffffff;
        }
    
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
    
        return this;
      };
    
      BN.prototype.muln = function muln (num) {
        return this.clone().imuln(num);
      };
    
      // `this` * `this`
      BN.prototype.sqr = function sqr () {
        return this.mul(this);
      };
    
      // `this` * `this` in-place
      BN.prototype.isqr = function isqr () {
        return this.imul(this.clone());
      };
    
      // Math.pow(`this`, `num`)
      BN.prototype.pow = function pow (num) {
        var w = toBitArray(num);
        if (w.length === 0) return new BN(1);
    
        // Skip leading zeroes
        var res = this;
        for (var i = 0; i < w.length; i++, res = res.sqr()) {
          if (w[i] !== 0) break;
        }
    
        if (++i < w.length) {
          for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
            if (w[i] === 0) continue;
    
            res = res.mul(q);
          }
        }
    
        return res;
      };
    
      // Shift-left in-place
      BN.prototype.iushln = function iushln (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
        var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
        var i;
    
        if (r !== 0) {
          var carry = 0;
    
          for (i = 0; i < this.length; i++) {
            var newCarry = this.words[i] & carryMask;
            var c = ((this.words[i] | 0) - newCarry) << r;
            this.words[i] = c | carry;
            carry = newCarry >>> (26 - r);
          }
    
          if (carry) {
            this.words[i] = carry;
            this.length++;
          }
        }
    
        if (s !== 0) {
          for (i = this.length - 1; i >= 0; i--) {
            this.words[i + s] = this.words[i];
          }
    
          for (i = 0; i < s; i++) {
            this.words[i] = 0;
          }
    
          this.length += s;
        }
    
        return this.strip();
      };
    
      BN.prototype.ishln = function ishln (bits) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushln(bits);
      };
    
      // Shift-right in-place
      // NOTE: `hint` is a lowest bit before trailing zeroes
      // NOTE: if `extended` is present - it will be filled with destroyed bits
      BN.prototype.iushrn = function iushrn (bits, hint, extended) {
        assert(typeof bits === 'number' && bits >= 0);
        var h;
        if (hint) {
          h = (hint - (hint % 26)) / 26;
        } else {
          h = 0;
        }
    
        var r = bits % 26;
        var s = Math.min((bits - r) / 26, this.length);
        var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
        var maskedWords = extended;
    
        h -= s;
        h = Math.max(0, h);
    
        // Extended mode, copy masked part
        if (maskedWords) {
          for (var i = 0; i < s; i++) {
            maskedWords.words[i] = this.words[i];
          }
          maskedWords.length = s;
        }
    
        if (s === 0) {
          // No-op, we should not move anything at all
        } else if (this.length > s) {
          this.length -= s;
          for (i = 0; i < this.length; i++) {
            this.words[i] = this.words[i + s];
          }
        } else {
          this.words[0] = 0;
          this.length = 1;
        }
    
        var carry = 0;
        for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
          var word = this.words[i] | 0;
          this.words[i] = (carry << (26 - r)) | (word >>> r);
          carry = word & mask;
        }
    
        // Push carried bits as a mask
        if (maskedWords && carry !== 0) {
          maskedWords.words[maskedWords.length++] = carry;
        }
    
        if (this.length === 0) {
          this.words[0] = 0;
          this.length = 1;
        }
    
        return this.strip();
      };
    
      BN.prototype.ishrn = function ishrn (bits, hint, extended) {
        // TODO(indutny): implement me
        assert(this.negative === 0);
        return this.iushrn(bits, hint, extended);
      };
    
      // Shift-left
      BN.prototype.shln = function shln (bits) {
        return this.clone().ishln(bits);
      };
    
      BN.prototype.ushln = function ushln (bits) {
        return this.clone().iushln(bits);
      };
    
      // Shift-right
      BN.prototype.shrn = function shrn (bits) {
        return this.clone().ishrn(bits);
      };
    
      BN.prototype.ushrn = function ushrn (bits) {
        return this.clone().iushrn(bits);
      };
    
      // Test if n bit is set
      BN.prototype.testn = function testn (bit) {
        assert(typeof bit === 'number' && bit >= 0);
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) return false;
    
        // Check bit and return
        var w = this.words[s];
    
        return !!(w & q);
      };
    
      // Return only lowers bits of number (in-place)
      BN.prototype.imaskn = function imaskn (bits) {
        assert(typeof bits === 'number' && bits >= 0);
        var r = bits % 26;
        var s = (bits - r) / 26;
    
        assert(this.negative === 0, 'imaskn works only with positive numbers');
    
        if (this.length <= s) {
          return this;
        }
    
        if (r !== 0) {
          s++;
        }
        this.length = Math.min(s, this.length);
    
        if (r !== 0) {
          var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
          this.words[this.length - 1] &= mask;
        }
    
        return this.strip();
      };
    
      // Return only lowers bits of number
      BN.prototype.maskn = function maskn (bits) {
        return this.clone().imaskn(bits);
      };
    
      // Add plain number `num` to `this`
      BN.prototype.iaddn = function iaddn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.isubn(-num);
    
        // Possible sign change
        if (this.negative !== 0) {
          if (this.length === 1 && (this.words[0] | 0) < num) {
            this.words[0] = num - (this.words[0] | 0);
            this.negative = 0;
            return this;
          }
    
          this.negative = 0;
          this.isubn(num);
          this.negative = 1;
          return this;
        }
    
        // Add without checks
        return this._iaddn(num);
      };
    
      BN.prototype._iaddn = function _iaddn (num) {
        this.words[0] += num;
    
        // Carry
        for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
          this.words[i] -= 0x4000000;
          if (i === this.length - 1) {
            this.words[i + 1] = 1;
          } else {
            this.words[i + 1]++;
          }
        }
        this.length = Math.max(this.length, i + 1);
    
        return this;
      };
    
      // Subtract plain number `num` from `this`
      BN.prototype.isubn = function isubn (num) {
        assert(typeof num === 'number');
        assert(num < 0x4000000);
        if (num < 0) return this.iaddn(-num);
    
        if (this.negative !== 0) {
          this.negative = 0;
          this.iaddn(num);
          this.negative = 1;
          return this;
        }
    
        this.words[0] -= num;
    
        if (this.length === 1 && this.words[0] < 0) {
          this.words[0] = -this.words[0];
          this.negative = 1;
        } else {
          // Carry
          for (var i = 0; i < this.length && this.words[i] < 0; i++) {
            this.words[i] += 0x4000000;
            this.words[i + 1] -= 1;
          }
        }
    
        return this.strip();
      };
    
      BN.prototype.addn = function addn (num) {
        return this.clone().iaddn(num);
      };
    
      BN.prototype.subn = function subn (num) {
        return this.clone().isubn(num);
      };
    
      BN.prototype.iabs = function iabs () {
        this.negative = 0;
    
        return this;
      };
    
      BN.prototype.abs = function abs () {
        return this.clone().iabs();
      };
    
      BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
        var len = num.length + shift;
        var i;
    
        this._expand(len);
    
        var w;
        var carry = 0;
        for (i = 0; i < num.length; i++) {
          w = (this.words[i + shift] | 0) + carry;
          var right = (num.words[i] | 0) * mul;
          w -= right & 0x3ffffff;
          carry = (w >> 26) - ((right / 0x4000000) | 0);
          this.words[i + shift] = w & 0x3ffffff;
        }
        for (; i < this.length - shift; i++) {
          w = (this.words[i + shift] | 0) + carry;
          carry = w >> 26;
          this.words[i + shift] = w & 0x3ffffff;
        }
    
        if (carry === 0) return this.strip();
    
        // Subtraction overflow
        assert(carry === -1);
        carry = 0;
        for (i = 0; i < this.length; i++) {
          w = -(this.words[i] | 0) + carry;
          carry = w >> 26;
          this.words[i] = w & 0x3ffffff;
        }
        this.negative = 1;
    
        return this.strip();
      };
    
      BN.prototype._wordDiv = function _wordDiv (num, mode) {
        var shift = this.length - num.length;
    
        var a = this.clone();
        var b = num;
    
        // Normalize
        var bhi = b.words[b.length - 1] | 0;
        var bhiBits = this._countBits(bhi);
        shift = 26 - bhiBits;
        if (shift !== 0) {
          b = b.ushln(shift);
          a.iushln(shift);
          bhi = b.words[b.length - 1] | 0;
        }
    
        // Initialize quotient
        var m = a.length - b.length;
        var q;
    
        if (mode !== 'mod') {
          q = new BN(null);
          q.length = m + 1;
          q.words = new Array(q.length);
          for (var i = 0; i < q.length; i++) {
            q.words[i] = 0;
          }
        }
    
        var diff = a.clone()._ishlnsubmul(b, 1, m);
        if (diff.negative === 0) {
          a = diff;
          if (q) {
            q.words[m] = 1;
          }
        }
    
        for (var j = m - 1; j >= 0; j--) {
          var qj = (a.words[b.length + j] | 0) * 0x4000000 +
            (a.words[b.length + j - 1] | 0);
    
          // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
          // (0x7ffffff)
          qj = Math.min((qj / bhi) | 0, 0x3ffffff);
    
          a._ishlnsubmul(b, qj, j);
          while (a.negative !== 0) {
            qj--;
            a.negative = 0;
            a._ishlnsubmul(b, 1, j);
            if (!a.isZero()) {
              a.negative ^= 1;
            }
          }
          if (q) {
            q.words[j] = qj;
          }
        }
        if (q) {
          q.strip();
        }
        a.strip();
    
        // Denormalize
        if (mode !== 'div' && shift !== 0) {
          a.iushrn(shift);
        }
    
        return {
          div: q || null,
          mod: a
        };
      };
    
      // NOTE: 1) `mode` can be set to `mod` to request mod only,
      //       to `div` to request div only, or be absent to
      //       request both div & mod
      //       2) `positive` is true if unsigned mod is requested
      BN.prototype.divmod = function divmod (num, mode, positive) {
        assert(!num.isZero());
    
        if (this.isZero()) {
          return {
            div: new BN(0),
            mod: new BN(0)
          };
        }
    
        var div, mod, res;
        if (this.negative !== 0 && num.negative === 0) {
          res = this.neg().divmod(num, mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.iadd(num);
            }
          }
    
          return {
            div: div,
            mod: mod
          };
        }
    
        if (this.negative === 0 && num.negative !== 0) {
          res = this.divmod(num.neg(), mode);
    
          if (mode !== 'mod') {
            div = res.div.neg();
          }
    
          return {
            div: div,
            mod: res.mod
          };
        }
    
        if ((this.negative & num.negative) !== 0) {
          res = this.neg().divmod(num.neg(), mode);
    
          if (mode !== 'div') {
            mod = res.mod.neg();
            if (positive && mod.negative !== 0) {
              mod.isub(num);
            }
          }
    
          return {
            div: res.div,
            mod: mod
          };
        }
    
        // Both numbers are positive at this point
    
        // Strip both numbers to approximate shift value
        if (num.length > this.length || this.cmp(num) < 0) {
          return {
            div: new BN(0),
            mod: this
          };
        }
    
        // Very short reduction
        if (num.length === 1) {
          if (mode === 'div') {
            return {
              div: this.divn(num.words[0]),
              mod: null
            };
          }
    
          if (mode === 'mod') {
            return {
              div: null,
              mod: new BN(this.modn(num.words[0]))
            };
          }
    
          return {
            div: this.divn(num.words[0]),
            mod: new BN(this.modn(num.words[0]))
          };
        }
    
        return this._wordDiv(num, mode);
      };
    
      // Find `this` / `num`
      BN.prototype.div = function div (num) {
        return this.divmod(num, 'div', false).div;
      };
    
      // Find `this` % `num`
      BN.prototype.mod = function mod (num) {
        return this.divmod(num, 'mod', false).mod;
      };
    
      BN.prototype.umod = function umod (num) {
        return this.divmod(num, 'mod', true).mod;
      };
    
      // Find Round(`this` / `num`)
      BN.prototype.divRound = function divRound (num) {
        var dm = this.divmod(num);
    
        // Fast case - exact division
        if (dm.mod.isZero()) return dm.div;
    
        var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
    
        var half = num.ushrn(1);
        var r2 = num.andln(1);
        var cmp = mod.cmp(half);
    
        // Round down
        if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
    
        // Round up
        return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
      };
    
      BN.prototype.modn = function modn (num) {
        assert(num <= 0x3ffffff);
        var p = (1 << 26) % num;
    
        var acc = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          acc = (p * acc + (this.words[i] | 0)) % num;
        }
    
        return acc;
      };
    
      // In-place division by number
      BN.prototype.idivn = function idivn (num) {
        assert(num <= 0x3ffffff);
    
        var carry = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var w = (this.words[i] | 0) + carry * 0x4000000;
          this.words[i] = (w / num) | 0;
          carry = w % num;
        }
    
        return this.strip();
      };
    
      BN.prototype.divn = function divn (num) {
        return this.clone().idivn(num);
      };
    
      BN.prototype.egcd = function egcd (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var x = this;
        var y = p.clone();
    
        if (x.negative !== 0) {
          x = x.umod(p);
        } else {
          x = x.clone();
        }
    
        // A * x + B * y = x
        var A = new BN(1);
        var B = new BN(0);
    
        // C * x + D * y = y
        var C = new BN(0);
        var D = new BN(1);
    
        var g = 0;
    
        while (x.isEven() && y.isEven()) {
          x.iushrn(1);
          y.iushrn(1);
          ++g;
        }
    
        var yp = y.clone();
        var xp = x.clone();
    
        while (!x.isZero()) {
          for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            x.iushrn(i);
            while (i-- > 0) {
              if (A.isOdd() || B.isOdd()) {
                A.iadd(yp);
                B.isub(xp);
              }
    
              A.iushrn(1);
              B.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            y.iushrn(j);
            while (j-- > 0) {
              if (C.isOdd() || D.isOdd()) {
                C.iadd(yp);
                D.isub(xp);
              }
    
              C.iushrn(1);
              D.iushrn(1);
            }
          }
    
          if (x.cmp(y) >= 0) {
            x.isub(y);
            A.isub(C);
            B.isub(D);
          } else {
            y.isub(x);
            C.isub(A);
            D.isub(B);
          }
        }
    
        return {
          a: C,
          b: D,
          gcd: y.iushln(g)
        };
      };
    
      // This is reduced incarnation of the binary EEA
      // above, designated to invert members of the
      // _prime_ fields F(p) at a maximal speed
      BN.prototype._invmp = function _invmp (p) {
        assert(p.negative === 0);
        assert(!p.isZero());
    
        var a = this;
        var b = p.clone();
    
        if (a.negative !== 0) {
          a = a.umod(p);
        } else {
          a = a.clone();
        }
    
        var x1 = new BN(1);
        var x2 = new BN(0);
    
        var delta = b.clone();
    
        while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
          for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
          if (i > 0) {
            a.iushrn(i);
            while (i-- > 0) {
              if (x1.isOdd()) {
                x1.iadd(delta);
              }
    
              x1.iushrn(1);
            }
          }
    
          for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
          if (j > 0) {
            b.iushrn(j);
            while (j-- > 0) {
              if (x2.isOdd()) {
                x2.iadd(delta);
              }
    
              x2.iushrn(1);
            }
          }
    
          if (a.cmp(b) >= 0) {
            a.isub(b);
            x1.isub(x2);
          } else {
            b.isub(a);
            x2.isub(x1);
          }
        }
    
        var res;
        if (a.cmpn(1) === 0) {
          res = x1;
        } else {
          res = x2;
        }
    
        if (res.cmpn(0) < 0) {
          res.iadd(p);
        }
    
        return res;
      };
    
      BN.prototype.gcd = function gcd (num) {
        if (this.isZero()) return num.abs();
        if (num.isZero()) return this.abs();
    
        var a = this.clone();
        var b = num.clone();
        a.negative = 0;
        b.negative = 0;
    
        // Remove common factor of two
        for (var shift = 0; a.isEven() && b.isEven(); shift++) {
          a.iushrn(1);
          b.iushrn(1);
        }
    
        do {
          while (a.isEven()) {
            a.iushrn(1);
          }
          while (b.isEven()) {
            b.iushrn(1);
          }
    
          var r = a.cmp(b);
          if (r < 0) {
            // Swap `a` and `b` to make `a` always bigger than `b`
            var t = a;
            a = b;
            b = t;
          } else if (r === 0 || b.cmpn(1) === 0) {
            break;
          }
    
          a.isub(b);
        } while (true);
    
        return b.iushln(shift);
      };
    
      // Invert number in the field F(num)
      BN.prototype.invm = function invm (num) {
        return this.egcd(num).a.umod(num);
      };
    
      BN.prototype.isEven = function isEven () {
        return (this.words[0] & 1) === 0;
      };
    
      BN.prototype.isOdd = function isOdd () {
        return (this.words[0] & 1) === 1;
      };
    
      // And first word and num
      BN.prototype.andln = function andln (num) {
        return this.words[0] & num;
      };
    
      // Increment at the bit position in-line
      BN.prototype.bincn = function bincn (bit) {
        assert(typeof bit === 'number');
        var r = bit % 26;
        var s = (bit - r) / 26;
        var q = 1 << r;
    
        // Fast case: bit is much higher than all existing words
        if (this.length <= s) {
          this._expand(s + 1);
          this.words[s] |= q;
          return this;
        }
    
        // Add bit and propagate, if needed
        var carry = q;
        for (var i = s; carry !== 0 && i < this.length; i++) {
          var w = this.words[i] | 0;
          w += carry;
          carry = w >>> 26;
          w &= 0x3ffffff;
          this.words[i] = w;
        }
        if (carry !== 0) {
          this.words[i] = carry;
          this.length++;
        }
        return this;
      };
    
      BN.prototype.isZero = function isZero () {
        return this.length === 1 && this.words[0] === 0;
      };
    
      BN.prototype.cmpn = function cmpn (num) {
        var negative = num < 0;
    
        if (this.negative !== 0 && !negative) return -1;
        if (this.negative === 0 && negative) return 1;
    
        this.strip();
    
        var res;
        if (this.length > 1) {
          res = 1;
        } else {
          if (negative) {
            num = -num;
          }
    
          assert(num <= 0x3ffffff, 'Number is too big');
    
          var w = this.words[0] | 0;
          res = w === num ? 0 : w < num ? -1 : 1;
        }
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Compare two numbers and return:
      // 1 - if `this` > `num`
      // 0 - if `this` == `num`
      // -1 - if `this` < `num`
      BN.prototype.cmp = function cmp (num) {
        if (this.negative !== 0 && num.negative === 0) return -1;
        if (this.negative === 0 && num.negative !== 0) return 1;
    
        var res = this.ucmp(num);
        if (this.negative !== 0) return -res | 0;
        return res;
      };
    
      // Unsigned comparison
      BN.prototype.ucmp = function ucmp (num) {
        // At this point both numbers have the same sign
        if (this.length > num.length) return 1;
        if (this.length < num.length) return -1;
    
        var res = 0;
        for (var i = this.length - 1; i >= 0; i--) {
          var a = this.words[i] | 0;
          var b = num.words[i] | 0;
    
          if (a === b) continue;
          if (a < b) {
            res = -1;
          } else if (a > b) {
            res = 1;
          }
          break;
        }
        return res;
      };
    
      BN.prototype.gtn = function gtn (num) {
        return this.cmpn(num) === 1;
      };
    
      BN.prototype.gt = function gt (num) {
        return this.cmp(num) === 1;
      };
    
      BN.prototype.gten = function gten (num) {
        return this.cmpn(num) >= 0;
      };
    
      BN.prototype.gte = function gte (num) {
        return this.cmp(num) >= 0;
      };
    
      BN.prototype.ltn = function ltn (num) {
        return this.cmpn(num) === -1;
      };
    
      BN.prototype.lt = function lt (num) {
        return this.cmp(num) === -1;
      };
    
      BN.prototype.lten = function lten (num) {
        return this.cmpn(num) <= 0;
      };
    
      BN.prototype.lte = function lte (num) {
        return this.cmp(num) <= 0;
      };
    
      BN.prototype.eqn = function eqn (num) {
        return this.cmpn(num) === 0;
      };
    
      BN.prototype.eq = function eq (num) {
        return this.cmp(num) === 0;
      };
    
      //
      // A reduce context, could be using montgomery or something better, depending
      // on the `m` itself.
      //
      BN.red = function red (num) {
        return new Red(num);
      };
    
      BN.prototype.toRed = function toRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        assert(this.negative === 0, 'red works only with positives');
        return ctx.convertTo(this)._forceRed(ctx);
      };
    
      BN.prototype.fromRed = function fromRed () {
        assert(this.red, 'fromRed works only with numbers in reduction context');
        return this.red.convertFrom(this);
      };
    
      BN.prototype._forceRed = function _forceRed (ctx) {
        this.red = ctx;
        return this;
      };
    
      BN.prototype.forceRed = function forceRed (ctx) {
        assert(!this.red, 'Already a number in reduction context');
        return this._forceRed(ctx);
      };
    
      BN.prototype.redAdd = function redAdd (num) {
        assert(this.red, 'redAdd works only with red numbers');
        return this.red.add(this, num);
      };
    
      BN.prototype.redIAdd = function redIAdd (num) {
        assert(this.red, 'redIAdd works only with red numbers');
        return this.red.iadd(this, num);
      };
    
      BN.prototype.redSub = function redSub (num) {
        assert(this.red, 'redSub works only with red numbers');
        return this.red.sub(this, num);
      };
    
      BN.prototype.redISub = function redISub (num) {
        assert(this.red, 'redISub works only with red numbers');
        return this.red.isub(this, num);
      };
    
      BN.prototype.redShl = function redShl (num) {
        assert(this.red, 'redShl works only with red numbers');
        return this.red.shl(this, num);
      };
    
      BN.prototype.redMul = function redMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.mul(this, num);
      };
    
      BN.prototype.redIMul = function redIMul (num) {
        assert(this.red, 'redMul works only with red numbers');
        this.red._verify2(this, num);
        return this.red.imul(this, num);
      };
    
      BN.prototype.redSqr = function redSqr () {
        assert(this.red, 'redSqr works only with red numbers');
        this.red._verify1(this);
        return this.red.sqr(this);
      };
    
      BN.prototype.redISqr = function redISqr () {
        assert(this.red, 'redISqr works only with red numbers');
        this.red._verify1(this);
        return this.red.isqr(this);
      };
    
      // Square root over p
      BN.prototype.redSqrt = function redSqrt () {
        assert(this.red, 'redSqrt works only with red numbers');
        this.red._verify1(this);
        return this.red.sqrt(this);
      };
    
      BN.prototype.redInvm = function redInvm () {
        assert(this.red, 'redInvm works only with red numbers');
        this.red._verify1(this);
        return this.red.invm(this);
      };
    
      // Return negative clone of `this` % `red modulo`
      BN.prototype.redNeg = function redNeg () {
        assert(this.red, 'redNeg works only with red numbers');
        this.red._verify1(this);
        return this.red.neg(this);
      };
    
      BN.prototype.redPow = function redPow (num) {
        assert(this.red && !num.red, 'redPow(normalNum)');
        this.red._verify1(this);
        return this.red.pow(this, num);
      };
    
      // Prime numbers with efficient reduction
      var primes = {
        k256: null,
        p224: null,
        p192: null,
        p25519: null
      };
    
      // Pseudo-Mersenne prime
      function MPrime (name, p) {
        // P = 2 ^ N - K
        this.name = name;
        this.p = new BN(p, 16);
        this.n = this.p.bitLength();
        this.k = new BN(1).iushln(this.n).isub(this.p);
    
        this.tmp = this._tmp();
      }
    
      MPrime.prototype._tmp = function _tmp () {
        var tmp = new BN(null);
        tmp.words = new Array(Math.ceil(this.n / 13));
        return tmp;
      };
    
      MPrime.prototype.ireduce = function ireduce (num) {
        // Assumes that `num` is less than `P^2`
        // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
        var r = num;
        var rlen;
    
        do {
          this.split(r, this.tmp);
          r = this.imulK(r);
          r = r.iadd(this.tmp);
          rlen = r.bitLength();
        } while (rlen > this.n);
    
        var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
        if (cmp === 0) {
          r.words[0] = 0;
          r.length = 1;
        } else if (cmp > 0) {
          r.isub(this.p);
        } else {
          if (r.strip !== undefined) {
            // r is BN v4 instance
            r.strip();
          } else {
            // r is BN v5 instance
            r._strip();
          }
        }
    
        return r;
      };
    
      MPrime.prototype.split = function split (input, out) {
        input.iushrn(this.n, 0, out);
      };
    
      MPrime.prototype.imulK = function imulK (num) {
        return num.imul(this.k);
      };
    
      function K256 () {
        MPrime.call(
          this,
          'k256',
          'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
      }
      inherits(K256, MPrime);
    
      K256.prototype.split = function split (input, output) {
        // 256 = 9 * 26 + 22
        var mask = 0x3fffff;
    
        var outLen = Math.min(input.length, 9);
        for (var i = 0; i < outLen; i++) {
          output.words[i] = input.words[i];
        }
        output.length = outLen;
    
        if (input.length <= 9) {
          input.words[0] = 0;
          input.length = 1;
          return;
        }
    
        // Shift by 9 limbs
        var prev = input.words[9];
        output.words[output.length++] = prev & mask;
    
        for (i = 10; i < input.length; i++) {
          var next = input.words[i] | 0;
          input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
          prev = next;
        }
        prev >>>= 22;
        input.words[i - 10] = prev;
        if (prev === 0 && input.length > 10) {
          input.length -= 10;
        } else {
          input.length -= 9;
        }
      };
    
      K256.prototype.imulK = function imulK (num) {
        // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
        num.words[num.length] = 0;
        num.words[num.length + 1] = 0;
        num.length += 2;
    
        // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
        var lo = 0;
        for (var i = 0; i < num.length; i++) {
          var w = num.words[i] | 0;
          lo += w * 0x3d1;
          num.words[i] = lo & 0x3ffffff;
          lo = w * 0x40 + ((lo / 0x4000000) | 0);
        }
    
        // Fast length reduction
        if (num.words[num.length - 1] === 0) {
          num.length--;
          if (num.words[num.length - 1] === 0) {
            num.length--;
          }
        }
        return num;
      };
    
      function P224 () {
        MPrime.call(
          this,
          'p224',
          'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
      }
      inherits(P224, MPrime);
    
      function P192 () {
        MPrime.call(
          this,
          'p192',
          'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
      }
      inherits(P192, MPrime);
    
      function P25519 () {
        // 2 ^ 255 - 19
        MPrime.call(
          this,
          '25519',
          '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
      }
      inherits(P25519, MPrime);
    
      P25519.prototype.imulK = function imulK (num) {
        // K = 0x13
        var carry = 0;
        for (var i = 0; i < num.length; i++) {
          var hi = (num.words[i] | 0) * 0x13 + carry;
          var lo = hi & 0x3ffffff;
          hi >>>= 26;
    
          num.words[i] = lo;
          carry = hi;
        }
        if (carry !== 0) {
          num.words[num.length++] = carry;
        }
        return num;
      };
    
      // Exported mostly for testing purposes, use plain name instead
      BN._prime = function prime (name) {
        // Cached version of prime
        if (primes[name]) return primes[name];
    
        var prime;
        if (name === 'k256') {
          prime = new K256();
        } else if (name === 'p224') {
          prime = new P224();
        } else if (name === 'p192') {
          prime = new P192();
        } else if (name === 'p25519') {
          prime = new P25519();
        } else {
          throw new Error('Unknown prime ' + name);
        }
        primes[name] = prime;
    
        return prime;
      };
    
      //
      // Base reduction engine
      //
      function Red (m) {
        if (typeof m === 'string') {
          var prime = BN._prime(m);
          this.m = prime.p;
          this.prime = prime;
        } else {
          assert(m.gtn(1), 'modulus must be greater than 1');
          this.m = m;
          this.prime = null;
        }
      }
    
      Red.prototype._verify1 = function _verify1 (a) {
        assert(a.negative === 0, 'red works only with positives');
        assert(a.red, 'red works only with red numbers');
      };
    
      Red.prototype._verify2 = function _verify2 (a, b) {
        assert((a.negative | b.negative) === 0, 'red works only with positives');
        assert(a.red && a.red === b.red,
          'red works only with red numbers');
      };
    
      Red.prototype.imod = function imod (a) {
        if (this.prime) return this.prime.ireduce(a)._forceRed(this);
        return a.umod(this.m)._forceRed(this);
      };
    
      Red.prototype.neg = function neg (a) {
        if (a.isZero()) {
          return a.clone();
        }
    
        return this.m.sub(a)._forceRed(this);
      };
    
      Red.prototype.add = function add (a, b) {
        this._verify2(a, b);
    
        var res = a.add(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.iadd = function iadd (a, b) {
        this._verify2(a, b);
    
        var res = a.iadd(b);
        if (res.cmp(this.m) >= 0) {
          res.isub(this.m);
        }
        return res;
      };
    
      Red.prototype.sub = function sub (a, b) {
        this._verify2(a, b);
    
        var res = a.sub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res._forceRed(this);
      };
    
      Red.prototype.isub = function isub (a, b) {
        this._verify2(a, b);
    
        var res = a.isub(b);
        if (res.cmpn(0) < 0) {
          res.iadd(this.m);
        }
        return res;
      };
    
      Red.prototype.shl = function shl (a, num) {
        this._verify1(a);
        return this.imod(a.ushln(num));
      };
    
      Red.prototype.imul = function imul (a, b) {
        this._verify2(a, b);
        return this.imod(a.imul(b));
      };
    
      Red.prototype.mul = function mul (a, b) {
        this._verify2(a, b);
        return this.imod(a.mul(b));
      };
    
      Red.prototype.isqr = function isqr (a) {
        return this.imul(a, a.clone());
      };
    
      Red.prototype.sqr = function sqr (a) {
        return this.mul(a, a);
      };
    
      Red.prototype.sqrt = function sqrt (a) {
        if (a.isZero()) return a.clone();
    
        var mod3 = this.m.andln(3);
        assert(mod3 % 2 === 1);
    
        // Fast case
        if (mod3 === 3) {
          var pow = this.m.add(new BN(1)).iushrn(2);
          return this.pow(a, pow);
        }
    
        // Tonelli-Shanks algorithm (Totally unoptimized and slow)
        //
        // Find Q and S, that Q * 2 ^ S = (P - 1)
        var q = this.m.subn(1);
        var s = 0;
        while (!q.isZero() && q.andln(1) === 0) {
          s++;
          q.iushrn(1);
        }
        assert(!q.isZero());
    
        var one = new BN(1).toRed(this);
        var nOne = one.redNeg();
    
        // Find quadratic non-residue
        // NOTE: Max is such because of generalized Riemann hypothesis.
        var lpow = this.m.subn(1).iushrn(1);
        var z = this.m.bitLength();
        z = new BN(2 * z * z).toRed(this);
    
        while (this.pow(z, lpow).cmp(nOne) !== 0) {
          z.redIAdd(nOne);
        }
    
        var c = this.pow(z, q);
        var r = this.pow(a, q.addn(1).iushrn(1));
        var t = this.pow(a, q);
        var m = s;
        while (t.cmp(one) !== 0) {
          var tmp = t;
          for (var i = 0; tmp.cmp(one) !== 0; i++) {
            tmp = tmp.redSqr();
          }
          assert(i < m);
          var b = this.pow(c, new BN(1).iushln(m - i - 1));
    
          r = r.redMul(b);
          c = b.redSqr();
          t = t.redMul(c);
          m = i;
        }
    
        return r;
      };
    
      Red.prototype.invm = function invm (a) {
        var inv = a._invmp(this.m);
        if (inv.negative !== 0) {
          inv.negative = 0;
          return this.imod(inv).redNeg();
        } else {
          return this.imod(inv);
        }
      };
    
      Red.prototype.pow = function pow (a, num) {
        if (num.isZero()) return new BN(1).toRed(this);
        if (num.cmpn(1) === 0) return a.clone();
    
        var windowSize = 4;
        var wnd = new Array(1 << windowSize);
        wnd[0] = new BN(1).toRed(this);
        wnd[1] = a;
        for (var i = 2; i < wnd.length; i++) {
          wnd[i] = this.mul(wnd[i - 1], a);
        }
    
        var res = wnd[0];
        var current = 0;
        var currentLen = 0;
        var start = num.bitLength() % 26;
        if (start === 0) {
          start = 26;
        }
    
        for (i = num.length - 1; i >= 0; i--) {
          var word = num.words[i];
          for (var j = start - 1; j >= 0; j--) {
            var bit = (word >> j) & 1;
            if (res !== wnd[0]) {
              res = this.sqr(res);
            }
    
            if (bit === 0 && current === 0) {
              currentLen = 0;
              continue;
            }
    
            current <<= 1;
            current |= bit;
            currentLen++;
            if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
    
            res = this.mul(res, wnd[current]);
            currentLen = 0;
            current = 0;
          }
          start = 26;
        }
    
        return res;
      };
    
      Red.prototype.convertTo = function convertTo (num) {
        var r = num.umod(this.m);
    
        return r === num ? r.clone() : r;
      };
    
      Red.prototype.convertFrom = function convertFrom (num) {
        var res = num.clone();
        res.red = null;
        return res;
      };
    
      //
      // Montgomery method engine
      //
    
      BN.mont = function mont (num) {
        return new Mont(num);
      };
    
      function Mont (m) {
        Red.call(this, m);
    
        this.shift = this.m.bitLength();
        if (this.shift % 26 !== 0) {
          this.shift += 26 - (this.shift % 26);
        }
    
        this.r = new BN(1).iushln(this.shift);
        this.r2 = this.imod(this.r.sqr());
        this.rinv = this.r._invmp(this.m);
    
        this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
        this.minv = this.minv.umod(this.r);
        this.minv = this.r.sub(this.minv);
      }
      inherits(Mont, Red);
    
      Mont.prototype.convertTo = function convertTo (num) {
        return this.imod(num.ushln(this.shift));
      };
    
      Mont.prototype.convertFrom = function convertFrom (num) {
        var r = this.imod(num.mul(this.rinv));
        r.red = null;
        return r;
      };
    
      Mont.prototype.imul = function imul (a, b) {
        if (a.isZero() || b.isZero()) {
          a.words[0] = 0;
          a.length = 1;
          return a;
        }
    
        var t = a.imul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
    
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.mul = function mul (a, b) {
        if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
    
        var t = a.mul(b);
        var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
        var u = t.isub(c).iushrn(this.shift);
        var res = u;
        if (u.cmp(this.m) >= 0) {
          res = u.isub(this.m);
        } else if (u.cmpn(0) < 0) {
          res = u.iadd(this.m);
        }
    
        return res._forceRed(this);
      };
    
      Mont.prototype.invm = function invm (a) {
        // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
        var res = this.imod(a._invmp(this.m).mul(this.r2));
        return res._forceRed(this);
      };
    })(typeof module === 'undefined' || module, this);
    
    },{"buffer":36}],276:[function(require,module,exports){
    arguments[4][25][0].apply(exports,arguments)
    },{"dup":25}],277:[function(require,module,exports){
    module.exports={
      "name": "mvc-lib",
      "version": "1.0.5",
      "description": "A pure and powerful JavaScript MetaverseChain (mvc) library.",
      "author": "zyoyoung <ouyangzhiying@showpay.top>",
      "ide": true,
      "main": "index.js",
      "scripts": {
        "lint": "standard",
        "test": "standard && mocha",
        "coverage": "nyc --reporter=text npm run test",
        "build-mvc": "webpack index.js --config webpack.config.js",
        "build-ecies": "webpack ecies/index.js --config webpack.subproject.config.js --output-library mvcEcies -o mvc-ecies.min.js",
        "build-message": "webpack message/index.js --config webpack.subproject.config.js --output-library mvcMessage -o mvc-message.min.js",
        "build-mnemonic": "webpack mnemonic/index.js --config webpack.subproject.config.js --output-library mvcMnemonic -o mvc-mnemonic.min.js",
        "build": "yarn build-mvc && yarn build-ecies && yarn build-message && yarn build-mnemonic",
        "prepublishOnly": "yarn build"
      },
      "unpkg": "mvc.min.js",
      "keywords": [
        "mvc",
        "metaversechain",
        "transaction",
        "address",
        "p5p",
        "ecies",
        "cryptocurrency",
        "blockchain",
        "payment",
        "bip21",
        "bip32",
        "bip37",
        "bip69",
        "bip70",
        "multisig"
      ],
      "repository": {
        "type": "git",
        "url": "https://github.com/MetaverseChain/mvc-lib-js"
      },
      "browser": {
        "request": "browser-request"
      },
      "dependencies": {
        "aes-js": "^3.1.2",
        "bn.js": "=4.11.9",
        "bs58": "=4.0.1",
        "clone-deep": "^4.0.1",
        "elliptic": "6.5.4",
        "hash.js": "^1.1.7",
        "inherits": "2.0.3",
        "unorm": "1.4.1"
      },
      "devDependencies": {
        "brfs": "2.0.1",
        "chai": "4.2.0",
        "mocha": "^8.4.0",
        "nyc": "^14.1.1",
        "sinon": "7.2.3",
        "standard": "12.0.1",
        "webpack": "4.29.3",
        "webpack-cli": "^3.3.12"
      },
      "license": "MIT",
      "standard": {
        "globals": [
          "afterEach",
          "beforeEach",
          "describe",
          "it"
        ],
        "ignore": [
          "dist/**"
        ]
      }
    }
    
    },{}],278:[function(require,module,exports){
    "use strict";
    var __assign = (this && this.__assign) || function () {
        __assign = Object.assign || function(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                    t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ABICoder = exports.FunctionCall = void 0;
    var utils_1 = require("./utils");
    var contract_1 = require("./contract");
    var scryptTypes_1 = require("./scryptTypes");
    var compilerWrapper_1 = require("./compilerWrapper");
    var FunctionCall = /** @class */ (function () {
        function FunctionCall(methodName, binding) {
            this.methodName = methodName;
            this.args = [];
            if (binding.lockingScript === undefined && binding.unlockingScript === undefined) {
                throw new Error('param binding.lockingScript & binding.unlockingScript cannot both be empty');
            }
            this.contract = binding.contract;
            this.args = binding.args;
            if (binding.lockingScript) {
                this._lockingScript = binding.lockingScript;
            }
            if (binding.unlockingScript) {
                this._unlockingScript = binding.unlockingScript;
            }
        }
        Object.defineProperty(FunctionCall.prototype, "unlockingScript", {
            get: function () {
                return this._unlockingScript;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(FunctionCall.prototype, "lockingScript", {
            get: function () {
                return this._lockingScript;
            },
            set: function (s) {
                this._lockingScript = s;
            },
            enumerable: false,
            configurable: true
        });
        FunctionCall.prototype.toASM = function () {
            return this.toScript().toASM();
        };
        FunctionCall.prototype.toString = function () {
            return this.toHex();
        };
        FunctionCall.prototype.toScript = function () {
            if (this.lockingScript) {
                return this.lockingScript;
            }
            else {
                return this.unlockingScript;
            }
        };
        FunctionCall.prototype.toHex = function () {
            return this.toScript().toHex();
        };
        FunctionCall.prototype.genLaunchConfig = function (txContext) {
            var constructorArgs = this.contract.ctorArgs().map(function (p) { return p.value; });
            var pubFuncArgs = this.args.map(function (arg) { return arg.value; });
            var pubFunc = this.methodName;
            var name = "Debug " + this.contract.contractName;
            var program = "" + this.contract.file;
            var asmArgs = this.contract.asmArgs || {};
            var state = !contract_1.AbstractContract.isStateful(this.contract) && this.contract.dataPart ? this.contract.dataPart.toASM() : undefined;
            var txCtx = Object.assign({}, this.contract.txContext || {}, txContext || {}, { opReturn: state });
            if (contract_1.AbstractContract.isStateful(this.contract)) {
                Object.assign(txCtx, { opReturnHex: this.contract.dataPart.toHex() });
            }
            else if (this.contract.dataPart) {
                Object.assign(txCtx, { opReturn: this.contract.dataPart.toASM() });
            }
            return utils_1.genLaunchConfigFile(constructorArgs, pubFuncArgs, pubFunc, name, program, txCtx, asmArgs);
        };
        FunctionCall.prototype.verify = function (txContext) {
            var result = this.contract.run_verify(this.unlockingScript.toASM() || '', txContext);
            if (!result.success) {
                var debugUrl = this.genLaunchConfig(txContext);
                if (debugUrl) {
                    result.error = result.error + ("\t[Launch Debugger](" + debugUrl.replace(/file:/i, 'scryptlaunch:') + ")\n");
                }
            }
            return result;
        };
        return FunctionCall;
    }());
    exports.FunctionCall = FunctionCall;
    var ABICoder = /** @class */ (function () {
        function ABICoder(abi, resolver) {
            this.abi = abi;
            this.resolver = resolver;
        }
        ABICoder.prototype.checkArgs = function (contractname, funname, params) {
            var _this = this;
            var args = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                args[_i - 3] = arguments[_i];
            }
            if (args.length !== params.length) {
                throw new Error("wrong number of arguments for '" + contractname + "." + funname + "', expected " + params.length + " but got " + args.length);
            }
            params.forEach(function (param, index) {
                var arg = args[index];
                var error = utils_1.checkSupportedParamType(arg, param, _this.resolver.resolverType);
                if (error)
                    throw error;
            });
        };
        ABICoder.prototype.encodeConstructorCall = function (contract, hexTemplate) {
            var _this = this;
            var args = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                args[_i - 2] = arguments[_i];
            }
            var constructorABI = this.abi.filter(function (entity) { return entity.type === compilerWrapper_1.ABIEntityType.CONSTRUCTOR; })[0];
            var cParams = (constructorABI === null || constructorABI === void 0 ? void 0 : constructorABI.params) || [];
            this.checkArgs.apply(this, __spread([contract.contractName, 'constructor', cParams], args));
            // handle array type
            var flatteredArgs = utils_1.flatternCtorArgs(cParams.map(function (p, index) {
                return Object.assign(__assign({}, p), {
                    value: args[index],
                });
            }), this.resolver.resolverType);
            flatteredArgs.forEach(function (arg) {
                if (!hexTemplate.includes("<" + arg.name + ">")) {
                    throw new Error("abi constructor params mismatch with args provided: missing " + arg.name + " in ASM tempalte");
                }
                contract.hexTemplateArgs.set("<" + arg.name + ">", _this.encodeParam(arg.value, arg));
            });
            contract.hexTemplateArgs.set('<__codePart__>', '00');
            contract.statePropsArgs = utils_1.buildDefaultStateProps(contract);
            var lockingScript = utils_1.buildContractCode(contract.hexTemplateArgs, contract.hexTemplateInlineASM, hexTemplate);
            return new FunctionCall('constructor', {
                contract: contract,
                lockingScript: lockingScript,
                args: cParams.map(function (param, index) { return ({
                    name: param.name,
                    type: param.type,
                    value: args[index],
                }); }),
            });
        };
        ABICoder.prototype.encodeConstructorCallFromRawHex = function (contract, hexTemplate, raw) {
            var script = utils_1.mvc.Script.fromHex(raw);
            var constructorABI = this.abi.filter(function (entity) { return entity.type === compilerWrapper_1.ABIEntityType.CONSTRUCTOR; })[0];
            var cParams = (constructorABI === null || constructorABI === void 0 ? void 0 : constructorABI.params) || [];
            var offset = 0;
            var dataPartInHex = undefined;
            for (var index = 0; index < script.chunks.length; index++) {
                var chunk = script.chunks[index];
                if (offset >= hexTemplate.length && chunk.opcodenum == 106 /*OP_RETURN*/) {
                    var b = utils_1.mvc.Script.fromChunks(script.chunks.slice(index + 1));
                    dataPartInHex = b.toHex();
                    break;
                }
                else if (hexTemplate.charAt(offset) == '<') {
                    var start = offset;
                    var found = false;
                    while (!found && offset < hexTemplate.length) {
                        offset++;
                        if (hexTemplate.charAt(offset) == '>') {
                            offset++;
                            found = true;
                        }
                    }
                    if (!found) {
                        throw new Error('cannot found break >');
                    }
                    var name_1 = hexTemplate.substring(start, offset);
                    var bw = new utils_1.mvc.encoding.BufferWriter();
                    bw.writeUInt8(chunk.opcodenum);
                    if (chunk.buf) {
                        if (chunk.opcodenum < utils_1.mvc.Opcode.OP_PUSHDATA1) {
                            bw.write(chunk.buf);
                        }
                        else if (chunk.opcodenum === utils_1.mvc.Opcode.OP_PUSHDATA1) {
                            bw.writeUInt8(chunk.len);
                            bw.write(chunk.buf);
                        }
                        else if (chunk.opcodenum === utils_1.mvc.Opcode.OP_PUSHDATA2) {
                            bw.writeUInt16LE(chunk.len);
                            bw.write(chunk.buf);
                        }
                        else if (chunk.opcodenum === utils_1.mvc.Opcode.OP_PUSHDATA4) {
                            bw.writeUInt32LE(chunk.len);
                            bw.write(chunk.buf);
                        }
                    }
                    if (name_1.startsWith("<" + contract.contractName + ".")) {
                        //inline asm
                        contract.hexTemplateInlineASM.set(name_1, bw.toBuffer().toString('hex'));
                    }
                    else {
                        contract.hexTemplateArgs.set(name_1, bw.toBuffer().toString('hex'));
                    }
                }
                else {
                    var op = hexTemplate.substring(offset, offset + 2);
                    offset = offset + 2;
                    if (parseInt(op, 16) != chunk.opcodenum) {
                        throw new Error("the raw script cannot match the ASM template of contract " + contract.contractName);
                    }
                    if (chunk.len > 0) {
                        var data = hexTemplate.substring(offset, offset + chunk.len * 2);
                        if (chunk.buf.toString('hex') != data) {
                            throw new Error("the raw script cannot match the ASM template of contract " + contract.contractName);
                        }
                        offset = offset + chunk.len * 2;
                    }
                }
            }
            var ctorArgs = cParams.map(function (param) {
                return utils_1.deserializeArgfromHex(contract.resolver, Object.assign(param, {
                    value: undefined,
                }), contract.hexTemplateArgs);
            });
            if (contract_1.AbstractContract.isStateful(contract)) {
                var scriptHex = dataPartInHex;
                var metaScript = dataPartInHex.substr(scriptHex.length - 10, 10);
                var version = utils_1.bin2num(metaScript.substr(metaScript.length - 2, 2));
                switch (version) {
                    case 0:
                        {
                            var _a = __read(utils_1.parseStateHex(contract, scriptHex), 2), firstCall = _a[0], args = _a[1];
                            contract.statePropsArgs = args;
                            contract.firstCall = firstCall;
                        }
                        break;
                }
            }
            else if (dataPartInHex) {
                contract.setDataPartInHex(dataPartInHex);
            }
            return new FunctionCall('constructor', { contract: contract, lockingScript: script, args: ctorArgs });
        };
        ABICoder.prototype.encodePubFunctionCall = function (contract, name, args) {
            var e_1, _a;
            var _this = this;
            try {
                for (var _b = __values(this.abi), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var entity = _c.value;
                    if (entity.name === name) {
                        this.checkArgs.apply(this, __spread([contract.contractName, name, entity.params], args));
                        var hex = this.encodeParams(args, entity.params.map(function (p) { return ({
                            name: p.name,
                            type: _this.resolver.resolverType(p.type).finalType,
                        }); }));
                        if (this.abi.length > 2 && entity.index !== undefined) {
                            // selector when there are multiple public functions
                            var pubFuncIndex = entity.index;
                            hex += "" + utils_1.mvc.Script.fromASM(utils_1.int2Asm(pubFuncIndex.toString())).toHex();
                        }
                        return new FunctionCall(name, {
                            contract: contract,
                            unlockingScript: utils_1.mvc.Script.fromHex(hex),
                            args: entity.params.map(function (param, index) { return ({
                                name: param.name,
                                type: param.type,
                                value: args[index],
                            }); }),
                        });
                    }
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                }
                finally { if (e_1) throw e_1.error; }
            }
            throw new Error("no public function named '" + name + "' found in contract '" + contract.contractName + "'");
        };
        /**
         * build a FunctionCall by function name and unlocking script in hex.
         * @param contract
         * @param name name of public function
         * @param hex hex of unlocking script
         * @returns a FunctionCall which contains the function parameters that have been deserialized
         */
        ABICoder.prototype.encodePubFunctionCallFromHex = function (contract, name, hex) {
            var script = utils_1.mvc.Script.fromHex(hex);
            var entity = this.abi.filter(function (entity) { return entity.type === 'function' && entity.name === name; })[0];
            if (!entity) {
                throw new Error("no public function named '" + name + "' found in contract '" + contract.contractName + "'");
            }
            var cParams = (entity === null || entity === void 0 ? void 0 : entity.params) || [];
            var flatternArgs = utils_1.flatternParams(cParams, contract.resolver);
            var fArgsLen = flatternArgs.length;
            if (this.abi.length > 2 && entity.index !== undefined) {
                fArgsLen += 1;
            }
            var usASM = script.toASM();
            var asmOpcodes = usASM.split(' ');
            if (fArgsLen != asmOpcodes.length) {
                throw new Error("the raw unlockingScript cannot match the arguments of public function " + name + " of contract " + contract.contractName);
            }
            var hexTemplateArgs = new Map();
            flatternArgs.forEach(function (farg, index) {
                hexTemplateArgs.set("<" + farg.name + ">", utils_1.mvc.Script.fromASM(asmOpcodes[index]).toHex());
            });
            var args = cParams.map(function (param) {
                return utils_1.deserializeArgfromHex(contract.resolver, Object.assign(param, {
                    value: undefined,
                }), hexTemplateArgs);
            });
            return new FunctionCall(name, { contract: contract, unlockingScript: script, args: args });
        };
        ABICoder.prototype.encodeParams = function (args, paramsEntitys) {
            var _this = this;
            return args.map(function (arg, i) { return _this.encodeParam(arg, paramsEntitys[i]); }).join('');
        };
        ABICoder.prototype.encodeParamArray = function (args, arrayParam) {
            var _this = this;
            return utils_1.flatternArray(args, arrayParam.name, arrayParam.type)
                .map(function (arg) {
                return _this.encodeParam(arg.value, { name: arg.name, type: _this.resolver.resolverType(arg.type).finalType });
            })
                .join('');
        };
        ABICoder.prototype.encodeParam = function (arg, paramEntity) {
            if (utils_1.isArrayType(paramEntity.type)) {
                return this.encodeParamArray(arg, paramEntity);
            }
            if (arg instanceof scryptTypes_1.ScryptType) {
                return arg.toHex();
            }
            var typeofArg = typeof arg;
            if (typeofArg === 'boolean') {
                arg = new scryptTypes_1.Bool(arg);
            }
            else if (typeofArg === 'number') {
                arg = new scryptTypes_1.Int(arg);
            }
            else if (typeofArg === 'bigint') {
                arg = new scryptTypes_1.Int(arg);
            }
            else if (typeof arg === 'string') {
                arg = new scryptTypes_1.Int(arg);
            }
            else {
                //we call checkArg before encodeParam, shouldn't get here under normal circumstances
                throw new Error("The value of parameter " + paramEntity.name + " is unknown type: " + typeofArg);
            }
            return arg.toHex();
        };
        return ABICoder;
    }());
    exports.ABICoder = ABICoder;
    
    },{"./compilerWrapper":279,"./contract":280,"./scryptTypes":285,"./utils":287}],279:[function(require,module,exports){
    "use strict";
    var __assign = (this && this.__assign) || function () {
        __assign = Object.assign || function(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                    t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    var __generator = (this && this.__generator) || function (thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    };
    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.loadSourceMapfromDesc = exports.getStaticDeclaration = exports.getAliasDeclaration = exports.getContractDeclaration = exports.getLibraryDeclaration = exports.getStructDeclaration = exports.getABIDeclaration = exports.getContractName = exports.getFullFilePath = exports.compilerVersion = exports.handleCompilerOutput = exports.compile = exports.settings2cmd = exports.compileAsync = exports.doCompileAsync = exports.ABIEntityType = exports.DebugModeTag = exports.CompileResult = exports.BuildType = exports.CompileErrorType = exports.SOURCE_REG = void 0;
    var path_1 = require("path");
    var child_process_1 = require("child_process");
    var fs_1 = require("fs");
    var md5 = require("md5");
    var rimraf = require("rimraf");
    var JSONbig = require("json-bigint");
    var internal_1 = require("./internal");
    var SYNTAX_ERR_REG = /(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):\n([^\n]+\n){3}(unexpected (?<unexpected>[^\n]+)\nexpecting (?<expecting>[^\n]+)|(?<message>[^\n]+))/g;
    var SEMANTIC_ERR_REG = /Error:(\s|\n)*(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+):*\n(?<message>[^\n]+)\n/g;
    var INTERNAL_ERR_REG = /Internal error:(?<message>.+)/;
    var WARNING_REG = /Warning:(\s|\n)*(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+):*\n(?<message>[^\n]+)\n/g;
    var JSONbigAlways = JSONbig({ alwaysParseAsBig: true, constructorAction: 'preserve' });
    //SOURCE_REG parser src eg: [0:6:3:8:4#Bar.constructor:0]
    exports.SOURCE_REG = /^(?<fileIndex>-?\d+):(?<line>\d+):(?<col>\d+):(?<endLine>\d+):(?<endCol>\d+)(#(?<tagStr>.+))?/;
    var RELATED_INFORMATION_REG = /(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+)/gi;
    // see VERSIONLOG.md
    var CompileErrorType;
    (function (CompileErrorType) {
        CompileErrorType["SyntaxError"] = "SyntaxError";
        CompileErrorType["SemanticError"] = "SemanticError";
        CompileErrorType["InternalError"] = "InternalError";
        CompileErrorType["Warning"] = "Warning";
    })(CompileErrorType = exports.CompileErrorType || (exports.CompileErrorType = {}));
    var BuildType;
    (function (BuildType) {
        BuildType["Debug"] = "debug";
        BuildType["Release"] = "release";
    })(BuildType = exports.BuildType || (exports.BuildType = {}));
    var CompileResult = /** @class */ (function () {
        function CompileResult(errors, warnings) {
            this.errors = errors;
            this.warnings = warnings;
        }
        CompileResult.prototype.toDesc = function () {
            var description = {
                version: internal_1.CURRENT_CONTRACT_DESCRIPTION_VERSION,
                compilerVersion: this.compilerVersion || '0.0.0',
                contract: this.contract || '',
                md5: this.md5 || '',
                structs: this.structs || [],
                library: this.library || [],
                alias: this.alias || [],
                abi: this.abi || [],
                stateProps: this.stateProps || [],
                buildType: this.buildType || BuildType.Debug,
                file: this.file || '',
                hex: this.hex || '',
                asm: '',
                sourceMap: [],
                sources: [],
                sourceMapFile: this.sourceMapFile || '',
            };
            return description;
        };
        return CompileResult;
    }());
    exports.CompileResult = CompileResult;
    var DebugModeTag;
    (function (DebugModeTag) {
        DebugModeTag["FuncStart"] = "F0";
        DebugModeTag["FuncEnd"] = "F1";
        DebugModeTag["LoopStart"] = "L0";
    })(DebugModeTag = exports.DebugModeTag || (exports.DebugModeTag = {}));
    var ABIEntityType;
    (function (ABIEntityType) {
        ABIEntityType["FUNCTION"] = "function";
        ABIEntityType["CONSTRUCTOR"] = "constructor";
    })(ABIEntityType = exports.ABIEntityType || (exports.ABIEntityType = {}));
    function toOutputDir(descDir, sourcePath) {
        return path_1.join(descDir, path_1.basename(sourcePath) + '-' + internal_1.hash160(sourcePath, 'utf-8').substring(0, 10));
    }
    function doCompileAsync(source, settings, callback) {
        var sourcePath = source.path;
        var srcDir = path_1.dirname(sourcePath);
        var curWorkingDir = settings.cwd || srcDir;
        var timeout = settings.timeout || 1200000;
        var sourceContent = source.content !== undefined ? source.content : fs_1.readFileSync(sourcePath, 'utf8');
        var cmd = settings2cmd(sourcePath, settings);
        var childProcess = child_process_1.exec(cmd, { cwd: curWorkingDir, timeout: timeout, killSignal: 'SIGKILL' }, function (error, stdout) {
            if (error) {
                console.error("exec error: " + error);
                callback(error, null);
                return;
            }
            callback(null, {
                path: sourcePath,
                output: stdout,
                md5: md5(sourceContent),
            });
        });
        childProcess.stdin.write(sourceContent, function (error) {
            if (error) {
                callback(error, null);
                return;
            }
            childProcess.stdin.end();
        });
        return childProcess;
    }
    exports.doCompileAsync = doCompileAsync;
    function compileAsync(source, settings) {
        var _this = this;
        settings = Object.assign({}, defaultCompilingSettings, settings);
        return new Promise(function (resolve, reject) {
            doCompileAsync(source, settings, function (error, data) { return __awaiter(_this, void 0, void 0, function () {
                var result;
                return __generator(this, function (_a) {
                    if (error) {
                        reject(error);
                        return [2 /*return*/];
                    }
                    try {
                        result = handleCompilerOutput(source.path, settings, data.output, data.md5);
                        resolve(result);
                    }
                    catch (error) {
                        reject(error);
                    }
                    return [2 /*return*/];
                });
            }); });
        });
    }
    exports.compileAsync = compileAsync;
    var defaultCompilingSettings = {
        ast: true,
        asm: false,
        hex: true,
        debug: false,
        desc: false,
        outputDir: '',
        outputToFiles: false,
        cwd: '',
        cmdPrefix: '',
        cmdArgs: '',
        buildType: BuildType.Debug,
        stdout: false,
        sourceMap: false,
        timeout: 1200000,
    };
    function settings2cmd(sourcePath, settings) {
        var srcDir = path_1.dirname(sourcePath);
        //dir that store desc file
        var descDir = settings.outputDir || srcDir;
        //dir that store ast,asm file
        var outputDir = toOutputDir(descDir, sourcePath);
        var cmdPrefix = settings.cmdPrefix || internal_1.findCompiler();
        var outOption = "-o \"" + outputDir + "\"";
        if (settings.stdout) {
            outOption = '--stdout';
            return cmdPrefix + " compile " + (settings.asm || settings.desc ? '--asm' : '') + " " + (settings.hex ? '--hex' : '') + " " + (settings.ast || settings.desc ? '--ast' : '') + " " + (settings.debug == true ? '--debug' : '') + " -r " + outOption + " " + (settings.cmdArgs ? settings.cmdArgs : '');
        }
        else {
            if (!fs_1.existsSync(outputDir)) {
                fs_1.mkdirSync(outputDir);
            }
        }
        return cmdPrefix + " compile " + (settings.hex ? '--hex' : '') + " " + (settings.ast || settings.desc ? '--ast' : '') + " " + (settings.debug == true ? '--debug' : '--optimize') + " " + (settings.sourceMap == true ? '--source-map' : '') + " -r " + outOption + " " + (settings.cmdArgs ? settings.cmdArgs : '');
    }
    exports.settings2cmd = settings2cmd;
    function compile(source, settings) {
        var sourcePath = source.path;
        var srcDir = path_1.dirname(sourcePath);
        //dir that store desc file
        var curWorkingDir = settings.cwd || srcDir;
        settings = Object.assign({}, defaultCompilingSettings, settings);
        var sourceContent = source.content !== undefined ? source.content : fs_1.readFileSync(sourcePath, 'utf8');
        var maxBuffer = settings.stdout ? 1024 * 1024 * 100 : 1024 * 1024;
        settings = Object.assign({}, defaultCompilingSettings, settings);
        var cmd = settings2cmd(sourcePath, settings);
        var output = child_process_1.execSync(cmd, {
            input: sourceContent,
            cwd: curWorkingDir,
            timeout: settings.timeout,
            maxBuffer: maxBuffer,
        }).toString();
        return handleCompilerOutput(sourcePath, settings, output, md5(sourceContent));
    }
    exports.compile = compile;
    function handleCompilerOutput(sourcePath, settings, output, md5) {
        var srcDir = path_1.dirname(sourcePath);
        var sourceFileName = path_1.basename(sourcePath);
        var descDir = settings.outputDir || srcDir;
        var outputDir = toOutputDir(descDir, sourcePath);
        var outputFiles = {};
        try {
            // Because the output of the compiler on the win32 platform uses crlf as a newline， here we change \r\n to \n. make SYNTAX_ERR_REG、SEMANTIC_ERR_REG、IMPORT_ERR_REG work.
            output = output.split(/\r?\n/g).join('\n');
            var result = new CompileResult([], []);
            result.compilerVersion = compilerVersion(settings.cmdPrefix ? settings.cmdPrefix : internal_1.findCompiler());
            result.md5 = md5;
            if (output.startsWith('Error:') || output.startsWith('Warning:')) {
                Object.assign(result, getErrorsAndWarnings(output, srcDir, sourceFileName));
                if (result.errors.length > 0) {
                    return result;
                }
                if (settings.stdout && result.warnings.length > 0) {
                    // stdout not allowed warnings
                    return result;
                }
            }
            if (settings.stdout) {
                var stdout = JSONbigAlways.parse(output);
                parserAst(result, stdout.ast, srcDir, sourceFileName, sourcePath);
                parserASM(result, stdout.asm, settings, srcDir, sourceFileName);
            }
            else {
                if (settings.ast || settings.desc) {
                    var outputFilePath = getOutputFilePath(outputDir, 'ast');
                    var astFile = outputFilePath.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                    fs_1.renameSync(outputFilePath, astFile);
                    outputFiles['ast'] = astFile;
                    var ast = JSONbigAlways.parse(fs_1.readFileSync(astFile, 'utf8'));
                    parserAst(result, ast, srcDir, sourceFileName, sourcePath);
                }
                if (settings.hex || settings.desc) {
                    var outputFilePath = getOutputFilePath(outputDir, 'hex');
                    var hexFile = outputFilePath.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                    fs_1.renameSync(outputFilePath, hexFile);
                    outputFiles['hex'] = hexFile;
                    result.hex = fs_1.readFileSync(hexFile, 'utf8');
                }
                if (settings.sourceMap) {
                    var outputFilePath = getOutputFilePath(outputDir, 'map');
                    if (settings.desc) {
                        var dist = getOutputFilePath(descDir, 'map');
                        var sourceMapFile = dist.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                        fs_1.renameSync(outputFilePath, sourceMapFile);
                        result.sourceMapFile = internal_1.path2uri(sourceMapFile);
                    }
                    else {
                        var sourceMapFile = outputFilePath.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                        fs_1.renameSync(outputFilePath, sourceMapFile);
                        outputFiles['map'] = sourceMapFile;
                        result.sourceMapFile = internal_1.path2uri(sourceMapFile);
                    }
                }
                if (settings.debug) {
                    var outputFilePath = getOutputFilePath(outputDir, 'dbg');
                    var dbgFile = outputFilePath.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                    fs_1.renameSync(outputFilePath, dbgFile);
                    result.dbgFile = internal_1.path2uri(dbgFile);
                }
                if (settings.desc) {
                    var outputFilePath = getOutputFilePath(descDir, 'desc');
                    var descFile = outputFilePath.replace('stdin', path_1.basename(sourcePath, '.scrypt'));
                    var description = result.toDesc();
                    fs_1.writeFileSync(descFile, JSON.stringify(description, function (key, value) {
                        //ignore deprecated fields
                        if (key == 'sources' || key == 'sourceMap' || key === 'asm')
                            return undefined;
                        else
                            return value;
                    }, 4));
                }
            }
            return result;
        }
        finally {
            doClean(settings, outputFiles, outputDir, sourcePath);
        }
    }
    exports.handleCompilerOutput = handleCompilerOutput;
    function compilerVersion(cwd) {
        try {
            var text = child_process_1.execSync(cwd + " version").toString();
            return /Version:\s*([^\s]+)\s*/.exec(text)[1];
        }
        catch (e) {
            throw new Error("compilerVersion fail when run: " + cwd + " version");
        }
    }
    exports.compilerVersion = compilerVersion;
    function addSourceLocation(astRoot, basePath, curFileName) {
        for (var fileName in astRoot) {
            if (fileName === 'std') {
                astRoot['std'] = _addSourceLocationProperty(astRoot['std'], 'std');
            }
            else {
                var realFileName = fileName === 'stdin' ? curFileName : fileName;
                var uri = internal_1.path2uri(path_1.join(basePath, realFileName));
                astRoot[uri] = _addSourceLocationProperty(astRoot[fileName], uri);
                delete astRoot[fileName];
            }
        }
        return astRoot;
    }
    function _addSourceLocationProperty(astObj, uri) {
        if (!(typeof astObj === 'object')) {
            return astObj;
        }
        for (var field in astObj) {
            var value = astObj[field];
            if (field === 'src') {
                var matches = /:(\d+):(\d+):(\d+):(\d+)/.exec(value);
                if (!matches) {
                    astObj.loc = null;
                }
                else {
                    astObj.loc = {
                        source: uri,
                        start: { line: parseInt(matches[1]), column: parseInt(matches[2]) },
                        end: { line: parseInt(matches[3]), column: parseInt(matches[4]) },
                    };
                }
                delete astObj['src'];
            }
            else if (typeof value === 'object') {
                _addSourceLocationProperty(value, uri);
            }
        }
        return astObj;
    }
    function getOutputFilePath(baseDir, target) {
        if (target == 'hex') {
            return path_1.join(baseDir, "stdin_" + target + ".txt");
        }
        else if (target === 'map') {
            return path_1.join(baseDir, "stdin." + target + ".json");
        }
        else if (target === 'dbg') {
            return path_1.join(baseDir, "stdin." + target + ".json");
        }
        return path_1.join(baseDir, "stdin_" + target + ".json");
    }
    function getFullFilePath(relativePath, baseDir, curFileName) {
        if (relativePath.endsWith('stdin')) {
            return path_1.join(baseDir, curFileName); // replace 'stdin' with real current compiling file name.
        }
        if (relativePath === 'std') {
            return 'std'; //
        }
        return path_1.join(baseDir, relativePath);
    }
    exports.getFullFilePath = getFullFilePath;
    function getConstructorDeclaration(mainContract) {
        // explict constructor
        if (mainContract['constructor']) {
            return {
                type: ABIEntityType.CONSTRUCTOR,
                params: mainContract['constructor']['params'].map(function (p) {
                    return { name: p['name'], type: p['type'] };
                }),
            };
        }
        else {
            // implicit constructor
            if (mainContract['properties']) {
                return {
                    type: ABIEntityType.CONSTRUCTOR,
                    params: mainContract['properties'].map(function (p) {
                        return { name: p['name'].replace('this.', ''), type: p['type'] };
                    }),
                };
            }
        }
    }
    function getStateProps(astRoot) {
        var mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
        if (mainContract && mainContract['properties']) {
            return mainContract['properties']
                .filter(function (p) { return p.state; })
                .map(function (p) {
                return { name: p['name'].replace('this.', ''), type: p['type'] };
            });
        }
        return [];
    }
    function getPublicFunctionDeclaration(mainContract) {
        var pubIndex = 0;
        var interfaces = mainContract['functions']
            .filter(function (f) { return f['visibility'] === 'Public'; })
            .map(function (f) {
            var entity = {
                type: ABIEntityType.FUNCTION,
                name: f['name'],
                index: f['nodeType'] === 'Constructor' ? undefined : pubIndex++,
                params: f['params'].map(function (p) {
                    return { name: p['name'], type: p['type'] };
                }),
            };
            return entity;
        });
        return interfaces;
    }
    function getContractName(astRoot) {
        var mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
        if (!mainContract) {
            return '';
        }
        return mainContract['name'] || '';
    }
    exports.getContractName = getContractName;
    function shortGenericType(genericType) {
        var m = genericType.match(/__SCRYPT_(\w+)__/);
        if (m) {
            return m[1];
        }
        return genericType;
    }
    /**
     *
     * @param astRoot AST root node after main contract compilation
     * @param typeResolver a Type Resolver
     * @returns All function ABIs defined by the main contract, including constructors
     */
    function getABIDeclaration(astRoot, typeResolver) {
        var mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
        if (!mainContract) {
            return {
                contract: '',
                abi: [],
            };
        }
        var interfaces = getPublicFunctionDeclaration(mainContract);
        var constructorABI = getConstructorDeclaration(mainContract);
        interfaces.push(constructorABI);
        interfaces.forEach(function (abi) {
            abi.params = abi.params.map(function (param) {
                return Object.assign(param, {
                    type: typeResolver(param.type).finalType,
                });
            });
        });
        return {
            contract: getContractName(astRoot),
            abi: interfaces,
        };
    }
    exports.getABIDeclaration = getABIDeclaration;
    /**
     *
     * @param astRoot AST root node after main contract compilation
     * @param dependencyAsts AST root node after all dependency contract compilation
     * @returns all defined structures of the main contract and dependent contracts
     */
    function getStructDeclaration(astRoot, dependencyAsts) {
        var allAst = [astRoot];
        Object.keys(dependencyAsts).forEach(function (key) {
            allAst.push(dependencyAsts[key]);
        });
        return allAst
            .map(function (ast) {
            return (ast['structs'] || []).map(function (s) { return ({
                name: s['name'],
                params: s['fields'].map(function (p) {
                    return { name: p['name'], type: p['type'] };
                }),
                genericTypes: s.genericTypes || [],
            }); });
        })
            .flat(1);
    }
    exports.getStructDeclaration = getStructDeclaration;
    /**
     *
     * @param astRoot AST root node after main contract compilation
     * @param dependencyAsts AST root node after all dependency contract compilation
     * @returns all defined Library of the main contract and dependent contracts
     */
    function getLibraryDeclaration(astRoot, dependencyAsts) {
        var allAst = [astRoot];
        Object.keys(dependencyAsts).forEach(function (key) {
            if (key !== 'std') {
                allAst.push(dependencyAsts[key]);
            }
        });
        return allAst
            .map(function (ast) {
            return (ast['contracts'] || [])
                .filter(function (c) { return c.nodeType == 'Library'; })
                .map(function (c) {
                if (c['constructor']) {
                    return {
                        name: c.name,
                        params: c['constructor']['params'].map(function (p) {
                            return { name: "ctor." + p['name'], type: p['type'] };
                        }),
                        properties: c['properties'].map(function (p) {
                            return { name: p['name'], type: p['type'] };
                        }),
                        genericTypes: c.genericTypes || [],
                    };
                }
                else {
                    // implicit constructor
                    if (c['properties']) {
                        return {
                            name: c.name,
                            params: c['properties'].map(function (p) {
                                return { name: p['name'], type: p['type'] };
                            }),
                            properties: c['properties'].map(function (p) {
                                return { name: p['name'], type: p['type'] };
                            }),
                            genericTypes: c.genericTypes || [],
                        };
                    }
                }
            });
        })
            .flat(1);
    }
    exports.getLibraryDeclaration = getLibraryDeclaration;
    function getContractDeclaration(astRoot, dependencyAsts) {
        var allAst = [astRoot];
        Object.keys(dependencyAsts).forEach(function (key) {
            if (key !== 'std') {
                allAst.push(dependencyAsts[key]);
            }
        });
        return allAst
            .map(function (ast) {
            return (ast['contracts'] || [])
                .filter(function (c) { return c.nodeType == 'Contract'; })
                .map(function (c) {
                if (c['constructor']) {
                    return {
                        name: c.name,
                        params: c['constructor']['params'].map(function (p) {
                            return { name: "ctor." + p['name'], type: p['type'] };
                        }),
                        properties: c['properties'].map(function (p) {
                            return { name: p['name'], type: p['type'] };
                        }),
                        genericTypes: c.genericTypes || [],
                    };
                }
                else {
                    // implicit constructor
                    if (c['properties']) {
                        return {
                            name: c.name,
                            params: c['properties'].map(function (p) {
                                return { name: p['name'], type: p['type'] };
                            }),
                            properties: c['properties'].map(function (p) {
                                return { name: p['name'], type: p['type'] };
                            }),
                            genericTypes: c.genericTypes || [],
                        };
                    }
                }
            });
        })
            .flat(1);
    }
    exports.getContractDeclaration = getContractDeclaration;
    /**
     *
     * @param astRoot AST root node after main contract compilation
     * @param dependencyAsts AST root node after all dependency contract compilation
     * @returns all defined type aliaes of the main contract and dependent contracts
     */
    function getAliasDeclaration(astRoot, dependencyAsts) {
        var allAst = [astRoot];
        Object.keys(dependencyAsts).forEach(function (key) {
            allAst.push(dependencyAsts[key]);
        });
        return allAst
            .map(function (ast) {
            return (ast['alias'] || []).map(function (s) { return ({
                name: s['alias'],
                type: s['type'],
            }); });
        })
            .flat(1);
    }
    exports.getAliasDeclaration = getAliasDeclaration;
    /**
     *
     * @param astRoot AST root node after main contract compilation
     * @param dependencyAsts AST root node after all dependency contract compilation
     * @returns all defined static const int literal of the main contract and dependent contracts
     */
    function getStaticDeclaration(astRoot, dependencyAsts) {
        var allAst = [astRoot];
        Object.keys(dependencyAsts).forEach(function (key) {
            allAst.push(dependencyAsts[key]);
        });
        return allAst
            .map(function (ast) {
            return (ast['contracts'] || []).map(function (contract) {
                return (contract.statics || []).map(function (node) {
                    return {
                        const: node.const,
                        name: contract.name + "." + node.name,
                        type: node.type,
                        value: internal_1.resolveConstValue(node),
                    };
                });
            });
        })
            .flat(Infinity)
            .flat(1);
    }
    exports.getStaticDeclaration = getStaticDeclaration;
    function getRelatedInformation(message, srcDir, sourceFileName) {
        var _a, _b, _c, _d;
        var relatedInformation = [];
        var result;
        while ((result = RELATED_INFORMATION_REG.exec(message))) {
            var relatedFilePath = result.groups.filePath;
            if (relatedFilePath === 'null')
                continue;
            var fullFilePath = getFullFilePath(relatedFilePath, srcDir, sourceFileName);
            var line = parseInt(((_a = result.groups) === null || _a === void 0 ? void 0 : _a.line) || '-1');
            var column = parseInt(((_b = result.groups) === null || _b === void 0 ? void 0 : _b.column) || '-1');
            relatedInformation.push({
                filePath: fullFilePath,
                position: [
                    {
                        line: line,
                        column: column,
                    },
                    {
                        line: parseInt(((_c = result.groups) === null || _c === void 0 ? void 0 : _c.line1) || '-1'),
                        column: parseInt(((_d = result.groups) === null || _d === void 0 ? void 0 : _d.column1) || '-1'),
                    },
                ],
                message: '',
            });
            message = message.replace(/([^\s]+):(\d+):(\d+):(\d+):(\d+)/, '');
        }
        return {
            relatedInformation: relatedInformation,
            message: message,
        };
    }
    function getErrorsAndWarnings(output, srcDir, sourceFileName) {
        var _a;
        var warnings = __spread(output.matchAll(WARNING_REG)).map(function (match) {
            var _a, _b, _c, _d, _e, _f;
            var filePath = ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.filePath) || '';
            var origin_message = ((_b = match.groups) === null || _b === void 0 ? void 0 : _b.message) || '';
            var _g = getRelatedInformation(origin_message, srcDir, sourceFileName), message = _g.message, relatedInformation = _g.relatedInformation;
            return {
                type: CompileErrorType.Warning,
                filePath: getFullFilePath(filePath, srcDir, sourceFileName),
                position: [
                    {
                        line: parseInt(((_c = match.groups) === null || _c === void 0 ? void 0 : _c.line) || '-1'),
                        column: parseInt(((_d = match.groups) === null || _d === void 0 ? void 0 : _d.column) || '-1'),
                    },
                    {
                        line: parseInt(((_e = match.groups) === null || _e === void 0 ? void 0 : _e.line1) || '-1'),
                        column: parseInt(((_f = match.groups) === null || _f === void 0 ? void 0 : _f.column1) || '-1'),
                    },
                ],
                message: message,
                relatedInformation: relatedInformation,
            };
        });
        if (output.match(INTERNAL_ERR_REG)) {
            var errors = [
                {
                    type: CompileErrorType.InternalError,
                    filePath: getFullFilePath('stdin', srcDir, sourceFileName),
                    message: "Compiler internal error: " + (((_a = output.match(INTERNAL_ERR_REG).groups) === null || _a === void 0 ? void 0 : _a.message) || ''),
                    position: [
                        {
                            line: 1,
                            column: 1,
                        },
                        {
                            line: 1,
                            column: 1,
                        },
                    ],
                    relatedInformation: [],
                },
            ];
            return new CompileResult(errors, warnings);
        }
        else if (output.includes('Syntax error:')) {
            var syntaxErrors = __spread(output.matchAll(SYNTAX_ERR_REG)).map(function (match) {
                var _a, _b, _c, _d, _e, _f;
                var filePath = ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.filePath) || '';
                var unexpected = ((_b = match.groups) === null || _b === void 0 ? void 0 : _b.unexpected) || '';
                var expecting = ((_c = match.groups) === null || _c === void 0 ? void 0 : _c.expecting) || '';
                var origin_message = ((_d = match.groups) === null || _d === void 0 ? void 0 : _d.message) || "unexpected " + unexpected + "\nexpecting " + expecting;
                var _g = getRelatedInformation(origin_message, srcDir, sourceFileName), message = _g.message, relatedInformation = _g.relatedInformation;
                return {
                    type: CompileErrorType.SyntaxError,
                    filePath: getFullFilePath(filePath, srcDir, sourceFileName),
                    position: [
                        {
                            line: parseInt(((_e = match.groups) === null || _e === void 0 ? void 0 : _e.line) || '-1'),
                            column: parseInt(((_f = match.groups) === null || _f === void 0 ? void 0 : _f.column) || '-1'),
                        },
                    ],
                    message: message,
                    unexpected: unexpected,
                    expecting: expecting,
                    relatedInformation: relatedInformation,
                };
            });
            return new CompileResult(syntaxErrors, warnings);
        }
        else {
            var semanticErrors = __spread(output.matchAll(SEMANTIC_ERR_REG)).map(function (match) {
                var _a, _b, _c, _d, _e, _f;
                var origin_message = ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.message) || '';
                var filePath = ((_b = match.groups) === null || _b === void 0 ? void 0 : _b.filePath) || '';
                var _g = getRelatedInformation(origin_message, srcDir, sourceFileName), message = _g.message, relatedInformation = _g.relatedInformation;
                return {
                    type: CompileErrorType.SemanticError,
                    filePath: getFullFilePath(filePath, srcDir, sourceFileName),
                    position: [
                        {
                            line: parseInt(((_c = match.groups) === null || _c === void 0 ? void 0 : _c.line) || '-1'),
                            column: parseInt(((_d = match.groups) === null || _d === void 0 ? void 0 : _d.column) || '-1'),
                        },
                        {
                            line: parseInt(((_e = match.groups) === null || _e === void 0 ? void 0 : _e.line1) || '-1'),
                            column: parseInt(((_f = match.groups) === null || _f === void 0 ? void 0 : _f.column1) || '-1'),
                        },
                    ],
                    message: message,
                    relatedInformation: relatedInformation,
                };
            });
            return new CompileResult(semanticErrors, warnings);
        }
    }
    function parserAst(result, ast, srcDir, sourceFileName, sourcePath) {
        var allAst = addSourceLocation(ast, srcDir, sourceFileName);
        var sourceUri = internal_1.path2uri(sourcePath);
        result.file = sourceUri;
        result.ast = allAst[sourceUri];
        delete allAst[sourceUri];
        result.dependencyAsts = allAst;
        var alias = getAliasDeclaration(result.ast, allAst);
        var structs = getStructDeclaration(result.ast, allAst);
        var library = getLibraryDeclaration(result.ast, allAst);
        var statics = getStaticDeclaration(result.ast, allAst);
        result.contracts = getContractDeclaration(result.ast, allAst);
        var typeResolver = internal_1.buildTypeResolver(getContractName(result.ast), alias, structs, library, result.contracts, statics);
        result.alias = alias.map(function (a) { return ({
            name: a.name,
            type: typeResolver(a.type).finalType,
        }); });
        result.structs = structs.map(function (a) { return ({
            name: a.name,
            params: a.params.map(function (p) { return ({ name: p.name, type: typeResolver(p.type).finalType }); }),
            genericTypes: a.genericTypes.map(function (t) { return shortGenericType(t); }),
        }); });
        result.library = library.map(function (a) { return ({
            name: a.name,
            params: a.params.map(function (p) { return ({ name: p.name, type: typeResolver(p.type).finalType }); }),
            properties: a.properties.map(function (p) { return ({ name: p.name, type: typeResolver(p.type).finalType }); }),
            genericTypes: a.genericTypes.map(function (t) { return shortGenericType(t); }),
        }); });
        result.statics = statics.map(function (s) {
            return Object.assign(__assign({}, s), {
                type: typeResolver(s.type).finalType,
            });
        });
        var _a = getABIDeclaration(result.ast, typeResolver), name = _a.contract, abi = _a.abi;
        result.stateProps = getStateProps(result.ast).map(function (p) { return ({ name: p.name, type: typeResolver(p.type).finalType }); });
        result.abi = abi;
        result.contract = name;
    }
    /**
     * @deprecated use `--hex` when compiling
     * @param result
     * @param asmObj
     * @param settings
     * @param srcDir
     * @param sourceFileName
     */
    function parserASM(result, asmObj, settings, srcDir, sourceFileName) {
        var sources = asmObj.sources;
        if (settings.debug) {
            Object.assign(result, {
                file: result.file,
                sources: asmObj.sources.map(function (source) { return getFullFilePath(source, srcDir, sourceFileName); }),
                sourceMap: asmObj.output.map(function (item) { return item.src; }),
            });
        }
        result.hex = settings.hex ? asmObj.output.map(function (item) { return item.hex; }).join('') : '';
        result.asm = asmObj.output.map(function (item) {
            if (!settings.debug) {
                return {
                    opcode: item.opcode,
                };
            }
            var match = exports.SOURCE_REG.exec(item.src);
            if (match && match.groups) {
                var fileIndex = parseInt(match.groups.fileIndex);
                var debugInfo = void 0;
                var tagStr = match.groups.tagStr;
                var m = /^(\w+)\.(\w+):(\d)(#(?<context>.+))?$/.exec(tagStr);
                if (m) {
                    debugInfo = {
                        contract: m[1],
                        func: m[2],
                        tag: m[3] == '0' ? DebugModeTag.FuncStart : DebugModeTag.FuncEnd,
                        context: m.groups.context,
                    };
                }
                else if (/loop:0/.test(tagStr)) {
                    debugInfo = {
                        contract: '',
                        func: '',
                        tag: DebugModeTag.LoopStart,
                        context: '',
                    };
                }
                var pos = sources[fileIndex]
                    ? {
                        file: sources[fileIndex] ? getFullFilePath(sources[fileIndex], srcDir, sourceFileName) : undefined,
                        line: sources[fileIndex] ? parseInt(match.groups.line) : undefined,
                        endLine: sources[fileIndex] ? parseInt(match.groups.endLine) : undefined,
                        column: sources[fileIndex] ? parseInt(match.groups.col) : undefined,
                        endColumn: sources[fileIndex] ? parseInt(match.groups.endCol) : undefined,
                    }
                    : undefined;
                return {
                    opcode: item.opcode,
                    stack: item.stack,
                    topVars: item.topVars || [],
                    pos: pos,
                    debugInfo: debugInfo,
                };
            }
            throw new Error('Compile Failed: Asm output parsing Error!');
        });
        if (settings.debug) {
            result.autoTypedVars = asmObj.autoTypedVars.map(function (item) {
                var match = exports.SOURCE_REG.exec(item.src);
                if (match && match.groups) {
                    var fileIndex = parseInt(match.groups.fileIndex);
                    var pos = sources[fileIndex]
                        ? {
                            file: sources[fileIndex] ? getFullFilePath(sources[fileIndex], srcDir, sourceFileName) : undefined,
                            line: sources[fileIndex] ? parseInt(match.groups.line) : undefined,
                            endLine: sources[fileIndex] ? parseInt(match.groups.endLine) : undefined,
                            column: sources[fileIndex] ? parseInt(match.groups.col) : undefined,
                            endColumn: sources[fileIndex] ? parseInt(match.groups.endCol) : undefined,
                        }
                        : undefined;
                    return {
                        name: item.name,
                        type: item.type,
                        pos: pos,
                    };
                }
            });
        }
    }
    function doClean(settings, outputFiles, outputDir, sourcePath) {
        if (settings.stdout || settings.outputToFiles) {
            return;
        }
        try {
            Object.keys(outputFiles).forEach(function (outputType) {
                var file = outputFiles[outputType];
                if (fs_1.existsSync(file)) {
                    fs_1.unlinkSync(file);
                }
            });
            rimraf.sync(outputDir);
        }
        catch (error) {
            console.error('clean compiler output files failed!');
        }
        // console.log('compile time spent: ', Date.now() - st)
    }
    function loadSourceMapfromDesc(desc) {
        var sources = desc.sources;
        var asm = desc.asm.split(' ');
        if (!desc.sourceMap || desc.sourceMap.length == 0) {
            return [];
        }
        return asm.map(function (opcode, index) {
            var item = desc.sourceMap[index];
            var match = exports.SOURCE_REG.exec(item);
            if (match && match.groups) {
                var fileIndex = parseInt(match.groups.fileIndex);
                var pos = sources[fileIndex]
                    ? {
                        file: sources[fileIndex],
                        line: sources[fileIndex] ? parseInt(match.groups.line) : undefined,
                        endLine: sources[fileIndex] ? parseInt(match.groups.endLine) : undefined,
                        column: sources[fileIndex] ? parseInt(match.groups.col) : undefined,
                        endColumn: sources[fileIndex] ? parseInt(match.groups.endCol) : undefined,
                    }
                    : undefined;
                return {
                    pos: pos,
                    opcode: opcode,
                };
            }
        });
    }
    exports.loadSourceMapfromDesc = loadSourceMapfromDesc;
    
    },{"./internal":283,"child_process":36,"fs":36,"json-bigint":188,"md5":192,"path":313,"rimraf":336}],280:[function(require,module,exports){
    "use strict";
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var __assign = (this && this.__assign) || function () {
        __assign = Object.assign || function(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                    t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.buildScryptTypeResolver = exports.buildTypeResolver = exports.buildTypeResolverFromDesc = exports.buildTypeClasses = exports.buildLibraryClass = exports.buildStructsClass = exports.buildContractClass = exports.AbstractContract = exports.SUPPORTED_MINIMUM_VERSION = exports.CURRENT_CONTRACT_DESCRIPTION_VERSION = void 0;
    var _1 = require(".");
    var compilerWrapper_1 = require("./compilerWrapper");
    var internal_1 = require("./internal");
    var scryptTypes_1 = require("./scryptTypes");
    var path_1 = require("path");
    exports.CURRENT_CONTRACT_DESCRIPTION_VERSION = 9;
    exports.SUPPORTED_MINIMUM_VERSION = 8;
    var AbstractContract = /** @class */ (function () {
        // eslint-disable-next-line @typescript-eslint/no-empty-function
        function AbstractContract() {
            var ctorParams = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                ctorParams[_i] = arguments[_i];
            }
            this.calls = new Map();
            this.hexTemplateInlineASM = new Map();
            this.hexTemplateArgs = new Map();
            this.statePropsArgs = [];
            // If true, the contract will read the state from property, if false, the contract will read the state from preimage
            // A newly constructed contract always has this set to true, and after invocation, always has it set to false
            this.firstCall = true;
        }
        Object.defineProperty(AbstractContract.prototype, "lockingScript", {
            get: function () {
                if (!this.dataPart) {
                    return this.scriptedConstructor.lockingScript;
                }
                // append dataPart script to codePart if there is dataPart
                return this.codePart.add(this.dataPart);
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "txContext", {
            get: function () {
                return this._txContext;
            },
            set: function (txContext) {
                this._txContext = txContext;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "sourceMapFile", {
            get: function () {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                return desc.sourceMapFile;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "file", {
            get: function () {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                return desc.file;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "contractName", {
            get: function () {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                return desc.contract;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "stateProps", {
            get: function () {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                return desc.stateProps || [];
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "version", {
            get: function () {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                return desc.version || 0;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "resolver", {
            get: function () {
                return Object.getPrototypeOf(this).constructor.resolver;
            },
            enumerable: false,
            configurable: true
        });
        // replace assembly variables with assembly values
        AbstractContract.prototype.replaceAsmVars = function (asmVarValues) {
            if (asmVarValues) {
                for (var key in asmVarValues) {
                    var val = asmVarValues[key];
                    this.hexTemplateInlineASM.set("<" + (key.startsWith('$') ? key.substring(1) : key) + ">", internal_1.mvc.Script.fromASM(val).toHex());
                }
            }
            var hexTemplate = Object.getPrototypeOf(this).constructor.hex;
            var lockingScript = internal_1.buildContractCode(this.hexTemplateArgs, this.hexTemplateInlineASM, hexTemplate);
            this.scriptedConstructor.lockingScript = lockingScript;
        };
        Object.defineProperty(AbstractContract.prototype, "asmArgs", {
            // replace assembly variables with assembly values
            get: function () {
                var e_1, _a;
                var result = {};
                try {
                    for (var _b = __values(this.hexTemplateInlineASM.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
                        var entry = _c.value;
                        var name_1 = entry[0].replace('<', '').replace('>', '');
                        var value = entry[1];
                        result[name_1] = internal_1.mvc.Script.fromHex(value).toASM();
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
                return result;
            },
            enumerable: false,
            configurable: true
        });
        AbstractContract.prototype.getTypeClassByType = function (type) {
            return this.resolver.resolverClass(type);
        };
        /**
         * @param states an object. Each key of the object is the name of a state property, and each value is the value of the state property.
         * @returns a locking script that includes the new states. If you only provide some but not all state properties, other state properties are not modified when calculating the locking script.
         */
        AbstractContract.prototype.getNewStateScript = function (states) {
            var _this = this;
            var stateArgs = this.statePropsArgs;
            if (stateArgs.length === 0) {
                throw new Error("Contract " + this.contractName + " does not have any stateful property");
            }
            var resolveKeys = [];
            var newState = stateArgs.map(function (arg) {
                if (Object.prototype.hasOwnProperty.call(states, arg.name)) {
                    resolveKeys.push(arg.name);
                    var state = states[arg.name];
                    var error = internal_1.checkSupportedParamType(state, arg, _this.resolver.resolverType);
                    if (error) {
                        throw error;
                    }
                    return Object.assign(__assign({}, arg), {
                        value: states[arg.name]
                    });
                }
                else {
                    return arg;
                }
            });
            Object.keys(states).forEach(function (key) {
                if (resolveKeys.indexOf(key) === -1) {
                    throw new Error("Contract " + _this.contractName + " does not have stateful property " + key);
                }
            });
            return this.codePart.add(internal_1.mvc.Script.fromHex(internal_1.buildContractState(newState, false, this.resolver.resolverType)));
        };
        AbstractContract.prototype.run_verify = function (unlockingScriptASM, txContext) {
            var txCtx = Object.assign({}, this._txContext || {}, txContext || {});
            var us = unlockingScriptASM.trim() ? internal_1.mvc.Script.fromASM(unlockingScriptASM.trim()) : new internal_1.mvc.Script();
            var ls = internal_1.mvc.Script.fromHex(this.lockingScript.toHex());
            var tx = txCtx.tx;
            var inputIndex = txCtx.inputIndex || 0;
            var inputSatoshis = txCtx.inputSatoshis || 0;
            internal_1.mvc.Script.Interpreter.MAX_SCRIPT_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
            internal_1.mvc.Script.Interpreter.MAXIMUM_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
            var bsi = internal_1.mvc.Script.Interpreter();
            var lastfExecs = {};
            bsi.stepListener = function (step) {
                if (step.fExec || (internal_1.mvc.Opcode.OP_IF <= step.opcode.toNumber() && step.opcode.toNumber() <= internal_1.mvc.Opcode.OP_ENDIF)) {
                    if ((internal_1.mvc.Opcode.OP_IF <= step.opcode.toNumber() && step.opcode.toNumber() <= internal_1.mvc.Opcode.OP_ENDIF) || step.opcode.toNumber() === internal_1.mvc.Opcode.OP_RETURN) /**Opreturn */ {
                        lastfExecs.opcode = step.opcode;
                    }
                    else {
                        lastfExecs = step;
                    }
                }
            };
            var result = bsi.verify(us, ls, tx, inputIndex, internal_1.DEFAULT_FLAGS, new internal_1.mvc.crypto.BN(inputSatoshis));
            if (result) {
                return {
                    success: true,
                    error: ''
                };
            }
            var failedOpCode = lastfExecs.opcode.toNumber();
            if ([internal_1.mvc.Opcode.OP_CHECKSIG, internal_1.mvc.Opcode.OP_CHECKSIGVERIFY, internal_1.mvc.Opcode.OP_CHECKMULTISIG, internal_1.mvc.Opcode.OP_CHECKMULTISIGVERIFY].includes(failedOpCode)) {
                if (!txCtx) {
                    throw new Error('should provide txContext when verify');
                }
                if (!tx) {
                    throw new Error('should provide txContext.tx when verify');
                }
            }
            var error = "VerifyError: " + bsi.errstr + ", fails at " + new internal_1.mvc.Opcode(failedOpCode) + "\n";
            if (this.sourceMapFile) {
                var sourceMapFilePath = internal_1.uri2path(this.sourceMapFile);
                var sourceMap = internal_1.JSONParserSync(sourceMapFilePath);
                var sourcePath = internal_1.uri2path(this.file);
                var srcDir_1 = path_1.dirname(sourcePath);
                var sourceFileName_1 = path_1.basename(sourcePath);
                var sources = sourceMap.sources.map(function (source) { return compilerWrapper_1.getFullFilePath(source, srcDir_1, sourceFileName_1); });
                var pos = internal_1.findSrcInfoV2(lastfExecs.pc, sourceMap);
                if (pos && sources[pos[1]]) {
                    error = "VerifyError: " + bsi.errstr + " \n\t[Go to Source](" + internal_1.path2uri(sources[pos[1]]) + "#" + pos[2] + ")  fails at " + new internal_1.mvc.Opcode(failedOpCode) + "\n";
                }
            }
            else if (this.version === 8) {
                var desc = Object.getPrototypeOf(this).constructor.desc;
                var sourceMap = compilerWrapper_1.loadSourceMapfromDesc(desc);
                if (sourceMap.length > 0) {
                    // the complete script may have op_return and data, but compiled output does not have it. So we need to make sure the index is in boundary.
                    var opcodeIndex = lastfExecs.pc;
                    if (sourceMap[opcodeIndex]) {
                        var opcode = sourceMap[opcodeIndex];
                        if (!opcode.pos || opcode.pos.file === 'std') {
                            var srcInfo = internal_1.findSrcInfoV1(sourceMap, opcodeIndex);
                            if (srcInfo) {
                                opcode.pos = srcInfo.pos;
                            }
                        }
                        // in vscode termianal need to use [:] to jump to file line, but here need to use [#] to jump to file line in output channel.
                        if (opcode && opcode.pos) {
                            error = "VerifyError: " + bsi.errstr + " \n\t[Go to Source](" + internal_1.path2uri(opcode.pos.file) + "#" + opcode.pos.line + ")  fails at " + new internal_1.mvc.Opcode(failedOpCode) + "\n";
                        }
                    }
                }
            }
            return {
                success: result,
                error: error
            };
        };
        Object.defineProperty(AbstractContract.prototype, "dataPart", {
            get: function () {
                if (AbstractContract.isStateful(this)) {
                    var state = internal_1.buildContractState(this.statePropsArgs, this.firstCall, this.resolver.resolverType);
                    return internal_1.mvc.Script.fromHex(state);
                }
                if (this._dataPartInHex) {
                    return internal_1.mvc.Script.fromHex(this._dataPartInHex);
                }
            },
            set: function (dataInScript) {
                throw new Error('Setter for dataPart is not available. Please use: setDataPart() instead');
            },
            enumerable: false,
            configurable: true
        });
        AbstractContract.prototype.setDataPart = function (state, isStateHex) {
            if (isStateHex === void 0) { isStateHex = false; }
            if (isStateHex == false) {
                console.warn('deprecated, using setDataPartInASM');
                this.setDataPartInASM(state);
            }
            else {
                console.warn('deprecated, using setDataPartInHex');
                this.setDataPartInHex(state);
            }
        };
        AbstractContract.prototype.setDataPartInASM = function (state) {
            if (AbstractContract.isStateful(this)) {
                throw new Error('should not use `setDataPartInASM` for a stateful contract, using `setDataPartInHex`');
            }
            var dataPartInASM = typeof state === 'string' ? state.trim() : internal_1.serializeState(state);
            this.setDataPartInHex(internal_1.mvc.Script.fromASM(dataPartInASM).toHex());
        };
        AbstractContract.prototype.setDataPartInHex = function (hex) {
            this._dataPartInHex = hex.trim();
            if (AbstractContract.isStateful(this)) {
                var _a = __read(_1.parseStateHex(this, this._dataPartInHex), 2), firstCall = _a[0], args = _a[1];
                this.statePropsArgs = args;
                this.firstCall = firstCall;
            }
        };
        Object.defineProperty(AbstractContract.prototype, "codePart", {
            get: function () {
                var lockingScript = this.scriptedConstructor.toScript();
                // note: do not trim the trailing space
                // 如果script有clone方法，这里可以直接clone
                if (lockingScript.hasOwnProperty('clone')) {
                    return lockingScript.clone().add(internal_1.mvc.Script.fromHex('6a'));
                }
                var cloneScript = internal_1.mvc.Script.fromHex(lockingScript.toHex());
                cloneScript.add(internal_1.mvc.Script.fromHex('6a'));
                return cloneScript;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AbstractContract.prototype, "codeHash", {
            get: function () {
                if (this.dataPart) {
                    return internal_1.hash160(this.codePart.toHex());
                }
                else {
                    return internal_1.hash160(this.lockingScript.toHex());
                }
            },
            enumerable: false,
            configurable: true
        });
        AbstractContract.getAsmVars = function (lockingScriptHex) {
            var instance = this.fromHex(lockingScriptHex);
            return instance.asmArgs;
        };
        AbstractContract.prototype.arguments = function (pubFuncName) {
            if (pubFuncName === 'constructor') {
                return this.scriptedConstructor.args;
            }
            if (this.calls.has(pubFuncName)) {
                return this.calls.get(pubFuncName).args;
            }
            return [];
        };
        AbstractContract.prototype.ctorArgs = function () {
            return this.arguments('constructor');
        };
        AbstractContract.fromASM = function (asm) {
            return null;
        };
        AbstractContract.fromHex = function (hex) {
            return null;
        };
        AbstractContract.fromTransaction = function (hex, outputIndex) {
            if (outputIndex === void 0) { outputIndex = 0; }
            return null;
        };
        AbstractContract.isStateful = function (contract) {
            return contract.stateProps.length > 0;
        };
        return AbstractContract;
    }());
    exports.AbstractContract = AbstractContract;
    var invalidMethodName = ['arguments',
        'setDataPart',
        'setDataPartInASM',
        'setDataPartInHex',
        'version',
        'stateProps',
        'sourceMapFile',
        'file',
        'contractName',
        'ctorArgs',
        'run_verify',
        'replaceAsmVars',
        'asmVars',
        'asmArguments',
        'dataPart',
        'lockingScript',
        'codeHash',
        'codePart',
        'resolver',
        'getTypeClassByType',
        'getNewStateScript',
        'txContext'];
    function buildContractClass(desc) {
        if (desc instanceof internal_1.CompileResult) {
            desc = desc.toDesc();
        }
        if (!desc.contract) {
            throw new Error('missing field `contract` in description');
        }
        if (!desc.version) {
            throw new Error('missing field `version` in description');
        }
        if (desc.version < exports.SUPPORTED_MINIMUM_VERSION) {
            throw new Error("Contract description version deprecated, The minimum version number currently supported is " + exports.SUPPORTED_MINIMUM_VERSION);
        }
        if (!desc.abi) {
            throw new Error('missing field `abi` in description');
        }
        if (!desc.hex) {
            throw new Error('missing field `hex` in description');
        }
        var ContractClass = /** @class */ (function (_super) {
            __extends(Contract, _super);
            function Contract() {
                var _a;
                var ctorParams = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    ctorParams[_i] = arguments[_i];
                }
                var _this = _super.call(this) || this;
                if (!Contract.asmContract) {
                    _this.scriptedConstructor = (_a = Contract.abiCoder).encodeConstructorCall.apply(_a, __spread([_this, Contract.hex], ctorParams));
                }
                return _this;
            }
            //When create a contract instance using UTXO, 
            //use fromHex or fromASM because you do not know the parameters of constructor.
            /**
             * Create a contract instance using UTXO asm
             * @param hex
             */
            Contract.fromASM = function (asm) {
                return ContractClass.fromHex(internal_1.mvc.Script.fromASM(asm).toHex());
            };
            /**
             * Create a contract instance using UTXO hex
             * @param hex
             */
            Contract.fromHex = function (hex) {
                Contract.asmContract = true;
                var obj = new this();
                Contract.asmContract = false;
                obj.scriptedConstructor = Contract.abiCoder.encodeConstructorCallFromRawHex(obj, Contract.hex, hex);
                return obj;
            };
            /**
             * Create a contract instance using raw Transaction
             * @param hex
             */
            Contract.fromTransaction = function (hex, outputIndex) {
                if (outputIndex === void 0) { outputIndex = 0; }
                var tx = new internal_1.mvc.Transaction(hex);
                return ContractClass.fromHex(tx.outputs[outputIndex].script.toHex());
            };
            Object.defineProperty(Contract.prototype, "asmVars", {
                /**
                 * Get the parameter of the constructor and inline asm vars,
                 * all values is hex string, need convert it to number or bytes on using
                 */
                get: function () {
                    return ContractClass.getAsmVars(this.scriptedConstructor.toHex());
                },
                enumerable: false,
                configurable: true
            });
            Object.defineProperty(Contract.prototype, "asmArguments", {
                get: function () {
                    //TODO: @deprecate AbstractContract.getAsmVars , using asmArguments
                    return null;
                },
                enumerable: false,
                configurable: true
            });
            return Contract;
        }(AbstractContract));
        ContractClass.desc = desc;
        ContractClass.resolver = buildScryptTypeResolver(desc);
        ContractClass.abi = desc.abi;
        ContractClass.hex = desc.hex;
        ContractClass.abiCoder = new internal_1.ABICoder(desc.abi, ContractClass.resolver);
        ContractClass.types = buildTypeClasses(desc);
        ContractClass.stateProps = desc.stateProps || [];
        ContractClass.abi.forEach(function (entity) {
            if (invalidMethodName.indexOf(entity.name) > -1) {
                throw new Error("Method name [" + entity.name + "] is used by scryptlib now, Pelease change you contract method name!");
            }
            ContractClass.prototype[entity.name] = function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                var call = ContractClass.abiCoder.encodePubFunctionCall(this, entity.name, args);
                this.calls.set(entity.name, call);
                return call;
            };
        });
        ContractClass.stateProps.forEach(function (p) {
            Object.defineProperty(ContractClass.prototype, p.name, {
                get: function () {
                    var arg = this.statePropsArgs.find(function (arg) {
                        return arg.name === p.name;
                    });
                    if (arg) {
                        return arg.value;
                    }
                    else {
                        throw new Error("property " + p.name + " does not exists");
                    }
                },
                set: function (value) {
                    var arg = this.statePropsArgs.find(function (arg) {
                        return arg.name === p.name;
                    });
                    if (arg) {
                        arg.value = value;
                        this.firstCall = false;
                    }
                    else {
                        throw new Error("property " + p.name + " does not exists");
                    }
                }
            });
        });
        return ContractClass;
    }
    exports.buildContractClass = buildContractClass;
    /**
     * @deprecated use buildTypeClasses
     * @param desc CompileResult or ContractDescription
     */
    function buildStructsClass(desc) {
        var structTypes = {};
        var structs = desc.structs || [];
        var finalTypeResolver = buildTypeResolverFromDesc(desc);
        structs.forEach(function (element) {
            var _a;
            var name = element.name;
            Object.assign(structTypes, (_a = {},
                _a[name] = /** @class */ (function (_super) {
                    __extends(class_1, _super);
                    function class_1(o) {
                        var _this = _super.call(this, o) || this;
                        _this._typeResolver = finalTypeResolver; //we should assign this before bind
                        _this.bind();
                        return _this;
                    }
                    return class_1;
                }(internal_1.Struct)),
                _a));
            structTypes[name].structAst = element;
        });
        return structTypes;
    }
    exports.buildStructsClass = buildStructsClass;
    function buildStdLibraryClass() {
        var _a, _b;
        var libraryTypes = {};
        Object.assign(libraryTypes, (_a = {},
            _a['HashedMap'] = scryptTypes_1.HashedMap,
            _a));
        Object.assign(libraryTypes, (_b = {},
            _b['HashedSet'] = scryptTypes_1.HashedSet,
            _b));
        return libraryTypes;
    }
    function buildLibraryClass(desc) {
        var libraryTypes = {};
        // map LibraryEntity to StructEntity, as we treat library as struct
        var library = desc.library || [];
        var finalTypeResolver = buildTypeResolverFromDesc(desc);
        Object.assign(libraryTypes, buildStdLibraryClass());
        library.forEach(function (element) {
            var _a;
            var name = element.name;
            var libraryClass = /** @class */ (function (_super) {
                __extends(class_2, _super);
                function class_2() {
                    var args = [];
                    for (var _i = 0; _i < arguments.length; _i++) {
                        args[_i] = arguments[_i];
                    }
                    var _this = _super.apply(this, __spread(args)) || this;
                    _this._typeResolver = finalTypeResolver; //we should assign this before bind
                    _this.bind();
                    return _this;
                }
                return class_2;
            }(scryptTypes_1.Library));
            libraryClass.libraryAst = element;
            Object.assign(libraryTypes, (_a = {},
                _a[name] = libraryClass,
                _a));
        });
        return libraryTypes;
    }
    exports.buildLibraryClass = buildLibraryClass;
    function buildTypeClasses(desc) {
        if (Object.prototype.hasOwnProperty.call(desc, 'types')) {
            var CLASS = desc;
            return CLASS.types;
        }
        desc = desc;
        var structClasses = buildStructsClass(desc);
        var libraryClasses = buildLibraryClass(desc);
        var allTypeClasses = {};
        var alias = desc.alias || [];
        var resolver = buildTypeResolverFromDesc(desc);
        alias.forEach(function (element) {
            var _a, _b;
            var typeInfo = resolver(element.name);
            if (!internal_1.isArrayType(typeInfo.finalType)) { //not need to build class type for array, we only build class type for array element
                if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                    var type = internal_1.getNameByType(typeInfo.finalType);
                    Object.assign(allTypeClasses, (_a = {},
                        _a[element.name] = /** @class */ (function (_super) {
                            __extends(class_3, _super);
                            function class_3(o) {
                                var _this = _super.call(this, o) || this;
                                _this._type = element.name;
                                _this._typeResolver = resolver;
                                return _this;
                            }
                            return class_3;
                        }(structClasses[type])),
                        _a));
                }
                else {
                    var C = internal_1.BasicScryptType[typeInfo.finalType];
                    if (C) {
                        var aliasClass = /** @class */ (function (_super) {
                            __extends(class_4, _super);
                            function class_4(o) {
                                var _this = _super.call(this, o) || this;
                                _this._type = element.name;
                                _this._typeResolver = resolver;
                                return _this;
                            }
                            return class_4;
                        }(C));
                        Object.assign(allTypeClasses, (_b = {},
                            _b[element.name] = aliasClass,
                            _b));
                    }
                    else {
                        throw new Error("can not resolve type alias " + element.name + " " + element.type);
                    }
                }
            }
        });
        Object.assign(allTypeClasses, structClasses);
        Object.assign(allTypeClasses, libraryClasses);
        Object.assign(allTypeClasses, internal_1.BasicScryptType);
        return allTypeClasses;
    }
    exports.buildTypeClasses = buildTypeClasses;
    function buildTypeResolverFromDesc(desc) {
        var alias = desc.alias || [];
        var library = desc.library || [];
        var structs = desc.structs || [];
        var contract = desc.contract;
        return buildTypeResolver(contract, alias, structs, library);
    }
    exports.buildTypeResolverFromDesc = buildTypeResolverFromDesc;
    // build a resolver witch can only resolve type
    function buildTypeResolver(contract, alias, structs, library, contracts, statics) {
        if (contracts === void 0) { contracts = []; }
        if (statics === void 0) { statics = []; }
        var resolvedTypes = {};
        structs.forEach(function (element) {
            resolvedTypes[element.name] = {
                finalType: element.name,
                symbolType: scryptTypes_1.SymbolType.Struct
            };
        });
        library.forEach(function (element) {
            resolvedTypes[element.name] = {
                finalType: element.name,
                symbolType: scryptTypes_1.SymbolType.Library
            };
        });
        contracts.forEach(function (element) {
            resolvedTypes[element.name] = {
                finalType: element.name,
                symbolType: scryptTypes_1.SymbolType.Contract
            };
        });
        // add std type
        resolvedTypes['HashedMap'] = {
            finalType: 'HashedMap',
            symbolType: scryptTypes_1.SymbolType.Library
        };
        resolvedTypes['HashedSet'] = {
            finalType: 'HashedSet',
            symbolType: scryptTypes_1.SymbolType.Library
        };
        resolvedTypes['SortedItem'] = {
            finalType: 'SortedItem',
            symbolType: scryptTypes_1.SymbolType.Struct
        };
        resolvedTypes['PubKeyHash'] = {
            finalType: 'Ripemd160',
            symbolType: scryptTypes_1.SymbolType.BaseType
        };
        alias.forEach(function (element) {
            resolvedTypes[element.name] = internal_1.resolveType(element.name, resolvedTypes, contract, statics, alias, library);
        });
        var resolver = function (type) {
            if (resolvedTypes[type]) {
                return resolvedTypes[type];
            }
            if (internal_1.BasicScryptType[type]) {
                return {
                    finalType: type,
                    symbolType: scryptTypes_1.SymbolType.BaseType
                };
            }
            return internal_1.resolveType(type, resolvedTypes, contract, statics, alias, library);
        };
        return resolver;
    }
    exports.buildTypeResolver = buildTypeResolver;
    // build a resolver which can resolve type and ScryptType class
    function buildScryptTypeResolver(desc) {
        var resolver = buildTypeResolverFromDesc(desc);
        var allTypes = buildTypeClasses(desc);
        return {
            resolverType: resolver,
            resolverClass: function (type) {
                var finalType = resolver(type).finalType;
                var typeName = internal_1.getNameByType(finalType) ? internal_1.getNameByType(finalType) : finalType;
                return allTypes[typeName];
            },
            allTypes: function () {
                return allTypes;
            }
        };
    }
    exports.buildScryptTypeResolver = buildScryptTypeResolver;
    
    },{".":282,"./compilerWrapper":279,"./internal":283,"./scryptTypes":285,"path":313}],281:[function(require,module,exports){
    (function (process,__dirname){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.findCompiler = exports.getPlatformScryptc = void 0;
    var path_1 = require("path");
    var minimist = require("minimist");
    var fs_1 = require("fs");
    var compareVersions = require("compare-versions");
    var child_process_1 = require("child_process");
    var chalk_1 = require("chalk");
    var os = require("os");
    var process_1 = require("process");
    function getPlatformScryptc() {
        switch (os.platform()) {
            case 'win32':
                return 'compiler/scryptc/win32/scryptc.exe';
            case 'linux':
                return 'compiler/scryptc/linux/scryptc';
            case 'darwin':
                return 'compiler/scryptc/mac/scryptc';
            default:
                throw "sCrypt doesn't support " + os.platform();
        }
    }
    exports.getPlatformScryptc = getPlatformScryptc;
    function find_compiler_vscode() {
        var homedir = os.homedir();
        var extensionPath = path_1.join(homedir, '.vscode/extensions');
        if (!fs_1.existsSync(extensionPath)) {
            return undefined;
        }
        var sCryptPrefix = 'bsv-scrypt.scrypt-';
        var versions = fs_1.readdirSync(extensionPath).reduce(function (filtered, item) {
            if (item.indexOf(sCryptPrefix) > -1) {
                var version = item.substring(sCryptPrefix.length);
                if (compareVersions.validate(version)) {
                    filtered.push(version);
                }
            }
            return filtered;
        }, []);
        // compareVersions is ascending, so reverse.
        versions = versions.sort(compareVersions).reverse();
        var sCryptExtensionDirName = sCryptPrefix + versions[0];
        var scryptc = path_1.join(extensionPath, sCryptExtensionDirName, getPlatformScryptc());
        return fs_1.existsSync(scryptc) ? scryptc : undefined;
    }
    function find_compiler_local(directory) {
        if (directory === void 0) { directory = __dirname; }
        var compiler = path_1.resolve(directory, 'compiler');
        if (fs_1.existsSync(compiler) && fs_1.statSync(compiler).isDirectory()) {
            var scryptc = path_1.join(compiler, '..', getPlatformScryptc());
            return fs_1.existsSync(scryptc) ? scryptc : undefined;
        }
        var parent = path_1.resolve(directory, '..');
        if (parent === directory) {
            return undefined;
        }
        return find_compiler_local(parent);
    }
    function find_compiler_PATH() {
        var isWin = os.platform().indexOf('win') > -1;
        var where = isWin ? 'where' : 'which';
        try {
            var scryptc = child_process_1.execSync(where + " scryptc", { stdio: [] }).toString();
            return scryptc.replace(/\r\n/g, '');
        }
        catch (error) {
            return undefined;
        }
    }
    // Searches known directories for a specific platform and returns Path object of the sCrypt compiler binary if found.
    function findCompiler() {
        var argv = minimist(process.argv.slice(2));
        var scryptc = argv.scryptc;
        if (scryptc && scryptc.startsWith('"') && scryptc.endsWith('"')) {
            scryptc = scryptc.substring(1, scryptc.length - 1);
        }
        // If a special compiler is specified on the command line, the specified compiler is used
        if (scryptc && fs_1.existsSync(scryptc)) {
            return scryptc;
        }
        scryptc = find_compiler_local();
        if (scryptc && fs_1.existsSync(scryptc)) {
            return scryptc;
        }
        scryptc = find_compiler_PATH();
        if (scryptc && fs_1.existsSync(scryptc)) {
            return scryptc;
        }
        scryptc = find_compiler_vscode();
        if (scryptc && fs_1.existsSync(scryptc)) {
            return scryptc;
        }
        console.info(chalk_1.default.red.bold('**ERROR**') + " " + chalk_1.default.red('No sCrypt compiler found.') + "\n\n  ");
        console.info("" + chalk_1.default.green.bold('You can install the compiler in the following ways: \n'));
        console.info("" + chalk_1.default.grey('•'), "Run " + chalk_1.default.yellow.bold('npx scryptlib download') + " to download the compiler binary.");
        console.info("" + chalk_1.default.grey('•'), "Install " + chalk_1.default.bold('sCrypt IDE') + " at vscode extension marketplace: " + chalk_1.default.blue.bold('https://marketplace.visualstudio.com/items?itemName=bsv-scrypt.sCrypt'));
        process_1.exit(-1);
    }
    exports.findCompiler = findCompiler;
    
    }).call(this)}).call(this,require('_process'),"/node_modules/mvc-scrypt/dist")
    
    },{"_process":321,"chalk":90,"child_process":36,"compare-versions":99,"fs":36,"minimist":197,"os":296,"path":313,"process":375}],282:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var internal_1 = require("./internal");
    Object.defineProperty(exports, "buildContractClass", { enumerable: true, get: function () { return internal_1.buildContractClass; } });
    Object.defineProperty(exports, "buildTypeClasses", { enumerable: true, get: function () { return internal_1.buildTypeClasses; } });
    Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return internal_1.compile; } });
    Object.defineProperty(exports, "compileAsync", { enumerable: true, get: function () { return internal_1.compileAsync; } });
    Object.defineProperty(exports, "compileContract", { enumerable: true, get: function () { return internal_1.compileContract; } });
    Object.defineProperty(exports, "doCompileAsync", { enumerable: true, get: function () { return internal_1.doCompileAsync; } });
    Object.defineProperty(exports, "getPreimage", { enumerable: true, get: function () { return internal_1.getPreimage; } });
    Object.defineProperty(exports, "signTx", { enumerable: true, get: function () { return internal_1.signTx; } });
    Object.defineProperty(exports, "handleCompilerOutput", { enumerable: true, get: function () { return internal_1.handleCompilerOutput; } });
    Object.defineProperty(exports, "compileContractAsync", { enumerable: true, get: function () { return internal_1.compileContractAsync; } });
    var internal_2 = require("./internal");
    Object.defineProperty(exports, "mvc", { enumerable: true, get: function () { return internal_2.mvc; } });
    Object.defineProperty(exports, "ECIES", { enumerable: true, get: function () { return internal_2.ECIES; } });
    Object.defineProperty(exports, "toHex", { enumerable: true, get: function () { return internal_2.toHex; } });
    Object.defineProperty(exports, "bin2num", { enumerable: true, get: function () { return internal_2.bin2num; } });
    Object.defineProperty(exports, "bool2Asm", { enumerable: true, get: function () { return internal_2.bool2Asm; } });
    Object.defineProperty(exports, "int2Asm", { enumerable: true, get: function () { return internal_2.int2Asm; } });
    Object.defineProperty(exports, "parseLiteral", { enumerable: true, get: function () { return internal_2.parseLiteral; } });
    Object.defineProperty(exports, "bytes2Literal", { enumerable: true, get: function () { return internal_2.bytes2Literal; } });
    Object.defineProperty(exports, "bytesToHexString", { enumerable: true, get: function () { return internal_2.bytesToHexString; } });
    Object.defineProperty(exports, "getValidatedHexString", { enumerable: true, get: function () { return internal_2.getValidatedHexString; } });
    Object.defineProperty(exports, "literal2ScryptType", { enumerable: true, get: function () { return internal_2.literal2ScryptType; } });
    Object.defineProperty(exports, "literal2Asm", { enumerable: true, get: function () { return internal_2.literal2Asm; } });
    Object.defineProperty(exports, "findStructByType", { enumerable: true, get: function () { return internal_2.findStructByType; } });
    Object.defineProperty(exports, "findStructByName", { enumerable: true, get: function () { return internal_2.findStructByName; } });
    Object.defineProperty(exports, "isArrayType", { enumerable: true, get: function () { return internal_2.isArrayType; } });
    Object.defineProperty(exports, "arrayTypeAndSize", { enumerable: true, get: function () { return internal_2.arrayTypeAndSize; } });
    Object.defineProperty(exports, "newCall", { enumerable: true, get: function () { return internal_2.newCall; } });
    Object.defineProperty(exports, "getNameByType", { enumerable: true, get: function () { return internal_2.getNameByType; } });
    Object.defineProperty(exports, "genLaunchConfigFile", { enumerable: true, get: function () { return internal_2.genLaunchConfigFile; } });
    Object.defineProperty(exports, "subArrayType", { enumerable: true, get: function () { return internal_2.subArrayType; } });
    Object.defineProperty(exports, "flattenSha256", { enumerable: true, get: function () { return internal_2.flattenSha256; } });
    Object.defineProperty(exports, "isGenericType", { enumerable: true, get: function () { return internal_2.isGenericType; } });
    Object.defineProperty(exports, "parseGenericType", { enumerable: true, get: function () { return internal_2.parseGenericType; } });
    Object.defineProperty(exports, "toData", { enumerable: true, get: function () { return internal_2.toData; } });
    Object.defineProperty(exports, "findKeyIndex", { enumerable: true, get: function () { return internal_2.findKeyIndex; } });
    Object.defineProperty(exports, "readLaunchJson", { enumerable: true, get: function () { return internal_2.readLaunchJson; } });
    Object.defineProperty(exports, "getLowSPreimage", { enumerable: true, get: function () { return internal_2.getLowSPreimage; } });
    Object.defineProperty(exports, "readBytes", { enumerable: true, get: function () { return internal_2.readBytes; } });
    Object.defineProperty(exports, "parseAbiFromUnlockingScript", { enumerable: true, get: function () { return internal_2.parseAbiFromUnlockingScript; } });
    Object.defineProperty(exports, "findConstStatic", { enumerable: true, get: function () { return internal_2.findConstStatic; } });
    Object.defineProperty(exports, "findStatic", { enumerable: true, get: function () { return internal_2.findStatic; } });
    Object.defineProperty(exports, "resolveConstValue", { enumerable: true, get: function () { return internal_2.resolveConstValue; } });
    Object.defineProperty(exports, "arrayTypeAndSizeStr", { enumerable: true, get: function () { return internal_2.arrayTypeAndSizeStr; } });
    Object.defineProperty(exports, "toLiteralArrayType", { enumerable: true, get: function () { return internal_2.toLiteralArrayType; } });
    Object.defineProperty(exports, "serializeSupportedParamType", { enumerable: true, get: function () { return internal_2.serializeSupportedParamType; } });
    Object.defineProperty(exports, "librarySign", { enumerable: true, get: function () { return internal_2.librarySign; } });
    Object.defineProperty(exports, "structSign", { enumerable: true, get: function () { return internal_2.structSign; } });
    Object.defineProperty(exports, "resolveGenericType", { enumerable: true, get: function () { return internal_2.resolveGenericType; } });
    Object.defineProperty(exports, "createDefaultLibrary", { enumerable: true, get: function () { return internal_2.createDefaultLibrary; } });
    Object.defineProperty(exports, "createLibraryProperties", { enumerable: true, get: function () { return internal_2.createLibraryProperties; } });
    Object.defineProperty(exports, "canAssignProperty", { enumerable: true, get: function () { return internal_2.canAssignProperty; } });
    Object.defineProperty(exports, "arrayToLiteral", { enumerable: true, get: function () { return internal_2.arrayToLiteral; } });
    Object.defineProperty(exports, "cloneArray", { enumerable: true, get: function () { return internal_2.cloneArray; } });
    Object.defineProperty(exports, "arrayToScryptType", { enumerable: true, get: function () { return internal_2.arrayToScryptType; } });
    Object.defineProperty(exports, "buildStructsClass", { enumerable: true, get: function () { return internal_2.buildStructsClass; } });
    Object.defineProperty(exports, "buildTypeResolver", { enumerable: true, get: function () { return internal_2.buildTypeResolver; } });
    Object.defineProperty(exports, "buildScryptTypeResolver", { enumerable: true, get: function () { return internal_2.buildScryptTypeResolver; } });
    Object.defineProperty(exports, "getStructDeclaration", { enumerable: true, get: function () { return internal_2.getStructDeclaration; } });
    Object.defineProperty(exports, "getABIDeclaration", { enumerable: true, get: function () { return internal_2.getABIDeclaration; } });
    Object.defineProperty(exports, "typeOfArg", { enumerable: true, get: function () { return internal_2.typeOfArg; } });
    Object.defineProperty(exports, "buildContractState", { enumerable: true, get: function () { return internal_2.buildContractState; } });
    Object.defineProperty(exports, "compilerVersion", { enumerable: true, get: function () { return internal_2.compilerVersion; } });
    Object.defineProperty(exports, "flatternLibrary", { enumerable: true, get: function () { return internal_2.flatternLibrary; } });
    Object.defineProperty(exports, "flatternLibraryState", { enumerable: true, get: function () { return internal_2.flatternLibraryState; } });
    Object.defineProperty(exports, "flatternCtorArgs", { enumerable: true, get: function () { return internal_2.flatternCtorArgs; } });
    Object.defineProperty(exports, "flatternStruct", { enumerable: true, get: function () { return internal_2.flatternStruct; } });
    Object.defineProperty(exports, "flatternArray", { enumerable: true, get: function () { return internal_2.flatternArray; } });
    Object.defineProperty(exports, "flatternParams", { enumerable: true, get: function () { return internal_2.flatternParams; } });
    Object.defineProperty(exports, "flatternStateArgs", { enumerable: true, get: function () { return internal_2.flatternStateArgs; } });
    Object.defineProperty(exports, "isEmpty", { enumerable: true, get: function () { return internal_2.isEmpty; } });
    Object.defineProperty(exports, "isStringLiteral", { enumerable: true, get: function () { return internal_2.isStringLiteral; } });
    Object.defineProperty(exports, "and", { enumerable: true, get: function () { return internal_2.and; } });
    Object.defineProperty(exports, "or", { enumerable: true, get: function () { return internal_2.or; } });
    Object.defineProperty(exports, "xor", { enumerable: true, get: function () { return internal_2.xor; } });
    Object.defineProperty(exports, "invert", { enumerable: true, get: function () { return internal_2.invert; } });
    Object.defineProperty(exports, "JSONParser", { enumerable: true, get: function () { return internal_2.JSONParser; } });
    Object.defineProperty(exports, "getFullFilePath", { enumerable: true, get: function () { return internal_2.getFullFilePath; } });
    Object.defineProperty(exports, "path2uri", { enumerable: true, get: function () { return internal_2.path2uri; } });
    Object.defineProperty(exports, "uri2path", { enumerable: true, get: function () { return internal_2.uri2path; } });
    Object.defineProperty(exports, "parseStateHex", { enumerable: true, get: function () { return internal_2.parseStateHex; } });
    var internal_3 = require("./internal");
    Object.defineProperty(exports, "Int", { enumerable: true, get: function () { return internal_3.Int; } });
    Object.defineProperty(exports, "Bool", { enumerable: true, get: function () { return internal_3.Bool; } });
    Object.defineProperty(exports, "Bytes", { enumerable: true, get: function () { return internal_3.Bytes; } });
    Object.defineProperty(exports, "PrivKey", { enumerable: true, get: function () { return internal_3.PrivKey; } });
    Object.defineProperty(exports, "PubKey", { enumerable: true, get: function () { return internal_3.PubKey; } });
    Object.defineProperty(exports, "Sig", { enumerable: true, get: function () { return internal_3.Sig; } });
    Object.defineProperty(exports, "Ripemd160", { enumerable: true, get: function () { return internal_3.Ripemd160; } });
    Object.defineProperty(exports, "Sha1", { enumerable: true, get: function () { return internal_3.Sha1; } });
    Object.defineProperty(exports, "Sha256", { enumerable: true, get: function () { return internal_3.Sha256; } });
    Object.defineProperty(exports, "SigHashType", { enumerable: true, get: function () { return internal_3.SigHashType; } });
    Object.defineProperty(exports, "SigHashPreimage", { enumerable: true, get: function () { return internal_3.SigHashPreimage; } });
    Object.defineProperty(exports, "String", { enumerable: true, get: function () { return internal_3.String; } });
    Object.defineProperty(exports, "SortedItem", { enumerable: true, get: function () { return internal_3.SortedItem; } });
    Object.defineProperty(exports, "OpCodeType", { enumerable: true, get: function () { return internal_3.OpCodeType; } });
    Object.defineProperty(exports, "ScryptType", { enumerable: true, get: function () { return internal_3.ScryptType; } });
    Object.defineProperty(exports, "PubKeyHash", { enumerable: true, get: function () { return internal_3.PubKeyHash; } });
    Object.defineProperty(exports, "Struct", { enumerable: true, get: function () { return internal_3.Struct; } });
    Object.defineProperty(exports, "VariableType", { enumerable: true, get: function () { return internal_3.VariableType; } });
    Object.defineProperty(exports, "Library", { enumerable: true, get: function () { return internal_3.Library; } });
    Object.defineProperty(exports, "SigHash", { enumerable: true, get: function () { return internal_3.SigHash; } });
    Object.defineProperty(exports, "ABIEntityType", { enumerable: true, get: function () { return internal_3.ABIEntityType; } });
    Object.defineProperty(exports, "BuildType", { enumerable: true, get: function () { return internal_3.BuildType; } });
    Object.defineProperty(exports, "AbstractContract", { enumerable: true, get: function () { return internal_3.AbstractContract; } });
    Object.defineProperty(exports, "DebugModeTag", { enumerable: true, get: function () { return internal_3.DebugModeTag; } });
    Object.defineProperty(exports, "HashedMap", { enumerable: true, get: function () { return internal_3.HashedMap; } });
    Object.defineProperty(exports, "HashedSet", { enumerable: true, get: function () { return internal_3.HashedSet; } });
    Object.defineProperty(exports, "SymbolType", { enumerable: true, get: function () { return internal_3.SymbolType; } });
    //Equivalent to the built-in functions
    var internal_4 = require("./internal");
    Object.defineProperty(exports, "hash160", { enumerable: true, get: function () { return internal_4.hash160; } });
    Object.defineProperty(exports, "sha256", { enumerable: true, get: function () { return internal_4.sha256; } });
    Object.defineProperty(exports, "hash256", { enumerable: true, get: function () { return internal_4.hash256; } });
    Object.defineProperty(exports, "num2bin", { enumerable: true, get: function () { return internal_4.num2bin; } });
    Object.defineProperty(exports, "buildOpreturnScript", { enumerable: true, get: function () { return internal_4.buildOpreturnScript; } });
    Object.defineProperty(exports, "len", { enumerable: true, get: function () { return internal_4.len; } });
    Object.defineProperty(exports, "buildPublicKeyHashScript", { enumerable: true, get: function () { return internal_4.buildPublicKeyHashScript; } });
    Object.defineProperty(exports, "toHashedMap", { enumerable: true, get: function () { return internal_4.toHashedMap; } });
    Object.defineProperty(exports, "toHashedSet", { enumerable: true, get: function () { return internal_4.toHashedSet; } });
    Object.defineProperty(exports, "writeVarint", { enumerable: true, get: function () { return internal_4.writeVarint; } });
    Object.defineProperty(exports, "toLEUnsigned", { enumerable: true, get: function () { return internal_4.toLEUnsigned; } });
    var internal_5 = require("./internal");
    Object.defineProperty(exports, "serializeState", { enumerable: true, get: function () { return internal_5.serializeState; } });
    Object.defineProperty(exports, "deserializeState", { enumerable: true, get: function () { return internal_5.deserializeState; } });
    Object.defineProperty(exports, "STATE_LEN_2BYTES", { enumerable: true, get: function () { return internal_5.STATE_LEN_2BYTES; } });
    Object.defineProperty(exports, "STATE_LEN_4BYTES", { enumerable: true, get: function () { return internal_5.STATE_LEN_4BYTES; } });
    Object.defineProperty(exports, "serialize", { enumerable: true, get: function () { return internal_5.serialize; } });
    var internal_6 = require("./internal");
    Object.defineProperty(exports, "getPlatformScryptc", { enumerable: true, get: function () { return internal_6.getPlatformScryptc; } });
    Object.defineProperty(exports, "findCompiler", { enumerable: true, get: function () { return internal_6.findCompiler; } });
    var internal_7 = require("./internal");
    Object.defineProperty(exports, "partialSha256", { enumerable: true, get: function () { return internal_7.partialSha256; } });
    Object.defineProperty(exports, "sha256ByPartialHash", { enumerable: true, get: function () { return internal_7.sha256ByPartialHash; } });
    
    },{"./internal":283}],283:[function(require,module,exports){
    "use strict";
    var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
        if (k2 === undefined) k2 = k;
        Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
    }) : (function(o, m, k, k2) {
        if (k2 === undefined) k2 = k;
        o[k2] = m[k];
    }));
    var __exportStar = (this && this.__exportStar) || function(m, exports) {
        for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    __exportStar(require("./utils"), exports);
    __exportStar(require("./scryptTypes"), exports);
    __exportStar(require("./serializer"), exports);
    __exportStar(require("./contract"), exports);
    __exportStar(require("./compilerWrapper"), exports);
    __exportStar(require("./abi"), exports);
    __exportStar(require("./findCompiler"), exports);
    __exportStar(require("./partialSha256"), exports);
    
    },{"./abi":278,"./compilerWrapper":279,"./contract":280,"./findCompiler":281,"./partialSha256":284,"./scryptTypes":285,"./serializer":286,"./utils":287}],284:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.sha256ByPartialHash = exports.partialSha256 = void 0;
    var K = [
        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
    ];
    /**
     *
     * @param message origin message to sha256
     * @param index The partial hash returned is the hash of 0~index chunks, 512 bits per chunk.
     * @returns [partialHash, partialPreimage, padding]
     */
    function partialSha256(message, index) {
        var bytesHashed = message.length;
        var padLength = (bytesHashed % 64 < 56) ? 64 - (bytesHashed % 64) : 128 - (bytesHashed % 64);
        var suffix = Buffer.alloc(padLength);
        var padded = Buffer.concat([message, suffix]);
        var bitLenHi = (bytesHashed / 0x20000000) | 0;
        var bitLenLo = bytesHashed << 3;
        padded[bytesHashed] = 0x80;
        for (var i = bytesHashed + 1; i < padded.length - 8; i++) {
            padded[i] = 0;
        }
        padded[padded.length - 8] = (bitLenHi >>> 24) & 0xff;
        padded[padded.length - 7] = (bitLenHi >>> 16) & 0xff;
        padded[padded.length - 6] = (bitLenHi >>> 8) & 0xff;
        padded[padded.length - 5] = (bitLenHi >>> 0) & 0xff;
        padded[padded.length - 4] = (bitLenLo >>> 24) & 0xff;
        padded[padded.length - 3] = (bitLenLo >>> 16) & 0xff;
        padded[padded.length - 2] = (bitLenLo >>> 8) & 0xff;
        padded[padded.length - 1] = (bitLenLo >>> 0) & 0xff;
        var broken = [];
        for (var i = 0; i < padded.length / 64; i++) {
            broken.push(padded.slice(i * 64, i * 64 + 64));
        }
        var h0 = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
        var hi = h0;
        for (var i = 0; i < broken.length; i++) {
            var chunk = broken[i];
            hi = g(hi, chunk);
            if (bytesHashed > 64 && i == index) {
                break;
            }
        }
        var partialHash = toHash(hi);
        if (index > -1 && bytesHashed > 64) {
            var partialPreimage = message.slice((index + 1) * 64);
            var padding = padded.slice(message.length);
            return [partialHash, partialPreimage.toString('hex'), padding.toString('hex')];
        }
        return [partialHash, '', ''];
    }
    exports.partialSha256 = partialSha256;
    /**
     *
     * @param partialHash
     * @param partialPreimage
     * @param padding
     * @returns sha256 of the origin message
     */
    function sha256ByPartialHash(partialHash, partialPreimage, padding) {
        var partialHashBuffer = Buffer.from(partialHash, 'hex');
        var padded = Buffer.from(partialPreimage + padding, 'hex');
        var broken = [];
        for (var i = 0; i < padded.length / 64; i++) {
            broken.push(padded.slice(i * 64, i * 64 + 64));
        }
        var h0 = [byteToUint32(partialHashBuffer.slice(0, 4)),
            byteToUint32(partialHashBuffer.slice(4, 8)),
            byteToUint32(partialHashBuffer.slice(8, 12)),
            byteToUint32(partialHashBuffer.slice(12, 16)),
            byteToUint32(partialHashBuffer.slice(16, 20)),
            byteToUint32(partialHashBuffer.slice(20, 24)),
            byteToUint32(partialHashBuffer.slice(24, 28)),
            byteToUint32(partialHashBuffer.slice(28, 32))
        ];
        var hi = h0;
        var W = [];
        for (var i = 0; i < broken.length; i++) {
            var chunk = broken[i];
            hi = g(hi, chunk);
        }
        return toHash(hi);
    }
    exports.sha256ByPartialHash = sha256ByPartialHash;
    function byteToUint32(b) {
        return b.readUInt32BE();
    }
    function ToInteger(x) {
        x = Number(x);
        return x < 0 ? Math.ceil(x) : Math.floor(x);
    }
    function modulo(a, b) {
        return a - Math.floor(a / b) * b;
    }
    function ToUint32(x) {
        return modulo(ToInteger(x), Math.pow(2, 32));
    }
    //sha256 compression function
    function g(hprev, chunk) {
        var a = hprev[0];
        var b = hprev[1];
        var c = hprev[2];
        var d = hprev[3];
        var e = hprev[4];
        var f = hprev[5];
        var g = hprev[6];
        var h = hprev[7];
        var W = [];
        // Computation
        for (var i = 0; i < 64; i++) {
            if (i < 16) {
                W[i] = (chunk.slice(i * 4, i * 4 + 4).readUInt32BE());
            }
            else {
                var gamma0x = W[i - 15];
                var gamma0 = (((gamma0x << 25) | (gamma0x >>> 7)) ^
                    ((gamma0x << 14) | (gamma0x >>> 18)) ^
                    (gamma0x >>> 3));
                var gamma1x = W[i - 2];
                var gamma1 = (((gamma1x << 15) | (gamma1x >>> 17)) ^
                    ((gamma1x << 13) | (gamma1x >>> 19)) ^
                    (gamma1x >>> 10));
                W[i] = (gamma0 + W[i - 7] + gamma1 + W[i - 16]);
            }
            var ch = ((e & f) ^ (~e & g));
            var maj = ((a & b) ^ (a & c) ^ (b & c));
            var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
            var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
            var t1 = (h + sigma1 + ch + K[i] + W[i]);
            var t2 = (sigma0 + maj);
            h = g;
            g = f;
            f = e;
            e = (d + t1);
            d = c;
            c = b;
            b = a;
            a = (t1 + t2);
        }
        return [ToUint32(hprev[0] + a),
            ToUint32(hprev[1] + b),
            ToUint32(hprev[2] + c),
            ToUint32(hprev[3] + d),
            ToUint32(hprev[4] + e),
            ToUint32(hprev[5] + f),
            ToUint32(hprev[6] + g),
            ToUint32(hprev[7] + h)];
    }
    function iToB(i) {
        var bs = Buffer.from([0, 0, 0, 0]);
        bs.writeUInt32BE(i);
        return bs;
    }
    function toHash(hi) {
        var hashBytes = [iToB(hi[0]), iToB(hi[1]), iToB(hi[2]), iToB(hi[3]), iToB(hi[4]), iToB(hi[5]), iToB(hi[6]), iToB(hi[7])];
        return hashBytes.reduce(function (acc, cur) {
            return Buffer.concat([acc, cur]);
        }, Buffer.from([])).toString('hex');
    }
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84}],285:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    var _a;
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.serializeSupportedParamType = exports.BasicScryptType = exports.BasicType = exports.VariableType = exports.SortedItem = exports.HashedSet = exports.HashedMap = exports.Library = exports.Struct = exports.OpCodeType = exports.SigHashPreimage = exports.SigHashType = exports.SigHash = exports.Sha256 = exports.Sha1 = exports.PubKeyHash = exports.Ripemd160 = exports.Sig = exports.PubKey = exports.PrivKey = exports.String = exports.Bytes = exports.Bool = exports.Int = exports.ScryptType = exports.SymbolType = void 0;
    var internal_1 = require("./internal");
    var serializer_1 = require("./serializer");
    var SymbolType;
    (function (SymbolType) {
        SymbolType["BaseType"] = "BaseType";
        SymbolType["Contract"] = "Contract";
        SymbolType["Library"] = "Library";
        SymbolType["Struct"] = "Struct";
        SymbolType["Unknown"] = "Unknown";
    })(SymbolType = exports.SymbolType || (exports.SymbolType = {}));
    var ScryptType = /** @class */ (function () {
        function ScryptType() {
            var value = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                value[_i] = arguments[_i];
            }
            try {
                this._value = this.checkValue(value);
                this._literal = this.toLiteral();
                var _a = __read(internal_1.parseLiteral(this._literal), 3), asm = _a[0], _ = _a[1], scrType = _a[2];
                this._type = scrType;
                this._asm = asm;
            }
            catch (error) {
                throw new Error("can't construct " + this.constructor.name + " from <" + value + ">, " + error.message);
            }
        }
        Object.defineProperty(ScryptType.prototype, "value", {
            get: function () {
                return this._value;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(ScryptType.prototype, "finalType", {
            get: function () {
                if (this._typeResolver)
                    return this._typeResolver(this.type).finalType;
                return this.type;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(ScryptType.prototype, "literal", {
            get: function () {
                return this._literal;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(ScryptType.prototype, "type", {
            get: function () {
                return this._type;
            },
            enumerable: false,
            configurable: true
        });
        ScryptType.prototype.toASM = function () {
            return this._asm;
        };
        ScryptType.prototype.toHex = function () {
            return internal_1.mvc.Script.fromASM(this._asm).toHex();
        };
        ScryptType.prototype.toString = function (format) {
            if (format === 'hex') {
                return this.toHex();
            }
            return this.toLiteral();
        };
        ScryptType.prototype.toJSON = function () {
            return this.toLiteral();
        };
        ScryptType.prototype.toLiteral = function () {
            return '';
        };
        ScryptType.prototype.checkValue = function (value) {
            if (typeof value === 'undefined') {
                throw new Error('constructor argument undefined');
            }
            if (value.length !== 1) {
                throw new Error('constructor argument undefined');
            }
            return value[0];
        };
        ScryptType.prototype.equals = function (obj) {
            return obj.finalType === this.finalType && obj.toASM() === this.toASM();
        };
        ScryptType.prototype.serialize = function () {
            return '';
        };
        ScryptType.prototype.clone = function () {
            return Object.assign(Object.create(this), {
                _value: this.value
            });
        };
        return ScryptType;
    }());
    exports.ScryptType = ScryptType;
    var Int = /** @class */ (function (_super) {
        __extends(Int, _super);
        function Int(intVal) {
            return _super.call(this, intVal) || this;
        }
        Int.prototype.toLiteral = function () {
            return this._value.toString();
        };
        Int.prototype.checkValue = function (value) {
            _super.prototype.checkValue.call(this, value);
            if (!internal_1.isInteger(value[0])) {
                throw new Error('Only supports integers, should use integer number, bigint, hex string or decimal string: ' + value[0]);
            }
            if (typeof value[0] == 'number' && !isNaN(value[0])) {
                if (!Number.isSafeInteger(value[0])) {
                    throw new Error("<" + value[0] + "> is not safe integer, should use bigint, hex string or decimal string");
                }
            }
            return value[0];
        };
        Int.prototype.toJSON = function () {
            return this.value;
        };
        Int.prototype.serialize = function () {
            return serializer_1.serializeInt(this.value);
        };
        Int.prototype.toNumber = function () {
            if (typeof this._value === 'number') {
                return this._value;
            }
            else if (typeof this._value === 'bigint') {
                return internal_1.int2Value(this._value.toString());
            }
            return internal_1.int2Value(this.value);
        };
        return Int;
    }(ScryptType));
    exports.Int = Int;
    var Bool = /** @class */ (function (_super) {
        __extends(Bool, _super);
        function Bool(boolVal) {
            return _super.call(this, boolVal) || this;
        }
        Bool.prototype.toLiteral = function () {
            return this._value.toString();
        };
        Bool.prototype.serialize = function () {
            return this.value ? '01' : '00';
        };
        return Bool;
    }(ScryptType));
    exports.Bool = Bool;
    var Bytes = /** @class */ (function (_super) {
        __extends(Bytes, _super);
        function Bytes(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        Bytes.prototype.toLiteral = function () {
            return "b'" + internal_1.getValidatedHexString(this._value.toString()) + "'";
        };
        Bytes.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return Bytes;
    }(ScryptType));
    exports.Bytes = Bytes;
    var String = /** @class */ (function (_super) {
        __extends(String, _super);
        function String(val) {
            return _super.call(this, String.toUtf8Hex(val)) || this;
        }
        String.toUtf8Hex = function (val) {
            var encoder = new TextEncoder();
            var uint8array = encoder.encode(val);
            return internal_1.toHex(Buffer.from(uint8array));
        };
        String.fromUtf8Hex = function (hex) {
            var utf8decoder = new TextDecoder();
            return utf8decoder.decode(Buffer.from(hex, 'hex'));
        };
        String.prototype.toLiteral = function () {
            return "\"" + this.show() + "\"";
        };
        String.prototype.show = function () {
            var hex = this.value;
            return String.fromUtf8Hex(hex);
        };
        return String;
    }(Bytes));
    exports.String = String;
    var PrivKey = /** @class */ (function (_super) {
        __extends(PrivKey, _super);
        function PrivKey(intVal) {
            return _super.call(this, intVal) || this;
        }
        PrivKey.prototype.toLiteral = function () {
            if (typeof this._value === 'string') {
                return "PrivKey(" + this._value + ")";
            }
            else {
                var v = this._value;
                return "PrivKey(0x" + internal_1.intValue2hex(v) + ")";
            }
        };
        PrivKey.prototype.toJSON = function () {
            return this.toLiteral();
        };
        PrivKey.prototype.serialize = function () {
            return serializer_1.serializeInt(this.value);
        };
        return PrivKey;
    }(Int));
    exports.PrivKey = PrivKey;
    var PubKey = /** @class */ (function (_super) {
        __extends(PubKey, _super);
        function PubKey(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        PubKey.prototype.toLiteral = function () {
            return "PubKey(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        PubKey.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return PubKey;
    }(ScryptType));
    exports.PubKey = PubKey;
    var Sig = /** @class */ (function (_super) {
        __extends(Sig, _super);
        function Sig(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        Sig.prototype.toLiteral = function () {
            return "Sig(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        Sig.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return Sig;
    }(ScryptType));
    exports.Sig = Sig;
    var Ripemd160 = /** @class */ (function (_super) {
        __extends(Ripemd160, _super);
        function Ripemd160(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        Ripemd160.prototype.toLiteral = function () {
            return "Ripemd160(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        Ripemd160.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return Ripemd160;
    }(ScryptType));
    exports.Ripemd160 = Ripemd160;
    var PubKeyHash = /** @class */ (function (_super) {
        __extends(PubKeyHash, _super);
        function PubKeyHash() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return PubKeyHash;
    }(Ripemd160));
    exports.PubKeyHash = PubKeyHash;
    var Sha1 = /** @class */ (function (_super) {
        __extends(Sha1, _super);
        function Sha1(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        Sha1.prototype.toLiteral = function () {
            return "Sha1(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        Sha1.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return Sha1;
    }(ScryptType));
    exports.Sha1 = Sha1;
    var Sha256 = /** @class */ (function (_super) {
        __extends(Sha256, _super);
        function Sha256(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        Sha256.prototype.toLiteral = function () {
            return "Sha256(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        Sha256.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return Sha256;
    }(ScryptType));
    exports.Sha256 = Sha256;
    var SigHash;
    (function (SigHash) {
        SigHash[SigHash["ALL"] = 1] = "ALL";
        SigHash[SigHash["NONE"] = 2] = "NONE";
        SigHash[SigHash["SINGLE"] = 3] = "SINGLE";
        SigHash[SigHash["FORKID"] = 64] = "FORKID";
        SigHash[SigHash["ANYONECANPAY"] = 128] = "ANYONECANPAY";
        SigHash[SigHash["ALL_FORKID"] = 65] = "ALL_FORKID";
        SigHash[SigHash["SINGLE_FORKID"] = 67] = "SINGLE_FORKID";
        SigHash[SigHash["NONE_FORKID"] = 66] = "NONE_FORKID";
        SigHash[SigHash["ANYONECANPAY_ALL_FORKID"] = 193] = "ANYONECANPAY_ALL_FORKID";
        SigHash[SigHash["ANYONECANPAY_SINGLE_FORKID"] = 195] = "ANYONECANPAY_SINGLE_FORKID";
        SigHash[SigHash["ANYONECANPAY_NONE_FORKID"] = 194] = "ANYONECANPAY_NONE_FORKID";
    })(SigHash = exports.SigHash || (exports.SigHash = {}));
    var SigHashType = /** @class */ (function (_super) {
        __extends(SigHashType, _super);
        function SigHashType(intVal) {
            return _super.call(this, intVal) || this;
        }
        SigHashType.prototype.toLiteral = function () {
            var hexStr = this._value.toString(16);
            if (hexStr.length % 2) {
                hexStr = '0' + hexStr;
            }
            return "SigHashType(b'" + hexStr + "')";
        };
        SigHashType.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        SigHashType.prototype.toString = function () {
            var types = [];
            var value = this._value;
            if ((value & SigHash.ANYONECANPAY) === SigHash.ANYONECANPAY) {
                types.push('SigHash.ANYONECANPAY');
                value = value - SigHash.ANYONECANPAY;
            }
            if ((value & SigHash.SINGLE) === SigHash.SINGLE) {
                types.push('SigHash.SINGLE');
                value = value - SigHash.SINGLE;
            }
            if ((value & SigHash.NONE) === SigHash.NONE) {
                types.push('SigHash.NONE');
                value = value - SigHash.NONE;
            }
            if ((value & SigHash.ALL) === SigHash.ALL) {
                types.push('SigHash.ALL');
                value = value - SigHash.ALL;
            }
            if ((value & SigHash.FORKID) === SigHash.FORKID) {
                types.push('SigHash.FORKID');
                value = value - SigHash.FORKID;
            }
            if (value === 0) {
                return types.join(' | ');
            }
            throw new Error("unknown sighash type value: " + this._value);
        };
        return SigHashType;
    }(ScryptType));
    exports.SigHashType = SigHashType;
    var SigHashPreimage = /** @class */ (function (_super) {
        __extends(SigHashPreimage, _super);
        function SigHashPreimage(bytesVal) {
            var _this = _super.call(this, bytesVal) || this;
            _this._buf = Buffer.from(bytesVal, 'hex');
            return _this;
        }
        SigHashPreimage.prototype.getReader = function (buf) {
            return new internal_1.mvc.encoding.BufferReader(buf);
        };
        Object.defineProperty(SigHashPreimage.prototype, "nVersion", {
            // nVersion of the transaction
            get: function () {
                return this.getReader(this._buf.slice(0, 4)).readUInt32LE();
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "hashPrevouts", {
            // hashPrevouts
            get: function () {
                return this._buf.slice(4, 4 + 32).toString('hex');
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "hashSequence", {
            // hashSequence
            get: function () {
                return this._buf.slice(36, 36 + 32).toString('hex');
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "outpoint", {
            // outpoint
            get: function () {
                var buf = this._buf.slice(68, 68 + 32 + 4);
                var hex = buf.toString('hex');
                var index = this.getReader(buf.slice(32, 32 + 4)).readUInt32LE();
                var hash = Buffer.from(buf.slice(0, 32)).reverse().toString('hex');
                return {
                    hash: hash,
                    index: index,
                    hex: hex
                };
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "scriptCode", {
            // scriptCode of the input
            get: function () {
                return this.getReader(this._buf.slice(104, this._buf.length - 52)).readVarLengthBuffer().toString('hex');
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "amount", {
            // value of the output spent by this input
            get: function () {
                return this.getReader(this._buf.slice(this._buf.length - 44 - 8, this._buf.length - 44)).readUInt32LE();
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "nSequence", {
            // nSequence of the input
            get: function () {
                return this.getReader(this._buf.slice(this._buf.length - 40 - 4, this._buf.length - 40)).readUInt32LE();
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "hashOutputs", {
            // hashOutputs
            get: function () {
                return this._buf.slice(this._buf.length - 8 - 32, this._buf.length - 8).toString('hex');
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "nLocktime", {
            // nLocktime of the transaction
            get: function () {
                return this.getReader(this._buf.slice(this._buf.length - 4 - 4, this._buf.length - 4)).readUInt32LE();
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(SigHashPreimage.prototype, "sighashType", {
            // sighash type of the signature
            get: function () {
                return this.getReader(this._buf.slice(this._buf.length - 4, this._buf.length)).readUInt32LE();
            },
            enumerable: false,
            configurable: true
        });
        SigHashPreimage.prototype.toString = function (format) {
            if (format === void 0) { format = 'hex'; }
            return this._buf.toString(format);
        };
        SigHashPreimage.prototype.toLiteral = function () {
            return "SigHashPreimage(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        SigHashPreimage.prototype.toJSONObject = function () {
            return {
                nVersion: this.nVersion,
                hashPrevouts: this.hashPrevouts,
                hashSequence: this.hashSequence,
                outpoint: this.outpoint,
                scriptCode: this.scriptCode,
                amount: this.amount,
                nSequence: this.nSequence,
                hashOutputs: this.hashOutputs,
                nLocktime: this.nLocktime,
                sighashType: new SigHashType(this.sighashType).toString()
            };
        };
        SigHashPreimage.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return SigHashPreimage;
    }(ScryptType));
    exports.SigHashPreimage = SigHashPreimage;
    var OpCodeType = /** @class */ (function (_super) {
        __extends(OpCodeType, _super);
        function OpCodeType(bytesVal) {
            return _super.call(this, bytesVal) || this;
        }
        OpCodeType.prototype.toLiteral = function () {
            return "OpCodeType(b'" + internal_1.getValidatedHexString(this._value.toString()) + "')";
        };
        OpCodeType.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        return OpCodeType;
    }(ScryptType));
    exports.OpCodeType = OpCodeType;
    var Struct = /** @class */ (function (_super) {
        __extends(Struct, _super);
        function Struct(o) {
            var _this = _super.call(this, o) || this;
            _this.sorted = false;
            _this.inferredTypes = {};
            return _this;
        }
        Struct.setStructAst = function (self, structAst) {
            Object.getPrototypeOf(self).constructor.structAst = structAst;
        };
        Struct.getStructAst = function (self) {
            return Object.getPrototypeOf(self).constructor.structAst;
        };
        Struct.prototype.flatten = function (varName) {
            return internal_1.flatternStruct(this, varName);
        };
        Struct.prototype.toHex = function () {
            if (!this.sorted) {
                throw 'unbinded Struct can\'t call toHex';
            }
            return internal_1.flatternStruct(this, '').map(function (v) {
                return v.value.toHex();
            }).join('');
        };
        Struct.prototype.init = function () {
            var _this = this;
            internal_1.checkStruct(Struct.getStructAst(this), this);
            this.inferrTypesByValue();
            var structAst = this.getStructAst();
            structAst.params.forEach(function (p) {
                var member = _this.memberByKey(p.name);
                internal_1.checkStructField(structAst, p, member, _this._typeResolver);
            });
            var ordered = {};
            var unordered = this.value;
            Object.keys(this.value).sort(function (a, b) {
                return (structAst.params.findIndex(function (e) {
                    return e.name === a;
                }) - structAst.params.findIndex(function (e) {
                    return e.name === b;
                }));
            }).forEach(function (key) {
                ordered[key] = unordered[key];
            });
            this.sorted = true;
            this._type = structAst.name;
            this._value = ordered;
        };
        Struct.prototype.bind = function () {
            var _this = this;
            this.init();
            var structAst = this.getStructAst();
            structAst.params.forEach(function (p) {
                Object.defineProperty(_this, p.name, {
                    get: function () {
                        return this.memberByKey(p.name);
                    },
                    set: function (value) {
                        internal_1.checkStructField(structAst, p, value, this._typeResolver);
                        this._value[p.name] = value;
                    }
                });
            });
        };
        Struct.prototype.getStructAst = function () {
            var _this = this;
            var structAst = Struct.getStructAst(this);
            return {
                name: structAst.name,
                params: structAst.params.map(function (p) { return ({
                    name: p.name,
                    type: internal_1.resolveGenericType(_this.inferredTypes, p.type)
                }); }),
                genericTypes: (structAst.genericTypes || []).map(function (t) { return t; })
            };
        };
        Struct.prototype.inferrTypesByValue = function () {
            var _this = this;
            var value = this.value;
            var structAst = this.getStructAst();
            structAst.params.forEach(function (p) {
                var _a;
                var argType = internal_1.inferrType(value[p.name]);
                if (structAst.genericTypes.includes(p.type)) {
                    if (_this.inferredTypes[p.type]) {
                        if (_this.inferredTypes[p.type] != argType) {
                            throw new Error("The type of " + structAst.name + " is wrong, expected " + internal_1.structSign(structAst) + " but got " + JSON.stringify(value));
                        }
                    }
                    else {
                        Object.assign(_this.inferredTypes, (_a = {},
                            _a[p.type] = argType,
                            _a));
                    }
                }
                else if (internal_1.isGenericType(p.type)) {
                    if (structAst.genericTypes.length > 0) {
                        if (!internal_1.isGenericType(argType)) {
                            throw new Error("The type of " + structAst.name + " is wrong, expected " + internal_1.structSign(structAst) + " but got " + JSON.stringify(value));
                        }
                        var _b = __read(internal_1.parseGenericType(argType), 2), _ = _b[0], argGenericTypes_1 = _b[1];
                        var _c = __read(internal_1.parseGenericType(p.type), 2), __ = _c[0], paramGenericTypes = _c[1];
                        paramGenericTypes.forEach(function (t, index) {
                            var _a;
                            if (_this.inferredTypes[t]) {
                                if (_this.inferredTypes[t] != argGenericTypes_1[index]) {
                                    throw new Error("The type of " + structAst.name + " is wrong, expected " + internal_1.structSign(structAst) + " but got " + JSON.stringify(value));
                                }
                            }
                            else {
                                Object.assign(_this.inferredTypes, (_a = {},
                                    _a[t] = argGenericTypes_1[index],
                                    _a));
                            }
                        });
                    }
                }
            });
        };
        Struct.prototype.inferrTypesByAssign = function (assignType) {
            var _this = this;
            if (!Struct.hasGeneric(this)) {
                return false;
            }
            var _a = __read(internal_1.parseGenericType(assignType), 2), struct = _a[0], genericTypes = _a[1];
            var structAst = this.getStructAst();
            if (structAst.name !== struct)
                return false;
            if (structAst.genericTypes.length !== genericTypes.length)
                return false;
            var succces = true;
            structAst.genericTypes.forEach(function (t, index) {
                var _a;
                var realT = genericTypes[index];
                if (_this.inferredTypes[t]) {
                    if (_this.inferredTypes[t] != realT) {
                        succces = false;
                    }
                }
                else {
                    Object.assign(_this.inferredTypes, (_a = {},
                        _a[t] = realT,
                        _a));
                }
            });
            return succces;
        };
        Struct.prototype.toASM = function () {
            if (!this.sorted) {
                throw 'unbinded Struct can\'t call toASM';
            }
            this._asm = internal_1.flatternStruct(this, '').map(function (v) {
                return v.value.toASM();
            }).join(' ');
            return this._asm;
        };
        /**
         * @deprecated use  flatternStruct, see toASM
         */
        Struct.prototype.toArray = function () {
            if (!this.sorted) {
                throw 'unbinded Struct can\'t call toArray';
            }
            return Object.values(this.value).map(function (v) { return internal_1.toScryptType(v); });
        };
        Struct.prototype.memberByIndex = function (index) {
            if (!this.sorted) {
                throw 'unbinded Struct can\'t call memberByIndex';
            }
            var v = this.value;
            return Object.keys(v)[index];
        };
        /**
        * @deprecated use  getMemberFinalType
        */
        Struct.prototype.getMemberType = function (key) {
            var v = this.value;
            return internal_1.toScryptType(v[key]).type;
        };
        /**
         * Get the real member type of the structure
         */
        Struct.prototype.getMemberFinalType = function (key) {
            var member = this.memberByKey(key);
            return internal_1.typeOfArg(member);
        };
        /**
         * Get the member type declared by the structure by structAst
         */
        Struct.prototype.getMemberAstFinalType = function (key) {
            var structAst = this.getStructAst();
            var paramEntity = structAst.params.find(function (p) {
                return p.name === key;
            });
            if (!paramEntity) {
                throw new Error(key + " is member of struct " + structAst.name);
            }
            return this._typeResolver(paramEntity.type).finalType;
        };
        Struct.prototype.getMembers = function () {
            var v = this.value;
            return Object.keys(v);
        };
        Struct.prototype.memberByKey = function (key) {
            var v = this.value;
            var member = v[key];
            if (Array.isArray(member)) {
                return member;
            }
            return typeof member !== 'undefined' ? internal_1.toScryptType(member) : undefined;
        };
        Struct.prototype.clone = function () {
            var _this = this;
            return Object.assign(Object.create(this), {
                _value: Object.keys(this.value).reduce(function (pre, current) {
                    var _a, _b;
                    var value = _this.value[current];
                    if (Array.isArray(value)) {
                        Object.assign(pre, (_a = {},
                            _a[current] = internal_1.cloneArray(value),
                            _a));
                    }
                    else {
                        Object.assign(pre, (_b = {},
                            _b[current] = internal_1.toScryptType(value).clone(),
                            _b));
                    }
                    return pre;
                }, {})
            });
        };
        Struct.prototype.toLiteral = function () {
            var v = this.value;
            var l = Object.keys(this.value).map(function (key) {
                if (Array.isArray(v[key])) {
                    return internal_1.arrayToLiteral(v[key]);
                }
                else {
                    return internal_1.toScryptType(v[key]).toLiteral();
                }
            }).join(',');
            return "{" + l + "}";
        };
        Struct.prototype.toJSON = function () {
            var v = this.value;
            return Array.from(Object.keys(v)).reduce(function (obj, key) {
                var _a, _b, _c, _d;
                if (v[key] instanceof ScryptType) {
                    if (Struct.isStruct(v[key])) {
                        return Object.assign(obj, (_a = {}, _a[key] = v[key].toJSON(), _a));
                    }
                    else if (Array.isArray(v[key])) {
                        return Object.assign(obj, (_b = {}, _b[key] = internal_1.arrayToJson(v[key]), _b));
                    }
                    else {
                        return Object.assign(obj, (_c = {}, _c[key] = v[key].toLiteral(), _c));
                    }
                }
                else {
                    return Object.assign(obj, (_d = {}, _d[key] = v[key], _d));
                }
            }, {});
        };
        Struct.isStruct = function (arg) {
            return arg instanceof Struct;
        };
        Struct.prototype.serialize = function () {
            return serializer_1.serialize(this.value);
        };
        Struct.hasGeneric = function (self) {
            var ast = Struct.getStructAst(self);
            return (ast.genericTypes || []).length > 0;
        };
        Object.defineProperty(Struct.prototype, "finalType", {
            get: function () {
                var _this = this;
                if (this._typeResolver) {
                    if (Struct.hasGeneric(this)) {
                        var structAst = this.getStructAst();
                        var type = internal_1.toGenericType(this.type, structAst.genericTypes.map(function (t) { return (_this.inferredTypes[t] || t); }));
                        return this._typeResolver(type).finalType;
                    }
                    else {
                        return this._typeResolver(this.type).finalType;
                    }
                }
                return this.type;
            },
            enumerable: false,
            configurable: true
        });
        return Struct;
    }(ScryptType));
    exports.Struct = Struct;
    var Library = /** @class */ (function (_super) {
        __extends(Library, _super);
        function Library() {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var _this = _super.apply(this, __spread(args)) || this;
            // store the value of properties
            _this.properties = {};
            _this.inferredTypes = {};
            var libraryAst = _this.getLibraryAst();
            if (internal_1.canAssignProperty(libraryAst)) {
                args.forEach(function (arg, index) {
                    var _a;
                    Object.assign(_this.properties, (_a = {},
                        _a[libraryAst.params[index].name] = arg,
                        _a));
                });
            }
            return _this;
        }
        Library.setLibraryAst = function (self, libraryAst) {
            Object.getPrototypeOf(self).constructor.libraryAst = libraryAst;
        };
        Library.getLibraryAst = function (self) {
            return Object.getPrototypeOf(self).constructor.libraryAst;
        };
        Library.prototype.getCtorArgs = function () {
            var args = this.value;
            return internal_1.arrayToScryptType(args);
        };
        Library.prototype.cloneProperties = function () {
            var _this = this;
            return Object.keys(this.properties).reduce(function (pre, current) {
                var _a, _b;
                var value = _this.properties[current];
                if (Array.isArray(value)) {
                    Object.assign(pre, (_a = {},
                        _a[current] = internal_1.cloneArray(value),
                        _a));
                }
                else {
                    Object.assign(pre, (_b = {},
                        _b[current] = internal_1.toScryptType(value).clone(),
                        _b));
                }
                return pre;
            }, {});
        };
        Library.prototype.clone = function () {
            return Object.assign(Object.create(this), {
                _value: internal_1.cloneArray(this.getCtorArgs()),
                properties: this.cloneProperties()
            });
        };
        Library.prototype.getProperty = function (property) {
            var p = this.properties[property];
            if (typeof p === 'undefined') {
                throw new Error("Property " + property + " not found, the properties of the current library are: " + JSON.stringify(this.properties));
            }
            return internal_1.toScryptType(p);
        };
        Library.prototype.getProperties = function () {
            return this.properties;
        };
        Library.prototype.getLibraryAst = function () {
            var _this = this;
            var libraryAst = Library.getLibraryAst(this);
            return {
                name: libraryAst.name,
                params: libraryAst.params.map(function (p) { return ({
                    name: p.name,
                    type: internal_1.resolveGenericType(_this.inferredTypes, p.type)
                }); }),
                properties: libraryAst.properties.map(function (p) { return ({
                    name: p.name,
                    type: internal_1.resolveGenericType(_this.inferredTypes, p.type)
                }); }),
                genericTypes: libraryAst.genericTypes.map(function (t) { return t; })
            };
        };
        Library.prototype.flatten = function (varName) {
            return internal_1.flatternLibrary(this, varName);
        };
        Library.prototype.checkValue = function (args) {
            var libraryAst = Library.getLibraryAst(this);
            if (libraryAst.params.length !== args.length) {
                throw new Error("The type of " + libraryAst.name + " is wrong, expected " + internal_1.librarySign(libraryAst) + " but got " + JSON.stringify(args));
            }
            return args;
        };
        Library.prototype.inferrTypesByValue = function () {
            var _this = this;
            var args = this.value;
            var libraryAst = this.getLibraryAst();
            libraryAst.params.forEach(function (p, index) {
                var _a;
                var argType = internal_1.inferrType(args[index]);
                if (libraryAst.genericTypes.includes(p.type)) {
                    if (_this.inferredTypes[p.type]) {
                        if (_this.inferredTypes[p.type] != argType) {
                            throw new Error("The type of " + libraryAst.name + " is wrong, expected " + internal_1.librarySign(libraryAst) + " but got " + JSON.stringify(args));
                        }
                    }
                    else {
                        Object.assign(_this.inferredTypes, (_a = {},
                            _a[p.type] = argType,
                            _a));
                    }
                }
                else if (internal_1.isGenericType(p.type)) {
                    if (libraryAst.genericTypes.length > 0) {
                        if (!internal_1.isGenericType(argType)) {
                            throw new Error("The type of " + libraryAst.name + " is wrong, expected " + internal_1.librarySign(libraryAst) + " but got " + JSON.stringify(args));
                        }
                        var _b = __read(internal_1.parseGenericType(argType), 2), _ = _b[0], argGenericTypes_2 = _b[1];
                        var _c = __read(internal_1.parseGenericType(p.type), 2), __ = _c[0], paramGenericTypes = _c[1];
                        paramGenericTypes.forEach(function (t, index) {
                            var _a;
                            if (_this.inferredTypes[t]) {
                                if (_this.inferredTypes[t] != argGenericTypes_2[index]) {
                                    throw new Error("The type of " + libraryAst.name + " is wrong, expected " + internal_1.librarySign(libraryAst) + " but got " + JSON.stringify(args));
                                }
                            }
                            else {
                                Object.assign(_this.inferredTypes, (_a = {},
                                    _a[t] = argGenericTypes_2[index],
                                    _a));
                            }
                        });
                    }
                }
            });
        };
        Library.prototype.inferrTypesByAssign = function (assignType) {
            var _this = this;
            if (!Library.hasGeneric(this)) {
                return false;
            }
            var _a = __read(internal_1.parseGenericType(assignType), 2), library = _a[0], genericTypes = _a[1];
            var libraryAst = this.getLibraryAst();
            if (libraryAst.name !== library)
                return false;
            if (libraryAst.genericTypes.length !== genericTypes.length)
                return false;
            var succces = true;
            libraryAst.genericTypes.forEach(function (t, index) {
                var _a;
                var realT = genericTypes[index];
                if (_this.inferredTypes[t]) {
                    if (_this.inferredTypes[t] != realT) {
                        succces = false;
                    }
                }
                else {
                    Object.assign(_this.inferredTypes, (_a = {},
                        _a[t] = realT,
                        _a));
                }
            });
            return succces;
        };
        Library.hasGeneric = function (self) {
            var ast = Library.getLibraryAst(self);
            return (ast.genericTypes || []).length > 0;
        };
        Library.prototype.attach = function () {
            var _this = this;
            var libraryAst = this.getLibraryAst();
            this._type = libraryAst.name;
            var args = this.value;
            //check value type
            libraryAst.params.forEach(function (param, index) {
                var error = internal_1.checkSupportedParamType(args[index], param, _this._typeResolver);
                if (error) {
                    throw new Error("The type of " + libraryAst.name + " is wrong, expected " + internal_1.librarySign(libraryAst) + " but got " + JSON.stringify(args));
                }
            });
            libraryAst.properties.forEach(function (p) {
                Object.defineProperty(_this, p.name, {
                    get: function () {
                        return this.properties[p.name];
                    },
                    set: function (value) {
                        this.properties[p.name] = value;
                    }
                });
            });
        };
        Library.isLibrary = function (arg) {
            return arg instanceof Library;
        };
        Library.prototype.bind = function () {
            this.inferrTypesByValue();
            this.attach();
        };
        Library.prototype.setProperties = function (properties) {
            this.properties = Object.assign(this.properties, properties);
            return this;
        };
        Library.prototype.toJSON = function () {
            return Array.from(Object.values(this.value)).map(function (v) {
                if (Array.isArray(v)) {
                    return internal_1.arrayToJson(v);
                }
                else {
                    return internal_1.toScryptType(v).toJSON();
                }
            });
        };
        Library.prototype.toLiteral = function () {
            return internal_1.arrayToLiteral(this.value);
        };
        Object.defineProperty(Library.prototype, "finalType", {
            get: function () {
                var _this = this;
                if (this._typeResolver) {
                    if (Library.hasGeneric(this)) {
                        var libraryAst = this.getLibraryAst();
                        var type = internal_1.toGenericType(this.type, libraryAst.genericTypes.map(function (t) { return (_this.inferredTypes[t] || t); }));
                        return this._typeResolver(type).finalType;
                    }
                    else {
                        return this._typeResolver(this.type).finalType;
                    }
                }
                return this.type;
            },
            enumerable: false,
            configurable: true
        });
        return Library;
    }(ScryptType));
    exports.Library = Library;
    var HashedMap = /** @class */ (function (_super) {
        __extends(HashedMap, _super);
        function HashedMap(data) {
            var _this = _super.call(this, data) || this;
            _this.setProperties({
                '_data': data
            });
            _this._typeResolver = function (t) { return ({ finalType: t, symbolType: SymbolType.Library }); }; //we should assign this before bind
            _this.bind();
            return _this;
        }
        return HashedMap;
    }(Library));
    exports.HashedMap = HashedMap;
    HashedMap.libraryAst = {
        name: 'HashedMap',
        params: [
            {
                name: '_data',
                type: 'bytes'
            }
        ],
        properties: [
            {
                name: '_data',
                type: 'bytes'
            }
        ],
        genericTypes: ['K', 'V']
    };
    var HashedSet = /** @class */ (function (_super) {
        __extends(HashedSet, _super);
        function HashedSet(data) {
            var _this = _super.call(this, data) || this;
            _this.setProperties({
                '_data': data
            });
            _this._typeResolver = function (t) { return ({ finalType: t, symbolType: SymbolType.Library }); }; //we should assign this before bind
            _this.bind();
            return _this;
        }
        return HashedSet;
    }(Library));
    exports.HashedSet = HashedSet;
    HashedSet.libraryAst = {
        name: 'HashedSet',
        params: [
            {
                name: '_data',
                type: 'bytes'
            }
        ],
        properties: [
            {
                name: '_data',
                type: 'bytes'
            }
        ],
        genericTypes: ['E']
    };
    var SortedItem = /** @class */ (function (_super) {
        __extends(SortedItem, _super);
        function SortedItem(data) {
            var _this = _super.call(this, data) || this;
            _this._typeResolver = function (t) { return ({ finalType: t, symbolType: SymbolType.Struct }); }; //we should assign this before bind
            _this.bind();
            return _this;
        }
        return SortedItem;
    }(Struct));
    exports.SortedItem = SortedItem;
    SortedItem.structAst = {
        name: 'SortedItem',
        params: [
            {
                name: 'item',
                type: 'T'
            },
            {
                name: 'idx',
                type: 'int'
            }
        ],
        genericTypes: ['T']
    };
    var VariableType;
    (function (VariableType) {
        VariableType["BOOL"] = "bool";
        VariableType["INT"] = "int";
        VariableType["BYTES"] = "bytes";
        VariableType["PUBKEY"] = "PubKey";
        VariableType["PRIVKEY"] = "PrivKey";
        VariableType["SIG"] = "Sig";
        VariableType["RIPEMD160"] = "Ripemd160";
        VariableType["SHA1"] = "Sha1";
        VariableType["SHA256"] = "Sha256";
        VariableType["SIGHASHTYPE"] = "SigHashType";
        VariableType["SIGHASHPREIMAGE"] = "SigHashPreimage";
        VariableType["OPCODETYPE"] = "OpCodeType";
        VariableType["PUBKEYHASH"] = "PubKeyHash";
        VariableType["STRUCT"] = "struct";
        VariableType["LIBRARY"] = "library";
    })(VariableType = exports.VariableType || (exports.VariableType = {}));
    exports.BasicType = Object.keys(VariableType).map(function (key) { return VariableType[key]; });
    exports.BasicScryptType = (_a = {},
        _a[VariableType.BOOL] = Bool,
        _a[VariableType.INT] = Int,
        _a[VariableType.BYTES] = Bytes,
        _a[VariableType.PUBKEY] = PubKey,
        _a[VariableType.PRIVKEY] = PrivKey,
        _a[VariableType.SIG] = Sig,
        _a[VariableType.RIPEMD160] = Ripemd160,
        _a[VariableType.SHA1] = Sha1,
        _a[VariableType.SHA256] = Sha256,
        _a[VariableType.SIGHASHTYPE] = SigHashType,
        _a[VariableType.OPCODETYPE] = OpCodeType,
        _a[VariableType.SIGHASHPREIMAGE] = SigHashPreimage,
        _a);
    function serializeSupportedParamType(x) {
        if (typeof x === 'boolean') {
            return new Bool(x).serialize();
        }
        else if (typeof x === 'number' || typeof x === 'bigint') {
            return serializer_1.serialize(x);
        }
        else if (x instanceof ScryptType) {
            return x.serialize();
        }
        else {
            throw new Error('serializeSupportedParamType unsupported: ' + x);
        }
    }
    exports.serializeSupportedParamType = serializeSupportedParamType;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./internal":283,"./serializer":286,"buffer":84}],286:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.deserializeState = exports.serializeState = exports.serialize = exports.serializeInt = exports.STATE_LEN_4BYTES = exports.STATE_LEN_2BYTES = void 0;
    var utils_1 = require("./utils");
    var Script = utils_1.mvc.Script;
    var Opcode = utils_1.mvc.Opcode;
    var BN = utils_1.mvc.crypto.BN;
    // number of bytes to denote state length after serialization, exclusing varint prefix
    exports.STATE_LEN_2BYTES = 2;
    exports.STATE_LEN_4BYTES = 4;
    function serializeBool(flag) {
        return flag ? 'OP_TRUE' : 'OP_FALSE';
    }
    function serializeInt(n) {
        var num = new BN(n);
        if (typeof n === 'string') {
            if (n.startsWith('0x')) {
                num = new BN(n.substr(2), 16);
            }
        }
        if (num.eqn(0)) {
            return '00';
        }
        return num.toSM({ endian: 'little' }).toString('hex');
    }
    exports.serializeInt = serializeInt;
    function serializeString(str) {
        if (str === '') {
            return '00';
        }
        var buf = Buffer.from(str, 'utf8');
        return buf.toString('hex');
    }
    // TODO: validate
    function serializeBytes(hexStr) {
        return hexStr;
    }
    function serializeWithSchema(state, key, schema) {
        if (schema === void 0) { schema = undefined; }
        var type = schema[key];
        if (type === 'boolean') {
            return serializeBool(state[key]);
        }
        else if (type === 'number') {
            return serializeInt(state[key]);
        }
        else if (type === 'bigint') {
            return serializeInt(state[key]);
        }
        else if (type === 'string') {
            return serializeString(state[key]);
        }
        else {
            return serializeBytes(state[key]);
        }
    }
    function serialize(x) {
        if (typeof x === 'boolean') {
            return serializeBool(x);
        }
        if (typeof x === 'number') {
            return serializeInt(x);
        }
        if (typeof x === 'bigint') {
            return serializeInt(x);
        }
        else {
            return serializeBytes(x);
        }
    }
    exports.serialize = serialize;
    // serialize contract state into Script ASM
    function serializeState(state, stateBytes, schema) {
        var e_1, _a;
        if (stateBytes === void 0) { stateBytes = exports.STATE_LEN_2BYTES; }
        if (schema === void 0) { schema = undefined; }
        var asms = [];
        var keys = Object.keys(state);
        try {
            for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
                var key = keys_1_1.value;
                if (schema) {
                    var str = serializeWithSchema(state, key, schema);
                    asms.push(str);
                }
                else {
                    var str = serialize(state[key]);
                    asms.push(str);
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        var script = Script.fromASM(asms.join(' '));
        var scriptHex = script.toHex();
        var stateLen = scriptHex.length / 2;
        // use fixed size to denote state len
        var len = utils_1.num2bin(stateLen, stateBytes);
        return script.toASM() + ' ' + len;
    }
    exports.serializeState = serializeState;
    var OpState = /** @class */ (function () {
        function OpState(op) {
            this.op = op;
        }
        OpState.prototype.toNumber = function () {
            if (this.op.opcodenum === Opcode.OP_1) {
                return Number(1);
            }
            else if (this.op.opcodenum === Opcode.OP_0) {
                return Number(0);
            }
            else if (this.op.opcodenum === Opcode.OP_1NEGATE) {
                return Number(-1);
            }
            else if (this.op.opcodenum >= Opcode.OP_2 && this.op.opcodenum <= Opcode.OP_16) {
                return Number(this.op.opcodenum - Opcode.OP_2 + 2);
            }
            else {
                if (!this.op.buf)
                    throw new Error('state does not have a number representation');
                return Number(utils_1.bin2num(this.op.buf));
            }
        };
        OpState.prototype.toBigInt = function () {
            if (this.op.opcodenum === Opcode.OP_1) {
                return BigInt(1);
            }
            else if (this.op.opcodenum === Opcode.OP_0) {
                return BigInt(0);
            }
            else if (this.op.opcodenum === Opcode.OP_1NEGATE) {
                return BigInt(-1);
            }
            else if (this.op.opcodenum >= Opcode.OP_2 && this.op.opcodenum <= Opcode.OP_16) {
                return BigInt(this.op.opcodenum - Opcode.OP_2 + 2);
            }
            else {
                if (!this.op.buf)
                    throw new Error('state does not have a number representation');
                return BigInt(utils_1.bin2num(this.op.buf));
            }
        };
        OpState.prototype.toBoolean = function () {
            return this.toNumber() !== Number(0);
        };
        OpState.prototype.toHex = function () {
            if (!this.op.buf)
                throw new Error('state does not have a hexadecimal representation');
            return this.op.buf.toString('hex');
        };
        OpState.prototype.toString = function (arg) {
            if (arg === void 0) { arg = 'utf8'; }
            if (!this.op.buf) {
                throw new Error('state does not have a string representation');
            }
            if (this.op.buf[0] === 0) {
                return '';
            }
            return this.op.buf.toString(arg);
        };
        return OpState;
    }());
    // deserialize Script or Script Hex or Script ASM Code to contract state array and object
    function deserializeState(s, schema) {
        if (schema === void 0) { schema = undefined; }
        var script;
        try {
            script = new Script(s);
        }
        catch (e) {
            script = Script.fromASM(s);
        }
        var chunks = script.chunks;
        var states = [];
        var pos = chunks.length;
        //the last opcode is length of stats, skip
        for (var i = pos - 2; i >= 0; i--) {
            var opcodenum = chunks[i].opcodenum;
            if (opcodenum === Opcode.OP_RETURN) {
                break;
            }
            else {
                states.unshift(new OpState(chunks[i]));
            }
        }
        //deserialize to an array
        if (!schema) {
            return states;
        }
        //deserialize to an object
        var ret;
        if (Array.isArray(schema)) {
            ret = [];
        }
        else {
            ret = {};
        }
        var keys = Object.keys(schema);
        for (var i = 0; i < states.length; i++) {
            var key = keys[i];
            if (!key) {
                break;
            }
            var val = schema[key];
            if (val === 'boolean' || typeof val === 'boolean') {
                ret[key] = states[i].toBoolean();
            }
            else if (val === 'number' || typeof val === 'number') {
                ret[key] = states[i].toNumber();
            }
            else if (val === 'bigint' || typeof val === 'bigint') {
                if (typeof BigInt === 'function') {
                    ret[key] = states[i].toBigInt();
                }
                else {
                    ret[key] = states[i].toNumber();
                }
            }
            else if (val === 'string') {
                ret[key] = states[i].toString();
            }
            else {
                ret[key] = states[i].toHex();
            }
        }
        return ret;
    }
    exports.deserializeState = deserializeState;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./utils":287,"buffer":84}],287:[function(require,module,exports){
    (function (process,Buffer,__dirname){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    var __generator = (this && this.__generator) || function (thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    };
    var __read = (this && this.__read) || function (o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    };
    var __spread = (this && this.__spread) || function () {
        for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
        return ar;
    };
    var __values = (this && this.__values) || function(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m) return m.call(o);
        if (o && typeof o.length === "number") return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.parseStateHex = exports.findSrcInfoV1 = exports.findSrcInfoV2 = exports.JSONStringify = exports.JSONParserSync = exports.JSONParser = exports.invert = exports.xor = exports.or = exports.and = exports.int2Number = exports.canAssignProperty = exports.arrayToLiteral = exports.structSign = exports.librarySign = exports.resolveGenericType = exports.inferrType = exports.cloneArray = exports.arrayToJson = exports.arrayToScryptType = exports.toScryptType = exports.parseAbiFromUnlockingScript = exports.buildPublicKeyHashScript = exports.buildOpreturnScript = exports.writeVarint = exports.toLEUnsigned = exports.len = exports.readLaunchJson = exports.hash256 = exports.sha256 = exports.hash160 = exports.parseGenericType = exports.isGenericType = exports.toHashedSet = exports.toHashedMap = exports.toData = exports.findKeyIndex = exports.sortset = exports.sortmap = exports.flattenSha256 = exports.deserializeArgfromState = exports.deserializeArgfromHex = exports.readBytes = exports.buildDefaultStateProps = exports.buildContractState = exports.buildContractCode = exports.findStatic = exports.findConstStatic = exports.isInteger = exports.toLiteral = exports.createArray = exports.createDefaultLibrary = exports.createLibraryProperties = exports.createLibrary = exports.createStruct = exports.stripAnsi = exports.ansiRegex = exports.resolveType = exports.resolveConstValue = exports.genLaunchConfigFile = exports.newCall = exports.compileContractAsync = exports.compileContract = exports.isEmpty = exports.readFileByLine = exports.typeOfArg = exports.flatternParams = exports.flatternStateArgs = exports.flatternCtorArgs = exports.flatternLibraryState = exports.flatternLibrary = exports.flatternStruct = exports.flatternArray = exports.subscript = exports.subArrayType = exports.toGenericType = exports.toLiteralArrayType = exports.arrayTypeAndSize = exports.arrayTypeAndSizeStr = exports.checkSupportedParamType = exports.checkStruct = exports.checkStructField = exports.findStructByType = exports.getNameByType = exports.isArrayType = exports.findStructByName = exports.literal2Asm = exports.uri2path = exports.path2uri = exports.isNode = exports.bin2num = exports.num2bin = exports.getLowSPreimage = exports.hashIsPositiveNumber = exports.getPreimage = exports.toHex = exports.signTx = exports.getValidatedHexString = exports.hexStringToBytes = exports.bytesToHexString = exports.bytes2Literal = exports.hex2ScryptType = exports.asm2ScryptType = exports.literal2ScryptType = exports.isStringLiteral = exports.parseLiteral = exports.intValue2hex = exports.int2Value = exports.hex2int = exports.asm2int = exports.int2Asm = exports.bool2Asm = exports.DEFAULT_SIGHASH_TYPE = exports.DEFAULT_FLAGS = exports.ECIES = exports.mvc = void 0;
    var url_1 = require("url");
    var mvc = require("mvc-lib");
    exports.mvc = mvc;
    var ECIES = require("mvc-lib/ecies");
    exports.ECIES = ECIES;
    var fs = require("fs");
    var path_1 = require("path");
    var os_1 = require("os");
    var json_ext_1 = require("@discoveryjs/json-ext");
    var sourcemap_codec_1 = require("sourcemap-codec");
    var internal_1 = require("./internal");
    var compilerWrapper_1 = require("./compilerWrapper");
    var scryptTypes_1 = require("./scryptTypes");
    var BN = mvc.crypto.BN;
    var Interp = mvc.Script.Interpreter;
    exports.DEFAULT_FLAGS = 
    //Interp.SCRIPT_VERIFY_P2SH | Interp.SCRIPT_VERIFY_CLEANSTACK | // no longer applies now p2sh is deprecated: cleanstack only applies to p2sh
    Interp.SCRIPT_ENABLE_MAGNETIC_OPCODES |
        Interp.SCRIPT_ENABLE_MONOLITH_OPCODES | // TODO: to be removed after upgrade to mvc 2.0
        Interp.SCRIPT_VERIFY_STRICTENC |
        Interp.SCRIPT_ENABLE_SIGHASH_FORKID |
        Interp.SCRIPT_VERIFY_LOW_S |
        Interp.SCRIPT_VERIFY_NULLFAIL |
        Interp.SCRIPT_VERIFY_DERSIG |
        Interp.SCRIPT_VERIFY_MINIMALDATA |
        Interp.SCRIPT_VERIFY_NULLDUMMY |
        Interp.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
        Interp.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
        Interp.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
        Interp.SCRIPT_VERIFY_CLEANSTACK;
    exports.DEFAULT_SIGHASH_TYPE = mvc.crypto.Signature.SIGHASH_ALL | mvc.crypto.Signature.SIGHASH_FORKID;
    function bool2Asm(str) {
        if (str === 'true') {
            return 'OP_TRUE';
        }
        if (str === 'false') {
            return 'OP_FALSE';
        }
        throw new Error("invalid str '" + str + "' to convert to bool");
    }
    exports.bool2Asm = bool2Asm;
    /**
     * decimal or hex int to little-endian signed magnitude
     */
    function int2Asm(str) {
        if (/^(-?\d+)$/.test(str) || /^0x([0-9a-fA-F]+)$/.test(str)) {
            var number = str.startsWith('0x') ? new BN(str.substring(2), 16) : new BN(str, 10);
            if (number.eqn(-1)) {
                return 'OP_1NEGATE';
            }
            if (number.gten(0) && number.lten(16)) {
                return 'OP_' + number.toString();
            }
            var m = number.toSM({ endian: 'little' });
            return m.toString('hex');
        }
        else {
            throw new Error("invalid str '" + str + "' to convert to int");
        }
    }
    exports.int2Asm = int2Asm;
    /**
     * convert asm string to number or bigint
     */
    function asm2int(str) {
        switch (str) {
            case 'OP_1NEGATE':
                return -1;
            case '0':
            case 'OP_0':
            case 'OP_1':
            case 'OP_2':
            case 'OP_3':
            case 'OP_4':
            case 'OP_5':
            case 'OP_6':
            case 'OP_7':
            case 'OP_8':
            case 'OP_9':
            case 'OP_10':
            case 'OP_11':
            case 'OP_12':
            case 'OP_13':
            case 'OP_14':
            case 'OP_15':
            case 'OP_16':
                return parseInt(str.replace('OP_', ''));
            default: {
                var value = getValidatedHexString(str);
                var bn = BN.fromHex(value, {
                    endian: 'little',
                });
                if (bn.toNumber() < Number.MAX_SAFE_INTEGER && bn.toNumber() > Number.MIN_SAFE_INTEGER) {
                    return bn.toNumber();
                }
                else {
                    return bn.toString();
                }
            }
        }
    }
    exports.asm2int = asm2int;
    /**
     * convert asm string to number or bigint
     */
    function hex2int(str) {
        var b = mvc.Script.fromHex(str);
        var chuck = b.chunks[0];
        switch (chuck.opcodenum) {
            case 0:
                return 0;
            case 79:
                return -1;
            case 81:
            case 82:
            case 83:
            case 84:
            case 85:
            case 86:
            case 87:
            case 88:
            case 89:
            case 90:
            case 91:
            case 92:
            case 93:
            case 94:
            case 95:
            case 96:
                return chuck.opcodenum - 80;
            default: {
                var value = chuck.buf.toString('hex');
                var bn = BN.fromHex(value, {
                    endian: 'little',
                });
                if (bn.toNumber() < Number.MAX_SAFE_INTEGER && bn.toNumber() > Number.MIN_SAFE_INTEGER) {
                    return bn.toNumber();
                }
                else {
                    return bn.toString();
                }
            }
        }
    }
    exports.hex2int = hex2int;
    /**
     * decimal int or hex str to number or bigint
     */
    function int2Value(str) {
        if (/^(-?\d+)$/.test(str) || /^0x([0-9a-fA-F]+)$/.test(str)) {
            var bn = str.startsWith('0x') ? new BN(str.substring(2), 16) : new BN(str, 10);
            if (bn.toNumber() < Number.MAX_SAFE_INTEGER && bn.toNumber() > Number.MIN_SAFE_INTEGER) {
                return bn.toNumber();
            }
            else {
                return str;
            }
        }
        else {
            throw new Error("invalid str '" + str + "' to convert to int");
        }
    }
    exports.int2Value = int2Value;
    function intValue2hex(val) {
        var hex = val.toString(16);
        if (hex.length % 2 === 1) {
            hex = '0' + hex;
        }
        return hex;
    }
    exports.intValue2hex = intValue2hex;
    function parseBytesLiteral(hex) {
        var hexString = getValidatedHexString(hex);
        if (hexString === '') {
            return ['OP_0', hexString, internal_1.VariableType.BYTES];
        }
        if (hexString.length / 2 > 1) {
            return [hexString, hexString, internal_1.VariableType.BYTES];
        }
        var intValue = parseInt(hexString, 16);
        if (intValue >= 1 && intValue <= 16) {
            return ["OP_" + intValue, hexString, internal_1.VariableType.BYTES];
        }
        return [hexString, hexString, internal_1.VariableType.BYTES];
    }
    function parseLiteral(l) {
        // bool
        if (l === 'false') {
            return ['OP_FALSE', false, internal_1.VariableType.BOOL];
        }
        if (l === 'true') {
            return ['OP_TRUE', true, internal_1.VariableType.BOOL];
        }
        // hex int
        var m = /^(0x[0-9a-fA-F]+)$/.exec(l);
        if (m) {
            return [int2Asm(m[1]), int2Value(m[1]), internal_1.VariableType.INT];
        }
        // decimal int
        m = /^(-?\d+)$/.exec(l);
        if (m) {
            return [int2Asm(m[1]), int2Value(m[1]), internal_1.VariableType.INT];
        }
        // bytes
        // note: special handling of empty bytes b''
        m = /^b'([\da-fA-F]*)'$/.exec(l);
        if (m) {
            return parseBytesLiteral(m[1]);
        }
        // String
        m = /^"([\s\S]*)"$/.exec(l);
        if (m) {
            var value = scryptTypes_1.String.toUtf8Hex(m[1]);
            return parseBytesLiteral(value);
        }
        // PrivKey
        // 1) decimal int
        m = /^PrivKey\((-?\d+)\)$/.exec(l);
        if (m) {
            return [int2Asm(m[1]), int2Value(m[1]), internal_1.VariableType.PRIVKEY];
        }
        // 2) hex int
        m = /^PrivKey\((0x[0-9a-fA-F]+)\)$/.exec(l);
        if (m) {
            return [int2Asm(m[1]), int2Value(m[1]), internal_1.VariableType.PRIVKEY];
        }
        // PubKey
        m = /^PubKey\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.PUBKEY];
        }
        // Sig
        m = /^Sig\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.SIG];
        }
        // Ripemd160
        m = /^Ripemd160\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.RIPEMD160];
        }
        // Sha1
        m = /^Sha1\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.SHA1];
        }
        // Sha256
        m = /^Sha256\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.SHA256];
        }
        // SigHashType
        m = /^SigHashType\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var bn = new BN(getValidatedHexString(m[1]), 16);
            return [bn.toString('hex', 2), bn.toNumber(), internal_1.VariableType.SIGHASHTYPE];
        }
        // SigHashPreimage
        m = /^SigHashPreimage\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.SIGHASHPREIMAGE];
        }
        // OpCodeType
        m = /^OpCodeType\(b'([\da-fA-F]+)'\)$/.exec(l);
        if (m) {
            var value = getValidatedHexString(m[1]);
            return [value, value, internal_1.VariableType.OPCODETYPE];
        }
        // Struct
        m = /^\{([\s\S]*)\}$/.exec(l);
        if (m) {
            // we use object to constructor a struct, no use literal, so here we return empty
            return ['', '', internal_1.VariableType.STRUCT];
        }
        // Library
        m = /^\[([\s\S]*)\]$/.exec(l);
        if (m) {
            // we use array to constructor a library, no use literal, so here we return empty
            return ['', '', internal_1.VariableType.LIBRARY];
        }
        throw new Error("<" + l + "> cannot be cast to ASM format, only sCrypt native types supported");
    }
    exports.parseLiteral = parseLiteral;
    function isStringLiteral(l) {
        var m = /^"([\s\S]*)"$/.exec(l.trim());
        if (m) {
            return true;
        }
        return false;
    }
    exports.isStringLiteral = isStringLiteral;
    /**
     * convert literals to Scrypt Type
     */
    function literal2ScryptType(l) {
        var _a = __read(parseLiteral(l), 3), asm = _a[0], value = _a[1], type = _a[2];
        switch (type) {
            case internal_1.VariableType.BOOL:
                return new internal_1.Bool(value);
            case internal_1.VariableType.INT:
                return new internal_1.Int(value);
            case internal_1.VariableType.BYTES:
                return isStringLiteral(l) ? new scryptTypes_1.String(scryptTypes_1.String.fromUtf8Hex(value)) : new internal_1.Bytes(value);
            case internal_1.VariableType.PRIVKEY:
                return new internal_1.PrivKey(value);
            case internal_1.VariableType.PUBKEY:
                return new internal_1.PubKey(value);
            case internal_1.VariableType.SIG:
                return new internal_1.Sig(value);
            case internal_1.VariableType.RIPEMD160:
                return new internal_1.Ripemd160(value);
            case internal_1.VariableType.SHA1:
                return new internal_1.Sha1(value);
            case internal_1.VariableType.SHA256:
                return new internal_1.Sha256(value);
            case internal_1.VariableType.SIGHASHTYPE:
                return new internal_1.SigHashType(value);
            case internal_1.VariableType.SIGHASHPREIMAGE:
                return new internal_1.SigHashPreimage(value);
            case internal_1.VariableType.OPCODETYPE:
                return new internal_1.OpCodeType(value);
            default:
                throw new Error("<" + l + "> cannot be cast to ScryptType, only sCrypt native types supported");
        }
    }
    exports.literal2ScryptType = literal2ScryptType;
    function asm2ScryptType(type, asm) {
        switch (type) {
            case internal_1.VariableType.BOOL:
                return new internal_1.Bool(BN.fromString(asm) > 0 ? true : false);
            case internal_1.VariableType.INT:
                return new internal_1.Int(asm2int(asm));
            case internal_1.VariableType.BYTES:
                return new internal_1.Bytes(asm == '0' || asm == 'OP_0' || asm == 'OP_FALSE' ? '' : asm);
            case internal_1.VariableType.PRIVKEY:
                return new internal_1.PrivKey(asm2int(asm));
            case internal_1.VariableType.PUBKEY:
                return new internal_1.PubKey(asm);
            case internal_1.VariableType.SIG:
                return new internal_1.Sig(asm);
            case internal_1.VariableType.RIPEMD160:
                return new internal_1.Ripemd160(asm);
            case internal_1.VariableType.SHA1:
                return new internal_1.Sha1(asm);
            case internal_1.VariableType.SHA256:
                return new internal_1.Sha256(asm);
            case internal_1.VariableType.SIGHASHTYPE:
                return new internal_1.SigHashType(asm2int(asm));
            case internal_1.VariableType.SIGHASHPREIMAGE:
                return new internal_1.SigHashPreimage(asm);
            case internal_1.VariableType.OPCODETYPE:
                return new internal_1.OpCodeType(asm);
            default:
                throw new Error("<" + type + "> cannot be cast to ScryptType, only sCrypt native types supported");
        }
    }
    exports.asm2ScryptType = asm2ScryptType;
    function hex2ScryptType(type, hex) {
        var b = mvc.Script.fromHex(hex);
        var chuck = b.chunks[0];
        switch (type) {
            case internal_1.VariableType.BOOL:
                return new internal_1.Bool(chuck.opcodenum == 0x51 ? true : false);
            case internal_1.VariableType.INT:
                return new internal_1.Int(hex2int(hex));
            case internal_1.VariableType.BYTES:
                return new internal_1.Bytes(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.PRIVKEY:
                return new internal_1.PrivKey(hex2int(hex));
            case internal_1.VariableType.PUBKEY:
                return new internal_1.PubKey(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.SIG:
                return new internal_1.Sig(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.RIPEMD160:
                return new internal_1.Ripemd160(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.SHA1:
                return new internal_1.Sha1(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.SHA256:
                return new internal_1.Sha256(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.SIGHASHTYPE:
                return new internal_1.SigHashType(hex2int(hex));
            case internal_1.VariableType.SIGHASHPREIMAGE:
                return new internal_1.SigHashPreimage(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            case internal_1.VariableType.OPCODETYPE:
                return new internal_1.OpCodeType(chuck.opcodenum == 0 ? '' : chuck.buf.toString('hex'));
            default:
                throw new Error("<" + type + "> cannot be cast to ScryptType, only sCrypt native types supported");
        }
    }
    exports.hex2ScryptType = hex2ScryptType;
    function bytes2Literal(bytearray, type) {
        switch (type) {
            case 'bool':
                return BN.fromBuffer(bytearray, { endian: 'little' }) > 0 ? 'true' : 'false';
            case 'int':
            case 'PrivKey':
                return BN.fromSM(bytearray, { endian: 'little' }).toString();
            case 'bytes':
                return "b'" + bytesToHexString(bytearray) + "'";
            default:
                return "b'" + bytesToHexString(bytearray) + "'";
        }
    }
    exports.bytes2Literal = bytes2Literal;
    function bytesToHexString(bytearray) {
        return bytearray.reduce(function (o, c) {
            return (o += ('0' + (c & 0xff).toString(16)).slice(-2));
        }, '');
    }
    exports.bytesToHexString = bytesToHexString;
    function hexStringToBytes(hex) {
        getValidatedHexString(hex);
        return hex
            .split('')
            .reduce(function (o, c, i) {
            if (i % 2 === 0) {
                o.push(c);
            }
            else {
                o[o.length - 1] += c;
            }
            return o;
        }, new Array())
            .map(function (b) { return parseInt(b, 16); });
    }
    exports.hexStringToBytes = hexStringToBytes;
    function getValidatedHexString(hex, allowEmpty) {
        if (allowEmpty === void 0) { allowEmpty = true; }
        var ret = hex.trim();
        if (ret.length < 1 && !allowEmpty) {
            throw new Error('can\'t be empty string');
        }
        if (ret.length % 2) {
            throw new Error(ret + " should have even length");
        }
        if (ret.length > 0 && !/^[\da-f]+$/i.test(ret)) {
            throw new Error(ret + " should only contain [0-9] or characters [a-fA-F]");
        }
        return ret;
    }
    exports.getValidatedHexString = getValidatedHexString;
    function signTx(tx, privateKey, lockingScript, inputAmount, inputIndex, sighashType, flags) {
        if (inputIndex === void 0) { inputIndex = 0; }
        if (sighashType === void 0) { sighashType = exports.DEFAULT_SIGHASH_TYPE; }
        if (flags === void 0) { flags = exports.DEFAULT_FLAGS; }
        if (!tx) {
            throw new Error('param tx can not be empty');
        }
        if (!privateKey) {
            throw new Error('param privateKey can not be empty');
        }
        if (!lockingScript) {
            throw new Error('param lockingScript can not be empty');
        }
        if (!inputAmount) {
            throw new Error('param inputAmount can not be empty');
        }
        if (typeof lockingScript === 'string') {
            throw new Error('Breaking change: LockingScript in ASM format is no longer supported, please use the lockingScript object directly');
        }
        var buf = toHex(mvc.Transaction.sighash
            .sign(tx, privateKey, sighashType, inputIndex, lockingScript, new mvc.crypto.BN(inputAmount), flags)
            .toTxFormat());
        return new internal_1.Sig(buf);
    }
    exports.signTx = signTx;
    function toHex(x) {
        if (x instanceof internal_1.ScryptType) {
            return x.serialize();
        }
        return x.toString('hex');
    }
    exports.toHex = toHex;
    function getPreimage(tx, lockingScript, inputAmount, inputIndex, sighashType, flags) {
        if (inputIndex === void 0) { inputIndex = 0; }
        if (sighashType === void 0) { sighashType = exports.DEFAULT_SIGHASH_TYPE; }
        if (flags === void 0) { flags = exports.DEFAULT_FLAGS; }
        var preimageBuf = mvc.Transaction.sighash.sighashPreimage(tx, sighashType, inputIndex, lockingScript, new mvc.crypto.BN(inputAmount), flags);
        return new internal_1.SigHashPreimage(preimageBuf.toString('hex'));
    }
    exports.getPreimage = getPreimage;
    var MSB_THRESHOLD = 0x7e;
    function hashIsPositiveNumber(sighash) {
        var highByte = sighash.readUInt8(31);
        return highByte < MSB_THRESHOLD;
    }
    exports.hashIsPositiveNumber = hashIsPositiveNumber;
    function getLowSPreimage(tx, lockingScript, inputAmount, inputIndex, sighashType, flags) {
        if (inputIndex === void 0) { inputIndex = 0; }
        if (sighashType === void 0) { sighashType = exports.DEFAULT_SIGHASH_TYPE; }
        if (flags === void 0) { flags = exports.DEFAULT_FLAGS; }
        for (var i = 0; i < Number.MAX_SAFE_INTEGER; i++) {
            var preimage = getPreimage(tx, lockingScript, inputAmount, inputIndex, sighashType, flags);
            var sighash = mvc.crypto.Hash.sha256sha256(Buffer.from(toHex(preimage), 'hex'));
            var msb = sighash.readUInt8();
            if (msb < MSB_THRESHOLD && hashIsPositiveNumber(sighash)) {
                return preimage;
            }
            tx.inputs[inputIndex].sequenceNumber--;
        }
    }
    exports.getLowSPreimage = getLowSPreimage;
    // Converts a number into a sign-magnitude representation of certain size as a string
    // Throws if the number cannot be accommodated
    // Often used to append numbers to OP_RETURN, which are read in contracts
    // Support Bigint
    function num2bin(n, dataLen) {
        var num = new BN(n);
        if (num.eqn(0)) {
            return '00'.repeat(dataLen);
        }
        var s = num.toSM({ endian: 'little' }).toString('hex');
        var byteLen_ = s.length / 2;
        if (byteLen_ > dataLen) {
            throw new Error(n + " cannot fit in " + dataLen + " byte[s]");
        }
        if (byteLen_ === dataLen) {
            return s;
        }
        var paddingLen = dataLen - byteLen_;
        var lastByte = s.substring(s.length - 2);
        var rest = s.substring(0, s.length - 2);
        var m = parseInt(lastByte, 16);
        if (num.isNeg) {
            // reset sign bit
            m &= 0x7f;
        }
        var mHex = m.toString(16);
        if (mHex.length < 2) {
            mHex = '0' + mHex;
        }
        var padding = n > 0 ? '00'.repeat(paddingLen) : '00'.repeat(paddingLen - 1) + '80';
        return rest + mHex + padding;
    }
    exports.num2bin = num2bin;
    //Support Bigint
    function bin2num(s) {
        var hex = s.toString('hex');
        var lastByte = hex.substring(hex.length - 2);
        var rest = hex.substring(0, hex.length - 2);
        var m = parseInt(lastByte, 16);
        var n = m & 0x7f;
        var nHex = n.toString(16);
        if (nHex.length < 2) {
            nHex = '0' + nHex;
        }
        //Support negative number
        var bn = BN.fromHex(rest + nHex, { endian: 'little' });
        if (m >> 7) {
            bn = bn.neg();
        }
        if (bn.toNumber() < Number.MAX_SAFE_INTEGER && bn.toNumber() > Number.MIN_SAFE_INTEGER) {
            return bn.toNumber();
        }
        else {
            return bn.toString();
        }
    }
    exports.bin2num = bin2num;
    function isNode() {
        return typeof window === 'undefined' && typeof process === 'object';
    }
    exports.isNode = isNode;
    function path2uri(path) {
        if (isNode()) {
            return url_1.pathToFileURL(path).toString();
        }
        else {
            return path;
        }
    }
    exports.path2uri = path2uri;
    function uri2path(uri) {
        if (isNode()) {
            return url_1.fileURLToPath(uri);
        }
        else {
            return uri;
        }
    }
    exports.uri2path = uri2path;
    /**
     * @deprecated
     * convert literals to script ASM format
     */
    function literal2Asm(l) {
        var _a = __read(parseLiteral(l), 3), asm = _a[0], _ = _a[1], type = _a[2];
        return [asm, type];
    }
    exports.literal2Asm = literal2Asm;
    function findStructByName(name, s) {
        return s.find(function (s) {
            return s.name == name;
        });
    }
    exports.findStructByName = findStructByName;
    // test Token[3], int[3], st.b.c[3]
    function isArrayType(type) {
        return /^(.+)(\[[\w.]+\])+$/.test(type);
    }
    exports.isArrayType = isArrayType;
    function getNameByType(type) {
        if (isArrayType(type)) {
            var _a = __read(arrayTypeAndSizeStr(type), 2), elemType = _a[0], _ = _a[1];
            return getNameByType(elemType);
        }
        if (isGenericType(type)) {
            var _b = __read(parseGenericType(type), 2), tn = _b[0], _ = _b[1];
            return getNameByType(tn);
        }
        return type;
    }
    exports.getNameByType = getNameByType;
    function findStructByType(type, s) {
        var name = getNameByType(type);
        if (name) {
            return findStructByName(name, s);
        }
        return undefined;
    }
    exports.findStructByType = findStructByType;
    function checkStructField(s, param, arg, typeResolver) {
        var expectedType = typeResolver(param.type).finalType;
        if (isArrayType(expectedType)) {
            if (checkArray(arg, param, expectedType, typeResolver)) {
                throw new Error("Member " + param.name + " of struct " + s.name + " is of wrong type, expected " + param.type);
            }
        }
        else {
            var realType = typeOfArg(arg);
            if (expectedType != realType) {
                throw new Error("Member " + param.name + " of struct " + s.name + " is of wrong type, expected " + expectedType + " but got " + realType);
            }
        }
    }
    exports.checkStructField = checkStructField;
    function checkStruct(s, arg) {
        s.params.forEach(function (p) {
            var member = arg.memberByKey(p.name);
            if (!member) {
                throw new Error("argument of type struct " + s.name + " missing member " + p.name);
            }
        });
        var members = s.params.map(function (p) { return p.name; });
        arg.getMembers().forEach(function (key) {
            if (!members.includes(key)) {
                throw new Error(key + " is not a member of struct " + s.name);
            }
        });
    }
    exports.checkStruct = checkStruct;
    function checkSupportedParamType(arg, param, resolver) {
        var typeInfo = resolver(param.type);
        var finalType = typeInfo.finalType;
        if (isArrayType(finalType)) {
            return checkArray(arg, param, finalType, resolver);
        }
        var error = new Error("The type of " + param.name + " is wrong, expected " + finalType + " but got " + typeOfArg(arg));
        if (isGenericType(finalType)) {
            if (scryptTypes_1.Library.isLibrary(arg)) {
                var argL = arg;
                if (!argL.inferrTypesByAssign(finalType)) {
                    return error;
                }
            }
            else if (internal_1.Struct.isStruct(arg)) {
                var argS = arg;
                if (!argS.inferrTypesByAssign(finalType)) {
                    return error;
                }
            }
            else {
                return error;
            }
        }
        var t = typeOfArg(arg);
        return t == finalType ? undefined : error;
    }
    exports.checkSupportedParamType = checkSupportedParamType;
    /**
     * return eg. int[N][N][4] => ['int', ["N","N","4"]]
     * @param arrayTypeName
     */
    function arrayTypeAndSizeStr(arrayTypeName) {
        var arraySizes = [];
        if (arrayTypeName.indexOf('>') > -1) {
            var elemTypeName_1 = arrayTypeName.substring(0, arrayTypeName.lastIndexOf('>') + 1);
            var sizeParts = arrayTypeName.substring(arrayTypeName.lastIndexOf('>') + 1);
            __spread(sizeParts.matchAll(/\[([\w.]+)\]+/g)).map(function (match) {
                arraySizes.push(match[1]);
            });
            return [elemTypeName_1, arraySizes];
        }
        __spread(arrayTypeName.matchAll(/\[([\w.]+)\]+/g)).map(function (match) {
            arraySizes.push(match[1]);
        });
        var group = arrayTypeName.split('[');
        var elemTypeName = group[0];
        return [elemTypeName, arraySizes];
    }
    exports.arrayTypeAndSizeStr = arrayTypeAndSizeStr;
    /**
     * return eg. int[2][3][4] => ['int', [2,3,4]]
     * @param arrayTypeName  eg. int[2][3][4]
     */
    function arrayTypeAndSize(arrayTypeName) {
        var _a = __read(arrayTypeAndSizeStr(arrayTypeName), 2), elemTypeName = _a[0], arraySizes = _a[1];
        return [
            elemTypeName,
            arraySizes.map(function (size) {
                var n = parseInt(size);
                if (isNaN(n)) {
                    throw new Error("arrayTypeAndSize error type " + arrayTypeName + " with sub isNaN");
                }
                return n;
            }),
        ];
    }
    exports.arrayTypeAndSize = arrayTypeAndSize;
    function toLiteralArrayType(elemTypeName, sizes) {
        return [elemTypeName, sizes.map(function (size) { return "[" + size + "]"; }).join('')].join('');
    }
    exports.toLiteralArrayType = toLiteralArrayType;
    function toGenericType(name, genericTypes) {
        return name + "<" + genericTypes.join(',') + ">";
    }
    exports.toGenericType = toGenericType;
    /**
     * return eg. int[2][3][4] => int[3][4]
     * @param arrayTypeName  eg. int[2][3][4]
     */
    function subArrayType(arrayTypeName) {
        var _a = __read(arrayTypeAndSize(arrayTypeName), 2), elemTypeName = _a[0], sizes = _a[1];
        return toLiteralArrayType(elemTypeName, sizes.slice(1));
    }
    exports.subArrayType = subArrayType;
    function checkArray(args, param, expectedType, resolver) {
        var finalType = resolver(param.type).finalType;
        var _a = __read(arrayTypeAndSize(finalType), 2), elemTypeName = _a[0], arraySizes = _a[1];
        if (!Array.isArray(args)) {
            return new Error("The type of " + param.name + " is wrong, expected " + expectedType + " but got " + typeOfArg(args));
        }
        var t = typeOfArg(args[0]);
        if (!args.every(function (arg) { return typeOfArg(arg) === t; })) {
            return new Error("The type of " + param.name + " is wrong, expected " + expectedType + " but not all element types are the same");
        }
        if (args.length !== arraySizes[0]) {
            return new Error("The type of " + param.name + " is wrong, should be " + expectedType);
        }
        if (arraySizes.length == 1) {
            var arg0 = args[0];
            var scryptType = typeOfArg(arg0);
            return scryptType === elemTypeName
                ? undefined
                : new Error("The type of " + param.name + " is wrong, should be " + expectedType);
        }
        else {
            return args
                .map(function (a) {
                return checkArray(a, {
                    name: param.name,
                    type: subArrayType(finalType),
                }, expectedType, resolver);
            })
                .filter(function (e) { return e; })[0];
        }
    }
    function subscript(index, arraySizes) {
        if (arraySizes.length == 1) {
            return "[" + index + "]";
        }
        else if (arraySizes.length > 1) {
            var subArraySizes = arraySizes.slice(1);
            var offset = subArraySizes.reduce(function (acc, val) {
                return acc * val;
            }, 1);
            return "[" + Math.floor(index / offset) + "]" + subscript(index % offset, subArraySizes);
        }
    }
    exports.subscript = subscript;
    function flatternArray(arg, name, finalType) {
        if (!Array.isArray(arg)) {
            throw new Error('flatternArray only work on array');
        }
        var _a = __read(arrayTypeAndSize(finalType), 2), elemTypeName = _a[0], arraySizes = _a[1];
        return arg
            .map(function (item, index) {
            if (typeof item === 'boolean') {
                item = new internal_1.Bool(item);
            }
            else if (typeof item === 'number') {
                item = new internal_1.Int(item);
            }
            else if (typeof item === 'bigint') {
                item = new internal_1.Int(item);
            }
            else if (Array.isArray(item)) {
                return flatternArray(item, name + "[" + index + "]", subArrayType(finalType));
            }
            else if (internal_1.Struct.isStruct(item)) {
                return flatternStruct(item, name + "[" + index + "]");
            }
            else if (scryptTypes_1.Library.isLibrary(item)) {
                return flatternLibrary(item, name + "[" + index + "]");
            }
            else {
                item = item;
            }
            return {
                value: item,
                name: "" + name + subscript(index, arraySizes),
                type: elemTypeName,
            };
        })
            .flat(Infinity);
    }
    exports.flatternArray = flatternArray;
    function flatternStruct(arg, name) {
        if (internal_1.Struct.isStruct(arg)) {
            var argS_1 = arg;
            var keys = argS_1.getMembers();
            return keys
                .map(function (key) {
                var member = argS_1.memberByKey(key);
                if (internal_1.Struct.isStruct(member)) {
                    return flatternStruct(member, name + "." + key);
                }
                else if (Array.isArray(member)) {
                    var finalType = argS_1.getMemberAstFinalType(key);
                    return flatternArray(member, name + "." + key, finalType);
                }
                else {
                    member = member;
                    return {
                        value: member,
                        name: name + "." + key,
                        type: member.type,
                    };
                }
            })
                .flat(Infinity);
        }
        else {
            throw new Error(arg + " should be struct");
        }
    }
    exports.flatternStruct = flatternStruct;
    function flatternLibrary(arg, name) {
        if (scryptTypes_1.Library.isLibrary(arg)) {
            var library = arg;
            var args_1 = library.getCtorArgs();
            return library
                .getLibraryAst()
                .params.map(function (param, index) {
                var arg = args_1[index];
                if (internal_1.Struct.isStruct(arg)) {
                    return flatternStruct(arg, name + "." + param.name);
                }
                else if (Array.isArray(arg)) {
                    return flatternArray(arg, name + "." + param.name, param.type);
                }
                else if (scryptTypes_1.Library.isLibrary(arg)) {
                    return flatternLibrary(arg, name + "." + param.name);
                }
                else {
                    return {
                        value: arg,
                        name: name + "." + param.name,
                        type: param.type,
                    };
                }
            })
                .flat(Infinity);
        }
        else {
            throw new Error(arg + " should be library");
        }
    }
    exports.flatternLibrary = flatternLibrary;
    function flatternLibraryState(arg, name) {
        if (scryptTypes_1.Library.isLibrary(arg)) {
            var library_1 = arg;
            return library_1
                .getLibraryAst()
                .properties.map(function (param, index) {
                var property = library_1.getProperty(param.name);
                if (internal_1.Struct.isStruct(property)) {
                    return flatternStruct(property, name + "." + param.name);
                }
                else if (Array.isArray(property)) {
                    return flatternArray(property, name + "." + param.name, param.type);
                }
                else if (scryptTypes_1.Library.isLibrary(property)) {
                    return flatternLibraryState(property, name + "." + param.name);
                }
                else {
                    return {
                        value: property,
                        name: name + "." + param.name,
                        type: param.type,
                    };
                }
            })
                .flat(Infinity);
        }
        else {
            throw new Error(arg + " should be library");
        }
    }
    exports.flatternLibraryState = flatternLibraryState;
    //using for flattern contract constructor arguments
    function flatternCtorArgs(args, resolver) {
        var args_ = [];
        args.forEach(function (arg) {
            var typeInfo = resolver(arg.type);
            if (isArrayType(typeInfo.finalType)) {
                flatternArray(arg.value, arg.name, typeInfo.finalType).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                flatternStruct(arg.value, arg.name).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                flatternLibrary(arg.value, arg.name).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else {
                args_.push({
                    name: arg.name,
                    type: typeInfo.finalType,
                    value: arg.value,
                });
            }
        });
        return args_;
    }
    exports.flatternCtorArgs = flatternCtorArgs;
    //using for flattern stateful contract states
    function flatternStateArgs(args, resolver) {
        var args_ = [];
        args.forEach(function (arg) {
            var typeInfo = resolver(arg.type);
            var finalType = typeInfo.finalType;
            if (isArrayType(finalType)) {
                flatternArray(arg.value, arg.name, finalType).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                flatternStruct(arg.value, arg.name).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                flatternLibraryState(arg.value, arg.name).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: resolver(e.type).finalType,
                        value: e.value,
                    });
                });
            }
            else {
                args_.push({
                    name: arg.name,
                    type: finalType,
                    value: arg.value,
                });
            }
        });
        return args_;
    }
    exports.flatternStateArgs = flatternStateArgs;
    function flatternLibraryParam(param, resolver, property) {
        var libraryClass = resolver.resolverClass(param.type);
        var ast = property ? libraryClass.libraryAst.properties : libraryClass.libraryAst.params;
        return ast
            .map(function (p) {
            var typeInfo = resolver.resolverType(p.type);
            p.type = typeInfo.finalType;
            if (isArrayType(p.type)) {
                return flatternArrayParam({
                    name: param.name + "." + p.name,
                    type: p.type,
                }, resolver);
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                return flatternStructParam({
                    name: param.name + "." + p.name,
                    type: p.type,
                }, resolver);
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                return flatternLibraryParam({
                    name: param.name + "." + p.name,
                    type: p.type,
                }, resolver, property);
            }
            else {
                return {
                    value: undefined,
                    name: param.name + "." + p.name,
                    type: p.type,
                };
            }
        })
            .flat(Infinity);
    }
    function flatternStructParam(param, resolver) {
        var StructClass = resolver.resolverClass(param.type);
        return StructClass.structAst.params
            .map(function (p) {
            var typeInfo = resolver.resolverType(p.type);
            p.type = typeInfo.finalType;
            if (isArrayType(p.type)) {
                return flatternArrayParam({
                    name: param.name + "." + p.name,
                    type: p.type,
                }, resolver);
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                return flatternStructParam({
                    name: param.name + "." + p.name,
                    type: p.type,
                }, resolver);
            }
            else {
                return {
                    value: undefined,
                    name: param.name + "." + p.name,
                    type: p.type,
                };
            }
        })
            .flat(Infinity);
    }
    function flatternArrayParam(param, resolver) {
        var typeInfo = resolver.resolverType(param.type);
        param.type = typeInfo.finalType;
        if (!isArrayType(param.type)) {
            throw new Error("ParamEntity " + param.name + " should be array");
        }
        var _a = __read(arrayTypeAndSize(param.type), 2), elemTypeName = _a[0], arraySizes = _a[1];
        var args = [];
        for (var index = 0; index < arraySizes[0]; index++) {
            if (arraySizes.length > 1) {
                flatternArrayParam({
                    name: param.name + "[" + index + "]",
                    type: subArrayType(param.type),
                }, resolver).forEach(function (a) {
                    args.push(a);
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                flatternStructParam({
                    name: param.name + "[" + index + "]",
                    type: elemTypeName,
                }, resolver).forEach(function (a) {
                    args.push(a);
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                flatternLibraryParam({
                    name: param.name + "[" + index + "]",
                    type: elemTypeName,
                }, resolver, true).forEach(function (a) {
                    args.push(a);
                });
            }
            else {
                args.push({
                    value: undefined,
                    name: "" + param.name + subscript(index, arraySizes),
                    type: elemTypeName,
                });
            }
        }
        return args.flat(Infinity);
    }
    function flatternParams(params, resolver) {
        var args_ = [];
        params.forEach(function (param) {
            var typeInfo = resolver.resolverType(param.type);
            param.type = typeInfo.finalType;
            if (isArrayType(param.type)) {
                flatternArrayParam(param, resolver).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: e.type,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                flatternStructParam(param, resolver).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: e.type,
                        value: e.value,
                    });
                });
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                flatternLibraryParam(param, resolver, true).forEach(function (e) {
                    args_.push({
                        name: e.name,
                        type: e.type,
                        value: e.value,
                    });
                });
            }
            else {
                args_.push({
                    name: param.name,
                    type: param.type,
                    value: undefined,
                });
            }
        });
        return args_;
    }
    exports.flatternParams = flatternParams;
    function typeOfArg(arg) {
        if (arg instanceof internal_1.ScryptType) {
            var scryptType = arg.finalType;
            return scryptType;
        }
        var typeofArg = typeof arg;
        if (typeofArg === 'boolean') {
            return 'bool';
        }
        if (typeofArg === 'number') {
            return 'int';
        }
        if (typeofArg === 'bigint') {
            return 'int';
        }
        if (typeofArg === 'string') {
            return new internal_1.Int(arg).finalType;
        }
        return typeof arg;
    }
    exports.typeOfArg = typeOfArg;
    function readFileByLine(path, index) {
        var result = '';
        fs.readFileSync(path, 'utf8')
            .split(/\r?\n/)
            .every(function (line, i) {
            if (i === index - 1) {
                result = line;
                return false;
            }
            return true;
        });
        return result;
    }
    exports.readFileByLine = readFileByLine;
    function isEmpty(obj) {
        return Object.keys(obj).length === 0 && obj.constructor === Object;
    }
    exports.isEmpty = isEmpty;
    function compileContract(file, options) {
        console.log("Compiling contract " + file + " ...");
        options = Object.assign({
            out: path_1.join(__dirname, '../out'),
            sourceMap: false,
            desc: false,
        }, options);
        if (!fs.existsSync(file)) {
            throw "file " + file + " not exists!";
        }
        if (!fs.existsSync(options.out)) {
            fs.mkdirSync(options.out);
        }
        var result = internal_1.compile({ path: file }, {
            desc: options.desc,
            outputDir: options.out,
            sourceMap: options.sourceMap,
            cmdPrefix: internal_1.findCompiler(),
        });
        return result;
    }
    exports.compileContract = compileContract;
    function compileContractAsync(file, options) {
        console.log("compiling contract " + file + " ...");
        options = Object.assign({
            out: path_1.join(__dirname, '..', 'out'),
            sourceMap: false,
            desc: false,
        }, options);
        if (!fs.existsSync(file)) {
            throw "file " + file + " not exists!";
        }
        if (!fs.existsSync(options.out)) {
            fs.mkdirSync(options.out);
        }
        return compilerWrapper_1.compileAsync({ path: file }, {
            desc: options.desc,
            outputDir: options.out,
            hex: true,
            cmdPrefix: internal_1.findCompiler(),
        });
    }
    exports.compileContractAsync = compileContractAsync;
    function newCall(Cls, args) {
        return new (Function.prototype.bind.apply(Cls, [null].concat(args)))();
    }
    exports.newCall = newCall;
    function genLaunchConfigFile(constructorArgs, pubFuncArgs, pubFunc, name, program, txContext, asmArgs) {
        // some desc without sourceMap will not have file property.
        if (!program) {
            return '';
        }
        var debugConfig = {
            type: 'scrypt',
            request: 'launch',
            internalConsoleOptions: 'openOnSessionStart',
            name: name,
            program: program,
            constructorArgs: constructorArgs,
            pubFunc: pubFunc,
            pubFuncArgs: pubFuncArgs,
        };
        var debugTxContext = {};
        if (!isEmpty(txContext)) {
            var tx = txContext.tx || '';
            var inputIndex = txContext.inputIndex || 0;
            var inputSatoshis = txContext.inputSatoshis || 0;
            if (tx) {
                Object.assign(debugTxContext, { hex: tx.toString(), inputIndex: inputIndex, inputSatoshis: inputSatoshis });
            }
            if (txContext.opReturn) {
                Object.assign(debugTxContext, { opReturn: txContext.opReturn });
            }
            else if (txContext.opReturnHex) {
                Object.assign(debugTxContext, { opReturnHex: txContext.opReturnHex });
            }
        }
        if (!isEmpty(asmArgs)) {
            Object.assign(debugConfig, { asmArgs: asmArgs });
        }
        if (!isEmpty(debugTxContext)) {
            Object.assign(debugConfig, { txContext: debugTxContext });
        }
        var launch = {
            version: '0.2.0',
            configurations: [debugConfig],
        };
        var jsonstr = JSON.stringify(launch, function (key, value) {
            if (typeof value === 'bigint') {
                return value.toString();
            }
            else {
                return value;
            }
        }, 2);
        if (isNode()) {
            var filename = name + "-launch.json";
            var file = path_1.join(fs.mkdtempSync("" + os_1.tmpdir() + path_1.sep + "sCrypt."), filename);
            fs.writeFileSync(file, jsonstr);
            return path2uri(file);
        }
        else {
            console.error(pubFunc + "() call fail, see launch.json", jsonstr);
        }
    }
    exports.genLaunchConfigFile = genLaunchConfigFile;
    function resolveConstValue(node) {
        var value = undefined;
        if (node.expr.nodeType === 'IntLiteral') {
            value = node.expr.value.toString(10);
        }
        else if (node.expr.nodeType === 'BoolLiteral') {
            value = node.expr.value;
        }
        if (node.expr.nodeType === 'BytesLiteral') {
            value = "b'" + node.expr.value.map(function (a) { return intValue2hex(a); }).join('') + "'";
        }
        if (node.expr.nodeType === 'FunctionCall') {
            if ([
                internal_1.VariableType.PUBKEY,
                internal_1.VariableType.RIPEMD160,
                internal_1.VariableType.PUBKEYHASH,
                internal_1.VariableType.SIG,
                internal_1.VariableType.SIGHASHTYPE,
                internal_1.VariableType.OPCODETYPE,
                internal_1.VariableType.SIGHASHPREIMAGE,
                internal_1.VariableType.SHA1,
                internal_1.VariableType.SHA256,
            ].includes(node.expr.name)) {
                value = "b'" + node.expr.params[0].value.map(function (a) { return intValue2hex(a); }).join('') + "'";
            }
            else if (node.expr.name === internal_1.VariableType.PRIVKEY) {
                value = node.expr.params[0].value.toString(10);
            }
        }
        return value;
    }
    exports.resolveConstValue = resolveConstValue;
    function resolveType(type, originTypes, contract, statics, alias, librarys) {
        var typeInfo = resolveAliasType(originTypes, alias, type);
        if (isArrayType(typeInfo.finalType)) {
            return {
                finalType: resolveArrayType(contract, typeInfo.finalType, statics),
                symbolType: typeInfo.symbolType,
            };
        }
        return typeInfo;
    }
    exports.resolveType = resolveType;
    function resolveArrayType(contract, type, statics) {
        if (isArrayType(type)) {
            var _a = __read(arrayTypeAndSizeStr(type), 2), elemTypeName = _a[0], arraySizes = _a[1];
            var sizes = arraySizes.map(function (size) {
                if (/^(\d)+$/.test(size)) {
                    return parseInt(size);
                }
                else {
                    // size as a static const
                    var size_ = size.indexOf('.') > 0 ? size : contract + "." + size;
                    var value = findConstStatic(statics, size_);
                    if (!value) {
                        // Unable to solve when the subscript of the array is a function parameter, [CTC](https://scryptdoc.readthedocs.io/en/latest/ctc.html)
                        return size;
                    }
                    return value.value;
                }
            });
            return toLiteralArrayType(elemTypeName, sizes);
        }
        return type;
    }
    function resolveAliasType(originTypes, alias, type) {
        if (isArrayType(type)) {
            var _a = __read(arrayTypeAndSizeStr(type), 2), elemTypeName = _a[0], sizes = _a[1];
            var elemTypeInfo = resolveAliasType(originTypes, alias, elemTypeName);
            if (isArrayType(elemTypeInfo.finalType)) {
                var _b = __read(arrayTypeAndSizeStr(elemTypeInfo.finalType), 2), elemTypeName_ = _b[0], sizes_ = _b[1];
                return {
                    finalType: toLiteralArrayType(elemTypeName_, sizes.concat(sizes_)),
                    symbolType: elemTypeInfo.symbolType,
                };
            }
            return {
                finalType: toLiteralArrayType(elemTypeInfo.finalType, sizes),
                symbolType: elemTypeInfo.symbolType,
            };
        }
        else if (isGenericType(type)) {
            var _c = __read(parseGenericType(type), 2), name_1 = _c[0], genericTypes = _c[1];
            var typeInfo = resolveAliasType(originTypes, alias, name_1);
            var gts = genericTypes.map(function (t) { return resolveAliasType(originTypes, alias, t).finalType; });
            return {
                finalType: toGenericType(typeInfo.finalType, gts),
                symbolType: typeInfo.symbolType,
            };
        }
        var a = alias.find(function (a) {
            return a.name === type;
        });
        if (a) {
            return resolveAliasType(originTypes, alias, a.type);
        }
        else if (originTypes[type]) {
            return originTypes[type];
        }
        else if (scryptTypes_1.BasicScryptType[type]) {
            return {
                finalType: type,
                symbolType: scryptTypes_1.SymbolType.BaseType,
            };
        }
        else {
            return {
                finalType: type,
                symbolType: scryptTypes_1.SymbolType.Unknown,
            };
        }
    }
    function ansiRegex(_a) {
        var _b = (_a === void 0 ? {} : _a).onlyFirst, onlyFirst = _b === void 0 ? false : _b;
        var pattern = [
            '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
            '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))',
        ].join('|');
        return new RegExp(pattern, onlyFirst ? undefined : 'g');
    }
    exports.ansiRegex = ansiRegex;
    function stripAnsi(string) {
        if (typeof string !== 'string') {
            throw new TypeError("Expected a `string`, got `" + typeof string + "`");
        }
        return string.replace(ansiRegex(), '');
    }
    exports.stripAnsi = stripAnsi;
    function createStruct(resolver, param, opcodesMap) {
        var structClass = resolver.resolverClass(param.type);
        var obj = Object.create({});
        structClass.structAst.params.forEach(function (p) {
            var _a, _b, _c, _d;
            var typeInfo = resolver.resolverType(p.type);
            if (isArrayType(typeInfo.finalType)) {
                Object.assign(obj, (_a = {},
                    _a[p.name] = createArray(resolver, typeInfo.finalType, param.name + "." + p.name, opcodesMap),
                    _a));
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                Object.assign(obj, (_b = {},
                    _b[p.name] = createStruct(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap),
                    _b));
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                Object.assign(obj, (_c = {},
                    _c[p.name] = createLibrary(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap),
                    _c));
            }
            else {
                Object.assign(obj, (_d = {},
                    _d[p.name] = hex2ScryptType(typeInfo.finalType, opcodesMap.get("<" + param.name + "." + p.name + ">")),
                    _d));
            }
        });
        return new structClass(obj);
    }
    exports.createStruct = createStruct;
    function createLibrary(resolver, param, opcodesMap) {
        var libraryClass = resolver.resolverClass(param.type);
        var args = libraryClass.libraryAst.params.map(function (p) {
            var typeInfo = resolver.resolverType(p.type);
            if (isArrayType(typeInfo.finalType)) {
                return createArray(resolver, typeInfo.finalType, param.name + "." + p.name, opcodesMap);
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                return createStruct(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap);
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                return createLibrary(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap);
            }
            else {
                return hex2ScryptType(typeInfo.finalType, opcodesMap.get("<" + param.name + "." + p.name + ">"));
            }
        });
        return new (libraryClass.bind.apply(libraryClass, __spread([void 0], args)))();
    }
    exports.createLibrary = createLibrary;
    function createLibraryProperties(resolver, param, opcodesMap) {
        var libraryClass = resolver.resolverClass(param.type);
        var properties = {};
        libraryClass.libraryAst.properties.forEach(function (p) {
            var _a, _b, _c, _d;
            var typeInfo = resolver.resolverType(p.type);
            if (isArrayType(typeInfo.finalType)) {
                Object.assign(properties, (_a = {},
                    _a[p.name] = createArray(resolver, p.type, param.name + "." + p.name, opcodesMap),
                    _a));
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                Object.assign(properties, (_b = {},
                    _b[p.name] = createStruct(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap),
                    _b));
            }
            else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                var library = createDefaultLibrary(resolver, { name: param.name + "." + p.name, type: p.type });
                library.setProperties(createLibraryProperties(resolver, { name: param.name + "." + p.name, type: p.type }, opcodesMap));
                Object.assign(properties, (_c = {},
                    _c[p.name] = library,
                    _c));
            }
            else {
                Object.assign(properties, (_d = {},
                    _d[p.name] = hex2ScryptType(typeInfo.finalType, opcodesMap.get("<" + param.name + "." + p.name + ">")),
                    _d));
            }
        });
        return properties;
    }
    exports.createLibraryProperties = createLibraryProperties;
    function createDefaultLibrary(resolver, param) {
        var flatternparams = flatternLibraryParam(param, resolver, false);
        var hexTemplateMap = new Map();
        flatternparams.forEach(function (p) {
            if (p.type === internal_1.VariableType.INT || p.type === internal_1.VariableType.PRIVKEY) {
                hexTemplateMap.set("<" + p.name + ">", '00');
            }
            else if (p.type === internal_1.VariableType.BOOL) {
                hexTemplateMap.set("<" + p.name + ">", '51');
            }
            else if (p.type === internal_1.VariableType.BYTES ||
                p.type === internal_1.VariableType.PUBKEY ||
                p.type === internal_1.VariableType.SIG ||
                p.type === internal_1.VariableType.RIPEMD160 ||
                p.type === internal_1.VariableType.SHA1 ||
                p.type === internal_1.VariableType.SHA256 ||
                p.type === internal_1.VariableType.SIGHASHTYPE ||
                p.type === internal_1.VariableType.SIGHASHPREIMAGE ||
                p.type === internal_1.VariableType.OPCODETYPE) {
                hexTemplateMap.set("<" + p.name + ">", '0100');
            }
            else {
                throw new Error("param " + p.name + " has unknown type " + p.type);
            }
        });
        return createLibrary(resolver, param, hexTemplateMap);
    }
    exports.createDefaultLibrary = createDefaultLibrary;
    function createArray(resolver, type, name, opcodesMap) {
        var arrays = [];
        var _a = __read(arrayTypeAndSize(type), 2), elemTypeName = _a[0], sizes = _a[1];
        var arraylen = sizes[0];
        if (sizes.length === 1) {
            for (var index = 0; index < arraylen; index++) {
                var typeInfo = resolver.resolverType(elemTypeName);
                if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
                    arrays.push(createStruct(resolver, {
                        name: name + "[" + index + "]",
                        type: typeInfo.finalType,
                    }, opcodesMap));
                }
                else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
                    arrays.push(createLibrary(resolver, {
                        name: name + "[" + index + "]",
                        type: typeInfo.finalType,
                    }, opcodesMap));
                }
                else {
                    arrays.push(hex2ScryptType(typeInfo.finalType, opcodesMap.get("<" + name + "[" + index + "]>")));
                }
            }
        }
        else {
            for (var index = 0; index < arraylen; index++) {
                var finalType = resolver.resolverType(elemTypeName).finalType;
                var subArrayType_1 = [
                    finalType,
                    sizes
                        .slice(1)
                        .map(function (size) { return "[" + size + "]"; })
                        .join(''),
                ].join('');
                arrays.push(createArray(resolver, subArrayType_1, name + "[" + index + "]", opcodesMap));
            }
        }
        return arrays;
    }
    exports.createArray = createArray;
    function toLiteral(value) {
        if (Array.isArray(value)) {
            var v = value;
            return "[" + v.map(function (i) { return toLiteral(i); }) + "]";
        }
        else {
            return value instanceof internal_1.ScryptType ? value.toLiteral() : value;
        }
    }
    exports.toLiteral = toLiteral;
    function isInteger(x) {
        // check if the passed value is a number
        if (typeof x == 'number' && !isNaN(x)) {
            // check if it is integer
            return Number.isInteger(x);
        }
        else if (typeof x == 'bigint') {
            return true;
        }
        else if (typeof x == 'string') {
            // hex int
            var m = /^(0x[0-9a-fA-F]+)$/.exec(x);
            if (m) {
                return true;
            }
            // decimal int
            m = /^(-?\d+)$/.exec(x);
            if (m) {
                return true;
            }
            return false;
        }
        return false;
    }
    exports.isInteger = isInteger;
    function findConstStatic(statics, name) {
        return statics.find(function (s) {
            return s.const === true && s.name === name;
        });
    }
    exports.findConstStatic = findConstStatic;
    function findStatic(statics, name) {
        return statics.find(function (s) {
            return s.name === name;
        });
    }
    exports.findStatic = findStatic;
    function escapeRegExp(stringToGoIntoTheRegex) {
        return stringToGoIntoTheRegex.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    // state version
    var CURRENT_STATE_VERSION = 0;
    function buildContractCode(hexTemplateArgs, hexTemplateInlineASM, hexTemplate) {
        var e_1, _a, e_2, _b;
        var lsHex = hexTemplate;
        try {
            for (var _c = __values(hexTemplateArgs.entries()), _d = _c.next(); !_d.done; _d = _c.next()) {
                var entry = _d.value;
                var name_2 = entry[0];
                var value = entry[1];
                lsHex = lsHex.replace(name_2, value);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
            }
            finally { if (e_1) throw e_1.error; }
        }
        try {
            for (var _e = __values(hexTemplateInlineASM.entries()), _f = _e.next(); !_f.done; _f = _e.next()) {
                var entry = _f.value;
                var name_3 = entry[0];
                var value = entry[1];
                lsHex = lsHex.replace(new RegExp("" + escapeRegExp(name_3), 'g'), value);
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
            }
            finally { if (e_2) throw e_2.error; }
        }
        return mvc.Script.fromHex(lsHex);
    }
    exports.buildContractCode = buildContractCode;
    /**
     * only used for state contract
     * @param args
     * @param firstCall
     * @param finalTypeResolver
     * @returns
     */
    function buildContractState(args, firstCall, finalTypeResolver) {
        var e_3, _a;
        var state_hex = '';
        var state_len = 0;
        var args_ = flatternStateArgs(args, finalTypeResolver);
        if (args_.length <= 0) {
            throw new Error('no state property found, buildContractState only used for state contract');
        }
        // append firstCall which is a hidden built-in state
        state_hex += "" + internal_1.serializeSupportedParamType(firstCall);
        try {
            for (var args_2 = __values(args_), args_2_1 = args_2.next(); !args_2_1.done; args_2_1 = args_2.next()) {
                var arg = args_2_1.value;
                if (arg.type == internal_1.VariableType.BOOL) {
                    //fixed length
                    state_hex += "" + internal_1.serializeSupportedParamType(arg.value);
                }
                else if (arg.type === internal_1.VariableType.INT ||
                    arg.type === internal_1.VariableType.BYTES ||
                    arg.type === internal_1.VariableType.PUBKEY ||
                    arg.type === internal_1.VariableType.PRIVKEY ||
                    arg.type === internal_1.VariableType.PUBKEY ||
                    arg.type === internal_1.VariableType.SIG ||
                    arg.type === internal_1.VariableType.RIPEMD160 ||
                    arg.type === internal_1.VariableType.SHA1 ||
                    arg.type === internal_1.VariableType.SHA256 ||
                    arg.type === internal_1.VariableType.SIGHASHTYPE ||
                    arg.type === internal_1.VariableType.SIGHASHPREIMAGE ||
                    arg.type === internal_1.VariableType.OPCODETYPE) {
                    state_hex += "" + mvc.Script.fromASM(internal_1.serializeSupportedParamType(arg.value)).toHex();
                }
            }
        }
        catch (e_3_1) { e_3 = { error: e_3_1 }; }
        finally {
            try {
                if (args_2_1 && !args_2_1.done && (_a = args_2.return)) _a.call(args_2);
            }
            finally { if (e_3) throw e_3.error; }
        }
        //append meta
        if (state_hex) {
            state_len = state_hex.length / 2;
            state_hex += num2bin(state_len, 4) + num2bin(CURRENT_STATE_VERSION, 1);
            return state_hex;
        }
        return state_hex;
    }
    exports.buildContractState = buildContractState;
    function buildDefaultStateProps(contract) {
        var flatternparams = flatternParams(contract.stateProps, contract.resolver);
        var hexTemplateMap = new Map();
        flatternparams.forEach(function (p) {
            if (p.type === internal_1.VariableType.INT || p.type === internal_1.VariableType.PRIVKEY) {
                hexTemplateMap.set("<" + p.name + ">", '00');
            }
            else if (p.type === internal_1.VariableType.BOOL) {
                hexTemplateMap.set("<" + p.name + ">", '51');
            }
            else if (p.type === internal_1.VariableType.BYTES ||
                p.type === internal_1.VariableType.PUBKEY ||
                p.type === internal_1.VariableType.SIG ||
                p.type === internal_1.VariableType.RIPEMD160 ||
                p.type === internal_1.VariableType.SHA1 ||
                p.type === internal_1.VariableType.SHA256 ||
                p.type === internal_1.VariableType.SIGHASHTYPE ||
                p.type === internal_1.VariableType.SIGHASHPREIMAGE ||
                p.type === internal_1.VariableType.OPCODETYPE) {
                hexTemplateMap.set("<" + p.name + ">", '0100');
            }
            else {
                throw new Error("param " + p.name + " has unknown type " + p.type);
            }
        });
        return contract.stateProps.map(function (param) {
            return deserializeArgfromState(contract.resolver, Object.assign(param, {
                value: undefined,
            }), hexTemplateMap);
        });
    }
    exports.buildDefaultStateProps = buildDefaultStateProps;
    function readBytes(br) {
        try {
            var opcodenum = br.readUInt8();
            var len_1, data = void 0;
            if (opcodenum == 0) {
                data = '';
            }
            else if (opcodenum > 0 && opcodenum < mvc.Opcode.OP_PUSHDATA1) {
                len_1 = opcodenum;
                data = br.read(len_1).toString('hex');
            }
            else if (opcodenum === mvc.Opcode.OP_PUSHDATA1) {
                len_1 = br.readUInt8();
                data = br.read(len_1).toString('hex');
            }
            else if (opcodenum === mvc.Opcode.OP_PUSHDATA2) {
                len_1 = br.readUInt16LE();
                data = br.read(len_1).toString('hex');
            }
            else if (opcodenum === mvc.Opcode.OP_PUSHDATA4) {
                len_1 = br.readUInt32LE();
                data = br.read(len_1).toString('hex');
            }
            else {
                data = num2bin(opcodenum - 80, 1);
            }
            return {
                data: data,
                opcodenum: opcodenum,
            };
        }
        catch (e) {
            throw new Error('readBytes: ' + e);
        }
    }
    exports.readBytes = readBytes;
    function deserializeArgfromHex(resolver, arg, opcodesMap) {
        var value;
        var typeInfo = resolver.resolverType(arg.type);
        if (isArrayType(typeInfo.finalType)) {
            value = createArray(resolver, arg.type, arg.name, opcodesMap);
        }
        else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
            value = createStruct(resolver, arg, opcodesMap);
        }
        else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
            value = createLibrary(resolver, arg, opcodesMap);
        }
        else {
            value = hex2ScryptType(arg.type, opcodesMap.get("<" + arg.name + ">"));
        }
        arg.value = value;
        return arg;
    }
    exports.deserializeArgfromHex = deserializeArgfromHex;
    function deserializeArgfromState(resolver, arg, opcodesMap) {
        var value;
        var typeInfo = resolver.resolverType(arg.type);
        if (isArrayType(typeInfo.finalType)) {
            value = createArray(resolver, arg.type, arg.name, opcodesMap);
        }
        else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Struct) {
            value = createStruct(resolver, arg, opcodesMap);
        }
        else if (typeInfo.symbolType === scryptTypes_1.SymbolType.Library) {
            value = createDefaultLibrary(resolver, arg);
            var properties = createLibraryProperties(resolver, arg, opcodesMap);
            value.setProperties(properties);
        }
        else {
            value = hex2ScryptType(arg.type, opcodesMap.get("<" + arg.name + ">"));
        }
        arg.value = value;
        return arg;
    }
    exports.deserializeArgfromState = deserializeArgfromState;
    /**
     *
     * @param data
     * @returns flat ScryptType array
     */
    function flattenData(data) {
        if (Array.isArray(data)) {
            return data
                .map(function (item) {
                return flattenData(item);
            })
                .flat(Infinity);
        }
        else if (internal_1.Struct.isStruct(data)) {
            var argS_2 = data;
            var keys = argS_2.getMembers();
            return keys
                .map(function (key) {
                var member = argS_2.memberByKey(key);
                return flattenData(member);
            })
                .flat(Infinity);
        }
        else if (typeof data === 'boolean') {
            return [new internal_1.Bool(data)];
        }
        else if (typeof data === 'number' || typeof data === 'bigint' || typeof data === 'string') {
            return [new internal_1.Int(data)];
        }
        else if (data instanceof internal_1.ScryptType) {
            return [data];
        }
    }
    // struct / array: sha256 every single element of the flattened struct / array, and concat the result to a joint byte, and sha256 again
    // basic type: sha256 every single element
    function flattenSha256(data) {
        var flattened = flattenData(data);
        if (flattened.length === 1) {
            var hex = flattened[0].serialize();
            if ((flattened[0] instanceof internal_1.Bool || flattened[0] instanceof internal_1.Int) && hex === '00') {
                hex = '';
            }
            return mvc.crypto.Hash.sha256(Buffer.from(hex, 'hex')).toString('hex');
        }
        else {
            var jointbytes = flattened
                .map(function (item) {
                var hex = item.serialize();
                if ((item instanceof internal_1.Bool || item instanceof internal_1.Int) && hex === '00') {
                    hex = '';
                }
                return mvc.crypto.Hash.sha256(Buffer.from(hex, 'hex')).toString('hex');
            })
                .join('');
            return mvc.crypto.Hash.sha256(Buffer.from(jointbytes, 'hex')).toString('hex');
        }
    }
    exports.flattenSha256 = flattenSha256;
    // sort the map by the result of flattenSha256 of the key
    function sortmap(map) {
        return new Map(__spread(map.entries()).sort(function (a, b) {
            return BN.fromSM(Buffer.from(flattenSha256(a[0]), 'hex'), {
                endian: 'little',
            }).cmp(BN.fromSM(Buffer.from(flattenSha256(b[0]), 'hex'), {
                endian: 'little',
            }));
        }));
    }
    exports.sortmap = sortmap;
    // sort the set by the result of flattenSha256 of the key
    function sortset(set) {
        return new Set(__spread(set.keys()).sort(function (a, b) {
            return BN.fromSM(Buffer.from(flattenSha256(a), 'hex'), {
                endian: 'little',
            }).cmp(BN.fromSM(Buffer.from(flattenSha256(b), 'hex'), {
                endian: 'little',
            }));
        }));
    }
    exports.sortset = sortset;
    // returns index of the HashedMap/HashedSet by the key
    function findKeyIndex(collection, key) {
        var e_4, _a, e_5, _b;
        if (collection instanceof Map) {
            var sortedMap = sortmap(collection);
            var m = [];
            try {
                for (var _c = __values(sortedMap.entries()), _d = _c.next(); !_d.done; _d = _c.next()) {
                    var entry = _d.value;
                    m.push(entry);
                }
            }
            catch (e_4_1) { e_4 = { error: e_4_1 }; }
            finally {
                try {
                    if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
                }
                finally { if (e_4) throw e_4.error; }
            }
            return m.findIndex(function (entry) {
                if (entry[0] === key) {
                    return true;
                }
                return false;
            });
        }
        else {
            var sortedSet = sortset(collection);
            var m = [];
            try {
                for (var _e = __values(sortedSet.keys()), _f = _e.next(); !_f.done; _f = _e.next()) {
                    var entry = _f.value;
                    m.push(entry);
                }
            }
            catch (e_5_1) { e_5 = { error: e_5_1 }; }
            finally {
                try {
                    if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
                }
                finally { if (e_5) throw e_5.error; }
            }
            return m.findIndex(function (entry) {
                if (entry === key) {
                    return true;
                }
                return false;
            });
        }
    }
    exports.findKeyIndex = findKeyIndex;
    // serialize the HashedMap/HashedSet, but only flattenSha256 of the key and value
    function toData(collection) {
        var e_6, _a, e_7, _b;
        var storage = '';
        if (collection instanceof Map) {
            var sortedMap = sortmap(collection);
            try {
                for (var _c = __values(sortedMap.entries()), _d = _c.next(); !_d.done; _d = _c.next()) {
                    var entry = _d.value;
                    storage += flattenSha256(entry[0]) + flattenSha256(entry[1]);
                }
            }
            catch (e_6_1) { e_6 = { error: e_6_1 }; }
            finally {
                try {
                    if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
                }
                finally { if (e_6) throw e_6.error; }
            }
        }
        else {
            var sortedSet = sortset(collection);
            try {
                for (var _e = __values(sortedSet.keys()), _f = _e.next(); !_f.done; _f = _e.next()) {
                    var key = _f.value;
                    storage += flattenSha256(key);
                }
            }
            catch (e_7_1) { e_7 = { error: e_7_1 }; }
            finally {
                try {
                    if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
                }
                finally { if (e_7) throw e_7.error; }
            }
        }
        return new internal_1.Bytes(storage);
    }
    exports.toData = toData;
    function toHashedMap(collection) {
        var data = toData(collection);
        var hashedMap = new scryptTypes_1.HashedMap(data);
        return hashedMap;
    }
    exports.toHashedMap = toHashedMap;
    function toHashedSet(collection) {
        var data = toData(collection);
        var hashedSet = new scryptTypes_1.HashedSet(data);
        return hashedSet;
    }
    exports.toHashedSet = toHashedSet;
    /**
     * check if a type is generic type
     * @param type
     * @returns
     */
    function isGenericType(type) {
        return /^([\w]+)<([\w,[\]\s<>]+)>$/.test(type);
    }
    exports.isGenericType = isGenericType;
    /**
     *
     * @param type eg. HashedMap<int,int>
     * @param eg. ["HashedMap", ["int", "int"]}] An array generic types returned by @getGenericDeclaration
     * @returns {"K": "int", "V": "int"}
     */
    function parseGenericType(type) {
        if (isGenericType(type)) {
            var m = type.match(/([\w]+)<([\w,[\]<>\s]+)>$/);
            if (m) {
                var library = m[1];
                var realTypes = [];
                var brackets = [];
                var tmpType = '';
                for (var i = 0; i < m[2].length; i++) {
                    var ch = m[2].charAt(i);
                    if (ch === '<' || ch === '[') {
                        brackets.push(ch);
                    }
                    else if (ch === '>' || ch === ']') {
                        brackets.pop();
                    }
                    else if (ch === ',') {
                        if (brackets.length === 0) {
                            realTypes.push(tmpType.trim());
                            tmpType = '';
                            continue;
                        }
                    }
                    tmpType += ch;
                }
                realTypes.push(tmpType.trim());
                return [library, realTypes];
            }
        }
        throw new Error("\"" + type + "\" is not generic type");
    }
    exports.parseGenericType = parseGenericType;
    // Equivalent to the built-in function `hash160` in scrypt
    function hash160(hexstr, encoding) {
        return mvc.crypto.Hash.sha256ripemd160(Buffer.from(hexstr, encoding || 'hex')).toString('hex');
    }
    exports.hash160 = hash160;
    // Equivalent to the built-in function `sha256` in scrypt
    function sha256(hexstr, encoding) {
        return mvc.crypto.Hash.sha256(Buffer.from(hexstr, encoding || 'hex')).toString('hex');
    }
    exports.sha256 = sha256;
    // Equivalent to the built-in function `hash256` in scrypt
    function hash256(hexstr, encoding) {
        return sha256(sha256(hexstr, encoding), encoding);
    }
    exports.hash256 = hash256;
    var LINKPATTERN = /(\[((!\[[^\]]*?\]\(\s*)([^\s()]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s()]|\([^\s()]*?\))+)\s*(".*?")?\)/g;
    function readLaunchJson(error) {
        var e_8, _a;
        try {
            for (var _b = __values(error.matchAll(LINKPATTERN)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var match = _c.value;
                if (match[5] && match[5].startsWith('scryptlaunch')) {
                    var file = match[5].replace(/scryptlaunch/, 'file');
                    return JSON.parse(fs.readFileSync(uri2path(file)).toString());
                }
            }
        }
        catch (e_8_1) { e_8 = { error: e_8_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_8) throw e_8.error; }
        }
        return undefined;
    }
    exports.readLaunchJson = readLaunchJson;
    // Equivalent to the built-in function `len` in scrypt
    function len(hexstr) {
        return hexstr.length / 2;
    }
    exports.len = len;
    // convert signed integer `n` to unsigned integer of `l` bytes, in little endian
    function toLEUnsigned(n, l) {
        // one extra byte to accommodate possible negative sign byte
        var m = num2bin(n, l + 1);
        // remove sign byte
        return m.slice(0, len(m) - 1);
    }
    exports.toLEUnsigned = toLEUnsigned;
    // convert 'b' to a VarInt field, including the preceding length
    function writeVarint(b) {
        var n = len(b);
        var header = '';
        if (n < 0xfd) {
            header = toLEUnsigned(n, 1);
        }
        else if (n < 0x10000) {
            header = 'fd' + toLEUnsigned(n, 2);
        }
        else if (n < 0x100000000) {
            header = 'fe' + toLEUnsigned(n, 4);
        }
        else if (n < 0x10000000000000000) {
            header = 'ff' + toLEUnsigned(n, 8);
        }
        return header + b;
    }
    exports.writeVarint = writeVarint;
    function buildOpreturnScript(data) {
        return mvc.Script.fromASM(['OP_FALSE', 'OP_RETURN', data].join(' '));
    }
    exports.buildOpreturnScript = buildOpreturnScript;
    function buildPublicKeyHashScript(pubKeyHash) {
        return mvc.Script.fromASM(['OP_DUP', 'OP_HASH160', pubKeyHash.toASM(), 'OP_EQUALVERIFY', 'OP_CHECKSIG'].join(' '));
    }
    exports.buildPublicKeyHashScript = buildPublicKeyHashScript;
    /**
     * Parse out which public function is called through unlocking script
     * @param contract
     * @param hex hex of unlocking script
     * @returns return ABIEntity of the public function which is call by the unlocking script
     */
    function parseAbiFromUnlockingScript(contract, hex) {
        var abis = Object.getPrototypeOf(contract).constructor.abi;
        var pubFunAbis = abis.filter(function (entity) { return entity.type === 'function'; });
        var pubFunCount = pubFunAbis.length;
        if (pubFunCount === 1) {
            return pubFunAbis[0];
        }
        var script = mvc.Script.fromHex(hex);
        var usASM = script.toASM();
        var pubFuncIndexASM = usASM.substr(usASM.lastIndexOf(' ') + 1);
        var pubFuncIndex = asm2int(pubFuncIndexASM);
        var entity = abis.find(function (entity) { return entity.index === pubFuncIndex; });
        if (!entity) {
            throw new Error("the raw unlocking script cannot match the contract " + contract.contractName);
        }
        return entity;
    }
    exports.parseAbiFromUnlockingScript = parseAbiFromUnlockingScript;
    function toScryptType(a) {
        if (typeof a === 'number' || typeof a === 'bigint' || typeof a === 'string') {
            return new internal_1.Int(a);
        }
        else if (typeof a === 'boolean') {
            return new internal_1.Bool(a);
        }
        else if (a instanceof internal_1.ScryptType) {
            return a;
        }
        else {
            throw a + " cannot be convert to ScryptType";
        }
    }
    exports.toScryptType = toScryptType;
    function arrayToScryptType(a) {
        return a.map(function (i) {
            if (Array.isArray(i)) {
                return arrayToScryptType(i);
            }
            return toScryptType(i);
        });
    }
    exports.arrayToScryptType = arrayToScryptType;
    function arrayToJson(a) {
        return a.map(function (i) {
            if (Array.isArray(i)) {
                return arrayToJson(i);
            }
            return toScryptType(i).toJSON();
        });
    }
    exports.arrayToJson = arrayToJson;
    function cloneArray(a) {
        return a.map(function (i) {
            if (Array.isArray(i)) {
                return cloneArray(i);
            }
            return toScryptType(i).clone();
        });
    }
    exports.cloneArray = cloneArray;
    function inferrType(a) {
        if (Array.isArray(a)) {
            if (a.length === 0) {
                throw new Error('cannot inferr type from empty array');
            }
            var arg0_1 = a[0];
            if (Array.isArray(arg0_1)) {
                if (!a.every(function (arg) { return Array.isArray(arg) && arg.length === arg0_1.length; })) {
                    throw new Error("cannot inferr type from [" + a + "] , not all length of element are the same");
                }
                var _a = __read(arrayTypeAndSize(inferrType(arg0_1)), 2), e = _a[0], sizes = _a[1];
                return toLiteralArrayType(e, [a.length].concat(sizes));
            }
            else {
                var t_1 = typeOfArg(arg0_1);
                if (!a.every(function (arg) { return typeOfArg(arg) === t_1; })) {
                    throw new Error("cannot inferr type from [" + a + "] , not all element types are the same");
                }
                return toScryptType(a[0]).finalType + "[" + a.length + "]";
            }
        }
        else {
            return toScryptType(a).finalType;
        }
    }
    exports.inferrType = inferrType;
    function resolveGenericType(genericTypeMap, type) {
        if (Object.keys(genericTypeMap).length > 0) {
            if (isGenericType(type)) {
                var _a = __read(parseGenericType(type), 2), name_4 = _a[0], types = _a[1];
                return toGenericType(name_4, types.map(function (t) { return genericTypeMap[t] || t; }));
            }
            if (isArrayType(type)) {
                var _b = __read(arrayTypeAndSizeStr(type), 2), elem = _b[0], sizes = _b[1];
                return toLiteralArrayType(elem, sizes.map(function (t) { return genericTypeMap[t] || t; }));
            }
            return genericTypeMap[type] || type;
        }
        return type;
    }
    exports.resolveGenericType = resolveGenericType;
    function librarySign(genericEntity) {
        return "[" + genericEntity.params.map(function (p) { return p.type; }).join(',') + "]";
    }
    exports.librarySign = librarySign;
    function structSign(structEntity) {
        return "" + JSON.stringify(structEntity.params.reduce(function (p, v) {
            var _a;
            return Object.assign(p, (_a = {},
                _a[v.name] = v.type,
                _a));
        }, {}), null, 4);
    }
    exports.structSign = structSign;
    function arrayToLiteral(a) {
        var al = a
            .map(function (i) {
            if (Array.isArray(i)) {
                return arrayToLiteral(i);
            }
            return toScryptType(i).toLiteral();
        })
            .join(',');
        return "[" + al + "]";
    }
    exports.arrayToLiteral = arrayToLiteral;
    // If the property is the same as the construction parameter, there may be no constructor, in which case the construction parameter can be assigned to the property. But this does not guarantee that the property is always correct, the user may have modified the value of the property in the constructor
    function canAssignProperty(libraryAst) {
        return (libraryAst.params.length === libraryAst.properties.length &&
            libraryAst.params.every(function (param, index) {
                return param.name === libraryAst.properties[index].name && param.type === libraryAst.properties[index].type;
            }));
    }
    exports.canAssignProperty = canAssignProperty;
    function int2Number(value) {
        if (typeof value === 'number' || typeof value === 'bigint') {
            return value;
        }
        else if (typeof value === 'string') {
            if (value.startsWith('0x')) {
                var bn = new BN(value.substr(2), 16);
                return bn.toNumber();
            }
            else {
                var bn = new BN(value);
                return bn.toNumber();
            }
        }
    }
    exports.int2Number = int2Number;
    function and(a, b) {
        var size1 = a.serialize().length / 2;
        var size2 = b.serialize().length / 2;
        var maxSize = Math.max(size1, size2);
        var ba = Buffer.from(num2bin(a.toNumber(), maxSize), 'hex');
        var bb = Buffer.from(num2bin(b.toNumber(), maxSize), 'hex');
        for (var i = 0; i < ba.length; i++) {
            ba[i] &= bb[i];
        }
        return new internal_1.Int(bin2num(ba));
    }
    exports.and = and;
    function or(a, b) {
        var size1 = a.serialize().length / 2;
        var size2 = b.serialize().length / 2;
        var maxSize = Math.max(size1, size2);
        var ba = Buffer.from(num2bin(a.toNumber(), maxSize), 'hex');
        var bb = Buffer.from(num2bin(b.toNumber(), maxSize), 'hex');
        for (var i = 0; i < ba.length; i++) {
            ba[i] |= bb[i];
        }
        return new internal_1.Int(bin2num(ba));
    }
    exports.or = or;
    function xor(a, b) {
        var size1 = a.serialize().length / 2;
        var size2 = b.serialize().length / 2;
        var maxSize = Math.max(size1, size2);
        var ba = Buffer.from(num2bin(a.toNumber(), maxSize), 'hex');
        var bb = Buffer.from(num2bin(b.toNumber(), maxSize), 'hex');
        for (var i = 0; i < ba.length; i++) {
            ba[i] ^= bb[i];
        }
        return new internal_1.Int(bin2num(ba));
    }
    exports.xor = xor;
    function invert(a) {
        if (a.toNumber() === 0) {
            return a;
        }
        var size = a.serialize().length / 2;
        var buffer = Buffer.from(num2bin(a.toNumber(), size), 'hex');
        for (var i = 0; i < buffer.length; i++) {
            buffer[i] = ~buffer[i];
        }
        return new internal_1.Int(bin2num(buffer));
    }
    exports.invert = invert;
    function JSONParser(file) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        json_ext_1.parseChunked(fs.createReadStream(file))
                            .then(function (data) {
                            resolve(data);
                        })
                            .catch(function (e) {
                            reject(e);
                        });
                    })];
            });
        });
    }
    exports.JSONParser = JSONParser;
    function JSONParserSync(file) {
        return JSON.parse(fs.readFileSync(file, 'utf8'));
    }
    exports.JSONParserSync = JSONParserSync;
    function JSONStringify(file, data) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        json_ext_1.stringifyStream(data)
                            .pipe(fs.createWriteStream(file))
                            .on('finish', function () {
                            resolve(true);
                        })
                            .on('error', function (e) {
                            reject(e);
                        });
                    })];
            });
        });
    }
    exports.JSONStringify = JSONStringify;
    function findSrcInfoV2(pc, sourceMap) {
        var decoded = sourcemap_codec_1.decode(sourceMap['mappings']);
        for (var index = 0; index < decoded[0].length; index++) {
            var element = decoded[0][index];
            if (element[0] <= pc) {
                continue;
            }
            return decoded[0][index - 1];
        }
        return decoded[0][decoded[0].length - 1];
    }
    exports.findSrcInfoV2 = findSrcInfoV2;
    /**
     * @deprecated use findSrcInfoV2
     * @param opcodes OpCode[] from sourceMap
     */
    function findSrcInfoV1(opcodes, opcodesIndex) {
        while (--opcodesIndex > 0) {
            if (opcodes[opcodesIndex].pos && opcodes[opcodesIndex].pos.file !== 'std' && opcodes[opcodesIndex].pos.line > 0) {
                return opcodes[opcodesIndex];
            }
        }
    }
    exports.findSrcInfoV1 = findSrcInfoV1;
    function parseStateHex(contract, scriptHex) {
        var metaScript = scriptHex.substr(scriptHex.length - 10, 10);
        var version = bin2num(metaScript.substr(metaScript.length - 2, 2));
        var stateLen = bin2num(metaScript.substr(0, 8));
        var stateHex = scriptHex.substr(scriptHex.length - 10 - stateLen * 2, stateLen * 2);
        var br = new mvc.encoding.BufferReader(stateHex);
        var opcodenum = br.readUInt8();
        var firstCall = opcodenum == 1;
        var stateTemplateArgs = new Map();
        var flatternparams = flatternParams(contract.stateProps, contract.resolver);
        flatternparams.forEach(function (param) {
            if (param.type === internal_1.VariableType.BOOL) {
                var opcodenum_1 = br.readUInt8();
                stateTemplateArgs.set("<" + param.name + ">", opcodenum_1 === 1 ? '51' : '00');
            }
            else {
                var data = readBytes(br).data;
                if (param.type === internal_1.VariableType.INT || param.type === internal_1.VariableType.PRIVKEY) {
                    stateTemplateArgs.set("<" + param.name + ">", new internal_1.Int(bin2num(data)).toHex());
                }
                else {
                    stateTemplateArgs.set("<" + param.name + ">", mvc.Script.fromASM(data).toHex());
                }
            }
        });
        return [
            firstCall,
            contract.stateProps.map(function (param) {
                return deserializeArgfromState(contract.resolver, Object.assign(param, {
                    value: undefined,
                }), stateTemplateArgs);
            }),
        ];
    }
    exports.parseStateHex = parseStateHex;
    
    }).call(this)}).call(this,require('_process'),require("buffer").Buffer,"/node_modules/mvc-scrypt/dist")
    
    },{"./compilerWrapper":279,"./internal":283,"./scryptTypes":285,"@discoveryjs/json-ext":2,"_process":321,"buffer":84,"fs":36,"mvc-lib":199,"mvc-lib/ecies":198,"os":296,"path":313,"sourcemap-codec":349,"url":368}],288:[function(require,module,exports){
    (function (global){(function (){
    "use strict";
    
    // ref: https://github.com/tc39/proposal-global
    var getGlobal = function () {
        // the only reliable means to get the global object is
        // `Function('return this')()`
        // However, this causes CSP violations in Chrome apps.
        if (typeof self !== 'undefined') { return self; }
        if (typeof window !== 'undefined') { return window; }
        if (typeof global !== 'undefined') { return global; }
        throw new Error('unable to locate global object');
    }
    
    var globalObject = getGlobal();
    
    module.exports = exports = globalObject.fetch;
    
    // Needed for TypeScript and Webpack.
    if (globalObject.fetch) {
        exports.default = globalObject.fetch.bind(globalObject);
    }
    
    exports.Headers = globalObject.Headers;
    exports.Request = globalObject.Request;
    exports.Response = globalObject.Response;
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{}],289:[function(require,module,exports){
    var hasMap = typeof Map === 'function' && Map.prototype;
    var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
    var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
    var mapForEach = hasMap && Map.prototype.forEach;
    var hasSet = typeof Set === 'function' && Set.prototype;
    var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
    var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
    var setForEach = hasSet && Set.prototype.forEach;
    var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
    var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
    var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
    var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
    var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
    var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
    var booleanValueOf = Boolean.prototype.valueOf;
    var objectToString = Object.prototype.toString;
    var functionToString = Function.prototype.toString;
    var $match = String.prototype.match;
    var $slice = String.prototype.slice;
    var $replace = String.prototype.replace;
    var $toUpperCase = String.prototype.toUpperCase;
    var $toLowerCase = String.prototype.toLowerCase;
    var $test = RegExp.prototype.test;
    var $concat = Array.prototype.concat;
    var $join = Array.prototype.join;
    var $arrSlice = Array.prototype.slice;
    var $floor = Math.floor;
    var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
    var gOPS = Object.getOwnPropertySymbols;
    var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
    var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
    // ie, `has-tostringtag/shams
    var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
        ? Symbol.toStringTag
        : null;
    var isEnumerable = Object.prototype.propertyIsEnumerable;
    
    var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
        [].__proto__ === Array.prototype // eslint-disable-line no-proto
            ? function (O) {
                return O.__proto__; // eslint-disable-line no-proto
            }
            : null
    );
    
    function addNumericSeparator(num, str) {
        if (
            num === Infinity
            || num === -Infinity
            || num !== num
            || (num && num > -1000 && num < 1000)
            || $test.call(/e/, str)
        ) {
            return str;
        }
        var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
        if (typeof num === 'number') {
            var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
            if (int !== num) {
                var intStr = String(int);
                var dec = $slice.call(str, intStr.length + 1);
                return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
            }
        }
        return $replace.call(str, sepRegex, '$&_');
    }
    
    var utilInspect = require('./util.inspect');
    var inspectCustom = utilInspect.custom;
    var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;
    
    module.exports = function inspect_(obj, options, depth, seen) {
        var opts = options || {};
    
        if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {
            throw new TypeError('option "quoteStyle" must be "single" or "double"');
        }
        if (
            has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
                ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
                : opts.maxStringLength !== null
            )
        ) {
            throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
        }
        var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
        if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
            throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
        }
    
        if (
            has(opts, 'indent')
            && opts.indent !== null
            && opts.indent !== '\t'
            && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
        ) {
            throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
        }
        if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
            throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
        }
        var numericSeparator = opts.numericSeparator;
    
        if (typeof obj === 'undefined') {
            return 'undefined';
        }
        if (obj === null) {
            return 'null';
        }
        if (typeof obj === 'boolean') {
            return obj ? 'true' : 'false';
        }
    
        if (typeof obj === 'string') {
            return inspectString(obj, opts);
        }
        if (typeof obj === 'number') {
            if (obj === 0) {
                return Infinity / obj > 0 ? '0' : '-0';
            }
            var str = String(obj);
            return numericSeparator ? addNumericSeparator(obj, str) : str;
        }
        if (typeof obj === 'bigint') {
            var bigIntStr = String(obj) + 'n';
            return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
        }
    
        var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
        if (typeof depth === 'undefined') { depth = 0; }
        if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
            return isArray(obj) ? '[Array]' : '[Object]';
        }
    
        var indent = getIndent(opts, depth);
    
        if (typeof seen === 'undefined') {
            seen = [];
        } else if (indexOf(seen, obj) >= 0) {
            return '[Circular]';
        }
    
        function inspect(value, from, noIndent) {
            if (from) {
                seen = $arrSlice.call(seen);
                seen.push(from);
            }
            if (noIndent) {
                var newOpts = {
                    depth: opts.depth
                };
                if (has(opts, 'quoteStyle')) {
                    newOpts.quoteStyle = opts.quoteStyle;
                }
                return inspect_(value, newOpts, depth + 1, seen);
            }
            return inspect_(value, opts, depth + 1, seen);
        }
    
        if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
            var name = nameOf(obj);
            var keys = arrObjKeys(obj, inspect);
            return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
        }
        if (isSymbol(obj)) {
            var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
            return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
        }
        if (isElement(obj)) {
            var s = '<' + $toLowerCase.call(String(obj.nodeName));
            var attrs = obj.attributes || [];
            for (var i = 0; i < attrs.length; i++) {
                s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
            }
            s += '>';
            if (obj.childNodes && obj.childNodes.length) { s += '...'; }
            s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';
            return s;
        }
        if (isArray(obj)) {
            if (obj.length === 0) { return '[]'; }
            var xs = arrObjKeys(obj, inspect);
            if (indent && !singleLineValues(xs)) {
                return '[' + indentedJoin(xs, indent) + ']';
            }
            return '[ ' + $join.call(xs, ', ') + ' ]';
        }
        if (isError(obj)) {
            var parts = arrObjKeys(obj, inspect);
            if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
                return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
            }
            if (parts.length === 0) { return '[' + String(obj) + ']'; }
            return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
        }
        if (typeof obj === 'object' && customInspect) {
            if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
                return utilInspect(obj, { depth: maxDepth - depth });
            } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
                return obj.inspect();
            }
        }
        if (isMap(obj)) {
            var mapParts = [];
            if (mapForEach) {
                mapForEach.call(obj, function (value, key) {
                    mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
                });
            }
            return collectionOf('Map', mapSize.call(obj), mapParts, indent);
        }
        if (isSet(obj)) {
            var setParts = [];
            if (setForEach) {
                setForEach.call(obj, function (value) {
                    setParts.push(inspect(value, obj));
                });
            }
            return collectionOf('Set', setSize.call(obj), setParts, indent);
        }
        if (isWeakMap(obj)) {
            return weakCollectionOf('WeakMap');
        }
        if (isWeakSet(obj)) {
            return weakCollectionOf('WeakSet');
        }
        if (isWeakRef(obj)) {
            return weakCollectionOf('WeakRef');
        }
        if (isNumber(obj)) {
            return markBoxed(inspect(Number(obj)));
        }
        if (isBigInt(obj)) {
            return markBoxed(inspect(bigIntValueOf.call(obj)));
        }
        if (isBoolean(obj)) {
            return markBoxed(booleanValueOf.call(obj));
        }
        if (isString(obj)) {
            return markBoxed(inspect(String(obj)));
        }
        if (!isDate(obj) && !isRegExp(obj)) {
            var ys = arrObjKeys(obj, inspect);
            var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
            var protoTag = obj instanceof Object ? '' : 'null prototype';
            var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
            var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
            var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
            if (ys.length === 0) { return tag + '{}'; }
            if (indent) {
                return tag + '{' + indentedJoin(ys, indent) + '}';
            }
            return tag + '{ ' + $join.call(ys, ', ') + ' }';
        }
        return String(obj);
    };
    
    function wrapQuotes(s, defaultStyle, opts) {
        var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'";
        return quoteChar + s + quoteChar;
    }
    
    function quote(s) {
        return $replace.call(String(s), /"/g, '&quot;');
    }
    
    function isArray(obj) { return toStr(obj) === '[object Array]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isDate(obj) { return toStr(obj) === '[object Date]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isError(obj) { return toStr(obj) === '[object Error]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isString(obj) { return toStr(obj) === '[object String]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isNumber(obj) { return toStr(obj) === '[object Number]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && (!toStringTag || !(typeof obj === 'object' && toStringTag in obj)); }
    
    // Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
    function isSymbol(obj) {
        if (hasShammedSymbols) {
            return obj && typeof obj === 'object' && obj instanceof Symbol;
        }
        if (typeof obj === 'symbol') {
            return true;
        }
        if (!obj || typeof obj !== 'object' || !symToString) {
            return false;
        }
        try {
            symToString.call(obj);
            return true;
        } catch (e) {}
        return false;
    }
    
    function isBigInt(obj) {
        if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
            return false;
        }
        try {
            bigIntValueOf.call(obj);
            return true;
        } catch (e) {}
        return false;
    }
    
    var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
    function has(obj, key) {
        return hasOwn.call(obj, key);
    }
    
    function toStr(obj) {
        return objectToString.call(obj);
    }
    
    function nameOf(f) {
        if (f.name) { return f.name; }
        var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
        if (m) { return m[1]; }
        return null;
    }
    
    function indexOf(xs, x) {
        if (xs.indexOf) { return xs.indexOf(x); }
        for (var i = 0, l = xs.length; i < l; i++) {
            if (xs[i] === x) { return i; }
        }
        return -1;
    }
    
    function isMap(x) {
        if (!mapSize || !x || typeof x !== 'object') {
            return false;
        }
        try {
            mapSize.call(x);
            try {
                setSize.call(x);
            } catch (s) {
                return true;
            }
            return x instanceof Map; // core-js workaround, pre-v2.5.0
        } catch (e) {}
        return false;
    }
    
    function isWeakMap(x) {
        if (!weakMapHas || !x || typeof x !== 'object') {
            return false;
        }
        try {
            weakMapHas.call(x, weakMapHas);
            try {
                weakSetHas.call(x, weakSetHas);
            } catch (s) {
                return true;
            }
            return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
        } catch (e) {}
        return false;
    }
    
    function isWeakRef(x) {
        if (!weakRefDeref || !x || typeof x !== 'object') {
            return false;
        }
        try {
            weakRefDeref.call(x);
            return true;
        } catch (e) {}
        return false;
    }
    
    function isSet(x) {
        if (!setSize || !x || typeof x !== 'object') {
            return false;
        }
        try {
            setSize.call(x);
            try {
                mapSize.call(x);
            } catch (m) {
                return true;
            }
            return x instanceof Set; // core-js workaround, pre-v2.5.0
        } catch (e) {}
        return false;
    }
    
    function isWeakSet(x) {
        if (!weakSetHas || !x || typeof x !== 'object') {
            return false;
        }
        try {
            weakSetHas.call(x, weakSetHas);
            try {
                weakMapHas.call(x, weakMapHas);
            } catch (s) {
                return true;
            }
            return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
        } catch (e) {}
        return false;
    }
    
    function isElement(x) {
        if (!x || typeof x !== 'object') { return false; }
        if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
            return true;
        }
        return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
    }
    
    function inspectString(str, opts) {
        if (str.length > opts.maxStringLength) {
            var remaining = str.length - opts.maxStringLength;
            var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
            return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
        }
        // eslint-disable-next-line no-control-regex
        var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte);
        return wrapQuotes(s, 'single', opts);
    }
    
    function lowbyte(c) {
        var n = c.charCodeAt(0);
        var x = {
            8: 'b',
            9: 't',
            10: 'n',
            12: 'f',
            13: 'r'
        }[n];
        if (x) { return '\\' + x; }
        return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
    }
    
    function markBoxed(str) {
        return 'Object(' + str + ')';
    }
    
    function weakCollectionOf(type) {
        return type + ' { ? }';
    }
    
    function collectionOf(type, size, entries, indent) {
        var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
        return type + ' (' + size + ') {' + joinedEntries + '}';
    }
    
    function singleLineValues(xs) {
        for (var i = 0; i < xs.length; i++) {
            if (indexOf(xs[i], '\n') >= 0) {
                return false;
            }
        }
        return true;
    }
    
    function getIndent(opts, depth) {
        var baseIndent;
        if (opts.indent === '\t') {
            baseIndent = '\t';
        } else if (typeof opts.indent === 'number' && opts.indent > 0) {
            baseIndent = $join.call(Array(opts.indent + 1), ' ');
        } else {
            return null;
        }
        return {
            base: baseIndent,
            prev: $join.call(Array(depth + 1), baseIndent)
        };
    }
    
    function indentedJoin(xs, indent) {
        if (xs.length === 0) { return ''; }
        var lineJoiner = '\n' + indent.prev + indent.base;
        return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
    }
    
    function arrObjKeys(obj, inspect) {
        var isArr = isArray(obj);
        var xs = [];
        if (isArr) {
            xs.length = obj.length;
            for (var i = 0; i < obj.length; i++) {
                xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
            }
        }
        var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
        var symMap;
        if (hasShammedSymbols) {
            symMap = {};
            for (var k = 0; k < syms.length; k++) {
                symMap['$' + syms[k]] = syms[k];
            }
        }
    
        for (var key in obj) { // eslint-disable-line no-restricted-syntax
            if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
            if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
            if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
                // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
                continue; // eslint-disable-line no-restricted-syntax, no-continue
            } else if ($test.call(/[^\w$]/, key)) {
                xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
            } else {
                xs.push(key + ': ' + inspect(obj[key], obj));
            }
        }
        if (typeof gOPS === 'function') {
            for (var j = 0; j < syms.length; j++) {
                if (isEnumerable.call(obj, syms[j])) {
                    xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
                }
            }
        }
        return xs;
    }
    
    },{"./util.inspect":36}],290:[function(require,module,exports){
    'use strict';
    
    var keysShim;
    if (!Object.keys) {
        // modified from https://github.com/es-shims/es5-shim
        var has = Object.prototype.hasOwnProperty;
        var toStr = Object.prototype.toString;
        var isArgs = require('./isArguments'); // eslint-disable-line global-require
        var isEnumerable = Object.prototype.propertyIsEnumerable;
        var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
        var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
        var dontEnums = [
            'toString',
            'toLocaleString',
            'valueOf',
            'hasOwnProperty',
            'isPrototypeOf',
            'propertyIsEnumerable',
            'constructor'
        ];
        var equalsConstructorPrototype = function (o) {
            var ctor = o.constructor;
            return ctor && ctor.prototype === o;
        };
        var excludedKeys = {
            $applicationCache: true,
            $console: true,
            $external: true,
            $frame: true,
            $frameElement: true,
            $frames: true,
            $innerHeight: true,
            $innerWidth: true,
            $onmozfullscreenchange: true,
            $onmozfullscreenerror: true,
            $outerHeight: true,
            $outerWidth: true,
            $pageXOffset: true,
            $pageYOffset: true,
            $parent: true,
            $scrollLeft: true,
            $scrollTop: true,
            $scrollX: true,
            $scrollY: true,
            $self: true,
            $webkitIndexedDB: true,
            $webkitStorageInfo: true,
            $window: true
        };
        var hasAutomationEqualityBug = (function () {
            /* global window */
            if (typeof window === 'undefined') { return false; }
            for (var k in window) {
                try {
                    if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
                        try {
                            equalsConstructorPrototype(window[k]);
                        } catch (e) {
                            return true;
                        }
                    }
                } catch (e) {
                    return true;
                }
            }
            return false;
        }());
        var equalsConstructorPrototypeIfNotBuggy = function (o) {
            /* global window */
            if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
                return equalsConstructorPrototype(o);
            }
            try {
                return equalsConstructorPrototype(o);
            } catch (e) {
                return false;
            }
        };
    
        keysShim = function keys(object) {
            var isObject = object !== null && typeof object === 'object';
            var isFunction = toStr.call(object) === '[object Function]';
            var isArguments = isArgs(object);
            var isString = isObject && toStr.call(object) === '[object String]';
            var theKeys = [];
    
            if (!isObject && !isFunction && !isArguments) {
                throw new TypeError('Object.keys called on a non-object');
            }
    
            var skipProto = hasProtoEnumBug && isFunction;
            if (isString && object.length > 0 && !has.call(object, 0)) {
                for (var i = 0; i < object.length; ++i) {
                    theKeys.push(String(i));
                }
            }
    
            if (isArguments && object.length > 0) {
                for (var j = 0; j < object.length; ++j) {
                    theKeys.push(String(j));
                }
            } else {
                for (var name in object) {
                    if (!(skipProto && name === 'prototype') && has.call(object, name)) {
                        theKeys.push(String(name));
                    }
                }
            }
    
            if (hasDontEnumBug) {
                var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
    
                for (var k = 0; k < dontEnums.length; ++k) {
                    if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
                        theKeys.push(dontEnums[k]);
                    }
                }
            }
            return theKeys;
        };
    }
    module.exports = keysShim;
    
    },{"./isArguments":292}],291:[function(require,module,exports){
    'use strict';
    
    var slice = Array.prototype.slice;
    var isArgs = require('./isArguments');
    
    var origKeys = Object.keys;
    var keysShim = origKeys ? function keys(o) { return origKeys(o); } : require('./implementation');
    
    var originalKeys = Object.keys;
    
    keysShim.shim = function shimObjectKeys() {
        if (Object.keys) {
            var keysWorksWithArguments = (function () {
                // Safari 5.0 bug
                var args = Object.keys(arguments);
                return args && args.length === arguments.length;
            }(1, 2));
            if (!keysWorksWithArguments) {
                Object.keys = function keys(object) { // eslint-disable-line func-name-matching
                    if (isArgs(object)) {
                        return originalKeys(slice.call(object));
                    }
                    return originalKeys(object);
                };
            }
        } else {
            Object.keys = keysShim;
        }
        return Object.keys || keysShim;
    };
    
    module.exports = keysShim;
    
    },{"./implementation":290,"./isArguments":292}],292:[function(require,module,exports){
    'use strict';
    
    var toStr = Object.prototype.toString;
    
    module.exports = function isArguments(value) {
        var str = toStr.call(value);
        var isArgs = str === '[object Arguments]';
        if (!isArgs) {
            isArgs = str !== '[object Array]' &&
                value !== null &&
                typeof value === 'object' &&
                typeof value.length === 'number' &&
                value.length >= 0 &&
                toStr.call(value.callee) === '[object Function]';
        }
        return isArgs;
    };
    
    },{}],293:[function(require,module,exports){
    'use strict';
    
    // modified from https://github.com/es-shims/es6-shim
    var objectKeys = require('object-keys');
    var hasSymbols = require('has-symbols/shams')();
    var callBound = require('call-bind/callBound');
    var toObject = Object;
    var $push = callBound('Array.prototype.push');
    var $propIsEnumerable = callBound('Object.prototype.propertyIsEnumerable');
    var originalGetSymbols = hasSymbols ? Object.getOwnPropertySymbols : null;
    
    // eslint-disable-next-line no-unused-vars
    module.exports = function assign(target, source1) {
        if (target == null) { throw new TypeError('target must be an object'); }
        var to = toObject(target); // step 1
        if (arguments.length === 1) {
            return to; // step 2
        }
        for (var s = 1; s < arguments.length; ++s) {
            var from = toObject(arguments[s]); // step 3.a.i
    
            // step 3.a.ii:
            var keys = objectKeys(from);
            var getSymbols = hasSymbols && (Object.getOwnPropertySymbols || originalGetSymbols);
            if (getSymbols) {
                var syms = getSymbols(from);
                for (var j = 0; j < syms.length; ++j) {
                    var key = syms[j];
                    if ($propIsEnumerable(from, key)) {
                        $push(keys, key);
                    }
                }
            }
    
            // step 3.a.iii:
            for (var i = 0; i < keys.length; ++i) {
                var nextKey = keys[i];
                if ($propIsEnumerable(from, nextKey)) { // step 3.a.iii.2
                    var propValue = from[nextKey]; // step 3.a.iii.2.a
                    to[nextKey] = propValue; // step 3.a.iii.2.b
                }
            }
        }
    
        return to; // step 4
    };
    
    },{"call-bind/callBound":88,"has-symbols/shams":148,"object-keys":291}],294:[function(require,module,exports){
    'use strict';
    
    var implementation = require('./implementation');
    
    var lacksProperEnumerationOrder = function () {
        if (!Object.assign) {
            return false;
        }
        /*
         * v8, specifically in node 4.x, has a bug with incorrect property enumeration order
         * note: this does not detect the bug unless there's 20 characters
         */
        var str = 'abcdefghijklmnopqrst';
        var letters = str.split('');
        var map = {};
        for (var i = 0; i < letters.length; ++i) {
            map[letters[i]] = letters[i];
        }
        var obj = Object.assign({}, map);
        var actual = '';
        for (var k in obj) {
            actual += k;
        }
        return str !== actual;
    };
    
    var assignHasPendingExceptions = function () {
        if (!Object.assign || !Object.preventExtensions) {
            return false;
        }
        /*
         * Firefox 37 still has "pending exception" logic in its Object.assign implementation,
         * which is 72% slower than our shim, and Firefox 40's native implementation.
         */
        var thrower = Object.preventExtensions({ 1: 2 });
        try {
            Object.assign(thrower, 'xy');
        } catch (e) {
            return thrower[1] === 'y';
        }
        return false;
    };
    
    module.exports = function getPolyfill() {
        if (!Object.assign) {
            return implementation;
        }
        if (lacksProperEnumerationOrder()) {
            return implementation;
        }
        if (assignHasPendingExceptions()) {
            return implementation;
        }
        return Object.assign;
    };
    
    },{"./implementation":293}],295:[function(require,module,exports){
    var wrappy = require('wrappy')
    module.exports = wrappy(once)
    module.exports.strict = wrappy(onceStrict)
    
    once.proto = once(function () {
      Object.defineProperty(Function.prototype, 'once', {
        value: function () {
          return once(this)
        },
        configurable: true
      })
    
      Object.defineProperty(Function.prototype, 'onceStrict', {
        value: function () {
          return onceStrict(this)
        },
        configurable: true
      })
    })
    
    function once (fn) {
      var f = function () {
        if (f.called) return f.value
        f.called = true
        return f.value = fn.apply(this, arguments)
      }
      f.called = false
      return f
    }
    
    function onceStrict (fn) {
      var f = function () {
        if (f.called)
          throw new Error(f.onceError)
        f.called = true
        return f.value = fn.apply(this, arguments)
      }
      var name = fn.name || 'Function wrapped with `once`'
      f.onceError = name + " shouldn't be called more than once"
      f.called = false
      return f
    }
    
    },{"wrappy":374}],296:[function(require,module,exports){
    exports.endianness = function () { return 'LE' };
    
    exports.hostname = function () {
        if (typeof location !== 'undefined') {
            return location.hostname
        }
        else return '';
    };
    
    exports.loadavg = function () { return [] };
    
    exports.uptime = function () { return 0 };
    
    exports.freemem = function () {
        return Number.MAX_VALUE;
    };
    
    exports.totalmem = function () {
        return Number.MAX_VALUE;
    };
    
    exports.cpus = function () { return [] };
    
    exports.type = function () { return 'Browser' };
    
    exports.release = function () {
        if (typeof navigator !== 'undefined') {
            return navigator.appVersion;
        }
        return '';
    };
    
    exports.networkInterfaces
    = exports.getNetworkInterfaces
    = function () { return {} };
    
    exports.arch = function () { return 'javascript' };
    
    exports.platform = function () { return 'browser' };
    
    exports.tmpdir = exports.tmpDir = function () {
        return '/tmp';
    };
    
    exports.EOL = '\n';
    
    exports.homedir = function () {
        return '/'
    };
    
    },{}],297:[function(require,module,exports){
    'use strict';
    
    
    var TYPED_OK =  (typeof Uint8Array !== 'undefined') &&
                    (typeof Uint16Array !== 'undefined') &&
                    (typeof Int32Array !== 'undefined');
    
    function _has(obj, key) {
      return Object.prototype.hasOwnProperty.call(obj, key);
    }
    
    exports.assign = function (obj /*from1, from2, from3, ...*/) {
      var sources = Array.prototype.slice.call(arguments, 1);
      while (sources.length) {
        var source = sources.shift();
        if (!source) { continue; }
    
        if (typeof source !== 'object') {
          throw new TypeError(source + 'must be non-object');
        }
    
        for (var p in source) {
          if (_has(source, p)) {
            obj[p] = source[p];
          }
        }
      }
    
      return obj;
    };
    
    
    // reduce buffer size, avoiding mem copy
    exports.shrinkBuf = function (buf, size) {
      if (buf.length === size) { return buf; }
      if (buf.subarray) { return buf.subarray(0, size); }
      buf.length = size;
      return buf;
    };
    
    
    var fnTyped = {
      arraySet: function (dest, src, src_offs, len, dest_offs) {
        if (src.subarray && dest.subarray) {
          dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
          return;
        }
        // Fallback to ordinary array
        for (var i = 0; i < len; i++) {
          dest[dest_offs + i] = src[src_offs + i];
        }
      },
      // Join array of chunks to single array.
      flattenChunks: function (chunks) {
        var i, l, len, pos, chunk, result;
    
        // calculate data length
        len = 0;
        for (i = 0, l = chunks.length; i < l; i++) {
          len += chunks[i].length;
        }
    
        // join chunks
        result = new Uint8Array(len);
        pos = 0;
        for (i = 0, l = chunks.length; i < l; i++) {
          chunk = chunks[i];
          result.set(chunk, pos);
          pos += chunk.length;
        }
    
        return result;
      }
    };
    
    var fnUntyped = {
      arraySet: function (dest, src, src_offs, len, dest_offs) {
        for (var i = 0; i < len; i++) {
          dest[dest_offs + i] = src[src_offs + i];
        }
      },
      // Join array of chunks to single array.
      flattenChunks: function (chunks) {
        return [].concat.apply([], chunks);
      }
    };
    
    
    // Enable/Disable typed arrays use, for testing
    //
    exports.setTyped = function (on) {
      if (on) {
        exports.Buf8  = Uint8Array;
        exports.Buf16 = Uint16Array;
        exports.Buf32 = Int32Array;
        exports.assign(exports, fnTyped);
      } else {
        exports.Buf8  = Array;
        exports.Buf16 = Array;
        exports.Buf32 = Array;
        exports.assign(exports, fnUntyped);
      }
    };
    
    exports.setTyped(TYPED_OK);
    
    },{}],298:[function(require,module,exports){
    'use strict';
    
    // Note: adler32 takes 12% for level 0 and 2% for level 6.
    // It isn't worth it to make additional optimizations as in original.
    // Small size is preferable.
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    function adler32(adler, buf, len, pos) {
      var s1 = (adler & 0xffff) |0,
          s2 = ((adler >>> 16) & 0xffff) |0,
          n = 0;
    
      while (len !== 0) {
        // Set limit ~ twice less than 5552, to keep
        // s2 in 31-bits, because we force signed ints.
        // in other case %= will fail.
        n = len > 2000 ? 2000 : len;
        len -= n;
    
        do {
          s1 = (s1 + buf[pos++]) |0;
          s2 = (s2 + s1) |0;
        } while (--n);
    
        s1 %= 65521;
        s2 %= 65521;
      }
    
      return (s1 | (s2 << 16)) |0;
    }
    
    
    module.exports = adler32;
    
    },{}],299:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    module.exports = {
    
      /* Allowed flush values; see deflate() and inflate() below for details */
      Z_NO_FLUSH:         0,
      Z_PARTIAL_FLUSH:    1,
      Z_SYNC_FLUSH:       2,
      Z_FULL_FLUSH:       3,
      Z_FINISH:           4,
      Z_BLOCK:            5,
      Z_TREES:            6,
    
      /* Return codes for the compression/decompression functions. Negative values
      * are errors, positive values are used for special but normal events.
      */
      Z_OK:               0,
      Z_STREAM_END:       1,
      Z_NEED_DICT:        2,
      Z_ERRNO:           -1,
      Z_STREAM_ERROR:    -2,
      Z_DATA_ERROR:      -3,
      //Z_MEM_ERROR:     -4,
      Z_BUF_ERROR:       -5,
      //Z_VERSION_ERROR: -6,
    
      /* compression levels */
      Z_NO_COMPRESSION:         0,
      Z_BEST_SPEED:             1,
      Z_BEST_COMPRESSION:       9,
      Z_DEFAULT_COMPRESSION:   -1,
    
    
      Z_FILTERED:               1,
      Z_HUFFMAN_ONLY:           2,
      Z_RLE:                    3,
      Z_FIXED:                  4,
      Z_DEFAULT_STRATEGY:       0,
    
      /* Possible values of the data_type field (though see inflate()) */
      Z_BINARY:                 0,
      Z_TEXT:                   1,
      //Z_ASCII:                1, // = Z_TEXT (deprecated)
      Z_UNKNOWN:                2,
    
      /* The deflate compression method */
      Z_DEFLATED:               8
      //Z_NULL:                 null // Use -1 or null inline, depending on var type
    };
    
    },{}],300:[function(require,module,exports){
    'use strict';
    
    // Note: we can't get significant speed boost here.
    // So write code to minimize size - no pregenerated tables
    // and array tools dependencies.
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    // Use ordinary array, since untyped makes no boost here
    function makeTable() {
      var c, table = [];
    
      for (var n = 0; n < 256; n++) {
        c = n;
        for (var k = 0; k < 8; k++) {
          c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
        }
        table[n] = c;
      }
    
      return table;
    }
    
    // Create table on load. Just 255 signed longs. Not a problem.
    var crcTable = makeTable();
    
    
    function crc32(crc, buf, len, pos) {
      var t = crcTable,
          end = pos + len;
    
      crc ^= -1;
    
      for (var i = pos; i < end; i++) {
        crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
      }
    
      return (crc ^ (-1)); // >>> 0;
    }
    
    
    module.exports = crc32;
    
    },{}],301:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    var utils   = require('../utils/common');
    var trees   = require('./trees');
    var adler32 = require('./adler32');
    var crc32   = require('./crc32');
    var msg     = require('./messages');
    
    /* Public constants ==========================================================*/
    /* ===========================================================================*/
    
    
    /* Allowed flush values; see deflate() and inflate() below for details */
    var Z_NO_FLUSH      = 0;
    var Z_PARTIAL_FLUSH = 1;
    //var Z_SYNC_FLUSH    = 2;
    var Z_FULL_FLUSH    = 3;
    var Z_FINISH        = 4;
    var Z_BLOCK         = 5;
    //var Z_TREES         = 6;
    
    
    /* Return codes for the compression/decompression functions. Negative values
     * are errors, positive values are used for special but normal events.
     */
    var Z_OK            = 0;
    var Z_STREAM_END    = 1;
    //var Z_NEED_DICT     = 2;
    //var Z_ERRNO         = -1;
    var Z_STREAM_ERROR  = -2;
    var Z_DATA_ERROR    = -3;
    //var Z_MEM_ERROR     = -4;
    var Z_BUF_ERROR     = -5;
    //var Z_VERSION_ERROR = -6;
    
    
    /* compression levels */
    //var Z_NO_COMPRESSION      = 0;
    //var Z_BEST_SPEED          = 1;
    //var Z_BEST_COMPRESSION    = 9;
    var Z_DEFAULT_COMPRESSION = -1;
    
    
    var Z_FILTERED            = 1;
    var Z_HUFFMAN_ONLY        = 2;
    var Z_RLE                 = 3;
    var Z_FIXED               = 4;
    var Z_DEFAULT_STRATEGY    = 0;
    
    /* Possible values of the data_type field (though see inflate()) */
    //var Z_BINARY              = 0;
    //var Z_TEXT                = 1;
    //var Z_ASCII               = 1; // = Z_TEXT
    var Z_UNKNOWN             = 2;
    
    
    /* The deflate compression method */
    var Z_DEFLATED  = 8;
    
    /*============================================================================*/
    
    
    var MAX_MEM_LEVEL = 9;
    /* Maximum value for memLevel in deflateInit2 */
    var MAX_WBITS = 15;
    /* 32K LZ77 window */
    var DEF_MEM_LEVEL = 8;
    
    
    var LENGTH_CODES  = 29;
    /* number of length codes, not counting the special END_BLOCK code */
    var LITERALS      = 256;
    /* number of literal bytes 0..255 */
    var L_CODES       = LITERALS + 1 + LENGTH_CODES;
    /* number of Literal or Length codes, including the END_BLOCK code */
    var D_CODES       = 30;
    /* number of distance codes */
    var BL_CODES      = 19;
    /* number of codes used to transfer the bit lengths */
    var HEAP_SIZE     = 2 * L_CODES + 1;
    /* maximum heap size */
    var MAX_BITS  = 15;
    /* All codes must not exceed MAX_BITS bits */
    
    var MIN_MATCH = 3;
    var MAX_MATCH = 258;
    var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
    
    var PRESET_DICT = 0x20;
    
    var INIT_STATE = 42;
    var EXTRA_STATE = 69;
    var NAME_STATE = 73;
    var COMMENT_STATE = 91;
    var HCRC_STATE = 103;
    var BUSY_STATE = 113;
    var FINISH_STATE = 666;
    
    var BS_NEED_MORE      = 1; /* block not completed, need more input or more output */
    var BS_BLOCK_DONE     = 2; /* block flush performed */
    var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
    var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */
    
    var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
    
    function err(strm, errorCode) {
      strm.msg = msg[errorCode];
      return errorCode;
    }
    
    function rank(f) {
      return ((f) << 1) - ((f) > 4 ? 9 : 0);
    }
    
    function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
    
    
    /* =========================================================================
     * Flush as much pending output as possible. All deflate() output goes
     * through this function so some applications may wish to modify it
     * to avoid allocating a large strm->output buffer and copying into it.
     * (See also read_buf()).
     */
    function flush_pending(strm) {
      var s = strm.state;
    
      //_tr_flush_bits(s);
      var len = s.pending;
      if (len > strm.avail_out) {
        len = strm.avail_out;
      }
      if (len === 0) { return; }
    
      utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
      strm.next_out += len;
      s.pending_out += len;
      strm.total_out += len;
      strm.avail_out -= len;
      s.pending -= len;
      if (s.pending === 0) {
        s.pending_out = 0;
      }
    }
    
    
    function flush_block_only(s, last) {
      trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
      s.block_start = s.strstart;
      flush_pending(s.strm);
    }
    
    
    function put_byte(s, b) {
      s.pending_buf[s.pending++] = b;
    }
    
    
    /* =========================================================================
     * Put a short in the pending buffer. The 16-bit value is put in MSB order.
     * IN assertion: the stream state is correct and there is enough room in
     * pending_buf.
     */
    function putShortMSB(s, b) {
    //  put_byte(s, (Byte)(b >> 8));
    //  put_byte(s, (Byte)(b & 0xff));
      s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
      s.pending_buf[s.pending++] = b & 0xff;
    }
    
    
    /* ===========================================================================
     * Read a new buffer from the current input stream, update the adler32
     * and total number of bytes read.  All deflate() input goes through
     * this function so some applications may wish to modify it to avoid
     * allocating a large strm->input buffer and copying from it.
     * (See also flush_pending()).
     */
    function read_buf(strm, buf, start, size) {
      var len = strm.avail_in;
    
      if (len > size) { len = size; }
      if (len === 0) { return 0; }
    
      strm.avail_in -= len;
    
      // zmemcpy(buf, strm->next_in, len);
      utils.arraySet(buf, strm.input, strm.next_in, len, start);
      if (strm.state.wrap === 1) {
        strm.adler = adler32(strm.adler, buf, len, start);
      }
    
      else if (strm.state.wrap === 2) {
        strm.adler = crc32(strm.adler, buf, len, start);
      }
    
      strm.next_in += len;
      strm.total_in += len;
    
      return len;
    }
    
    
    /* ===========================================================================
     * Set match_start to the longest match starting at the given string and
     * return its length. Matches shorter or equal to prev_length are discarded,
     * in which case the result is equal to prev_length and match_start is
     * garbage.
     * IN assertions: cur_match is the head of the hash chain for the current
     *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
     * OUT assertion: the match length is not greater than s->lookahead.
     */
    function longest_match(s, cur_match) {
      var chain_length = s.max_chain_length;      /* max hash chain length */
      var scan = s.strstart; /* current string */
      var match;                       /* matched string */
      var len;                           /* length of current match */
      var best_len = s.prev_length;              /* best match length so far */
      var nice_match = s.nice_match;             /* stop if match long enough */
      var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
          s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
    
      var _win = s.window; // shortcut
    
      var wmask = s.w_mask;
      var prev  = s.prev;
    
      /* Stop when cur_match becomes <= limit. To simplify the code,
       * we prevent matches with the string of window index 0.
       */
    
      var strend = s.strstart + MAX_MATCH;
      var scan_end1  = _win[scan + best_len - 1];
      var scan_end   = _win[scan + best_len];
    
      /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
       * It is easy to get rid of this optimization if necessary.
       */
      // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
    
      /* Do not waste too much time if we already have a good match: */
      if (s.prev_length >= s.good_match) {
        chain_length >>= 2;
      }
      /* Do not look for matches beyond the end of the input. This is necessary
       * to make deflate deterministic.
       */
      if (nice_match > s.lookahead) { nice_match = s.lookahead; }
    
      // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
    
      do {
        // Assert(cur_match < s->strstart, "no future");
        match = cur_match;
    
        /* Skip to next match if the match length cannot increase
         * or if the match length is less than 2.  Note that the checks below
         * for insufficient lookahead only occur occasionally for performance
         * reasons.  Therefore uninitialized memory will be accessed, and
         * conditional jumps will be made that depend on those values.
         * However the length of the match is limited to the lookahead, so
         * the output of deflate is not affected by the uninitialized values.
         */
    
        if (_win[match + best_len]     !== scan_end  ||
            _win[match + best_len - 1] !== scan_end1 ||
            _win[match]                !== _win[scan] ||
            _win[++match]              !== _win[scan + 1]) {
          continue;
        }
    
        /* The check at best_len-1 can be removed because it will be made
         * again later. (This heuristic is not always a win.)
         * It is not necessary to compare scan[2] and match[2] since they
         * are always equal when the other bytes match, given that
         * the hash keys are equal and that HASH_BITS >= 8.
         */
        scan += 2;
        match++;
        // Assert(*scan == *match, "match[2]?");
    
        /* We check for insufficient lookahead only every 8th comparison;
         * the 256th check will be made at strstart+258.
         */
        do {
          /*jshint noempty:false*/
        } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
                 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
                 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
                 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
                 scan < strend);
    
        // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
    
        len = MAX_MATCH - (strend - scan);
        scan = strend - MAX_MATCH;
    
        if (len > best_len) {
          s.match_start = cur_match;
          best_len = len;
          if (len >= nice_match) {
            break;
          }
          scan_end1  = _win[scan + best_len - 1];
          scan_end   = _win[scan + best_len];
        }
      } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
    
      if (best_len <= s.lookahead) {
        return best_len;
      }
      return s.lookahead;
    }
    
    
    /* ===========================================================================
     * Fill the window when the lookahead becomes insufficient.
     * Updates strstart and lookahead.
     *
     * IN assertion: lookahead < MIN_LOOKAHEAD
     * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
     *    At least one byte has been read, or avail_in == 0; reads are
     *    performed for at least two bytes (required for the zip translate_eol
     *    option -- not supported here).
     */
    function fill_window(s) {
      var _w_size = s.w_size;
      var p, n, m, more, str;
    
      //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
    
      do {
        more = s.window_size - s.lookahead - s.strstart;
    
        // JS ints have 32 bit, block below not needed
        /* Deal with !@#$% 64K limit: */
        //if (sizeof(int) <= 2) {
        //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
        //        more = wsize;
        //
        //  } else if (more == (unsigned)(-1)) {
        //        /* Very unlikely, but possible on 16 bit machine if
        //         * strstart == 0 && lookahead == 1 (input done a byte at time)
        //         */
        //        more--;
        //    }
        //}
    
    
        /* If the window is almost full and there is insufficient lookahead,
         * move the upper half to the lower one to make room in the upper half.
         */
        if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
    
          utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
          s.match_start -= _w_size;
          s.strstart -= _w_size;
          /* we now have strstart >= MAX_DIST */
          s.block_start -= _w_size;
    
          /* Slide the hash table (could be avoided with 32 bit values
           at the expense of memory usage). We slide even when level == 0
           to keep the hash table consistent if we switch back to level > 0
           later. (Using level 0 permanently is not an optimal usage of
           zlib, so we don't care about this pathological case.)
           */
    
          n = s.hash_size;
          p = n;
          do {
            m = s.head[--p];
            s.head[p] = (m >= _w_size ? m - _w_size : 0);
          } while (--n);
    
          n = _w_size;
          p = n;
          do {
            m = s.prev[--p];
            s.prev[p] = (m >= _w_size ? m - _w_size : 0);
            /* If n is not on any hash chain, prev[n] is garbage but
             * its value will never be used.
             */
          } while (--n);
    
          more += _w_size;
        }
        if (s.strm.avail_in === 0) {
          break;
        }
    
        /* If there was no sliding:
         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
         *    more == window_size - lookahead - strstart
         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
         * => more >= window_size - 2*WSIZE + 2
         * In the BIG_MEM or MMAP case (not yet supported),
         *   window_size == input_size + MIN_LOOKAHEAD  &&
         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
         * Otherwise, window_size == 2*WSIZE so more >= 2.
         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
         */
        //Assert(more >= 2, "more < 2");
        n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
        s.lookahead += n;
    
        /* Initialize the hash value now that we have some input: */
        if (s.lookahead + s.insert >= MIN_MATCH) {
          str = s.strstart - s.insert;
          s.ins_h = s.window[str];
    
          /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
    //#if MIN_MATCH != 3
    //        Call update_hash() MIN_MATCH-3 more times
    //#endif
          while (s.insert) {
            /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
            s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
    
            s.prev[str & s.w_mask] = s.head[s.ins_h];
            s.head[s.ins_h] = str;
            str++;
            s.insert--;
            if (s.lookahead + s.insert < MIN_MATCH) {
              break;
            }
          }
        }
        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
         * but this is not important since only literal bytes will be emitted.
         */
    
      } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
    
      /* If the WIN_INIT bytes after the end of the current data have never been
       * written, then zero those bytes in order to avoid memory check reports of
       * the use of uninitialized (or uninitialised as Julian writes) bytes by
       * the longest match routines.  Update the high water mark for the next
       * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
       * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
       */
    //  if (s.high_water < s.window_size) {
    //    var curr = s.strstart + s.lookahead;
    //    var init = 0;
    //
    //    if (s.high_water < curr) {
    //      /* Previous high water mark below current data -- zero WIN_INIT
    //       * bytes or up to end of window, whichever is less.
    //       */
    //      init = s.window_size - curr;
    //      if (init > WIN_INIT)
    //        init = WIN_INIT;
    //      zmemzero(s->window + curr, (unsigned)init);
    //      s->high_water = curr + init;
    //    }
    //    else if (s->high_water < (ulg)curr + WIN_INIT) {
    //      /* High water mark at or above current data, but below current data
    //       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
    //       * to end of window, whichever is less.
    //       */
    //      init = (ulg)curr + WIN_INIT - s->high_water;
    //      if (init > s->window_size - s->high_water)
    //        init = s->window_size - s->high_water;
    //      zmemzero(s->window + s->high_water, (unsigned)init);
    //      s->high_water += init;
    //    }
    //  }
    //
    //  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
    //    "not enough room for search");
    }
    
    /* ===========================================================================
     * Copy without compression as much as possible from the input stream, return
     * the current block state.
     * This function does not insert new strings in the dictionary since
     * uncompressible data is probably not useful. This function is used
     * only for the level=0 compression option.
     * NOTE: this function should be optimized to avoid extra copying from
     * window to pending_buf.
     */
    function deflate_stored(s, flush) {
      /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
       * to pending_buf_size, and each stored block has a 5 byte header:
       */
      var max_block_size = 0xffff;
    
      if (max_block_size > s.pending_buf_size - 5) {
        max_block_size = s.pending_buf_size - 5;
      }
    
      /* Copy as much as possible from input to output: */
      for (;;) {
        /* Fill the window as much as possible: */
        if (s.lookahead <= 1) {
    
          //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
          //  s->block_start >= (long)s->w_size, "slide too late");
    //      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
    //        s.block_start >= s.w_size)) {
    //        throw  new Error("slide too late");
    //      }
    
          fill_window(s);
          if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
            return BS_NEED_MORE;
          }
    
          if (s.lookahead === 0) {
            break;
          }
          /* flush the current block */
        }
        //Assert(s->block_start >= 0L, "block gone");
    //    if (s.block_start < 0) throw new Error("block gone");
    
        s.strstart += s.lookahead;
        s.lookahead = 0;
    
        /* Emit a stored block if pending_buf will be full: */
        var max_start = s.block_start + max_block_size;
    
        if (s.strstart === 0 || s.strstart >= max_start) {
          /* strstart == 0 is possible when wraparound on 16-bit machine */
          s.lookahead = s.strstart - max_start;
          s.strstart = max_start;
          /*** FLUSH_BLOCK(s, 0); ***/
          flush_block_only(s, false);
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
          /***/
    
    
        }
        /* Flush if we may have to slide, otherwise block_start may become
         * negative and the data will be gone:
         */
        if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
          /*** FLUSH_BLOCK(s, 0); ***/
          flush_block_only(s, false);
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
          /***/
        }
      }
    
      s.insert = 0;
    
      if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/
        flush_block_only(s, true);
        if (s.strm.avail_out === 0) {
          return BS_FINISH_STARTED;
        }
        /***/
        return BS_FINISH_DONE;
      }
    
      if (s.strstart > s.block_start) {
        /*** FLUSH_BLOCK(s, 0); ***/
        flush_block_only(s, false);
        if (s.strm.avail_out === 0) {
          return BS_NEED_MORE;
        }
        /***/
      }
    
      return BS_NEED_MORE;
    }
    
    /* ===========================================================================
     * Compress as much as possible from the input stream, return the current
     * block state.
     * This function does not perform lazy evaluation of matches and inserts
     * new strings in the dictionary only for unmatched strings or for short
     * matches. It is used only for the fast compression options.
     */
    function deflate_fast(s, flush) {
      var hash_head;        /* head of the hash chain */
      var bflush;           /* set if current block must be flushed */
    
      for (;;) {
        /* Make sure that we always have enough lookahead, except
         * at the end of the input file. We need MAX_MATCH bytes
         * for the next match, plus MIN_MATCH bytes to insert the
         * string following the next match.
         */
        if (s.lookahead < MIN_LOOKAHEAD) {
          fill_window(s);
          if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
            return BS_NEED_MORE;
          }
          if (s.lookahead === 0) {
            break; /* flush the current block */
          }
        }
    
        /* Insert the string window[strstart .. strstart+2] in the
         * dictionary, and set hash_head to the head of the hash chain:
         */
        hash_head = 0/*NIL*/;
        if (s.lookahead >= MIN_MATCH) {
          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
          s.head[s.ins_h] = s.strstart;
          /***/
        }
    
        /* Find the longest match, discarding those <= prev_length.
         * At this point we have always match_length < MIN_MATCH
         */
        if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
          /* To simplify the code, we prevent matches with the string
           * of window index 0 (in particular we have to avoid a match
           * of the string with itself at the start of the input file).
           */
          s.match_length = longest_match(s, hash_head);
          /* longest_match() sets match_start */
        }
        if (s.match_length >= MIN_MATCH) {
          // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
    
          /*** _tr_tally_dist(s, s.strstart - s.match_start,
                         s.match_length - MIN_MATCH, bflush); ***/
          bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
    
          s.lookahead -= s.match_length;
    
          /* Insert new strings in the hash table only if the match length
           * is not too large. This saves time but degrades compression.
           */
          if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
            s.match_length--; /* string at strstart already in table */
            do {
              s.strstart++;
              /*** INSERT_STRING(s, s.strstart, hash_head); ***/
              s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
              hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
              s.head[s.ins_h] = s.strstart;
              /***/
              /* strstart never exceeds WSIZE-MAX_MATCH, so there are
               * always MIN_MATCH bytes ahead.
               */
            } while (--s.match_length !== 0);
            s.strstart++;
          } else
          {
            s.strstart += s.match_length;
            s.match_length = 0;
            s.ins_h = s.window[s.strstart];
            /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
            s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
    
    //#if MIN_MATCH != 3
    //                Call UPDATE_HASH() MIN_MATCH-3 more times
    //#endif
            /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
             * matter since it will be recomputed at next deflate call.
             */
          }
        } else {
          /* No match, output a literal byte */
          //Tracevv((stderr,"%c", s.window[s.strstart]));
          /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
          bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
    
          s.lookahead--;
          s.strstart++;
        }
        if (bflush) {
          /*** FLUSH_BLOCK(s, 0); ***/
          flush_block_only(s, false);
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
          /***/
        }
      }
      s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
      if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/
        flush_block_only(s, true);
        if (s.strm.avail_out === 0) {
          return BS_FINISH_STARTED;
        }
        /***/
        return BS_FINISH_DONE;
      }
      if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/
        flush_block_only(s, false);
        if (s.strm.avail_out === 0) {
          return BS_NEED_MORE;
        }
        /***/
      }
      return BS_BLOCK_DONE;
    }
    
    /* ===========================================================================
     * Same as above, but achieves better compression. We use a lazy
     * evaluation for matches: a match is finally adopted only if there is
     * no better match at the next window position.
     */
    function deflate_slow(s, flush) {
      var hash_head;          /* head of hash chain */
      var bflush;              /* set if current block must be flushed */
    
      var max_insert;
    
      /* Process the input block. */
      for (;;) {
        /* Make sure that we always have enough lookahead, except
         * at the end of the input file. We need MAX_MATCH bytes
         * for the next match, plus MIN_MATCH bytes to insert the
         * string following the next match.
         */
        if (s.lookahead < MIN_LOOKAHEAD) {
          fill_window(s);
          if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
            return BS_NEED_MORE;
          }
          if (s.lookahead === 0) { break; } /* flush the current block */
        }
    
        /* Insert the string window[strstart .. strstart+2] in the
         * dictionary, and set hash_head to the head of the hash chain:
         */
        hash_head = 0/*NIL*/;
        if (s.lookahead >= MIN_MATCH) {
          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
          s.head[s.ins_h] = s.strstart;
          /***/
        }
    
        /* Find the longest match, discarding those <= prev_length.
         */
        s.prev_length = s.match_length;
        s.prev_match = s.match_start;
        s.match_length = MIN_MATCH - 1;
    
        if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
            s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
          /* To simplify the code, we prevent matches with the string
           * of window index 0 (in particular we have to avoid a match
           * of the string with itself at the start of the input file).
           */
          s.match_length = longest_match(s, hash_head);
          /* longest_match() sets match_start */
    
          if (s.match_length <= 5 &&
             (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
    
            /* If prev_match is also MIN_MATCH, match_start is garbage
             * but we will ignore the current match anyway.
             */
            s.match_length = MIN_MATCH - 1;
          }
        }
        /* If there was a match at the previous step and the current
         * match is not better, output the previous match:
         */
        if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
          max_insert = s.strstart + s.lookahead - MIN_MATCH;
          /* Do not insert strings in hash table beyond this. */
    
          //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
    
          /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
                         s.prev_length - MIN_MATCH, bflush);***/
          bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
          /* Insert in hash table all strings up to the end of the match.
           * strstart-1 and strstart are already inserted. If there is not
           * enough lookahead, the last two strings are not inserted in
           * the hash table.
           */
          s.lookahead -= s.prev_length - 1;
          s.prev_length -= 2;
          do {
            if (++s.strstart <= max_insert) {
              /*** INSERT_STRING(s, s.strstart, hash_head); ***/
              s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
              hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
              s.head[s.ins_h] = s.strstart;
              /***/
            }
          } while (--s.prev_length !== 0);
          s.match_available = 0;
          s.match_length = MIN_MATCH - 1;
          s.strstart++;
    
          if (bflush) {
            /*** FLUSH_BLOCK(s, 0); ***/
            flush_block_only(s, false);
            if (s.strm.avail_out === 0) {
              return BS_NEED_MORE;
            }
            /***/
          }
    
        } else if (s.match_available) {
          /* If there was no match at the previous position, output a
           * single literal. If there was a match but the current match
           * is longer, truncate the previous match to a single literal.
           */
          //Tracevv((stderr,"%c", s->window[s->strstart-1]));
          /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
          bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
    
          if (bflush) {
            /*** FLUSH_BLOCK_ONLY(s, 0) ***/
            flush_block_only(s, false);
            /***/
          }
          s.strstart++;
          s.lookahead--;
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
        } else {
          /* There is no previous match to compare with, wait for
           * the next step to decide.
           */
          s.match_available = 1;
          s.strstart++;
          s.lookahead--;
        }
      }
      //Assert (flush != Z_NO_FLUSH, "no flush?");
      if (s.match_available) {
        //Tracevv((stderr,"%c", s->window[s->strstart-1]));
        /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
        bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
    
        s.match_available = 0;
      }
      s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
      if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/
        flush_block_only(s, true);
        if (s.strm.avail_out === 0) {
          return BS_FINISH_STARTED;
        }
        /***/
        return BS_FINISH_DONE;
      }
      if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/
        flush_block_only(s, false);
        if (s.strm.avail_out === 0) {
          return BS_NEED_MORE;
        }
        /***/
      }
    
      return BS_BLOCK_DONE;
    }
    
    
    /* ===========================================================================
     * For Z_RLE, simply look for runs of bytes, generate matches only of distance
     * one.  Do not maintain a hash table.  (It will be regenerated if this run of
     * deflate switches away from Z_RLE.)
     */
    function deflate_rle(s, flush) {
      var bflush;            /* set if current block must be flushed */
      var prev;              /* byte at distance one to match */
      var scan, strend;      /* scan goes up to strend for length of run */
    
      var _win = s.window;
    
      for (;;) {
        /* Make sure that we always have enough lookahead, except
         * at the end of the input file. We need MAX_MATCH bytes
         * for the longest run, plus one for the unrolled loop.
         */
        if (s.lookahead <= MAX_MATCH) {
          fill_window(s);
          if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
            return BS_NEED_MORE;
          }
          if (s.lookahead === 0) { break; } /* flush the current block */
        }
    
        /* See how many times the previous byte repeats */
        s.match_length = 0;
        if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
          scan = s.strstart - 1;
          prev = _win[scan];
          if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
            strend = s.strstart + MAX_MATCH;
            do {
              /*jshint noempty:false*/
            } while (prev === _win[++scan] && prev === _win[++scan] &&
                     prev === _win[++scan] && prev === _win[++scan] &&
                     prev === _win[++scan] && prev === _win[++scan] &&
                     prev === _win[++scan] && prev === _win[++scan] &&
                     scan < strend);
            s.match_length = MAX_MATCH - (strend - scan);
            if (s.match_length > s.lookahead) {
              s.match_length = s.lookahead;
            }
          }
          //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
        }
    
        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
        if (s.match_length >= MIN_MATCH) {
          //check_match(s, s.strstart, s.strstart - 1, s.match_length);
    
          /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
          bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
    
          s.lookahead -= s.match_length;
          s.strstart += s.match_length;
          s.match_length = 0;
        } else {
          /* No match, output a literal byte */
          //Tracevv((stderr,"%c", s->window[s->strstart]));
          /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
          bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
    
          s.lookahead--;
          s.strstart++;
        }
        if (bflush) {
          /*** FLUSH_BLOCK(s, 0); ***/
          flush_block_only(s, false);
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
          /***/
        }
      }
      s.insert = 0;
      if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/
        flush_block_only(s, true);
        if (s.strm.avail_out === 0) {
          return BS_FINISH_STARTED;
        }
        /***/
        return BS_FINISH_DONE;
      }
      if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/
        flush_block_only(s, false);
        if (s.strm.avail_out === 0) {
          return BS_NEED_MORE;
        }
        /***/
      }
      return BS_BLOCK_DONE;
    }
    
    /* ===========================================================================
     * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
     * (It will be regenerated if this run of deflate switches away from Huffman.)
     */
    function deflate_huff(s, flush) {
      var bflush;             /* set if current block must be flushed */
    
      for (;;) {
        /* Make sure that we have a literal to write. */
        if (s.lookahead === 0) {
          fill_window(s);
          if (s.lookahead === 0) {
            if (flush === Z_NO_FLUSH) {
              return BS_NEED_MORE;
            }
            break;      /* flush the current block */
          }
        }
    
        /* Output a literal byte */
        s.match_length = 0;
        //Tracevv((stderr,"%c", s->window[s->strstart]));
        /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
        bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
        s.lookahead--;
        s.strstart++;
        if (bflush) {
          /*** FLUSH_BLOCK(s, 0); ***/
          flush_block_only(s, false);
          if (s.strm.avail_out === 0) {
            return BS_NEED_MORE;
          }
          /***/
        }
      }
      s.insert = 0;
      if (flush === Z_FINISH) {
        /*** FLUSH_BLOCK(s, 1); ***/
        flush_block_only(s, true);
        if (s.strm.avail_out === 0) {
          return BS_FINISH_STARTED;
        }
        /***/
        return BS_FINISH_DONE;
      }
      if (s.last_lit) {
        /*** FLUSH_BLOCK(s, 0); ***/
        flush_block_only(s, false);
        if (s.strm.avail_out === 0) {
          return BS_NEED_MORE;
        }
        /***/
      }
      return BS_BLOCK_DONE;
    }
    
    /* Values for max_lazy_match, good_match and max_chain_length, depending on
     * the desired pack level (0..9). The values given below have been tuned to
     * exclude worst case performance for pathological files. Better values may be
     * found for specific files.
     */
    function Config(good_length, max_lazy, nice_length, max_chain, func) {
      this.good_length = good_length;
      this.max_lazy = max_lazy;
      this.nice_length = nice_length;
      this.max_chain = max_chain;
      this.func = func;
    }
    
    var configuration_table;
    
    configuration_table = [
      /*      good lazy nice chain */
      new Config(0, 0, 0, 0, deflate_stored),          /* 0 store only */
      new Config(4, 4, 8, 4, deflate_fast),            /* 1 max speed, no lazy matches */
      new Config(4, 5, 16, 8, deflate_fast),           /* 2 */
      new Config(4, 6, 32, 32, deflate_fast),          /* 3 */
    
      new Config(4, 4, 16, 16, deflate_slow),          /* 4 lazy matches */
      new Config(8, 16, 32, 32, deflate_slow),         /* 5 */
      new Config(8, 16, 128, 128, deflate_slow),       /* 6 */
      new Config(8, 32, 128, 256, deflate_slow),       /* 7 */
      new Config(32, 128, 258, 1024, deflate_slow),    /* 8 */
      new Config(32, 258, 258, 4096, deflate_slow)     /* 9 max compression */
    ];
    
    
    /* ===========================================================================
     * Initialize the "longest match" routines for a new zlib stream
     */
    function lm_init(s) {
      s.window_size = 2 * s.w_size;
    
      /*** CLEAR_HASH(s); ***/
      zero(s.head); // Fill with NIL (= 0);
    
      /* Set the default configuration parameters:
       */
      s.max_lazy_match = configuration_table[s.level].max_lazy;
      s.good_match = configuration_table[s.level].good_length;
      s.nice_match = configuration_table[s.level].nice_length;
      s.max_chain_length = configuration_table[s.level].max_chain;
    
      s.strstart = 0;
      s.block_start = 0;
      s.lookahead = 0;
      s.insert = 0;
      s.match_length = s.prev_length = MIN_MATCH - 1;
      s.match_available = 0;
      s.ins_h = 0;
    }
    
    
    function DeflateState() {
      this.strm = null;            /* pointer back to this zlib stream */
      this.status = 0;            /* as the name implies */
      this.pending_buf = null;      /* output still pending */
      this.pending_buf_size = 0;  /* size of pending_buf */
      this.pending_out = 0;       /* next pending byte to output to the stream */
      this.pending = 0;           /* nb of bytes in the pending buffer */
      this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
      this.gzhead = null;         /* gzip header information to write */
      this.gzindex = 0;           /* where in extra, name, or comment */
      this.method = Z_DEFLATED; /* can only be DEFLATED */
      this.last_flush = -1;   /* value of flush param for previous deflate call */
    
      this.w_size = 0;  /* LZ77 window size (32K by default) */
      this.w_bits = 0;  /* log2(w_size)  (8..16) */
      this.w_mask = 0;  /* w_size - 1 */
    
      this.window = null;
      /* Sliding window. Input bytes are read into the second half of the window,
       * and move to the first half later to keep a dictionary of at least wSize
       * bytes. With this organization, matches are limited to a distance of
       * wSize-MAX_MATCH bytes, but this ensures that IO is always
       * performed with a length multiple of the block size.
       */
    
      this.window_size = 0;
      /* Actual size of window: 2*wSize, except when the user input buffer
       * is directly used as sliding window.
       */
    
      this.prev = null;
      /* Link to older string with same hash index. To limit the size of this
       * array to 64K, this link is maintained only for the last 32K strings.
       * An index in this array is thus a window index modulo 32K.
       */
    
      this.head = null;   /* Heads of the hash chains or NIL. */
    
      this.ins_h = 0;       /* hash index of string to be inserted */
      this.hash_size = 0;   /* number of elements in hash table */
      this.hash_bits = 0;   /* log2(hash_size) */
      this.hash_mask = 0;   /* hash_size-1 */
    
      this.hash_shift = 0;
      /* Number of bits by which ins_h must be shifted at each input
       * step. It must be such that after MIN_MATCH steps, the oldest
       * byte no longer takes part in the hash key, that is:
       *   hash_shift * MIN_MATCH >= hash_bits
       */
    
      this.block_start = 0;
      /* Window position at the beginning of the current output block. Gets
       * negative when the window is moved backwards.
       */
    
      this.match_length = 0;      /* length of best match */
      this.prev_match = 0;        /* previous match */
      this.match_available = 0;   /* set if previous match exists */
      this.strstart = 0;          /* start of string to insert */
      this.match_start = 0;       /* start of matching string */
      this.lookahead = 0;         /* number of valid bytes ahead in window */
    
      this.prev_length = 0;
      /* Length of the best match at previous step. Matches not greater than this
       * are discarded. This is used in the lazy match evaluation.
       */
    
      this.max_chain_length = 0;
      /* To speed up deflation, hash chains are never searched beyond this
       * length.  A higher limit improves compression ratio but degrades the
       * speed.
       */
    
      this.max_lazy_match = 0;
      /* Attempt to find a better match only when the current match is strictly
       * smaller than this value. This mechanism is used only for compression
       * levels >= 4.
       */
      // That's alias to max_lazy_match, don't use directly
      //this.max_insert_length = 0;
      /* Insert new strings in the hash table only if the match length is not
       * greater than this length. This saves time but degrades compression.
       * max_insert_length is used only for compression levels <= 3.
       */
    
      this.level = 0;     /* compression level (1..9) */
      this.strategy = 0;  /* favor or force Huffman coding*/
    
      this.good_match = 0;
      /* Use a faster search when the previous match is longer than this */
    
      this.nice_match = 0; /* Stop searching when current match exceeds this */
    
                  /* used by trees.c: */
    
      /* Didn't use ct_data typedef below to suppress compiler warning */
    
      // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
      // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
      // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
    
      // Use flat array of DOUBLE size, with interleaved fata,
      // because JS does not support effective
      this.dyn_ltree  = new utils.Buf16(HEAP_SIZE * 2);
      this.dyn_dtree  = new utils.Buf16((2 * D_CODES + 1) * 2);
      this.bl_tree    = new utils.Buf16((2 * BL_CODES + 1) * 2);
      zero(this.dyn_ltree);
      zero(this.dyn_dtree);
      zero(this.bl_tree);
    
      this.l_desc   = null;         /* desc. for literal tree */
      this.d_desc   = null;         /* desc. for distance tree */
      this.bl_desc  = null;         /* desc. for bit length tree */
    
      //ush bl_count[MAX_BITS+1];
      this.bl_count = new utils.Buf16(MAX_BITS + 1);
      /* number of codes at each bit length for an optimal tree */
    
      //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
      this.heap = new utils.Buf16(2 * L_CODES + 1);  /* heap used to build the Huffman trees */
      zero(this.heap);
    
      this.heap_len = 0;               /* number of elements in the heap */
      this.heap_max = 0;               /* element of largest frequency */
      /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
       * The same heap array is used to build all trees.
       */
    
      this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
      zero(this.depth);
      /* Depth of each subtree used as tie breaker for trees of equal frequency
       */
    
      this.l_buf = 0;          /* buffer index for literals or lengths */
    
      this.lit_bufsize = 0;
      /* Size of match buffer for literals/lengths.  There are 4 reasons for
       * limiting lit_bufsize to 64K:
       *   - frequencies can be kept in 16 bit counters
       *   - if compression is not successful for the first block, all input
       *     data is still in the window so we can still emit a stored block even
       *     when input comes from standard input.  (This can also be done for
       *     all blocks if lit_bufsize is not greater than 32K.)
       *   - if compression is not successful for a file smaller than 64K, we can
       *     even emit a stored file instead of a stored block (saving 5 bytes).
       *     This is applicable only for zip (not gzip or zlib).
       *   - creating new Huffman trees less frequently may not provide fast
       *     adaptation to changes in the input data statistics. (Take for
       *     example a binary file with poorly compressible code followed by
       *     a highly compressible string table.) Smaller buffer sizes give
       *     fast adaptation but have of course the overhead of transmitting
       *     trees more frequently.
       *   - I can't count above 4
       */
    
      this.last_lit = 0;      /* running index in l_buf */
    
      this.d_buf = 0;
      /* Buffer index for distances. To simplify the code, d_buf and l_buf have
       * the same number of elements. To use different lengths, an extra flag
       * array would be necessary.
       */
    
      this.opt_len = 0;       /* bit length of current block with optimal trees */
      this.static_len = 0;    /* bit length of current block with static trees */
      this.matches = 0;       /* number of string matches in current block */
      this.insert = 0;        /* bytes at end of window left to insert */
    
    
      this.bi_buf = 0;
      /* Output buffer. bits are inserted starting at the bottom (least
       * significant bits).
       */
      this.bi_valid = 0;
      /* Number of valid bits in bi_buf.  All bits above the last valid bit
       * are always zero.
       */
    
      // Used for window memory init. We safely ignore it for JS. That makes
      // sense only for pointers and memory check tools.
      //this.high_water = 0;
      /* High water mark offset in window for initialized bytes -- bytes above
       * this are set to zero in order to avoid memory check warnings when
       * longest match routines access bytes past the input.  This is then
       * updated to the new high water mark.
       */
    }
    
    
    function deflateResetKeep(strm) {
      var s;
    
      if (!strm || !strm.state) {
        return err(strm, Z_STREAM_ERROR);
      }
    
      strm.total_in = strm.total_out = 0;
      strm.data_type = Z_UNKNOWN;
    
      s = strm.state;
      s.pending = 0;
      s.pending_out = 0;
    
      if (s.wrap < 0) {
        s.wrap = -s.wrap;
        /* was made negative by deflate(..., Z_FINISH); */
      }
      s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
      strm.adler = (s.wrap === 2) ?
        0  // crc32(0, Z_NULL, 0)
      :
        1; // adler32(0, Z_NULL, 0)
      s.last_flush = Z_NO_FLUSH;
      trees._tr_init(s);
      return Z_OK;
    }
    
    
    function deflateReset(strm) {
      var ret = deflateResetKeep(strm);
      if (ret === Z_OK) {
        lm_init(strm.state);
      }
      return ret;
    }
    
    
    function deflateSetHeader(strm, head) {
      if (!strm || !strm.state) { return Z_STREAM_ERROR; }
      if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
      strm.state.gzhead = head;
      return Z_OK;
    }
    
    
    function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
      if (!strm) { // === Z_NULL
        return Z_STREAM_ERROR;
      }
      var wrap = 1;
    
      if (level === Z_DEFAULT_COMPRESSION) {
        level = 6;
      }
    
      if (windowBits < 0) { /* suppress zlib wrapper */
        wrap = 0;
        windowBits = -windowBits;
      }
    
      else if (windowBits > 15) {
        wrap = 2;           /* write gzip wrapper instead */
        windowBits -= 16;
      }
    
    
      if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
        strategy < 0 || strategy > Z_FIXED) {
        return err(strm, Z_STREAM_ERROR);
      }
    
    
      if (windowBits === 8) {
        windowBits = 9;
      }
      /* until 256-byte window bug fixed */
    
      var s = new DeflateState();
    
      strm.state = s;
      s.strm = strm;
    
      s.wrap = wrap;
      s.gzhead = null;
      s.w_bits = windowBits;
      s.w_size = 1 << s.w_bits;
      s.w_mask = s.w_size - 1;
    
      s.hash_bits = memLevel + 7;
      s.hash_size = 1 << s.hash_bits;
      s.hash_mask = s.hash_size - 1;
      s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
    
      s.window = new utils.Buf8(s.w_size * 2);
      s.head = new utils.Buf16(s.hash_size);
      s.prev = new utils.Buf16(s.w_size);
    
      // Don't need mem init magic for JS.
      //s.high_water = 0;  /* nothing written to s->window yet */
    
      s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
    
      s.pending_buf_size = s.lit_bufsize * 4;
    
      //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
      //s->pending_buf = (uchf *) overlay;
      s.pending_buf = new utils.Buf8(s.pending_buf_size);
    
      // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
      //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
      s.d_buf = 1 * s.lit_bufsize;
    
      //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
      s.l_buf = (1 + 2) * s.lit_bufsize;
    
      s.level = level;
      s.strategy = strategy;
      s.method = method;
    
      return deflateReset(strm);
    }
    
    function deflateInit(strm, level) {
      return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
    }
    
    
    function deflate(strm, flush) {
      var old_flush, s;
      var beg, val; // for gzip header write only
    
      if (!strm || !strm.state ||
        flush > Z_BLOCK || flush < 0) {
        return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
      }
    
      s = strm.state;
    
      if (!strm.output ||
          (!strm.input && strm.avail_in !== 0) ||
          (s.status === FINISH_STATE && flush !== Z_FINISH)) {
        return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
      }
    
      s.strm = strm; /* just in case */
      old_flush = s.last_flush;
      s.last_flush = flush;
    
      /* Write the header */
      if (s.status === INIT_STATE) {
    
        if (s.wrap === 2) { // GZIP header
          strm.adler = 0;  //crc32(0L, Z_NULL, 0);
          put_byte(s, 31);
          put_byte(s, 139);
          put_byte(s, 8);
          if (!s.gzhead) { // s->gzhead == Z_NULL
            put_byte(s, 0);
            put_byte(s, 0);
            put_byte(s, 0);
            put_byte(s, 0);
            put_byte(s, 0);
            put_byte(s, s.level === 9 ? 2 :
                        (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
                         4 : 0));
            put_byte(s, OS_CODE);
            s.status = BUSY_STATE;
          }
          else {
            put_byte(s, (s.gzhead.text ? 1 : 0) +
                        (s.gzhead.hcrc ? 2 : 0) +
                        (!s.gzhead.extra ? 0 : 4) +
                        (!s.gzhead.name ? 0 : 8) +
                        (!s.gzhead.comment ? 0 : 16)
            );
            put_byte(s, s.gzhead.time & 0xff);
            put_byte(s, (s.gzhead.time >> 8) & 0xff);
            put_byte(s, (s.gzhead.time >> 16) & 0xff);
            put_byte(s, (s.gzhead.time >> 24) & 0xff);
            put_byte(s, s.level === 9 ? 2 :
                        (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
                         4 : 0));
            put_byte(s, s.gzhead.os & 0xff);
            if (s.gzhead.extra && s.gzhead.extra.length) {
              put_byte(s, s.gzhead.extra.length & 0xff);
              put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
            }
            if (s.gzhead.hcrc) {
              strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
            }
            s.gzindex = 0;
            s.status = EXTRA_STATE;
          }
        }
        else // DEFLATE header
        {
          var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
          var level_flags = -1;
    
          if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
            level_flags = 0;
          } else if (s.level < 6) {
            level_flags = 1;
          } else if (s.level === 6) {
            level_flags = 2;
          } else {
            level_flags = 3;
          }
          header |= (level_flags << 6);
          if (s.strstart !== 0) { header |= PRESET_DICT; }
          header += 31 - (header % 31);
    
          s.status = BUSY_STATE;
          putShortMSB(s, header);
    
          /* Save the adler32 of the preset dictionary: */
          if (s.strstart !== 0) {
            putShortMSB(s, strm.adler >>> 16);
            putShortMSB(s, strm.adler & 0xffff);
          }
          strm.adler = 1; // adler32(0L, Z_NULL, 0);
        }
      }
    
    //#ifdef GZIP
      if (s.status === EXTRA_STATE) {
        if (s.gzhead.extra/* != Z_NULL*/) {
          beg = s.pending;  /* start of bytes to update crc */
    
          while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
            if (s.pending === s.pending_buf_size) {
              if (s.gzhead.hcrc && s.pending > beg) {
                strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
              }
              flush_pending(strm);
              beg = s.pending;
              if (s.pending === s.pending_buf_size) {
                break;
              }
            }
            put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
            s.gzindex++;
          }
          if (s.gzhead.hcrc && s.pending > beg) {
            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
          }
          if (s.gzindex === s.gzhead.extra.length) {
            s.gzindex = 0;
            s.status = NAME_STATE;
          }
        }
        else {
          s.status = NAME_STATE;
        }
      }
      if (s.status === NAME_STATE) {
        if (s.gzhead.name/* != Z_NULL*/) {
          beg = s.pending;  /* start of bytes to update crc */
          //int val;
    
          do {
            if (s.pending === s.pending_buf_size) {
              if (s.gzhead.hcrc && s.pending > beg) {
                strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
              }
              flush_pending(strm);
              beg = s.pending;
              if (s.pending === s.pending_buf_size) {
                val = 1;
                break;
              }
            }
            // JS specific: little magic to add zero terminator to end of string
            if (s.gzindex < s.gzhead.name.length) {
              val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
            } else {
              val = 0;
            }
            put_byte(s, val);
          } while (val !== 0);
    
          if (s.gzhead.hcrc && s.pending > beg) {
            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
          }
          if (val === 0) {
            s.gzindex = 0;
            s.status = COMMENT_STATE;
          }
        }
        else {
          s.status = COMMENT_STATE;
        }
      }
      if (s.status === COMMENT_STATE) {
        if (s.gzhead.comment/* != Z_NULL*/) {
          beg = s.pending;  /* start of bytes to update crc */
          //int val;
    
          do {
            if (s.pending === s.pending_buf_size) {
              if (s.gzhead.hcrc && s.pending > beg) {
                strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
              }
              flush_pending(strm);
              beg = s.pending;
              if (s.pending === s.pending_buf_size) {
                val = 1;
                break;
              }
            }
            // JS specific: little magic to add zero terminator to end of string
            if (s.gzindex < s.gzhead.comment.length) {
              val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
            } else {
              val = 0;
            }
            put_byte(s, val);
          } while (val !== 0);
    
          if (s.gzhead.hcrc && s.pending > beg) {
            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
          }
          if (val === 0) {
            s.status = HCRC_STATE;
          }
        }
        else {
          s.status = HCRC_STATE;
        }
      }
      if (s.status === HCRC_STATE) {
        if (s.gzhead.hcrc) {
          if (s.pending + 2 > s.pending_buf_size) {
            flush_pending(strm);
          }
          if (s.pending + 2 <= s.pending_buf_size) {
            put_byte(s, strm.adler & 0xff);
            put_byte(s, (strm.adler >> 8) & 0xff);
            strm.adler = 0; //crc32(0L, Z_NULL, 0);
            s.status = BUSY_STATE;
          }
        }
        else {
          s.status = BUSY_STATE;
        }
      }
    //#endif
    
      /* Flush as much pending output as possible */
      if (s.pending !== 0) {
        flush_pending(strm);
        if (strm.avail_out === 0) {
          /* Since avail_out is 0, deflate will be called again with
           * more output space, but possibly with both pending and
           * avail_in equal to zero. There won't be anything to do,
           * but this is not an error situation so make sure we
           * return OK instead of BUF_ERROR at next call of deflate:
           */
          s.last_flush = -1;
          return Z_OK;
        }
    
        /* Make sure there is something to do and avoid duplicate consecutive
         * flushes. For repeated and useless calls with Z_FINISH, we keep
         * returning Z_STREAM_END instead of Z_BUF_ERROR.
         */
      } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
        flush !== Z_FINISH) {
        return err(strm, Z_BUF_ERROR);
      }
    
      /* User must not provide more input after the first FINISH: */
      if (s.status === FINISH_STATE && strm.avail_in !== 0) {
        return err(strm, Z_BUF_ERROR);
      }
    
      /* Start a new block or continue the current one.
       */
      if (strm.avail_in !== 0 || s.lookahead !== 0 ||
        (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
        var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
          (s.strategy === Z_RLE ? deflate_rle(s, flush) :
            configuration_table[s.level].func(s, flush));
    
        if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
          s.status = FINISH_STATE;
        }
        if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
          if (strm.avail_out === 0) {
            s.last_flush = -1;
            /* avoid BUF_ERROR next call, see above */
          }
          return Z_OK;
          /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
           * of deflate should use the same flush parameter to make sure
           * that the flush is complete. So we don't have to output an
           * empty block here, this will be done at next call. This also
           * ensures that for a very small output buffer, we emit at most
           * one empty block.
           */
        }
        if (bstate === BS_BLOCK_DONE) {
          if (flush === Z_PARTIAL_FLUSH) {
            trees._tr_align(s);
          }
          else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
    
            trees._tr_stored_block(s, 0, 0, false);
            /* For a full flush, this empty block will be recognized
             * as a special marker by inflate_sync().
             */
            if (flush === Z_FULL_FLUSH) {
              /*** CLEAR_HASH(s); ***/             /* forget history */
              zero(s.head); // Fill with NIL (= 0);
    
              if (s.lookahead === 0) {
                s.strstart = 0;
                s.block_start = 0;
                s.insert = 0;
              }
            }
          }
          flush_pending(strm);
          if (strm.avail_out === 0) {
            s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
            return Z_OK;
          }
        }
      }
      //Assert(strm->avail_out > 0, "bug2");
      //if (strm.avail_out <= 0) { throw new Error("bug2");}
    
      if (flush !== Z_FINISH) { return Z_OK; }
      if (s.wrap <= 0) { return Z_STREAM_END; }
    
      /* Write the trailer */
      if (s.wrap === 2) {
        put_byte(s, strm.adler & 0xff);
        put_byte(s, (strm.adler >> 8) & 0xff);
        put_byte(s, (strm.adler >> 16) & 0xff);
        put_byte(s, (strm.adler >> 24) & 0xff);
        put_byte(s, strm.total_in & 0xff);
        put_byte(s, (strm.total_in >> 8) & 0xff);
        put_byte(s, (strm.total_in >> 16) & 0xff);
        put_byte(s, (strm.total_in >> 24) & 0xff);
      }
      else
      {
        putShortMSB(s, strm.adler >>> 16);
        putShortMSB(s, strm.adler & 0xffff);
      }
    
      flush_pending(strm);
      /* If avail_out is zero, the application will call deflate again
       * to flush the rest.
       */
      if (s.wrap > 0) { s.wrap = -s.wrap; }
      /* write the trailer only once! */
      return s.pending !== 0 ? Z_OK : Z_STREAM_END;
    }
    
    function deflateEnd(strm) {
      var status;
    
      if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
        return Z_STREAM_ERROR;
      }
    
      status = strm.state.status;
      if (status !== INIT_STATE &&
        status !== EXTRA_STATE &&
        status !== NAME_STATE &&
        status !== COMMENT_STATE &&
        status !== HCRC_STATE &&
        status !== BUSY_STATE &&
        status !== FINISH_STATE
      ) {
        return err(strm, Z_STREAM_ERROR);
      }
    
      strm.state = null;
    
      return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
    }
    
    
    /* =========================================================================
     * Initializes the compression dictionary from the given byte
     * sequence without producing any compressed output.
     */
    function deflateSetDictionary(strm, dictionary) {
      var dictLength = dictionary.length;
    
      var s;
      var str, n;
      var wrap;
      var avail;
      var next;
      var input;
      var tmpDict;
    
      if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
        return Z_STREAM_ERROR;
      }
    
      s = strm.state;
      wrap = s.wrap;
    
      if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
        return Z_STREAM_ERROR;
      }
    
      /* when using zlib wrappers, compute Adler-32 for provided dictionary */
      if (wrap === 1) {
        /* adler32(strm->adler, dictionary, dictLength); */
        strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
      }
    
      s.wrap = 0;   /* avoid computing Adler-32 in read_buf */
    
      /* if dictionary would fill window, just replace the history */
      if (dictLength >= s.w_size) {
        if (wrap === 0) {            /* already empty otherwise */
          /*** CLEAR_HASH(s); ***/
          zero(s.head); // Fill with NIL (= 0);
          s.strstart = 0;
          s.block_start = 0;
          s.insert = 0;
        }
        /* use the tail */
        // dictionary = dictionary.slice(dictLength - s.w_size);
        tmpDict = new utils.Buf8(s.w_size);
        utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
        dictionary = tmpDict;
        dictLength = s.w_size;
      }
      /* insert dictionary into window and hash */
      avail = strm.avail_in;
      next = strm.next_in;
      input = strm.input;
      strm.avail_in = dictLength;
      strm.next_in = 0;
      strm.input = dictionary;
      fill_window(s);
      while (s.lookahead >= MIN_MATCH) {
        str = s.strstart;
        n = s.lookahead - (MIN_MATCH - 1);
        do {
          /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
    
          s.prev[str & s.w_mask] = s.head[s.ins_h];
    
          s.head[s.ins_h] = str;
          str++;
        } while (--n);
        s.strstart = str;
        s.lookahead = MIN_MATCH - 1;
        fill_window(s);
      }
      s.strstart += s.lookahead;
      s.block_start = s.strstart;
      s.insert = s.lookahead;
      s.lookahead = 0;
      s.match_length = s.prev_length = MIN_MATCH - 1;
      s.match_available = 0;
      strm.next_in = next;
      strm.input = input;
      strm.avail_in = avail;
      s.wrap = wrap;
      return Z_OK;
    }
    
    
    exports.deflateInit = deflateInit;
    exports.deflateInit2 = deflateInit2;
    exports.deflateReset = deflateReset;
    exports.deflateResetKeep = deflateResetKeep;
    exports.deflateSetHeader = deflateSetHeader;
    exports.deflate = deflate;
    exports.deflateEnd = deflateEnd;
    exports.deflateSetDictionary = deflateSetDictionary;
    exports.deflateInfo = 'pako deflate (from Nodeca project)';
    
    /* Not implemented
    exports.deflateBound = deflateBound;
    exports.deflateCopy = deflateCopy;
    exports.deflateParams = deflateParams;
    exports.deflatePending = deflatePending;
    exports.deflatePrime = deflatePrime;
    exports.deflateTune = deflateTune;
    */
    
    },{"../utils/common":297,"./adler32":298,"./crc32":300,"./messages":305,"./trees":306}],302:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    // See state defs from inflate.js
    var BAD = 30;       /* got a data error -- remain here until reset */
    var TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
    
    /*
       Decode literal, length, and distance codes and write out the resulting
       literal and match bytes until either not enough input or output is
       available, an end-of-block is encountered, or a data error is encountered.
       When large enough input and output buffers are supplied to inflate(), for
       example, a 16K input buffer and a 64K output buffer, more than 95% of the
       inflate execution time is spent in this routine.
    
       Entry assumptions:
    
            state.mode === LEN
            strm.avail_in >= 6
            strm.avail_out >= 258
            start >= strm.avail_out
            state.bits < 8
    
       On return, state.mode is one of:
    
            LEN -- ran out of enough output space or enough available input
            TYPE -- reached end of block code, inflate() to interpret next block
            BAD -- error in block data
    
       Notes:
    
        - The maximum input bits used by a length/distance pair is 15 bits for the
          length code, 5 bits for the length extra, 15 bits for the distance code,
          and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
          Therefore if strm.avail_in >= 6, then there is enough input to avoid
          checking for available input while decoding.
    
        - The maximum bytes that a single length/distance pair can output is 258
          bytes, which is the maximum length that can be coded.  inflate_fast()
          requires strm.avail_out >= 258 for each loop to avoid checking for
          output space.
     */
    module.exports = function inflate_fast(strm, start) {
      var state;
      var _in;                    /* local strm.input */
      var last;                   /* have enough input while in < last */
      var _out;                   /* local strm.output */
      var beg;                    /* inflate()'s initial strm.output */
      var end;                    /* while out < end, enough space available */
    //#ifdef INFLATE_STRICT
      var dmax;                   /* maximum distance from zlib header */
    //#endif
      var wsize;                  /* window size or zero if not using window */
      var whave;                  /* valid bytes in the window */
      var wnext;                  /* window write index */
      // Use `s_window` instead `window`, avoid conflict with instrumentation tools
      var s_window;               /* allocated sliding window, if wsize != 0 */
      var hold;                   /* local strm.hold */
      var bits;                   /* local strm.bits */
      var lcode;                  /* local strm.lencode */
      var dcode;                  /* local strm.distcode */
      var lmask;                  /* mask for first level of length codes */
      var dmask;                  /* mask for first level of distance codes */
      var here;                   /* retrieved table entry */
      var op;                     /* code bits, operation, extra bits, or */
                                  /*  window position, window bytes to copy */
      var len;                    /* match length, unused bytes */
      var dist;                   /* match distance */
      var from;                   /* where to copy match from */
      var from_source;
    
    
      var input, output; // JS specific, because we have no pointers
    
      /* copy state to local variables */
      state = strm.state;
      //here = state.here;
      _in = strm.next_in;
      input = strm.input;
      last = _in + (strm.avail_in - 5);
      _out = strm.next_out;
      output = strm.output;
      beg = _out - (start - strm.avail_out);
      end = _out + (strm.avail_out - 257);
    //#ifdef INFLATE_STRICT
      dmax = state.dmax;
    //#endif
      wsize = state.wsize;
      whave = state.whave;
      wnext = state.wnext;
      s_window = state.window;
      hold = state.hold;
      bits = state.bits;
      lcode = state.lencode;
      dcode = state.distcode;
      lmask = (1 << state.lenbits) - 1;
      dmask = (1 << state.distbits) - 1;
    
    
      /* decode literals and length/distances until end-of-block or not enough
         input data or output space */
    
      top:
      do {
        if (bits < 15) {
          hold += input[_in++] << bits;
          bits += 8;
          hold += input[_in++] << bits;
          bits += 8;
        }
    
        here = lcode[hold & lmask];
    
        dolen:
        for (;;) { // Goto emulation
          op = here >>> 24/*here.bits*/;
          hold >>>= op;
          bits -= op;
          op = (here >>> 16) & 0xff/*here.op*/;
          if (op === 0) {                          /* literal */
            //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
            //        "inflate:         literal '%c'\n" :
            //        "inflate:         literal 0x%02x\n", here.val));
            output[_out++] = here & 0xffff/*here.val*/;
          }
          else if (op & 16) {                     /* length base */
            len = here & 0xffff/*here.val*/;
            op &= 15;                           /* number of extra bits */
            if (op) {
              if (bits < op) {
                hold += input[_in++] << bits;
                bits += 8;
              }
              len += hold & ((1 << op) - 1);
              hold >>>= op;
              bits -= op;
            }
            //Tracevv((stderr, "inflate:         length %u\n", len));
            if (bits < 15) {
              hold += input[_in++] << bits;
              bits += 8;
              hold += input[_in++] << bits;
              bits += 8;
            }
            here = dcode[hold & dmask];
    
            dodist:
            for (;;) { // goto emulation
              op = here >>> 24/*here.bits*/;
              hold >>>= op;
              bits -= op;
              op = (here >>> 16) & 0xff/*here.op*/;
    
              if (op & 16) {                      /* distance base */
                dist = here & 0xffff/*here.val*/;
                op &= 15;                       /* number of extra bits */
                if (bits < op) {
                  hold += input[_in++] << bits;
                  bits += 8;
                  if (bits < op) {
                    hold += input[_in++] << bits;
                    bits += 8;
                  }
                }
                dist += hold & ((1 << op) - 1);
    //#ifdef INFLATE_STRICT
                if (dist > dmax) {
                  strm.msg = 'invalid distance too far back';
                  state.mode = BAD;
                  break top;
                }
    //#endif
                hold >>>= op;
                bits -= op;
                //Tracevv((stderr, "inflate:         distance %u\n", dist));
                op = _out - beg;                /* max distance in output */
                if (dist > op) {                /* see if copy from window */
                  op = dist - op;               /* distance back in window */
                  if (op > whave) {
                    if (state.sane) {
                      strm.msg = 'invalid distance too far back';
                      state.mode = BAD;
                      break top;
                    }
    
    // (!) This block is disabled in zlib defaults,
    // don't enable it for binary compatibility
    //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
    //                if (len <= op - whave) {
    //                  do {
    //                    output[_out++] = 0;
    //                  } while (--len);
    //                  continue top;
    //                }
    //                len -= op - whave;
    //                do {
    //                  output[_out++] = 0;
    //                } while (--op > whave);
    //                if (op === 0) {
    //                  from = _out - dist;
    //                  do {
    //                    output[_out++] = output[from++];
    //                  } while (--len);
    //                  continue top;
    //                }
    //#endif
                  }
                  from = 0; // window index
                  from_source = s_window;
                  if (wnext === 0) {           /* very common case */
                    from += wsize - op;
                    if (op < len) {         /* some from window */
                      len -= op;
                      do {
                        output[_out++] = s_window[from++];
                      } while (--op);
                      from = _out - dist;  /* rest from output */
                      from_source = output;
                    }
                  }
                  else if (wnext < op) {      /* wrap around window */
                    from += wsize + wnext - op;
                    op -= wnext;
                    if (op < len) {         /* some from end of window */
                      len -= op;
                      do {
                        output[_out++] = s_window[from++];
                      } while (--op);
                      from = 0;
                      if (wnext < len) {  /* some from start of window */
                        op = wnext;
                        len -= op;
                        do {
                          output[_out++] = s_window[from++];
                        } while (--op);
                        from = _out - dist;      /* rest from output */
                        from_source = output;
                      }
                    }
                  }
                  else {                      /* contiguous in window */
                    from += wnext - op;
                    if (op < len) {         /* some from window */
                      len -= op;
                      do {
                        output[_out++] = s_window[from++];
                      } while (--op);
                      from = _out - dist;  /* rest from output */
                      from_source = output;
                    }
                  }
                  while (len > 2) {
                    output[_out++] = from_source[from++];
                    output[_out++] = from_source[from++];
                    output[_out++] = from_source[from++];
                    len -= 3;
                  }
                  if (len) {
                    output[_out++] = from_source[from++];
                    if (len > 1) {
                      output[_out++] = from_source[from++];
                    }
                  }
                }
                else {
                  from = _out - dist;          /* copy direct from output */
                  do {                        /* minimum length is three */
                    output[_out++] = output[from++];
                    output[_out++] = output[from++];
                    output[_out++] = output[from++];
                    len -= 3;
                  } while (len > 2);
                  if (len) {
                    output[_out++] = output[from++];
                    if (len > 1) {
                      output[_out++] = output[from++];
                    }
                  }
                }
              }
              else if ((op & 64) === 0) {          /* 2nd level distance code */
                here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
                continue dodist;
              }
              else {
                strm.msg = 'invalid distance code';
                state.mode = BAD;
                break top;
              }
    
              break; // need to emulate goto via "continue"
            }
          }
          else if ((op & 64) === 0) {              /* 2nd level length code */
            here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];
            continue dolen;
          }
          else if (op & 32) {                     /* end-of-block */
            //Tracevv((stderr, "inflate:         end of block\n"));
            state.mode = TYPE;
            break top;
          }
          else {
            strm.msg = 'invalid literal/length code';
            state.mode = BAD;
            break top;
          }
    
          break; // need to emulate goto via "continue"
        }
      } while (_in < last && _out < end);
    
      /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
      len = bits >> 3;
      _in -= len;
      bits -= len << 3;
      hold &= (1 << bits) - 1;
    
      /* update state and return */
      strm.next_in = _in;
      strm.next_out = _out;
      strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
      strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
      state.hold = hold;
      state.bits = bits;
      return;
    };
    
    },{}],303:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    var utils         = require('../utils/common');
    var adler32       = require('./adler32');
    var crc32         = require('./crc32');
    var inflate_fast  = require('./inffast');
    var inflate_table = require('./inftrees');
    
    var CODES = 0;
    var LENS = 1;
    var DISTS = 2;
    
    /* Public constants ==========================================================*/
    /* ===========================================================================*/
    
    
    /* Allowed flush values; see deflate() and inflate() below for details */
    //var Z_NO_FLUSH      = 0;
    //var Z_PARTIAL_FLUSH = 1;
    //var Z_SYNC_FLUSH    = 2;
    //var Z_FULL_FLUSH    = 3;
    var Z_FINISH        = 4;
    var Z_BLOCK         = 5;
    var Z_TREES         = 6;
    
    
    /* Return codes for the compression/decompression functions. Negative values
     * are errors, positive values are used for special but normal events.
     */
    var Z_OK            = 0;
    var Z_STREAM_END    = 1;
    var Z_NEED_DICT     = 2;
    //var Z_ERRNO         = -1;
    var Z_STREAM_ERROR  = -2;
    var Z_DATA_ERROR    = -3;
    var Z_MEM_ERROR     = -4;
    var Z_BUF_ERROR     = -5;
    //var Z_VERSION_ERROR = -6;
    
    /* The deflate compression method */
    var Z_DEFLATED  = 8;
    
    
    /* STATES ====================================================================*/
    /* ===========================================================================*/
    
    
    var    HEAD = 1;       /* i: waiting for magic header */
    var    FLAGS = 2;      /* i: waiting for method and flags (gzip) */
    var    TIME = 3;       /* i: waiting for modification time (gzip) */
    var    OS = 4;         /* i: waiting for extra flags and operating system (gzip) */
    var    EXLEN = 5;      /* i: waiting for extra length (gzip) */
    var    EXTRA = 6;      /* i: waiting for extra bytes (gzip) */
    var    NAME = 7;       /* i: waiting for end of file name (gzip) */
    var    COMMENT = 8;    /* i: waiting for end of comment (gzip) */
    var    HCRC = 9;       /* i: waiting for header crc (gzip) */
    var    DICTID = 10;    /* i: waiting for dictionary check value */
    var    DICT = 11;      /* waiting for inflateSetDictionary() call */
    var        TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
    var        TYPEDO = 13;    /* i: same, but skip check to exit inflate on new block */
    var        STORED = 14;    /* i: waiting for stored size (length and complement) */
    var        COPY_ = 15;     /* i/o: same as COPY below, but only first time in */
    var        COPY = 16;      /* i/o: waiting for input or output to copy stored block */
    var        TABLE = 17;     /* i: waiting for dynamic block table lengths */
    var        LENLENS = 18;   /* i: waiting for code length code lengths */
    var        CODELENS = 19;  /* i: waiting for length/lit and distance code lengths */
    var            LEN_ = 20;      /* i: same as LEN below, but only first time in */
    var            LEN = 21;       /* i: waiting for length/lit/eob code */
    var            LENEXT = 22;    /* i: waiting for length extra bits */
    var            DIST = 23;      /* i: waiting for distance code */
    var            DISTEXT = 24;   /* i: waiting for distance extra bits */
    var            MATCH = 25;     /* o: waiting for output space to copy string */
    var            LIT = 26;       /* o: waiting for output space to write literal */
    var    CHECK = 27;     /* i: waiting for 32-bit check value */
    var    LENGTH = 28;    /* i: waiting for 32-bit length (gzip) */
    var    DONE = 29;      /* finished check, done -- remain here until reset */
    var    BAD = 30;       /* got a data error -- remain here until reset */
    var    MEM = 31;       /* got an inflate() memory error -- remain here until reset */
    var    SYNC = 32;      /* looking for synchronization bytes to restart inflate() */
    
    /* ===========================================================================*/
    
    
    
    var ENOUGH_LENS = 852;
    var ENOUGH_DISTS = 592;
    //var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
    
    var MAX_WBITS = 15;
    /* 32K LZ77 window */
    var DEF_WBITS = MAX_WBITS;
    
    
    function zswap32(q) {
      return  (((q >>> 24) & 0xff) +
              ((q >>> 8) & 0xff00) +
              ((q & 0xff00) << 8) +
              ((q & 0xff) << 24));
    }
    
    
    function InflateState() {
      this.mode = 0;             /* current inflate mode */
      this.last = false;          /* true if processing last block */
      this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
      this.havedict = false;      /* true if dictionary provided */
      this.flags = 0;             /* gzip header method and flags (0 if zlib) */
      this.dmax = 0;              /* zlib header max distance (INFLATE_STRICT) */
      this.check = 0;             /* protected copy of check value */
      this.total = 0;             /* protected copy of output count */
      // TODO: may be {}
      this.head = null;           /* where to save gzip header information */
    
      /* sliding window */
      this.wbits = 0;             /* log base 2 of requested window size */
      this.wsize = 0;             /* window size or zero if not using window */
      this.whave = 0;             /* valid bytes in the window */
      this.wnext = 0;             /* window write index */
      this.window = null;         /* allocated sliding window, if needed */
    
      /* bit accumulator */
      this.hold = 0;              /* input bit accumulator */
      this.bits = 0;              /* number of bits in "in" */
    
      /* for string and stored block copying */
      this.length = 0;            /* literal or length of data to copy */
      this.offset = 0;            /* distance back to copy string from */
    
      /* for table and code decoding */
      this.extra = 0;             /* extra bits needed */
    
      /* fixed and dynamic code tables */
      this.lencode = null;          /* starting table for length/literal codes */
      this.distcode = null;         /* starting table for distance codes */
      this.lenbits = 0;           /* index bits for lencode */
      this.distbits = 0;          /* index bits for distcode */
    
      /* dynamic table building */
      this.ncode = 0;             /* number of code length code lengths */
      this.nlen = 0;              /* number of length code lengths */
      this.ndist = 0;             /* number of distance code lengths */
      this.have = 0;              /* number of code lengths in lens[] */
      this.next = null;              /* next available space in codes[] */
    
      this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
      this.work = new utils.Buf16(288); /* work area for code table building */
    
      /*
       because we don't have pointers in js, we use lencode and distcode directly
       as buffers so we don't need codes
      */
      //this.codes = new utils.Buf32(ENOUGH);       /* space for code tables */
      this.lendyn = null;              /* dynamic table for length/literal codes (JS specific) */
      this.distdyn = null;             /* dynamic table for distance codes (JS specific) */
      this.sane = 0;                   /* if false, allow invalid distance too far */
      this.back = 0;                   /* bits back of last unprocessed length/lit */
      this.was = 0;                    /* initial length of match */
    }
    
    function inflateResetKeep(strm) {
      var state;
    
      if (!strm || !strm.state) { return Z_STREAM_ERROR; }
      state = strm.state;
      strm.total_in = strm.total_out = state.total = 0;
      strm.msg = ''; /*Z_NULL*/
      if (state.wrap) {       /* to support ill-conceived Java test suite */
        strm.adler = state.wrap & 1;
      }
      state.mode = HEAD;
      state.last = 0;
      state.havedict = 0;
      state.dmax = 32768;
      state.head = null/*Z_NULL*/;
      state.hold = 0;
      state.bits = 0;
      //state.lencode = state.distcode = state.next = state.codes;
      state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
      state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
    
      state.sane = 1;
      state.back = -1;
      //Tracev((stderr, "inflate: reset\n"));
      return Z_OK;
    }
    
    function inflateReset(strm) {
      var state;
    
      if (!strm || !strm.state) { return Z_STREAM_ERROR; }
      state = strm.state;
      state.wsize = 0;
      state.whave = 0;
      state.wnext = 0;
      return inflateResetKeep(strm);
    
    }
    
    function inflateReset2(strm, windowBits) {
      var wrap;
      var state;
    
      /* get the state */
      if (!strm || !strm.state) { return Z_STREAM_ERROR; }
      state = strm.state;
    
      /* extract wrap request from windowBits parameter */
      if (windowBits < 0) {
        wrap = 0;
        windowBits = -windowBits;
      }
      else {
        wrap = (windowBits >> 4) + 1;
        if (windowBits < 48) {
          windowBits &= 15;
        }
      }
    
      /* set number of window bits, free window if different */
      if (windowBits && (windowBits < 8 || windowBits > 15)) {
        return Z_STREAM_ERROR;
      }
      if (state.window !== null && state.wbits !== windowBits) {
        state.window = null;
      }
    
      /* update state and reset the rest of it */
      state.wrap = wrap;
      state.wbits = windowBits;
      return inflateReset(strm);
    }
    
    function inflateInit2(strm, windowBits) {
      var ret;
      var state;
    
      if (!strm) { return Z_STREAM_ERROR; }
      //strm.msg = Z_NULL;                 /* in case we return an error */
    
      state = new InflateState();
    
      //if (state === Z_NULL) return Z_MEM_ERROR;
      //Tracev((stderr, "inflate: allocated\n"));
      strm.state = state;
      state.window = null/*Z_NULL*/;
      ret = inflateReset2(strm, windowBits);
      if (ret !== Z_OK) {
        strm.state = null/*Z_NULL*/;
      }
      return ret;
    }
    
    function inflateInit(strm) {
      return inflateInit2(strm, DEF_WBITS);
    }
    
    
    /*
     Return state with length and distance decoding tables and index sizes set to
     fixed code decoding.  Normally this returns fixed tables from inffixed.h.
     If BUILDFIXED is defined, then instead this routine builds the tables the
     first time it's called, and returns those tables the first time and
     thereafter.  This reduces the size of the code by about 2K bytes, in
     exchange for a little execution time.  However, BUILDFIXED should not be
     used for threaded applications, since the rewriting of the tables and virgin
     may not be thread-safe.
     */
    var virgin = true;
    
    var lenfix, distfix; // We have no pointers in JS, so keep tables separate
    
    function fixedtables(state) {
      /* build fixed huffman tables if first call (may not be thread safe) */
      if (virgin) {
        var sym;
    
        lenfix = new utils.Buf32(512);
        distfix = new utils.Buf32(32);
    
        /* literal/length table */
        sym = 0;
        while (sym < 144) { state.lens[sym++] = 8; }
        while (sym < 256) { state.lens[sym++] = 9; }
        while (sym < 280) { state.lens[sym++] = 7; }
        while (sym < 288) { state.lens[sym++] = 8; }
    
        inflate_table(LENS,  state.lens, 0, 288, lenfix,   0, state.work, { bits: 9 });
    
        /* distance table */
        sym = 0;
        while (sym < 32) { state.lens[sym++] = 5; }
    
        inflate_table(DISTS, state.lens, 0, 32,   distfix, 0, state.work, { bits: 5 });
    
        /* do this just once */
        virgin = false;
      }
    
      state.lencode = lenfix;
      state.lenbits = 9;
      state.distcode = distfix;
      state.distbits = 5;
    }
    
    
    /*
     Update the window with the last wsize (normally 32K) bytes written before
     returning.  If window does not exist yet, create it.  This is only called
     when a window is already in use, or when output has been written during this
     inflate call, but the end of the deflate stream has not been reached yet.
     It is also called to create a window for dictionary data when a dictionary
     is loaded.
    
     Providing output buffers larger than 32K to inflate() should provide a speed
     advantage, since only the last 32K of output is copied to the sliding window
     upon return from inflate(), and since all distances after the first 32K of
     output will fall in the output data, making match copies simpler and faster.
     The advantage may be dependent on the size of the processor's data caches.
     */
    function updatewindow(strm, src, end, copy) {
      var dist;
      var state = strm.state;
    
      /* if it hasn't been done already, allocate space for the window */
      if (state.window === null) {
        state.wsize = 1 << state.wbits;
        state.wnext = 0;
        state.whave = 0;
    
        state.window = new utils.Buf8(state.wsize);
      }
    
      /* copy state->wsize or less output bytes into the circular window */
      if (copy >= state.wsize) {
        utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
        state.wnext = 0;
        state.whave = state.wsize;
      }
      else {
        dist = state.wsize - state.wnext;
        if (dist > copy) {
          dist = copy;
        }
        //zmemcpy(state->window + state->wnext, end - copy, dist);
        utils.arraySet(state.window, src, end - copy, dist, state.wnext);
        copy -= dist;
        if (copy) {
          //zmemcpy(state->window, end - copy, copy);
          utils.arraySet(state.window, src, end - copy, copy, 0);
          state.wnext = copy;
          state.whave = state.wsize;
        }
        else {
          state.wnext += dist;
          if (state.wnext === state.wsize) { state.wnext = 0; }
          if (state.whave < state.wsize) { state.whave += dist; }
        }
      }
      return 0;
    }
    
    function inflate(strm, flush) {
      var state;
      var input, output;          // input/output buffers
      var next;                   /* next input INDEX */
      var put;                    /* next output INDEX */
      var have, left;             /* available input and output */
      var hold;                   /* bit buffer */
      var bits;                   /* bits in bit buffer */
      var _in, _out;              /* save starting available input and output */
      var copy;                   /* number of stored or match bytes to copy */
      var from;                   /* where to copy match bytes from */
      var from_source;
      var here = 0;               /* current decoding table entry */
      var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
      //var last;                   /* parent table entry */
      var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
      var len;                    /* length to copy for repeats, bits to drop */
      var ret;                    /* return code */
      var hbuf = new utils.Buf8(4);    /* buffer for gzip header crc calculation */
      var opts;
    
      var n; // temporary var for NEED_BITS
    
      var order = /* permutation of code lengths */
        [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
    
    
      if (!strm || !strm.state || !strm.output ||
          (!strm.input && strm.avail_in !== 0)) {
        return Z_STREAM_ERROR;
      }
    
      state = strm.state;
      if (state.mode === TYPE) { state.mode = TYPEDO; }    /* skip check */
    
    
      //--- LOAD() ---
      put = strm.next_out;
      output = strm.output;
      left = strm.avail_out;
      next = strm.next_in;
      input = strm.input;
      have = strm.avail_in;
      hold = state.hold;
      bits = state.bits;
      //---
    
      _in = have;
      _out = left;
      ret = Z_OK;
    
      inf_leave: // goto emulation
      for (;;) {
        switch (state.mode) {
          case HEAD:
            if (state.wrap === 0) {
              state.mode = TYPEDO;
              break;
            }
            //=== NEEDBITS(16);
            while (bits < 16) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            if ((state.wrap & 2) && hold === 0x8b1f) {  /* gzip header */
              state.check = 0/*crc32(0L, Z_NULL, 0)*/;
              //=== CRC2(state.check, hold);
              hbuf[0] = hold & 0xff;
              hbuf[1] = (hold >>> 8) & 0xff;
              state.check = crc32(state.check, hbuf, 2, 0);
              //===//
    
              //=== INITBITS();
              hold = 0;
              bits = 0;
              //===//
              state.mode = FLAGS;
              break;
            }
            state.flags = 0;           /* expect zlib header */
            if (state.head) {
              state.head.done = false;
            }
            if (!(state.wrap & 1) ||   /* check if zlib header allowed */
              (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
              strm.msg = 'incorrect header check';
              state.mode = BAD;
              break;
            }
            if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
              strm.msg = 'unknown compression method';
              state.mode = BAD;
              break;
            }
            //--- DROPBITS(4) ---//
            hold >>>= 4;
            bits -= 4;
            //---//
            len = (hold & 0x0f)/*BITS(4)*/ + 8;
            if (state.wbits === 0) {
              state.wbits = len;
            }
            else if (len > state.wbits) {
              strm.msg = 'invalid window size';
              state.mode = BAD;
              break;
            }
            state.dmax = 1 << len;
            //Tracev((stderr, "inflate:   zlib header ok\n"));
            strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
            state.mode = hold & 0x200 ? DICTID : TYPE;
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            break;
          case FLAGS:
            //=== NEEDBITS(16); */
            while (bits < 16) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            state.flags = hold;
            if ((state.flags & 0xff) !== Z_DEFLATED) {
              strm.msg = 'unknown compression method';
              state.mode = BAD;
              break;
            }
            if (state.flags & 0xe000) {
              strm.msg = 'unknown header flags set';
              state.mode = BAD;
              break;
            }
            if (state.head) {
              state.head.text = ((hold >> 8) & 1);
            }
            if (state.flags & 0x0200) {
              //=== CRC2(state.check, hold);
              hbuf[0] = hold & 0xff;
              hbuf[1] = (hold >>> 8) & 0xff;
              state.check = crc32(state.check, hbuf, 2, 0);
              //===//
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = TIME;
            /* falls through */
          case TIME:
            //=== NEEDBITS(32); */
            while (bits < 32) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            if (state.head) {
              state.head.time = hold;
            }
            if (state.flags & 0x0200) {
              //=== CRC4(state.check, hold)
              hbuf[0] = hold & 0xff;
              hbuf[1] = (hold >>> 8) & 0xff;
              hbuf[2] = (hold >>> 16) & 0xff;
              hbuf[3] = (hold >>> 24) & 0xff;
              state.check = crc32(state.check, hbuf, 4, 0);
              //===
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = OS;
            /* falls through */
          case OS:
            //=== NEEDBITS(16); */
            while (bits < 16) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            if (state.head) {
              state.head.xflags = (hold & 0xff);
              state.head.os = (hold >> 8);
            }
            if (state.flags & 0x0200) {
              //=== CRC2(state.check, hold);
              hbuf[0] = hold & 0xff;
              hbuf[1] = (hold >>> 8) & 0xff;
              state.check = crc32(state.check, hbuf, 2, 0);
              //===//
            }
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = EXLEN;
            /* falls through */
          case EXLEN:
            if (state.flags & 0x0400) {
              //=== NEEDBITS(16); */
              while (bits < 16) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              state.length = hold;
              if (state.head) {
                state.head.extra_len = hold;
              }
              if (state.flags & 0x0200) {
                //=== CRC2(state.check, hold);
                hbuf[0] = hold & 0xff;
                hbuf[1] = (hold >>> 8) & 0xff;
                state.check = crc32(state.check, hbuf, 2, 0);
                //===//
              }
              //=== INITBITS();
              hold = 0;
              bits = 0;
              //===//
            }
            else if (state.head) {
              state.head.extra = null/*Z_NULL*/;
            }
            state.mode = EXTRA;
            /* falls through */
          case EXTRA:
            if (state.flags & 0x0400) {
              copy = state.length;
              if (copy > have) { copy = have; }
              if (copy) {
                if (state.head) {
                  len = state.head.extra_len - state.length;
                  if (!state.head.extra) {
                    // Use untyped array for more convenient processing later
                    state.head.extra = new Array(state.head.extra_len);
                  }
                  utils.arraySet(
                    state.head.extra,
                    input,
                    next,
                    // extra field is limited to 65536 bytes
                    // - no need for additional size check
                    copy,
                    /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
                    len
                  );
                  //zmemcpy(state.head.extra + len, next,
                  //        len + copy > state.head.extra_max ?
                  //        state.head.extra_max - len : copy);
                }
                if (state.flags & 0x0200) {
                  state.check = crc32(state.check, input, copy, next);
                }
                have -= copy;
                next += copy;
                state.length -= copy;
              }
              if (state.length) { break inf_leave; }
            }
            state.length = 0;
            state.mode = NAME;
            /* falls through */
          case NAME:
            if (state.flags & 0x0800) {
              if (have === 0) { break inf_leave; }
              copy = 0;
              do {
                // TODO: 2 or 1 bytes?
                len = input[next + copy++];
                /* use constant limit because in js we should not preallocate memory */
                if (state.head && len &&
                    (state.length < 65536 /*state.head.name_max*/)) {
                  state.head.name += String.fromCharCode(len);
                }
              } while (len && copy < have);
    
              if (state.flags & 0x0200) {
                state.check = crc32(state.check, input, copy, next);
              }
              have -= copy;
              next += copy;
              if (len) { break inf_leave; }
            }
            else if (state.head) {
              state.head.name = null;
            }
            state.length = 0;
            state.mode = COMMENT;
            /* falls through */
          case COMMENT:
            if (state.flags & 0x1000) {
              if (have === 0) { break inf_leave; }
              copy = 0;
              do {
                len = input[next + copy++];
                /* use constant limit because in js we should not preallocate memory */
                if (state.head && len &&
                    (state.length < 65536 /*state.head.comm_max*/)) {
                  state.head.comment += String.fromCharCode(len);
                }
              } while (len && copy < have);
              if (state.flags & 0x0200) {
                state.check = crc32(state.check, input, copy, next);
              }
              have -= copy;
              next += copy;
              if (len) { break inf_leave; }
            }
            else if (state.head) {
              state.head.comment = null;
            }
            state.mode = HCRC;
            /* falls through */
          case HCRC:
            if (state.flags & 0x0200) {
              //=== NEEDBITS(16); */
              while (bits < 16) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              if (hold !== (state.check & 0xffff)) {
                strm.msg = 'header crc mismatch';
                state.mode = BAD;
                break;
              }
              //=== INITBITS();
              hold = 0;
              bits = 0;
              //===//
            }
            if (state.head) {
              state.head.hcrc = ((state.flags >> 9) & 1);
              state.head.done = true;
            }
            strm.adler = state.check = 0;
            state.mode = TYPE;
            break;
          case DICTID:
            //=== NEEDBITS(32); */
            while (bits < 32) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            strm.adler = state.check = zswap32(hold);
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = DICT;
            /* falls through */
          case DICT:
            if (state.havedict === 0) {
              //--- RESTORE() ---
              strm.next_out = put;
              strm.avail_out = left;
              strm.next_in = next;
              strm.avail_in = have;
              state.hold = hold;
              state.bits = bits;
              //---
              return Z_NEED_DICT;
            }
            strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
            state.mode = TYPE;
            /* falls through */
          case TYPE:
            if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
            /* falls through */
          case TYPEDO:
            if (state.last) {
              //--- BYTEBITS() ---//
              hold >>>= bits & 7;
              bits -= bits & 7;
              //---//
              state.mode = CHECK;
              break;
            }
            //=== NEEDBITS(3); */
            while (bits < 3) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            state.last = (hold & 0x01)/*BITS(1)*/;
            //--- DROPBITS(1) ---//
            hold >>>= 1;
            bits -= 1;
            //---//
    
            switch ((hold & 0x03)/*BITS(2)*/) {
              case 0:                             /* stored block */
                //Tracev((stderr, "inflate:     stored block%s\n",
                //        state.last ? " (last)" : ""));
                state.mode = STORED;
                break;
              case 1:                             /* fixed block */
                fixedtables(state);
                //Tracev((stderr, "inflate:     fixed codes block%s\n",
                //        state.last ? " (last)" : ""));
                state.mode = LEN_;             /* decode codes */
                if (flush === Z_TREES) {
                  //--- DROPBITS(2) ---//
                  hold >>>= 2;
                  bits -= 2;
                  //---//
                  break inf_leave;
                }
                break;
              case 2:                             /* dynamic block */
                //Tracev((stderr, "inflate:     dynamic codes block%s\n",
                //        state.last ? " (last)" : ""));
                state.mode = TABLE;
                break;
              case 3:
                strm.msg = 'invalid block type';
                state.mode = BAD;
            }
            //--- DROPBITS(2) ---//
            hold >>>= 2;
            bits -= 2;
            //---//
            break;
          case STORED:
            //--- BYTEBITS() ---// /* go to byte boundary */
            hold >>>= bits & 7;
            bits -= bits & 7;
            //---//
            //=== NEEDBITS(32); */
            while (bits < 32) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
              strm.msg = 'invalid stored block lengths';
              state.mode = BAD;
              break;
            }
            state.length = hold & 0xffff;
            //Tracev((stderr, "inflate:       stored length %u\n",
            //        state.length));
            //=== INITBITS();
            hold = 0;
            bits = 0;
            //===//
            state.mode = COPY_;
            if (flush === Z_TREES) { break inf_leave; }
            /* falls through */
          case COPY_:
            state.mode = COPY;
            /* falls through */
          case COPY:
            copy = state.length;
            if (copy) {
              if (copy > have) { copy = have; }
              if (copy > left) { copy = left; }
              if (copy === 0) { break inf_leave; }
              //--- zmemcpy(put, next, copy); ---
              utils.arraySet(output, input, next, copy, put);
              //---//
              have -= copy;
              next += copy;
              left -= copy;
              put += copy;
              state.length -= copy;
              break;
            }
            //Tracev((stderr, "inflate:       stored end\n"));
            state.mode = TYPE;
            break;
          case TABLE:
            //=== NEEDBITS(14); */
            while (bits < 14) {
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
            }
            //===//
            state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
            //--- DROPBITS(5) ---//
            hold >>>= 5;
            bits -= 5;
            //---//
            state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
            //--- DROPBITS(5) ---//
            hold >>>= 5;
            bits -= 5;
            //---//
            state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
            //--- DROPBITS(4) ---//
            hold >>>= 4;
            bits -= 4;
            //---//
    //#ifndef PKZIP_BUG_WORKAROUND
            if (state.nlen > 286 || state.ndist > 30) {
              strm.msg = 'too many length or distance symbols';
              state.mode = BAD;
              break;
            }
    //#endif
            //Tracev((stderr, "inflate:       table sizes ok\n"));
            state.have = 0;
            state.mode = LENLENS;
            /* falls through */
          case LENLENS:
            while (state.have < state.ncode) {
              //=== NEEDBITS(3);
              while (bits < 3) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
              //--- DROPBITS(3) ---//
              hold >>>= 3;
              bits -= 3;
              //---//
            }
            while (state.have < 19) {
              state.lens[order[state.have++]] = 0;
            }
            // We have separate tables & no pointers. 2 commented lines below not needed.
            //state.next = state.codes;
            //state.lencode = state.next;
            // Switch to use dynamic table
            state.lencode = state.lendyn;
            state.lenbits = 7;
    
            opts = { bits: state.lenbits };
            ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
            state.lenbits = opts.bits;
    
            if (ret) {
              strm.msg = 'invalid code lengths set';
              state.mode = BAD;
              break;
            }
            //Tracev((stderr, "inflate:       code lengths ok\n"));
            state.have = 0;
            state.mode = CODELENS;
            /* falls through */
          case CODELENS:
            while (state.have < state.nlen + state.ndist) {
              for (;;) {
                here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
                here_bits = here >>> 24;
                here_op = (here >>> 16) & 0xff;
                here_val = here & 0xffff;
    
                if ((here_bits) <= bits) { break; }
                //--- PULLBYTE() ---//
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
                //---//
              }
              if (here_val < 16) {
                //--- DROPBITS(here.bits) ---//
                hold >>>= here_bits;
                bits -= here_bits;
                //---//
                state.lens[state.have++] = here_val;
              }
              else {
                if (here_val === 16) {
                  //=== NEEDBITS(here.bits + 2);
                  n = here_bits + 2;
                  while (bits < n) {
                    if (have === 0) { break inf_leave; }
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                  }
                  //===//
                  //--- DROPBITS(here.bits) ---//
                  hold >>>= here_bits;
                  bits -= here_bits;
                  //---//
                  if (state.have === 0) {
                    strm.msg = 'invalid bit length repeat';
                    state.mode = BAD;
                    break;
                  }
                  len = state.lens[state.have - 1];
                  copy = 3 + (hold & 0x03);//BITS(2);
                  //--- DROPBITS(2) ---//
                  hold >>>= 2;
                  bits -= 2;
                  //---//
                }
                else if (here_val === 17) {
                  //=== NEEDBITS(here.bits + 3);
                  n = here_bits + 3;
                  while (bits < n) {
                    if (have === 0) { break inf_leave; }
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                  }
                  //===//
                  //--- DROPBITS(here.bits) ---//
                  hold >>>= here_bits;
                  bits -= here_bits;
                  //---//
                  len = 0;
                  copy = 3 + (hold & 0x07);//BITS(3);
                  //--- DROPBITS(3) ---//
                  hold >>>= 3;
                  bits -= 3;
                  //---//
                }
                else {
                  //=== NEEDBITS(here.bits + 7);
                  n = here_bits + 7;
                  while (bits < n) {
                    if (have === 0) { break inf_leave; }
                    have--;
                    hold += input[next++] << bits;
                    bits += 8;
                  }
                  //===//
                  //--- DROPBITS(here.bits) ---//
                  hold >>>= here_bits;
                  bits -= here_bits;
                  //---//
                  len = 0;
                  copy = 11 + (hold & 0x7f);//BITS(7);
                  //--- DROPBITS(7) ---//
                  hold >>>= 7;
                  bits -= 7;
                  //---//
                }
                if (state.have + copy > state.nlen + state.ndist) {
                  strm.msg = 'invalid bit length repeat';
                  state.mode = BAD;
                  break;
                }
                while (copy--) {
                  state.lens[state.have++] = len;
                }
              }
            }
    
            /* handle error breaks in while */
            if (state.mode === BAD) { break; }
    
            /* check for end-of-block code (better have one) */
            if (state.lens[256] === 0) {
              strm.msg = 'invalid code -- missing end-of-block';
              state.mode = BAD;
              break;
            }
    
            /* build code tables -- note: do not change the lenbits or distbits
               values here (9 and 6) without reading the comments in inftrees.h
               concerning the ENOUGH constants, which depend on those values */
            state.lenbits = 9;
    
            opts = { bits: state.lenbits };
            ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
            // We have separate tables & no pointers. 2 commented lines below not needed.
            // state.next_index = opts.table_index;
            state.lenbits = opts.bits;
            // state.lencode = state.next;
    
            if (ret) {
              strm.msg = 'invalid literal/lengths set';
              state.mode = BAD;
              break;
            }
    
            state.distbits = 6;
            //state.distcode.copy(state.codes);
            // Switch to use dynamic table
            state.distcode = state.distdyn;
            opts = { bits: state.distbits };
            ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
            // We have separate tables & no pointers. 2 commented lines below not needed.
            // state.next_index = opts.table_index;
            state.distbits = opts.bits;
            // state.distcode = state.next;
    
            if (ret) {
              strm.msg = 'invalid distances set';
              state.mode = BAD;
              break;
            }
            //Tracev((stderr, 'inflate:       codes ok\n'));
            state.mode = LEN_;
            if (flush === Z_TREES) { break inf_leave; }
            /* falls through */
          case LEN_:
            state.mode = LEN;
            /* falls through */
          case LEN:
            if (have >= 6 && left >= 258) {
              //--- RESTORE() ---
              strm.next_out = put;
              strm.avail_out = left;
              strm.next_in = next;
              strm.avail_in = have;
              state.hold = hold;
              state.bits = bits;
              //---
              inflate_fast(strm, _out);
              //--- LOAD() ---
              put = strm.next_out;
              output = strm.output;
              left = strm.avail_out;
              next = strm.next_in;
              input = strm.input;
              have = strm.avail_in;
              hold = state.hold;
              bits = state.bits;
              //---
    
              if (state.mode === TYPE) {
                state.back = -1;
              }
              break;
            }
            state.back = 0;
            for (;;) {
              here = state.lencode[hold & ((1 << state.lenbits) - 1)];  /*BITS(state.lenbits)*/
              here_bits = here >>> 24;
              here_op = (here >>> 16) & 0xff;
              here_val = here & 0xffff;
    
              if (here_bits <= bits) { break; }
              //--- PULLBYTE() ---//
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
              //---//
            }
            if (here_op && (here_op & 0xf0) === 0) {
              last_bits = here_bits;
              last_op = here_op;
              last_val = here_val;
              for (;;) {
                here = state.lencode[last_val +
                        ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
                here_bits = here >>> 24;
                here_op = (here >>> 16) & 0xff;
                here_val = here & 0xffff;
    
                if ((last_bits + here_bits) <= bits) { break; }
                //--- PULLBYTE() ---//
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
                //---//
              }
              //--- DROPBITS(last.bits) ---//
              hold >>>= last_bits;
              bits -= last_bits;
              //---//
              state.back += last_bits;
            }
            //--- DROPBITS(here.bits) ---//
            hold >>>= here_bits;
            bits -= here_bits;
            //---//
            state.back += here_bits;
            state.length = here_val;
            if (here_op === 0) {
              //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
              //        "inflate:         literal '%c'\n" :
              //        "inflate:         literal 0x%02x\n", here.val));
              state.mode = LIT;
              break;
            }
            if (here_op & 32) {
              //Tracevv((stderr, "inflate:         end of block\n"));
              state.back = -1;
              state.mode = TYPE;
              break;
            }
            if (here_op & 64) {
              strm.msg = 'invalid literal/length code';
              state.mode = BAD;
              break;
            }
            state.extra = here_op & 15;
            state.mode = LENEXT;
            /* falls through */
          case LENEXT:
            if (state.extra) {
              //=== NEEDBITS(state.extra);
              n = state.extra;
              while (bits < n) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
              //--- DROPBITS(state.extra) ---//
              hold >>>= state.extra;
              bits -= state.extra;
              //---//
              state.back += state.extra;
            }
            //Tracevv((stderr, "inflate:         length %u\n", state.length));
            state.was = state.length;
            state.mode = DIST;
            /* falls through */
          case DIST:
            for (;;) {
              here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
              here_bits = here >>> 24;
              here_op = (here >>> 16) & 0xff;
              here_val = here & 0xffff;
    
              if ((here_bits) <= bits) { break; }
              //--- PULLBYTE() ---//
              if (have === 0) { break inf_leave; }
              have--;
              hold += input[next++] << bits;
              bits += 8;
              //---//
            }
            if ((here_op & 0xf0) === 0) {
              last_bits = here_bits;
              last_op = here_op;
              last_val = here_val;
              for (;;) {
                here = state.distcode[last_val +
                        ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
                here_bits = here >>> 24;
                here_op = (here >>> 16) & 0xff;
                here_val = here & 0xffff;
    
                if ((last_bits + here_bits) <= bits) { break; }
                //--- PULLBYTE() ---//
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
                //---//
              }
              //--- DROPBITS(last.bits) ---//
              hold >>>= last_bits;
              bits -= last_bits;
              //---//
              state.back += last_bits;
            }
            //--- DROPBITS(here.bits) ---//
            hold >>>= here_bits;
            bits -= here_bits;
            //---//
            state.back += here_bits;
            if (here_op & 64) {
              strm.msg = 'invalid distance code';
              state.mode = BAD;
              break;
            }
            state.offset = here_val;
            state.extra = (here_op) & 15;
            state.mode = DISTEXT;
            /* falls through */
          case DISTEXT:
            if (state.extra) {
              //=== NEEDBITS(state.extra);
              n = state.extra;
              while (bits < n) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
              //--- DROPBITS(state.extra) ---//
              hold >>>= state.extra;
              bits -= state.extra;
              //---//
              state.back += state.extra;
            }
    //#ifdef INFLATE_STRICT
            if (state.offset > state.dmax) {
              strm.msg = 'invalid distance too far back';
              state.mode = BAD;
              break;
            }
    //#endif
            //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
            state.mode = MATCH;
            /* falls through */
          case MATCH:
            if (left === 0) { break inf_leave; }
            copy = _out - left;
            if (state.offset > copy) {         /* copy from window */
              copy = state.offset - copy;
              if (copy > state.whave) {
                if (state.sane) {
                  strm.msg = 'invalid distance too far back';
                  state.mode = BAD;
                  break;
                }
    // (!) This block is disabled in zlib defaults,
    // don't enable it for binary compatibility
    //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
    //          Trace((stderr, "inflate.c too far\n"));
    //          copy -= state.whave;
    //          if (copy > state.length) { copy = state.length; }
    //          if (copy > left) { copy = left; }
    //          left -= copy;
    //          state.length -= copy;
    //          do {
    //            output[put++] = 0;
    //          } while (--copy);
    //          if (state.length === 0) { state.mode = LEN; }
    //          break;
    //#endif
              }
              if (copy > state.wnext) {
                copy -= state.wnext;
                from = state.wsize - copy;
              }
              else {
                from = state.wnext - copy;
              }
              if (copy > state.length) { copy = state.length; }
              from_source = state.window;
            }
            else {                              /* copy from output */
              from_source = output;
              from = put - state.offset;
              copy = state.length;
            }
            if (copy > left) { copy = left; }
            left -= copy;
            state.length -= copy;
            do {
              output[put++] = from_source[from++];
            } while (--copy);
            if (state.length === 0) { state.mode = LEN; }
            break;
          case LIT:
            if (left === 0) { break inf_leave; }
            output[put++] = state.length;
            left--;
            state.mode = LEN;
            break;
          case CHECK:
            if (state.wrap) {
              //=== NEEDBITS(32);
              while (bits < 32) {
                if (have === 0) { break inf_leave; }
                have--;
                // Use '|' instead of '+' to make sure that result is signed
                hold |= input[next++] << bits;
                bits += 8;
              }
              //===//
              _out -= left;
              strm.total_out += _out;
              state.total += _out;
              if (_out) {
                strm.adler = state.check =
                    /*UPDATE(state.check, put - _out, _out);*/
                    (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
    
              }
              _out = left;
              // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
              if ((state.flags ? hold : zswap32(hold)) !== state.check) {
                strm.msg = 'incorrect data check';
                state.mode = BAD;
                break;
              }
              //=== INITBITS();
              hold = 0;
              bits = 0;
              //===//
              //Tracev((stderr, "inflate:   check matches trailer\n"));
            }
            state.mode = LENGTH;
            /* falls through */
          case LENGTH:
            if (state.wrap && state.flags) {
              //=== NEEDBITS(32);
              while (bits < 32) {
                if (have === 0) { break inf_leave; }
                have--;
                hold += input[next++] << bits;
                bits += 8;
              }
              //===//
              if (hold !== (state.total & 0xffffffff)) {
                strm.msg = 'incorrect length check';
                state.mode = BAD;
                break;
              }
              //=== INITBITS();
              hold = 0;
              bits = 0;
              //===//
              //Tracev((stderr, "inflate:   length matches trailer\n"));
            }
            state.mode = DONE;
            /* falls through */
          case DONE:
            ret = Z_STREAM_END;
            break inf_leave;
          case BAD:
            ret = Z_DATA_ERROR;
            break inf_leave;
          case MEM:
            return Z_MEM_ERROR;
          case SYNC:
            /* falls through */
          default:
            return Z_STREAM_ERROR;
        }
      }
    
      // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
    
      /*
         Return from inflate(), updating the total counts and the check value.
         If there was no progress during the inflate() call, return a buffer
         error.  Call updatewindow() to create and/or update the window state.
         Note: a memory error from inflate() is non-recoverable.
       */
    
      //--- RESTORE() ---
      strm.next_out = put;
      strm.avail_out = left;
      strm.next_in = next;
      strm.avail_in = have;
      state.hold = hold;
      state.bits = bits;
      //---
    
      if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
                          (state.mode < CHECK || flush !== Z_FINISH))) {
        if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
          state.mode = MEM;
          return Z_MEM_ERROR;
        }
      }
      _in -= strm.avail_in;
      _out -= strm.avail_out;
      strm.total_in += _in;
      strm.total_out += _out;
      state.total += _out;
      if (state.wrap && _out) {
        strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
          (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
      }
      strm.data_type = state.bits + (state.last ? 64 : 0) +
                        (state.mode === TYPE ? 128 : 0) +
                        (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
      if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
        ret = Z_BUF_ERROR;
      }
      return ret;
    }
    
    function inflateEnd(strm) {
    
      if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
        return Z_STREAM_ERROR;
      }
    
      var state = strm.state;
      if (state.window) {
        state.window = null;
      }
      strm.state = null;
      return Z_OK;
    }
    
    function inflateGetHeader(strm, head) {
      var state;
    
      /* check state */
      if (!strm || !strm.state) { return Z_STREAM_ERROR; }
      state = strm.state;
      if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
    
      /* save header structure */
      state.head = head;
      head.done = false;
      return Z_OK;
    }
    
    function inflateSetDictionary(strm, dictionary) {
      var dictLength = dictionary.length;
    
      var state;
      var dictid;
      var ret;
    
      /* check state */
      if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
      state = strm.state;
    
      if (state.wrap !== 0 && state.mode !== DICT) {
        return Z_STREAM_ERROR;
      }
    
      /* check for correct dictionary identifier */
      if (state.mode === DICT) {
        dictid = 1; /* adler32(0, null, 0)*/
        /* dictid = adler32(dictid, dictionary, dictLength); */
        dictid = adler32(dictid, dictionary, dictLength, 0);
        if (dictid !== state.check) {
          return Z_DATA_ERROR;
        }
      }
      /* copy dictionary to window using updatewindow(), which will amend the
       existing dictionary if appropriate */
      ret = updatewindow(strm, dictionary, dictLength, dictLength);
      if (ret) {
        state.mode = MEM;
        return Z_MEM_ERROR;
      }
      state.havedict = 1;
      // Tracev((stderr, "inflate:   dictionary set\n"));
      return Z_OK;
    }
    
    exports.inflateReset = inflateReset;
    exports.inflateReset2 = inflateReset2;
    exports.inflateResetKeep = inflateResetKeep;
    exports.inflateInit = inflateInit;
    exports.inflateInit2 = inflateInit2;
    exports.inflate = inflate;
    exports.inflateEnd = inflateEnd;
    exports.inflateGetHeader = inflateGetHeader;
    exports.inflateSetDictionary = inflateSetDictionary;
    exports.inflateInfo = 'pako inflate (from Nodeca project)';
    
    /* Not implemented
    exports.inflateCopy = inflateCopy;
    exports.inflateGetDictionary = inflateGetDictionary;
    exports.inflateMark = inflateMark;
    exports.inflatePrime = inflatePrime;
    exports.inflateSync = inflateSync;
    exports.inflateSyncPoint = inflateSyncPoint;
    exports.inflateUndermine = inflateUndermine;
    */
    
    },{"../utils/common":297,"./adler32":298,"./crc32":300,"./inffast":302,"./inftrees":304}],304:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    var utils = require('../utils/common');
    
    var MAXBITS = 15;
    var ENOUGH_LENS = 852;
    var ENOUGH_DISTS = 592;
    //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
    
    var CODES = 0;
    var LENS = 1;
    var DISTS = 2;
    
    var lbase = [ /* Length codes 257..285 base */
      3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
      35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
    ];
    
    var lext = [ /* Length codes 257..285 extra */
      16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
      19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
    ];
    
    var dbase = [ /* Distance codes 0..29 base */
      1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
      257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
      8193, 12289, 16385, 24577, 0, 0
    ];
    
    var dext = [ /* Distance codes 0..29 extra */
      16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
      23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
      28, 28, 29, 29, 64, 64
    ];
    
    module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
    {
      var bits = opts.bits;
          //here = opts.here; /* table entry for duplication */
    
      var len = 0;               /* a code's length in bits */
      var sym = 0;               /* index of code symbols */
      var min = 0, max = 0;          /* minimum and maximum code lengths */
      var root = 0;              /* number of index bits for root table */
      var curr = 0;              /* number of index bits for current table */
      var drop = 0;              /* code bits to drop for sub-table */
      var left = 0;                   /* number of prefix codes available */
      var used = 0;              /* code entries in table used */
      var huff = 0;              /* Huffman code */
      var incr;              /* for incrementing code, index */
      var fill;              /* index for replicating entries */
      var low;               /* low bits for current root entry */
      var mask;              /* mask for low root bits */
      var next;             /* next available space in table */
      var base = null;     /* base value table to use */
      var base_index = 0;
    //  var shoextra;    /* extra bits table to use */
      var end;                    /* use base and extra for symbol > end */
      var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */
      var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */
      var extra = null;
      var extra_index = 0;
    
      var here_bits, here_op, here_val;
    
      /*
       Process a set of code lengths to create a canonical Huffman code.  The
       code lengths are lens[0..codes-1].  Each length corresponds to the
       symbols 0..codes-1.  The Huffman code is generated by first sorting the
       symbols by length from short to long, and retaining the symbol order
       for codes with equal lengths.  Then the code starts with all zero bits
       for the first code of the shortest length, and the codes are integer
       increments for the same length, and zeros are appended as the length
       increases.  For the deflate format, these bits are stored backwards
       from their more natural integer increment ordering, and so when the
       decoding tables are built in the large loop below, the integer codes
       are incremented backwards.
    
       This routine assumes, but does not check, that all of the entries in
       lens[] are in the range 0..MAXBITS.  The caller must assure this.
       1..MAXBITS is interpreted as that code length.  zero means that that
       symbol does not occur in this code.
    
       The codes are sorted by computing a count of codes for each length,
       creating from that a table of starting indices for each length in the
       sorted table, and then entering the symbols in order in the sorted
       table.  The sorted table is work[], with that space being provided by
       the caller.
    
       The length counts are used for other purposes as well, i.e. finding
       the minimum and maximum length codes, determining if there are any
       codes at all, checking for a valid set of lengths, and looking ahead
       at length counts to determine sub-table sizes when building the
       decoding tables.
       */
    
      /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
      for (len = 0; len <= MAXBITS; len++) {
        count[len] = 0;
      }
      for (sym = 0; sym < codes; sym++) {
        count[lens[lens_index + sym]]++;
      }
    
      /* bound code lengths, force root to be within code lengths */
      root = bits;
      for (max = MAXBITS; max >= 1; max--) {
        if (count[max] !== 0) { break; }
      }
      if (root > max) {
        root = max;
      }
      if (max === 0) {                     /* no symbols to code at all */
        //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */
        //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;
        //table.val[opts.table_index++] = 0;   //here.val = (var short)0;
        table[table_index++] = (1 << 24) | (64 << 16) | 0;
    
    
        //table.op[opts.table_index] = 64;
        //table.bits[opts.table_index] = 1;
        //table.val[opts.table_index++] = 0;
        table[table_index++] = (1 << 24) | (64 << 16) | 0;
    
        opts.bits = 1;
        return 0;     /* no symbols, but wait for decoding to report error */
      }
      for (min = 1; min < max; min++) {
        if (count[min] !== 0) { break; }
      }
      if (root < min) {
        root = min;
      }
    
      /* check for an over-subscribed or incomplete set of lengths */
      left = 1;
      for (len = 1; len <= MAXBITS; len++) {
        left <<= 1;
        left -= count[len];
        if (left < 0) {
          return -1;
        }        /* over-subscribed */
      }
      if (left > 0 && (type === CODES || max !== 1)) {
        return -1;                      /* incomplete set */
      }
    
      /* generate offsets into symbol table for each length for sorting */
      offs[1] = 0;
      for (len = 1; len < MAXBITS; len++) {
        offs[len + 1] = offs[len] + count[len];
      }
    
      /* sort symbols by length, by symbol order within each length */
      for (sym = 0; sym < codes; sym++) {
        if (lens[lens_index + sym] !== 0) {
          work[offs[lens[lens_index + sym]]++] = sym;
        }
      }
    
      /*
       Create and fill in decoding tables.  In this loop, the table being
       filled is at next and has curr index bits.  The code being used is huff
       with length len.  That code is converted to an index by dropping drop
       bits off of the bottom.  For codes where len is less than drop + curr,
       those top drop + curr - len bits are incremented through all values to
       fill the table with replicated entries.
    
       root is the number of index bits for the root table.  When len exceeds
       root, sub-tables are created pointed to by the root entry with an index
       of the low root bits of huff.  This is saved in low to check for when a
       new sub-table should be started.  drop is zero when the root table is
       being filled, and drop is root when sub-tables are being filled.
    
       When a new sub-table is needed, it is necessary to look ahead in the
       code lengths to determine what size sub-table is needed.  The length
       counts are used for this, and so count[] is decremented as codes are
       entered in the tables.
    
       used keeps track of how many table entries have been allocated from the
       provided *table space.  It is checked for LENS and DIST tables against
       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
       the initial root table size constants.  See the comments in inftrees.h
       for more information.
    
       sym increments through all symbols, and the loop terminates when
       all codes of length max, i.e. all codes, have been processed.  This
       routine permits incomplete codes, so another loop after this one fills
       in the rest of the decoding tables with invalid code markers.
       */
    
      /* set up for code type */
      // poor man optimization - use if-else instead of switch,
      // to avoid deopts in old v8
      if (type === CODES) {
        base = extra = work;    /* dummy value--not used */
        end = 19;
    
      } else if (type === LENS) {
        base = lbase;
        base_index -= 257;
        extra = lext;
        extra_index -= 257;
        end = 256;
    
      } else {                    /* DISTS */
        base = dbase;
        extra = dext;
        end = -1;
      }
    
      /* initialize opts for loop */
      huff = 0;                   /* starting code */
      sym = 0;                    /* starting code symbol */
      len = min;                  /* starting code length */
      next = table_index;              /* current table to fill in */
      curr = root;                /* current table index bits */
      drop = 0;                   /* current bits to drop from code for index */
      low = -1;                   /* trigger new sub-table when len > root */
      used = 1 << root;          /* use root table entries */
      mask = used - 1;            /* mask for comparing low */
    
      /* check available table space */
      if ((type === LENS && used > ENOUGH_LENS) ||
        (type === DISTS && used > ENOUGH_DISTS)) {
        return 1;
      }
    
      /* process all codes and make table entries */
      for (;;) {
        /* create table entry */
        here_bits = len - drop;
        if (work[sym] < end) {
          here_op = 0;
          here_val = work[sym];
        }
        else if (work[sym] > end) {
          here_op = extra[extra_index + work[sym]];
          here_val = base[base_index + work[sym]];
        }
        else {
          here_op = 32 + 64;         /* end of block */
          here_val = 0;
        }
    
        /* replicate for those indices with low len bits equal to huff */
        incr = 1 << (len - drop);
        fill = 1 << curr;
        min = fill;                 /* save offset to next table */
        do {
          fill -= incr;
          table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
        } while (fill !== 0);
    
        /* backwards increment the len-bit code huff */
        incr = 1 << (len - 1);
        while (huff & incr) {
          incr >>= 1;
        }
        if (incr !== 0) {
          huff &= incr - 1;
          huff += incr;
        } else {
          huff = 0;
        }
    
        /* go to next symbol, update count, len */
        sym++;
        if (--count[len] === 0) {
          if (len === max) { break; }
          len = lens[lens_index + work[sym]];
        }
    
        /* create new sub-table if needed */
        if (len > root && (huff & mask) !== low) {
          /* if first time, transition to sub-tables */
          if (drop === 0) {
            drop = root;
          }
    
          /* increment past last table */
          next += min;            /* here min is 1 << curr */
    
          /* determine length of next table */
          curr = len - drop;
          left = 1 << curr;
          while (curr + drop < max) {
            left -= count[curr + drop];
            if (left <= 0) { break; }
            curr++;
            left <<= 1;
          }
    
          /* check for enough space */
          used += 1 << curr;
          if ((type === LENS && used > ENOUGH_LENS) ||
            (type === DISTS && used > ENOUGH_DISTS)) {
            return 1;
          }
    
          /* point entry in root table to sub-table */
          low = huff & mask;
          /*table.op[low] = curr;
          table.bits[low] = root;
          table.val[low] = next - opts.table_index;*/
          table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
        }
      }
    
      /* fill in remaining table entry if code is incomplete (guaranteed to have
       at most one remaining entry, since if the code is incomplete, the
       maximum code length that was allowed to get this far is one bit) */
      if (huff !== 0) {
        //table.op[next + huff] = 64;            /* invalid code marker */
        //table.bits[next + huff] = len - drop;
        //table.val[next + huff] = 0;
        table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
      }
    
      /* set return parameters */
      //opts.table_index += used;
      opts.bits = root;
      return 0;
    };
    
    },{"../utils/common":297}],305:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    module.exports = {
      2:      'need dictionary',     /* Z_NEED_DICT       2  */
      1:      'stream end',          /* Z_STREAM_END      1  */
      0:      '',                    /* Z_OK              0  */
      '-1':   'file error',          /* Z_ERRNO         (-1) */
      '-2':   'stream error',        /* Z_STREAM_ERROR  (-2) */
      '-3':   'data error',          /* Z_DATA_ERROR    (-3) */
      '-4':   'insufficient memory', /* Z_MEM_ERROR     (-4) */
      '-5':   'buffer error',        /* Z_BUF_ERROR     (-5) */
      '-6':   'incompatible version' /* Z_VERSION_ERROR (-6) */
    };
    
    },{}],306:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    /* eslint-disable space-unary-ops */
    
    var utils = require('../utils/common');
    
    /* Public constants ==========================================================*/
    /* ===========================================================================*/
    
    
    //var Z_FILTERED          = 1;
    //var Z_HUFFMAN_ONLY      = 2;
    //var Z_RLE               = 3;
    var Z_FIXED               = 4;
    //var Z_DEFAULT_STRATEGY  = 0;
    
    /* Possible values of the data_type field (though see inflate()) */
    var Z_BINARY              = 0;
    var Z_TEXT                = 1;
    //var Z_ASCII             = 1; // = Z_TEXT
    var Z_UNKNOWN             = 2;
    
    /*============================================================================*/
    
    
    function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
    
    // From zutil.h
    
    var STORED_BLOCK = 0;
    var STATIC_TREES = 1;
    var DYN_TREES    = 2;
    /* The three kinds of block type */
    
    var MIN_MATCH    = 3;
    var MAX_MATCH    = 258;
    /* The minimum and maximum match lengths */
    
    // From deflate.h
    /* ===========================================================================
     * Internal compression state.
     */
    
    var LENGTH_CODES  = 29;
    /* number of length codes, not counting the special END_BLOCK code */
    
    var LITERALS      = 256;
    /* number of literal bytes 0..255 */
    
    var L_CODES       = LITERALS + 1 + LENGTH_CODES;
    /* number of Literal or Length codes, including the END_BLOCK code */
    
    var D_CODES       = 30;
    /* number of distance codes */
    
    var BL_CODES      = 19;
    /* number of codes used to transfer the bit lengths */
    
    var HEAP_SIZE     = 2 * L_CODES + 1;
    /* maximum heap size */
    
    var MAX_BITS      = 15;
    /* All codes must not exceed MAX_BITS bits */
    
    var Buf_size      = 16;
    /* size of bit buffer in bi_buf */
    
    
    /* ===========================================================================
     * Constants
     */
    
    var MAX_BL_BITS = 7;
    /* Bit length codes must not exceed MAX_BL_BITS bits */
    
    var END_BLOCK   = 256;
    /* end of block literal code */
    
    var REP_3_6     = 16;
    /* repeat previous bit length 3-6 times (2 bits of repeat count) */
    
    var REPZ_3_10   = 17;
    /* repeat a zero length 3-10 times  (3 bits of repeat count) */
    
    var REPZ_11_138 = 18;
    /* repeat a zero length 11-138 times  (7 bits of repeat count) */
    
    /* eslint-disable comma-spacing,array-bracket-spacing */
    var extra_lbits =   /* extra bits for each length code */
      [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
    
    var extra_dbits =   /* extra bits for each distance code */
      [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
    
    var extra_blbits =  /* extra bits for each bit length code */
      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
    
    var bl_order =
      [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
    /* eslint-enable comma-spacing,array-bracket-spacing */
    
    /* The lengths of the bit length codes are sent in order of decreasing
     * probability, to avoid transmitting the lengths for unused bit length codes.
     */
    
    /* ===========================================================================
     * Local data. These are initialized only once.
     */
    
    // We pre-fill arrays with 0 to avoid uninitialized gaps
    
    var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
    
    // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
    var static_ltree  = new Array((L_CODES + 2) * 2);
    zero(static_ltree);
    /* The static literal tree. Since the bit lengths are imposed, there is no
     * need for the L_CODES extra codes used during heap construction. However
     * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
     * below).
     */
    
    var static_dtree  = new Array(D_CODES * 2);
    zero(static_dtree);
    /* The static distance tree. (Actually a trivial tree since all codes use
     * 5 bits.)
     */
    
    var _dist_code    = new Array(DIST_CODE_LEN);
    zero(_dist_code);
    /* Distance codes. The first 256 values correspond to the distances
     * 3 .. 258, the last 256 values correspond to the top 8 bits of
     * the 15 bit distances.
     */
    
    var _length_code  = new Array(MAX_MATCH - MIN_MATCH + 1);
    zero(_length_code);
    /* length code for each normalized match length (0 == MIN_MATCH) */
    
    var base_length   = new Array(LENGTH_CODES);
    zero(base_length);
    /* First normalized length for each code (0 = MIN_MATCH) */
    
    var base_dist     = new Array(D_CODES);
    zero(base_dist);
    /* First normalized distance for each code (0 = distance of 1) */
    
    
    function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
    
      this.static_tree  = static_tree;  /* static tree or NULL */
      this.extra_bits   = extra_bits;   /* extra bits for each code or NULL */
      this.extra_base   = extra_base;   /* base index for extra_bits */
      this.elems        = elems;        /* max number of elements in the tree */
      this.max_length   = max_length;   /* max bit length for the codes */
    
      // show if `static_tree` has data or dummy - needed for monomorphic objects
      this.has_stree    = static_tree && static_tree.length;
    }
    
    
    var static_l_desc;
    var static_d_desc;
    var static_bl_desc;
    
    
    function TreeDesc(dyn_tree, stat_desc) {
      this.dyn_tree = dyn_tree;     /* the dynamic tree */
      this.max_code = 0;            /* largest code with non zero frequency */
      this.stat_desc = stat_desc;   /* the corresponding static tree */
    }
    
    
    
    function d_code(dist) {
      return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
    }
    
    
    /* ===========================================================================
     * Output a short LSB first on the stream.
     * IN assertion: there is enough room in pendingBuf.
     */
    function put_short(s, w) {
    //    put_byte(s, (uch)((w) & 0xff));
    //    put_byte(s, (uch)((ush)(w) >> 8));
      s.pending_buf[s.pending++] = (w) & 0xff;
      s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
    }
    
    
    /* ===========================================================================
     * Send a value on a given number of bits.
     * IN assertion: length <= 16 and value fits in length bits.
     */
    function send_bits(s, value, length) {
      if (s.bi_valid > (Buf_size - length)) {
        s.bi_buf |= (value << s.bi_valid) & 0xffff;
        put_short(s, s.bi_buf);
        s.bi_buf = value >> (Buf_size - s.bi_valid);
        s.bi_valid += length - Buf_size;
      } else {
        s.bi_buf |= (value << s.bi_valid) & 0xffff;
        s.bi_valid += length;
      }
    }
    
    
    function send_code(s, c, tree) {
      send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
    }
    
    
    /* ===========================================================================
     * Reverse the first len bits of a code, using straightforward code (a faster
     * method would use a table)
     * IN assertion: 1 <= len <= 15
     */
    function bi_reverse(code, len) {
      var res = 0;
      do {
        res |= code & 1;
        code >>>= 1;
        res <<= 1;
      } while (--len > 0);
      return res >>> 1;
    }
    
    
    /* ===========================================================================
     * Flush the bit buffer, keeping at most 7 bits in it.
     */
    function bi_flush(s) {
      if (s.bi_valid === 16) {
        put_short(s, s.bi_buf);
        s.bi_buf = 0;
        s.bi_valid = 0;
    
      } else if (s.bi_valid >= 8) {
        s.pending_buf[s.pending++] = s.bi_buf & 0xff;
        s.bi_buf >>= 8;
        s.bi_valid -= 8;
      }
    }
    
    
    /* ===========================================================================
     * Compute the optimal bit lengths for a tree and update the total bit length
     * for the current block.
     * IN assertion: the fields freq and dad are set, heap[heap_max] and
     *    above are the tree nodes sorted by increasing frequency.
     * OUT assertions: the field len is set to the optimal bit length, the
     *     array bl_count contains the frequencies for each bit length.
     *     The length opt_len is updated; static_len is also updated if stree is
     *     not null.
     */
    function gen_bitlen(s, desc)
    //    deflate_state *s;
    //    tree_desc *desc;    /* the tree descriptor */
    {
      var tree            = desc.dyn_tree;
      var max_code        = desc.max_code;
      var stree           = desc.stat_desc.static_tree;
      var has_stree       = desc.stat_desc.has_stree;
      var extra           = desc.stat_desc.extra_bits;
      var base            = desc.stat_desc.extra_base;
      var max_length      = desc.stat_desc.max_length;
      var h;              /* heap index */
      var n, m;           /* iterate over the tree elements */
      var bits;           /* bit length */
      var xbits;          /* extra bits */
      var f;              /* frequency */
      var overflow = 0;   /* number of elements with bit length too large */
    
      for (bits = 0; bits <= MAX_BITS; bits++) {
        s.bl_count[bits] = 0;
      }
    
      /* In a first pass, compute the optimal bit lengths (which may
       * overflow in the case of the bit length tree).
       */
      tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
    
      for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
        n = s.heap[h];
        bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
        if (bits > max_length) {
          bits = max_length;
          overflow++;
        }
        tree[n * 2 + 1]/*.Len*/ = bits;
        /* We overwrite tree[n].Dad which is no longer needed */
    
        if (n > max_code) { continue; } /* not a leaf node */
    
        s.bl_count[bits]++;
        xbits = 0;
        if (n >= base) {
          xbits = extra[n - base];
        }
        f = tree[n * 2]/*.Freq*/;
        s.opt_len += f * (bits + xbits);
        if (has_stree) {
          s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
        }
      }
      if (overflow === 0) { return; }
    
      // Trace((stderr,"\nbit length overflow\n"));
      /* This happens for example on obj2 and pic of the Calgary corpus */
    
      /* Find the first bit length which could increase: */
      do {
        bits = max_length - 1;
        while (s.bl_count[bits] === 0) { bits--; }
        s.bl_count[bits]--;      /* move one leaf down the tree */
        s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
        s.bl_count[max_length]--;
        /* The brother of the overflow item also moves one step up,
         * but this does not affect bl_count[max_length]
         */
        overflow -= 2;
      } while (overflow > 0);
    
      /* Now recompute all bit lengths, scanning in increasing frequency.
       * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
       * lengths instead of fixing only the wrong ones. This idea is taken
       * from 'ar' written by Haruhiko Okumura.)
       */
      for (bits = max_length; bits !== 0; bits--) {
        n = s.bl_count[bits];
        while (n !== 0) {
          m = s.heap[--h];
          if (m > max_code) { continue; }
          if (tree[m * 2 + 1]/*.Len*/ !== bits) {
            // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
            s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
            tree[m * 2 + 1]/*.Len*/ = bits;
          }
          n--;
        }
      }
    }
    
    
    /* ===========================================================================
     * Generate the codes for a given tree and bit counts (which need not be
     * optimal).
     * IN assertion: the array bl_count contains the bit length statistics for
     * the given tree and the field len is set for all tree elements.
     * OUT assertion: the field code is set for all tree elements of non
     *     zero code length.
     */
    function gen_codes(tree, max_code, bl_count)
    //    ct_data *tree;             /* the tree to decorate */
    //    int max_code;              /* largest code with non zero frequency */
    //    ushf *bl_count;            /* number of codes at each bit length */
    {
      var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
      var code = 0;              /* running code value */
      var bits;                  /* bit index */
      var n;                     /* code index */
    
      /* The distribution counts are first used to generate the code values
       * without bit reversal.
       */
      for (bits = 1; bits <= MAX_BITS; bits++) {
        next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
      }
      /* Check that the bit counts in bl_count are consistent. The last code
       * must be all ones.
       */
      //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
      //        "inconsistent bit counts");
      //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
    
      for (n = 0;  n <= max_code; n++) {
        var len = tree[n * 2 + 1]/*.Len*/;
        if (len === 0) { continue; }
        /* Now reverse the bits */
        tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
    
        //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
        //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
      }
    }
    
    
    /* ===========================================================================
     * Initialize the various 'constant' tables.
     */
    function tr_static_init() {
      var n;        /* iterates over tree elements */
      var bits;     /* bit counter */
      var length;   /* length value */
      var code;     /* code value */
      var dist;     /* distance index */
      var bl_count = new Array(MAX_BITS + 1);
      /* number of codes at each bit length for an optimal tree */
    
      // do check in _tr_init()
      //if (static_init_done) return;
    
      /* For some embedded targets, global variables are not initialized: */
    /*#ifdef NO_INIT_GLOBAL_POINTERS
      static_l_desc.static_tree = static_ltree;
      static_l_desc.extra_bits = extra_lbits;
      static_d_desc.static_tree = static_dtree;
      static_d_desc.extra_bits = extra_dbits;
      static_bl_desc.extra_bits = extra_blbits;
    #endif*/
    
      /* Initialize the mapping length (0..255) -> length code (0..28) */
      length = 0;
      for (code = 0; code < LENGTH_CODES - 1; code++) {
        base_length[code] = length;
        for (n = 0; n < (1 << extra_lbits[code]); n++) {
          _length_code[length++] = code;
        }
      }
      //Assert (length == 256, "tr_static_init: length != 256");
      /* Note that the length 255 (match length 258) can be represented
       * in two different ways: code 284 + 5 bits or code 285, so we
       * overwrite length_code[255] to use the best encoding:
       */
      _length_code[length - 1] = code;
    
      /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
      dist = 0;
      for (code = 0; code < 16; code++) {
        base_dist[code] = dist;
        for (n = 0; n < (1 << extra_dbits[code]); n++) {
          _dist_code[dist++] = code;
        }
      }
      //Assert (dist == 256, "tr_static_init: dist != 256");
      dist >>= 7; /* from now on, all distances are divided by 128 */
      for (; code < D_CODES; code++) {
        base_dist[code] = dist << 7;
        for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
          _dist_code[256 + dist++] = code;
        }
      }
      //Assert (dist == 256, "tr_static_init: 256+dist != 512");
    
      /* Construct the codes of the static literal tree */
      for (bits = 0; bits <= MAX_BITS; bits++) {
        bl_count[bits] = 0;
      }
    
      n = 0;
      while (n <= 143) {
        static_ltree[n * 2 + 1]/*.Len*/ = 8;
        n++;
        bl_count[8]++;
      }
      while (n <= 255) {
        static_ltree[n * 2 + 1]/*.Len*/ = 9;
        n++;
        bl_count[9]++;
      }
      while (n <= 279) {
        static_ltree[n * 2 + 1]/*.Len*/ = 7;
        n++;
        bl_count[7]++;
      }
      while (n <= 287) {
        static_ltree[n * 2 + 1]/*.Len*/ = 8;
        n++;
        bl_count[8]++;
      }
      /* Codes 286 and 287 do not exist, but we must include them in the
       * tree construction to get a canonical Huffman tree (longest code
       * all ones)
       */
      gen_codes(static_ltree, L_CODES + 1, bl_count);
    
      /* The static distance tree is trivial: */
      for (n = 0; n < D_CODES; n++) {
        static_dtree[n * 2 + 1]/*.Len*/ = 5;
        static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
      }
    
      // Now data ready and we can init static trees
      static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
      static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS);
      static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0,         BL_CODES, MAX_BL_BITS);
    
      //static_init_done = true;
    }
    
    
    /* ===========================================================================
     * Initialize a new block.
     */
    function init_block(s) {
      var n; /* iterates over tree elements */
    
      /* Initialize the trees. */
      for (n = 0; n < L_CODES;  n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }
      for (n = 0; n < D_CODES;  n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }
      for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }
    
      s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
      s.opt_len = s.static_len = 0;
      s.last_lit = s.matches = 0;
    }
    
    
    /* ===========================================================================
     * Flush the bit buffer and align the output on a byte boundary
     */
    function bi_windup(s)
    {
      if (s.bi_valid > 8) {
        put_short(s, s.bi_buf);
      } else if (s.bi_valid > 0) {
        //put_byte(s, (Byte)s->bi_buf);
        s.pending_buf[s.pending++] = s.bi_buf;
      }
      s.bi_buf = 0;
      s.bi_valid = 0;
    }
    
    /* ===========================================================================
     * Copy a stored block, storing first the length and its
     * one's complement if requested.
     */
    function copy_block(s, buf, len, header)
    //DeflateState *s;
    //charf    *buf;    /* the input data */
    //unsigned len;     /* its length */
    //int      header;  /* true if block header must be written */
    {
      bi_windup(s);        /* align on byte boundary */
    
      if (header) {
        put_short(s, len);
        put_short(s, ~len);
      }
    //  while (len--) {
    //    put_byte(s, *buf++);
    //  }
      utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
      s.pending += len;
    }
    
    /* ===========================================================================
     * Compares to subtrees, using the tree depth as tie breaker when
     * the subtrees have equal frequency. This minimizes the worst case length.
     */
    function smaller(tree, n, m, depth) {
      var _n2 = n * 2;
      var _m2 = m * 2;
      return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
             (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));
    }
    
    /* ===========================================================================
     * Restore the heap property by moving down the tree starting at node k,
     * exchanging a node with the smallest of its two sons if necessary, stopping
     * when the heap property is re-established (each father smaller than its
     * two sons).
     */
    function pqdownheap(s, tree, k)
    //    deflate_state *s;
    //    ct_data *tree;  /* the tree to restore */
    //    int k;               /* node to move down */
    {
      var v = s.heap[k];
      var j = k << 1;  /* left son of k */
      while (j <= s.heap_len) {
        /* Set j to the smallest of the two sons: */
        if (j < s.heap_len &&
          smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
          j++;
        }
        /* Exit if v is smaller than both sons */
        if (smaller(tree, v, s.heap[j], s.depth)) { break; }
    
        /* Exchange v with the smallest son */
        s.heap[k] = s.heap[j];
        k = j;
    
        /* And continue down the tree, setting j to the left son of k */
        j <<= 1;
      }
      s.heap[k] = v;
    }
    
    
    // inlined manually
    // var SMALLEST = 1;
    
    /* ===========================================================================
     * Send the block data compressed using the given Huffman trees
     */
    function compress_block(s, ltree, dtree)
    //    deflate_state *s;
    //    const ct_data *ltree; /* literal tree */
    //    const ct_data *dtree; /* distance tree */
    {
      var dist;           /* distance of matched string */
      var lc;             /* match length or unmatched char (if dist == 0) */
      var lx = 0;         /* running index in l_buf */
      var code;           /* the code to send */
      var extra;          /* number of extra bits to send */
    
      if (s.last_lit !== 0) {
        do {
          dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
          lc = s.pending_buf[s.l_buf + lx];
          lx++;
    
          if (dist === 0) {
            send_code(s, lc, ltree); /* send a literal byte */
            //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
          } else {
            /* Here, lc is the match length - MIN_MATCH */
            code = _length_code[lc];
            send_code(s, code + LITERALS + 1, ltree); /* send the length code */
            extra = extra_lbits[code];
            if (extra !== 0) {
              lc -= base_length[code];
              send_bits(s, lc, extra);       /* send the extra length bits */
            }
            dist--; /* dist is now the match distance - 1 */
            code = d_code(dist);
            //Assert (code < D_CODES, "bad d_code");
    
            send_code(s, code, dtree);       /* send the distance code */
            extra = extra_dbits[code];
            if (extra !== 0) {
              dist -= base_dist[code];
              send_bits(s, dist, extra);   /* send the extra distance bits */
            }
          } /* literal or match pair ? */
    
          /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
          //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
          //       "pendingBuf overflow");
    
        } while (lx < s.last_lit);
      }
    
      send_code(s, END_BLOCK, ltree);
    }
    
    
    /* ===========================================================================
     * Construct one Huffman tree and assigns the code bit strings and lengths.
     * Update the total bit length for the current block.
     * IN assertion: the field freq is set for all tree elements.
     * OUT assertions: the fields len and code are set to the optimal bit length
     *     and corresponding code. The length opt_len is updated; static_len is
     *     also updated if stree is not null. The field max_code is set.
     */
    function build_tree(s, desc)
    //    deflate_state *s;
    //    tree_desc *desc; /* the tree descriptor */
    {
      var tree     = desc.dyn_tree;
      var stree    = desc.stat_desc.static_tree;
      var has_stree = desc.stat_desc.has_stree;
      var elems    = desc.stat_desc.elems;
      var n, m;          /* iterate over heap elements */
      var max_code = -1; /* largest code with non zero frequency */
      var node;          /* new node being created */
    
      /* Construct the initial heap, with least frequent element in
       * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
       * heap[0] is not used.
       */
      s.heap_len = 0;
      s.heap_max = HEAP_SIZE;
    
      for (n = 0; n < elems; n++) {
        if (tree[n * 2]/*.Freq*/ !== 0) {
          s.heap[++s.heap_len] = max_code = n;
          s.depth[n] = 0;
    
        } else {
          tree[n * 2 + 1]/*.Len*/ = 0;
        }
      }
    
      /* The pkzip format requires that at least one distance code exists,
       * and that at least one bit should be sent even if there is only one
       * possible code. So to avoid special checks later on we force at least
       * two codes of non zero frequency.
       */
      while (s.heap_len < 2) {
        node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
        tree[node * 2]/*.Freq*/ = 1;
        s.depth[node] = 0;
        s.opt_len--;
    
        if (has_stree) {
          s.static_len -= stree[node * 2 + 1]/*.Len*/;
        }
        /* node is 0 or 1 so it does not have extra bits */
      }
      desc.max_code = max_code;
    
      /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
       * establish sub-heaps of increasing lengths:
       */
      for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }
    
      /* Construct the Huffman tree by repeatedly combining the least two
       * frequent nodes.
       */
      node = elems;              /* next internal node of the tree */
      do {
        //pqremove(s, tree, n);  /* n = node of least frequency */
        /*** pqremove ***/
        n = s.heap[1/*SMALLEST*/];
        s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
        pqdownheap(s, tree, 1/*SMALLEST*/);
        /***/
    
        m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
    
        s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
        s.heap[--s.heap_max] = m;
    
        /* Create a new node father of n and m */
        tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
        s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
        tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
    
        /* and insert the new node in the heap */
        s.heap[1/*SMALLEST*/] = node++;
        pqdownheap(s, tree, 1/*SMALLEST*/);
    
      } while (s.heap_len >= 2);
    
      s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
    
      /* At this point, the fields freq and dad are set. We can now
       * generate the bit lengths.
       */
      gen_bitlen(s, desc);
    
      /* The field len is now set, we can generate the bit codes */
      gen_codes(tree, max_code, s.bl_count);
    }
    
    
    /* ===========================================================================
     * Scan a literal or distance tree to determine the frequencies of the codes
     * in the bit length tree.
     */
    function scan_tree(s, tree, max_code)
    //    deflate_state *s;
    //    ct_data *tree;   /* the tree to be scanned */
    //    int max_code;    /* and its largest code of non zero frequency */
    {
      var n;                     /* iterates over all tree elements */
      var prevlen = -1;          /* last emitted length */
      var curlen;                /* length of current code */
    
      var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
    
      var count = 0;             /* repeat count of the current code */
      var max_count = 7;         /* max repeat count */
      var min_count = 4;         /* min repeat count */
    
      if (nextlen === 0) {
        max_count = 138;
        min_count = 3;
      }
      tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
    
      for (n = 0; n <= max_code; n++) {
        curlen = nextlen;
        nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
    
        if (++count < max_count && curlen === nextlen) {
          continue;
    
        } else if (count < min_count) {
          s.bl_tree[curlen * 2]/*.Freq*/ += count;
    
        } else if (curlen !== 0) {
    
          if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }
          s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
    
        } else if (count <= 10) {
          s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
    
        } else {
          s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
        }
    
        count = 0;
        prevlen = curlen;
    
        if (nextlen === 0) {
          max_count = 138;
          min_count = 3;
    
        } else if (curlen === nextlen) {
          max_count = 6;
          min_count = 3;
    
        } else {
          max_count = 7;
          min_count = 4;
        }
      }
    }
    
    
    /* ===========================================================================
     * Send a literal or distance tree in compressed form, using the codes in
     * bl_tree.
     */
    function send_tree(s, tree, max_code)
    //    deflate_state *s;
    //    ct_data *tree; /* the tree to be scanned */
    //    int max_code;       /* and its largest code of non zero frequency */
    {
      var n;                     /* iterates over all tree elements */
      var prevlen = -1;          /* last emitted length */
      var curlen;                /* length of current code */
    
      var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
    
      var count = 0;             /* repeat count of the current code */
      var max_count = 7;         /* max repeat count */
      var min_count = 4;         /* min repeat count */
    
      /* tree[max_code+1].Len = -1; */  /* guard already set */
      if (nextlen === 0) {
        max_count = 138;
        min_count = 3;
      }
    
      for (n = 0; n <= max_code; n++) {
        curlen = nextlen;
        nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
    
        if (++count < max_count && curlen === nextlen) {
          continue;
    
        } else if (count < min_count) {
          do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
    
        } else if (curlen !== 0) {
          if (curlen !== prevlen) {
            send_code(s, curlen, s.bl_tree);
            count--;
          }
          //Assert(count >= 3 && count <= 6, " 3_6?");
          send_code(s, REP_3_6, s.bl_tree);
          send_bits(s, count - 3, 2);
    
        } else if (count <= 10) {
          send_code(s, REPZ_3_10, s.bl_tree);
          send_bits(s, count - 3, 3);
    
        } else {
          send_code(s, REPZ_11_138, s.bl_tree);
          send_bits(s, count - 11, 7);
        }
    
        count = 0;
        prevlen = curlen;
        if (nextlen === 0) {
          max_count = 138;
          min_count = 3;
    
        } else if (curlen === nextlen) {
          max_count = 6;
          min_count = 3;
    
        } else {
          max_count = 7;
          min_count = 4;
        }
      }
    }
    
    
    /* ===========================================================================
     * Construct the Huffman tree for the bit lengths and return the index in
     * bl_order of the last bit length code to send.
     */
    function build_bl_tree(s) {
      var max_blindex;  /* index of last bit length code of non zero freq */
    
      /* Determine the bit length frequencies for literal and distance trees */
      scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
      scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
    
      /* Build the bit length tree: */
      build_tree(s, s.bl_desc);
      /* opt_len now includes the length of the tree representations, except
       * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
       */
    
      /* Determine the number of bit length codes to send. The pkzip format
       * requires that at least 4 bit length codes be sent. (appnote.txt says
       * 3 but the actual value used is 4.)
       */
      for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
        if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
          break;
        }
      }
      /* Update opt_len to include the bit length tree and counts */
      s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
      //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
      //        s->opt_len, s->static_len));
    
      return max_blindex;
    }
    
    
    /* ===========================================================================
     * Send the header for a block using dynamic Huffman trees: the counts, the
     * lengths of the bit length codes, the literal tree and the distance tree.
     * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
     */
    function send_all_trees(s, lcodes, dcodes, blcodes)
    //    deflate_state *s;
    //    int lcodes, dcodes, blcodes; /* number of codes for each tree */
    {
      var rank;                    /* index in bl_order */
    
      //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
      //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
      //        "too many codes");
      //Tracev((stderr, "\nbl counts: "));
      send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
      send_bits(s, dcodes - 1,   5);
      send_bits(s, blcodes - 4,  4); /* not -3 as stated in appnote.txt */
      for (rank = 0; rank < blcodes; rank++) {
        //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
        send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
      }
      //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
    
      send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
      //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
    
      send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
      //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
    }
    
    
    /* ===========================================================================
     * Check if the data type is TEXT or BINARY, using the following algorithm:
     * - TEXT if the two conditions below are satisfied:
     *    a) There are no non-portable control characters belonging to the
     *       "black list" (0..6, 14..25, 28..31).
     *    b) There is at least one printable character belonging to the
     *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
     * - BINARY otherwise.
     * - The following partially-portable control characters form a
     *   "gray list" that is ignored in this detection algorithm:
     *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
     * IN assertion: the fields Freq of dyn_ltree are set.
     */
    function detect_data_type(s) {
      /* black_mask is the bit mask of black-listed bytes
       * set bits 0..6, 14..25, and 28..31
       * 0xf3ffc07f = binary 11110011111111111100000001111111
       */
      var black_mask = 0xf3ffc07f;
      var n;
    
      /* Check for non-textual ("black-listed") bytes. */
      for (n = 0; n <= 31; n++, black_mask >>>= 1) {
        if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {
          return Z_BINARY;
        }
      }
    
      /* Check for textual ("white-listed") bytes. */
      if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
          s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
        return Z_TEXT;
      }
      for (n = 32; n < LITERALS; n++) {
        if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
          return Z_TEXT;
        }
      }
    
      /* There are no "black-listed" or "white-listed" bytes:
       * this stream either is empty or has tolerated ("gray-listed") bytes only.
       */
      return Z_BINARY;
    }
    
    
    var static_init_done = false;
    
    /* ===========================================================================
     * Initialize the tree data structures for a new zlib stream.
     */
    function _tr_init(s)
    {
    
      if (!static_init_done) {
        tr_static_init();
        static_init_done = true;
      }
    
      s.l_desc  = new TreeDesc(s.dyn_ltree, static_l_desc);
      s.d_desc  = new TreeDesc(s.dyn_dtree, static_d_desc);
      s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
    
      s.bi_buf = 0;
      s.bi_valid = 0;
    
      /* Initialize the first block of the first file: */
      init_block(s);
    }
    
    
    /* ===========================================================================
     * Send a stored block
     */
    function _tr_stored_block(s, buf, stored_len, last)
    //DeflateState *s;
    //charf *buf;       /* input block */
    //ulg stored_len;   /* length of input block */
    //int last;         /* one if this is the last block for a file */
    {
      send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);    /* send block type */
      copy_block(s, buf, stored_len, true); /* with header */
    }
    
    
    /* ===========================================================================
     * Send one empty static block to give enough lookahead for inflate.
     * This takes 10 bits, of which 7 may remain in the bit buffer.
     */
    function _tr_align(s) {
      send_bits(s, STATIC_TREES << 1, 3);
      send_code(s, END_BLOCK, static_ltree);
      bi_flush(s);
    }
    
    
    /* ===========================================================================
     * Determine the best encoding for the current block: dynamic trees, static
     * trees or store, and output the encoded block to the zip file.
     */
    function _tr_flush_block(s, buf, stored_len, last)
    //DeflateState *s;
    //charf *buf;       /* input block, or NULL if too old */
    //ulg stored_len;   /* length of input block */
    //int last;         /* one if this is the last block for a file */
    {
      var opt_lenb, static_lenb;  /* opt_len and static_len in bytes */
      var max_blindex = 0;        /* index of last bit length code of non zero freq */
    
      /* Build the Huffman trees unless a stored block is forced */
      if (s.level > 0) {
    
        /* Check if the file is binary or text */
        if (s.strm.data_type === Z_UNKNOWN) {
          s.strm.data_type = detect_data_type(s);
        }
    
        /* Construct the literal and distance trees */
        build_tree(s, s.l_desc);
        // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
        //        s->static_len));
    
        build_tree(s, s.d_desc);
        // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
        //        s->static_len));
        /* At this point, opt_len and static_len are the total bit lengths of
         * the compressed block data, excluding the tree representations.
         */
    
        /* Build the bit length tree for the above two trees, and get the index
         * in bl_order of the last bit length code to send.
         */
        max_blindex = build_bl_tree(s);
    
        /* Determine the best encoding. Compute the block lengths in bytes. */
        opt_lenb = (s.opt_len + 3 + 7) >>> 3;
        static_lenb = (s.static_len + 3 + 7) >>> 3;
    
        // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
        //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
        //        s->last_lit));
    
        if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
    
      } else {
        // Assert(buf != (char*)0, "lost buf");
        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
      }
    
      if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
        /* 4: two words for the lengths */
    
        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
         * Otherwise we can't have processed more than WSIZE input bytes since
         * the last block flush, because compression would have been
         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
         * transform a block into a stored block.
         */
        _tr_stored_block(s, buf, stored_len, last);
    
      } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
    
        send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
        compress_block(s, static_ltree, static_dtree);
    
      } else {
        send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
        send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
        compress_block(s, s.dyn_ltree, s.dyn_dtree);
      }
      // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
      /* The above check is made mod 2^32, for files larger than 512 MB
       * and uLong implemented on 32 bits.
       */
      init_block(s);
    
      if (last) {
        bi_windup(s);
      }
      // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
      //       s->compressed_len-7*last));
    }
    
    /* ===========================================================================
     * Save the match info and tally the frequency counts. Return true if
     * the current block must be flushed.
     */
    function _tr_tally(s, dist, lc)
    //    deflate_state *s;
    //    unsigned dist;  /* distance of matched string */
    //    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
    {
      //var out_length, in_length, dcode;
    
      s.pending_buf[s.d_buf + s.last_lit * 2]     = (dist >>> 8) & 0xff;
      s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
    
      s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
      s.last_lit++;
    
      if (dist === 0) {
        /* lc is the unmatched char */
        s.dyn_ltree[lc * 2]/*.Freq*/++;
      } else {
        s.matches++;
        /* Here, lc is the match length - MIN_MATCH */
        dist--;             /* dist = match distance - 1 */
        //Assert((ush)dist < (ush)MAX_DIST(s) &&
        //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
        //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
    
        s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
        s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
      }
    
    // (!) This block is disabled in zlib defaults,
    // don't enable it for binary compatibility
    
    //#ifdef TRUNCATE_BLOCK
    //  /* Try to guess if it is profitable to stop the current block here */
    //  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
    //    /* Compute an upper bound for the compressed length */
    //    out_length = s.last_lit*8;
    //    in_length = s.strstart - s.block_start;
    //
    //    for (dcode = 0; dcode < D_CODES; dcode++) {
    //      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
    //    }
    //    out_length >>>= 3;
    //    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
    //    //       s->last_lit, in_length, out_length,
    //    //       100L - out_length*100L/in_length));
    //    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
    //      return true;
    //    }
    //  }
    //#endif
    
      return (s.last_lit === s.lit_bufsize - 1);
      /* We avoid equality with lit_bufsize because of wraparound at 64K
       * on 16 bit machines and because stored blocks are restricted to
       * 64K-1 bytes.
       */
    }
    
    exports._tr_init  = _tr_init;
    exports._tr_stored_block = _tr_stored_block;
    exports._tr_flush_block  = _tr_flush_block;
    exports._tr_tally = _tr_tally;
    exports._tr_align = _tr_align;
    
    },{"../utils/common":297}],307:[function(require,module,exports){
    'use strict';
    
    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
    //
    // This software is provided 'as-is', without any express or implied
    // warranty. In no event will the authors be held liable for any damages
    // arising from the use of this software.
    //
    // Permission is granted to anyone to use this software for any purpose,
    // including commercial applications, and to alter it and redistribute it
    // freely, subject to the following restrictions:
    //
    // 1. The origin of this software must not be misrepresented; you must not
    //   claim that you wrote the original software. If you use this software
    //   in a product, an acknowledgment in the product documentation would be
    //   appreciated but is not required.
    // 2. Altered source versions must be plainly marked as such, and must not be
    //   misrepresented as being the original software.
    // 3. This notice may not be removed or altered from any source distribution.
    
    function ZStream() {
      /* next input byte */
      this.input = null; // JS specific, because we have no pointers
      this.next_in = 0;
      /* number of bytes available at input */
      this.avail_in = 0;
      /* total number of input bytes read so far */
      this.total_in = 0;
      /* next output byte should be put there */
      this.output = null; // JS specific, because we have no pointers
      this.next_out = 0;
      /* remaining free space at output */
      this.avail_out = 0;
      /* total number of bytes output so far */
      this.total_out = 0;
      /* last error message, NULL if no error */
      this.msg = ''/*Z_NULL*/;
      /* not visible by applications */
      this.state = null;
      /* best guess about the data type: binary or text */
      this.data_type = 2/*Z_UNKNOWN*/;
      /* adler32 value of the uncompressed data */
      this.adler = 0;
    }
    
    module.exports = ZStream;
    
    },{}],308:[function(require,module,exports){
    module.exports={"2.16.840.1.101.3.4.1.1": "aes-128-ecb",
    "2.16.840.1.101.3.4.1.2": "aes-128-cbc",
    "2.16.840.1.101.3.4.1.3": "aes-128-ofb",
    "2.16.840.1.101.3.4.1.4": "aes-128-cfb",
    "2.16.840.1.101.3.4.1.21": "aes-192-ecb",
    "2.16.840.1.101.3.4.1.22": "aes-192-cbc",
    "2.16.840.1.101.3.4.1.23": "aes-192-ofb",
    "2.16.840.1.101.3.4.1.24": "aes-192-cfb",
    "2.16.840.1.101.3.4.1.41": "aes-256-ecb",
    "2.16.840.1.101.3.4.1.42": "aes-256-cbc",
    "2.16.840.1.101.3.4.1.43": "aes-256-ofb",
    "2.16.840.1.101.3.4.1.44": "aes-256-cfb"
    }
    },{}],309:[function(require,module,exports){
    // from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js
    // Fedor, you are amazing.
    'use strict'
    
    var asn1 = require('asn1.js')
    
    exports.certificate = require('./certificate')
    
    var RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
      this.seq().obj(
        this.key('version').int(),
        this.key('modulus').int(),
        this.key('publicExponent').int(),
        this.key('privateExponent').int(),
        this.key('prime1').int(),
        this.key('prime2').int(),
        this.key('exponent1').int(),
        this.key('exponent2').int(),
        this.key('coefficient').int()
      )
    })
    exports.RSAPrivateKey = RSAPrivateKey
    
    var RSAPublicKey = asn1.define('RSAPublicKey', function () {
      this.seq().obj(
        this.key('modulus').int(),
        this.key('publicExponent').int()
      )
    })
    exports.RSAPublicKey = RSAPublicKey
    
    var PublicKey = asn1.define('SubjectPublicKeyInfo', function () {
      this.seq().obj(
        this.key('algorithm').use(AlgorithmIdentifier),
        this.key('subjectPublicKey').bitstr()
      )
    })
    exports.PublicKey = PublicKey
    
    var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
      this.seq().obj(
        this.key('algorithm').objid(),
        this.key('none').null_().optional(),
        this.key('curve').objid().optional(),
        this.key('params').seq().obj(
          this.key('p').int(),
          this.key('q').int(),
          this.key('g').int()
        ).optional()
      )
    })
    
    var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () {
      this.seq().obj(
        this.key('version').int(),
        this.key('algorithm').use(AlgorithmIdentifier),
        this.key('subjectPrivateKey').octstr()
      )
    })
    exports.PrivateKey = PrivateKeyInfo
    var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () {
      this.seq().obj(
        this.key('algorithm').seq().obj(
          this.key('id').objid(),
          this.key('decrypt').seq().obj(
            this.key('kde').seq().obj(
              this.key('id').objid(),
              this.key('kdeparams').seq().obj(
                this.key('salt').octstr(),
                this.key('iters').int()
              )
            ),
            this.key('cipher').seq().obj(
              this.key('algo').objid(),
              this.key('iv').octstr()
            )
          )
        ),
        this.key('subjectPrivateKey').octstr()
      )
    })
    
    exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo
    
    var DSAPrivateKey = asn1.define('DSAPrivateKey', function () {
      this.seq().obj(
        this.key('version').int(),
        this.key('p').int(),
        this.key('q').int(),
        this.key('g').int(),
        this.key('pub_key').int(),
        this.key('priv_key').int()
      )
    })
    exports.DSAPrivateKey = DSAPrivateKey
    
    exports.DSAparam = asn1.define('DSAparam', function () {
      this.int()
    })
    
    var ECPrivateKey = asn1.define('ECPrivateKey', function () {
      this.seq().obj(
        this.key('version').int(),
        this.key('privateKey').octstr(),
        this.key('parameters').optional().explicit(0).use(ECParameters),
        this.key('publicKey').optional().explicit(1).bitstr()
      )
    })
    exports.ECPrivateKey = ECPrivateKey
    
    var ECParameters = asn1.define('ECParameters', function () {
      this.choice({
        namedCurve: this.objid()
      })
    })
    
    exports.signature = asn1.define('signature', function () {
      this.seq().obj(
        this.key('r').int(),
        this.key('s').int()
      )
    })
    
    },{"./certificate":310,"asn1.js":10}],310:[function(require,module,exports){
    // from https://github.com/Rantanen/node-dtls/blob/25a7dc861bda38cfeac93a723500eea4f0ac2e86/Certificate.js
    // thanks to @Rantanen
    
    'use strict'
    
    var asn = require('asn1.js')
    
    var Time = asn.define('Time', function () {
      this.choice({
        utcTime: this.utctime(),
        generalTime: this.gentime()
      })
    })
    
    var AttributeTypeValue = asn.define('AttributeTypeValue', function () {
      this.seq().obj(
        this.key('type').objid(),
        this.key('value').any()
      )
    })
    
    var AlgorithmIdentifier = asn.define('AlgorithmIdentifier', function () {
      this.seq().obj(
        this.key('algorithm').objid(),
        this.key('parameters').optional(),
        this.key('curve').objid().optional()
      )
    })
    
    var SubjectPublicKeyInfo = asn.define('SubjectPublicKeyInfo', function () {
      this.seq().obj(
        this.key('algorithm').use(AlgorithmIdentifier),
        this.key('subjectPublicKey').bitstr()
      )
    })
    
    var RelativeDistinguishedName = asn.define('RelativeDistinguishedName', function () {
      this.setof(AttributeTypeValue)
    })
    
    var RDNSequence = asn.define('RDNSequence', function () {
      this.seqof(RelativeDistinguishedName)
    })
    
    var Name = asn.define('Name', function () {
      this.choice({
        rdnSequence: this.use(RDNSequence)
      })
    })
    
    var Validity = asn.define('Validity', function () {
      this.seq().obj(
        this.key('notBefore').use(Time),
        this.key('notAfter').use(Time)
      )
    })
    
    var Extension = asn.define('Extension', function () {
      this.seq().obj(
        this.key('extnID').objid(),
        this.key('critical').bool().def(false),
        this.key('extnValue').octstr()
      )
    })
    
    var TBSCertificate = asn.define('TBSCertificate', function () {
      this.seq().obj(
        this.key('version').explicit(0).int().optional(),
        this.key('serialNumber').int(),
        this.key('signature').use(AlgorithmIdentifier),
        this.key('issuer').use(Name),
        this.key('validity').use(Validity),
        this.key('subject').use(Name),
        this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo),
        this.key('issuerUniqueID').implicit(1).bitstr().optional(),
        this.key('subjectUniqueID').implicit(2).bitstr().optional(),
        this.key('extensions').explicit(3).seqof(Extension).optional()
      )
    })
    
    var X509Certificate = asn.define('X509Certificate', function () {
      this.seq().obj(
        this.key('tbsCertificate').use(TBSCertificate),
        this.key('signatureAlgorithm').use(AlgorithmIdentifier),
        this.key('signatureValue').bitstr()
      )
    })
    
    module.exports = X509Certificate
    
    },{"asn1.js":10}],311:[function(require,module,exports){
    // adapted from https://github.com/apatil/pemstrip
    var findProc = /Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r+/=]+)[\n\r]+/m
    var startRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----/m
    var fullRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----([0-9A-z\n\r+/=]+)-----END \1-----$/m
    var evp = require('evp_bytestokey')
    var ciphers = require('browserify-aes')
    var Buffer = require('safe-buffer').Buffer
    module.exports = function (okey, password) {
      var key = okey.toString()
      var match = key.match(findProc)
      var decrypted
      if (!match) {
        var match2 = key.match(fullRegex)
        decrypted = Buffer.from(match2[2].replace(/[\r\n]/g, ''), 'base64')
      } else {
        var suite = 'aes' + match[1]
        var iv = Buffer.from(match[2], 'hex')
        var cipherText = Buffer.from(match[3].replace(/[\r\n]/g, ''), 'base64')
        var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
        var out = []
        var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
        out.push(cipher.update(cipherText))
        out.push(cipher.final())
        decrypted = Buffer.concat(out)
      }
      var tag = key.match(startRegex)[1]
      return {
        tag: tag,
        data: decrypted
      }
    }
    
    },{"browserify-aes":39,"evp_bytestokey":135,"safe-buffer":338}],312:[function(require,module,exports){
    var asn1 = require('./asn1')
    var aesid = require('./aesid.json')
    var fixProc = require('./fixProc')
    var ciphers = require('browserify-aes')
    var compat = require('pbkdf2')
    var Buffer = require('safe-buffer').Buffer
    module.exports = parseKeys
    
    function parseKeys (buffer) {
      var password
      if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
        password = buffer.passphrase
        buffer = buffer.key
      }
      if (typeof buffer === 'string') {
        buffer = Buffer.from(buffer)
      }
    
      var stripped = fixProc(buffer, password)
    
      var type = stripped.tag
      var data = stripped.data
      var subtype, ndata
      switch (type) {
        case 'CERTIFICATE':
          ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo
          // falls through
        case 'PUBLIC KEY':
          if (!ndata) {
            ndata = asn1.PublicKey.decode(data, 'der')
          }
          subtype = ndata.algorithm.algorithm.join('.')
          switch (subtype) {
            case '1.2.840.113549.1.1.1':
              return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
            case '1.2.840.10045.2.1':
              ndata.subjectPrivateKey = ndata.subjectPublicKey
              return {
                type: 'ec',
                data: ndata
              }
            case '1.2.840.10040.4.1':
              ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
              return {
                type: 'dsa',
                data: ndata.algorithm.params
              }
            default: throw new Error('unknown key id ' + subtype)
          }
          // throw new Error('unknown key type ' + type)
        case 'ENCRYPTED PRIVATE KEY':
          data = asn1.EncryptedPrivateKey.decode(data, 'der')
          data = decrypt(data, password)
          // falls through
        case 'PRIVATE KEY':
          ndata = asn1.PrivateKey.decode(data, 'der')
          subtype = ndata.algorithm.algorithm.join('.')
          switch (subtype) {
            case '1.2.840.113549.1.1.1':
              return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
            case '1.2.840.10045.2.1':
              return {
                curve: ndata.algorithm.curve,
                privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
              }
            case '1.2.840.10040.4.1':
              ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
              return {
                type: 'dsa',
                params: ndata.algorithm.params
              }
            default: throw new Error('unknown key id ' + subtype)
          }
          // throw new Error('unknown key type ' + type)
        case 'RSA PUBLIC KEY':
          return asn1.RSAPublicKey.decode(data, 'der')
        case 'RSA PRIVATE KEY':
          return asn1.RSAPrivateKey.decode(data, 'der')
        case 'DSA PRIVATE KEY':
          return {
            type: 'dsa',
            params: asn1.DSAPrivateKey.decode(data, 'der')
          }
        case 'EC PRIVATE KEY':
          data = asn1.ECPrivateKey.decode(data, 'der')
          return {
            curve: data.parameters.value,
            privateKey: data.privateKey
          }
        default: throw new Error('unknown key type ' + type)
      }
    }
    parseKeys.signature = asn1.signature
    function decrypt (data, password) {
      var salt = data.algorithm.decrypt.kde.kdeparams.salt
      var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
      var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
      var iv = data.algorithm.decrypt.cipher.iv
      var cipherText = data.subjectPrivateKey
      var keylen = parseInt(algo.split('-')[1], 10) / 8
      var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1')
      var cipher = ciphers.createDecipheriv(algo, key, iv)
      var out = []
      out.push(cipher.update(cipherText))
      out.push(cipher.final())
      return Buffer.concat(out)
    }
    
    },{"./aesid.json":308,"./asn1":309,"./fixProc":311,"browserify-aes":39,"pbkdf2":315,"safe-buffer":338}],313:[function(require,module,exports){
    (function (process){(function (){
    // 'path' module extracted from Node.js v8.11.1 (only the posix part)
    // transplited with Babel
    
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    function assertPath(path) {
      if (typeof path !== 'string') {
        throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
      }
    }
    
    // Resolves . and .. elements in a path with directory names
    function normalizeStringPosix(path, allowAboveRoot) {
      var res = '';
      var lastSegmentLength = 0;
      var lastSlash = -1;
      var dots = 0;
      var code;
      for (var i = 0; i <= path.length; ++i) {
        if (i < path.length)
          code = path.charCodeAt(i);
        else if (code === 47 /*/*/)
          break;
        else
          code = 47 /*/*/;
        if (code === 47 /*/*/) {
          if (lastSlash === i - 1 || dots === 1) {
            // NOOP
          } else if (lastSlash !== i - 1 && dots === 2) {
            if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
              if (res.length > 2) {
                var lastSlashIndex = res.lastIndexOf('/');
                if (lastSlashIndex !== res.length - 1) {
                  if (lastSlashIndex === -1) {
                    res = '';
                    lastSegmentLength = 0;
                  } else {
                    res = res.slice(0, lastSlashIndex);
                    lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
                  }
                  lastSlash = i;
                  dots = 0;
                  continue;
                }
              } else if (res.length === 2 || res.length === 1) {
                res = '';
                lastSegmentLength = 0;
                lastSlash = i;
                dots = 0;
                continue;
              }
            }
            if (allowAboveRoot) {
              if (res.length > 0)
                res += '/..';
              else
                res = '..';
              lastSegmentLength = 2;
            }
          } else {
            if (res.length > 0)
              res += '/' + path.slice(lastSlash + 1, i);
            else
              res = path.slice(lastSlash + 1, i);
            lastSegmentLength = i - lastSlash - 1;
          }
          lastSlash = i;
          dots = 0;
        } else if (code === 46 /*.*/ && dots !== -1) {
          ++dots;
        } else {
          dots = -1;
        }
      }
      return res;
    }
    
    function _format(sep, pathObject) {
      var dir = pathObject.dir || pathObject.root;
      var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
      if (!dir) {
        return base;
      }
      if (dir === pathObject.root) {
        return dir + base;
      }
      return dir + sep + base;
    }
    
    var posix = {
      // path.resolve([from ...], to)
      resolve: function resolve() {
        var resolvedPath = '';
        var resolvedAbsolute = false;
        var cwd;
    
        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
          var path;
          if (i >= 0)
            path = arguments[i];
          else {
            if (cwd === undefined)
              cwd = process.cwd();
            path = cwd;
          }
    
          assertPath(path);
    
          // Skip empty entries
          if (path.length === 0) {
            continue;
          }
    
          resolvedPath = path + '/' + resolvedPath;
          resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;
        }
    
        // At this point the path should be resolved to a full absolute path, but
        // handle relative paths to be safe (might happen when process.cwd() fails)
    
        // Normalize the path
        resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
    
        if (resolvedAbsolute) {
          if (resolvedPath.length > 0)
            return '/' + resolvedPath;
          else
            return '/';
        } else if (resolvedPath.length > 0) {
          return resolvedPath;
        } else {
          return '.';
        }
      },
    
      normalize: function normalize(path) {
        assertPath(path);
    
        if (path.length === 0) return '.';
    
        var isAbsolute = path.charCodeAt(0) === 47 /*/*/;
        var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;
    
        // Normalize the path
        path = normalizeStringPosix(path, !isAbsolute);
    
        if (path.length === 0 && !isAbsolute) path = '.';
        if (path.length > 0 && trailingSeparator) path += '/';
    
        if (isAbsolute) return '/' + path;
        return path;
      },
    
      isAbsolute: function isAbsolute(path) {
        assertPath(path);
        return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;
      },
    
      join: function join() {
        if (arguments.length === 0)
          return '.';
        var joined;
        for (var i = 0; i < arguments.length; ++i) {
          var arg = arguments[i];
          assertPath(arg);
          if (arg.length > 0) {
            if (joined === undefined)
              joined = arg;
            else
              joined += '/' + arg;
          }
        }
        if (joined === undefined)
          return '.';
        return posix.normalize(joined);
      },
    
      relative: function relative(from, to) {
        assertPath(from);
        assertPath(to);
    
        if (from === to) return '';
    
        from = posix.resolve(from);
        to = posix.resolve(to);
    
        if (from === to) return '';
    
        // Trim any leading backslashes
        var fromStart = 1;
        for (; fromStart < from.length; ++fromStart) {
          if (from.charCodeAt(fromStart) !== 47 /*/*/)
            break;
        }
        var fromEnd = from.length;
        var fromLen = fromEnd - fromStart;
    
        // Trim any leading backslashes
        var toStart = 1;
        for (; toStart < to.length; ++toStart) {
          if (to.charCodeAt(toStart) !== 47 /*/*/)
            break;
        }
        var toEnd = to.length;
        var toLen = toEnd - toStart;
    
        // Compare paths to find the longest common path from root
        var length = fromLen < toLen ? fromLen : toLen;
        var lastCommonSep = -1;
        var i = 0;
        for (; i <= length; ++i) {
          if (i === length) {
            if (toLen > length) {
              if (to.charCodeAt(toStart + i) === 47 /*/*/) {
                // We get here if `from` is the exact base path for `to`.
                // For example: from='/foo/bar'; to='/foo/bar/baz'
                return to.slice(toStart + i + 1);
              } else if (i === 0) {
                // We get here if `from` is the root
                // For example: from='/'; to='/foo'
                return to.slice(toStart + i);
              }
            } else if (fromLen > length) {
              if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
                // We get here if `to` is the exact base path for `from`.
                // For example: from='/foo/bar/baz'; to='/foo/bar'
                lastCommonSep = i;
              } else if (i === 0) {
                // We get here if `to` is the root.
                // For example: from='/foo'; to='/'
                lastCommonSep = 0;
              }
            }
            break;
          }
          var fromCode = from.charCodeAt(fromStart + i);
          var toCode = to.charCodeAt(toStart + i);
          if (fromCode !== toCode)
            break;
          else if (fromCode === 47 /*/*/)
            lastCommonSep = i;
        }
    
        var out = '';
        // Generate the relative path based on the path difference between `to`
        // and `from`
        for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
          if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
            if (out.length === 0)
              out += '..';
            else
              out += '/..';
          }
        }
    
        // Lastly, append the rest of the destination (`to`) path that comes after
        // the common path parts
        if (out.length > 0)
          return out + to.slice(toStart + lastCommonSep);
        else {
          toStart += lastCommonSep;
          if (to.charCodeAt(toStart) === 47 /*/*/)
            ++toStart;
          return to.slice(toStart);
        }
      },
    
      _makeLong: function _makeLong(path) {
        return path;
      },
    
      dirname: function dirname(path) {
        assertPath(path);
        if (path.length === 0) return '.';
        var code = path.charCodeAt(0);
        var hasRoot = code === 47 /*/*/;
        var end = -1;
        var matchedSlash = true;
        for (var i = path.length - 1; i >= 1; --i) {
          code = path.charCodeAt(i);
          if (code === 47 /*/*/) {
              if (!matchedSlash) {
                end = i;
                break;
              }
            } else {
            // We saw the first non-path separator
            matchedSlash = false;
          }
        }
    
        if (end === -1) return hasRoot ? '/' : '.';
        if (hasRoot && end === 1) return '//';
        return path.slice(0, end);
      },
    
      basename: function basename(path, ext) {
        if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
        assertPath(path);
    
        var start = 0;
        var end = -1;
        var matchedSlash = true;
        var i;
    
        if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
          if (ext.length === path.length && ext === path) return '';
          var extIdx = ext.length - 1;
          var firstNonSlashEnd = -1;
          for (i = path.length - 1; i >= 0; --i) {
            var code = path.charCodeAt(i);
            if (code === 47 /*/*/) {
                // If we reached a path separator that was not part of a set of path
                // separators at the end of the string, stop now
                if (!matchedSlash) {
                  start = i + 1;
                  break;
                }
              } else {
              if (firstNonSlashEnd === -1) {
                // We saw the first non-path separator, remember this index in case
                // we need it if the extension ends up not matching
                matchedSlash = false;
                firstNonSlashEnd = i + 1;
              }
              if (extIdx >= 0) {
                // Try to match the explicit extension
                if (code === ext.charCodeAt(extIdx)) {
                  if (--extIdx === -1) {
                    // We matched the extension, so mark this as the end of our path
                    // component
                    end = i;
                  }
                } else {
                  // Extension does not match, so our result is the entire path
                  // component
                  extIdx = -1;
                  end = firstNonSlashEnd;
                }
              }
            }
          }
    
          if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
          return path.slice(start, end);
        } else {
          for (i = path.length - 1; i >= 0; --i) {
            if (path.charCodeAt(i) === 47 /*/*/) {
                // If we reached a path separator that was not part of a set of path
                // separators at the end of the string, stop now
                if (!matchedSlash) {
                  start = i + 1;
                  break;
                }
              } else if (end === -1) {
              // We saw the first non-path separator, mark this as the end of our
              // path component
              matchedSlash = false;
              end = i + 1;
            }
          }
    
          if (end === -1) return '';
          return path.slice(start, end);
        }
      },
    
      extname: function extname(path) {
        assertPath(path);
        var startDot = -1;
        var startPart = 0;
        var end = -1;
        var matchedSlash = true;
        // Track the state of characters (if any) we see before our first dot and
        // after any path separator we find
        var preDotState = 0;
        for (var i = path.length - 1; i >= 0; --i) {
          var code = path.charCodeAt(i);
          if (code === 47 /*/*/) {
              // If we reached a path separator that was not part of a set of path
              // separators at the end of the string, stop now
              if (!matchedSlash) {
                startPart = i + 1;
                break;
              }
              continue;
            }
          if (end === -1) {
            // We saw the first non-path separator, mark this as the end of our
            // extension
            matchedSlash = false;
            end = i + 1;
          }
          if (code === 46 /*.*/) {
              // If this is our first dot, mark it as the start of our extension
              if (startDot === -1)
                startDot = i;
              else if (preDotState !== 1)
                preDotState = 1;
          } else if (startDot !== -1) {
            // We saw a non-dot and non-path separator before our dot, so we should
            // have a good chance at having a non-empty extension
            preDotState = -1;
          }
        }
    
        if (startDot === -1 || end === -1 ||
            // We saw a non-dot character immediately before the dot
            preDotState === 0 ||
            // The (right-most) trimmed path component is exactly '..'
            preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
          return '';
        }
        return path.slice(startDot, end);
      },
    
      format: function format(pathObject) {
        if (pathObject === null || typeof pathObject !== 'object') {
          throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
        }
        return _format('/', pathObject);
      },
    
      parse: function parse(path) {
        assertPath(path);
    
        var ret = { root: '', dir: '', base: '', ext: '', name: '' };
        if (path.length === 0) return ret;
        var code = path.charCodeAt(0);
        var isAbsolute = code === 47 /*/*/;
        var start;
        if (isAbsolute) {
          ret.root = '/';
          start = 1;
        } else {
          start = 0;
        }
        var startDot = -1;
        var startPart = 0;
        var end = -1;
        var matchedSlash = true;
        var i = path.length - 1;
    
        // Track the state of characters (if any) we see before our first dot and
        // after any path separator we find
        var preDotState = 0;
    
        // Get non-dir info
        for (; i >= start; --i) {
          code = path.charCodeAt(i);
          if (code === 47 /*/*/) {
              // If we reached a path separator that was not part of a set of path
              // separators at the end of the string, stop now
              if (!matchedSlash) {
                startPart = i + 1;
                break;
              }
              continue;
            }
          if (end === -1) {
            // We saw the first non-path separator, mark this as the end of our
            // extension
            matchedSlash = false;
            end = i + 1;
          }
          if (code === 46 /*.*/) {
              // If this is our first dot, mark it as the start of our extension
              if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
            } else if (startDot !== -1) {
            // We saw a non-dot and non-path separator before our dot, so we should
            // have a good chance at having a non-empty extension
            preDotState = -1;
          }
        }
    
        if (startDot === -1 || end === -1 ||
        // We saw a non-dot character immediately before the dot
        preDotState === 0 ||
        // The (right-most) trimmed path component is exactly '..'
        preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
          if (end !== -1) {
            if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
          }
        } else {
          if (startPart === 0 && isAbsolute) {
            ret.name = path.slice(1, startDot);
            ret.base = path.slice(1, end);
          } else {
            ret.name = path.slice(startPart, startDot);
            ret.base = path.slice(startPart, end);
          }
          ret.ext = path.slice(startDot, end);
        }
    
        if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
    
        return ret;
      },
    
      sep: '/',
      delimiter: ':',
      win32: null,
      posix: null
    };
    
    posix.posix = posix;
    
    module.exports = posix;
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321}],314:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    function posix(path) {
        return path.charAt(0) === '/';
    }
    
    function win32(path) {
        // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
        var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
        var result = splitDeviceRe.exec(path);
        var device = result[1] || '';
        var isUnc = Boolean(device && device.charAt(1) !== ':');
    
        // UNC paths are always absolute
        return Boolean(result[2] || isUnc);
    }
    
    module.exports = process.platform === 'win32' ? win32 : posix;
    module.exports.posix = posix;
    module.exports.win32 = win32;
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321}],315:[function(require,module,exports){
    exports.pbkdf2 = require('./lib/async')
    exports.pbkdf2Sync = require('./lib/sync')
    
    },{"./lib/async":316,"./lib/sync":319}],316:[function(require,module,exports){
    (function (global){(function (){
    var Buffer = require('safe-buffer').Buffer
    
    var checkParameters = require('./precondition')
    var defaultEncoding = require('./default-encoding')
    var sync = require('./sync')
    var toBuffer = require('./to-buffer')
    
    var ZERO_BUF
    var subtle = global.crypto && global.crypto.subtle
    var toBrowser = {
      sha: 'SHA-1',
      'sha-1': 'SHA-1',
      sha1: 'SHA-1',
      sha256: 'SHA-256',
      'sha-256': 'SHA-256',
      sha384: 'SHA-384',
      'sha-384': 'SHA-384',
      'sha-512': 'SHA-512',
      sha512: 'SHA-512'
    }
    var checks = []
    function checkNative (algo) {
      if (global.process && !global.process.browser) {
        return Promise.resolve(false)
      }
      if (!subtle || !subtle.importKey || !subtle.deriveBits) {
        return Promise.resolve(false)
      }
      if (checks[algo] !== undefined) {
        return checks[algo]
      }
      ZERO_BUF = ZERO_BUF || Buffer.alloc(8)
      var prom = browserPbkdf2(ZERO_BUF, ZERO_BUF, 10, 128, algo)
        .then(function () {
          return true
        }).catch(function () {
          return false
        })
      checks[algo] = prom
      return prom
    }
    var nextTick
    function getNextTick () {
      if (nextTick) {
        return nextTick
      }
      if (global.process && global.process.nextTick) {
        nextTick = global.process.nextTick
      } else if (global.queueMicrotask) {
        nextTick = global.queueMicrotask
      } else if (global.setImmediate) {
        nextTick = global.setImmediate
      } else {
        nextTick = global.setTimeout
      }
      return nextTick
    }
    function browserPbkdf2 (password, salt, iterations, length, algo) {
      return subtle.importKey(
        'raw', password, { name: 'PBKDF2' }, false, ['deriveBits']
      ).then(function (key) {
        return subtle.deriveBits({
          name: 'PBKDF2',
          salt: salt,
          iterations: iterations,
          hash: {
            name: algo
          }
        }, key, length << 3)
      }).then(function (res) {
        return Buffer.from(res)
      })
    }
    
    function resolvePromise (promise, callback) {
      promise.then(function (out) {
        getNextTick()(function () {
          callback(null, out)
        })
      }, function (e) {
        getNextTick()(function () {
          callback(e)
        })
      })
    }
    module.exports = function (password, salt, iterations, keylen, digest, callback) {
      if (typeof digest === 'function') {
        callback = digest
        digest = undefined
      }
    
      digest = digest || 'sha1'
      var algo = toBrowser[digest.toLowerCase()]
    
      if (!algo || typeof global.Promise !== 'function') {
        getNextTick()(function () {
          var out
          try {
            out = sync(password, salt, iterations, keylen, digest)
          } catch (e) {
            return callback(e)
          }
          callback(null, out)
        })
        return
      }
    
      checkParameters(iterations, keylen)
      password = toBuffer(password, defaultEncoding, 'Password')
      salt = toBuffer(salt, defaultEncoding, 'Salt')
      if (typeof callback !== 'function') throw new Error('No callback provided to pbkdf2')
    
      resolvePromise(checkNative(algo).then(function (resp) {
        if (resp) return browserPbkdf2(password, salt, iterations, keylen, algo)
    
        return sync(password, salt, iterations, keylen, digest)
      }), callback)
    }
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"./default-encoding":317,"./precondition":318,"./sync":319,"./to-buffer":320,"safe-buffer":338}],317:[function(require,module,exports){
    (function (process,global){(function (){
    var defaultEncoding
    /* istanbul ignore next */
    if (global.process && global.process.browser) {
      defaultEncoding = 'utf-8'
    } else if (global.process && global.process.version) {
      var pVersionMajor = parseInt(process.version.split('.')[0].slice(1), 10)
    
      defaultEncoding = pVersionMajor >= 6 ? 'utf-8' : 'binary'
    } else {
      defaultEncoding = 'utf-8'
    }
    module.exports = defaultEncoding
    
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"_process":321}],318:[function(require,module,exports){
    var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs
    
    module.exports = function (iterations, keylen) {
      if (typeof iterations !== 'number') {
        throw new TypeError('Iterations not a number')
      }
    
      if (iterations < 0) {
        throw new TypeError('Bad iterations')
      }
    
      if (typeof keylen !== 'number') {
        throw new TypeError('Key length not a number')
      }
    
      if (keylen < 0 || keylen > MAX_ALLOC || keylen !== keylen) { /* eslint no-self-compare: 0 */
        throw new TypeError('Bad key length')
      }
    }
    
    },{}],319:[function(require,module,exports){
    var md5 = require('create-hash/md5')
    var RIPEMD160 = require('ripemd160')
    var sha = require('sha.js')
    var Buffer = require('safe-buffer').Buffer
    
    var checkParameters = require('./precondition')
    var defaultEncoding = require('./default-encoding')
    var toBuffer = require('./to-buffer')
    
    var ZEROS = Buffer.alloc(128)
    var sizes = {
      md5: 16,
      sha1: 20,
      sha224: 28,
      sha256: 32,
      sha384: 48,
      sha512: 64,
      rmd160: 20,
      ripemd160: 20
    }
    
    function Hmac (alg, key, saltLen) {
      var hash = getDigest(alg)
      var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
    
      if (key.length > blocksize) {
        key = hash(key)
      } else if (key.length < blocksize) {
        key = Buffer.concat([key, ZEROS], blocksize)
      }
    
      var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])
      var opad = Buffer.allocUnsafe(blocksize + sizes[alg])
      for (var i = 0; i < blocksize; i++) {
        ipad[i] = key[i] ^ 0x36
        opad[i] = key[i] ^ 0x5C
      }
    
      var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)
      ipad.copy(ipad1, 0, 0, blocksize)
      this.ipad1 = ipad1
      this.ipad2 = ipad
      this.opad = opad
      this.alg = alg
      this.blocksize = blocksize
      this.hash = hash
      this.size = sizes[alg]
    }
    
    Hmac.prototype.run = function (data, ipad) {
      data.copy(ipad, this.blocksize)
      var h = this.hash(ipad)
      h.copy(this.opad, this.blocksize)
      return this.hash(this.opad)
    }
    
    function getDigest (alg) {
      function shaFunc (data) {
        return sha(alg).update(data).digest()
      }
      function rmd160Func (data) {
        return new RIPEMD160().update(data).digest()
      }
    
      if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func
      if (alg === 'md5') return md5
      return shaFunc
    }
    
    function pbkdf2 (password, salt, iterations, keylen, digest) {
      checkParameters(iterations, keylen)
      password = toBuffer(password, defaultEncoding, 'Password')
      salt = toBuffer(salt, defaultEncoding, 'Salt')
    
      digest = digest || 'sha1'
    
      var hmac = new Hmac(digest, password, salt.length)
    
      var DK = Buffer.allocUnsafe(keylen)
      var block1 = Buffer.allocUnsafe(salt.length + 4)
      salt.copy(block1, 0, 0, salt.length)
    
      var destPos = 0
      var hLen = sizes[digest]
      var l = Math.ceil(keylen / hLen)
    
      for (var i = 1; i <= l; i++) {
        block1.writeUInt32BE(i, salt.length)
    
        var T = hmac.run(block1, hmac.ipad1)
        var U = T
    
        for (var j = 1; j < iterations; j++) {
          U = hmac.run(U, hmac.ipad2)
          for (var k = 0; k < hLen; k++) T[k] ^= U[k]
        }
    
        T.copy(DK, destPos)
        destPos += hLen
      }
    
      return DK
    }
    
    module.exports = pbkdf2
    
    },{"./default-encoding":317,"./precondition":318,"./to-buffer":320,"create-hash/md5":103,"ripemd160":337,"safe-buffer":338,"sha.js":341}],320:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    
    module.exports = function (thing, encoding, name) {
      if (Buffer.isBuffer(thing)) {
        return thing
      } else if (typeof thing === 'string') {
        return Buffer.from(thing, encoding)
      } else if (ArrayBuffer.isView(thing)) {
        return Buffer.from(thing.buffer)
      } else {
        throw new TypeError(name + ' must be a string, a Buffer, a typed array or a DataView')
      }
    }
    
    },{"safe-buffer":338}],321:[function(require,module,exports){
    // shim for using process in browser
    var process = module.exports = {};
    
    // cached from whatever global is present so that test runners that stub it
    // don't break things.  But we need to wrap it in a try catch in case it is
    // wrapped in strict mode code which doesn't define any globals.  It's inside a
    // function because try/catches deoptimize in certain engines.
    
    var cachedSetTimeout;
    var cachedClearTimeout;
    
    function defaultSetTimout() {
        throw new Error('setTimeout has not been defined');
    }
    function defaultClearTimeout () {
        throw new Error('clearTimeout has not been defined');
    }
    (function () {
        try {
            if (typeof setTimeout === 'function') {
                cachedSetTimeout = setTimeout;
            } else {
                cachedSetTimeout = defaultSetTimout;
            }
        } catch (e) {
            cachedSetTimeout = defaultSetTimout;
        }
        try {
            if (typeof clearTimeout === 'function') {
                cachedClearTimeout = clearTimeout;
            } else {
                cachedClearTimeout = defaultClearTimeout;
            }
        } catch (e) {
            cachedClearTimeout = defaultClearTimeout;
        }
    } ())
    function runTimeout(fun) {
        if (cachedSetTimeout === setTimeout) {
            //normal enviroments in sane situations
            return setTimeout(fun, 0);
        }
        // if setTimeout wasn't available but was latter defined
        if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
            cachedSetTimeout = setTimeout;
            return setTimeout(fun, 0);
        }
        try {
            // when when somebody has screwed with setTimeout but no I.E. maddness
            return cachedSetTimeout(fun, 0);
        } catch(e){
            try {
                // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
                return cachedSetTimeout.call(null, fun, 0);
            } catch(e){
                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
                return cachedSetTimeout.call(this, fun, 0);
            }
        }
    
    
    }
    function runClearTimeout(marker) {
        if (cachedClearTimeout === clearTimeout) {
            //normal enviroments in sane situations
            return clearTimeout(marker);
        }
        // if clearTimeout wasn't available but was latter defined
        if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
            cachedClearTimeout = clearTimeout;
            return clearTimeout(marker);
        }
        try {
            // when when somebody has screwed with setTimeout but no I.E. maddness
            return cachedClearTimeout(marker);
        } catch (e){
            try {
                // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
                return cachedClearTimeout.call(null, marker);
            } catch (e){
                // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
                // Some versions of I.E. have different rules for clearTimeout vs setTimeout
                return cachedClearTimeout.call(this, marker);
            }
        }
    
    
    
    }
    var queue = [];
    var draining = false;
    var currentQueue;
    var queueIndex = -1;
    
    function cleanUpNextTick() {
        if (!draining || !currentQueue) {
            return;
        }
        draining = false;
        if (currentQueue.length) {
            queue = currentQueue.concat(queue);
        } else {
            queueIndex = -1;
        }
        if (queue.length) {
            drainQueue();
        }
    }
    
    function drainQueue() {
        if (draining) {
            return;
        }
        var timeout = runTimeout(cleanUpNextTick);
        draining = true;
    
        var len = queue.length;
        while(len) {
            currentQueue = queue;
            queue = [];
            while (++queueIndex < len) {
                if (currentQueue) {
                    currentQueue[queueIndex].run();
                }
            }
            queueIndex = -1;
            len = queue.length;
        }
        currentQueue = null;
        draining = false;
        runClearTimeout(timeout);
    }
    
    process.nextTick = function (fun) {
        var args = new Array(arguments.length - 1);
        if (arguments.length > 1) {
            for (var i = 1; i < arguments.length; i++) {
                args[i - 1] = arguments[i];
            }
        }
        queue.push(new Item(fun, args));
        if (queue.length === 1 && !draining) {
            runTimeout(drainQueue);
        }
    };
    
    // v8 likes predictible objects
    function Item(fun, array) {
        this.fun = fun;
        this.array = array;
    }
    Item.prototype.run = function () {
        this.fun.apply(null, this.array);
    };
    process.title = 'browser';
    process.browser = true;
    process.env = {};
    process.argv = [];
    process.version = ''; // empty string to avoid regexp issues
    process.versions = {};
    
    function noop() {}
    
    process.on = noop;
    process.addListener = noop;
    process.once = noop;
    process.off = noop;
    process.removeListener = noop;
    process.removeAllListeners = noop;
    process.emit = noop;
    process.prependListener = noop;
    process.prependOnceListener = noop;
    
    process.listeners = function (name) { return [] }
    
    process.binding = function (name) {
        throw new Error('process.binding is not supported');
    };
    
    process.cwd = function () { return '/' };
    process.chdir = function (dir) {
        throw new Error('process.chdir is not supported');
    };
    process.umask = function() { return 0; };
    
    },{}],322:[function(require,module,exports){
    exports.publicEncrypt = require('./publicEncrypt')
    exports.privateDecrypt = require('./privateDecrypt')
    
    exports.privateEncrypt = function privateEncrypt (key, buf) {
      return exports.publicEncrypt(key, buf, true)
    }
    
    exports.publicDecrypt = function publicDecrypt (key, buf) {
      return exports.privateDecrypt(key, buf, true)
    }
    
    },{"./privateDecrypt":324,"./publicEncrypt":325}],323:[function(require,module,exports){
    var createHash = require('create-hash')
    var Buffer = require('safe-buffer').Buffer
    
    module.exports = function (seed, len) {
      var t = Buffer.alloc(0)
      var i = 0
      var c
      while (t.length < len) {
        c = i2ops(i++)
        t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()])
      }
      return t.slice(0, len)
    }
    
    function i2ops (c) {
      var out = Buffer.allocUnsafe(4)
      out.writeUInt32BE(c, 0)
      return out
    }
    
    },{"create-hash":102,"safe-buffer":338}],324:[function(require,module,exports){
    var parseKeys = require('parse-asn1')
    var mgf = require('./mgf')
    var xor = require('./xor')
    var BN = require('bn.js')
    var crt = require('browserify-rsa')
    var createHash = require('create-hash')
    var withPublic = require('./withPublic')
    var Buffer = require('safe-buffer').Buffer
    
    module.exports = function privateDecrypt (privateKey, enc, reverse) {
      var padding
      if (privateKey.padding) {
        padding = privateKey.padding
      } else if (reverse) {
        padding = 1
      } else {
        padding = 4
      }
    
      var key = parseKeys(privateKey)
      var k = key.modulus.byteLength()
      if (enc.length > k || new BN(enc).cmp(key.modulus) >= 0) {
        throw new Error('decryption error')
      }
      var msg
      if (reverse) {
        msg = withPublic(new BN(enc), key)
      } else {
        msg = crt(enc, key)
      }
      var zBuffer = Buffer.alloc(k - msg.length)
      msg = Buffer.concat([zBuffer, msg], k)
      if (padding === 4) {
        return oaep(key, msg)
      } else if (padding === 1) {
        return pkcs1(key, msg, reverse)
      } else if (padding === 3) {
        return msg
      } else {
        throw new Error('unknown padding')
      }
    }
    
    function oaep (key, msg) {
      var k = key.modulus.byteLength()
      var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
      var hLen = iHash.length
      if (msg[0] !== 0) {
        throw new Error('decryption error')
      }
      var maskedSeed = msg.slice(1, hLen + 1)
      var maskedDb = msg.slice(hLen + 1)
      var seed = xor(maskedSeed, mgf(maskedDb, hLen))
      var db = xor(maskedDb, mgf(seed, k - hLen - 1))
      if (compare(iHash, db.slice(0, hLen))) {
        throw new Error('decryption error')
      }
      var i = hLen
      while (db[i] === 0) {
        i++
      }
      if (db[i++] !== 1) {
        throw new Error('decryption error')
      }
      return db.slice(i)
    }
    
    function pkcs1 (key, msg, reverse) {
      var p1 = msg.slice(0, 2)
      var i = 2
      var status = 0
      while (msg[i++] !== 0) {
        if (i >= msg.length) {
          status++
          break
        }
      }
      var ps = msg.slice(2, i - 1)
    
      if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)) {
        status++
      }
      if (ps.length < 8) {
        status++
      }
      if (status) {
        throw new Error('decryption error')
      }
      return msg.slice(i)
    }
    function compare (a, b) {
      a = Buffer.from(a)
      b = Buffer.from(b)
      var dif = 0
      var len = a.length
      if (a.length !== b.length) {
        dif++
        len = Math.min(a.length, b.length)
      }
      var i = -1
      while (++i < len) {
        dif += (a[i] ^ b[i])
      }
      return dif
    }
    
    },{"./mgf":323,"./withPublic":326,"./xor":327,"bn.js":33,"browserify-rsa":57,"create-hash":102,"parse-asn1":312,"safe-buffer":338}],325:[function(require,module,exports){
    var parseKeys = require('parse-asn1')
    var randomBytes = require('randombytes')
    var createHash = require('create-hash')
    var mgf = require('./mgf')
    var xor = require('./xor')
    var BN = require('bn.js')
    var withPublic = require('./withPublic')
    var crt = require('browserify-rsa')
    var Buffer = require('safe-buffer').Buffer
    
    module.exports = function publicEncrypt (publicKey, msg, reverse) {
      var padding
      if (publicKey.padding) {
        padding = publicKey.padding
      } else if (reverse) {
        padding = 1
      } else {
        padding = 4
      }
      var key = parseKeys(publicKey)
      var paddedMsg
      if (padding === 4) {
        paddedMsg = oaep(key, msg)
      } else if (padding === 1) {
        paddedMsg = pkcs1(key, msg, reverse)
      } else if (padding === 3) {
        paddedMsg = new BN(msg)
        if (paddedMsg.cmp(key.modulus) >= 0) {
          throw new Error('data too long for modulus')
        }
      } else {
        throw new Error('unknown padding')
      }
      if (reverse) {
        return crt(paddedMsg, key)
      } else {
        return withPublic(paddedMsg, key)
      }
    }
    
    function oaep (key, msg) {
      var k = key.modulus.byteLength()
      var mLen = msg.length
      var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
      var hLen = iHash.length
      var hLen2 = 2 * hLen
      if (mLen > k - hLen2 - 2) {
        throw new Error('message too long')
      }
      var ps = Buffer.alloc(k - mLen - hLen2 - 2)
      var dblen = k - hLen - 1
      var seed = randomBytes(hLen)
      var maskedDb = xor(Buffer.concat([iHash, ps, Buffer.alloc(1, 1), msg], dblen), mgf(seed, dblen))
      var maskedSeed = xor(seed, mgf(maskedDb, hLen))
      return new BN(Buffer.concat([Buffer.alloc(1), maskedSeed, maskedDb], k))
    }
    function pkcs1 (key, msg, reverse) {
      var mLen = msg.length
      var k = key.modulus.byteLength()
      if (mLen > k - 11) {
        throw new Error('message too long')
      }
      var ps
      if (reverse) {
        ps = Buffer.alloc(k - mLen - 3, 0xff)
      } else {
        ps = nonZero(k - mLen - 3)
      }
      return new BN(Buffer.concat([Buffer.from([0, reverse ? 1 : 2]), ps, Buffer.alloc(1), msg], k))
    }
    function nonZero (len) {
      var out = Buffer.allocUnsafe(len)
      var i = 0
      var cache = randomBytes(len * 2)
      var cur = 0
      var num
      while (i < len) {
        if (cur === cache.length) {
          cache = randomBytes(len * 2)
          cur = 0
        }
        num = cache[cur++]
        if (num) {
          out[i++] = num
        }
      }
      return out
    }
    
    },{"./mgf":323,"./withPublic":326,"./xor":327,"bn.js":33,"browserify-rsa":57,"create-hash":102,"parse-asn1":312,"randombytes":334,"safe-buffer":338}],326:[function(require,module,exports){
    var BN = require('bn.js')
    var Buffer = require('safe-buffer').Buffer
    
    function withPublic (paddedMsg, key) {
      return Buffer.from(paddedMsg
        .toRed(BN.mont(key.modulus))
        .redPow(new BN(key.publicExponent))
        .fromRed()
        .toArray())
    }
    
    module.exports = withPublic
    
    },{"bn.js":33,"safe-buffer":338}],327:[function(require,module,exports){
    module.exports = function xor (a, b) {
      var len = a.length
      var i = -1
      while (++i < len) {
        a[i] ^= b[i]
      }
      return a
    }
    
    },{}],328:[function(require,module,exports){
    (function (global){(function (){
    /*! https://mths.be/punycode v1.4.1 by @mathias */
    ;(function(root) {
    
        /** Detect free variables */
        var freeExports = typeof exports == 'object' && exports &&
            !exports.nodeType && exports;
        var freeModule = typeof module == 'object' && module &&
            !module.nodeType && module;
        var freeGlobal = typeof global == 'object' && global;
        if (
            freeGlobal.global === freeGlobal ||
            freeGlobal.window === freeGlobal ||
            freeGlobal.self === freeGlobal
        ) {
            root = freeGlobal;
        }
    
        /**
         * The `punycode` object.
         * @name punycode
         * @type Object
         */
        var punycode,
    
        /** Highest positive signed 32-bit float value */
        maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
    
        /** Bootstring parameters */
        base = 36,
        tMin = 1,
        tMax = 26,
        skew = 38,
        damp = 700,
        initialBias = 72,
        initialN = 128, // 0x80
        delimiter = '-', // '\x2D'
    
        /** Regular expressions */
        regexPunycode = /^xn--/,
        regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
        regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
    
        /** Error messages */
        errors = {
            'overflow': 'Overflow: input needs wider integers to process',
            'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
            'invalid-input': 'Invalid input'
        },
    
        /** Convenience shortcuts */
        baseMinusTMin = base - tMin,
        floor = Math.floor,
        stringFromCharCode = String.fromCharCode,
    
        /** Temporary variable */
        key;
    
        /*--------------------------------------------------------------------------*/
    
        /**
         * A generic error utility function.
         * @private
         * @param {String} type The error type.
         * @returns {Error} Throws a `RangeError` with the applicable error message.
         */
        function error(type) {
            throw new RangeError(errors[type]);
        }
    
        /**
         * A generic `Array#map` utility function.
         * @private
         * @param {Array} array The array to iterate over.
         * @param {Function} callback The function that gets called for every array
         * item.
         * @returns {Array} A new array of values returned by the callback function.
         */
        function map(array, fn) {
            var length = array.length;
            var result = [];
            while (length--) {
                result[length] = fn(array[length]);
            }
            return result;
        }
    
        /**
         * A simple `Array#map`-like wrapper to work with domain name strings or email
         * addresses.
         * @private
         * @param {String} domain The domain name or email address.
         * @param {Function} callback The function that gets called for every
         * character.
         * @returns {Array} A new string of characters returned by the callback
         * function.
         */
        function mapDomain(string, fn) {
            var parts = string.split('@');
            var result = '';
            if (parts.length > 1) {
                // In email addresses, only the domain name should be punycoded. Leave
                // the local part (i.e. everything up to `@`) intact.
                result = parts[0] + '@';
                string = parts[1];
            }
            // Avoid `split(regex)` for IE8 compatibility. See #17.
            string = string.replace(regexSeparators, '\x2E');
            var labels = string.split('.');
            var encoded = map(labels, fn).join('.');
            return result + encoded;
        }
    
        /**
         * Creates an array containing the numeric code points of each Unicode
         * character in the string. While JavaScript uses UCS-2 internally,
         * this function will convert a pair of surrogate halves (each of which
         * UCS-2 exposes as separate characters) into a single code point,
         * matching UTF-16.
         * @see `punycode.ucs2.encode`
         * @see <https://mathiasbynens.be/notes/javascript-encoding>
         * @memberOf punycode.ucs2
         * @name decode
         * @param {String} string The Unicode input string (UCS-2).
         * @returns {Array} The new array of code points.
         */
        function ucs2decode(string) {
            var output = [],
                counter = 0,
                length = string.length,
                value,
                extra;
            while (counter < length) {
                value = string.charCodeAt(counter++);
                if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
                    // high surrogate, and there is a next character
                    extra = string.charCodeAt(counter++);
                    if ((extra & 0xFC00) == 0xDC00) { // low surrogate
                        output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
                    } else {
                        // unmatched surrogate; only append this code unit, in case the next
                        // code unit is the high surrogate of a surrogate pair
                        output.push(value);
                        counter--;
                    }
                } else {
                    output.push(value);
                }
            }
            return output;
        }
    
        /**
         * Creates a string based on an array of numeric code points.
         * @see `punycode.ucs2.decode`
         * @memberOf punycode.ucs2
         * @name encode
         * @param {Array} codePoints The array of numeric code points.
         * @returns {String} The new Unicode string (UCS-2).
         */
        function ucs2encode(array) {
            return map(array, function(value) {
                var output = '';
                if (value > 0xFFFF) {
                    value -= 0x10000;
                    output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
                    value = 0xDC00 | value & 0x3FF;
                }
                output += stringFromCharCode(value);
                return output;
            }).join('');
        }
    
        /**
         * Converts a basic code point into a digit/integer.
         * @see `digitToBasic()`
         * @private
         * @param {Number} codePoint The basic numeric code point value.
         * @returns {Number} The numeric value of a basic code point (for use in
         * representing integers) in the range `0` to `base - 1`, or `base` if
         * the code point does not represent a value.
         */
        function basicToDigit(codePoint) {
            if (codePoint - 48 < 10) {
                return codePoint - 22;
            }
            if (codePoint - 65 < 26) {
                return codePoint - 65;
            }
            if (codePoint - 97 < 26) {
                return codePoint - 97;
            }
            return base;
        }
    
        /**
         * Converts a digit/integer into a basic code point.
         * @see `basicToDigit()`
         * @private
         * @param {Number} digit The numeric value of a basic code point.
         * @returns {Number} The basic code point whose value (when used for
         * representing integers) is `digit`, which needs to be in the range
         * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
         * used; else, the lowercase form is used. The behavior is undefined
         * if `flag` is non-zero and `digit` has no uppercase form.
         */
        function digitToBasic(digit, flag) {
            //  0..25 map to ASCII a..z or A..Z
            // 26..35 map to ASCII 0..9
            return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
        }
    
        /**
         * Bias adaptation function as per section 3.4 of RFC 3492.
         * https://tools.ietf.org/html/rfc3492#section-3.4
         * @private
         */
        function adapt(delta, numPoints, firstTime) {
            var k = 0;
            delta = firstTime ? floor(delta / damp) : delta >> 1;
            delta += floor(delta / numPoints);
            for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
                delta = floor(delta / baseMinusTMin);
            }
            return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
        }
    
        /**
         * Converts a Punycode string of ASCII-only symbols to a string of Unicode
         * symbols.
         * @memberOf punycode
         * @param {String} input The Punycode string of ASCII-only symbols.
         * @returns {String} The resulting string of Unicode symbols.
         */
        function decode(input) {
            // Don't use UCS-2
            var output = [],
                inputLength = input.length,
                out,
                i = 0,
                n = initialN,
                bias = initialBias,
                basic,
                j,
                index,
                oldi,
                w,
                k,
                digit,
                t,
                /** Cached calculation results */
                baseMinusT;
    
            // Handle the basic code points: let `basic` be the number of input code
            // points before the last delimiter, or `0` if there is none, then copy
            // the first basic code points to the output.
    
            basic = input.lastIndexOf(delimiter);
            if (basic < 0) {
                basic = 0;
            }
    
            for (j = 0; j < basic; ++j) {
                // if it's not a basic code point
                if (input.charCodeAt(j) >= 0x80) {
                    error('not-basic');
                }
                output.push(input.charCodeAt(j));
            }
    
            // Main decoding loop: start just after the last delimiter if any basic code
            // points were copied; start at the beginning otherwise.
    
            for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
    
                // `index` is the index of the next character to be consumed.
                // Decode a generalized variable-length integer into `delta`,
                // which gets added to `i`. The overflow checking is easier
                // if we increase `i` as we go, then subtract off its starting
                // value at the end to obtain `delta`.
                for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
    
                    if (index >= inputLength) {
                        error('invalid-input');
                    }
    
                    digit = basicToDigit(input.charCodeAt(index++));
    
                    if (digit >= base || digit > floor((maxInt - i) / w)) {
                        error('overflow');
                    }
    
                    i += digit * w;
                    t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
    
                    if (digit < t) {
                        break;
                    }
    
                    baseMinusT = base - t;
                    if (w > floor(maxInt / baseMinusT)) {
                        error('overflow');
                    }
    
                    w *= baseMinusT;
    
                }
    
                out = output.length + 1;
                bias = adapt(i - oldi, out, oldi == 0);
    
                // `i` was supposed to wrap around from `out` to `0`,
                // incrementing `n` each time, so we'll fix that now:
                if (floor(i / out) > maxInt - n) {
                    error('overflow');
                }
    
                n += floor(i / out);
                i %= out;
    
                // Insert `n` at position `i` of the output
                output.splice(i++, 0, n);
    
            }
    
            return ucs2encode(output);
        }
    
        /**
         * Converts a string of Unicode symbols (e.g. a domain name label) to a
         * Punycode string of ASCII-only symbols.
         * @memberOf punycode
         * @param {String} input The string of Unicode symbols.
         * @returns {String} The resulting Punycode string of ASCII-only symbols.
         */
        function encode(input) {
            var n,
                delta,
                handledCPCount,
                basicLength,
                bias,
                j,
                m,
                q,
                k,
                t,
                currentValue,
                output = [],
                /** `inputLength` will hold the number of code points in `input`. */
                inputLength,
                /** Cached calculation results */
                handledCPCountPlusOne,
                baseMinusT,
                qMinusT;
    
            // Convert the input in UCS-2 to Unicode
            input = ucs2decode(input);
    
            // Cache the length
            inputLength = input.length;
    
            // Initialize the state
            n = initialN;
            delta = 0;
            bias = initialBias;
    
            // Handle the basic code points
            for (j = 0; j < inputLength; ++j) {
                currentValue = input[j];
                if (currentValue < 0x80) {
                    output.push(stringFromCharCode(currentValue));
                }
            }
    
            handledCPCount = basicLength = output.length;
    
            // `handledCPCount` is the number of code points that have been handled;
            // `basicLength` is the number of basic code points.
    
            // Finish the basic string - if it is not empty - with a delimiter
            if (basicLength) {
                output.push(delimiter);
            }
    
            // Main encoding loop:
            while (handledCPCount < inputLength) {
    
                // All non-basic code points < n have been handled already. Find the next
                // larger one:
                for (m = maxInt, j = 0; j < inputLength; ++j) {
                    currentValue = input[j];
                    if (currentValue >= n && currentValue < m) {
                        m = currentValue;
                    }
                }
    
                // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
                // but guard against overflow
                handledCPCountPlusOne = handledCPCount + 1;
                if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
                    error('overflow');
                }
    
                delta += (m - n) * handledCPCountPlusOne;
                n = m;
    
                for (j = 0; j < inputLength; ++j) {
                    currentValue = input[j];
    
                    if (currentValue < n && ++delta > maxInt) {
                        error('overflow');
                    }
    
                    if (currentValue == n) {
                        // Represent delta as a generalized variable-length integer
                        for (q = delta, k = base; /* no condition */; k += base) {
                            t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
                            if (q < t) {
                                break;
                            }
                            qMinusT = q - t;
                            baseMinusT = base - t;
                            output.push(
                                stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
                            );
                            q = floor(qMinusT / baseMinusT);
                        }
    
                        output.push(stringFromCharCode(digitToBasic(q, 0)));
                        bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
                        delta = 0;
                        ++handledCPCount;
                    }
                }
    
                ++delta;
                ++n;
    
            }
            return output.join('');
        }
    
        /**
         * Converts a Punycode string representing a domain name or an email address
         * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
         * it doesn't matter if you call it on a string that has already been
         * converted to Unicode.
         * @memberOf punycode
         * @param {String} input The Punycoded domain name or email address to
         * convert to Unicode.
         * @returns {String} The Unicode representation of the given Punycode
         * string.
         */
        function toUnicode(input) {
            return mapDomain(input, function(string) {
                return regexPunycode.test(string)
                    ? decode(string.slice(4).toLowerCase())
                    : string;
            });
        }
    
        /**
         * Converts a Unicode string representing a domain name or an email address to
         * Punycode. Only the non-ASCII parts of the domain name will be converted,
         * i.e. it doesn't matter if you call it with a domain that's already in
         * ASCII.
         * @memberOf punycode
         * @param {String} input The domain name or email address to convert, as a
         * Unicode string.
         * @returns {String} The Punycode representation of the given domain name or
         * email address.
         */
        function toASCII(input) {
            return mapDomain(input, function(string) {
                return regexNonASCII.test(string)
                    ? 'xn--' + encode(string)
                    : string;
            });
        }
    
        /*--------------------------------------------------------------------------*/
    
        /** Define the public API */
        punycode = {
            /**
             * A string representing the current Punycode.js version number.
             * @memberOf punycode
             * @type String
             */
            'version': '1.4.1',
            /**
             * An object of methods to convert from JavaScript's internal character
             * representation (UCS-2) to Unicode code points, and back.
             * @see <https://mathiasbynens.be/notes/javascript-encoding>
             * @memberOf punycode
             * @type Object
             */
            'ucs2': {
                'decode': ucs2decode,
                'encode': ucs2encode
            },
            'decode': decode,
            'encode': encode,
            'toASCII': toASCII,
            'toUnicode': toUnicode
        };
    
        /** Expose `punycode` */
        // Some AMD build optimizers, like r.js, check for specific condition patterns
        // like the following:
        if (
            typeof define == 'function' &&
            typeof define.amd == 'object' &&
            define.amd
        ) {
            define('punycode', function() {
                return punycode;
            });
        } else if (freeExports && freeModule) {
            if (module.exports == freeExports) {
                // in Node.js, io.js, or RingoJS v0.8.0+
                freeModule.exports = punycode;
            } else {
                // in Narwhal or RingoJS v0.7.0-
                for (key in punycode) {
                    punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
                }
            }
        } else {
            // in Rhino or a web browser
            root.punycode = punycode;
        }
    
    }(this));
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{}],329:[function(require,module,exports){
    'use strict';
    
    var replace = String.prototype.replace;
    var percentTwenties = /%20/g;
    
    var Format = {
        RFC1738: 'RFC1738',
        RFC3986: 'RFC3986'
    };
    
    module.exports = {
        'default': Format.RFC3986,
        formatters: {
            RFC1738: function (value) {
                return replace.call(value, percentTwenties, '+');
            },
            RFC3986: function (value) {
                return String(value);
            }
        },
        RFC1738: Format.RFC1738,
        RFC3986: Format.RFC3986
    };
    
    },{}],330:[function(require,module,exports){
    'use strict';
    
    var stringify = require('./stringify');
    var parse = require('./parse');
    var formats = require('./formats');
    
    module.exports = {
        formats: formats,
        parse: parse,
        stringify: stringify
    };
    
    },{"./formats":329,"./parse":331,"./stringify":332}],331:[function(require,module,exports){
    'use strict';
    
    var utils = require('./utils');
    
    var has = Object.prototype.hasOwnProperty;
    var isArray = Array.isArray;
    
    var defaults = {
        allowDots: false,
        allowPrototypes: false,
        allowSparse: false,
        arrayLimit: 20,
        charset: 'utf-8',
        charsetSentinel: false,
        comma: false,
        decoder: utils.decode,
        delimiter: '&',
        depth: 5,
        ignoreQueryPrefix: false,
        interpretNumericEntities: false,
        parameterLimit: 1000,
        parseArrays: true,
        plainObjects: false,
        strictNullHandling: false
    };
    
    var interpretNumericEntities = function (str) {
        return str.replace(/&#(\d+);/g, function ($0, numberStr) {
            return String.fromCharCode(parseInt(numberStr, 10));
        });
    };
    
    var parseArrayValue = function (val, options) {
        if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
            return val.split(',');
        }
    
        return val;
    };
    
    // This is what browsers will submit when the ✓ character occurs in an
    // application/x-www-form-urlencoded body and the encoding of the page containing
    // the form is iso-8859-1, or when the submitted form has an accept-charset
    // attribute of iso-8859-1. Presumably also with other charsets that do not contain
    // the ✓ character, such as us-ascii.
    var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')
    
    // These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
    var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
    
    var parseValues = function parseQueryStringValues(str, options) {
        var obj = { __proto__: null };
    
        var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
        var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
        var parts = cleanStr.split(options.delimiter, limit);
        var skipIndex = -1; // Keep track of where the utf8 sentinel was found
        var i;
    
        var charset = options.charset;
        if (options.charsetSentinel) {
            for (i = 0; i < parts.length; ++i) {
                if (parts[i].indexOf('utf8=') === 0) {
                    if (parts[i] === charsetSentinel) {
                        charset = 'utf-8';
                    } else if (parts[i] === isoSentinel) {
                        charset = 'iso-8859-1';
                    }
                    skipIndex = i;
                    i = parts.length; // The eslint settings do not allow break;
                }
            }
        }
    
        for (i = 0; i < parts.length; ++i) {
            if (i === skipIndex) {
                continue;
            }
            var part = parts[i];
    
            var bracketEqualsPos = part.indexOf(']=');
            var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
    
            var key, val;
            if (pos === -1) {
                key = options.decoder(part, defaults.decoder, charset, 'key');
                val = options.strictNullHandling ? null : '';
            } else {
                key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
                val = utils.maybeMap(
                    parseArrayValue(part.slice(pos + 1), options),
                    function (encodedVal) {
                        return options.decoder(encodedVal, defaults.decoder, charset, 'value');
                    }
                );
            }
    
            if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
                val = interpretNumericEntities(val);
            }
    
            if (part.indexOf('[]=') > -1) {
                val = isArray(val) ? [val] : val;
            }
    
            if (has.call(obj, key)) {
                obj[key] = utils.combine(obj[key], val);
            } else {
                obj[key] = val;
            }
        }
    
        return obj;
    };
    
    var parseObject = function (chain, val, options, valuesParsed) {
        var leaf = valuesParsed ? val : parseArrayValue(val, options);
    
        for (var i = chain.length - 1; i >= 0; --i) {
            var obj;
            var root = chain[i];
    
            if (root === '[]' && options.parseArrays) {
                obj = [].concat(leaf);
            } else {
                obj = options.plainObjects ? Object.create(null) : {};
                var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
                var index = parseInt(cleanRoot, 10);
                if (!options.parseArrays && cleanRoot === '') {
                    obj = { 0: leaf };
                } else if (
                    !isNaN(index)
                    && root !== cleanRoot
                    && String(index) === cleanRoot
                    && index >= 0
                    && (options.parseArrays && index <= options.arrayLimit)
                ) {
                    obj = [];
                    obj[index] = leaf;
                } else if (cleanRoot !== '__proto__') {
                    obj[cleanRoot] = leaf;
                }
            }
    
            leaf = obj;
        }
    
        return leaf;
    };
    
    var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
        if (!givenKey) {
            return;
        }
    
        // Transform dot notation to bracket notation
        var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
    
        // The regex chunks
    
        var brackets = /(\[[^[\]]*])/;
        var child = /(\[[^[\]]*])/g;
    
        // Get the parent
    
        var segment = options.depth > 0 && brackets.exec(key);
        var parent = segment ? key.slice(0, segment.index) : key;
    
        // Stash the parent if it exists
    
        var keys = [];
        if (parent) {
            // If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
            if (!options.plainObjects && has.call(Object.prototype, parent)) {
                if (!options.allowPrototypes) {
                    return;
                }
            }
    
            keys.push(parent);
        }
    
        // Loop through children appending to the array until we hit depth
    
        var i = 0;
        while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
            i += 1;
            if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
                if (!options.allowPrototypes) {
                    return;
                }
            }
            keys.push(segment[1]);
        }
    
        // If there's a remainder, just add whatever is left
    
        if (segment) {
            keys.push('[' + key.slice(segment.index) + ']');
        }
    
        return parseObject(keys, val, options, valuesParsed);
    };
    
    var normalizeParseOptions = function normalizeParseOptions(opts) {
        if (!opts) {
            return defaults;
        }
    
        if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
            throw new TypeError('Decoder has to be a function.');
        }
    
        if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
            throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
        }
        var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
    
        return {
            allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
            allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
            allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
            arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
            charset: charset,
            charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
            comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
            decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
            delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
            // eslint-disable-next-line no-implicit-coercion, no-extra-parens
            depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
            ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
            interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
            parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
            parseArrays: opts.parseArrays !== false,
            plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
            strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
        };
    };
    
    module.exports = function (str, opts) {
        var options = normalizeParseOptions(opts);
    
        if (str === '' || str === null || typeof str === 'undefined') {
            return options.plainObjects ? Object.create(null) : {};
        }
    
        var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
        var obj = options.plainObjects ? Object.create(null) : {};
    
        // Iterate over the keys and setup the new object
    
        var keys = Object.keys(tempObj);
        for (var i = 0; i < keys.length; ++i) {
            var key = keys[i];
            var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
            obj = utils.merge(obj, newObj, options);
        }
    
        if (options.allowSparse === true) {
            return obj;
        }
    
        return utils.compact(obj);
    };
    
    },{"./utils":333}],332:[function(require,module,exports){
    'use strict';
    
    var getSideChannel = require('side-channel');
    var utils = require('./utils');
    var formats = require('./formats');
    var has = Object.prototype.hasOwnProperty;
    
    var arrayPrefixGenerators = {
        brackets: function brackets(prefix) {
            return prefix + '[]';
        },
        comma: 'comma',
        indices: function indices(prefix, key) {
            return prefix + '[' + key + ']';
        },
        repeat: function repeat(prefix) {
            return prefix;
        }
    };
    
    var isArray = Array.isArray;
    var push = Array.prototype.push;
    var pushToArray = function (arr, valueOrArray) {
        push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
    };
    
    var toISO = Date.prototype.toISOString;
    
    var defaultFormat = formats['default'];
    var defaults = {
        addQueryPrefix: false,
        allowDots: false,
        charset: 'utf-8',
        charsetSentinel: false,
        delimiter: '&',
        encode: true,
        encoder: utils.encode,
        encodeValuesOnly: false,
        format: defaultFormat,
        formatter: formats.formatters[defaultFormat],
        // deprecated
        indices: false,
        serializeDate: function serializeDate(date) {
            return toISO.call(date);
        },
        skipNulls: false,
        strictNullHandling: false
    };
    
    var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
        return typeof v === 'string'
            || typeof v === 'number'
            || typeof v === 'boolean'
            || typeof v === 'symbol'
            || typeof v === 'bigint';
    };
    
    var sentinel = {};
    
    var stringify = function stringify(
        object,
        prefix,
        generateArrayPrefix,
        commaRoundTrip,
        strictNullHandling,
        skipNulls,
        encoder,
        filter,
        sort,
        allowDots,
        serializeDate,
        format,
        formatter,
        encodeValuesOnly,
        charset,
        sideChannel
    ) {
        var obj = object;
    
        var tmpSc = sideChannel;
        var step = 0;
        var findFlag = false;
        while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
            // Where object last appeared in the ref tree
            var pos = tmpSc.get(object);
            step += 1;
            if (typeof pos !== 'undefined') {
                if (pos === step) {
                    throw new RangeError('Cyclic object value');
                } else {
                    findFlag = true; // Break while
                }
            }
            if (typeof tmpSc.get(sentinel) === 'undefined') {
                step = 0;
            }
        }
    
        if (typeof filter === 'function') {
            obj = filter(prefix, obj);
        } else if (obj instanceof Date) {
            obj = serializeDate(obj);
        } else if (generateArrayPrefix === 'comma' && isArray(obj)) {
            obj = utils.maybeMap(obj, function (value) {
                if (value instanceof Date) {
                    return serializeDate(value);
                }
                return value;
            });
        }
    
        if (obj === null) {
            if (strictNullHandling) {
                return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
            }
    
            obj = '';
        }
    
        if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
            if (encoder) {
                var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
                return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
            }
            return [formatter(prefix) + '=' + formatter(String(obj))];
        }
    
        var values = [];
    
        if (typeof obj === 'undefined') {
            return values;
        }
    
        var objKeys;
        if (generateArrayPrefix === 'comma' && isArray(obj)) {
            // we need to join elements in
            if (encodeValuesOnly && encoder) {
                obj = utils.maybeMap(obj, encoder);
            }
            objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
        } else if (isArray(filter)) {
            objKeys = filter;
        } else {
            var keys = Object.keys(obj);
            objKeys = sort ? keys.sort(sort) : keys;
        }
    
        var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix;
    
        for (var j = 0; j < objKeys.length; ++j) {
            var key = objKeys[j];
            var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
    
            if (skipNulls && value === null) {
                continue;
            }
    
            var keyPrefix = isArray(obj)
                ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix
                : adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']');
    
            sideChannel.set(object, step);
            var valueSideChannel = getSideChannel();
            valueSideChannel.set(sentinel, sideChannel);
            pushToArray(values, stringify(
                value,
                keyPrefix,
                generateArrayPrefix,
                commaRoundTrip,
                strictNullHandling,
                skipNulls,
                generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder,
                filter,
                sort,
                allowDots,
                serializeDate,
                format,
                formatter,
                encodeValuesOnly,
                charset,
                valueSideChannel
            ));
        }
    
        return values;
    };
    
    var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
        if (!opts) {
            return defaults;
        }
    
        if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
            throw new TypeError('Encoder has to be a function.');
        }
    
        var charset = opts.charset || defaults.charset;
        if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
            throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
        }
    
        var format = formats['default'];
        if (typeof opts.format !== 'undefined') {
            if (!has.call(formats.formatters, opts.format)) {
                throw new TypeError('Unknown format option provided.');
            }
            format = opts.format;
        }
        var formatter = formats.formatters[format];
    
        var filter = defaults.filter;
        if (typeof opts.filter === 'function' || isArray(opts.filter)) {
            filter = opts.filter;
        }
    
        return {
            addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
            allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
            charset: charset,
            charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
            delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
            encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
            encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
            encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
            filter: filter,
            format: format,
            formatter: formatter,
            serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
            skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
            sort: typeof opts.sort === 'function' ? opts.sort : null,
            strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
        };
    };
    
    module.exports = function (object, opts) {
        var obj = object;
        var options = normalizeStringifyOptions(opts);
    
        var objKeys;
        var filter;
    
        if (typeof options.filter === 'function') {
            filter = options.filter;
            obj = filter('', obj);
        } else if (isArray(options.filter)) {
            filter = options.filter;
            objKeys = filter;
        }
    
        var keys = [];
    
        if (typeof obj !== 'object' || obj === null) {
            return '';
        }
    
        var arrayFormat;
        if (opts && opts.arrayFormat in arrayPrefixGenerators) {
            arrayFormat = opts.arrayFormat;
        } else if (opts && 'indices' in opts) {
            arrayFormat = opts.indices ? 'indices' : 'repeat';
        } else {
            arrayFormat = 'indices';
        }
    
        var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
        if (opts && 'commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
            throw new TypeError('`commaRoundTrip` must be a boolean, or absent');
        }
        var commaRoundTrip = generateArrayPrefix === 'comma' && opts && opts.commaRoundTrip;
    
        if (!objKeys) {
            objKeys = Object.keys(obj);
        }
    
        if (options.sort) {
            objKeys.sort(options.sort);
        }
    
        var sideChannel = getSideChannel();
        for (var i = 0; i < objKeys.length; ++i) {
            var key = objKeys[i];
    
            if (options.skipNulls && obj[key] === null) {
                continue;
            }
            pushToArray(keys, stringify(
                obj[key],
                key,
                generateArrayPrefix,
                commaRoundTrip,
                options.strictNullHandling,
                options.skipNulls,
                options.encode ? options.encoder : null,
                options.filter,
                options.sort,
                options.allowDots,
                options.serializeDate,
                options.format,
                options.formatter,
                options.encodeValuesOnly,
                options.charset,
                sideChannel
            ));
        }
    
        var joined = keys.join(options.delimiter);
        var prefix = options.addQueryPrefix === true ? '?' : '';
    
        if (options.charsetSentinel) {
            if (options.charset === 'iso-8859-1') {
                // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
                prefix += 'utf8=%26%2310003%3B&';
            } else {
                // encodeURIComponent('✓')
                prefix += 'utf8=%E2%9C%93&';
            }
        }
    
        return joined.length > 0 ? prefix + joined : '';
    };
    
    },{"./formats":329,"./utils":333,"side-channel":348}],333:[function(require,module,exports){
    'use strict';
    
    var formats = require('./formats');
    
    var has = Object.prototype.hasOwnProperty;
    var isArray = Array.isArray;
    
    var hexTable = (function () {
        var array = [];
        for (var i = 0; i < 256; ++i) {
            array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
        }
    
        return array;
    }());
    
    var compactQueue = function compactQueue(queue) {
        while (queue.length > 1) {
            var item = queue.pop();
            var obj = item.obj[item.prop];
    
            if (isArray(obj)) {
                var compacted = [];
    
                for (var j = 0; j < obj.length; ++j) {
                    if (typeof obj[j] !== 'undefined') {
                        compacted.push(obj[j]);
                    }
                }
    
                item.obj[item.prop] = compacted;
            }
        }
    };
    
    var arrayToObject = function arrayToObject(source, options) {
        var obj = options && options.plainObjects ? Object.create(null) : {};
        for (var i = 0; i < source.length; ++i) {
            if (typeof source[i] !== 'undefined') {
                obj[i] = source[i];
            }
        }
    
        return obj;
    };
    
    var merge = function merge(target, source, options) {
        /* eslint no-param-reassign: 0 */
        if (!source) {
            return target;
        }
    
        if (typeof source !== 'object') {
            if (isArray(target)) {
                target.push(source);
            } else if (target && typeof target === 'object') {
                if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
                    target[source] = true;
                }
            } else {
                return [target, source];
            }
    
            return target;
        }
    
        if (!target || typeof target !== 'object') {
            return [target].concat(source);
        }
    
        var mergeTarget = target;
        if (isArray(target) && !isArray(source)) {
            mergeTarget = arrayToObject(target, options);
        }
    
        if (isArray(target) && isArray(source)) {
            source.forEach(function (item, i) {
                if (has.call(target, i)) {
                    var targetItem = target[i];
                    if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
                        target[i] = merge(targetItem, item, options);
                    } else {
                        target.push(item);
                    }
                } else {
                    target[i] = item;
                }
            });
            return target;
        }
    
        return Object.keys(source).reduce(function (acc, key) {
            var value = source[key];
    
            if (has.call(acc, key)) {
                acc[key] = merge(acc[key], value, options);
            } else {
                acc[key] = value;
            }
            return acc;
        }, mergeTarget);
    };
    
    var assign = function assignSingleSource(target, source) {
        return Object.keys(source).reduce(function (acc, key) {
            acc[key] = source[key];
            return acc;
        }, target);
    };
    
    var decode = function (str, decoder, charset) {
        var strWithoutPlus = str.replace(/\+/g, ' ');
        if (charset === 'iso-8859-1') {
            // unescape never throws, no try...catch needed:
            return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
        }
        // utf-8
        try {
            return decodeURIComponent(strWithoutPlus);
        } catch (e) {
            return strWithoutPlus;
        }
    };
    
    var encode = function encode(str, defaultEncoder, charset, kind, format) {
        // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
        // It has been adapted here for stricter adherence to RFC 3986
        if (str.length === 0) {
            return str;
        }
    
        var string = str;
        if (typeof str === 'symbol') {
            string = Symbol.prototype.toString.call(str);
        } else if (typeof str !== 'string') {
            string = String(str);
        }
    
        if (charset === 'iso-8859-1') {
            return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
                return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
            });
        }
    
        var out = '';
        for (var i = 0; i < string.length; ++i) {
            var c = string.charCodeAt(i);
    
            if (
                c === 0x2D // -
                || c === 0x2E // .
                || c === 0x5F // _
                || c === 0x7E // ~
                || (c >= 0x30 && c <= 0x39) // 0-9
                || (c >= 0x41 && c <= 0x5A) // a-z
                || (c >= 0x61 && c <= 0x7A) // A-Z
                || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
            ) {
                out += string.charAt(i);
                continue;
            }
    
            if (c < 0x80) {
                out = out + hexTable[c];
                continue;
            }
    
            if (c < 0x800) {
                out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
                continue;
            }
    
            if (c < 0xD800 || c >= 0xE000) {
                out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
                continue;
            }
    
            i += 1;
            c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
            /* eslint operator-linebreak: [2, "before"] */
            out += hexTable[0xF0 | (c >> 18)]
                + hexTable[0x80 | ((c >> 12) & 0x3F)]
                + hexTable[0x80 | ((c >> 6) & 0x3F)]
                + hexTable[0x80 | (c & 0x3F)];
        }
    
        return out;
    };
    
    var compact = function compact(value) {
        var queue = [{ obj: { o: value }, prop: 'o' }];
        var refs = [];
    
        for (var i = 0; i < queue.length; ++i) {
            var item = queue[i];
            var obj = item.obj[item.prop];
    
            var keys = Object.keys(obj);
            for (var j = 0; j < keys.length; ++j) {
                var key = keys[j];
                var val = obj[key];
                if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
                    queue.push({ obj: obj, prop: key });
                    refs.push(val);
                }
            }
        }
    
        compactQueue(queue);
    
        return value;
    };
    
    var isRegExp = function isRegExp(obj) {
        return Object.prototype.toString.call(obj) === '[object RegExp]';
    };
    
    var isBuffer = function isBuffer(obj) {
        if (!obj || typeof obj !== 'object') {
            return false;
        }
    
        return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
    };
    
    var combine = function combine(a, b) {
        return [].concat(a, b);
    };
    
    var maybeMap = function maybeMap(val, fn) {
        if (isArray(val)) {
            var mapped = [];
            for (var i = 0; i < val.length; i += 1) {
                mapped.push(fn(val[i]));
            }
            return mapped;
        }
        return fn(val);
    };
    
    module.exports = {
        arrayToObject: arrayToObject,
        assign: assign,
        combine: combine,
        compact: compact,
        decode: decode,
        encode: encode,
        isBuffer: isBuffer,
        isRegExp: isRegExp,
        maybeMap: maybeMap,
        merge: merge
    };
    
    },{"./formats":329}],334:[function(require,module,exports){
    (function (process,global){(function (){
    'use strict'
    
    // limit of Crypto.getRandomValues()
    // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
    var MAX_BYTES = 65536
    
    // Node supports requesting up to this number of bytes
    // https://github.com/nodejs/node/blob/master/lib/internal/crypto/random.js#L48
    var MAX_UINT32 = 4294967295
    
    function oldBrowser () {
      throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')
    }
    
    var Buffer = require('safe-buffer').Buffer
    var crypto = global.crypto || global.msCrypto
    
    if (crypto && crypto.getRandomValues) {
      module.exports = randomBytes
    } else {
      module.exports = oldBrowser
    }
    
    function randomBytes (size, cb) {
      // phantomjs needs to throw
      if (size > MAX_UINT32) throw new RangeError('requested too many random bytes')
    
      var bytes = Buffer.allocUnsafe(size)
    
      if (size > 0) {  // getRandomValues fails on IE if size == 0
        if (size > MAX_BYTES) { // this is the max bytes crypto.getRandomValues
          // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
          for (var generated = 0; generated < size; generated += MAX_BYTES) {
            // buffer.slice automatically checks if the end is past the end of
            // the buffer so we don't have to here
            crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES))
          }
        } else {
          crypto.getRandomValues(bytes)
        }
      }
    
      if (typeof cb === 'function') {
        return process.nextTick(function () {
          cb(null, bytes)
        })
      }
    
      return bytes
    }
    
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"_process":321,"safe-buffer":338}],335:[function(require,module,exports){
    (function (process,global){(function (){
    'use strict'
    
    function oldBrowser () {
      throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')
    }
    var safeBuffer = require('safe-buffer')
    var randombytes = require('randombytes')
    var Buffer = safeBuffer.Buffer
    var kBufferMaxLength = safeBuffer.kMaxLength
    var crypto = global.crypto || global.msCrypto
    var kMaxUint32 = Math.pow(2, 32) - 1
    function assertOffset (offset, length) {
      if (typeof offset !== 'number' || offset !== offset) { // eslint-disable-line no-self-compare
        throw new TypeError('offset must be a number')
      }
    
      if (offset > kMaxUint32 || offset < 0) {
        throw new TypeError('offset must be a uint32')
      }
    
      if (offset > kBufferMaxLength || offset > length) {
        throw new RangeError('offset out of range')
      }
    }
    
    function assertSize (size, offset, length) {
      if (typeof size !== 'number' || size !== size) { // eslint-disable-line no-self-compare
        throw new TypeError('size must be a number')
      }
    
      if (size > kMaxUint32 || size < 0) {
        throw new TypeError('size must be a uint32')
      }
    
      if (size + offset > length || size > kBufferMaxLength) {
        throw new RangeError('buffer too small')
      }
    }
    if ((crypto && crypto.getRandomValues) || !process.browser) {
      exports.randomFill = randomFill
      exports.randomFillSync = randomFillSync
    } else {
      exports.randomFill = oldBrowser
      exports.randomFillSync = oldBrowser
    }
    function randomFill (buf, offset, size, cb) {
      if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
        throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
      }
    
      if (typeof offset === 'function') {
        cb = offset
        offset = 0
        size = buf.length
      } else if (typeof size === 'function') {
        cb = size
        size = buf.length - offset
      } else if (typeof cb !== 'function') {
        throw new TypeError('"cb" argument must be a function')
      }
      assertOffset(offset, buf.length)
      assertSize(size, offset, buf.length)
      return actualFill(buf, offset, size, cb)
    }
    
    function actualFill (buf, offset, size, cb) {
      if (process.browser) {
        var ourBuf = buf.buffer
        var uint = new Uint8Array(ourBuf, offset, size)
        crypto.getRandomValues(uint)
        if (cb) {
          process.nextTick(function () {
            cb(null, buf)
          })
          return
        }
        return buf
      }
      if (cb) {
        randombytes(size, function (err, bytes) {
          if (err) {
            return cb(err)
          }
          bytes.copy(buf, offset)
          cb(null, buf)
        })
        return
      }
      var bytes = randombytes(size)
      bytes.copy(buf, offset)
      return buf
    }
    function randomFillSync (buf, offset, size) {
      if (typeof offset === 'undefined') {
        offset = 0
      }
      if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {
        throw new TypeError('"buf" argument must be a Buffer or Uint8Array')
      }
    
      assertOffset(offset, buf.length)
    
      if (size === undefined) size = buf.length - offset
    
      assertSize(size, offset, buf.length)
    
      return actualFill(buf, offset, size)
    }
    
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"_process":321,"randombytes":334,"safe-buffer":338}],336:[function(require,module,exports){
    (function (process){(function (){
    module.exports = rimraf
    rimraf.sync = rimrafSync
    
    var assert = require("assert")
    var path = require("path")
    var fs = require("fs")
    var glob = undefined
    try {
      glob = require("glob")
    } catch (_err) {
      // treat glob as optional.
    }
    var _0666 = parseInt('666', 8)
    
    var defaultGlobOpts = {
      nosort: true,
      silent: true
    }
    
    // for EMFILE handling
    var timeout = 0
    
    var isWindows = (process.platform === "win32")
    
    function defaults (options) {
      var methods = [
        'unlink',
        'chmod',
        'stat',
        'lstat',
        'rmdir',
        'readdir'
      ]
      methods.forEach(function(m) {
        options[m] = options[m] || fs[m]
        m = m + 'Sync'
        options[m] = options[m] || fs[m]
      })
    
      options.maxBusyTries = options.maxBusyTries || 3
      options.emfileWait = options.emfileWait || 1000
      if (options.glob === false) {
        options.disableGlob = true
      }
      if (options.disableGlob !== true && glob === undefined) {
        throw Error('glob dependency not found, set `options.disableGlob = true` if intentional')
      }
      options.disableGlob = options.disableGlob || false
      options.glob = options.glob || defaultGlobOpts
    }
    
    function rimraf (p, options, cb) {
      if (typeof options === 'function') {
        cb = options
        options = {}
      }
    
      assert(p, 'rimraf: missing path')
      assert.equal(typeof p, 'string', 'rimraf: path should be a string')
      assert.equal(typeof cb, 'function', 'rimraf: callback function required')
      assert(options, 'rimraf: invalid options argument provided')
      assert.equal(typeof options, 'object', 'rimraf: options should be object')
    
      defaults(options)
    
      var busyTries = 0
      var errState = null
      var n = 0
    
      if (options.disableGlob || !glob.hasMagic(p))
        return afterGlob(null, [p])
    
      options.lstat(p, function (er, stat) {
        if (!er)
          return afterGlob(null, [p])
    
        glob(p, options.glob, afterGlob)
      })
    
      function next (er) {
        errState = errState || er
        if (--n === 0)
          cb(errState)
      }
    
      function afterGlob (er, results) {
        if (er)
          return cb(er)
    
        n = results.length
        if (n === 0)
          return cb()
    
        results.forEach(function (p) {
          rimraf_(p, options, function CB (er) {
            if (er) {
              if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
                  busyTries < options.maxBusyTries) {
                busyTries ++
                var time = busyTries * 100
                // try again, with the same exact callback as this one.
                return setTimeout(function () {
                  rimraf_(p, options, CB)
                }, time)
              }
    
              // this one won't happen if graceful-fs is used.
              if (er.code === "EMFILE" && timeout < options.emfileWait) {
                return setTimeout(function () {
                  rimraf_(p, options, CB)
                }, timeout ++)
              }
    
              // already gone
              if (er.code === "ENOENT") er = null
            }
    
            timeout = 0
            next(er)
          })
        })
      }
    }
    
    // Two possible strategies.
    // 1. Assume it's a file.  unlink it, then do the dir stuff on EPERM or EISDIR
    // 2. Assume it's a directory.  readdir, then do the file stuff on ENOTDIR
    //
    // Both result in an extra syscall when you guess wrong.  However, there
    // are likely far more normal files in the world than directories.  This
    // is based on the assumption that a the average number of files per
    // directory is >= 1.
    //
    // If anyone ever complains about this, then I guess the strategy could
    // be made configurable somehow.  But until then, YAGNI.
    function rimraf_ (p, options, cb) {
      assert(p)
      assert(options)
      assert(typeof cb === 'function')
    
      // sunos lets the root user unlink directories, which is... weird.
      // so we have to lstat here and make sure it's not a dir.
      options.lstat(p, function (er, st) {
        if (er && er.code === "ENOENT")
          return cb(null)
    
        // Windows can EPERM on stat.  Life is suffering.
        if (er && er.code === "EPERM" && isWindows)
          fixWinEPERM(p, options, er, cb)
    
        if (st && st.isDirectory())
          return rmdir(p, options, er, cb)
    
        options.unlink(p, function (er) {
          if (er) {
            if (er.code === "ENOENT")
              return cb(null)
            if (er.code === "EPERM")
              return (isWindows)
                ? fixWinEPERM(p, options, er, cb)
                : rmdir(p, options, er, cb)
            if (er.code === "EISDIR")
              return rmdir(p, options, er, cb)
          }
          return cb(er)
        })
      })
    }
    
    function fixWinEPERM (p, options, er, cb) {
      assert(p)
      assert(options)
      assert(typeof cb === 'function')
      if (er)
        assert(er instanceof Error)
    
      options.chmod(p, _0666, function (er2) {
        if (er2)
          cb(er2.code === "ENOENT" ? null : er)
        else
          options.stat(p, function(er3, stats) {
            if (er3)
              cb(er3.code === "ENOENT" ? null : er)
            else if (stats.isDirectory())
              rmdir(p, options, er, cb)
            else
              options.unlink(p, cb)
          })
      })
    }
    
    function fixWinEPERMSync (p, options, er) {
      assert(p)
      assert(options)
      if (er)
        assert(er instanceof Error)
    
      try {
        options.chmodSync(p, _0666)
      } catch (er2) {
        if (er2.code === "ENOENT")
          return
        else
          throw er
      }
    
      try {
        var stats = options.statSync(p)
      } catch (er3) {
        if (er3.code === "ENOENT")
          return
        else
          throw er
      }
    
      if (stats.isDirectory())
        rmdirSync(p, options, er)
      else
        options.unlinkSync(p)
    }
    
    function rmdir (p, options, originalEr, cb) {
      assert(p)
      assert(options)
      if (originalEr)
        assert(originalEr instanceof Error)
      assert(typeof cb === 'function')
    
      // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
      // if we guessed wrong, and it's not a directory, then
      // raise the original error.
      options.rmdir(p, function (er) {
        if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
          rmkids(p, options, cb)
        else if (er && er.code === "ENOTDIR")
          cb(originalEr)
        else
          cb(er)
      })
    }
    
    function rmkids(p, options, cb) {
      assert(p)
      assert(options)
      assert(typeof cb === 'function')
    
      options.readdir(p, function (er, files) {
        if (er)
          return cb(er)
        var n = files.length
        if (n === 0)
          return options.rmdir(p, cb)
        var errState
        files.forEach(function (f) {
          rimraf(path.join(p, f), options, function (er) {
            if (errState)
              return
            if (er)
              return cb(errState = er)
            if (--n === 0)
              options.rmdir(p, cb)
          })
        })
      })
    }
    
    // this looks simpler, and is strictly *faster*, but will
    // tie up the JavaScript thread and fail on excessively
    // deep directory trees.
    function rimrafSync (p, options) {
      options = options || {}
      defaults(options)
    
      assert(p, 'rimraf: missing path')
      assert.equal(typeof p, 'string', 'rimraf: path should be a string')
      assert(options, 'rimraf: missing options')
      assert.equal(typeof options, 'object', 'rimraf: options should be object')
    
      var results
    
      if (options.disableGlob || !glob.hasMagic(p)) {
        results = [p]
      } else {
        try {
          options.lstatSync(p)
          results = [p]
        } catch (er) {
          results = glob.sync(p, options.glob)
        }
      }
    
      if (!results.length)
        return
    
      for (var i = 0; i < results.length; i++) {
        var p = results[i]
    
        try {
          var st = options.lstatSync(p)
        } catch (er) {
          if (er.code === "ENOENT")
            return
    
          // Windows can EPERM on stat.  Life is suffering.
          if (er.code === "EPERM" && isWindows)
            fixWinEPERMSync(p, options, er)
        }
    
        try {
          // sunos lets the root user unlink directories, which is... weird.
          if (st && st.isDirectory())
            rmdirSync(p, options, null)
          else
            options.unlinkSync(p)
        } catch (er) {
          if (er.code === "ENOENT")
            return
          if (er.code === "EPERM")
            return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
          if (er.code !== "EISDIR")
            throw er
    
          rmdirSync(p, options, er)
        }
      }
    }
    
    function rmdirSync (p, options, originalEr) {
      assert(p)
      assert(options)
      if (originalEr)
        assert(originalEr instanceof Error)
    
      try {
        options.rmdirSync(p)
      } catch (er) {
        if (er.code === "ENOENT")
          return
        if (er.code === "ENOTDIR")
          throw originalEr
        if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
          rmkidsSync(p, options)
      }
    }
    
    function rmkidsSync (p, options) {
      assert(p)
      assert(options)
      options.readdirSync(p).forEach(function (f) {
        rimrafSync(path.join(p, f), options)
      })
    
      // We only end up here once we got ENOTEMPTY at least once, and
      // at this point, we are guaranteed to have removed all the kids.
      // So, we know that it won't be ENOENT or ENOTDIR or anything else.
      // try really hard to delete stuff on windows, because it has a
      // PROFOUNDLY annoying habit of not closing handles promptly when
      // files are deleted, resulting in spurious ENOTEMPTY errors.
      var retries = isWindows ? 100 : 1
      var i = 0
      do {
        var threw = true
        try {
          var ret = options.rmdirSync(p, options)
          threw = false
          return ret
        } finally {
          if (++i < retries && threw)
            continue
        }
      } while (true)
    }
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321,"assert":24,"fs":83,"glob":143,"path":313}],337:[function(require,module,exports){
    'use strict'
    var Buffer = require('buffer').Buffer
    var inherits = require('inherits')
    var HashBase = require('hash-base')
    
    var ARRAY16 = new Array(16)
    
    var zl = [
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
      7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
      3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
      1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
      4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
    ]
    
    var zr = [
      5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
      6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
      15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
      8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
      12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
    ]
    
    var sl = [
      11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
      7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
      11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
      11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
      9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
    ]
    
    var sr = [
      8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
      9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
      9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
      15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
      8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
    ]
    
    var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]
    var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]
    
    function RIPEMD160 () {
      HashBase.call(this, 64)
    
      // state
      this._a = 0x67452301
      this._b = 0xefcdab89
      this._c = 0x98badcfe
      this._d = 0x10325476
      this._e = 0xc3d2e1f0
    }
    
    inherits(RIPEMD160, HashBase)
    
    RIPEMD160.prototype._update = function () {
      var words = ARRAY16
      for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4)
    
      var al = this._a | 0
      var bl = this._b | 0
      var cl = this._c | 0
      var dl = this._d | 0
      var el = this._e | 0
    
      var ar = this._a | 0
      var br = this._b | 0
      var cr = this._c | 0
      var dr = this._d | 0
      var er = this._e | 0
    
      // computation
      for (var i = 0; i < 80; i += 1) {
        var tl
        var tr
        if (i < 16) {
          tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i])
          tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i])
        } else if (i < 32) {
          tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i])
          tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i])
        } else if (i < 48) {
          tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i])
          tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i])
        } else if (i < 64) {
          tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i])
          tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i])
        } else { // if (i<80) {
          tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i])
          tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i])
        }
    
        al = el
        el = dl
        dl = rotl(cl, 10)
        cl = bl
        bl = tl
    
        ar = er
        er = dr
        dr = rotl(cr, 10)
        cr = br
        br = tr
      }
    
      // update state
      var t = (this._b + cl + dr) | 0
      this._b = (this._c + dl + er) | 0
      this._c = (this._d + el + ar) | 0
      this._d = (this._e + al + br) | 0
      this._e = (this._a + bl + cr) | 0
      this._a = t
    }
    
    RIPEMD160.prototype._digest = function () {
      // create padding and handle blocks
      this._block[this._blockOffset++] = 0x80
      if (this._blockOffset > 56) {
        this._block.fill(0, this._blockOffset, 64)
        this._update()
        this._blockOffset = 0
      }
    
      this._block.fill(0, this._blockOffset, 56)
      this._block.writeUInt32LE(this._length[0], 56)
      this._block.writeUInt32LE(this._length[1], 60)
      this._update()
    
      // produce result
      var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20)
      buffer.writeInt32LE(this._a, 0)
      buffer.writeInt32LE(this._b, 4)
      buffer.writeInt32LE(this._c, 8)
      buffer.writeInt32LE(this._d, 12)
      buffer.writeInt32LE(this._e, 16)
      return buffer
    }
    
    function rotl (x, n) {
      return (x << n) | (x >>> (32 - n))
    }
    
    function fn1 (a, b, c, d, e, m, k, s) {
      return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0
    }
    
    function fn2 (a, b, c, d, e, m, k, s) {
      return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0
    }
    
    function fn3 (a, b, c, d, e, m, k, s) {
      return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0
    }
    
    function fn4 (a, b, c, d, e, m, k, s) {
      return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0
    }
    
    function fn5 (a, b, c, d, e, m, k, s) {
      return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0
    }
    
    module.exports = RIPEMD160
    
    },{"buffer":84,"hash-base":151,"inherits":182}],338:[function(require,module,exports){
    /*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
    /* eslint-disable node/no-deprecated-api */
    var buffer = require('buffer')
    var Buffer = buffer.Buffer
    
    // alternative to using Object.keys for old browsers
    function copyProps (src, dst) {
      for (var key in src) {
        dst[key] = src[key]
      }
    }
    if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
      module.exports = buffer
    } else {
      // Copy properties from require('buffer')
      copyProps(buffer, exports)
      exports.Buffer = SafeBuffer
    }
    
    function SafeBuffer (arg, encodingOrOffset, length) {
      return Buffer(arg, encodingOrOffset, length)
    }
    
    SafeBuffer.prototype = Object.create(Buffer.prototype)
    
    // Copy static methods from Buffer
    copyProps(Buffer, SafeBuffer)
    
    SafeBuffer.from = function (arg, encodingOrOffset, length) {
      if (typeof arg === 'number') {
        throw new TypeError('Argument must not be a number')
      }
      return Buffer(arg, encodingOrOffset, length)
    }
    
    SafeBuffer.alloc = function (size, fill, encoding) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      var buf = Buffer(size)
      if (fill !== undefined) {
        if (typeof encoding === 'string') {
          buf.fill(fill, encoding)
        } else {
          buf.fill(fill)
        }
      } else {
        buf.fill(0)
      }
      return buf
    }
    
    SafeBuffer.allocUnsafe = function (size) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      return Buffer(size)
    }
    
    SafeBuffer.allocUnsafeSlow = function (size) {
      if (typeof size !== 'number') {
        throw new TypeError('Argument must be a number')
      }
      return buffer.SlowBuffer(size)
    }
    
    },{"buffer":84}],339:[function(require,module,exports){
    (function (process){(function (){
    /* eslint-disable node/no-deprecated-api */
    
    'use strict'
    
    var buffer = require('buffer')
    var Buffer = buffer.Buffer
    
    var safer = {}
    
    var key
    
    for (key in buffer) {
      if (!buffer.hasOwnProperty(key)) continue
      if (key === 'SlowBuffer' || key === 'Buffer') continue
      safer[key] = buffer[key]
    }
    
    var Safer = safer.Buffer = {}
    for (key in Buffer) {
      if (!Buffer.hasOwnProperty(key)) continue
      if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue
      Safer[key] = Buffer[key]
    }
    
    safer.Buffer.prototype = Buffer.prototype
    
    if (!Safer.from || Safer.from === Uint8Array.from) {
      Safer.from = function (value, encodingOrOffset, length) {
        if (typeof value === 'number') {
          throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value)
        }
        if (value && typeof value.length === 'undefined') {
          throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value)
        }
        return Buffer(value, encodingOrOffset, length)
      }
    }
    
    if (!Safer.alloc) {
      Safer.alloc = function (size, fill, encoding) {
        if (typeof size !== 'number') {
          throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size)
        }
        if (size < 0 || size >= 2 * (1 << 30)) {
          throw new RangeError('The value "' + size + '" is invalid for option "size"')
        }
        var buf = Buffer(size)
        if (!fill || fill.length === 0) {
          buf.fill(0)
        } else if (typeof encoding === 'string') {
          buf.fill(fill, encoding)
        } else {
          buf.fill(fill)
        }
        return buf
      }
    }
    
    if (!safer.kStringMaxLength) {
      try {
        safer.kStringMaxLength = process.binding('buffer').kStringMaxLength
      } catch (e) {
        // we can't determine kStringMaxLength in environments where process.binding
        // is unsupported, so let's not set it
      }
    }
    
    if (!safer.constants) {
      safer.constants = {
        MAX_LENGTH: safer.kMaxLength
      }
      if (safer.kStringMaxLength) {
        safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength
      }
    }
    
    module.exports = safer
    
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321,"buffer":84}],340:[function(require,module,exports){
    var Buffer = require('safe-buffer').Buffer
    
    // prototype class for hash functions
    function Hash (blockSize, finalSize) {
      this._block = Buffer.alloc(blockSize)
      this._finalSize = finalSize
      this._blockSize = blockSize
      this._len = 0
    }
    
    Hash.prototype.update = function (data, enc) {
      if (typeof data === 'string') {
        enc = enc || 'utf8'
        data = Buffer.from(data, enc)
      }
    
      var block = this._block
      var blockSize = this._blockSize
      var length = data.length
      var accum = this._len
    
      for (var offset = 0; offset < length;) {
        var assigned = accum % blockSize
        var remainder = Math.min(length - offset, blockSize - assigned)
    
        for (var i = 0; i < remainder; i++) {
          block[assigned + i] = data[offset + i]
        }
    
        accum += remainder
        offset += remainder
    
        if ((accum % blockSize) === 0) {
          this._update(block)
        }
      }
    
      this._len += length
      return this
    }
    
    Hash.prototype.digest = function (enc) {
      var rem = this._len % this._blockSize
    
      this._block[rem] = 0x80
    
      // zero (rem + 1) trailing bits, where (rem + 1) is the smallest
      // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize
      this._block.fill(0, rem + 1)
    
      if (rem >= this._finalSize) {
        this._update(this._block)
        this._block.fill(0)
      }
    
      var bits = this._len * 8
    
      // uint32
      if (bits <= 0xffffffff) {
        this._block.writeUInt32BE(bits, this._blockSize - 4)
    
      // uint64
      } else {
        var lowBits = (bits & 0xffffffff) >>> 0
        var highBits = (bits - lowBits) / 0x100000000
    
        this._block.writeUInt32BE(highBits, this._blockSize - 8)
        this._block.writeUInt32BE(lowBits, this._blockSize - 4)
      }
    
      this._update(this._block)
      var hash = this._hash()
    
      return enc ? hash.toString(enc) : hash
    }
    
    Hash.prototype._update = function () {
      throw new Error('_update must be implemented by subclass')
    }
    
    module.exports = Hash
    
    },{"safe-buffer":338}],341:[function(require,module,exports){
    var exports = module.exports = function SHA (algorithm) {
      algorithm = algorithm.toLowerCase()
    
      var Algorithm = exports[algorithm]
      if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
    
      return new Algorithm()
    }
    
    exports.sha = require('./sha')
    exports.sha1 = require('./sha1')
    exports.sha224 = require('./sha224')
    exports.sha256 = require('./sha256')
    exports.sha384 = require('./sha384')
    exports.sha512 = require('./sha512')
    
    },{"./sha":342,"./sha1":343,"./sha224":344,"./sha256":345,"./sha384":346,"./sha512":347}],342:[function(require,module,exports){
    /*
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
     * in FIPS PUB 180-1
     * This source code is derived from sha1.js of the same repository.
     * The difference between SHA-0 and SHA-1 is just a bitwise rotate left
     * operation was added.
     */
    
    var inherits = require('inherits')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var K = [
      0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
    ]
    
    var W = new Array(80)
    
    function Sha () {
      this.init()
      this._w = W
    
      Hash.call(this, 64, 56)
    }
    
    inherits(Sha, Hash)
    
    Sha.prototype.init = function () {
      this._a = 0x67452301
      this._b = 0xefcdab89
      this._c = 0x98badcfe
      this._d = 0x10325476
      this._e = 0xc3d2e1f0
    
      return this
    }
    
    function rotl5 (num) {
      return (num << 5) | (num >>> 27)
    }
    
    function rotl30 (num) {
      return (num << 30) | (num >>> 2)
    }
    
    function ft (s, b, c, d) {
      if (s === 0) return (b & c) | ((~b) & d)
      if (s === 2) return (b & c) | (b & d) | (c & d)
      return b ^ c ^ d
    }
    
    Sha.prototype._update = function (M) {
      var W = this._w
    
      var a = this._a | 0
      var b = this._b | 0
      var c = this._c | 0
      var d = this._d | 0
      var e = this._e | 0
    
      for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
      for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
    
      for (var j = 0; j < 80; ++j) {
        var s = ~~(j / 20)
        var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
    
        e = d
        d = c
        c = rotl30(b)
        b = a
        a = t
      }
    
      this._a = (a + this._a) | 0
      this._b = (b + this._b) | 0
      this._c = (c + this._c) | 0
      this._d = (d + this._d) | 0
      this._e = (e + this._e) | 0
    }
    
    Sha.prototype._hash = function () {
      var H = Buffer.allocUnsafe(20)
    
      H.writeInt32BE(this._a | 0, 0)
      H.writeInt32BE(this._b | 0, 4)
      H.writeInt32BE(this._c | 0, 8)
      H.writeInt32BE(this._d | 0, 12)
      H.writeInt32BE(this._e | 0, 16)
    
      return H
    }
    
    module.exports = Sha
    
    },{"./hash":340,"inherits":182,"safe-buffer":338}],343:[function(require,module,exports){
    /*
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
     * in FIPS PUB 180-1
     * Version 2.1a Copyright Paul Johnston 2000 - 2002.
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     * Distributed under the BSD License
     * See http://pajhome.org.uk/crypt/md5 for details.
     */
    
    var inherits = require('inherits')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var K = [
      0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
    ]
    
    var W = new Array(80)
    
    function Sha1 () {
      this.init()
      this._w = W
    
      Hash.call(this, 64, 56)
    }
    
    inherits(Sha1, Hash)
    
    Sha1.prototype.init = function () {
      this._a = 0x67452301
      this._b = 0xefcdab89
      this._c = 0x98badcfe
      this._d = 0x10325476
      this._e = 0xc3d2e1f0
    
      return this
    }
    
    function rotl1 (num) {
      return (num << 1) | (num >>> 31)
    }
    
    function rotl5 (num) {
      return (num << 5) | (num >>> 27)
    }
    
    function rotl30 (num) {
      return (num << 30) | (num >>> 2)
    }
    
    function ft (s, b, c, d) {
      if (s === 0) return (b & c) | ((~b) & d)
      if (s === 2) return (b & c) | (b & d) | (c & d)
      return b ^ c ^ d
    }
    
    Sha1.prototype._update = function (M) {
      var W = this._w
    
      var a = this._a | 0
      var b = this._b | 0
      var c = this._c | 0
      var d = this._d | 0
      var e = this._e | 0
    
      for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
      for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
    
      for (var j = 0; j < 80; ++j) {
        var s = ~~(j / 20)
        var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
    
        e = d
        d = c
        c = rotl30(b)
        b = a
        a = t
      }
    
      this._a = (a + this._a) | 0
      this._b = (b + this._b) | 0
      this._c = (c + this._c) | 0
      this._d = (d + this._d) | 0
      this._e = (e + this._e) | 0
    }
    
    Sha1.prototype._hash = function () {
      var H = Buffer.allocUnsafe(20)
    
      H.writeInt32BE(this._a | 0, 0)
      H.writeInt32BE(this._b | 0, 4)
      H.writeInt32BE(this._c | 0, 8)
      H.writeInt32BE(this._d | 0, 12)
      H.writeInt32BE(this._e | 0, 16)
    
      return H
    }
    
    module.exports = Sha1
    
    },{"./hash":340,"inherits":182,"safe-buffer":338}],344:[function(require,module,exports){
    /**
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
     * in FIPS 180-2
     * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     *
     */
    
    var inherits = require('inherits')
    var Sha256 = require('./sha256')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var W = new Array(64)
    
    function Sha224 () {
      this.init()
    
      this._w = W // new Array(64)
    
      Hash.call(this, 64, 56)
    }
    
    inherits(Sha224, Sha256)
    
    Sha224.prototype.init = function () {
      this._a = 0xc1059ed8
      this._b = 0x367cd507
      this._c = 0x3070dd17
      this._d = 0xf70e5939
      this._e = 0xffc00b31
      this._f = 0x68581511
      this._g = 0x64f98fa7
      this._h = 0xbefa4fa4
    
      return this
    }
    
    Sha224.prototype._hash = function () {
      var H = Buffer.allocUnsafe(28)
    
      H.writeInt32BE(this._a, 0)
      H.writeInt32BE(this._b, 4)
      H.writeInt32BE(this._c, 8)
      H.writeInt32BE(this._d, 12)
      H.writeInt32BE(this._e, 16)
      H.writeInt32BE(this._f, 20)
      H.writeInt32BE(this._g, 24)
    
      return H
    }
    
    module.exports = Sha224
    
    },{"./hash":340,"./sha256":345,"inherits":182,"safe-buffer":338}],345:[function(require,module,exports){
    /**
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
     * in FIPS 180-2
     * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     *
     */
    
    var inherits = require('inherits')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var K = [
      0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
      0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
      0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
      0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
      0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
      0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
      0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
      0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
      0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
      0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
      0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
      0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
      0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
      0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
      0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
      0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
    ]
    
    var W = new Array(64)
    
    function Sha256 () {
      this.init()
    
      this._w = W // new Array(64)
    
      Hash.call(this, 64, 56)
    }
    
    inherits(Sha256, Hash)
    
    Sha256.prototype.init = function () {
      this._a = 0x6a09e667
      this._b = 0xbb67ae85
      this._c = 0x3c6ef372
      this._d = 0xa54ff53a
      this._e = 0x510e527f
      this._f = 0x9b05688c
      this._g = 0x1f83d9ab
      this._h = 0x5be0cd19
    
      return this
    }
    
    function ch (x, y, z) {
      return z ^ (x & (y ^ z))
    }
    
    function maj (x, y, z) {
      return (x & y) | (z & (x | y))
    }
    
    function sigma0 (x) {
      return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
    }
    
    function sigma1 (x) {
      return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
    }
    
    function gamma0 (x) {
      return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
    }
    
    function gamma1 (x) {
      return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
    }
    
    Sha256.prototype._update = function (M) {
      var W = this._w
    
      var a = this._a | 0
      var b = this._b | 0
      var c = this._c | 0
      var d = this._d | 0
      var e = this._e | 0
      var f = this._f | 0
      var g = this._g | 0
      var h = this._h | 0
    
      for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
      for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
    
      for (var j = 0; j < 64; ++j) {
        var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
        var T2 = (sigma0(a) + maj(a, b, c)) | 0
    
        h = g
        g = f
        f = e
        e = (d + T1) | 0
        d = c
        c = b
        b = a
        a = (T1 + T2) | 0
      }
    
      this._a = (a + this._a) | 0
      this._b = (b + this._b) | 0
      this._c = (c + this._c) | 0
      this._d = (d + this._d) | 0
      this._e = (e + this._e) | 0
      this._f = (f + this._f) | 0
      this._g = (g + this._g) | 0
      this._h = (h + this._h) | 0
    }
    
    Sha256.prototype._hash = function () {
      var H = Buffer.allocUnsafe(32)
    
      H.writeInt32BE(this._a, 0)
      H.writeInt32BE(this._b, 4)
      H.writeInt32BE(this._c, 8)
      H.writeInt32BE(this._d, 12)
      H.writeInt32BE(this._e, 16)
      H.writeInt32BE(this._f, 20)
      H.writeInt32BE(this._g, 24)
      H.writeInt32BE(this._h, 28)
    
      return H
    }
    
    module.exports = Sha256
    
    },{"./hash":340,"inherits":182,"safe-buffer":338}],346:[function(require,module,exports){
    var inherits = require('inherits')
    var SHA512 = require('./sha512')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var W = new Array(160)
    
    function Sha384 () {
      this.init()
      this._w = W
    
      Hash.call(this, 128, 112)
    }
    
    inherits(Sha384, SHA512)
    
    Sha384.prototype.init = function () {
      this._ah = 0xcbbb9d5d
      this._bh = 0x629a292a
      this._ch = 0x9159015a
      this._dh = 0x152fecd8
      this._eh = 0x67332667
      this._fh = 0x8eb44a87
      this._gh = 0xdb0c2e0d
      this._hh = 0x47b5481d
    
      this._al = 0xc1059ed8
      this._bl = 0x367cd507
      this._cl = 0x3070dd17
      this._dl = 0xf70e5939
      this._el = 0xffc00b31
      this._fl = 0x68581511
      this._gl = 0x64f98fa7
      this._hl = 0xbefa4fa4
    
      return this
    }
    
    Sha384.prototype._hash = function () {
      var H = Buffer.allocUnsafe(48)
    
      function writeInt64BE (h, l, offset) {
        H.writeInt32BE(h, offset)
        H.writeInt32BE(l, offset + 4)
      }
    
      writeInt64BE(this._ah, this._al, 0)
      writeInt64BE(this._bh, this._bl, 8)
      writeInt64BE(this._ch, this._cl, 16)
      writeInt64BE(this._dh, this._dl, 24)
      writeInt64BE(this._eh, this._el, 32)
      writeInt64BE(this._fh, this._fl, 40)
    
      return H
    }
    
    module.exports = Sha384
    
    },{"./hash":340,"./sha512":347,"inherits":182,"safe-buffer":338}],347:[function(require,module,exports){
    var inherits = require('inherits')
    var Hash = require('./hash')
    var Buffer = require('safe-buffer').Buffer
    
    var K = [
      0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
      0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
      0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
      0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
      0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
      0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
      0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
      0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
      0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
      0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
      0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
      0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
      0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
      0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
      0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
      0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
      0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
      0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
      0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
      0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
      0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
      0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
      0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
      0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
      0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
      0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
      0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
      0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
      0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
      0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
      0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
      0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
      0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
      0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
      0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
      0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
      0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
      0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
      0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
      0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
    ]
    
    var W = new Array(160)
    
    function Sha512 () {
      this.init()
      this._w = W
    
      Hash.call(this, 128, 112)
    }
    
    inherits(Sha512, Hash)
    
    Sha512.prototype.init = function () {
      this._ah = 0x6a09e667
      this._bh = 0xbb67ae85
      this._ch = 0x3c6ef372
      this._dh = 0xa54ff53a
      this._eh = 0x510e527f
      this._fh = 0x9b05688c
      this._gh = 0x1f83d9ab
      this._hh = 0x5be0cd19
    
      this._al = 0xf3bcc908
      this._bl = 0x84caa73b
      this._cl = 0xfe94f82b
      this._dl = 0x5f1d36f1
      this._el = 0xade682d1
      this._fl = 0x2b3e6c1f
      this._gl = 0xfb41bd6b
      this._hl = 0x137e2179
    
      return this
    }
    
    function Ch (x, y, z) {
      return z ^ (x & (y ^ z))
    }
    
    function maj (x, y, z) {
      return (x & y) | (z & (x | y))
    }
    
    function sigma0 (x, xl) {
      return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
    }
    
    function sigma1 (x, xl) {
      return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
    }
    
    function Gamma0 (x, xl) {
      return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
    }
    
    function Gamma0l (x, xl) {
      return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
    }
    
    function Gamma1 (x, xl) {
      return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
    }
    
    function Gamma1l (x, xl) {
      return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
    }
    
    function getCarry (a, b) {
      return (a >>> 0) < (b >>> 0) ? 1 : 0
    }
    
    Sha512.prototype._update = function (M) {
      var W = this._w
    
      var ah = this._ah | 0
      var bh = this._bh | 0
      var ch = this._ch | 0
      var dh = this._dh | 0
      var eh = this._eh | 0
      var fh = this._fh | 0
      var gh = this._gh | 0
      var hh = this._hh | 0
    
      var al = this._al | 0
      var bl = this._bl | 0
      var cl = this._cl | 0
      var dl = this._dl | 0
      var el = this._el | 0
      var fl = this._fl | 0
      var gl = this._gl | 0
      var hl = this._hl | 0
    
      for (var i = 0; i < 32; i += 2) {
        W[i] = M.readInt32BE(i * 4)
        W[i + 1] = M.readInt32BE(i * 4 + 4)
      }
      for (; i < 160; i += 2) {
        var xh = W[i - 15 * 2]
        var xl = W[i - 15 * 2 + 1]
        var gamma0 = Gamma0(xh, xl)
        var gamma0l = Gamma0l(xl, xh)
    
        xh = W[i - 2 * 2]
        xl = W[i - 2 * 2 + 1]
        var gamma1 = Gamma1(xh, xl)
        var gamma1l = Gamma1l(xl, xh)
    
        // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
        var Wi7h = W[i - 7 * 2]
        var Wi7l = W[i - 7 * 2 + 1]
    
        var Wi16h = W[i - 16 * 2]
        var Wi16l = W[i - 16 * 2 + 1]
    
        var Wil = (gamma0l + Wi7l) | 0
        var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
        Wil = (Wil + gamma1l) | 0
        Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
        Wil = (Wil + Wi16l) | 0
        Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
    
        W[i] = Wih
        W[i + 1] = Wil
      }
    
      for (var j = 0; j < 160; j += 2) {
        Wih = W[j]
        Wil = W[j + 1]
    
        var majh = maj(ah, bh, ch)
        var majl = maj(al, bl, cl)
    
        var sigma0h = sigma0(ah, al)
        var sigma0l = sigma0(al, ah)
        var sigma1h = sigma1(eh, el)
        var sigma1l = sigma1(el, eh)
    
        // t1 = h + sigma1 + ch + K[j] + W[j]
        var Kih = K[j]
        var Kil = K[j + 1]
    
        var chh = Ch(eh, fh, gh)
        var chl = Ch(el, fl, gl)
    
        var t1l = (hl + sigma1l) | 0
        var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
        t1l = (t1l + chl) | 0
        t1h = (t1h + chh + getCarry(t1l, chl)) | 0
        t1l = (t1l + Kil) | 0
        t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
        t1l = (t1l + Wil) | 0
        t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
    
        // t2 = sigma0 + maj
        var t2l = (sigma0l + majl) | 0
        var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
    
        hh = gh
        hl = gl
        gh = fh
        gl = fl
        fh = eh
        fl = el
        el = (dl + t1l) | 0
        eh = (dh + t1h + getCarry(el, dl)) | 0
        dh = ch
        dl = cl
        ch = bh
        cl = bl
        bh = ah
        bl = al
        al = (t1l + t2l) | 0
        ah = (t1h + t2h + getCarry(al, t1l)) | 0
      }
    
      this._al = (this._al + al) | 0
      this._bl = (this._bl + bl) | 0
      this._cl = (this._cl + cl) | 0
      this._dl = (this._dl + dl) | 0
      this._el = (this._el + el) | 0
      this._fl = (this._fl + fl) | 0
      this._gl = (this._gl + gl) | 0
      this._hl = (this._hl + hl) | 0
    
      this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
      this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
      this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
      this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
      this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
      this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
      this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
      this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
    }
    
    Sha512.prototype._hash = function () {
      var H = Buffer.allocUnsafe(64)
    
      function writeInt64BE (h, l, offset) {
        H.writeInt32BE(h, offset)
        H.writeInt32BE(l, offset + 4)
      }
    
      writeInt64BE(this._ah, this._al, 0)
      writeInt64BE(this._bh, this._bl, 8)
      writeInt64BE(this._ch, this._cl, 16)
      writeInt64BE(this._dh, this._dl, 24)
      writeInt64BE(this._eh, this._el, 32)
      writeInt64BE(this._fh, this._fl, 40)
      writeInt64BE(this._gh, this._gl, 48)
      writeInt64BE(this._hh, this._hl, 56)
    
      return H
    }
    
    module.exports = Sha512
    
    },{"./hash":340,"inherits":182,"safe-buffer":338}],348:[function(require,module,exports){
    'use strict';
    
    var GetIntrinsic = require('get-intrinsic');
    var callBound = require('call-bind/callBound');
    var inspect = require('object-inspect');
    
    var $TypeError = GetIntrinsic('%TypeError%');
    var $WeakMap = GetIntrinsic('%WeakMap%', true);
    var $Map = GetIntrinsic('%Map%', true);
    
    var $weakMapGet = callBound('WeakMap.prototype.get', true);
    var $weakMapSet = callBound('WeakMap.prototype.set', true);
    var $weakMapHas = callBound('WeakMap.prototype.has', true);
    var $mapGet = callBound('Map.prototype.get', true);
    var $mapSet = callBound('Map.prototype.set', true);
    var $mapHas = callBound('Map.prototype.has', true);
    
    /*
     * This function traverses the list returning the node corresponding to the
     * given key.
     *
     * That node is also moved to the head of the list, so that if it's accessed
     * again we don't need to traverse the whole list. By doing so, all the recently
     * used nodes can be accessed relatively quickly.
     */
    var listGetNode = function (list, key) { // eslint-disable-line consistent-return
        for (var prev = list, curr; (curr = prev.next) !== null; prev = curr) {
            if (curr.key === key) {
                prev.next = curr.next;
                curr.next = list.next;
                list.next = curr; // eslint-disable-line no-param-reassign
                return curr;
            }
        }
    };
    
    var listGet = function (objects, key) {
        var node = listGetNode(objects, key);
        return node && node.value;
    };
    var listSet = function (objects, key, value) {
        var node = listGetNode(objects, key);
        if (node) {
            node.value = value;
        } else {
            // Prepend the new node to the beginning of the list
            objects.next = { // eslint-disable-line no-param-reassign
                key: key,
                next: objects.next,
                value: value
            };
        }
    };
    var listHas = function (objects, key) {
        return !!listGetNode(objects, key);
    };
    
    module.exports = function getSideChannel() {
        var $wm;
        var $m;
        var $o;
        var channel = {
            assert: function (key) {
                if (!channel.has(key)) {
                    throw new $TypeError('Side channel does not contain ' + inspect(key));
                }
            },
            get: function (key) { // eslint-disable-line consistent-return
                if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
                    if ($wm) {
                        return $weakMapGet($wm, key);
                    }
                } else if ($Map) {
                    if ($m) {
                        return $mapGet($m, key);
                    }
                } else {
                    if ($o) { // eslint-disable-line no-lonely-if
                        return listGet($o, key);
                    }
                }
            },
            has: function (key) {
                if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
                    if ($wm) {
                        return $weakMapHas($wm, key);
                    }
                } else if ($Map) {
                    if ($m) {
                        return $mapHas($m, key);
                    }
                } else {
                    if ($o) { // eslint-disable-line no-lonely-if
                        return listHas($o, key);
                    }
                }
                return false;
            },
            set: function (key, value) {
                if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
                    if (!$wm) {
                        $wm = new $WeakMap();
                    }
                    $weakMapSet($wm, key, value);
                } else if ($Map) {
                    if (!$m) {
                        $m = new $Map();
                    }
                    $mapSet($m, key, value);
                } else {
                    if (!$o) {
                        /*
                         * Initialize the linked list as an empty node, so that we don't have
                         * to special-case handling of the first node: we can always refer to
                         * it as (previous node).next, instead of something like (list).head
                         */
                        $o = { key: {}, next: null };
                    }
                    listSet($o, key, value);
                }
            }
        };
        return channel;
    };
    
    },{"call-bind/callBound":88,"get-intrinsic":141,"object-inspect":289}],349:[function(require,module,exports){
    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
        typeof define === 'function' && define.amd ? define(['exports'], factory) :
        (global = global || self, factory(global.sourcemapCodec = {}));
    }(this, function (exports) { 'use strict';
    
        var charToInteger = {};
        var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
        for (var i = 0; i < chars.length; i++) {
            charToInteger[chars.charCodeAt(i)] = i;
        }
        function decode(mappings) {
            var decoded = [];
            var line = [];
            var segment = [
                0,
                0,
                0,
                0,
                0,
            ];
            var j = 0;
            for (var i = 0, shift = 0, value = 0; i < mappings.length; i++) {
                var c = mappings.charCodeAt(i);
                if (c === 44) { // ","
                    segmentify(line, segment, j);
                    j = 0;
                }
                else if (c === 59) { // ";"
                    segmentify(line, segment, j);
                    j = 0;
                    decoded.push(line);
                    line = [];
                    segment[0] = 0;
                }
                else {
                    var integer = charToInteger[c];
                    if (integer === undefined) {
                        throw new Error('Invalid character (' + String.fromCharCode(c) + ')');
                    }
                    var hasContinuationBit = integer & 32;
                    integer &= 31;
                    value += integer << shift;
                    if (hasContinuationBit) {
                        shift += 5;
                    }
                    else {
                        var shouldNegate = value & 1;
                        value >>>= 1;
                        if (shouldNegate) {
                            value = value === 0 ? -0x80000000 : -value;
                        }
                        segment[j] += value;
                        j++;
                        value = shift = 0; // reset
                    }
                }
            }
            segmentify(line, segment, j);
            decoded.push(line);
            return decoded;
        }
        function segmentify(line, segment, j) {
            // This looks ugly, but we're creating specialized arrays with a specific
            // length. This is much faster than creating a new array (which v8 expands to
            // a capacity of 17 after pushing the first item), or slicing out a subarray
            // (which is slow). Length 4 is assumed to be the most frequent, followed by
            // length 5 (since not everything will have an associated name), followed by
            // length 1 (it's probably rare for a source substring to not have an
            // associated segment data).
            if (j === 4)
                line.push([segment[0], segment[1], segment[2], segment[3]]);
            else if (j === 5)
                line.push([segment[0], segment[1], segment[2], segment[3], segment[4]]);
            else if (j === 1)
                line.push([segment[0]]);
        }
        function encode(decoded) {
            var sourceFileIndex = 0; // second field
            var sourceCodeLine = 0; // third field
            var sourceCodeColumn = 0; // fourth field
            var nameIndex = 0; // fifth field
            var mappings = '';
            for (var i = 0; i < decoded.length; i++) {
                var line = decoded[i];
                if (i > 0)
                    mappings += ';';
                if (line.length === 0)
                    continue;
                var generatedCodeColumn = 0; // first field
                var lineMappings = [];
                for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
                    var segment = line_1[_i];
                    var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
                    generatedCodeColumn = segment[0];
                    if (segment.length > 1) {
                        segmentMappings +=
                            encodeInteger(segment[1] - sourceFileIndex) +
                                encodeInteger(segment[2] - sourceCodeLine) +
                                encodeInteger(segment[3] - sourceCodeColumn);
                        sourceFileIndex = segment[1];
                        sourceCodeLine = segment[2];
                        sourceCodeColumn = segment[3];
                    }
                    if (segment.length === 5) {
                        segmentMappings += encodeInteger(segment[4] - nameIndex);
                        nameIndex = segment[4];
                    }
                    lineMappings.push(segmentMappings);
                }
                mappings += lineMappings.join(',');
            }
            return mappings;
        }
        function encodeInteger(num) {
            var result = '';
            num = num < 0 ? (-num << 1) | 1 : num << 1;
            do {
                var clamped = num & 31;
                num >>>= 5;
                if (num > 0) {
                    clamped |= 32;
                }
                result += chars[clamped];
            } while (num > 0);
            return result;
        }
    
        exports.decode = decode;
        exports.encode = encode;
    
        Object.defineProperty(exports, '__esModule', { value: true });
    
    }));
    
    
    },{}],350:[function(require,module,exports){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    module.exports = Stream;
    
    var EE = require('events').EventEmitter;
    var inherits = require('inherits');
    
    inherits(Stream, EE);
    Stream.Readable = require('readable-stream/lib/_stream_readable.js');
    Stream.Writable = require('readable-stream/lib/_stream_writable.js');
    Stream.Duplex = require('readable-stream/lib/_stream_duplex.js');
    Stream.Transform = require('readable-stream/lib/_stream_transform.js');
    Stream.PassThrough = require('readable-stream/lib/_stream_passthrough.js');
    Stream.finished = require('readable-stream/lib/internal/streams/end-of-stream.js')
    Stream.pipeline = require('readable-stream/lib/internal/streams/pipeline.js')
    
    // Backwards-compat with node 0.4.x
    Stream.Stream = Stream;
    
    
    
    // old-style streams.  Note that the pipe method (the only relevant
    // part of this class) is overridden in the Readable class.
    
    function Stream() {
      EE.call(this);
    }
    
    Stream.prototype.pipe = function(dest, options) {
      var source = this;
    
      function ondata(chunk) {
        if (dest.writable) {
          if (false === dest.write(chunk) && source.pause) {
            source.pause();
          }
        }
      }
    
      source.on('data', ondata);
    
      function ondrain() {
        if (source.readable && source.resume) {
          source.resume();
        }
      }
    
      dest.on('drain', ondrain);
    
      // If the 'end' option is not supplied, dest.end() will be called when
      // source gets the 'end' or 'close' events.  Only dest.end() once.
      if (!dest._isStdio && (!options || options.end !== false)) {
        source.on('end', onend);
        source.on('close', onclose);
      }
    
      var didOnEnd = false;
      function onend() {
        if (didOnEnd) return;
        didOnEnd = true;
    
        dest.end();
      }
    
    
      function onclose() {
        if (didOnEnd) return;
        didOnEnd = true;
    
        if (typeof dest.destroy === 'function') dest.destroy();
      }
    
      // don't leave dangling pipes when there are errors.
      function onerror(er) {
        cleanup();
        if (EE.listenerCount(this, 'error') === 0) {
          throw er; // Unhandled stream error in pipe.
        }
      }
    
      source.on('error', onerror);
      dest.on('error', onerror);
    
      // remove all the event listeners that were added.
      function cleanup() {
        source.removeListener('data', ondata);
        dest.removeListener('drain', ondrain);
    
        source.removeListener('end', onend);
        source.removeListener('close', onclose);
    
        source.removeListener('error', onerror);
        dest.removeListener('error', onerror);
    
        source.removeListener('end', cleanup);
        source.removeListener('close', cleanup);
    
        dest.removeListener('close', cleanup);
      }
    
      source.on('end', cleanup);
      source.on('close', cleanup);
    
      dest.on('close', cleanup);
    
      dest.emit('pipe', source);
    
      // Allow for unix-like usage: A.pipe(B).pipe(C)
      return dest;
    };
    
    },{"events":134,"inherits":182,"readable-stream/lib/_stream_duplex.js":352,"readable-stream/lib/_stream_passthrough.js":353,"readable-stream/lib/_stream_readable.js":354,"readable-stream/lib/_stream_transform.js":355,"readable-stream/lib/_stream_writable.js":356,"readable-stream/lib/internal/streams/end-of-stream.js":360,"readable-stream/lib/internal/streams/pipeline.js":362}],351:[function(require,module,exports){
    arguments[4][66][0].apply(exports,arguments)
    },{"dup":66}],352:[function(require,module,exports){
    (function (process){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // a duplex stream is just a stream that is both readable and writable.
    // Since JS doesn't have multiple prototypal inheritance, this class
    // prototypally inherits from Readable, and then parasitically from
    // Writable.
    
    'use strict';
    
    /*<replacement>*/
    var objectKeys = Object.keys || function (obj) {
      var keys = [];
      for (var key in obj) keys.push(key);
      return keys;
    };
    /*</replacement>*/
    
    module.exports = Duplex;
    var Readable = require('./_stream_readable');
    var Writable = require('./_stream_writable');
    require('inherits')(Duplex, Readable);
    {
      // Allow the keys array to be GC'ed.
      var keys = objectKeys(Writable.prototype);
      for (var v = 0; v < keys.length; v++) {
        var method = keys[v];
        if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
      }
    }
    function Duplex(options) {
      if (!(this instanceof Duplex)) return new Duplex(options);
      Readable.call(this, options);
      Writable.call(this, options);
      this.allowHalfOpen = true;
      if (options) {
        if (options.readable === false) this.readable = false;
        if (options.writable === false) this.writable = false;
        if (options.allowHalfOpen === false) {
          this.allowHalfOpen = false;
          this.once('end', onend);
        }
      }
    }
    Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    Object.defineProperty(Duplex.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    
    // the no-half-open enforcer
    function onend() {
      // If the writable side ended, then we're ok.
      if (this._writableState.ended) return;
    
      // no more data can be written.
      // But allow more writes to happen in this tick.
      process.nextTick(onEndNT, this);
    }
    function onEndNT(self) {
      self.end();
    }
    Object.defineProperty(Duplex.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined || this._writableState === undefined) {
          return false;
        }
        return this._readableState.destroyed && this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (this._readableState === undefined || this._writableState === undefined) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
        this._writableState.destroyed = value;
      }
    });
    }).call(this)}).call(this,require('_process'))
    
    },{"./_stream_readable":354,"./_stream_writable":356,"_process":321,"inherits":182}],353:[function(require,module,exports){
    arguments[4][68][0].apply(exports,arguments)
    },{"./_stream_transform":355,"dup":68,"inherits":182}],354:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    module.exports = Readable;
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Readable.ReadableState = ReadableState;
    
    /*<replacement>*/
    var EE = require('events').EventEmitter;
    var EElistenerCount = function EElistenerCount(emitter, type) {
      return emitter.listeners(type).length;
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    
    /*<replacement>*/
    var debugUtil = require('util');
    var debug;
    if (debugUtil && debugUtil.debuglog) {
      debug = debugUtil.debuglog('stream');
    } else {
      debug = function debug() {};
    }
    /*</replacement>*/
    
    var BufferList = require('./internal/streams/buffer_list');
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;
    
    // Lazy loaded to improve the startup performance.
    var StringDecoder;
    var createReadableStreamAsyncIterator;
    var from;
    require('inherits')(Readable, Stream);
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
    function prependListener(emitter, event, fn) {
      // Sadly this is not cacheable as some libraries bundle their own
      // event emitter implementation with them.
      if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
    
      // This is a hack to make sure that our error handler is attached before any
      // userland ones.  NEVER DO THIS. This is here only because this code needs
      // to continue to work with older versions of Node.js that do not include
      // the prependListener() method. The goal is to eventually remove this hack.
      if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
    }
    function ReadableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream.
      // These options can be provided separately as readableXXX and writableXXX.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag. Used to make read(n) ignore n and to
      // make all the buffer merging and length checks go away
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
    
      // the point at which it stops calling _read() to fill the buffer
      // Note: 0 is a valid value, means "don't call _read preemptively ever"
      this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex);
    
      // A linked list is used to store data chunks instead of an array because the
      // linked list can remove elements from the beginning faster than
      // array.shift()
      this.buffer = new BufferList();
      this.length = 0;
      this.pipes = null;
      this.pipesCount = 0;
      this.flowing = null;
      this.ended = false;
      this.endEmitted = false;
      this.reading = false;
    
      // a flag to be able to tell if the event 'readable'/'data' is emitted
      // immediately, or on a later tick.  We set this to true at first, because
      // any actions that shouldn't happen until "later" should generally also
      // not happen before the first read call.
      this.sync = true;
    
      // whenever we return null, then we set a flag to say
      // that we're awaiting a 'readable' event emission.
      this.needReadable = false;
      this.emittedReadable = false;
      this.readableListening = false;
      this.resumeScheduled = false;
      this.paused = true;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'end' (and potentially 'finish')
      this.autoDestroy = !!options.autoDestroy;
    
      // has it been destroyed
      this.destroyed = false;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // the number of writers that are awaiting a drain event in .pipe()s
      this.awaitDrain = 0;
    
      // if true, a maybeReadMore has been scheduled
      this.readingMore = false;
      this.decoder = null;
      this.encoding = null;
      if (options.encoding) {
        if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
        this.decoder = new StringDecoder(options.encoding);
        this.encoding = options.encoding;
      }
    }
    function Readable(options) {
      Duplex = Duplex || require('./_stream_duplex');
      if (!(this instanceof Readable)) return new Readable(options);
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the ReadableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      this._readableState = new ReadableState(options, this, isDuplex);
    
      // legacy
      this.readable = true;
      if (options) {
        if (typeof options.read === 'function') this._read = options.read;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
      }
      Stream.call(this);
    }
    Object.defineProperty(Readable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._readableState === undefined) {
          return false;
        }
        return this._readableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._readableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._readableState.destroyed = value;
      }
    });
    Readable.prototype.destroy = destroyImpl.destroy;
    Readable.prototype._undestroy = destroyImpl.undestroy;
    Readable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    
    // Manually shove something into the read() buffer.
    // This returns true if the highWaterMark has not been hit yet,
    // similar to how Writable.write() returns true if you should
    // write() some more.
    Readable.prototype.push = function (chunk, encoding) {
      var state = this._readableState;
      var skipChunkCheck;
      if (!state.objectMode) {
        if (typeof chunk === 'string') {
          encoding = encoding || state.defaultEncoding;
          if (encoding !== state.encoding) {
            chunk = Buffer.from(chunk, encoding);
            encoding = '';
          }
          skipChunkCheck = true;
        }
      } else {
        skipChunkCheck = true;
      }
      return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
    };
    
    // Unshift should *always* be something directly out of read()
    Readable.prototype.unshift = function (chunk) {
      return readableAddChunk(this, chunk, null, true, false);
    };
    function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
      debug('readableAddChunk', chunk);
      var state = stream._readableState;
      if (chunk === null) {
        state.reading = false;
        onEofChunk(stream, state);
      } else {
        var er;
        if (!skipChunkCheck) er = chunkInvalid(state, chunk);
        if (er) {
          errorOrDestroy(stream, er);
        } else if (state.objectMode || chunk && chunk.length > 0) {
          if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
            chunk = _uint8ArrayToBuffer(chunk);
          }
          if (addToFront) {
            if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true);
          } else if (state.ended) {
            errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF());
          } else if (state.destroyed) {
            return false;
          } else {
            state.reading = false;
            if (state.decoder && !encoding) {
              chunk = state.decoder.write(chunk);
              if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
            } else {
              addChunk(stream, state, chunk, false);
            }
          }
        } else if (!addToFront) {
          state.reading = false;
          maybeReadMore(stream, state);
        }
      }
    
      // We can push more data if we are below the highWaterMark.
      // Also, if we have no data yet, we can stand some more bytes.
      // This is to work around cases where hwm=0, such as the repl.
      return !state.ended && (state.length < state.highWaterMark || state.length === 0);
    }
    function addChunk(stream, state, chunk, addToFront) {
      if (state.flowing && state.length === 0 && !state.sync) {
        state.awaitDrain = 0;
        stream.emit('data', chunk);
      } else {
        // update the buffer info.
        state.length += state.objectMode ? 1 : chunk.length;
        if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
        if (state.needReadable) emitReadable(stream);
      }
      maybeReadMore(stream, state);
    }
    function chunkInvalid(state, chunk) {
      var er;
      if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
      }
      return er;
    }
    Readable.prototype.isPaused = function () {
      return this._readableState.flowing === false;
    };
    
    // backwards compatibility.
    Readable.prototype.setEncoding = function (enc) {
      if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
      var decoder = new StringDecoder(enc);
      this._readableState.decoder = decoder;
      // If setEncoding(null), decoder.encoding equals utf8
      this._readableState.encoding = this._readableState.decoder.encoding;
    
      // Iterate over current buffer to convert already stored Buffers:
      var p = this._readableState.buffer.head;
      var content = '';
      while (p !== null) {
        content += decoder.write(p.data);
        p = p.next;
      }
      this._readableState.buffer.clear();
      if (content !== '') this._readableState.buffer.push(content);
      this._readableState.length = content.length;
      return this;
    };
    
    // Don't raise the hwm > 1GB
    var MAX_HWM = 0x40000000;
    function computeNewHighWaterMark(n) {
      if (n >= MAX_HWM) {
        // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE.
        n = MAX_HWM;
      } else {
        // Get the next highest power of 2 to prevent increasing hwm excessively in
        // tiny amounts
        n--;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        n++;
      }
      return n;
    }
    
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function howMuchToRead(n, state) {
      if (n <= 0 || state.length === 0 && state.ended) return 0;
      if (state.objectMode) return 1;
      if (n !== n) {
        // Only flow one buffer at a time
        if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
      }
      // If we're asking for more than the current hwm, then raise the hwm.
      if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
      if (n <= state.length) return n;
      // Don't have enough
      if (!state.ended) {
        state.needReadable = true;
        return 0;
      }
      return state.length;
    }
    
    // you can override either this method, or the async _read(n) below.
    Readable.prototype.read = function (n) {
      debug('read', n);
      n = parseInt(n, 10);
      var state = this._readableState;
      var nOrig = n;
      if (n !== 0) state.emittedReadable = false;
    
      // if we're doing read(0) to trigger a readable event, but we
      // already have a bunch of data in the buffer, then just trigger
      // the 'readable' event and move on.
      if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) {
        debug('read: emitReadable', state.length, state.ended);
        if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
        return null;
      }
      n = howMuchToRead(n, state);
    
      // if we've ended, and we're now clear, then finish it up.
      if (n === 0 && state.ended) {
        if (state.length === 0) endReadable(this);
        return null;
      }
    
      // All the actual chunk generation logic needs to be
      // *below* the call to _read.  The reason is that in certain
      // synthetic stream cases, such as passthrough streams, _read
      // may be a completely synchronous operation which may change
      // the state of the read buffer, providing enough data when
      // before there was *not* enough.
      //
      // So, the steps are:
      // 1. Figure out what the state of things will be after we do
      // a read from the buffer.
      //
      // 2. If that resulting state will trigger a _read, then call _read.
      // Note that this may be asynchronous, or synchronous.  Yes, it is
      // deeply ugly to write APIs this way, but that still doesn't mean
      // that the Readable class should behave improperly, as streams are
      // designed to be sync/async agnostic.
      // Take note if the _read call is sync or async (ie, if the read call
      // has returned yet), so that we know whether or not it's safe to emit
      // 'readable' etc.
      //
      // 3. Actually pull the requested chunks out of the buffer and return.
    
      // if we need a readable event, then we need to do some reading.
      var doRead = state.needReadable;
      debug('need readable', doRead);
    
      // if we currently have less than the highWaterMark, then also read some
      if (state.length === 0 || state.length - n < state.highWaterMark) {
        doRead = true;
        debug('length less than watermark', doRead);
      }
    
      // however, if we've ended, then there's no point, and if we're already
      // reading, then it's unnecessary.
      if (state.ended || state.reading) {
        doRead = false;
        debug('reading or ended', doRead);
      } else if (doRead) {
        debug('do read');
        state.reading = true;
        state.sync = true;
        // if the length is currently zero, then we *need* a readable event.
        if (state.length === 0) state.needReadable = true;
        // call internal read method
        this._read(state.highWaterMark);
        state.sync = false;
        // If _read pushed data synchronously, then `reading` will be false,
        // and we need to re-evaluate how much data we can return to the user.
        if (!state.reading) n = howMuchToRead(nOrig, state);
      }
      var ret;
      if (n > 0) ret = fromList(n, state);else ret = null;
      if (ret === null) {
        state.needReadable = state.length <= state.highWaterMark;
        n = 0;
      } else {
        state.length -= n;
        state.awaitDrain = 0;
      }
      if (state.length === 0) {
        // If we have nothing in the buffer, then we want to know
        // as soon as we *do* get something into the buffer.
        if (!state.ended) state.needReadable = true;
    
        // If we tried to read() past the EOF, then emit end on the next tick.
        if (nOrig !== n && state.ended) endReadable(this);
      }
      if (ret !== null) this.emit('data', ret);
      return ret;
    };
    function onEofChunk(stream, state) {
      debug('onEofChunk');
      if (state.ended) return;
      if (state.decoder) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length) {
          state.buffer.push(chunk);
          state.length += state.objectMode ? 1 : chunk.length;
        }
      }
      state.ended = true;
      if (state.sync) {
        // if we are sync, wait until next tick to emit the data.
        // Otherwise we risk emitting data in the flow()
        // the readable code triggers during a read() call
        emitReadable(stream);
      } else {
        // emit 'readable' now to make sure it gets picked up.
        state.needReadable = false;
        if (!state.emittedReadable) {
          state.emittedReadable = true;
          emitReadable_(stream);
        }
      }
    }
    
    // Don't emit readable right away in sync mode, because this can trigger
    // another read() call => stack overflow.  This way, it might trigger
    // a nextTick recursion warning, but that's not so bad.
    function emitReadable(stream) {
      var state = stream._readableState;
      debug('emitReadable', state.needReadable, state.emittedReadable);
      state.needReadable = false;
      if (!state.emittedReadable) {
        debug('emitReadable', state.flowing);
        state.emittedReadable = true;
        process.nextTick(emitReadable_, stream);
      }
    }
    function emitReadable_(stream) {
      var state = stream._readableState;
      debug('emitReadable_', state.destroyed, state.length, state.ended);
      if (!state.destroyed && (state.length || state.ended)) {
        stream.emit('readable');
        state.emittedReadable = false;
      }
    
      // The stream needs another readable event if
      // 1. It is not flowing, as the flow mechanism will take
      //    care of it.
      // 2. It is not ended.
      // 3. It is below the highWaterMark, so we can schedule
      //    another readable later.
      state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark;
      flow(stream);
    }
    
    // at this point, the user has presumably seen the 'readable' event,
    // and called read() to consume some data.  that may have triggered
    // in turn another _read(n) call, in which case reading = true if
    // it's in progress.
    // However, if we're not ended, or reading, and the length < hwm,
    // then go ahead and try to read some more preemptively.
    function maybeReadMore(stream, state) {
      if (!state.readingMore) {
        state.readingMore = true;
        process.nextTick(maybeReadMore_, stream, state);
      }
    }
    function maybeReadMore_(stream, state) {
      // Attempt to read more data if we should.
      //
      // The conditions for reading more data are (one of):
      // - Not enough data buffered (state.length < state.highWaterMark). The loop
      //   is responsible for filling the buffer with enough data if such data
      //   is available. If highWaterMark is 0 and we are not in the flowing mode
      //   we should _not_ attempt to buffer any extra data. We'll get more data
      //   when the stream consumer calls read() instead.
      // - No data in the buffer, and the stream is in flowing mode. In this mode
      //   the loop below is responsible for ensuring read() is called. Failing to
      //   call read here would abort the flow and there's no other mechanism for
      //   continuing the flow if the stream consumer has just subscribed to the
      //   'data' event.
      //
      // In addition to the above conditions to keep reading data, the following
      // conditions prevent the data from being read:
      // - The stream has ended (state.ended).
      // - There is already a pending 'read' operation (state.reading). This is a
      //   case where the the stream has called the implementation defined _read()
      //   method, but they are processing the call asynchronously and have _not_
      //   called push() with new data. In this case we skip performing more
      //   read()s. The execution ends in this method again after the _read() ends
      //   up calling push() with more data.
      while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) {
        var len = state.length;
        debug('maybeReadMore read 0');
        stream.read(0);
        if (len === state.length)
          // didn't get any data, stop spinning.
          break;
      }
      state.readingMore = false;
    }
    
    // abstract method.  to be overridden in specific implementation classes.
    // call cb(er, data) where data is <= n in length.
    // for virtual (non-string, non-buffer) streams, "length" is somewhat
    // arbitrary, and perhaps not very meaningful.
    Readable.prototype._read = function (n) {
      errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()'));
    };
    Readable.prototype.pipe = function (dest, pipeOpts) {
      var src = this;
      var state = this._readableState;
      switch (state.pipesCount) {
        case 0:
          state.pipes = dest;
          break;
        case 1:
          state.pipes = [state.pipes, dest];
          break;
        default:
          state.pipes.push(dest);
          break;
      }
      state.pipesCount += 1;
      debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
      var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
      var endFn = doEnd ? onend : unpipe;
      if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn);
      dest.on('unpipe', onunpipe);
      function onunpipe(readable, unpipeInfo) {
        debug('onunpipe');
        if (readable === src) {
          if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
            unpipeInfo.hasUnpiped = true;
            cleanup();
          }
        }
      }
      function onend() {
        debug('onend');
        dest.end();
      }
    
      // when the dest drains, it reduces the awaitDrain counter
      // on the source.  This would be more elegant with a .once()
      // handler in flow(), but adding and removing repeatedly is
      // too slow.
      var ondrain = pipeOnDrain(src);
      dest.on('drain', ondrain);
      var cleanedUp = false;
      function cleanup() {
        debug('cleanup');
        // cleanup event handlers once the pipe is broken
        dest.removeListener('close', onclose);
        dest.removeListener('finish', onfinish);
        dest.removeListener('drain', ondrain);
        dest.removeListener('error', onerror);
        dest.removeListener('unpipe', onunpipe);
        src.removeListener('end', onend);
        src.removeListener('end', unpipe);
        src.removeListener('data', ondata);
        cleanedUp = true;
    
        // if the reader is waiting for a drain event from this
        // specific writer, then it would cause it to never start
        // flowing again.
        // So, if this is awaiting a drain, then we just call it now.
        // If we don't know, then assume that we are waiting for one.
        if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
      }
      src.on('data', ondata);
      function ondata(chunk) {
        debug('ondata');
        var ret = dest.write(chunk);
        debug('dest.write', ret);
        if (ret === false) {
          // If the user unpiped during `dest.write()`, it is possible
          // to get stuck in a permanently paused state if that write
          // also returned false.
          // => Check whether `dest` is still a piping destination.
          if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
            debug('false write response, pause', state.awaitDrain);
            state.awaitDrain++;
          }
          src.pause();
        }
      }
    
      // if the dest has an error, then stop piping into it.
      // however, don't suppress the throwing behavior for this.
      function onerror(er) {
        debug('onerror', er);
        unpipe();
        dest.removeListener('error', onerror);
        if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er);
      }
    
      // Make sure our error handler is attached before userland ones.
      prependListener(dest, 'error', onerror);
    
      // Both close and finish should trigger unpipe, but only once.
      function onclose() {
        dest.removeListener('finish', onfinish);
        unpipe();
      }
      dest.once('close', onclose);
      function onfinish() {
        debug('onfinish');
        dest.removeListener('close', onclose);
        unpipe();
      }
      dest.once('finish', onfinish);
      function unpipe() {
        debug('unpipe');
        src.unpipe(dest);
      }
    
      // tell the dest that it's being piped to
      dest.emit('pipe', src);
    
      // start the flow if it hasn't been started already.
      if (!state.flowing) {
        debug('pipe resume');
        src.resume();
      }
      return dest;
    };
    function pipeOnDrain(src) {
      return function pipeOnDrainFunctionResult() {
        var state = src._readableState;
        debug('pipeOnDrain', state.awaitDrain);
        if (state.awaitDrain) state.awaitDrain--;
        if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
          state.flowing = true;
          flow(src);
        }
      };
    }
    Readable.prototype.unpipe = function (dest) {
      var state = this._readableState;
      var unpipeInfo = {
        hasUnpiped: false
      };
    
      // if we're not piping anywhere, then do nothing.
      if (state.pipesCount === 0) return this;
    
      // just one destination.  most common case.
      if (state.pipesCount === 1) {
        // passed in one, but it's not the right one.
        if (dest && dest !== state.pipes) return this;
        if (!dest) dest = state.pipes;
    
        // got a match.
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        if (dest) dest.emit('unpipe', this, unpipeInfo);
        return this;
      }
    
      // slow case. multiple pipe destinations.
    
      if (!dest) {
        // remove all.
        var dests = state.pipes;
        var len = state.pipesCount;
        state.pipes = null;
        state.pipesCount = 0;
        state.flowing = false;
        for (var i = 0; i < len; i++) dests[i].emit('unpipe', this, {
          hasUnpiped: false
        });
        return this;
      }
    
      // try to find the right one.
      var index = indexOf(state.pipes, dest);
      if (index === -1) return this;
      state.pipes.splice(index, 1);
      state.pipesCount -= 1;
      if (state.pipesCount === 1) state.pipes = state.pipes[0];
      dest.emit('unpipe', this, unpipeInfo);
      return this;
    };
    
    // set up data events if they are asked for
    // Ensure readable listeners eventually get something
    Readable.prototype.on = function (ev, fn) {
      var res = Stream.prototype.on.call(this, ev, fn);
      var state = this._readableState;
      if (ev === 'data') {
        // update readableListening so that resume() may be a no-op
        // a few lines down. This is needed to support once('readable').
        state.readableListening = this.listenerCount('readable') > 0;
    
        // Try start flowing on next tick if stream isn't explicitly paused
        if (state.flowing !== false) this.resume();
      } else if (ev === 'readable') {
        if (!state.endEmitted && !state.readableListening) {
          state.readableListening = state.needReadable = true;
          state.flowing = false;
          state.emittedReadable = false;
          debug('on readable', state.length, state.reading);
          if (state.length) {
            emitReadable(this);
          } else if (!state.reading) {
            process.nextTick(nReadingNextTick, this);
          }
        }
      }
      return res;
    };
    Readable.prototype.addListener = Readable.prototype.on;
    Readable.prototype.removeListener = function (ev, fn) {
      var res = Stream.prototype.removeListener.call(this, ev, fn);
      if (ev === 'readable') {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    Readable.prototype.removeAllListeners = function (ev) {
      var res = Stream.prototype.removeAllListeners.apply(this, arguments);
      if (ev === 'readable' || ev === undefined) {
        // We need to check if there is someone still listening to
        // readable and reset the state. However this needs to happen
        // after readable has been emitted but before I/O (nextTick) to
        // support once('readable', fn) cycles. This means that calling
        // resume within the same tick will have no
        // effect.
        process.nextTick(updateReadableListening, this);
      }
      return res;
    };
    function updateReadableListening(self) {
      var state = self._readableState;
      state.readableListening = self.listenerCount('readable') > 0;
      if (state.resumeScheduled && !state.paused) {
        // flowing needs to be set to true now, otherwise
        // the upcoming resume will not flow.
        state.flowing = true;
    
        // crude way to check if we should resume
      } else if (self.listenerCount('data') > 0) {
        self.resume();
      }
    }
    function nReadingNextTick(self) {
      debug('readable nexttick read 0');
      self.read(0);
    }
    
    // pause() and resume() are remnants of the legacy readable stream API
    // If the user uses them, then switch into old mode.
    Readable.prototype.resume = function () {
      var state = this._readableState;
      if (!state.flowing) {
        debug('resume');
        // we flow only if there is no one listening
        // for readable, but we still have to call
        // resume()
        state.flowing = !state.readableListening;
        resume(this, state);
      }
      state.paused = false;
      return this;
    };
    function resume(stream, state) {
      if (!state.resumeScheduled) {
        state.resumeScheduled = true;
        process.nextTick(resume_, stream, state);
      }
    }
    function resume_(stream, state) {
      debug('resume', state.reading);
      if (!state.reading) {
        stream.read(0);
      }
      state.resumeScheduled = false;
      stream.emit('resume');
      flow(stream);
      if (state.flowing && !state.reading) stream.read(0);
    }
    Readable.prototype.pause = function () {
      debug('call pause flowing=%j', this._readableState.flowing);
      if (this._readableState.flowing !== false) {
        debug('pause');
        this._readableState.flowing = false;
        this.emit('pause');
      }
      this._readableState.paused = true;
      return this;
    };
    function flow(stream) {
      var state = stream._readableState;
      debug('flow', state.flowing);
      while (state.flowing && stream.read() !== null);
    }
    
    // wrap an old-style stream as the async data source.
    // This is *not* part of the readable stream interface.
    // It is an ugly unfortunate mess of history.
    Readable.prototype.wrap = function (stream) {
      var _this = this;
      var state = this._readableState;
      var paused = false;
      stream.on('end', function () {
        debug('wrapped end');
        if (state.decoder && !state.ended) {
          var chunk = state.decoder.end();
          if (chunk && chunk.length) _this.push(chunk);
        }
        _this.push(null);
      });
      stream.on('data', function (chunk) {
        debug('wrapped data');
        if (state.decoder) chunk = state.decoder.write(chunk);
    
        // don't skip over falsy values in objectMode
        if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
        var ret = _this.push(chunk);
        if (!ret) {
          paused = true;
          stream.pause();
        }
      });
    
      // proxy all the other methods.
      // important when wrapping filters and duplexes.
      for (var i in stream) {
        if (this[i] === undefined && typeof stream[i] === 'function') {
          this[i] = function methodWrap(method) {
            return function methodWrapReturnFunction() {
              return stream[method].apply(stream, arguments);
            };
          }(i);
        }
      }
    
      // proxy certain important events.
      for (var n = 0; n < kProxyEvents.length; n++) {
        stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
      }
    
      // when we try to consume some more bytes, simply unpause the
      // underlying stream.
      this._read = function (n) {
        debug('wrapped _read', n);
        if (paused) {
          paused = false;
          stream.resume();
        }
      };
      return this;
    };
    if (typeof Symbol === 'function') {
      Readable.prototype[Symbol.asyncIterator] = function () {
        if (createReadableStreamAsyncIterator === undefined) {
          createReadableStreamAsyncIterator = require('./internal/streams/async_iterator');
        }
        return createReadableStreamAsyncIterator(this);
      };
    }
    Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.highWaterMark;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState && this._readableState.buffer;
      }
    });
    Object.defineProperty(Readable.prototype, 'readableFlowing', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.flowing;
      },
      set: function set(state) {
        if (this._readableState) {
          this._readableState.flowing = state;
        }
      }
    });
    
    // exposed for testing purposes only.
    Readable._fromList = fromList;
    Object.defineProperty(Readable.prototype, 'readableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._readableState.length;
      }
    });
    
    // Pluck off n bytes from an array of buffers.
    // Length is the combined lengths of all the buffers in the list.
    // This function is designed to be inlinable, so please take care when making
    // changes to the function body.
    function fromList(n, state) {
      // nothing buffered
      if (state.length === 0) return null;
      var ret;
      if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
        // read it all, truncate the list
        if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length);
        state.buffer.clear();
      } else {
        // read part of list
        ret = state.buffer.consume(n, state.decoder);
      }
      return ret;
    }
    function endReadable(stream) {
      var state = stream._readableState;
      debug('endReadable', state.endEmitted);
      if (!state.endEmitted) {
        state.ended = true;
        process.nextTick(endReadableNT, state, stream);
      }
    }
    function endReadableNT(state, stream) {
      debug('endReadableNT', state.endEmitted, state.length);
    
      // Check that we didn't get one last unshift.
      if (!state.endEmitted && state.length === 0) {
        state.endEmitted = true;
        stream.readable = false;
        stream.emit('end');
        if (state.autoDestroy) {
          // In case of duplex streams we need a way to detect
          // if the writable side is ready for autoDestroy as well
          var wState = stream._writableState;
          if (!wState || wState.autoDestroy && wState.finished) {
            stream.destroy();
          }
        }
      }
    }
    if (typeof Symbol === 'function') {
      Readable.from = function (iterable, opts) {
        if (from === undefined) {
          from = require('./internal/streams/from');
        }
        return from(Readable, iterable, opts);
      };
    }
    function indexOf(xs, x) {
      for (var i = 0, l = xs.length; i < l; i++) {
        if (xs[i] === x) return i;
      }
      return -1;
    }
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":351,"./_stream_duplex":352,"./internal/streams/async_iterator":357,"./internal/streams/buffer_list":358,"./internal/streams/destroy":359,"./internal/streams/from":361,"./internal/streams/state":363,"./internal/streams/stream":364,"_process":321,"buffer":84,"events":134,"inherits":182,"string_decoder/":365,"util":36}],355:[function(require,module,exports){
    arguments[4][70][0].apply(exports,arguments)
    },{"../errors":351,"./_stream_duplex":352,"dup":70,"inherits":182}],356:[function(require,module,exports){
    (function (process,global){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // A bit simpler than readable streams.
    // Implement an async ._write(chunk, encoding, cb), and it'll handle all
    // the drain event emission and buffering.
    
    'use strict';
    
    module.exports = Writable;
    
    /* <replacement> */
    function WriteReq(chunk, encoding, cb) {
      this.chunk = chunk;
      this.encoding = encoding;
      this.callback = cb;
      this.next = null;
    }
    
    // It seems a linked list but it is not
    // there will be only 2 of these for each stream
    function CorkedRequest(state) {
      var _this = this;
      this.next = null;
      this.entry = null;
      this.finish = function () {
        onCorkedFinish(_this, state);
      };
    }
    /* </replacement> */
    
    /*<replacement>*/
    var Duplex;
    /*</replacement>*/
    
    Writable.WritableState = WritableState;
    
    /*<replacement>*/
    var internalUtil = {
      deprecate: require('util-deprecate')
    };
    /*</replacement>*/
    
    /*<replacement>*/
    var Stream = require('./internal/streams/stream');
    /*</replacement>*/
    
    var Buffer = require('buffer').Buffer;
    var OurUint8Array = (typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}).Uint8Array || function () {};
    function _uint8ArrayToBuffer(chunk) {
      return Buffer.from(chunk);
    }
    function _isUint8Array(obj) {
      return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
    }
    var destroyImpl = require('./internal/streams/destroy');
    var _require = require('./internal/streams/state'),
      getHighWaterMark = _require.getHighWaterMark;
    var _require$codes = require('../errors').codes,
      ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
      ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED,
      ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK,
      ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE,
      ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED,
      ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES,
      ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END,
      ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING;
    var errorOrDestroy = destroyImpl.errorOrDestroy;
    require('inherits')(Writable, Stream);
    function nop() {}
    function WritableState(options, stream, isDuplex) {
      Duplex = Duplex || require('./_stream_duplex');
      options = options || {};
    
      // Duplex streams are both readable and writable, but share
      // the same options object.
      // However, some cases require setting options to different
      // values for the readable and the writable sides of the duplex stream,
      // e.g. options.readableObjectMode vs. options.writableObjectMode, etc.
      if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex;
    
      // object stream flag to indicate whether or not this stream
      // contains buffers or objects.
      this.objectMode = !!options.objectMode;
      if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
    
      // the point at which write() starts returning false
      // Note: 0 is a valid value, means that we always return false if
      // the entire buffer is not flushed immediately on write()
      this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex);
    
      // if _final has been called
      this.finalCalled = false;
    
      // drain event flag.
      this.needDrain = false;
      // at the start of calling end()
      this.ending = false;
      // when end() has been called, and returned
      this.ended = false;
      // when 'finish' is emitted
      this.finished = false;
    
      // has it been destroyed
      this.destroyed = false;
    
      // should we decode strings into buffers before passing to _write?
      // this is here so that some node-core streams can optimize string
      // handling at a lower level.
      var noDecode = options.decodeStrings === false;
      this.decodeStrings = !noDecode;
    
      // Crypto is kind of old and crusty.  Historically, its default string
      // encoding is 'binary' so we have to make this configurable.
      // Everything else in the universe uses 'utf8', though.
      this.defaultEncoding = options.defaultEncoding || 'utf8';
    
      // not an actual buffer we keep track of, but a measurement
      // of how much we're waiting to get pushed to some underlying
      // socket or file.
      this.length = 0;
    
      // a flag to see when we're in the middle of a write.
      this.writing = false;
    
      // when true all writes will be buffered until .uncork() call
      this.corked = 0;
    
      // a flag to be able to tell if the onwrite cb is called immediately,
      // or on a later tick.  We set this to true at first, because any
      // actions that shouldn't happen until "later" should generally also
      // not happen before the first write call.
      this.sync = true;
    
      // a flag to know if we're processing previously buffered items, which
      // may call the _write() callback in the same tick, so that we don't
      // end up in an overlapped onwrite situation.
      this.bufferProcessing = false;
    
      // the callback that's passed to _write(chunk,cb)
      this.onwrite = function (er) {
        onwrite(stream, er);
      };
    
      // the callback that the user supplies to write(chunk,encoding,cb)
      this.writecb = null;
    
      // the amount that is being written when _write is called.
      this.writelen = 0;
      this.bufferedRequest = null;
      this.lastBufferedRequest = null;
    
      // number of pending user-supplied write callbacks
      // this must be 0 before 'finish' can be emitted
      this.pendingcb = 0;
    
      // emit prefinish if the only thing we're waiting for is _write cbs
      // This is relevant for synchronous Transform streams
      this.prefinished = false;
    
      // True if the error was already emitted and should not be thrown again
      this.errorEmitted = false;
    
      // Should close be emitted on destroy. Defaults to true.
      this.emitClose = options.emitClose !== false;
    
      // Should .destroy() be called after 'finish' (and potentially 'end')
      this.autoDestroy = !!options.autoDestroy;
    
      // count buffered requests
      this.bufferedRequestCount = 0;
    
      // allocate the first CorkedRequest, there is always
      // one allocated and free to use, and we maintain at most two
      this.corkedRequestsFree = new CorkedRequest(this);
    }
    WritableState.prototype.getBuffer = function getBuffer() {
      var current = this.bufferedRequest;
      var out = [];
      while (current) {
        out.push(current);
        current = current.next;
      }
      return out;
    };
    (function () {
      try {
        Object.defineProperty(WritableState.prototype, 'buffer', {
          get: internalUtil.deprecate(function writableStateBufferGetter() {
            return this.getBuffer();
          }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
        });
      } catch (_) {}
    })();
    
    // Test _writableState for inheritance to account for Duplex streams,
    // whose prototype chain only points to Readable.
    var realHasInstance;
    if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
      realHasInstance = Function.prototype[Symbol.hasInstance];
      Object.defineProperty(Writable, Symbol.hasInstance, {
        value: function value(object) {
          if (realHasInstance.call(this, object)) return true;
          if (this !== Writable) return false;
          return object && object._writableState instanceof WritableState;
        }
      });
    } else {
      realHasInstance = function realHasInstance(object) {
        return object instanceof this;
      };
    }
    function Writable(options) {
      Duplex = Duplex || require('./_stream_duplex');
    
      // Writable ctor is applied to Duplexes, too.
      // `realHasInstance` is necessary because using plain `instanceof`
      // would return false, as no `_writableState` property is attached.
    
      // Trying to use the custom `instanceof` for Writable here will also break the
      // Node.js LazyTransform implementation, which has a non-trivial getter for
      // `_writableState` that would lead to infinite recursion.
    
      // Checking for a Stream.Duplex instance is faster here instead of inside
      // the WritableState constructor, at least with V8 6.5
      var isDuplex = this instanceof Duplex;
      if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options);
      this._writableState = new WritableState(options, this, isDuplex);
    
      // legacy.
      this.writable = true;
      if (options) {
        if (typeof options.write === 'function') this._write = options.write;
        if (typeof options.writev === 'function') this._writev = options.writev;
        if (typeof options.destroy === 'function') this._destroy = options.destroy;
        if (typeof options.final === 'function') this._final = options.final;
      }
      Stream.call(this);
    }
    
    // Otherwise people can pipe Writable streams, which is just wrong.
    Writable.prototype.pipe = function () {
      errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());
    };
    function writeAfterEnd(stream, cb) {
      var er = new ERR_STREAM_WRITE_AFTER_END();
      // TODO: defer error events consistently everywhere, not just the cb
      errorOrDestroy(stream, er);
      process.nextTick(cb, er);
    }
    
    // Checks that a user-supplied chunk is valid, especially for the particular
    // mode the stream is in. Currently this means that `null` is never accepted
    // and undefined/non-string values are only allowed in object mode.
    function validChunk(stream, state, chunk, cb) {
      var er;
      if (chunk === null) {
        er = new ERR_STREAM_NULL_VALUES();
      } else if (typeof chunk !== 'string' && !state.objectMode) {
        er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk);
      }
      if (er) {
        errorOrDestroy(stream, er);
        process.nextTick(cb, er);
        return false;
      }
      return true;
    }
    Writable.prototype.write = function (chunk, encoding, cb) {
      var state = this._writableState;
      var ret = false;
      var isBuf = !state.objectMode && _isUint8Array(chunk);
      if (isBuf && !Buffer.isBuffer(chunk)) {
        chunk = _uint8ArrayToBuffer(chunk);
      }
      if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
      if (typeof cb !== 'function') cb = nop;
      if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
        state.pendingcb++;
        ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
      }
      return ret;
    };
    Writable.prototype.cork = function () {
      this._writableState.corked++;
    };
    Writable.prototype.uncork = function () {
      var state = this._writableState;
      if (state.corked) {
        state.corked--;
        if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
      }
    };
    Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
      // node::ParseEncoding() requires lower case.
      if (typeof encoding === 'string') encoding = encoding.toLowerCase();
      if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding);
      this._writableState.defaultEncoding = encoding;
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableBuffer', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState && this._writableState.getBuffer();
      }
    });
    function decodeChunk(state, chunk, encoding) {
      if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
        chunk = Buffer.from(chunk, encoding);
      }
      return chunk;
    }
    Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.highWaterMark;
      }
    });
    
    // if we're already writing something, then just put this
    // in the queue, and wait our turn.  Otherwise, call _write
    // If we return false, then we need a drain event, so set that flag.
    function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
      if (!isBuf) {
        var newChunk = decodeChunk(state, chunk, encoding);
        if (chunk !== newChunk) {
          isBuf = true;
          encoding = 'buffer';
          chunk = newChunk;
        }
      }
      var len = state.objectMode ? 1 : chunk.length;
      state.length += len;
      var ret = state.length < state.highWaterMark;
      // we must ensure that previous needDrain will not be reset to false.
      if (!ret) state.needDrain = true;
      if (state.writing || state.corked) {
        var last = state.lastBufferedRequest;
        state.lastBufferedRequest = {
          chunk: chunk,
          encoding: encoding,
          isBuf: isBuf,
          callback: cb,
          next: null
        };
        if (last) {
          last.next = state.lastBufferedRequest;
        } else {
          state.bufferedRequest = state.lastBufferedRequest;
        }
        state.bufferedRequestCount += 1;
      } else {
        doWrite(stream, state, false, len, chunk, encoding, cb);
      }
      return ret;
    }
    function doWrite(stream, state, writev, len, chunk, encoding, cb) {
      state.writelen = len;
      state.writecb = cb;
      state.writing = true;
      state.sync = true;
      if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
      state.sync = false;
    }
    function onwriteError(stream, state, sync, er, cb) {
      --state.pendingcb;
      if (sync) {
        // defer the callback if we are being called synchronously
        // to avoid piling up things on the stack
        process.nextTick(cb, er);
        // this can emit finish, and it will always happen
        // after error
        process.nextTick(finishMaybe, stream, state);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
      } else {
        // the caller expect this to happen before if
        // it is async
        cb(er);
        stream._writableState.errorEmitted = true;
        errorOrDestroy(stream, er);
        // this can emit finish, but finish must
        // always follow error
        finishMaybe(stream, state);
      }
    }
    function onwriteStateUpdate(state) {
      state.writing = false;
      state.writecb = null;
      state.length -= state.writelen;
      state.writelen = 0;
    }
    function onwrite(stream, er) {
      var state = stream._writableState;
      var sync = state.sync;
      var cb = state.writecb;
      if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK();
      onwriteStateUpdate(state);
      if (er) onwriteError(stream, state, sync, er, cb);else {
        // Check if we're actually ready to finish, but don't emit yet
        var finished = needFinish(state) || stream.destroyed;
        if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
          clearBuffer(stream, state);
        }
        if (sync) {
          process.nextTick(afterWrite, stream, state, finished, cb);
        } else {
          afterWrite(stream, state, finished, cb);
        }
      }
    }
    function afterWrite(stream, state, finished, cb) {
      if (!finished) onwriteDrain(stream, state);
      state.pendingcb--;
      cb();
      finishMaybe(stream, state);
    }
    
    // Must force callback to be called on nextTick, so that we don't
    // emit 'drain' before the write() consumer gets the 'false' return
    // value, and has a chance to attach a 'drain' listener.
    function onwriteDrain(stream, state) {
      if (state.length === 0 && state.needDrain) {
        state.needDrain = false;
        stream.emit('drain');
      }
    }
    
    // if there's something in the buffer waiting, then process it
    function clearBuffer(stream, state) {
      state.bufferProcessing = true;
      var entry = state.bufferedRequest;
      if (stream._writev && entry && entry.next) {
        // Fast case, write everything using _writev()
        var l = state.bufferedRequestCount;
        var buffer = new Array(l);
        var holder = state.corkedRequestsFree;
        holder.entry = entry;
        var count = 0;
        var allBuffers = true;
        while (entry) {
          buffer[count] = entry;
          if (!entry.isBuf) allBuffers = false;
          entry = entry.next;
          count += 1;
        }
        buffer.allBuffers = allBuffers;
        doWrite(stream, state, true, state.length, buffer, '', holder.finish);
    
        // doWrite is almost always async, defer these to save a bit of time
        // as the hot path ends with doWrite
        state.pendingcb++;
        state.lastBufferedRequest = null;
        if (holder.next) {
          state.corkedRequestsFree = holder.next;
          holder.next = null;
        } else {
          state.corkedRequestsFree = new CorkedRequest(state);
        }
        state.bufferedRequestCount = 0;
      } else {
        // Slow case, write chunks one-by-one
        while (entry) {
          var chunk = entry.chunk;
          var encoding = entry.encoding;
          var cb = entry.callback;
          var len = state.objectMode ? 1 : chunk.length;
          doWrite(stream, state, false, len, chunk, encoding, cb);
          entry = entry.next;
          state.bufferedRequestCount--;
          // if we didn't call the onwrite immediately, then
          // it means that we need to wait until it does.
          // also, that means that the chunk and cb are currently
          // being processed, so move the buffer counter past them.
          if (state.writing) {
            break;
          }
        }
        if (entry === null) state.lastBufferedRequest = null;
      }
      state.bufferedRequest = entry;
      state.bufferProcessing = false;
    }
    Writable.prototype._write = function (chunk, encoding, cb) {
      cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()'));
    };
    Writable.prototype._writev = null;
    Writable.prototype.end = function (chunk, encoding, cb) {
      var state = this._writableState;
      if (typeof chunk === 'function') {
        cb = chunk;
        chunk = null;
        encoding = null;
      } else if (typeof encoding === 'function') {
        cb = encoding;
        encoding = null;
      }
      if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
    
      // .end() fully uncorks
      if (state.corked) {
        state.corked = 1;
        this.uncork();
      }
    
      // ignore unnecessary end() calls.
      if (!state.ending) endWritable(this, state, cb);
      return this;
    };
    Object.defineProperty(Writable.prototype, 'writableLength', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        return this._writableState.length;
      }
    });
    function needFinish(state) {
      return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
    }
    function callFinal(stream, state) {
      stream._final(function (err) {
        state.pendingcb--;
        if (err) {
          errorOrDestroy(stream, err);
        }
        state.prefinished = true;
        stream.emit('prefinish');
        finishMaybe(stream, state);
      });
    }
    function prefinish(stream, state) {
      if (!state.prefinished && !state.finalCalled) {
        if (typeof stream._final === 'function' && !state.destroyed) {
          state.pendingcb++;
          state.finalCalled = true;
          process.nextTick(callFinal, stream, state);
        } else {
          state.prefinished = true;
          stream.emit('prefinish');
        }
      }
    }
    function finishMaybe(stream, state) {
      var need = needFinish(state);
      if (need) {
        prefinish(stream, state);
        if (state.pendingcb === 0) {
          state.finished = true;
          stream.emit('finish');
          if (state.autoDestroy) {
            // In case of duplex streams we need a way to detect
            // if the readable side is ready for autoDestroy as well
            var rState = stream._readableState;
            if (!rState || rState.autoDestroy && rState.endEmitted) {
              stream.destroy();
            }
          }
        }
      }
      return need;
    }
    function endWritable(stream, state, cb) {
      state.ending = true;
      finishMaybe(stream, state);
      if (cb) {
        if (state.finished) process.nextTick(cb);else stream.once('finish', cb);
      }
      state.ended = true;
      stream.writable = false;
    }
    function onCorkedFinish(corkReq, state, err) {
      var entry = corkReq.entry;
      corkReq.entry = null;
      while (entry) {
        var cb = entry.callback;
        state.pendingcb--;
        cb(err);
        entry = entry.next;
      }
    
      // reuse the free corkReq.
      state.corkedRequestsFree.next = corkReq;
    }
    Object.defineProperty(Writable.prototype, 'destroyed', {
      // making it explicit this property is not enumerable
      // because otherwise some prototype manipulation in
      // userland will fail
      enumerable: false,
      get: function get() {
        if (this._writableState === undefined) {
          return false;
        }
        return this._writableState.destroyed;
      },
      set: function set(value) {
        // we ignore the value if the stream
        // has not been initialized yet
        if (!this._writableState) {
          return;
        }
    
        // backward compatibility, the user is explicitly
        // managing destroyed
        this._writableState.destroyed = value;
      }
    });
    Writable.prototype.destroy = destroyImpl.destroy;
    Writable.prototype._undestroy = destroyImpl.undestroy;
    Writable.prototype._destroy = function (err, cb) {
      cb(err);
    };
    }).call(this)}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"../errors":351,"./_stream_duplex":352,"./internal/streams/destroy":359,"./internal/streams/state":363,"./internal/streams/stream":364,"_process":321,"buffer":84,"inherits":182,"util-deprecate":369}],357:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    var _Object$setPrototypeO;
    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
    function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
    function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
    var finished = require('./end-of-stream');
    var kLastResolve = Symbol('lastResolve');
    var kLastReject = Symbol('lastReject');
    var kError = Symbol('error');
    var kEnded = Symbol('ended');
    var kLastPromise = Symbol('lastPromise');
    var kHandlePromise = Symbol('handlePromise');
    var kStream = Symbol('stream');
    function createIterResult(value, done) {
      return {
        value: value,
        done: done
      };
    }
    function readAndResolve(iter) {
      var resolve = iter[kLastResolve];
      if (resolve !== null) {
        var data = iter[kStream].read();
        // we defer if data is null
        // we can be expecting either 'end' or
        // 'error'
        if (data !== null) {
          iter[kLastPromise] = null;
          iter[kLastResolve] = null;
          iter[kLastReject] = null;
          resolve(createIterResult(data, false));
        }
      }
    }
    function onReadable(iter) {
      // we wait for the next tick, because it might
      // emit an error with process.nextTick
      process.nextTick(readAndResolve, iter);
    }
    function wrapForNext(lastPromise, iter) {
      return function (resolve, reject) {
        lastPromise.then(function () {
          if (iter[kEnded]) {
            resolve(createIterResult(undefined, true));
            return;
          }
          iter[kHandlePromise](resolve, reject);
        }, reject);
      };
    }
    var AsyncIteratorPrototype = Object.getPrototypeOf(function () {});
    var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = {
      get stream() {
        return this[kStream];
      },
      next: function next() {
        var _this = this;
        // if we have detected an error in the meanwhile
        // reject straight away
        var error = this[kError];
        if (error !== null) {
          return Promise.reject(error);
        }
        if (this[kEnded]) {
          return Promise.resolve(createIterResult(undefined, true));
        }
        if (this[kStream].destroyed) {
          // We need to defer via nextTick because if .destroy(err) is
          // called, the error will be emitted via nextTick, and
          // we cannot guarantee that there is no error lingering around
          // waiting to be emitted.
          return new Promise(function (resolve, reject) {
            process.nextTick(function () {
              if (_this[kError]) {
                reject(_this[kError]);
              } else {
                resolve(createIterResult(undefined, true));
              }
            });
          });
        }
    
        // if we have multiple next() calls
        // we will wait for the previous Promise to finish
        // this logic is optimized to support for await loops,
        // where next() is only called once at a time
        var lastPromise = this[kLastPromise];
        var promise;
        if (lastPromise) {
          promise = new Promise(wrapForNext(lastPromise, this));
        } else {
          // fast path needed to support multiple this.push()
          // without triggering the next() queue
          var data = this[kStream].read();
          if (data !== null) {
            return Promise.resolve(createIterResult(data, false));
          }
          promise = new Promise(this[kHandlePromise]);
        }
        this[kLastPromise] = promise;
        return promise;
      }
    }, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () {
      return this;
    }), _defineProperty(_Object$setPrototypeO, "return", function _return() {
      var _this2 = this;
      // destroy(err, cb) is a private API
      // we can guarantee we have that here, because we control the
      // Readable class this is attached to
      return new Promise(function (resolve, reject) {
        _this2[kStream].destroy(null, function (err) {
          if (err) {
            reject(err);
            return;
          }
          resolve(createIterResult(undefined, true));
        });
      });
    }), _Object$setPrototypeO), AsyncIteratorPrototype);
    var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) {
      var _Object$create;
      var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, {
        value: stream,
        writable: true
      }), _defineProperty(_Object$create, kLastResolve, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kLastReject, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kError, {
        value: null,
        writable: true
      }), _defineProperty(_Object$create, kEnded, {
        value: stream._readableState.endEmitted,
        writable: true
      }), _defineProperty(_Object$create, kHandlePromise, {
        value: function value(resolve, reject) {
          var data = iterator[kStream].read();
          if (data) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            resolve(createIterResult(data, false));
          } else {
            iterator[kLastResolve] = resolve;
            iterator[kLastReject] = reject;
          }
        },
        writable: true
      }), _Object$create));
      iterator[kLastPromise] = null;
      finished(stream, function (err) {
        if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
          var reject = iterator[kLastReject];
          // reject if we are waiting for data in the Promise
          // returned by next() and store the error
          if (reject !== null) {
            iterator[kLastPromise] = null;
            iterator[kLastResolve] = null;
            iterator[kLastReject] = null;
            reject(err);
          }
          iterator[kError] = err;
          return;
        }
        var resolve = iterator[kLastResolve];
        if (resolve !== null) {
          iterator[kLastPromise] = null;
          iterator[kLastResolve] = null;
          iterator[kLastReject] = null;
          resolve(createIterResult(undefined, true));
        }
        iterator[kEnded] = true;
      });
      stream.on('readable', onReadable.bind(null, iterator));
      return iterator;
    };
    module.exports = createReadableStreamAsyncIterator;
    }).call(this)}).call(this,require('_process'))
    
    },{"./end-of-stream":360,"_process":321}],358:[function(require,module,exports){
    arguments[4][73][0].apply(exports,arguments)
    },{"buffer":84,"dup":73,"util":36}],359:[function(require,module,exports){
    (function (process){(function (){
    'use strict';
    
    // undocumented cb() API, needed for core, not for public API
    function destroy(err, cb) {
      var _this = this;
      var readableDestroyed = this._readableState && this._readableState.destroyed;
      var writableDestroyed = this._writableState && this._writableState.destroyed;
      if (readableDestroyed || writableDestroyed) {
        if (cb) {
          cb(err);
        } else if (err) {
          if (!this._writableState) {
            process.nextTick(emitErrorNT, this, err);
          } else if (!this._writableState.errorEmitted) {
            this._writableState.errorEmitted = true;
            process.nextTick(emitErrorNT, this, err);
          }
        }
        return this;
      }
    
      // we set destroyed to true before firing error callbacks in order
      // to make it re-entrance safe in case destroy() is called within callbacks
    
      if (this._readableState) {
        this._readableState.destroyed = true;
      }
    
      // if this is a duplex stream mark the writable part as destroyed as well
      if (this._writableState) {
        this._writableState.destroyed = true;
      }
      this._destroy(err || null, function (err) {
        if (!cb && err) {
          if (!_this._writableState) {
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else if (!_this._writableState.errorEmitted) {
            _this._writableState.errorEmitted = true;
            process.nextTick(emitErrorAndCloseNT, _this, err);
          } else {
            process.nextTick(emitCloseNT, _this);
          }
        } else if (cb) {
          process.nextTick(emitCloseNT, _this);
          cb(err);
        } else {
          process.nextTick(emitCloseNT, _this);
        }
      });
      return this;
    }
    function emitErrorAndCloseNT(self, err) {
      emitErrorNT(self, err);
      emitCloseNT(self);
    }
    function emitCloseNT(self) {
      if (self._writableState && !self._writableState.emitClose) return;
      if (self._readableState && !self._readableState.emitClose) return;
      self.emit('close');
    }
    function undestroy() {
      if (this._readableState) {
        this._readableState.destroyed = false;
        this._readableState.reading = false;
        this._readableState.ended = false;
        this._readableState.endEmitted = false;
      }
      if (this._writableState) {
        this._writableState.destroyed = false;
        this._writableState.ended = false;
        this._writableState.ending = false;
        this._writableState.finalCalled = false;
        this._writableState.prefinished = false;
        this._writableState.finished = false;
        this._writableState.errorEmitted = false;
      }
    }
    function emitErrorNT(self, err) {
      self.emit('error', err);
    }
    function errorOrDestroy(stream, err) {
      // We have tests that rely on errors being emitted
      // in the same tick, so changing this is semver major.
      // For now when you opt-in to autoDestroy we allow
      // the error to be emitted nextTick. In a future
      // semver major update we should change the default to this.
    
      var rState = stream._readableState;
      var wState = stream._writableState;
      if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err);
    }
    module.exports = {
      destroy: destroy,
      undestroy: undestroy,
      errorOrDestroy: errorOrDestroy
    };
    }).call(this)}).call(this,require('_process'))
    
    },{"_process":321}],360:[function(require,module,exports){
    arguments[4][75][0].apply(exports,arguments)
    },{"../../../errors":351,"dup":75}],361:[function(require,module,exports){
    arguments[4][76][0].apply(exports,arguments)
    },{"dup":76}],362:[function(require,module,exports){
    arguments[4][77][0].apply(exports,arguments)
    },{"../../../errors":351,"./end-of-stream":360,"dup":77}],363:[function(require,module,exports){
    arguments[4][78][0].apply(exports,arguments)
    },{"../../../errors":351,"dup":78}],364:[function(require,module,exports){
    arguments[4][79][0].apply(exports,arguments)
    },{"dup":79,"events":134}],365:[function(require,module,exports){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    'use strict';
    
    /*<replacement>*/
    
    var Buffer = require('safe-buffer').Buffer;
    /*</replacement>*/
    
    var isEncoding = Buffer.isEncoding || function (encoding) {
      encoding = '' + encoding;
      switch (encoding && encoding.toLowerCase()) {
        case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
          return true;
        default:
          return false;
      }
    };
    
    function _normalizeEncoding(enc) {
      if (!enc) return 'utf8';
      var retried;
      while (true) {
        switch (enc) {
          case 'utf8':
          case 'utf-8':
            return 'utf8';
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return 'utf16le';
          case 'latin1':
          case 'binary':
            return 'latin1';
          case 'base64':
          case 'ascii':
          case 'hex':
            return enc;
          default:
            if (retried) return; // undefined
            enc = ('' + enc).toLowerCase();
            retried = true;
        }
      }
    };
    
    // Do not cache `Buffer.isEncoding` when checking encoding names as some
    // modules monkey-patch it to support additional encodings
    function normalizeEncoding(enc) {
      var nenc = _normalizeEncoding(enc);
      if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
      return nenc || enc;
    }
    
    // StringDecoder provides an interface for efficiently splitting a series of
    // buffers into a series of JS strings without breaking apart multi-byte
    // characters.
    exports.StringDecoder = StringDecoder;
    function StringDecoder(encoding) {
      this.encoding = normalizeEncoding(encoding);
      var nb;
      switch (this.encoding) {
        case 'utf16le':
          this.text = utf16Text;
          this.end = utf16End;
          nb = 4;
          break;
        case 'utf8':
          this.fillLast = utf8FillLast;
          nb = 4;
          break;
        case 'base64':
          this.text = base64Text;
          this.end = base64End;
          nb = 3;
          break;
        default:
          this.write = simpleWrite;
          this.end = simpleEnd;
          return;
      }
      this.lastNeed = 0;
      this.lastTotal = 0;
      this.lastChar = Buffer.allocUnsafe(nb);
    }
    
    StringDecoder.prototype.write = function (buf) {
      if (buf.length === 0) return '';
      var r;
      var i;
      if (this.lastNeed) {
        r = this.fillLast(buf);
        if (r === undefined) return '';
        i = this.lastNeed;
        this.lastNeed = 0;
      } else {
        i = 0;
      }
      if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
      return r || '';
    };
    
    StringDecoder.prototype.end = utf8End;
    
    // Returns only complete characters in a Buffer
    StringDecoder.prototype.text = utf8Text;
    
    // Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
    StringDecoder.prototype.fillLast = function (buf) {
      if (this.lastNeed <= buf.length) {
        buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
        return this.lastChar.toString(this.encoding, 0, this.lastTotal);
      }
      buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
      this.lastNeed -= buf.length;
    };
    
    // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
    // continuation byte. If an invalid byte is detected, -2 is returned.
    function utf8CheckByte(byte) {
      if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
      return byte >> 6 === 0x02 ? -1 : -2;
    }
    
    // Checks at most 3 bytes at the end of a Buffer in order to detect an
    // incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
    // needed to complete the UTF-8 character (if applicable) are returned.
    function utf8CheckIncomplete(self, buf, i) {
      var j = buf.length - 1;
      if (j < i) return 0;
      var nb = utf8CheckByte(buf[j]);
      if (nb >= 0) {
        if (nb > 0) self.lastNeed = nb - 1;
        return nb;
      }
      if (--j < i || nb === -2) return 0;
      nb = utf8CheckByte(buf[j]);
      if (nb >= 0) {
        if (nb > 0) self.lastNeed = nb - 2;
        return nb;
      }
      if (--j < i || nb === -2) return 0;
      nb = utf8CheckByte(buf[j]);
      if (nb >= 0) {
        if (nb > 0) {
          if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
        }
        return nb;
      }
      return 0;
    }
    
    // Validates as many continuation bytes for a multi-byte UTF-8 character as
    // needed or are available. If we see a non-continuation byte where we expect
    // one, we "replace" the validated continuation bytes we've seen so far with
    // a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
    // behavior. The continuation byte check is included three times in the case
    // where all of the continuation bytes for a character exist in the same buffer.
    // It is also done this way as a slight performance increase instead of using a
    // loop.
    function utf8CheckExtraBytes(self, buf, p) {
      if ((buf[0] & 0xC0) !== 0x80) {
        self.lastNeed = 0;
        return '\ufffd';
      }
      if (self.lastNeed > 1 && buf.length > 1) {
        if ((buf[1] & 0xC0) !== 0x80) {
          self.lastNeed = 1;
          return '\ufffd';
        }
        if (self.lastNeed > 2 && buf.length > 2) {
          if ((buf[2] & 0xC0) !== 0x80) {
            self.lastNeed = 2;
            return '\ufffd';
          }
        }
      }
    }
    
    // Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
    function utf8FillLast(buf) {
      var p = this.lastTotal - this.lastNeed;
      var r = utf8CheckExtraBytes(this, buf, p);
      if (r !== undefined) return r;
      if (this.lastNeed <= buf.length) {
        buf.copy(this.lastChar, p, 0, this.lastNeed);
        return this.lastChar.toString(this.encoding, 0, this.lastTotal);
      }
      buf.copy(this.lastChar, p, 0, buf.length);
      this.lastNeed -= buf.length;
    }
    
    // Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
    // partial character, the character's bytes are buffered until the required
    // number of bytes are available.
    function utf8Text(buf, i) {
      var total = utf8CheckIncomplete(this, buf, i);
      if (!this.lastNeed) return buf.toString('utf8', i);
      this.lastTotal = total;
      var end = buf.length - (total - this.lastNeed);
      buf.copy(this.lastChar, 0, end);
      return buf.toString('utf8', i, end);
    }
    
    // For UTF-8, a replacement character is added when ending on a partial
    // character.
    function utf8End(buf) {
      var r = buf && buf.length ? this.write(buf) : '';
      if (this.lastNeed) return r + '\ufffd';
      return r;
    }
    
    // UTF-16LE typically needs two bytes per character, but even if we have an even
    // number of bytes available, we need to check if we end on a leading/high
    // surrogate. In that case, we need to wait for the next two bytes in order to
    // decode the last character properly.
    function utf16Text(buf, i) {
      if ((buf.length - i) % 2 === 0) {
        var r = buf.toString('utf16le', i);
        if (r) {
          var c = r.charCodeAt(r.length - 1);
          if (c >= 0xD800 && c <= 0xDBFF) {
            this.lastNeed = 2;
            this.lastTotal = 4;
            this.lastChar[0] = buf[buf.length - 2];
            this.lastChar[1] = buf[buf.length - 1];
            return r.slice(0, -1);
          }
        }
        return r;
      }
      this.lastNeed = 1;
      this.lastTotal = 2;
      this.lastChar[0] = buf[buf.length - 1];
      return buf.toString('utf16le', i, buf.length - 1);
    }
    
    // For UTF-16LE we do not explicitly append special replacement characters if we
    // end on a partial character, we simply let v8 handle that.
    function utf16End(buf) {
      var r = buf && buf.length ? this.write(buf) : '';
      if (this.lastNeed) {
        var end = this.lastTotal - this.lastNeed;
        return r + this.lastChar.toString('utf16le', 0, end);
      }
      return r;
    }
    
    function base64Text(buf, i) {
      var n = (buf.length - i) % 3;
      if (n === 0) return buf.toString('base64', i);
      this.lastNeed = 3 - n;
      this.lastTotal = 3;
      if (n === 1) {
        this.lastChar[0] = buf[buf.length - 1];
      } else {
        this.lastChar[0] = buf[buf.length - 2];
        this.lastChar[1] = buf[buf.length - 1];
      }
      return buf.toString('base64', i, buf.length - n);
    }
    
    function base64End(buf) {
      var r = buf && buf.length ? this.write(buf) : '';
      if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
      return r;
    }
    
    // Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
    function simpleWrite(buf) {
      return buf.toString(this.encoding);
    }
    
    function simpleEnd(buf) {
      return buf && buf.length ? this.write(buf) : '';
    }
    },{"safe-buffer":338}],366:[function(require,module,exports){
    'use strict';
    module.exports = {
        stdout: false,
        stderr: false
    };
    
    },{}],367:[function(require,module,exports){
    (function (root) {
       "use strict";
    
    /***** unorm.js *****/
    
    /*
     * UnicodeNormalizer 1.0.0
     * Copyright (c) 2008 Matsuza
     * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
     * $Date: 2008-06-05 16:44:17 +0200 (Thu, 05 Jun 2008) $
     * $Rev: 13309 $
     */
    
       var DEFAULT_FEATURE = [null, 0, {}];
       var CACHE_THRESHOLD = 10;
       var SBase = 0xAC00, LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7, LCount = 19, VCount = 21, TCount = 28;
       var NCount = VCount * TCount; // 588
       var SCount = LCount * NCount; // 11172
    
       var UChar = function(cp, feature){
          this.codepoint = cp;
          this.feature = feature;
       };
    
       // Strategies
       var cache = {};
       var cacheCounter = [];
       for (var i = 0; i <= 0xFF; ++i){
          cacheCounter[i] = 0;
       }
    
       function fromCache(next, cp, needFeature){
          var ret = cache[cp];
          if(!ret){
             ret = next(cp, needFeature);
             if(!!ret.feature && ++cacheCounter[(cp >> 8) & 0xFF] > CACHE_THRESHOLD){
                cache[cp] = ret;
             }
          }
          return ret;
       }
    
       function fromData(next, cp, needFeature){
          var hash = cp & 0xFF00;
          var dunit = UChar.udata[hash] || {};
          var f = dunit[cp];
          return f ? new UChar(cp, f) : new UChar(cp, DEFAULT_FEATURE);
       }
       function fromCpOnly(next, cp, needFeature){
          return !!needFeature ? next(cp, needFeature) : new UChar(cp, null);
       }
       function fromRuleBasedJamo(next, cp, needFeature){
          var j;
          if(cp < LBase || (LBase + LCount <= cp && cp < SBase) || (SBase + SCount < cp)){
             return next(cp, needFeature);
          }
          if(LBase <= cp && cp < LBase + LCount){
             var c = {};
             var base = (cp - LBase) * VCount;
             for (j = 0; j < VCount; ++j){
                c[VBase + j] = SBase + TCount * (j + base);
             }
             return new UChar(cp, [,,c]);
          }
    
          var SIndex = cp - SBase;
          var TIndex = SIndex % TCount;
          var feature = [];
          if(TIndex !== 0){
             feature[0] = [SBase + SIndex - TIndex, TBase + TIndex];
          } else {
             feature[0] = [LBase + Math.floor(SIndex / NCount), VBase + Math.floor((SIndex % NCount) / TCount)];
             feature[2] = {};
             for (j = 1; j < TCount; ++j){
                feature[2][TBase + j] = cp + j;
             }
          }
          return new UChar(cp, feature);
       }
       function fromCpFilter(next, cp, needFeature){
          return cp < 60 || 13311 < cp && cp < 42607 ? new UChar(cp, DEFAULT_FEATURE) : next(cp, needFeature);
       }
    
       var strategies = [fromCpFilter, fromCache, fromCpOnly, fromRuleBasedJamo, fromData];
    
       UChar.fromCharCode = strategies.reduceRight(function (next, strategy) {
          return function (cp, needFeature) {
             return strategy(next, cp, needFeature);
          };
       }, null);
    
       UChar.isHighSurrogate = function(cp){
          return cp >= 0xD800 && cp <= 0xDBFF;
       };
       UChar.isLowSurrogate = function(cp){
          return cp >= 0xDC00 && cp <= 0xDFFF;
       };
    
       UChar.prototype.prepFeature = function(){
          if(!this.feature){
             this.feature = UChar.fromCharCode(this.codepoint, true).feature;
          }
       };
    
       UChar.prototype.toString = function(){
          if(this.codepoint < 0x10000){
             return String.fromCharCode(this.codepoint);
          } else {
             var x = this.codepoint - 0x10000;
             return String.fromCharCode(Math.floor(x / 0x400) + 0xD800, x % 0x400 + 0xDC00);
          }
       };
    
       UChar.prototype.getDecomp = function(){
          this.prepFeature();
          return this.feature[0] || null;
       };
    
       UChar.prototype.isCompatibility = function(){
          this.prepFeature();
          return !!this.feature[1] && (this.feature[1] & (1 << 8));
       };
       UChar.prototype.isExclude = function(){
          this.prepFeature();
          return !!this.feature[1] && (this.feature[1] & (1 << 9));
       };
       UChar.prototype.getCanonicalClass = function(){
          this.prepFeature();
          return !!this.feature[1] ? (this.feature[1] & 0xff) : 0;
       };
       UChar.prototype.getComposite = function(following){
          this.prepFeature();
          if(!this.feature[2]){
             return null;
          }
          var cp = this.feature[2][following.codepoint];
          return cp ? UChar.fromCharCode(cp) : null;
       };
    
       var UCharIterator = function(str){
          this.str = str;
          this.cursor = 0;
       };
       UCharIterator.prototype.next = function(){
          if(!!this.str && this.cursor < this.str.length){
             var cp = this.str.charCodeAt(this.cursor++);
             var d;
             if(UChar.isHighSurrogate(cp) && this.cursor < this.str.length && UChar.isLowSurrogate((d = this.str.charCodeAt(this.cursor)))){
                cp = (cp - 0xD800) * 0x400 + (d -0xDC00) + 0x10000;
                ++this.cursor;
             }
             return UChar.fromCharCode(cp);
          } else {
             this.str = null;
             return null;
          }
       };
    
       var RecursDecompIterator = function(it, cano){
          this.it = it;
          this.canonical = cano;
          this.resBuf = [];
       };
    
       RecursDecompIterator.prototype.next = function(){
          function recursiveDecomp(cano, uchar){
             var decomp = uchar.getDecomp();
             if(!!decomp && !(cano && uchar.isCompatibility())){
                var ret = [];
                for(var i = 0; i < decomp.length; ++i){
                   var a = recursiveDecomp(cano, UChar.fromCharCode(decomp[i]));
                    ret = ret.concat(a);
                }
                return ret;
             } else {
                return [uchar];
             }
          }
          if(this.resBuf.length === 0){
             var uchar = this.it.next();
             if(!uchar){
                return null;
             }
             this.resBuf = recursiveDecomp(this.canonical, uchar);
          }
          return this.resBuf.shift();
       };
    
       var DecompIterator = function(it){
          this.it = it;
          this.resBuf = [];
       };
    
       DecompIterator.prototype.next = function(){
          var cc;
          if(this.resBuf.length === 0){
             do{
                var uchar = this.it.next();
                if(!uchar){
                   break;
                }
                cc = uchar.getCanonicalClass();
                var inspt = this.resBuf.length;
                if(cc !== 0){
                   for(; inspt > 0; --inspt){
                      var uchar2 = this.resBuf[inspt - 1];
                      var cc2 = uchar2.getCanonicalClass();
                      if(cc2 <= cc){
                         break;
                      }
                   }
                }
                this.resBuf.splice(inspt, 0, uchar);
             } while(cc !== 0);
          }
          return this.resBuf.shift();
       };
    
       var CompIterator = function(it){
          this.it = it;
          this.procBuf = [];
          this.resBuf = [];
          this.lastClass = null;
       };
    
       CompIterator.prototype.next = function(){
          while(this.resBuf.length === 0){
             var uchar = this.it.next();
             if(!uchar){
                this.resBuf = this.procBuf;
                this.procBuf = [];
                break;
             }
             if(this.procBuf.length === 0){
                this.lastClass = uchar.getCanonicalClass();
                this.procBuf.push(uchar);
             } else {
                var starter = this.procBuf[0];
                var composite = starter.getComposite(uchar);
                var cc = uchar.getCanonicalClass();
                if(!!composite && (this.lastClass < cc || this.lastClass === 0)){
                   this.procBuf[0] = composite;
                } else {
                   if(cc === 0){
                      this.resBuf = this.procBuf;
                      this.procBuf = [];
                   }
                   this.lastClass = cc;
                   this.procBuf.push(uchar);
                }
             }
          }
          return this.resBuf.shift();
       };
    
       var createIterator = function(mode, str){
          switch(mode){
             case "NFD":
                return new DecompIterator(new RecursDecompIterator(new UCharIterator(str), true));
             case "NFKD":
                return new DecompIterator(new RecursDecompIterator(new UCharIterator(str), false));
             case "NFC":
                return new CompIterator(new DecompIterator(new RecursDecompIterator(new UCharIterator(str), true)));
             case "NFKC":
                return new CompIterator(new DecompIterator(new RecursDecompIterator(new UCharIterator(str), false)));
          }
          throw mode + " is invalid";
       };
       var normalize = function(mode, str){
          var it = createIterator(mode, str);
          var ret = "";
          var uchar;
          while(!!(uchar = it.next())){
             ret += uchar.toString();
          }
          return ret;
       };
    
       /* API functions */
       function nfd(str){
          return normalize("NFD", str);
       }
    
       function nfkd(str){
          return normalize("NFKD", str);
       }
    
       function nfc(str){
          return normalize("NFC", str);
       }
    
       function nfkc(str){
          return normalize("NFKC", str);
       }
    
    /* Unicode data */
    UChar.udata={
    0:{60:[,,{824:8814}],61:[,,{824:8800}],62:[,,{824:8815}],65:[,,{768:192,769:193,770:194,771:195,772:256,774:258,775:550,776:196,777:7842,778:197,780:461,783:512,785:514,803:7840,805:7680,808:260}],66:[,,{775:7682,803:7684,817:7686}],67:[,,{769:262,770:264,775:266,780:268,807:199}],68:[,,{775:7690,780:270,803:7692,807:7696,813:7698,817:7694}],69:[,,{768:200,769:201,770:202,771:7868,772:274,774:276,775:278,776:203,777:7866,780:282,783:516,785:518,803:7864,807:552,808:280,813:7704,816:7706}],70:[,,{775:7710}],71:[,,{769:500,770:284,772:7712,774:286,775:288,780:486,807:290}],72:[,,{770:292,775:7714,776:7718,780:542,803:7716,807:7720,814:7722}],73:[,,{768:204,769:205,770:206,771:296,772:298,774:300,775:304,776:207,777:7880,780:463,783:520,785:522,803:7882,808:302,816:7724}],74:[,,{770:308}],75:[,,{769:7728,780:488,803:7730,807:310,817:7732}],76:[,,{769:313,780:317,803:7734,807:315,813:7740,817:7738}],77:[,,{769:7742,775:7744,803:7746}],78:[,,{768:504,769:323,771:209,775:7748,780:327,803:7750,807:325,813:7754,817:7752}],79:[,,{768:210,769:211,770:212,771:213,772:332,774:334,775:558,776:214,777:7886,779:336,780:465,783:524,785:526,795:416,803:7884,808:490}],80:[,,{769:7764,775:7766}],82:[,,{769:340,775:7768,780:344,783:528,785:530,803:7770,807:342,817:7774}],83:[,,{769:346,770:348,775:7776,780:352,803:7778,806:536,807:350}],84:[,,{775:7786,780:356,803:7788,806:538,807:354,813:7792,817:7790}],85:[,,{768:217,769:218,770:219,771:360,772:362,774:364,776:220,777:7910,778:366,779:368,780:467,783:532,785:534,795:431,803:7908,804:7794,808:370,813:7798,816:7796}],86:[,,{771:7804,803:7806}],87:[,,{768:7808,769:7810,770:372,775:7814,776:7812,803:7816}],88:[,,{775:7818,776:7820}],89:[,,{768:7922,769:221,770:374,771:7928,772:562,775:7822,776:376,777:7926,803:7924}],90:[,,{769:377,770:7824,775:379,780:381,803:7826,817:7828}],97:[,,{768:224,769:225,770:226,771:227,772:257,774:259,775:551,776:228,777:7843,778:229,780:462,783:513,785:515,803:7841,805:7681,808:261}],98:[,,{775:7683,803:7685,817:7687}],99:[,,{769:263,770:265,775:267,780:269,807:231}],100:[,,{775:7691,780:271,803:7693,807:7697,813:7699,817:7695}],101:[,,{768:232,769:233,770:234,771:7869,772:275,774:277,775:279,776:235,777:7867,780:283,783:517,785:519,803:7865,807:553,808:281,813:7705,816:7707}],102:[,,{775:7711}],103:[,,{769:501,770:285,772:7713,774:287,775:289,780:487,807:291}],104:[,,{770:293,775:7715,776:7719,780:543,803:7717,807:7721,814:7723,817:7830}],105:[,,{768:236,769:237,770:238,771:297,772:299,774:301,776:239,777:7881,780:464,783:521,785:523,803:7883,808:303,816:7725}],106:[,,{770:309,780:496}],107:[,,{769:7729,780:489,803:7731,807:311,817:7733}],108:[,,{769:314,780:318,803:7735,807:316,813:7741,817:7739}],109:[,,{769:7743,775:7745,803:7747}],110:[,,{768:505,769:324,771:241,775:7749,780:328,803:7751,807:326,813:7755,817:7753}],111:[,,{768:242,769:243,770:244,771:245,772:333,774:335,775:559,776:246,777:7887,779:337,780:466,783:525,785:527,795:417,803:7885,808:491}],112:[,,{769:7765,775:7767}],114:[,,{769:341,775:7769,780:345,783:529,785:531,803:7771,807:343,817:7775}],115:[,,{769:347,770:349,775:7777,780:353,803:7779,806:537,807:351}],116:[,,{775:7787,776:7831,780:357,803:7789,806:539,807:355,813:7793,817:7791}],117:[,,{768:249,769:250,770:251,771:361,772:363,774:365,776:252,777:7911,778:367,779:369,780:468,783:533,785:535,795:432,803:7909,804:7795,808:371,813:7799,816:7797}],118:[,,{771:7805,803:7807}],119:[,,{768:7809,769:7811,770:373,775:7815,776:7813,778:7832,803:7817}],120:[,,{775:7819,776:7821}],121:[,,{768:7923,769:253,770:375,771:7929,772:563,775:7823,776:255,777:7927,778:7833,803:7925}],122:[,,{769:378,770:7825,775:380,780:382,803:7827,817:7829}],160:[[32],256],168:[[32,776],256,{768:8173,769:901,834:8129}],170:[[97],256],175:[[32,772],256],178:[[50],256],179:[[51],256],180:[[32,769],256],181:[[956],256],184:[[32,807],256],185:[[49],256],186:[[111],256],188:[[49,8260,52],256],189:[[49,8260,50],256],190:[[51,8260,52],256],192:[[65,768]],193:[[65,769]],194:[[65,770],,{768:7846,769:7844,771:7850,777:7848}],195:[[65,771]],196:[[65,776],,{772:478}],197:[[65,778],,{769:506}],198:[,,{769:508,772:482}],199:[[67,807],,{769:7688}],200:[[69,768]],201:[[69,769]],202:[[69,770],,{768:7872,769:7870,771:7876,777:7874}],203:[[69,776]],204:[[73,768]],205:[[73,769]],206:[[73,770]],207:[[73,776],,{769:7726}],209:[[78,771]],210:[[79,768]],211:[[79,769]],212:[[79,770],,{768:7890,769:7888,771:7894,777:7892}],213:[[79,771],,{769:7756,772:556,776:7758}],214:[[79,776],,{772:554}],216:[,,{769:510}],217:[[85,768]],218:[[85,769]],219:[[85,770]],220:[[85,776],,{768:475,769:471,772:469,780:473}],221:[[89,769]],224:[[97,768]],225:[[97,769]],226:[[97,770],,{768:7847,769:7845,771:7851,777:7849}],227:[[97,771]],228:[[97,776],,{772:479}],229:[[97,778],,{769:507}],230:[,,{769:509,772:483}],231:[[99,807],,{769:7689}],232:[[101,768]],233:[[101,769]],234:[[101,770],,{768:7873,769:7871,771:7877,777:7875}],235:[[101,776]],236:[[105,768]],237:[[105,769]],238:[[105,770]],239:[[105,776],,{769:7727}],241:[[110,771]],242:[[111,768]],243:[[111,769]],244:[[111,770],,{768:7891,769:7889,771:7895,777:7893}],245:[[111,771],,{769:7757,772:557,776:7759}],246:[[111,776],,{772:555}],248:[,,{769:511}],249:[[117,768]],250:[[117,769]],251:[[117,770]],252:[[117,776],,{768:476,769:472,772:470,780:474}],253:[[121,769]],255:[[121,776]]},
    256:{256:[[65,772]],257:[[97,772]],258:[[65,774],,{768:7856,769:7854,771:7860,777:7858}],259:[[97,774],,{768:7857,769:7855,771:7861,777:7859}],260:[[65,808]],261:[[97,808]],262:[[67,769]],263:[[99,769]],264:[[67,770]],265:[[99,770]],266:[[67,775]],267:[[99,775]],268:[[67,780]],269:[[99,780]],270:[[68,780]],271:[[100,780]],274:[[69,772],,{768:7700,769:7702}],275:[[101,772],,{768:7701,769:7703}],276:[[69,774]],277:[[101,774]],278:[[69,775]],279:[[101,775]],280:[[69,808]],281:[[101,808]],282:[[69,780]],283:[[101,780]],284:[[71,770]],285:[[103,770]],286:[[71,774]],287:[[103,774]],288:[[71,775]],289:[[103,775]],290:[[71,807]],291:[[103,807]],292:[[72,770]],293:[[104,770]],296:[[73,771]],297:[[105,771]],298:[[73,772]],299:[[105,772]],300:[[73,774]],301:[[105,774]],302:[[73,808]],303:[[105,808]],304:[[73,775]],306:[[73,74],256],307:[[105,106],256],308:[[74,770]],309:[[106,770]],310:[[75,807]],311:[[107,807]],313:[[76,769]],314:[[108,769]],315:[[76,807]],316:[[108,807]],317:[[76,780]],318:[[108,780]],319:[[76,183],256],320:[[108,183],256],323:[[78,769]],324:[[110,769]],325:[[78,807]],326:[[110,807]],327:[[78,780]],328:[[110,780]],329:[[700,110],256],332:[[79,772],,{768:7760,769:7762}],333:[[111,772],,{768:7761,769:7763}],334:[[79,774]],335:[[111,774]],336:[[79,779]],337:[[111,779]],340:[[82,769]],341:[[114,769]],342:[[82,807]],343:[[114,807]],344:[[82,780]],345:[[114,780]],346:[[83,769],,{775:7780}],347:[[115,769],,{775:7781}],348:[[83,770]],349:[[115,770]],350:[[83,807]],351:[[115,807]],352:[[83,780],,{775:7782}],353:[[115,780],,{775:7783}],354:[[84,807]],355:[[116,807]],356:[[84,780]],357:[[116,780]],360:[[85,771],,{769:7800}],361:[[117,771],,{769:7801}],362:[[85,772],,{776:7802}],363:[[117,772],,{776:7803}],364:[[85,774]],365:[[117,774]],366:[[85,778]],367:[[117,778]],368:[[85,779]],369:[[117,779]],370:[[85,808]],371:[[117,808]],372:[[87,770]],373:[[119,770]],374:[[89,770]],375:[[121,770]],376:[[89,776]],377:[[90,769]],378:[[122,769]],379:[[90,775]],380:[[122,775]],381:[[90,780]],382:[[122,780]],383:[[115],256,{775:7835}],416:[[79,795],,{768:7900,769:7898,771:7904,777:7902,803:7906}],417:[[111,795],,{768:7901,769:7899,771:7905,777:7903,803:7907}],431:[[85,795],,{768:7914,769:7912,771:7918,777:7916,803:7920}],432:[[117,795],,{768:7915,769:7913,771:7919,777:7917,803:7921}],439:[,,{780:494}],452:[[68,381],256],453:[[68,382],256],454:[[100,382],256],455:[[76,74],256],456:[[76,106],256],457:[[108,106],256],458:[[78,74],256],459:[[78,106],256],460:[[110,106],256],461:[[65,780]],462:[[97,780]],463:[[73,780]],464:[[105,780]],465:[[79,780]],466:[[111,780]],467:[[85,780]],468:[[117,780]],469:[[220,772]],470:[[252,772]],471:[[220,769]],472:[[252,769]],473:[[220,780]],474:[[252,780]],475:[[220,768]],476:[[252,768]],478:[[196,772]],479:[[228,772]],480:[[550,772]],481:[[551,772]],482:[[198,772]],483:[[230,772]],486:[[71,780]],487:[[103,780]],488:[[75,780]],489:[[107,780]],490:[[79,808],,{772:492}],491:[[111,808],,{772:493}],492:[[490,772]],493:[[491,772]],494:[[439,780]],495:[[658,780]],496:[[106,780]],497:[[68,90],256],498:[[68,122],256],499:[[100,122],256],500:[[71,769]],501:[[103,769]],504:[[78,768]],505:[[110,768]],506:[[197,769]],507:[[229,769]],508:[[198,769]],509:[[230,769]],510:[[216,769]],511:[[248,769]],66045:[,220]},
    512:{512:[[65,783]],513:[[97,783]],514:[[65,785]],515:[[97,785]],516:[[69,783]],517:[[101,783]],518:[[69,785]],519:[[101,785]],520:[[73,783]],521:[[105,783]],522:[[73,785]],523:[[105,785]],524:[[79,783]],525:[[111,783]],526:[[79,785]],527:[[111,785]],528:[[82,783]],529:[[114,783]],530:[[82,785]],531:[[114,785]],532:[[85,783]],533:[[117,783]],534:[[85,785]],535:[[117,785]],536:[[83,806]],537:[[115,806]],538:[[84,806]],539:[[116,806]],542:[[72,780]],543:[[104,780]],550:[[65,775],,{772:480}],551:[[97,775],,{772:481}],552:[[69,807],,{774:7708}],553:[[101,807],,{774:7709}],554:[[214,772]],555:[[246,772]],556:[[213,772]],557:[[245,772]],558:[[79,775],,{772:560}],559:[[111,775],,{772:561}],560:[[558,772]],561:[[559,772]],562:[[89,772]],563:[[121,772]],658:[,,{780:495}],688:[[104],256],689:[[614],256],690:[[106],256],691:[[114],256],692:[[633],256],693:[[635],256],694:[[641],256],695:[[119],256],696:[[121],256],728:[[32,774],256],729:[[32,775],256],730:[[32,778],256],731:[[32,808],256],732:[[32,771],256],733:[[32,779],256],736:[[611],256],737:[[108],256],738:[[115],256],739:[[120],256],740:[[661],256],66272:[,220]},
    768:{768:[,230],769:[,230],770:[,230],771:[,230],772:[,230],773:[,230],774:[,230],775:[,230],776:[,230,{769:836}],777:[,230],778:[,230],779:[,230],780:[,230],781:[,230],782:[,230],783:[,230],784:[,230],785:[,230],786:[,230],787:[,230],788:[,230],789:[,232],790:[,220],791:[,220],792:[,220],793:[,220],794:[,232],795:[,216],796:[,220],797:[,220],798:[,220],799:[,220],800:[,220],801:[,202],802:[,202],803:[,220],804:[,220],805:[,220],806:[,220],807:[,202],808:[,202],809:[,220],810:[,220],811:[,220],812:[,220],813:[,220],814:[,220],815:[,220],816:[,220],817:[,220],818:[,220],819:[,220],820:[,1],821:[,1],822:[,1],823:[,1],824:[,1],825:[,220],826:[,220],827:[,220],828:[,220],829:[,230],830:[,230],831:[,230],832:[[768],230],833:[[769],230],834:[,230],835:[[787],230],836:[[776,769],230],837:[,240],838:[,230],839:[,220],840:[,220],841:[,220],842:[,230],843:[,230],844:[,230],845:[,220],846:[,220],848:[,230],849:[,230],850:[,230],851:[,220],852:[,220],853:[,220],854:[,220],855:[,230],856:[,232],857:[,220],858:[,220],859:[,230],860:[,233],861:[,234],862:[,234],863:[,233],864:[,234],865:[,234],866:[,233],867:[,230],868:[,230],869:[,230],870:[,230],871:[,230],872:[,230],873:[,230],874:[,230],875:[,230],876:[,230],877:[,230],878:[,230],879:[,230],884:[[697]],890:[[32,837],256],894:[[59]],900:[[32,769],256],901:[[168,769]],902:[[913,769]],903:[[183]],904:[[917,769]],905:[[919,769]],906:[[921,769]],908:[[927,769]],910:[[933,769]],911:[[937,769]],912:[[970,769]],913:[,,{768:8122,769:902,772:8121,774:8120,787:7944,788:7945,837:8124}],917:[,,{768:8136,769:904,787:7960,788:7961}],919:[,,{768:8138,769:905,787:7976,788:7977,837:8140}],921:[,,{768:8154,769:906,772:8153,774:8152,776:938,787:7992,788:7993}],927:[,,{768:8184,769:908,787:8008,788:8009}],929:[,,{788:8172}],933:[,,{768:8170,769:910,772:8169,774:8168,776:939,788:8025}],937:[,,{768:8186,769:911,787:8040,788:8041,837:8188}],938:[[921,776]],939:[[933,776]],940:[[945,769],,{837:8116}],941:[[949,769]],942:[[951,769],,{837:8132}],943:[[953,769]],944:[[971,769]],945:[,,{768:8048,769:940,772:8113,774:8112,787:7936,788:7937,834:8118,837:8115}],949:[,,{768:8050,769:941,787:7952,788:7953}],951:[,,{768:8052,769:942,787:7968,788:7969,834:8134,837:8131}],953:[,,{768:8054,769:943,772:8145,774:8144,776:970,787:7984,788:7985,834:8150}],959:[,,{768:8056,769:972,787:8000,788:8001}],961:[,,{787:8164,788:8165}],965:[,,{768:8058,769:973,772:8161,774:8160,776:971,787:8016,788:8017,834:8166}],969:[,,{768:8060,769:974,787:8032,788:8033,834:8182,837:8179}],970:[[953,776],,{768:8146,769:912,834:8151}],971:[[965,776],,{768:8162,769:944,834:8167}],972:[[959,769]],973:[[965,769]],974:[[969,769],,{837:8180}],976:[[946],256],977:[[952],256],978:[[933],256,{769:979,776:980}],979:[[978,769]],980:[[978,776]],981:[[966],256],982:[[960],256],1008:[[954],256],1009:[[961],256],1010:[[962],256],1012:[[920],256],1013:[[949],256],1017:[[931],256],66422:[,230],66423:[,230],66424:[,230],66425:[,230],66426:[,230]},
    1024:{1024:[[1045,768]],1025:[[1045,776]],1027:[[1043,769]],1030:[,,{776:1031}],1031:[[1030,776]],1036:[[1050,769]],1037:[[1048,768]],1038:[[1059,774]],1040:[,,{774:1232,776:1234}],1043:[,,{769:1027}],1045:[,,{768:1024,774:1238,776:1025}],1046:[,,{774:1217,776:1244}],1047:[,,{776:1246}],1048:[,,{768:1037,772:1250,774:1049,776:1252}],1049:[[1048,774]],1050:[,,{769:1036}],1054:[,,{776:1254}],1059:[,,{772:1262,774:1038,776:1264,779:1266}],1063:[,,{776:1268}],1067:[,,{776:1272}],1069:[,,{776:1260}],1072:[,,{774:1233,776:1235}],1075:[,,{769:1107}],1077:[,,{768:1104,774:1239,776:1105}],1078:[,,{774:1218,776:1245}],1079:[,,{776:1247}],1080:[,,{768:1117,772:1251,774:1081,776:1253}],1081:[[1080,774]],1082:[,,{769:1116}],1086:[,,{776:1255}],1091:[,,{772:1263,774:1118,776:1265,779:1267}],1095:[,,{776:1269}],1099:[,,{776:1273}],1101:[,,{776:1261}],1104:[[1077,768]],1105:[[1077,776]],1107:[[1075,769]],1110:[,,{776:1111}],1111:[[1110,776]],1116:[[1082,769]],1117:[[1080,768]],1118:[[1091,774]],1140:[,,{783:1142}],1141:[,,{783:1143}],1142:[[1140,783]],1143:[[1141,783]],1155:[,230],1156:[,230],1157:[,230],1158:[,230],1159:[,230],1217:[[1046,774]],1218:[[1078,774]],1232:[[1040,774]],1233:[[1072,774]],1234:[[1040,776]],1235:[[1072,776]],1238:[[1045,774]],1239:[[1077,774]],1240:[,,{776:1242}],1241:[,,{776:1243}],1242:[[1240,776]],1243:[[1241,776]],1244:[[1046,776]],1245:[[1078,776]],1246:[[1047,776]],1247:[[1079,776]],1250:[[1048,772]],1251:[[1080,772]],1252:[[1048,776]],1253:[[1080,776]],1254:[[1054,776]],1255:[[1086,776]],1256:[,,{776:1258}],1257:[,,{776:1259}],1258:[[1256,776]],1259:[[1257,776]],1260:[[1069,776]],1261:[[1101,776]],1262:[[1059,772]],1263:[[1091,772]],1264:[[1059,776]],1265:[[1091,776]],1266:[[1059,779]],1267:[[1091,779]],1268:[[1063,776]],1269:[[1095,776]],1272:[[1067,776]],1273:[[1099,776]]},
    1280:{1415:[[1381,1410],256],1425:[,220],1426:[,230],1427:[,230],1428:[,230],1429:[,230],1430:[,220],1431:[,230],1432:[,230],1433:[,230],1434:[,222],1435:[,220],1436:[,230],1437:[,230],1438:[,230],1439:[,230],1440:[,230],1441:[,230],1442:[,220],1443:[,220],1444:[,220],1445:[,220],1446:[,220],1447:[,220],1448:[,230],1449:[,230],1450:[,220],1451:[,230],1452:[,230],1453:[,222],1454:[,228],1455:[,230],1456:[,10],1457:[,11],1458:[,12],1459:[,13],1460:[,14],1461:[,15],1462:[,16],1463:[,17],1464:[,18],1465:[,19],1466:[,19],1467:[,20],1468:[,21],1469:[,22],1471:[,23],1473:[,24],1474:[,25],1476:[,230],1477:[,220],1479:[,18]},
    1536:{1552:[,230],1553:[,230],1554:[,230],1555:[,230],1556:[,230],1557:[,230],1558:[,230],1559:[,230],1560:[,30],1561:[,31],1562:[,32],1570:[[1575,1619]],1571:[[1575,1620]],1572:[[1608,1620]],1573:[[1575,1621]],1574:[[1610,1620]],1575:[,,{1619:1570,1620:1571,1621:1573}],1608:[,,{1620:1572}],1610:[,,{1620:1574}],1611:[,27],1612:[,28],1613:[,29],1614:[,30],1615:[,31],1616:[,32],1617:[,33],1618:[,34],1619:[,230],1620:[,230],1621:[,220],1622:[,220],1623:[,230],1624:[,230],1625:[,230],1626:[,230],1627:[,230],1628:[,220],1629:[,230],1630:[,230],1631:[,220],1648:[,35],1653:[[1575,1652],256],1654:[[1608,1652],256],1655:[[1735,1652],256],1656:[[1610,1652],256],1728:[[1749,1620]],1729:[,,{1620:1730}],1730:[[1729,1620]],1746:[,,{1620:1747}],1747:[[1746,1620]],1749:[,,{1620:1728}],1750:[,230],1751:[,230],1752:[,230],1753:[,230],1754:[,230],1755:[,230],1756:[,230],1759:[,230],1760:[,230],1761:[,230],1762:[,230],1763:[,220],1764:[,230],1767:[,230],1768:[,230],1770:[,220],1771:[,230],1772:[,230],1773:[,220]},
    1792:{1809:[,36],1840:[,230],1841:[,220],1842:[,230],1843:[,230],1844:[,220],1845:[,230],1846:[,230],1847:[,220],1848:[,220],1849:[,220],1850:[,230],1851:[,220],1852:[,220],1853:[,230],1854:[,220],1855:[,230],1856:[,230],1857:[,230],1858:[,220],1859:[,230],1860:[,220],1861:[,230],1862:[,220],1863:[,230],1864:[,220],1865:[,230],1866:[,230],2027:[,230],2028:[,230],2029:[,230],2030:[,230],2031:[,230],2032:[,230],2033:[,230],2034:[,220],2035:[,230]},
    2048:{2070:[,230],2071:[,230],2072:[,230],2073:[,230],2075:[,230],2076:[,230],2077:[,230],2078:[,230],2079:[,230],2080:[,230],2081:[,230],2082:[,230],2083:[,230],2085:[,230],2086:[,230],2087:[,230],2089:[,230],2090:[,230],2091:[,230],2092:[,230],2093:[,230],2137:[,220],2138:[,220],2139:[,220],2276:[,230],2277:[,230],2278:[,220],2279:[,230],2280:[,230],2281:[,220],2282:[,230],2283:[,230],2284:[,230],2285:[,220],2286:[,220],2287:[,220],2288:[,27],2289:[,28],2290:[,29],2291:[,230],2292:[,230],2293:[,230],2294:[,220],2295:[,230],2296:[,230],2297:[,220],2298:[,220],2299:[,230],2300:[,230],2301:[,230],2302:[,230],2303:[,230]},
    2304:{2344:[,,{2364:2345}],2345:[[2344,2364]],2352:[,,{2364:2353}],2353:[[2352,2364]],2355:[,,{2364:2356}],2356:[[2355,2364]],2364:[,7],2381:[,9],2385:[,230],2386:[,220],2387:[,230],2388:[,230],2392:[[2325,2364],512],2393:[[2326,2364],512],2394:[[2327,2364],512],2395:[[2332,2364],512],2396:[[2337,2364],512],2397:[[2338,2364],512],2398:[[2347,2364],512],2399:[[2351,2364],512],2492:[,7],2503:[,,{2494:2507,2519:2508}],2507:[[2503,2494]],2508:[[2503,2519]],2509:[,9],2524:[[2465,2492],512],2525:[[2466,2492],512],2527:[[2479,2492],512]},
    2560:{2611:[[2610,2620],512],2614:[[2616,2620],512],2620:[,7],2637:[,9],2649:[[2582,2620],512],2650:[[2583,2620],512],2651:[[2588,2620],512],2654:[[2603,2620],512],2748:[,7],2765:[,9],68109:[,220],68111:[,230],68152:[,230],68153:[,1],68154:[,220],68159:[,9],68325:[,230],68326:[,220]},
    2816:{2876:[,7],2887:[,,{2878:2891,2902:2888,2903:2892}],2888:[[2887,2902]],2891:[[2887,2878]],2892:[[2887,2903]],2893:[,9],2908:[[2849,2876],512],2909:[[2850,2876],512],2962:[,,{3031:2964}],2964:[[2962,3031]],3014:[,,{3006:3018,3031:3020}],3015:[,,{3006:3019}],3018:[[3014,3006]],3019:[[3015,3006]],3020:[[3014,3031]],3021:[,9]},
    3072:{3142:[,,{3158:3144}],3144:[[3142,3158]],3149:[,9],3157:[,84],3158:[,91],3260:[,7],3263:[,,{3285:3264}],3264:[[3263,3285]],3270:[,,{3266:3274,3285:3271,3286:3272}],3271:[[3270,3285]],3272:[[3270,3286]],3274:[[3270,3266],,{3285:3275}],3275:[[3274,3285]],3277:[,9]},
    3328:{3398:[,,{3390:3402,3415:3404}],3399:[,,{3390:3403}],3402:[[3398,3390]],3403:[[3399,3390]],3404:[[3398,3415]],3405:[,9],3530:[,9],3545:[,,{3530:3546,3535:3548,3551:3550}],3546:[[3545,3530]],3548:[[3545,3535],,{3530:3549}],3549:[[3548,3530]],3550:[[3545,3551]]},
    3584:{3635:[[3661,3634],256],3640:[,103],3641:[,103],3642:[,9],3656:[,107],3657:[,107],3658:[,107],3659:[,107],3763:[[3789,3762],256],3768:[,118],3769:[,118],3784:[,122],3785:[,122],3786:[,122],3787:[,122],3804:[[3755,3737],256],3805:[[3755,3745],256]},
    3840:{3852:[[3851],256],3864:[,220],3865:[,220],3893:[,220],3895:[,220],3897:[,216],3907:[[3906,4023],512],3917:[[3916,4023],512],3922:[[3921,4023],512],3927:[[3926,4023],512],3932:[[3931,4023],512],3945:[[3904,4021],512],3953:[,129],3954:[,130],3955:[[3953,3954],512],3956:[,132],3957:[[3953,3956],512],3958:[[4018,3968],512],3959:[[4018,3969],256],3960:[[4019,3968],512],3961:[[4019,3969],256],3962:[,130],3963:[,130],3964:[,130],3965:[,130],3968:[,130],3969:[[3953,3968],512],3970:[,230],3971:[,230],3972:[,9],3974:[,230],3975:[,230],3987:[[3986,4023],512],3997:[[3996,4023],512],4002:[[4001,4023],512],4007:[[4006,4023],512],4012:[[4011,4023],512],4025:[[3984,4021],512],4038:[,220]},
    4096:{4133:[,,{4142:4134}],4134:[[4133,4142]],4151:[,7],4153:[,9],4154:[,9],4237:[,220],4348:[[4316],256],69702:[,9],69759:[,9],69785:[,,{69818:69786}],69786:[[69785,69818]],69787:[,,{69818:69788}],69788:[[69787,69818]],69797:[,,{69818:69803}],69803:[[69797,69818]],69817:[,9],69818:[,7]},
    4352:{69888:[,230],69889:[,230],69890:[,230],69934:[[69937,69927]],69935:[[69938,69927]],69937:[,,{69927:69934}],69938:[,,{69927:69935}],69939:[,9],69940:[,9],70003:[,7],70080:[,9]},
    4608:{70197:[,9],70198:[,7],70377:[,7],70378:[,9]},
    4864:{4957:[,230],4958:[,230],4959:[,230],70460:[,7],70471:[,,{70462:70475,70487:70476}],70475:[[70471,70462]],70476:[[70471,70487]],70477:[,9],70502:[,230],70503:[,230],70504:[,230],70505:[,230],70506:[,230],70507:[,230],70508:[,230],70512:[,230],70513:[,230],70514:[,230],70515:[,230],70516:[,230]},
    5120:{70841:[,,{70832:70844,70842:70843,70845:70846}],70843:[[70841,70842]],70844:[[70841,70832]],70846:[[70841,70845]],70850:[,9],70851:[,7]},
    5376:{71096:[,,{71087:71098}],71097:[,,{71087:71099}],71098:[[71096,71087]],71099:[[71097,71087]],71103:[,9],71104:[,7]},
    5632:{71231:[,9],71350:[,9],71351:[,7]},
    5888:{5908:[,9],5940:[,9],6098:[,9],6109:[,230]},
    6144:{6313:[,228]},
    6400:{6457:[,222],6458:[,230],6459:[,220]},
    6656:{6679:[,230],6680:[,220],6752:[,9],6773:[,230],6774:[,230],6775:[,230],6776:[,230],6777:[,230],6778:[,230],6779:[,230],6780:[,230],6783:[,220],6832:[,230],6833:[,230],6834:[,230],6835:[,230],6836:[,230],6837:[,220],6838:[,220],6839:[,220],6840:[,220],6841:[,220],6842:[,220],6843:[,230],6844:[,230],6845:[,220]},
    6912:{6917:[,,{6965:6918}],6918:[[6917,6965]],6919:[,,{6965:6920}],6920:[[6919,6965]],6921:[,,{6965:6922}],6922:[[6921,6965]],6923:[,,{6965:6924}],6924:[[6923,6965]],6925:[,,{6965:6926}],6926:[[6925,6965]],6929:[,,{6965:6930}],6930:[[6929,6965]],6964:[,7],6970:[,,{6965:6971}],6971:[[6970,6965]],6972:[,,{6965:6973}],6973:[[6972,6965]],6974:[,,{6965:6976}],6975:[,,{6965:6977}],6976:[[6974,6965]],6977:[[6975,6965]],6978:[,,{6965:6979}],6979:[[6978,6965]],6980:[,9],7019:[,230],7020:[,220],7021:[,230],7022:[,230],7023:[,230],7024:[,230],7025:[,230],7026:[,230],7027:[,230],7082:[,9],7083:[,9],7142:[,7],7154:[,9],7155:[,9]},
    7168:{7223:[,7],7376:[,230],7377:[,230],7378:[,230],7380:[,1],7381:[,220],7382:[,220],7383:[,220],7384:[,220],7385:[,220],7386:[,230],7387:[,230],7388:[,220],7389:[,220],7390:[,220],7391:[,220],7392:[,230],7394:[,1],7395:[,1],7396:[,1],7397:[,1],7398:[,1],7399:[,1],7400:[,1],7405:[,220],7412:[,230],7416:[,230],7417:[,230]},
    7424:{7468:[[65],256],7469:[[198],256],7470:[[66],256],7472:[[68],256],7473:[[69],256],7474:[[398],256],7475:[[71],256],7476:[[72],256],7477:[[73],256],7478:[[74],256],7479:[[75],256],7480:[[76],256],7481:[[77],256],7482:[[78],256],7484:[[79],256],7485:[[546],256],7486:[[80],256],7487:[[82],256],7488:[[84],256],7489:[[85],256],7490:[[87],256],7491:[[97],256],7492:[[592],256],7493:[[593],256],7494:[[7426],256],7495:[[98],256],7496:[[100],256],7497:[[101],256],7498:[[601],256],7499:[[603],256],7500:[[604],256],7501:[[103],256],7503:[[107],256],7504:[[109],256],7505:[[331],256],7506:[[111],256],7507:[[596],256],7508:[[7446],256],7509:[[7447],256],7510:[[112],256],7511:[[116],256],7512:[[117],256],7513:[[7453],256],7514:[[623],256],7515:[[118],256],7516:[[7461],256],7517:[[946],256],7518:[[947],256],7519:[[948],256],7520:[[966],256],7521:[[967],256],7522:[[105],256],7523:[[114],256],7524:[[117],256],7525:[[118],256],7526:[[946],256],7527:[[947],256],7528:[[961],256],7529:[[966],256],7530:[[967],256],7544:[[1085],256],7579:[[594],256],7580:[[99],256],7581:[[597],256],7582:[[240],256],7583:[[604],256],7584:[[102],256],7585:[[607],256],7586:[[609],256],7587:[[613],256],7588:[[616],256],7589:[[617],256],7590:[[618],256],7591:[[7547],256],7592:[[669],256],7593:[[621],256],7594:[[7557],256],7595:[[671],256],7596:[[625],256],7597:[[624],256],7598:[[626],256],7599:[[627],256],7600:[[628],256],7601:[[629],256],7602:[[632],256],7603:[[642],256],7604:[[643],256],7605:[[427],256],7606:[[649],256],7607:[[650],256],7608:[[7452],256],7609:[[651],256],7610:[[652],256],7611:[[122],256],7612:[[656],256],7613:[[657],256],7614:[[658],256],7615:[[952],256],7616:[,230],7617:[,230],7618:[,220],7619:[,230],7620:[,230],7621:[,230],7622:[,230],7623:[,230],7624:[,230],7625:[,230],7626:[,220],7627:[,230],7628:[,230],7629:[,234],7630:[,214],7631:[,220],7632:[,202],7633:[,230],7634:[,230],7635:[,230],7636:[,230],7637:[,230],7638:[,230],7639:[,230],7640:[,230],7641:[,230],7642:[,230],7643:[,230],7644:[,230],7645:[,230],7646:[,230],7647:[,230],7648:[,230],7649:[,230],7650:[,230],7651:[,230],7652:[,230],7653:[,230],7654:[,230],7655:[,230],7656:[,230],7657:[,230],7658:[,230],7659:[,230],7660:[,230],7661:[,230],7662:[,230],7663:[,230],7664:[,230],7665:[,230],7666:[,230],7667:[,230],7668:[,230],7669:[,230],7676:[,233],7677:[,220],7678:[,230],7679:[,220]},
    7680:{7680:[[65,805]],7681:[[97,805]],7682:[[66,775]],7683:[[98,775]],7684:[[66,803]],7685:[[98,803]],7686:[[66,817]],7687:[[98,817]],7688:[[199,769]],7689:[[231,769]],7690:[[68,775]],7691:[[100,775]],7692:[[68,803]],7693:[[100,803]],7694:[[68,817]],7695:[[100,817]],7696:[[68,807]],7697:[[100,807]],7698:[[68,813]],7699:[[100,813]],7700:[[274,768]],7701:[[275,768]],7702:[[274,769]],7703:[[275,769]],7704:[[69,813]],7705:[[101,813]],7706:[[69,816]],7707:[[101,816]],7708:[[552,774]],7709:[[553,774]],7710:[[70,775]],7711:[[102,775]],7712:[[71,772]],7713:[[103,772]],7714:[[72,775]],7715:[[104,775]],7716:[[72,803]],7717:[[104,803]],7718:[[72,776]],7719:[[104,776]],7720:[[72,807]],7721:[[104,807]],7722:[[72,814]],7723:[[104,814]],7724:[[73,816]],7725:[[105,816]],7726:[[207,769]],7727:[[239,769]],7728:[[75,769]],7729:[[107,769]],7730:[[75,803]],7731:[[107,803]],7732:[[75,817]],7733:[[107,817]],7734:[[76,803],,{772:7736}],7735:[[108,803],,{772:7737}],7736:[[7734,772]],7737:[[7735,772]],7738:[[76,817]],7739:[[108,817]],7740:[[76,813]],7741:[[108,813]],7742:[[77,769]],7743:[[109,769]],7744:[[77,775]],7745:[[109,775]],7746:[[77,803]],7747:[[109,803]],7748:[[78,775]],7749:[[110,775]],7750:[[78,803]],7751:[[110,803]],7752:[[78,817]],7753:[[110,817]],7754:[[78,813]],7755:[[110,813]],7756:[[213,769]],7757:[[245,769]],7758:[[213,776]],7759:[[245,776]],7760:[[332,768]],7761:[[333,768]],7762:[[332,769]],7763:[[333,769]],7764:[[80,769]],7765:[[112,769]],7766:[[80,775]],7767:[[112,775]],7768:[[82,775]],7769:[[114,775]],7770:[[82,803],,{772:7772}],7771:[[114,803],,{772:7773}],7772:[[7770,772]],7773:[[7771,772]],7774:[[82,817]],7775:[[114,817]],7776:[[83,775]],7777:[[115,775]],7778:[[83,803],,{775:7784}],7779:[[115,803],,{775:7785}],7780:[[346,775]],7781:[[347,775]],7782:[[352,775]],7783:[[353,775]],7784:[[7778,775]],7785:[[7779,775]],7786:[[84,775]],7787:[[116,775]],7788:[[84,803]],7789:[[116,803]],7790:[[84,817]],7791:[[116,817]],7792:[[84,813]],7793:[[116,813]],7794:[[85,804]],7795:[[117,804]],7796:[[85,816]],7797:[[117,816]],7798:[[85,813]],7799:[[117,813]],7800:[[360,769]],7801:[[361,769]],7802:[[362,776]],7803:[[363,776]],7804:[[86,771]],7805:[[118,771]],7806:[[86,803]],7807:[[118,803]],7808:[[87,768]],7809:[[119,768]],7810:[[87,769]],7811:[[119,769]],7812:[[87,776]],7813:[[119,776]],7814:[[87,775]],7815:[[119,775]],7816:[[87,803]],7817:[[119,803]],7818:[[88,775]],7819:[[120,775]],7820:[[88,776]],7821:[[120,776]],7822:[[89,775]],7823:[[121,775]],7824:[[90,770]],7825:[[122,770]],7826:[[90,803]],7827:[[122,803]],7828:[[90,817]],7829:[[122,817]],7830:[[104,817]],7831:[[116,776]],7832:[[119,778]],7833:[[121,778]],7834:[[97,702],256],7835:[[383,775]],7840:[[65,803],,{770:7852,774:7862}],7841:[[97,803],,{770:7853,774:7863}],7842:[[65,777]],7843:[[97,777]],7844:[[194,769]],7845:[[226,769]],7846:[[194,768]],7847:[[226,768]],7848:[[194,777]],7849:[[226,777]],7850:[[194,771]],7851:[[226,771]],7852:[[7840,770]],7853:[[7841,770]],7854:[[258,769]],7855:[[259,769]],7856:[[258,768]],7857:[[259,768]],7858:[[258,777]],7859:[[259,777]],7860:[[258,771]],7861:[[259,771]],7862:[[7840,774]],7863:[[7841,774]],7864:[[69,803],,{770:7878}],7865:[[101,803],,{770:7879}],7866:[[69,777]],7867:[[101,777]],7868:[[69,771]],7869:[[101,771]],7870:[[202,769]],7871:[[234,769]],7872:[[202,768]],7873:[[234,768]],7874:[[202,777]],7875:[[234,777]],7876:[[202,771]],7877:[[234,771]],7878:[[7864,770]],7879:[[7865,770]],7880:[[73,777]],7881:[[105,777]],7882:[[73,803]],7883:[[105,803]],7884:[[79,803],,{770:7896}],7885:[[111,803],,{770:7897}],7886:[[79,777]],7887:[[111,777]],7888:[[212,769]],7889:[[244,769]],7890:[[212,768]],7891:[[244,768]],7892:[[212,777]],7893:[[244,777]],7894:[[212,771]],7895:[[244,771]],7896:[[7884,770]],7897:[[7885,770]],7898:[[416,769]],7899:[[417,769]],7900:[[416,768]],7901:[[417,768]],7902:[[416,777]],7903:[[417,777]],7904:[[416,771]],7905:[[417,771]],7906:[[416,803]],7907:[[417,803]],7908:[[85,803]],7909:[[117,803]],7910:[[85,777]],7911:[[117,777]],7912:[[431,769]],7913:[[432,769]],7914:[[431,768]],7915:[[432,768]],7916:[[431,777]],7917:[[432,777]],7918:[[431,771]],7919:[[432,771]],7920:[[431,803]],7921:[[432,803]],7922:[[89,768]],7923:[[121,768]],7924:[[89,803]],7925:[[121,803]],7926:[[89,777]],7927:[[121,777]],7928:[[89,771]],7929:[[121,771]]},
    7936:{7936:[[945,787],,{768:7938,769:7940,834:7942,837:8064}],7937:[[945,788],,{768:7939,769:7941,834:7943,837:8065}],7938:[[7936,768],,{837:8066}],7939:[[7937,768],,{837:8067}],7940:[[7936,769],,{837:8068}],7941:[[7937,769],,{837:8069}],7942:[[7936,834],,{837:8070}],7943:[[7937,834],,{837:8071}],7944:[[913,787],,{768:7946,769:7948,834:7950,837:8072}],7945:[[913,788],,{768:7947,769:7949,834:7951,837:8073}],7946:[[7944,768],,{837:8074}],7947:[[7945,768],,{837:8075}],7948:[[7944,769],,{837:8076}],7949:[[7945,769],,{837:8077}],7950:[[7944,834],,{837:8078}],7951:[[7945,834],,{837:8079}],7952:[[949,787],,{768:7954,769:7956}],7953:[[949,788],,{768:7955,769:7957}],7954:[[7952,768]],7955:[[7953,768]],7956:[[7952,769]],7957:[[7953,769]],7960:[[917,787],,{768:7962,769:7964}],7961:[[917,788],,{768:7963,769:7965}],7962:[[7960,768]],7963:[[7961,768]],7964:[[7960,769]],7965:[[7961,769]],7968:[[951,787],,{768:7970,769:7972,834:7974,837:8080}],7969:[[951,788],,{768:7971,769:7973,834:7975,837:8081}],7970:[[7968,768],,{837:8082}],7971:[[7969,768],,{837:8083}],7972:[[7968,769],,{837:8084}],7973:[[7969,769],,{837:8085}],7974:[[7968,834],,{837:8086}],7975:[[7969,834],,{837:8087}],7976:[[919,787],,{768:7978,769:7980,834:7982,837:8088}],7977:[[919,788],,{768:7979,769:7981,834:7983,837:8089}],7978:[[7976,768],,{837:8090}],7979:[[7977,768],,{837:8091}],7980:[[7976,769],,{837:8092}],7981:[[7977,769],,{837:8093}],7982:[[7976,834],,{837:8094}],7983:[[7977,834],,{837:8095}],7984:[[953,787],,{768:7986,769:7988,834:7990}],7985:[[953,788],,{768:7987,769:7989,834:7991}],7986:[[7984,768]],7987:[[7985,768]],7988:[[7984,769]],7989:[[7985,769]],7990:[[7984,834]],7991:[[7985,834]],7992:[[921,787],,{768:7994,769:7996,834:7998}],7993:[[921,788],,{768:7995,769:7997,834:7999}],7994:[[7992,768]],7995:[[7993,768]],7996:[[7992,769]],7997:[[7993,769]],7998:[[7992,834]],7999:[[7993,834]],8000:[[959,787],,{768:8002,769:8004}],8001:[[959,788],,{768:8003,769:8005}],8002:[[8000,768]],8003:[[8001,768]],8004:[[8000,769]],8005:[[8001,769]],8008:[[927,787],,{768:8010,769:8012}],8009:[[927,788],,{768:8011,769:8013}],8010:[[8008,768]],8011:[[8009,768]],8012:[[8008,769]],8013:[[8009,769]],8016:[[965,787],,{768:8018,769:8020,834:8022}],8017:[[965,788],,{768:8019,769:8021,834:8023}],8018:[[8016,768]],8019:[[8017,768]],8020:[[8016,769]],8021:[[8017,769]],8022:[[8016,834]],8023:[[8017,834]],8025:[[933,788],,{768:8027,769:8029,834:8031}],8027:[[8025,768]],8029:[[8025,769]],8031:[[8025,834]],8032:[[969,787],,{768:8034,769:8036,834:8038,837:8096}],8033:[[969,788],,{768:8035,769:8037,834:8039,837:8097}],8034:[[8032,768],,{837:8098}],8035:[[8033,768],,{837:8099}],8036:[[8032,769],,{837:8100}],8037:[[8033,769],,{837:8101}],8038:[[8032,834],,{837:8102}],8039:[[8033,834],,{837:8103}],8040:[[937,787],,{768:8042,769:8044,834:8046,837:8104}],8041:[[937,788],,{768:8043,769:8045,834:8047,837:8105}],8042:[[8040,768],,{837:8106}],8043:[[8041,768],,{837:8107}],8044:[[8040,769],,{837:8108}],8045:[[8041,769],,{837:8109}],8046:[[8040,834],,{837:8110}],8047:[[8041,834],,{837:8111}],8048:[[945,768],,{837:8114}],8049:[[940]],8050:[[949,768]],8051:[[941]],8052:[[951,768],,{837:8130}],8053:[[942]],8054:[[953,768]],8055:[[943]],8056:[[959,768]],8057:[[972]],8058:[[965,768]],8059:[[973]],8060:[[969,768],,{837:8178}],8061:[[974]],8064:[[7936,837]],8065:[[7937,837]],8066:[[7938,837]],8067:[[7939,837]],8068:[[7940,837]],8069:[[7941,837]],8070:[[7942,837]],8071:[[7943,837]],8072:[[7944,837]],8073:[[7945,837]],8074:[[7946,837]],8075:[[7947,837]],8076:[[7948,837]],8077:[[7949,837]],8078:[[7950,837]],8079:[[7951,837]],8080:[[7968,837]],8081:[[7969,837]],8082:[[7970,837]],8083:[[7971,837]],8084:[[7972,837]],8085:[[7973,837]],8086:[[7974,837]],8087:[[7975,837]],8088:[[7976,837]],8089:[[7977,837]],8090:[[7978,837]],8091:[[7979,837]],8092:[[7980,837]],8093:[[7981,837]],8094:[[7982,837]],8095:[[7983,837]],8096:[[8032,837]],8097:[[8033,837]],8098:[[8034,837]],8099:[[8035,837]],8100:[[8036,837]],8101:[[8037,837]],8102:[[8038,837]],8103:[[8039,837]],8104:[[8040,837]],8105:[[8041,837]],8106:[[8042,837]],8107:[[8043,837]],8108:[[8044,837]],8109:[[8045,837]],8110:[[8046,837]],8111:[[8047,837]],8112:[[945,774]],8113:[[945,772]],8114:[[8048,837]],8115:[[945,837]],8116:[[940,837]],8118:[[945,834],,{837:8119}],8119:[[8118,837]],8120:[[913,774]],8121:[[913,772]],8122:[[913,768]],8123:[[902]],8124:[[913,837]],8125:[[32,787],256],8126:[[953]],8127:[[32,787],256,{768:8141,769:8142,834:8143}],8128:[[32,834],256],8129:[[168,834]],8130:[[8052,837]],8131:[[951,837]],8132:[[942,837]],8134:[[951,834],,{837:8135}],8135:[[8134,837]],8136:[[917,768]],8137:[[904]],8138:[[919,768]],8139:[[905]],8140:[[919,837]],8141:[[8127,768]],8142:[[8127,769]],8143:[[8127,834]],8144:[[953,774]],8145:[[953,772]],8146:[[970,768]],8147:[[912]],8150:[[953,834]],8151:[[970,834]],8152:[[921,774]],8153:[[921,772]],8154:[[921,768]],8155:[[906]],8157:[[8190,768]],8158:[[8190,769]],8159:[[8190,834]],8160:[[965,774]],8161:[[965,772]],8162:[[971,768]],8163:[[944]],8164:[[961,787]],8165:[[961,788]],8166:[[965,834]],8167:[[971,834]],8168:[[933,774]],8169:[[933,772]],8170:[[933,768]],8171:[[910]],8172:[[929,788]],8173:[[168,768]],8174:[[901]],8175:[[96]],8178:[[8060,837]],8179:[[969,837]],8180:[[974,837]],8182:[[969,834],,{837:8183}],8183:[[8182,837]],8184:[[927,768]],8185:[[908]],8186:[[937,768]],8187:[[911]],8188:[[937,837]],8189:[[180]],8190:[[32,788],256,{768:8157,769:8158,834:8159}]},
    8192:{8192:[[8194]],8193:[[8195]],8194:[[32],256],8195:[[32],256],8196:[[32],256],8197:[[32],256],8198:[[32],256],8199:[[32],256],8200:[[32],256],8201:[[32],256],8202:[[32],256],8209:[[8208],256],8215:[[32,819],256],8228:[[46],256],8229:[[46,46],256],8230:[[46,46,46],256],8239:[[32],256],8243:[[8242,8242],256],8244:[[8242,8242,8242],256],8246:[[8245,8245],256],8247:[[8245,8245,8245],256],8252:[[33,33],256],8254:[[32,773],256],8263:[[63,63],256],8264:[[63,33],256],8265:[[33,63],256],8279:[[8242,8242,8242,8242],256],8287:[[32],256],8304:[[48],256],8305:[[105],256],8308:[[52],256],8309:[[53],256],8310:[[54],256],8311:[[55],256],8312:[[56],256],8313:[[57],256],8314:[[43],256],8315:[[8722],256],8316:[[61],256],8317:[[40],256],8318:[[41],256],8319:[[110],256],8320:[[48],256],8321:[[49],256],8322:[[50],256],8323:[[51],256],8324:[[52],256],8325:[[53],256],8326:[[54],256],8327:[[55],256],8328:[[56],256],8329:[[57],256],8330:[[43],256],8331:[[8722],256],8332:[[61],256],8333:[[40],256],8334:[[41],256],8336:[[97],256],8337:[[101],256],8338:[[111],256],8339:[[120],256],8340:[[601],256],8341:[[104],256],8342:[[107],256],8343:[[108],256],8344:[[109],256],8345:[[110],256],8346:[[112],256],8347:[[115],256],8348:[[116],256],8360:[[82,115],256],8400:[,230],8401:[,230],8402:[,1],8403:[,1],8404:[,230],8405:[,230],8406:[,230],8407:[,230],8408:[,1],8409:[,1],8410:[,1],8411:[,230],8412:[,230],8417:[,230],8421:[,1],8422:[,1],8423:[,230],8424:[,220],8425:[,230],8426:[,1],8427:[,1],8428:[,220],8429:[,220],8430:[,220],8431:[,220],8432:[,230]},
    8448:{8448:[[97,47,99],256],8449:[[97,47,115],256],8450:[[67],256],8451:[[176,67],256],8453:[[99,47,111],256],8454:[[99,47,117],256],8455:[[400],256],8457:[[176,70],256],8458:[[103],256],8459:[[72],256],8460:[[72],256],8461:[[72],256],8462:[[104],256],8463:[[295],256],8464:[[73],256],8465:[[73],256],8466:[[76],256],8467:[[108],256],8469:[[78],256],8470:[[78,111],256],8473:[[80],256],8474:[[81],256],8475:[[82],256],8476:[[82],256],8477:[[82],256],8480:[[83,77],256],8481:[[84,69,76],256],8482:[[84,77],256],8484:[[90],256],8486:[[937]],8488:[[90],256],8490:[[75]],8491:[[197]],8492:[[66],256],8493:[[67],256],8495:[[101],256],8496:[[69],256],8497:[[70],256],8499:[[77],256],8500:[[111],256],8501:[[1488],256],8502:[[1489],256],8503:[[1490],256],8504:[[1491],256],8505:[[105],256],8507:[[70,65,88],256],8508:[[960],256],8509:[[947],256],8510:[[915],256],8511:[[928],256],8512:[[8721],256],8517:[[68],256],8518:[[100],256],8519:[[101],256],8520:[[105],256],8521:[[106],256],8528:[[49,8260,55],256],8529:[[49,8260,57],256],8530:[[49,8260,49,48],256],8531:[[49,8260,51],256],8532:[[50,8260,51],256],8533:[[49,8260,53],256],8534:[[50,8260,53],256],8535:[[51,8260,53],256],8536:[[52,8260,53],256],8537:[[49,8260,54],256],8538:[[53,8260,54],256],8539:[[49,8260,56],256],8540:[[51,8260,56],256],8541:[[53,8260,56],256],8542:[[55,8260,56],256],8543:[[49,8260],256],8544:[[73],256],8545:[[73,73],256],8546:[[73,73,73],256],8547:[[73,86],256],8548:[[86],256],8549:[[86,73],256],8550:[[86,73,73],256],8551:[[86,73,73,73],256],8552:[[73,88],256],8553:[[88],256],8554:[[88,73],256],8555:[[88,73,73],256],8556:[[76],256],8557:[[67],256],8558:[[68],256],8559:[[77],256],8560:[[105],256],8561:[[105,105],256],8562:[[105,105,105],256],8563:[[105,118],256],8564:[[118],256],8565:[[118,105],256],8566:[[118,105,105],256],8567:[[118,105,105,105],256],8568:[[105,120],256],8569:[[120],256],8570:[[120,105],256],8571:[[120,105,105],256],8572:[[108],256],8573:[[99],256],8574:[[100],256],8575:[[109],256],8585:[[48,8260,51],256],8592:[,,{824:8602}],8594:[,,{824:8603}],8596:[,,{824:8622}],8602:[[8592,824]],8603:[[8594,824]],8622:[[8596,824]],8653:[[8656,824]],8654:[[8660,824]],8655:[[8658,824]],8656:[,,{824:8653}],8658:[,,{824:8655}],8660:[,,{824:8654}]},
    8704:{8707:[,,{824:8708}],8708:[[8707,824]],8712:[,,{824:8713}],8713:[[8712,824]],8715:[,,{824:8716}],8716:[[8715,824]],8739:[,,{824:8740}],8740:[[8739,824]],8741:[,,{824:8742}],8742:[[8741,824]],8748:[[8747,8747],256],8749:[[8747,8747,8747],256],8751:[[8750,8750],256],8752:[[8750,8750,8750],256],8764:[,,{824:8769}],8769:[[8764,824]],8771:[,,{824:8772}],8772:[[8771,824]],8773:[,,{824:8775}],8775:[[8773,824]],8776:[,,{824:8777}],8777:[[8776,824]],8781:[,,{824:8813}],8800:[[61,824]],8801:[,,{824:8802}],8802:[[8801,824]],8804:[,,{824:8816}],8805:[,,{824:8817}],8813:[[8781,824]],8814:[[60,824]],8815:[[62,824]],8816:[[8804,824]],8817:[[8805,824]],8818:[,,{824:8820}],8819:[,,{824:8821}],8820:[[8818,824]],8821:[[8819,824]],8822:[,,{824:8824}],8823:[,,{824:8825}],8824:[[8822,824]],8825:[[8823,824]],8826:[,,{824:8832}],8827:[,,{824:8833}],8828:[,,{824:8928}],8829:[,,{824:8929}],8832:[[8826,824]],8833:[[8827,824]],8834:[,,{824:8836}],8835:[,,{824:8837}],8836:[[8834,824]],8837:[[8835,824]],8838:[,,{824:8840}],8839:[,,{824:8841}],8840:[[8838,824]],8841:[[8839,824]],8849:[,,{824:8930}],8850:[,,{824:8931}],8866:[,,{824:8876}],8872:[,,{824:8877}],8873:[,,{824:8878}],8875:[,,{824:8879}],8876:[[8866,824]],8877:[[8872,824]],8878:[[8873,824]],8879:[[8875,824]],8882:[,,{824:8938}],8883:[,,{824:8939}],8884:[,,{824:8940}],8885:[,,{824:8941}],8928:[[8828,824]],8929:[[8829,824]],8930:[[8849,824]],8931:[[8850,824]],8938:[[8882,824]],8939:[[8883,824]],8940:[[8884,824]],8941:[[8885,824]]},
    8960:{9001:[[12296]],9002:[[12297]]},
    9216:{9312:[[49],256],9313:[[50],256],9314:[[51],256],9315:[[52],256],9316:[[53],256],9317:[[54],256],9318:[[55],256],9319:[[56],256],9320:[[57],256],9321:[[49,48],256],9322:[[49,49],256],9323:[[49,50],256],9324:[[49,51],256],9325:[[49,52],256],9326:[[49,53],256],9327:[[49,54],256],9328:[[49,55],256],9329:[[49,56],256],9330:[[49,57],256],9331:[[50,48],256],9332:[[40,49,41],256],9333:[[40,50,41],256],9334:[[40,51,41],256],9335:[[40,52,41],256],9336:[[40,53,41],256],9337:[[40,54,41],256],9338:[[40,55,41],256],9339:[[40,56,41],256],9340:[[40,57,41],256],9341:[[40,49,48,41],256],9342:[[40,49,49,41],256],9343:[[40,49,50,41],256],9344:[[40,49,51,41],256],9345:[[40,49,52,41],256],9346:[[40,49,53,41],256],9347:[[40,49,54,41],256],9348:[[40,49,55,41],256],9349:[[40,49,56,41],256],9350:[[40,49,57,41],256],9351:[[40,50,48,41],256],9352:[[49,46],256],9353:[[50,46],256],9354:[[51,46],256],9355:[[52,46],256],9356:[[53,46],256],9357:[[54,46],256],9358:[[55,46],256],9359:[[56,46],256],9360:[[57,46],256],9361:[[49,48,46],256],9362:[[49,49,46],256],9363:[[49,50,46],256],9364:[[49,51,46],256],9365:[[49,52,46],256],9366:[[49,53,46],256],9367:[[49,54,46],256],9368:[[49,55,46],256],9369:[[49,56,46],256],9370:[[49,57,46],256],9371:[[50,48,46],256],9372:[[40,97,41],256],9373:[[40,98,41],256],9374:[[40,99,41],256],9375:[[40,100,41],256],9376:[[40,101,41],256],9377:[[40,102,41],256],9378:[[40,103,41],256],9379:[[40,104,41],256],9380:[[40,105,41],256],9381:[[40,106,41],256],9382:[[40,107,41],256],9383:[[40,108,41],256],9384:[[40,109,41],256],9385:[[40,110,41],256],9386:[[40,111,41],256],9387:[[40,112,41],256],9388:[[40,113,41],256],9389:[[40,114,41],256],9390:[[40,115,41],256],9391:[[40,116,41],256],9392:[[40,117,41],256],9393:[[40,118,41],256],9394:[[40,119,41],256],9395:[[40,120,41],256],9396:[[40,121,41],256],9397:[[40,122,41],256],9398:[[65],256],9399:[[66],256],9400:[[67],256],9401:[[68],256],9402:[[69],256],9403:[[70],256],9404:[[71],256],9405:[[72],256],9406:[[73],256],9407:[[74],256],9408:[[75],256],9409:[[76],256],9410:[[77],256],9411:[[78],256],9412:[[79],256],9413:[[80],256],9414:[[81],256],9415:[[82],256],9416:[[83],256],9417:[[84],256],9418:[[85],256],9419:[[86],256],9420:[[87],256],9421:[[88],256],9422:[[89],256],9423:[[90],256],9424:[[97],256],9425:[[98],256],9426:[[99],256],9427:[[100],256],9428:[[101],256],9429:[[102],256],9430:[[103],256],9431:[[104],256],9432:[[105],256],9433:[[106],256],9434:[[107],256],9435:[[108],256],9436:[[109],256],9437:[[110],256],9438:[[111],256],9439:[[112],256],9440:[[113],256],9441:[[114],256],9442:[[115],256],9443:[[116],256],9444:[[117],256],9445:[[118],256],9446:[[119],256],9447:[[120],256],9448:[[121],256],9449:[[122],256],9450:[[48],256]},
    10752:{10764:[[8747,8747,8747,8747],256],10868:[[58,58,61],256],10869:[[61,61],256],10870:[[61,61,61],256],10972:[[10973,824],512]},
    11264:{11388:[[106],256],11389:[[86],256],11503:[,230],11504:[,230],11505:[,230]},
    11520:{11631:[[11617],256],11647:[,9],11744:[,230],11745:[,230],11746:[,230],11747:[,230],11748:[,230],11749:[,230],11750:[,230],11751:[,230],11752:[,230],11753:[,230],11754:[,230],11755:[,230],11756:[,230],11757:[,230],11758:[,230],11759:[,230],11760:[,230],11761:[,230],11762:[,230],11763:[,230],11764:[,230],11765:[,230],11766:[,230],11767:[,230],11768:[,230],11769:[,230],11770:[,230],11771:[,230],11772:[,230],11773:[,230],11774:[,230],11775:[,230]},
    11776:{11935:[[27597],256],12019:[[40863],256]},
    12032:{12032:[[19968],256],12033:[[20008],256],12034:[[20022],256],12035:[[20031],256],12036:[[20057],256],12037:[[20101],256],12038:[[20108],256],12039:[[20128],256],12040:[[20154],256],12041:[[20799],256],12042:[[20837],256],12043:[[20843],256],12044:[[20866],256],12045:[[20886],256],12046:[[20907],256],12047:[[20960],256],12048:[[20981],256],12049:[[20992],256],12050:[[21147],256],12051:[[21241],256],12052:[[21269],256],12053:[[21274],256],12054:[[21304],256],12055:[[21313],256],12056:[[21340],256],12057:[[21353],256],12058:[[21378],256],12059:[[21430],256],12060:[[21448],256],12061:[[21475],256],12062:[[22231],256],12063:[[22303],256],12064:[[22763],256],12065:[[22786],256],12066:[[22794],256],12067:[[22805],256],12068:[[22823],256],12069:[[22899],256],12070:[[23376],256],12071:[[23424],256],12072:[[23544],256],12073:[[23567],256],12074:[[23586],256],12075:[[23608],256],12076:[[23662],256],12077:[[23665],256],12078:[[24027],256],12079:[[24037],256],12080:[[24049],256],12081:[[24062],256],12082:[[24178],256],12083:[[24186],256],12084:[[24191],256],12085:[[24308],256],12086:[[24318],256],12087:[[24331],256],12088:[[24339],256],12089:[[24400],256],12090:[[24417],256],12091:[[24435],256],12092:[[24515],256],12093:[[25096],256],12094:[[25142],256],12095:[[25163],256],12096:[[25903],256],12097:[[25908],256],12098:[[25991],256],12099:[[26007],256],12100:[[26020],256],12101:[[26041],256],12102:[[26080],256],12103:[[26085],256],12104:[[26352],256],12105:[[26376],256],12106:[[26408],256],12107:[[27424],256],12108:[[27490],256],12109:[[27513],256],12110:[[27571],256],12111:[[27595],256],12112:[[27604],256],12113:[[27611],256],12114:[[27663],256],12115:[[27668],256],12116:[[27700],256],12117:[[28779],256],12118:[[29226],256],12119:[[29238],256],12120:[[29243],256],12121:[[29247],256],12122:[[29255],256],12123:[[29273],256],12124:[[29275],256],12125:[[29356],256],12126:[[29572],256],12127:[[29577],256],12128:[[29916],256],12129:[[29926],256],12130:[[29976],256],12131:[[29983],256],12132:[[29992],256],12133:[[30000],256],12134:[[30091],256],12135:[[30098],256],12136:[[30326],256],12137:[[30333],256],12138:[[30382],256],12139:[[30399],256],12140:[[30446],256],12141:[[30683],256],12142:[[30690],256],12143:[[30707],256],12144:[[31034],256],12145:[[31160],256],12146:[[31166],256],12147:[[31348],256],12148:[[31435],256],12149:[[31481],256],12150:[[31859],256],12151:[[31992],256],12152:[[32566],256],12153:[[32593],256],12154:[[32650],256],12155:[[32701],256],12156:[[32769],256],12157:[[32780],256],12158:[[32786],256],12159:[[32819],256],12160:[[32895],256],12161:[[32905],256],12162:[[33251],256],12163:[[33258],256],12164:[[33267],256],12165:[[33276],256],12166:[[33292],256],12167:[[33307],256],12168:[[33311],256],12169:[[33390],256],12170:[[33394],256],12171:[[33400],256],12172:[[34381],256],12173:[[34411],256],12174:[[34880],256],12175:[[34892],256],12176:[[34915],256],12177:[[35198],256],12178:[[35211],256],12179:[[35282],256],12180:[[35328],256],12181:[[35895],256],12182:[[35910],256],12183:[[35925],256],12184:[[35960],256],12185:[[35997],256],12186:[[36196],256],12187:[[36208],256],12188:[[36275],256],12189:[[36523],256],12190:[[36554],256],12191:[[36763],256],12192:[[36784],256],12193:[[36789],256],12194:[[37009],256],12195:[[37193],256],12196:[[37318],256],12197:[[37324],256],12198:[[37329],256],12199:[[38263],256],12200:[[38272],256],12201:[[38428],256],12202:[[38582],256],12203:[[38585],256],12204:[[38632],256],12205:[[38737],256],12206:[[38750],256],12207:[[38754],256],12208:[[38761],256],12209:[[38859],256],12210:[[38893],256],12211:[[38899],256],12212:[[38913],256],12213:[[39080],256],12214:[[39131],256],12215:[[39135],256],12216:[[39318],256],12217:[[39321],256],12218:[[39340],256],12219:[[39592],256],12220:[[39640],256],12221:[[39647],256],12222:[[39717],256],12223:[[39727],256],12224:[[39730],256],12225:[[39740],256],12226:[[39770],256],12227:[[40165],256],12228:[[40565],256],12229:[[40575],256],12230:[[40613],256],12231:[[40635],256],12232:[[40643],256],12233:[[40653],256],12234:[[40657],256],12235:[[40697],256],12236:[[40701],256],12237:[[40718],256],12238:[[40723],256],12239:[[40736],256],12240:[[40763],256],12241:[[40778],256],12242:[[40786],256],12243:[[40845],256],12244:[[40860],256],12245:[[40864],256]},
    12288:{12288:[[32],256],12330:[,218],12331:[,228],12332:[,232],12333:[,222],12334:[,224],12335:[,224],12342:[[12306],256],12344:[[21313],256],12345:[[21316],256],12346:[[21317],256],12358:[,,{12441:12436}],12363:[,,{12441:12364}],12364:[[12363,12441]],12365:[,,{12441:12366}],12366:[[12365,12441]],12367:[,,{12441:12368}],12368:[[12367,12441]],12369:[,,{12441:12370}],12370:[[12369,12441]],12371:[,,{12441:12372}],12372:[[12371,12441]],12373:[,,{12441:12374}],12374:[[12373,12441]],12375:[,,{12441:12376}],12376:[[12375,12441]],12377:[,,{12441:12378}],12378:[[12377,12441]],12379:[,,{12441:12380}],12380:[[12379,12441]],12381:[,,{12441:12382}],12382:[[12381,12441]],12383:[,,{12441:12384}],12384:[[12383,12441]],12385:[,,{12441:12386}],12386:[[12385,12441]],12388:[,,{12441:12389}],12389:[[12388,12441]],12390:[,,{12441:12391}],12391:[[12390,12441]],12392:[,,{12441:12393}],12393:[[12392,12441]],12399:[,,{12441:12400,12442:12401}],12400:[[12399,12441]],12401:[[12399,12442]],12402:[,,{12441:12403,12442:12404}],12403:[[12402,12441]],12404:[[12402,12442]],12405:[,,{12441:12406,12442:12407}],12406:[[12405,12441]],12407:[[12405,12442]],12408:[,,{12441:12409,12442:12410}],12409:[[12408,12441]],12410:[[12408,12442]],12411:[,,{12441:12412,12442:12413}],12412:[[12411,12441]],12413:[[12411,12442]],12436:[[12358,12441]],12441:[,8],12442:[,8],12443:[[32,12441],256],12444:[[32,12442],256],12445:[,,{12441:12446}],12446:[[12445,12441]],12447:[[12424,12426],256],12454:[,,{12441:12532}],12459:[,,{12441:12460}],12460:[[12459,12441]],12461:[,,{12441:12462}],12462:[[12461,12441]],12463:[,,{12441:12464}],12464:[[12463,12441]],12465:[,,{12441:12466}],12466:[[12465,12441]],12467:[,,{12441:12468}],12468:[[12467,12441]],12469:[,,{12441:12470}],12470:[[12469,12441]],12471:[,,{12441:12472}],12472:[[12471,12441]],12473:[,,{12441:12474}],12474:[[12473,12441]],12475:[,,{12441:12476}],12476:[[12475,12441]],12477:[,,{12441:12478}],12478:[[12477,12441]],12479:[,,{12441:12480}],12480:[[12479,12441]],12481:[,,{12441:12482}],12482:[[12481,12441]],12484:[,,{12441:12485}],12485:[[12484,12441]],12486:[,,{12441:12487}],12487:[[12486,12441]],12488:[,,{12441:12489}],12489:[[12488,12441]],12495:[,,{12441:12496,12442:12497}],12496:[[12495,12441]],12497:[[12495,12442]],12498:[,,{12441:12499,12442:12500}],12499:[[12498,12441]],12500:[[12498,12442]],12501:[,,{12441:12502,12442:12503}],12502:[[12501,12441]],12503:[[12501,12442]],12504:[,,{12441:12505,12442:12506}],12505:[[12504,12441]],12506:[[12504,12442]],12507:[,,{12441:12508,12442:12509}],12508:[[12507,12441]],12509:[[12507,12442]],12527:[,,{12441:12535}],12528:[,,{12441:12536}],12529:[,,{12441:12537}],12530:[,,{12441:12538}],12532:[[12454,12441]],12535:[[12527,12441]],12536:[[12528,12441]],12537:[[12529,12441]],12538:[[12530,12441]],12541:[,,{12441:12542}],12542:[[12541,12441]],12543:[[12467,12488],256]},
    12544:{12593:[[4352],256],12594:[[4353],256],12595:[[4522],256],12596:[[4354],256],12597:[[4524],256],12598:[[4525],256],12599:[[4355],256],12600:[[4356],256],12601:[[4357],256],12602:[[4528],256],12603:[[4529],256],12604:[[4530],256],12605:[[4531],256],12606:[[4532],256],12607:[[4533],256],12608:[[4378],256],12609:[[4358],256],12610:[[4359],256],12611:[[4360],256],12612:[[4385],256],12613:[[4361],256],12614:[[4362],256],12615:[[4363],256],12616:[[4364],256],12617:[[4365],256],12618:[[4366],256],12619:[[4367],256],12620:[[4368],256],12621:[[4369],256],12622:[[4370],256],12623:[[4449],256],12624:[[4450],256],12625:[[4451],256],12626:[[4452],256],12627:[[4453],256],12628:[[4454],256],12629:[[4455],256],12630:[[4456],256],12631:[[4457],256],12632:[[4458],256],12633:[[4459],256],12634:[[4460],256],12635:[[4461],256],12636:[[4462],256],12637:[[4463],256],12638:[[4464],256],12639:[[4465],256],12640:[[4466],256],12641:[[4467],256],12642:[[4468],256],12643:[[4469],256],12644:[[4448],256],12645:[[4372],256],12646:[[4373],256],12647:[[4551],256],12648:[[4552],256],12649:[[4556],256],12650:[[4558],256],12651:[[4563],256],12652:[[4567],256],12653:[[4569],256],12654:[[4380],256],12655:[[4573],256],12656:[[4575],256],12657:[[4381],256],12658:[[4382],256],12659:[[4384],256],12660:[[4386],256],12661:[[4387],256],12662:[[4391],256],12663:[[4393],256],12664:[[4395],256],12665:[[4396],256],12666:[[4397],256],12667:[[4398],256],12668:[[4399],256],12669:[[4402],256],12670:[[4406],256],12671:[[4416],256],12672:[[4423],256],12673:[[4428],256],12674:[[4593],256],12675:[[4594],256],12676:[[4439],256],12677:[[4440],256],12678:[[4441],256],12679:[[4484],256],12680:[[4485],256],12681:[[4488],256],12682:[[4497],256],12683:[[4498],256],12684:[[4500],256],12685:[[4510],256],12686:[[4513],256],12690:[[19968],256],12691:[[20108],256],12692:[[19977],256],12693:[[22235],256],12694:[[19978],256],12695:[[20013],256],12696:[[19979],256],12697:[[30002],256],12698:[[20057],256],12699:[[19993],256],12700:[[19969],256],12701:[[22825],256],12702:[[22320],256],12703:[[20154],256]},
    12800:{12800:[[40,4352,41],256],12801:[[40,4354,41],256],12802:[[40,4355,41],256],12803:[[40,4357,41],256],12804:[[40,4358,41],256],12805:[[40,4359,41],256],12806:[[40,4361,41],256],12807:[[40,4363,41],256],12808:[[40,4364,41],256],12809:[[40,4366,41],256],12810:[[40,4367,41],256],12811:[[40,4368,41],256],12812:[[40,4369,41],256],12813:[[40,4370,41],256],12814:[[40,4352,4449,41],256],12815:[[40,4354,4449,41],256],12816:[[40,4355,4449,41],256],12817:[[40,4357,4449,41],256],12818:[[40,4358,4449,41],256],12819:[[40,4359,4449,41],256],12820:[[40,4361,4449,41],256],12821:[[40,4363,4449,41],256],12822:[[40,4364,4449,41],256],12823:[[40,4366,4449,41],256],12824:[[40,4367,4449,41],256],12825:[[40,4368,4449,41],256],12826:[[40,4369,4449,41],256],12827:[[40,4370,4449,41],256],12828:[[40,4364,4462,41],256],12829:[[40,4363,4457,4364,4453,4523,41],256],12830:[[40,4363,4457,4370,4462,41],256],12832:[[40,19968,41],256],12833:[[40,20108,41],256],12834:[[40,19977,41],256],12835:[[40,22235,41],256],12836:[[40,20116,41],256],12837:[[40,20845,41],256],12838:[[40,19971,41],256],12839:[[40,20843,41],256],12840:[[40,20061,41],256],12841:[[40,21313,41],256],12842:[[40,26376,41],256],12843:[[40,28779,41],256],12844:[[40,27700,41],256],12845:[[40,26408,41],256],12846:[[40,37329,41],256],12847:[[40,22303,41],256],12848:[[40,26085,41],256],12849:[[40,26666,41],256],12850:[[40,26377,41],256],12851:[[40,31038,41],256],12852:[[40,21517,41],256],12853:[[40,29305,41],256],12854:[[40,36001,41],256],12855:[[40,31069,41],256],12856:[[40,21172,41],256],12857:[[40,20195,41],256],12858:[[40,21628,41],256],12859:[[40,23398,41],256],12860:[[40,30435,41],256],12861:[[40,20225,41],256],12862:[[40,36039,41],256],12863:[[40,21332,41],256],12864:[[40,31085,41],256],12865:[[40,20241,41],256],12866:[[40,33258,41],256],12867:[[40,33267,41],256],12868:[[21839],256],12869:[[24188],256],12870:[[25991],256],12871:[[31631],256],12880:[[80,84,69],256],12881:[[50,49],256],12882:[[50,50],256],12883:[[50,51],256],12884:[[50,52],256],12885:[[50,53],256],12886:[[50,54],256],12887:[[50,55],256],12888:[[50,56],256],12889:[[50,57],256],12890:[[51,48],256],12891:[[51,49],256],12892:[[51,50],256],12893:[[51,51],256],12894:[[51,52],256],12895:[[51,53],256],12896:[[4352],256],12897:[[4354],256],12898:[[4355],256],12899:[[4357],256],12900:[[4358],256],12901:[[4359],256],12902:[[4361],256],12903:[[4363],256],12904:[[4364],256],12905:[[4366],256],12906:[[4367],256],12907:[[4368],256],12908:[[4369],256],12909:[[4370],256],12910:[[4352,4449],256],12911:[[4354,4449],256],12912:[[4355,4449],256],12913:[[4357,4449],256],12914:[[4358,4449],256],12915:[[4359,4449],256],12916:[[4361,4449],256],12917:[[4363,4449],256],12918:[[4364,4449],256],12919:[[4366,4449],256],12920:[[4367,4449],256],12921:[[4368,4449],256],12922:[[4369,4449],256],12923:[[4370,4449],256],12924:[[4366,4449,4535,4352,4457],256],12925:[[4364,4462,4363,4468],256],12926:[[4363,4462],256],12928:[[19968],256],12929:[[20108],256],12930:[[19977],256],12931:[[22235],256],12932:[[20116],256],12933:[[20845],256],12934:[[19971],256],12935:[[20843],256],12936:[[20061],256],12937:[[21313],256],12938:[[26376],256],12939:[[28779],256],12940:[[27700],256],12941:[[26408],256],12942:[[37329],256],12943:[[22303],256],12944:[[26085],256],12945:[[26666],256],12946:[[26377],256],12947:[[31038],256],12948:[[21517],256],12949:[[29305],256],12950:[[36001],256],12951:[[31069],256],12952:[[21172],256],12953:[[31192],256],12954:[[30007],256],12955:[[22899],256],12956:[[36969],256],12957:[[20778],256],12958:[[21360],256],12959:[[27880],256],12960:[[38917],256],12961:[[20241],256],12962:[[20889],256],12963:[[27491],256],12964:[[19978],256],12965:[[20013],256],12966:[[19979],256],12967:[[24038],256],12968:[[21491],256],12969:[[21307],256],12970:[[23447],256],12971:[[23398],256],12972:[[30435],256],12973:[[20225],256],12974:[[36039],256],12975:[[21332],256],12976:[[22812],256],12977:[[51,54],256],12978:[[51,55],256],12979:[[51,56],256],12980:[[51,57],256],12981:[[52,48],256],12982:[[52,49],256],12983:[[52,50],256],12984:[[52,51],256],12985:[[52,52],256],12986:[[52,53],256],12987:[[52,54],256],12988:[[52,55],256],12989:[[52,56],256],12990:[[52,57],256],12991:[[53,48],256],12992:[[49,26376],256],12993:[[50,26376],256],12994:[[51,26376],256],12995:[[52,26376],256],12996:[[53,26376],256],12997:[[54,26376],256],12998:[[55,26376],256],12999:[[56,26376],256],13000:[[57,26376],256],13001:[[49,48,26376],256],13002:[[49,49,26376],256],13003:[[49,50,26376],256],13004:[[72,103],256],13005:[[101,114,103],256],13006:[[101,86],256],13007:[[76,84,68],256],13008:[[12450],256],13009:[[12452],256],13010:[[12454],256],13011:[[12456],256],13012:[[12458],256],13013:[[12459],256],13014:[[12461],256],13015:[[12463],256],13016:[[12465],256],13017:[[12467],256],13018:[[12469],256],13019:[[12471],256],13020:[[12473],256],13021:[[12475],256],13022:[[12477],256],13023:[[12479],256],13024:[[12481],256],13025:[[12484],256],13026:[[12486],256],13027:[[12488],256],13028:[[12490],256],13029:[[12491],256],13030:[[12492],256],13031:[[12493],256],13032:[[12494],256],13033:[[12495],256],13034:[[12498],256],13035:[[12501],256],13036:[[12504],256],13037:[[12507],256],13038:[[12510],256],13039:[[12511],256],13040:[[12512],256],13041:[[12513],256],13042:[[12514],256],13043:[[12516],256],13044:[[12518],256],13045:[[12520],256],13046:[[12521],256],13047:[[12522],256],13048:[[12523],256],13049:[[12524],256],13050:[[12525],256],13051:[[12527],256],13052:[[12528],256],13053:[[12529],256],13054:[[12530],256]},
    13056:{13056:[[12450,12497,12540,12488],256],13057:[[12450,12523,12501,12449],256],13058:[[12450,12531,12506,12450],256],13059:[[12450,12540,12523],256],13060:[[12452,12491,12531,12464],256],13061:[[12452,12531,12481],256],13062:[[12454,12457,12531],256],13063:[[12456,12473,12463,12540,12489],256],13064:[[12456,12540,12459,12540],256],13065:[[12458,12531,12473],256],13066:[[12458,12540,12512],256],13067:[[12459,12452,12522],256],13068:[[12459,12521,12483,12488],256],13069:[[12459,12525,12522,12540],256],13070:[[12460,12525,12531],256],13071:[[12460,12531,12510],256],13072:[[12462,12460],256],13073:[[12462,12491,12540],256],13074:[[12461,12517,12522,12540],256],13075:[[12462,12523,12480,12540],256],13076:[[12461,12525],256],13077:[[12461,12525,12464,12521,12512],256],13078:[[12461,12525,12513,12540,12488,12523],256],13079:[[12461,12525,12527,12483,12488],256],13080:[[12464,12521,12512],256],13081:[[12464,12521,12512,12488,12531],256],13082:[[12463,12523,12476,12452,12525],256],13083:[[12463,12525,12540,12493],256],13084:[[12465,12540,12473],256],13085:[[12467,12523,12490],256],13086:[[12467,12540,12509],256],13087:[[12469,12452,12463,12523],256],13088:[[12469,12531,12481,12540,12512],256],13089:[[12471,12522,12531,12464],256],13090:[[12475,12531,12481],256],13091:[[12475,12531,12488],256],13092:[[12480,12540,12473],256],13093:[[12487,12471],256],13094:[[12489,12523],256],13095:[[12488,12531],256],13096:[[12490,12494],256],13097:[[12494,12483,12488],256],13098:[[12495,12452,12484],256],13099:[[12497,12540,12475,12531,12488],256],13100:[[12497,12540,12484],256],13101:[[12496,12540,12524,12523],256],13102:[[12500,12450,12473,12488,12523],256],13103:[[12500,12463,12523],256],13104:[[12500,12467],256],13105:[[12499,12523],256],13106:[[12501,12449,12521,12483,12489],256],13107:[[12501,12451,12540,12488],256],13108:[[12502,12483,12471,12455,12523],256],13109:[[12501,12521,12531],256],13110:[[12504,12463,12479,12540,12523],256],13111:[[12506,12477],256],13112:[[12506,12491,12498],256],13113:[[12504,12523,12484],256],13114:[[12506,12531,12473],256],13115:[[12506,12540,12472],256],13116:[[12505,12540,12479],256],13117:[[12509,12452,12531,12488],256],13118:[[12508,12523,12488],256],13119:[[12507,12531],256],13120:[[12509,12531,12489],256],13121:[[12507,12540,12523],256],13122:[[12507,12540,12531],256],13123:[[12510,12452,12463,12525],256],13124:[[12510,12452,12523],256],13125:[[12510,12483,12495],256],13126:[[12510,12523,12463],256],13127:[[12510,12531,12471,12519,12531],256],13128:[[12511,12463,12525,12531],256],13129:[[12511,12522],256],13130:[[12511,12522,12496,12540,12523],256],13131:[[12513,12460],256],13132:[[12513,12460,12488,12531],256],13133:[[12513,12540,12488,12523],256],13134:[[12516,12540,12489],256],13135:[[12516,12540,12523],256],13136:[[12518,12450,12531],256],13137:[[12522,12483,12488,12523],256],13138:[[12522,12521],256],13139:[[12523,12500,12540],256],13140:[[12523,12540,12502,12523],256],13141:[[12524,12512],256],13142:[[12524,12531,12488,12466,12531],256],13143:[[12527,12483,12488],256],13144:[[48,28857],256],13145:[[49,28857],256],13146:[[50,28857],256],13147:[[51,28857],256],13148:[[52,28857],256],13149:[[53,28857],256],13150:[[54,28857],256],13151:[[55,28857],256],13152:[[56,28857],256],13153:[[57,28857],256],13154:[[49,48,28857],256],13155:[[49,49,28857],256],13156:[[49,50,28857],256],13157:[[49,51,28857],256],13158:[[49,52,28857],256],13159:[[49,53,28857],256],13160:[[49,54,28857],256],13161:[[49,55,28857],256],13162:[[49,56,28857],256],13163:[[49,57,28857],256],13164:[[50,48,28857],256],13165:[[50,49,28857],256],13166:[[50,50,28857],256],13167:[[50,51,28857],256],13168:[[50,52,28857],256],13169:[[104,80,97],256],13170:[[100,97],256],13171:[[65,85],256],13172:[[98,97,114],256],13173:[[111,86],256],13174:[[112,99],256],13175:[[100,109],256],13176:[[100,109,178],256],13177:[[100,109,179],256],13178:[[73,85],256],13179:[[24179,25104],256],13180:[[26157,21644],256],13181:[[22823,27491],256],13182:[[26126,27835],256],13183:[[26666,24335,20250,31038],256],13184:[[112,65],256],13185:[[110,65],256],13186:[[956,65],256],13187:[[109,65],256],13188:[[107,65],256],13189:[[75,66],256],13190:[[77,66],256],13191:[[71,66],256],13192:[[99,97,108],256],13193:[[107,99,97,108],256],13194:[[112,70],256],13195:[[110,70],256],13196:[[956,70],256],13197:[[956,103],256],13198:[[109,103],256],13199:[[107,103],256],13200:[[72,122],256],13201:[[107,72,122],256],13202:[[77,72,122],256],13203:[[71,72,122],256],13204:[[84,72,122],256],13205:[[956,8467],256],13206:[[109,8467],256],13207:[[100,8467],256],13208:[[107,8467],256],13209:[[102,109],256],13210:[[110,109],256],13211:[[956,109],256],13212:[[109,109],256],13213:[[99,109],256],13214:[[107,109],256],13215:[[109,109,178],256],13216:[[99,109,178],256],13217:[[109,178],256],13218:[[107,109,178],256],13219:[[109,109,179],256],13220:[[99,109,179],256],13221:[[109,179],256],13222:[[107,109,179],256],13223:[[109,8725,115],256],13224:[[109,8725,115,178],256],13225:[[80,97],256],13226:[[107,80,97],256],13227:[[77,80,97],256],13228:[[71,80,97],256],13229:[[114,97,100],256],13230:[[114,97,100,8725,115],256],13231:[[114,97,100,8725,115,178],256],13232:[[112,115],256],13233:[[110,115],256],13234:[[956,115],256],13235:[[109,115],256],13236:[[112,86],256],13237:[[110,86],256],13238:[[956,86],256],13239:[[109,86],256],13240:[[107,86],256],13241:[[77,86],256],13242:[[112,87],256],13243:[[110,87],256],13244:[[956,87],256],13245:[[109,87],256],13246:[[107,87],256],13247:[[77,87],256],13248:[[107,937],256],13249:[[77,937],256],13250:[[97,46,109,46],256],13251:[[66,113],256],13252:[[99,99],256],13253:[[99,100],256],13254:[[67,8725,107,103],256],13255:[[67,111,46],256],13256:[[100,66],256],13257:[[71,121],256],13258:[[104,97],256],13259:[[72,80],256],13260:[[105,110],256],13261:[[75,75],256],13262:[[75,77],256],13263:[[107,116],256],13264:[[108,109],256],13265:[[108,110],256],13266:[[108,111,103],256],13267:[[108,120],256],13268:[[109,98],256],13269:[[109,105,108],256],13270:[[109,111,108],256],13271:[[80,72],256],13272:[[112,46,109,46],256],13273:[[80,80,77],256],13274:[[80,82],256],13275:[[115,114],256],13276:[[83,118],256],13277:[[87,98],256],13278:[[86,8725,109],256],13279:[[65,8725,109],256],13280:[[49,26085],256],13281:[[50,26085],256],13282:[[51,26085],256],13283:[[52,26085],256],13284:[[53,26085],256],13285:[[54,26085],256],13286:[[55,26085],256],13287:[[56,26085],256],13288:[[57,26085],256],13289:[[49,48,26085],256],13290:[[49,49,26085],256],13291:[[49,50,26085],256],13292:[[49,51,26085],256],13293:[[49,52,26085],256],13294:[[49,53,26085],256],13295:[[49,54,26085],256],13296:[[49,55,26085],256],13297:[[49,56,26085],256],13298:[[49,57,26085],256],13299:[[50,48,26085],256],13300:[[50,49,26085],256],13301:[[50,50,26085],256],13302:[[50,51,26085],256],13303:[[50,52,26085],256],13304:[[50,53,26085],256],13305:[[50,54,26085],256],13306:[[50,55,26085],256],13307:[[50,56,26085],256],13308:[[50,57,26085],256],13309:[[51,48,26085],256],13310:[[51,49,26085],256],13311:[[103,97,108],256]},
    27136:{92912:[,1],92913:[,1],92914:[,1],92915:[,1],92916:[,1]},
    27392:{92976:[,230],92977:[,230],92978:[,230],92979:[,230],92980:[,230],92981:[,230],92982:[,230]},
    42496:{42607:[,230],42612:[,230],42613:[,230],42614:[,230],42615:[,230],42616:[,230],42617:[,230],42618:[,230],42619:[,230],42620:[,230],42621:[,230],42652:[[1098],256],42653:[[1100],256],42655:[,230],42736:[,230],42737:[,230]},
    42752:{42864:[[42863],256],43000:[[294],256],43001:[[339],256]},
    43008:{43014:[,9],43204:[,9],43232:[,230],43233:[,230],43234:[,230],43235:[,230],43236:[,230],43237:[,230],43238:[,230],43239:[,230],43240:[,230],43241:[,230],43242:[,230],43243:[,230],43244:[,230],43245:[,230],43246:[,230],43247:[,230],43248:[,230],43249:[,230]},
    43264:{43307:[,220],43308:[,220],43309:[,220],43347:[,9],43443:[,7],43456:[,9]},
    43520:{43696:[,230],43698:[,230],43699:[,230],43700:[,220],43703:[,230],43704:[,230],43710:[,230],43711:[,230],43713:[,230],43766:[,9]},
    43776:{43868:[[42791],256],43869:[[43831],256],43870:[[619],256],43871:[[43858],256],44013:[,9]},
    48128:{113822:[,1]},
    53504:{119134:[[119127,119141],512],119135:[[119128,119141],512],119136:[[119135,119150],512],119137:[[119135,119151],512],119138:[[119135,119152],512],119139:[[119135,119153],512],119140:[[119135,119154],512],119141:[,216],119142:[,216],119143:[,1],119144:[,1],119145:[,1],119149:[,226],119150:[,216],119151:[,216],119152:[,216],119153:[,216],119154:[,216],119163:[,220],119164:[,220],119165:[,220],119166:[,220],119167:[,220],119168:[,220],119169:[,220],119170:[,220],119173:[,230],119174:[,230],119175:[,230],119176:[,230],119177:[,230],119178:[,220],119179:[,220],119210:[,230],119211:[,230],119212:[,230],119213:[,230],119227:[[119225,119141],512],119228:[[119226,119141],512],119229:[[119227,119150],512],119230:[[119228,119150],512],119231:[[119227,119151],512],119232:[[119228,119151],512]},
    53760:{119362:[,230],119363:[,230],119364:[,230]},
    54272:{119808:[[65],256],119809:[[66],256],119810:[[67],256],119811:[[68],256],119812:[[69],256],119813:[[70],256],119814:[[71],256],119815:[[72],256],119816:[[73],256],119817:[[74],256],119818:[[75],256],119819:[[76],256],119820:[[77],256],119821:[[78],256],119822:[[79],256],119823:[[80],256],119824:[[81],256],119825:[[82],256],119826:[[83],256],119827:[[84],256],119828:[[85],256],119829:[[86],256],119830:[[87],256],119831:[[88],256],119832:[[89],256],119833:[[90],256],119834:[[97],256],119835:[[98],256],119836:[[99],256],119837:[[100],256],119838:[[101],256],119839:[[102],256],119840:[[103],256],119841:[[104],256],119842:[[105],256],119843:[[106],256],119844:[[107],256],119845:[[108],256],119846:[[109],256],119847:[[110],256],119848:[[111],256],119849:[[112],256],119850:[[113],256],119851:[[114],256],119852:[[115],256],119853:[[116],256],119854:[[117],256],119855:[[118],256],119856:[[119],256],119857:[[120],256],119858:[[121],256],119859:[[122],256],119860:[[65],256],119861:[[66],256],119862:[[67],256],119863:[[68],256],119864:[[69],256],119865:[[70],256],119866:[[71],256],119867:[[72],256],119868:[[73],256],119869:[[74],256],119870:[[75],256],119871:[[76],256],119872:[[77],256],119873:[[78],256],119874:[[79],256],119875:[[80],256],119876:[[81],256],119877:[[82],256],119878:[[83],256],119879:[[84],256],119880:[[85],256],119881:[[86],256],119882:[[87],256],119883:[[88],256],119884:[[89],256],119885:[[90],256],119886:[[97],256],119887:[[98],256],119888:[[99],256],119889:[[100],256],119890:[[101],256],119891:[[102],256],119892:[[103],256],119894:[[105],256],119895:[[106],256],119896:[[107],256],119897:[[108],256],119898:[[109],256],119899:[[110],256],119900:[[111],256],119901:[[112],256],119902:[[113],256],119903:[[114],256],119904:[[115],256],119905:[[116],256],119906:[[117],256],119907:[[118],256],119908:[[119],256],119909:[[120],256],119910:[[121],256],119911:[[122],256],119912:[[65],256],119913:[[66],256],119914:[[67],256],119915:[[68],256],119916:[[69],256],119917:[[70],256],119918:[[71],256],119919:[[72],256],119920:[[73],256],119921:[[74],256],119922:[[75],256],119923:[[76],256],119924:[[77],256],119925:[[78],256],119926:[[79],256],119927:[[80],256],119928:[[81],256],119929:[[82],256],119930:[[83],256],119931:[[84],256],119932:[[85],256],119933:[[86],256],119934:[[87],256],119935:[[88],256],119936:[[89],256],119937:[[90],256],119938:[[97],256],119939:[[98],256],119940:[[99],256],119941:[[100],256],119942:[[101],256],119943:[[102],256],119944:[[103],256],119945:[[104],256],119946:[[105],256],119947:[[106],256],119948:[[107],256],119949:[[108],256],119950:[[109],256],119951:[[110],256],119952:[[111],256],119953:[[112],256],119954:[[113],256],119955:[[114],256],119956:[[115],256],119957:[[116],256],119958:[[117],256],119959:[[118],256],119960:[[119],256],119961:[[120],256],119962:[[121],256],119963:[[122],256],119964:[[65],256],119966:[[67],256],119967:[[68],256],119970:[[71],256],119973:[[74],256],119974:[[75],256],119977:[[78],256],119978:[[79],256],119979:[[80],256],119980:[[81],256],119982:[[83],256],119983:[[84],256],119984:[[85],256],119985:[[86],256],119986:[[87],256],119987:[[88],256],119988:[[89],256],119989:[[90],256],119990:[[97],256],119991:[[98],256],119992:[[99],256],119993:[[100],256],119995:[[102],256],119997:[[104],256],119998:[[105],256],119999:[[106],256],120000:[[107],256],120001:[[108],256],120002:[[109],256],120003:[[110],256],120005:[[112],256],120006:[[113],256],120007:[[114],256],120008:[[115],256],120009:[[116],256],120010:[[117],256],120011:[[118],256],120012:[[119],256],120013:[[120],256],120014:[[121],256],120015:[[122],256],120016:[[65],256],120017:[[66],256],120018:[[67],256],120019:[[68],256],120020:[[69],256],120021:[[70],256],120022:[[71],256],120023:[[72],256],120024:[[73],256],120025:[[74],256],120026:[[75],256],120027:[[76],256],120028:[[77],256],120029:[[78],256],120030:[[79],256],120031:[[80],256],120032:[[81],256],120033:[[82],256],120034:[[83],256],120035:[[84],256],120036:[[85],256],120037:[[86],256],120038:[[87],256],120039:[[88],256],120040:[[89],256],120041:[[90],256],120042:[[97],256],120043:[[98],256],120044:[[99],256],120045:[[100],256],120046:[[101],256],120047:[[102],256],120048:[[103],256],120049:[[104],256],120050:[[105],256],120051:[[106],256],120052:[[107],256],120053:[[108],256],120054:[[109],256],120055:[[110],256],120056:[[111],256],120057:[[112],256],120058:[[113],256],120059:[[114],256],120060:[[115],256],120061:[[116],256],120062:[[117],256],120063:[[118],256]},
    54528:{120064:[[119],256],120065:[[120],256],120066:[[121],256],120067:[[122],256],120068:[[65],256],120069:[[66],256],120071:[[68],256],120072:[[69],256],120073:[[70],256],120074:[[71],256],120077:[[74],256],120078:[[75],256],120079:[[76],256],120080:[[77],256],120081:[[78],256],120082:[[79],256],120083:[[80],256],120084:[[81],256],120086:[[83],256],120087:[[84],256],120088:[[85],256],120089:[[86],256],120090:[[87],256],120091:[[88],256],120092:[[89],256],120094:[[97],256],120095:[[98],256],120096:[[99],256],120097:[[100],256],120098:[[101],256],120099:[[102],256],120100:[[103],256],120101:[[104],256],120102:[[105],256],120103:[[106],256],120104:[[107],256],120105:[[108],256],120106:[[109],256],120107:[[110],256],120108:[[111],256],120109:[[112],256],120110:[[113],256],120111:[[114],256],120112:[[115],256],120113:[[116],256],120114:[[117],256],120115:[[118],256],120116:[[119],256],120117:[[120],256],120118:[[121],256],120119:[[122],256],120120:[[65],256],120121:[[66],256],120123:[[68],256],120124:[[69],256],120125:[[70],256],120126:[[71],256],120128:[[73],256],120129:[[74],256],120130:[[75],256],120131:[[76],256],120132:[[77],256],120134:[[79],256],120138:[[83],256],120139:[[84],256],120140:[[85],256],120141:[[86],256],120142:[[87],256],120143:[[88],256],120144:[[89],256],120146:[[97],256],120147:[[98],256],120148:[[99],256],120149:[[100],256],120150:[[101],256],120151:[[102],256],120152:[[103],256],120153:[[104],256],120154:[[105],256],120155:[[106],256],120156:[[107],256],120157:[[108],256],120158:[[109],256],120159:[[110],256],120160:[[111],256],120161:[[112],256],120162:[[113],256],120163:[[114],256],120164:[[115],256],120165:[[116],256],120166:[[117],256],120167:[[118],256],120168:[[119],256],120169:[[120],256],120170:[[121],256],120171:[[122],256],120172:[[65],256],120173:[[66],256],120174:[[67],256],120175:[[68],256],120176:[[69],256],120177:[[70],256],120178:[[71],256],120179:[[72],256],120180:[[73],256],120181:[[74],256],120182:[[75],256],120183:[[76],256],120184:[[77],256],120185:[[78],256],120186:[[79],256],120187:[[80],256],120188:[[81],256],120189:[[82],256],120190:[[83],256],120191:[[84],256],120192:[[85],256],120193:[[86],256],120194:[[87],256],120195:[[88],256],120196:[[89],256],120197:[[90],256],120198:[[97],256],120199:[[98],256],120200:[[99],256],120201:[[100],256],120202:[[101],256],120203:[[102],256],120204:[[103],256],120205:[[104],256],120206:[[105],256],120207:[[106],256],120208:[[107],256],120209:[[108],256],120210:[[109],256],120211:[[110],256],120212:[[111],256],120213:[[112],256],120214:[[113],256],120215:[[114],256],120216:[[115],256],120217:[[116],256],120218:[[117],256],120219:[[118],256],120220:[[119],256],120221:[[120],256],120222:[[121],256],120223:[[122],256],120224:[[65],256],120225:[[66],256],120226:[[67],256],120227:[[68],256],120228:[[69],256],120229:[[70],256],120230:[[71],256],120231:[[72],256],120232:[[73],256],120233:[[74],256],120234:[[75],256],120235:[[76],256],120236:[[77],256],120237:[[78],256],120238:[[79],256],120239:[[80],256],120240:[[81],256],120241:[[82],256],120242:[[83],256],120243:[[84],256],120244:[[85],256],120245:[[86],256],120246:[[87],256],120247:[[88],256],120248:[[89],256],120249:[[90],256],120250:[[97],256],120251:[[98],256],120252:[[99],256],120253:[[100],256],120254:[[101],256],120255:[[102],256],120256:[[103],256],120257:[[104],256],120258:[[105],256],120259:[[106],256],120260:[[107],256],120261:[[108],256],120262:[[109],256],120263:[[110],256],120264:[[111],256],120265:[[112],256],120266:[[113],256],120267:[[114],256],120268:[[115],256],120269:[[116],256],120270:[[117],256],120271:[[118],256],120272:[[119],256],120273:[[120],256],120274:[[121],256],120275:[[122],256],120276:[[65],256],120277:[[66],256],120278:[[67],256],120279:[[68],256],120280:[[69],256],120281:[[70],256],120282:[[71],256],120283:[[72],256],120284:[[73],256],120285:[[74],256],120286:[[75],256],120287:[[76],256],120288:[[77],256],120289:[[78],256],120290:[[79],256],120291:[[80],256],120292:[[81],256],120293:[[82],256],120294:[[83],256],120295:[[84],256],120296:[[85],256],120297:[[86],256],120298:[[87],256],120299:[[88],256],120300:[[89],256],120301:[[90],256],120302:[[97],256],120303:[[98],256],120304:[[99],256],120305:[[100],256],120306:[[101],256],120307:[[102],256],120308:[[103],256],120309:[[104],256],120310:[[105],256],120311:[[106],256],120312:[[107],256],120313:[[108],256],120314:[[109],256],120315:[[110],256],120316:[[111],256],120317:[[112],256],120318:[[113],256],120319:[[114],256]},
    54784:{120320:[[115],256],120321:[[116],256],120322:[[117],256],120323:[[118],256],120324:[[119],256],120325:[[120],256],120326:[[121],256],120327:[[122],256],120328:[[65],256],120329:[[66],256],120330:[[67],256],120331:[[68],256],120332:[[69],256],120333:[[70],256],120334:[[71],256],120335:[[72],256],120336:[[73],256],120337:[[74],256],120338:[[75],256],120339:[[76],256],120340:[[77],256],120341:[[78],256],120342:[[79],256],120343:[[80],256],120344:[[81],256],120345:[[82],256],120346:[[83],256],120347:[[84],256],120348:[[85],256],120349:[[86],256],120350:[[87],256],120351:[[88],256],120352:[[89],256],120353:[[90],256],120354:[[97],256],120355:[[98],256],120356:[[99],256],120357:[[100],256],120358:[[101],256],120359:[[102],256],120360:[[103],256],120361:[[104],256],120362:[[105],256],120363:[[106],256],120364:[[107],256],120365:[[108],256],120366:[[109],256],120367:[[110],256],120368:[[111],256],120369:[[112],256],120370:[[113],256],120371:[[114],256],120372:[[115],256],120373:[[116],256],120374:[[117],256],120375:[[118],256],120376:[[119],256],120377:[[120],256],120378:[[121],256],120379:[[122],256],120380:[[65],256],120381:[[66],256],120382:[[67],256],120383:[[68],256],120384:[[69],256],120385:[[70],256],120386:[[71],256],120387:[[72],256],120388:[[73],256],120389:[[74],256],120390:[[75],256],120391:[[76],256],120392:[[77],256],120393:[[78],256],120394:[[79],256],120395:[[80],256],120396:[[81],256],120397:[[82],256],120398:[[83],256],120399:[[84],256],120400:[[85],256],120401:[[86],256],120402:[[87],256],120403:[[88],256],120404:[[89],256],120405:[[90],256],120406:[[97],256],120407:[[98],256],120408:[[99],256],120409:[[100],256],120410:[[101],256],120411:[[102],256],120412:[[103],256],120413:[[104],256],120414:[[105],256],120415:[[106],256],120416:[[107],256],120417:[[108],256],120418:[[109],256],120419:[[110],256],120420:[[111],256],120421:[[112],256],120422:[[113],256],120423:[[114],256],120424:[[115],256],120425:[[116],256],120426:[[117],256],120427:[[118],256],120428:[[119],256],120429:[[120],256],120430:[[121],256],120431:[[122],256],120432:[[65],256],120433:[[66],256],120434:[[67],256],120435:[[68],256],120436:[[69],256],120437:[[70],256],120438:[[71],256],120439:[[72],256],120440:[[73],256],120441:[[74],256],120442:[[75],256],120443:[[76],256],120444:[[77],256],120445:[[78],256],120446:[[79],256],120447:[[80],256],120448:[[81],256],120449:[[82],256],120450:[[83],256],120451:[[84],256],120452:[[85],256],120453:[[86],256],120454:[[87],256],120455:[[88],256],120456:[[89],256],120457:[[90],256],120458:[[97],256],120459:[[98],256],120460:[[99],256],120461:[[100],256],120462:[[101],256],120463:[[102],256],120464:[[103],256],120465:[[104],256],120466:[[105],256],120467:[[106],256],120468:[[107],256],120469:[[108],256],120470:[[109],256],120471:[[110],256],120472:[[111],256],120473:[[112],256],120474:[[113],256],120475:[[114],256],120476:[[115],256],120477:[[116],256],120478:[[117],256],120479:[[118],256],120480:[[119],256],120481:[[120],256],120482:[[121],256],120483:[[122],256],120484:[[305],256],120485:[[567],256],120488:[[913],256],120489:[[914],256],120490:[[915],256],120491:[[916],256],120492:[[917],256],120493:[[918],256],120494:[[919],256],120495:[[920],256],120496:[[921],256],120497:[[922],256],120498:[[923],256],120499:[[924],256],120500:[[925],256],120501:[[926],256],120502:[[927],256],120503:[[928],256],120504:[[929],256],120505:[[1012],256],120506:[[931],256],120507:[[932],256],120508:[[933],256],120509:[[934],256],120510:[[935],256],120511:[[936],256],120512:[[937],256],120513:[[8711],256],120514:[[945],256],120515:[[946],256],120516:[[947],256],120517:[[948],256],120518:[[949],256],120519:[[950],256],120520:[[951],256],120521:[[952],256],120522:[[953],256],120523:[[954],256],120524:[[955],256],120525:[[956],256],120526:[[957],256],120527:[[958],256],120528:[[959],256],120529:[[960],256],120530:[[961],256],120531:[[962],256],120532:[[963],256],120533:[[964],256],120534:[[965],256],120535:[[966],256],120536:[[967],256],120537:[[968],256],120538:[[969],256],120539:[[8706],256],120540:[[1013],256],120541:[[977],256],120542:[[1008],256],120543:[[981],256],120544:[[1009],256],120545:[[982],256],120546:[[913],256],120547:[[914],256],120548:[[915],256],120549:[[916],256],120550:[[917],256],120551:[[918],256],120552:[[919],256],120553:[[920],256],120554:[[921],256],120555:[[922],256],120556:[[923],256],120557:[[924],256],120558:[[925],256],120559:[[926],256],120560:[[927],256],120561:[[928],256],120562:[[929],256],120563:[[1012],256],120564:[[931],256],120565:[[932],256],120566:[[933],256],120567:[[934],256],120568:[[935],256],120569:[[936],256],120570:[[937],256],120571:[[8711],256],120572:[[945],256],120573:[[946],256],120574:[[947],256],120575:[[948],256]},
    55040:{120576:[[949],256],120577:[[950],256],120578:[[951],256],120579:[[952],256],120580:[[953],256],120581:[[954],256],120582:[[955],256],120583:[[956],256],120584:[[957],256],120585:[[958],256],120586:[[959],256],120587:[[960],256],120588:[[961],256],120589:[[962],256],120590:[[963],256],120591:[[964],256],120592:[[965],256],120593:[[966],256],120594:[[967],256],120595:[[968],256],120596:[[969],256],120597:[[8706],256],120598:[[1013],256],120599:[[977],256],120600:[[1008],256],120601:[[981],256],120602:[[1009],256],120603:[[982],256],120604:[[913],256],120605:[[914],256],120606:[[915],256],120607:[[916],256],120608:[[917],256],120609:[[918],256],120610:[[919],256],120611:[[920],256],120612:[[921],256],120613:[[922],256],120614:[[923],256],120615:[[924],256],120616:[[925],256],120617:[[926],256],120618:[[927],256],120619:[[928],256],120620:[[929],256],120621:[[1012],256],120622:[[931],256],120623:[[932],256],120624:[[933],256],120625:[[934],256],120626:[[935],256],120627:[[936],256],120628:[[937],256],120629:[[8711],256],120630:[[945],256],120631:[[946],256],120632:[[947],256],120633:[[948],256],120634:[[949],256],120635:[[950],256],120636:[[951],256],120637:[[952],256],120638:[[953],256],120639:[[954],256],120640:[[955],256],120641:[[956],256],120642:[[957],256],120643:[[958],256],120644:[[959],256],120645:[[960],256],120646:[[961],256],120647:[[962],256],120648:[[963],256],120649:[[964],256],120650:[[965],256],120651:[[966],256],120652:[[967],256],120653:[[968],256],120654:[[969],256],120655:[[8706],256],120656:[[1013],256],120657:[[977],256],120658:[[1008],256],120659:[[981],256],120660:[[1009],256],120661:[[982],256],120662:[[913],256],120663:[[914],256],120664:[[915],256],120665:[[916],256],120666:[[917],256],120667:[[918],256],120668:[[919],256],120669:[[920],256],120670:[[921],256],120671:[[922],256],120672:[[923],256],120673:[[924],256],120674:[[925],256],120675:[[926],256],120676:[[927],256],120677:[[928],256],120678:[[929],256],120679:[[1012],256],120680:[[931],256],120681:[[932],256],120682:[[933],256],120683:[[934],256],120684:[[935],256],120685:[[936],256],120686:[[937],256],120687:[[8711],256],120688:[[945],256],120689:[[946],256],120690:[[947],256],120691:[[948],256],120692:[[949],256],120693:[[950],256],120694:[[951],256],120695:[[952],256],120696:[[953],256],120697:[[954],256],120698:[[955],256],120699:[[956],256],120700:[[957],256],120701:[[958],256],120702:[[959],256],120703:[[960],256],120704:[[961],256],120705:[[962],256],120706:[[963],256],120707:[[964],256],120708:[[965],256],120709:[[966],256],120710:[[967],256],120711:[[968],256],120712:[[969],256],120713:[[8706],256],120714:[[1013],256],120715:[[977],256],120716:[[1008],256],120717:[[981],256],120718:[[1009],256],120719:[[982],256],120720:[[913],256],120721:[[914],256],120722:[[915],256],120723:[[916],256],120724:[[917],256],120725:[[918],256],120726:[[919],256],120727:[[920],256],120728:[[921],256],120729:[[922],256],120730:[[923],256],120731:[[924],256],120732:[[925],256],120733:[[926],256],120734:[[927],256],120735:[[928],256],120736:[[929],256],120737:[[1012],256],120738:[[931],256],120739:[[932],256],120740:[[933],256],120741:[[934],256],120742:[[935],256],120743:[[936],256],120744:[[937],256],120745:[[8711],256],120746:[[945],256],120747:[[946],256],120748:[[947],256],120749:[[948],256],120750:[[949],256],120751:[[950],256],120752:[[951],256],120753:[[952],256],120754:[[953],256],120755:[[954],256],120756:[[955],256],120757:[[956],256],120758:[[957],256],120759:[[958],256],120760:[[959],256],120761:[[960],256],120762:[[961],256],120763:[[962],256],120764:[[963],256],120765:[[964],256],120766:[[965],256],120767:[[966],256],120768:[[967],256],120769:[[968],256],120770:[[969],256],120771:[[8706],256],120772:[[1013],256],120773:[[977],256],120774:[[1008],256],120775:[[981],256],120776:[[1009],256],120777:[[982],256],120778:[[988],256],120779:[[989],256],120782:[[48],256],120783:[[49],256],120784:[[50],256],120785:[[51],256],120786:[[52],256],120787:[[53],256],120788:[[54],256],120789:[[55],256],120790:[[56],256],120791:[[57],256],120792:[[48],256],120793:[[49],256],120794:[[50],256],120795:[[51],256],120796:[[52],256],120797:[[53],256],120798:[[54],256],120799:[[55],256],120800:[[56],256],120801:[[57],256],120802:[[48],256],120803:[[49],256],120804:[[50],256],120805:[[51],256],120806:[[52],256],120807:[[53],256],120808:[[54],256],120809:[[55],256],120810:[[56],256],120811:[[57],256],120812:[[48],256],120813:[[49],256],120814:[[50],256],120815:[[51],256],120816:[[52],256],120817:[[53],256],120818:[[54],256],120819:[[55],256],120820:[[56],256],120821:[[57],256],120822:[[48],256],120823:[[49],256],120824:[[50],256],120825:[[51],256],120826:[[52],256],120827:[[53],256],120828:[[54],256],120829:[[55],256],120830:[[56],256],120831:[[57],256]},
    59392:{125136:[,220],125137:[,220],125138:[,220],125139:[,220],125140:[,220],125141:[,220],125142:[,220]},
    60928:{126464:[[1575],256],126465:[[1576],256],126466:[[1580],256],126467:[[1583],256],126469:[[1608],256],126470:[[1586],256],126471:[[1581],256],126472:[[1591],256],126473:[[1610],256],126474:[[1603],256],126475:[[1604],256],126476:[[1605],256],126477:[[1606],256],126478:[[1587],256],126479:[[1593],256],126480:[[1601],256],126481:[[1589],256],126482:[[1602],256],126483:[[1585],256],126484:[[1588],256],126485:[[1578],256],126486:[[1579],256],126487:[[1582],256],126488:[[1584],256],126489:[[1590],256],126490:[[1592],256],126491:[[1594],256],126492:[[1646],256],126493:[[1722],256],126494:[[1697],256],126495:[[1647],256],126497:[[1576],256],126498:[[1580],256],126500:[[1607],256],126503:[[1581],256],126505:[[1610],256],126506:[[1603],256],126507:[[1604],256],126508:[[1605],256],126509:[[1606],256],126510:[[1587],256],126511:[[1593],256],126512:[[1601],256],126513:[[1589],256],126514:[[1602],256],126516:[[1588],256],126517:[[1578],256],126518:[[1579],256],126519:[[1582],256],126521:[[1590],256],126523:[[1594],256],126530:[[1580],256],126535:[[1581],256],126537:[[1610],256],126539:[[1604],256],126541:[[1606],256],126542:[[1587],256],126543:[[1593],256],126545:[[1589],256],126546:[[1602],256],126548:[[1588],256],126551:[[1582],256],126553:[[1590],256],126555:[[1594],256],126557:[[1722],256],126559:[[1647],256],126561:[[1576],256],126562:[[1580],256],126564:[[1607],256],126567:[[1581],256],126568:[[1591],256],126569:[[1610],256],126570:[[1603],256],126572:[[1605],256],126573:[[1606],256],126574:[[1587],256],126575:[[1593],256],126576:[[1601],256],126577:[[1589],256],126578:[[1602],256],126580:[[1588],256],126581:[[1578],256],126582:[[1579],256],126583:[[1582],256],126585:[[1590],256],126586:[[1592],256],126587:[[1594],256],126588:[[1646],256],126590:[[1697],256],126592:[[1575],256],126593:[[1576],256],126594:[[1580],256],126595:[[1583],256],126596:[[1607],256],126597:[[1608],256],126598:[[1586],256],126599:[[1581],256],126600:[[1591],256],126601:[[1610],256],126603:[[1604],256],126604:[[1605],256],126605:[[1606],256],126606:[[1587],256],126607:[[1593],256],126608:[[1601],256],126609:[[1589],256],126610:[[1602],256],126611:[[1585],256],126612:[[1588],256],126613:[[1578],256],126614:[[1579],256],126615:[[1582],256],126616:[[1584],256],126617:[[1590],256],126618:[[1592],256],126619:[[1594],256],126625:[[1576],256],126626:[[1580],256],126627:[[1583],256],126629:[[1608],256],126630:[[1586],256],126631:[[1581],256],126632:[[1591],256],126633:[[1610],256],126635:[[1604],256],126636:[[1605],256],126637:[[1606],256],126638:[[1587],256],126639:[[1593],256],126640:[[1601],256],126641:[[1589],256],126642:[[1602],256],126643:[[1585],256],126644:[[1588],256],126645:[[1578],256],126646:[[1579],256],126647:[[1582],256],126648:[[1584],256],126649:[[1590],256],126650:[[1592],256],126651:[[1594],256]},
    61696:{127232:[[48,46],256],127233:[[48,44],256],127234:[[49,44],256],127235:[[50,44],256],127236:[[51,44],256],127237:[[52,44],256],127238:[[53,44],256],127239:[[54,44],256],127240:[[55,44],256],127241:[[56,44],256],127242:[[57,44],256],127248:[[40,65,41],256],127249:[[40,66,41],256],127250:[[40,67,41],256],127251:[[40,68,41],256],127252:[[40,69,41],256],127253:[[40,70,41],256],127254:[[40,71,41],256],127255:[[40,72,41],256],127256:[[40,73,41],256],127257:[[40,74,41],256],127258:[[40,75,41],256],127259:[[40,76,41],256],127260:[[40,77,41],256],127261:[[40,78,41],256],127262:[[40,79,41],256],127263:[[40,80,41],256],127264:[[40,81,41],256],127265:[[40,82,41],256],127266:[[40,83,41],256],127267:[[40,84,41],256],127268:[[40,85,41],256],127269:[[40,86,41],256],127270:[[40,87,41],256],127271:[[40,88,41],256],127272:[[40,89,41],256],127273:[[40,90,41],256],127274:[[12308,83,12309],256],127275:[[67],256],127276:[[82],256],127277:[[67,68],256],127278:[[87,90],256],127280:[[65],256],127281:[[66],256],127282:[[67],256],127283:[[68],256],127284:[[69],256],127285:[[70],256],127286:[[71],256],127287:[[72],256],127288:[[73],256],127289:[[74],256],127290:[[75],256],127291:[[76],256],127292:[[77],256],127293:[[78],256],127294:[[79],256],127295:[[80],256],127296:[[81],256],127297:[[82],256],127298:[[83],256],127299:[[84],256],127300:[[85],256],127301:[[86],256],127302:[[87],256],127303:[[88],256],127304:[[89],256],127305:[[90],256],127306:[[72,86],256],127307:[[77,86],256],127308:[[83,68],256],127309:[[83,83],256],127310:[[80,80,86],256],127311:[[87,67],256],127338:[[77,67],256],127339:[[77,68],256],127376:[[68,74],256]},
    61952:{127488:[[12411,12363],256],127489:[[12467,12467],256],127490:[[12469],256],127504:[[25163],256],127505:[[23383],256],127506:[[21452],256],127507:[[12487],256],127508:[[20108],256],127509:[[22810],256],127510:[[35299],256],127511:[[22825],256],127512:[[20132],256],127513:[[26144],256],127514:[[28961],256],127515:[[26009],256],127516:[[21069],256],127517:[[24460],256],127518:[[20877],256],127519:[[26032],256],127520:[[21021],256],127521:[[32066],256],127522:[[29983],256],127523:[[36009],256],127524:[[22768],256],127525:[[21561],256],127526:[[28436],256],127527:[[25237],256],127528:[[25429],256],127529:[[19968],256],127530:[[19977],256],127531:[[36938],256],127532:[[24038],256],127533:[[20013],256],127534:[[21491],256],127535:[[25351],256],127536:[[36208],256],127537:[[25171],256],127538:[[31105],256],127539:[[31354],256],127540:[[21512],256],127541:[[28288],256],127542:[[26377],256],127543:[[26376],256],127544:[[30003],256],127545:[[21106],256],127546:[[21942],256],127552:[[12308,26412,12309],256],127553:[[12308,19977,12309],256],127554:[[12308,20108,12309],256],127555:[[12308,23433,12309],256],127556:[[12308,28857,12309],256],127557:[[12308,25171,12309],256],127558:[[12308,30423,12309],256],127559:[[12308,21213,12309],256],127560:[[12308,25943,12309],256],127568:[[24471],256],127569:[[21487],256]},
    63488:{194560:[[20029]],194561:[[20024]],194562:[[20033]],194563:[[131362]],194564:[[20320]],194565:[[20398]],194566:[[20411]],194567:[[20482]],194568:[[20602]],194569:[[20633]],194570:[[20711]],194571:[[20687]],194572:[[13470]],194573:[[132666]],194574:[[20813]],194575:[[20820]],194576:[[20836]],194577:[[20855]],194578:[[132380]],194579:[[13497]],194580:[[20839]],194581:[[20877]],194582:[[132427]],194583:[[20887]],194584:[[20900]],194585:[[20172]],194586:[[20908]],194587:[[20917]],194588:[[168415]],194589:[[20981]],194590:[[20995]],194591:[[13535]],194592:[[21051]],194593:[[21062]],194594:[[21106]],194595:[[21111]],194596:[[13589]],194597:[[21191]],194598:[[21193]],194599:[[21220]],194600:[[21242]],194601:[[21253]],194602:[[21254]],194603:[[21271]],194604:[[21321]],194605:[[21329]],194606:[[21338]],194607:[[21363]],194608:[[21373]],194609:[[21375]],194610:[[21375]],194611:[[21375]],194612:[[133676]],194613:[[28784]],194614:[[21450]],194615:[[21471]],194616:[[133987]],194617:[[21483]],194618:[[21489]],194619:[[21510]],194620:[[21662]],194621:[[21560]],194622:[[21576]],194623:[[21608]],194624:[[21666]],194625:[[21750]],194626:[[21776]],194627:[[21843]],194628:[[21859]],194629:[[21892]],194630:[[21892]],194631:[[21913]],194632:[[21931]],194633:[[21939]],194634:[[21954]],194635:[[22294]],194636:[[22022]],194637:[[22295]],194638:[[22097]],194639:[[22132]],194640:[[20999]],194641:[[22766]],194642:[[22478]],194643:[[22516]],194644:[[22541]],194645:[[22411]],194646:[[22578]],194647:[[22577]],194648:[[22700]],194649:[[136420]],194650:[[22770]],194651:[[22775]],194652:[[22790]],194653:[[22810]],194654:[[22818]],194655:[[22882]],194656:[[136872]],194657:[[136938]],194658:[[23020]],194659:[[23067]],194660:[[23079]],194661:[[23000]],194662:[[23142]],194663:[[14062]],194664:[[14076]],194665:[[23304]],194666:[[23358]],194667:[[23358]],194668:[[137672]],194669:[[23491]],194670:[[23512]],194671:[[23527]],194672:[[23539]],194673:[[138008]],194674:[[23551]],194675:[[23558]],194676:[[24403]],194677:[[23586]],194678:[[14209]],194679:[[23648]],194680:[[23662]],194681:[[23744]],194682:[[23693]],194683:[[138724]],194684:[[23875]],194685:[[138726]],194686:[[23918]],194687:[[23915]],194688:[[23932]],194689:[[24033]],194690:[[24034]],194691:[[14383]],194692:[[24061]],194693:[[24104]],194694:[[24125]],194695:[[24169]],194696:[[14434]],194697:[[139651]],194698:[[14460]],194699:[[24240]],194700:[[24243]],194701:[[24246]],194702:[[24266]],194703:[[172946]],194704:[[24318]],194705:[[140081]],194706:[[140081]],194707:[[33281]],194708:[[24354]],194709:[[24354]],194710:[[14535]],194711:[[144056]],194712:[[156122]],194713:[[24418]],194714:[[24427]],194715:[[14563]],194716:[[24474]],194717:[[24525]],194718:[[24535]],194719:[[24569]],194720:[[24705]],194721:[[14650]],194722:[[14620]],194723:[[24724]],194724:[[141012]],194725:[[24775]],194726:[[24904]],194727:[[24908]],194728:[[24910]],194729:[[24908]],194730:[[24954]],194731:[[24974]],194732:[[25010]],194733:[[24996]],194734:[[25007]],194735:[[25054]],194736:[[25074]],194737:[[25078]],194738:[[25104]],194739:[[25115]],194740:[[25181]],194741:[[25265]],194742:[[25300]],194743:[[25424]],194744:[[142092]],194745:[[25405]],194746:[[25340]],194747:[[25448]],194748:[[25475]],194749:[[25572]],194750:[[142321]],194751:[[25634]],194752:[[25541]],194753:[[25513]],194754:[[14894]],194755:[[25705]],194756:[[25726]],194757:[[25757]],194758:[[25719]],194759:[[14956]],194760:[[25935]],194761:[[25964]],194762:[[143370]],194763:[[26083]],194764:[[26360]],194765:[[26185]],194766:[[15129]],194767:[[26257]],194768:[[15112]],194769:[[15076]],194770:[[20882]],194771:[[20885]],194772:[[26368]],194773:[[26268]],194774:[[32941]],194775:[[17369]],194776:[[26391]],194777:[[26395]],194778:[[26401]],194779:[[26462]],194780:[[26451]],194781:[[144323]],194782:[[15177]],194783:[[26618]],194784:[[26501]],194785:[[26706]],194786:[[26757]],194787:[[144493]],194788:[[26766]],194789:[[26655]],194790:[[26900]],194791:[[15261]],194792:[[26946]],194793:[[27043]],194794:[[27114]],194795:[[27304]],194796:[[145059]],194797:[[27355]],194798:[[15384]],194799:[[27425]],194800:[[145575]],194801:[[27476]],194802:[[15438]],194803:[[27506]],194804:[[27551]],194805:[[27578]],194806:[[27579]],194807:[[146061]],194808:[[138507]],194809:[[146170]],194810:[[27726]],194811:[[146620]],194812:[[27839]],194813:[[27853]],194814:[[27751]],194815:[[27926]]},
    63744:{63744:[[35912]],63745:[[26356]],63746:[[36554]],63747:[[36040]],63748:[[28369]],63749:[[20018]],63750:[[21477]],63751:[[40860]],63752:[[40860]],63753:[[22865]],63754:[[37329]],63755:[[21895]],63756:[[22856]],63757:[[25078]],63758:[[30313]],63759:[[32645]],63760:[[34367]],63761:[[34746]],63762:[[35064]],63763:[[37007]],63764:[[27138]],63765:[[27931]],63766:[[28889]],63767:[[29662]],63768:[[33853]],63769:[[37226]],63770:[[39409]],63771:[[20098]],63772:[[21365]],63773:[[27396]],63774:[[29211]],63775:[[34349]],63776:[[40478]],63777:[[23888]],63778:[[28651]],63779:[[34253]],63780:[[35172]],63781:[[25289]],63782:[[33240]],63783:[[34847]],63784:[[24266]],63785:[[26391]],63786:[[28010]],63787:[[29436]],63788:[[37070]],63789:[[20358]],63790:[[20919]],63791:[[21214]],63792:[[25796]],63793:[[27347]],63794:[[29200]],63795:[[30439]],63796:[[32769]],63797:[[34310]],63798:[[34396]],63799:[[36335]],63800:[[38706]],63801:[[39791]],63802:[[40442]],63803:[[30860]],63804:[[31103]],63805:[[32160]],63806:[[33737]],63807:[[37636]],63808:[[40575]],63809:[[35542]],63810:[[22751]],63811:[[24324]],63812:[[31840]],63813:[[32894]],63814:[[29282]],63815:[[30922]],63816:[[36034]],63817:[[38647]],63818:[[22744]],63819:[[23650]],63820:[[27155]],63821:[[28122]],63822:[[28431]],63823:[[32047]],63824:[[32311]],63825:[[38475]],63826:[[21202]],63827:[[32907]],63828:[[20956]],63829:[[20940]],63830:[[31260]],63831:[[32190]],63832:[[33777]],63833:[[38517]],63834:[[35712]],63835:[[25295]],63836:[[27138]],63837:[[35582]],63838:[[20025]],63839:[[23527]],63840:[[24594]],63841:[[29575]],63842:[[30064]],63843:[[21271]],63844:[[30971]],63845:[[20415]],63846:[[24489]],63847:[[19981]],63848:[[27852]],63849:[[25976]],63850:[[32034]],63851:[[21443]],63852:[[22622]],63853:[[30465]],63854:[[33865]],63855:[[35498]],63856:[[27578]],63857:[[36784]],63858:[[27784]],63859:[[25342]],63860:[[33509]],63861:[[25504]],63862:[[30053]],63863:[[20142]],63864:[[20841]],63865:[[20937]],63866:[[26753]],63867:[[31975]],63868:[[33391]],63869:[[35538]],63870:[[37327]],63871:[[21237]],63872:[[21570]],63873:[[22899]],63874:[[24300]],63875:[[26053]],63876:[[28670]],63877:[[31018]],63878:[[38317]],63879:[[39530]],63880:[[40599]],63881:[[40654]],63882:[[21147]],63883:[[26310]],63884:[[27511]],63885:[[36706]],63886:[[24180]],63887:[[24976]],63888:[[25088]],63889:[[25754]],63890:[[28451]],63891:[[29001]],63892:[[29833]],63893:[[31178]],63894:[[32244]],63895:[[32879]],63896:[[36646]],63897:[[34030]],63898:[[36899]],63899:[[37706]],63900:[[21015]],63901:[[21155]],63902:[[21693]],63903:[[28872]],63904:[[35010]],63905:[[35498]],63906:[[24265]],63907:[[24565]],63908:[[25467]],63909:[[27566]],63910:[[31806]],63911:[[29557]],63912:[[20196]],63913:[[22265]],63914:[[23527]],63915:[[23994]],63916:[[24604]],63917:[[29618]],63918:[[29801]],63919:[[32666]],63920:[[32838]],63921:[[37428]],63922:[[38646]],63923:[[38728]],63924:[[38936]],63925:[[20363]],63926:[[31150]],63927:[[37300]],63928:[[38584]],63929:[[24801]],63930:[[20102]],63931:[[20698]],63932:[[23534]],63933:[[23615]],63934:[[26009]],63935:[[27138]],63936:[[29134]],63937:[[30274]],63938:[[34044]],63939:[[36988]],63940:[[40845]],63941:[[26248]],63942:[[38446]],63943:[[21129]],63944:[[26491]],63945:[[26611]],63946:[[27969]],63947:[[28316]],63948:[[29705]],63949:[[30041]],63950:[[30827]],63951:[[32016]],63952:[[39006]],63953:[[20845]],63954:[[25134]],63955:[[38520]],63956:[[20523]],63957:[[23833]],63958:[[28138]],63959:[[36650]],63960:[[24459]],63961:[[24900]],63962:[[26647]],63963:[[29575]],63964:[[38534]],63965:[[21033]],63966:[[21519]],63967:[[23653]],63968:[[26131]],63969:[[26446]],63970:[[26792]],63971:[[27877]],63972:[[29702]],63973:[[30178]],63974:[[32633]],63975:[[35023]],63976:[[35041]],63977:[[37324]],63978:[[38626]],63979:[[21311]],63980:[[28346]],63981:[[21533]],63982:[[29136]],63983:[[29848]],63984:[[34298]],63985:[[38563]],63986:[[40023]],63987:[[40607]],63988:[[26519]],63989:[[28107]],63990:[[33256]],63991:[[31435]],63992:[[31520]],63993:[[31890]],63994:[[29376]],63995:[[28825]],63996:[[35672]],63997:[[20160]],63998:[[33590]],63999:[[21050]],194816:[[27966]],194817:[[28023]],194818:[[27969]],194819:[[28009]],194820:[[28024]],194821:[[28037]],194822:[[146718]],194823:[[27956]],194824:[[28207]],194825:[[28270]],194826:[[15667]],194827:[[28363]],194828:[[28359]],194829:[[147153]],194830:[[28153]],194831:[[28526]],194832:[[147294]],194833:[[147342]],194834:[[28614]],194835:[[28729]],194836:[[28702]],194837:[[28699]],194838:[[15766]],194839:[[28746]],194840:[[28797]],194841:[[28791]],194842:[[28845]],194843:[[132389]],194844:[[28997]],194845:[[148067]],194846:[[29084]],194847:[[148395]],194848:[[29224]],194849:[[29237]],194850:[[29264]],194851:[[149000]],194852:[[29312]],194853:[[29333]],194854:[[149301]],194855:[[149524]],194856:[[29562]],194857:[[29579]],194858:[[16044]],194859:[[29605]],194860:[[16056]],194861:[[16056]],194862:[[29767]],194863:[[29788]],194864:[[29809]],194865:[[29829]],194866:[[29898]],194867:[[16155]],194868:[[29988]],194869:[[150582]],194870:[[30014]],194871:[[150674]],194872:[[30064]],194873:[[139679]],194874:[[30224]],194875:[[151457]],194876:[[151480]],194877:[[151620]],194878:[[16380]],194879:[[16392]],194880:[[30452]],194881:[[151795]],194882:[[151794]],194883:[[151833]],194884:[[151859]],194885:[[30494]],194886:[[30495]],194887:[[30495]],194888:[[30538]],194889:[[16441]],194890:[[30603]],194891:[[16454]],194892:[[16534]],194893:[[152605]],194894:[[30798]],194895:[[30860]],194896:[[30924]],194897:[[16611]],194898:[[153126]],194899:[[31062]],194900:[[153242]],194901:[[153285]],194902:[[31119]],194903:[[31211]],194904:[[16687]],194905:[[31296]],194906:[[31306]],194907:[[31311]],194908:[[153980]],194909:[[154279]],194910:[[154279]],194911:[[31470]],194912:[[16898]],194913:[[154539]],194914:[[31686]],194915:[[31689]],194916:[[16935]],194917:[[154752]],194918:[[31954]],194919:[[17056]],194920:[[31976]],194921:[[31971]],194922:[[32000]],194923:[[155526]],194924:[[32099]],194925:[[17153]],194926:[[32199]],194927:[[32258]],194928:[[32325]],194929:[[17204]],194930:[[156200]],194931:[[156231]],194932:[[17241]],194933:[[156377]],194934:[[32634]],194935:[[156478]],194936:[[32661]],194937:[[32762]],194938:[[32773]],194939:[[156890]],194940:[[156963]],194941:[[32864]],194942:[[157096]],194943:[[32880]],194944:[[144223]],194945:[[17365]],194946:[[32946]],194947:[[33027]],194948:[[17419]],194949:[[33086]],194950:[[23221]],194951:[[157607]],194952:[[157621]],194953:[[144275]],194954:[[144284]],194955:[[33281]],194956:[[33284]],194957:[[36766]],194958:[[17515]],194959:[[33425]],194960:[[33419]],194961:[[33437]],194962:[[21171]],194963:[[33457]],194964:[[33459]],194965:[[33469]],194966:[[33510]],194967:[[158524]],194968:[[33509]],194969:[[33565]],194970:[[33635]],194971:[[33709]],194972:[[33571]],194973:[[33725]],194974:[[33767]],194975:[[33879]],194976:[[33619]],194977:[[33738]],194978:[[33740]],194979:[[33756]],194980:[[158774]],194981:[[159083]],194982:[[158933]],194983:[[17707]],194984:[[34033]],194985:[[34035]],194986:[[34070]],194987:[[160714]],194988:[[34148]],194989:[[159532]],194990:[[17757]],194991:[[17761]],194992:[[159665]],194993:[[159954]],194994:[[17771]],194995:[[34384]],194996:[[34396]],194997:[[34407]],194998:[[34409]],194999:[[34473]],195000:[[34440]],195001:[[34574]],195002:[[34530]],195003:[[34681]],195004:[[34600]],195005:[[34667]],195006:[[34694]],195007:[[17879]],195008:[[34785]],195009:[[34817]],195010:[[17913]],195011:[[34912]],195012:[[34915]],195013:[[161383]],195014:[[35031]],195015:[[35038]],195016:[[17973]],195017:[[35066]],195018:[[13499]],195019:[[161966]],195020:[[162150]],195021:[[18110]],195022:[[18119]],195023:[[35488]],195024:[[35565]],195025:[[35722]],195026:[[35925]],195027:[[162984]],195028:[[36011]],195029:[[36033]],195030:[[36123]],195031:[[36215]],195032:[[163631]],195033:[[133124]],195034:[[36299]],195035:[[36284]],195036:[[36336]],195037:[[133342]],195038:[[36564]],195039:[[36664]],195040:[[165330]],195041:[[165357]],195042:[[37012]],195043:[[37105]],195044:[[37137]],195045:[[165678]],195046:[[37147]],195047:[[37432]],195048:[[37591]],195049:[[37592]],195050:[[37500]],195051:[[37881]],195052:[[37909]],195053:[[166906]],195054:[[38283]],195055:[[18837]],195056:[[38327]],195057:[[167287]],195058:[[18918]],195059:[[38595]],195060:[[23986]],195061:[[38691]],195062:[[168261]],195063:[[168474]],195064:[[19054]],195065:[[19062]],195066:[[38880]],195067:[[168970]],195068:[[19122]],195069:[[169110]],195070:[[38923]],195071:[[38923]]},
    64000:{64000:[[20999]],64001:[[24230]],64002:[[25299]],64003:[[31958]],64004:[[23429]],64005:[[27934]],64006:[[26292]],64007:[[36667]],64008:[[34892]],64009:[[38477]],64010:[[35211]],64011:[[24275]],64012:[[20800]],64013:[[21952]],64016:[[22618]],64018:[[26228]],64021:[[20958]],64022:[[29482]],64023:[[30410]],64024:[[31036]],64025:[[31070]],64026:[[31077]],64027:[[31119]],64028:[[38742]],64029:[[31934]],64030:[[32701]],64032:[[34322]],64034:[[35576]],64037:[[36920]],64038:[[37117]],64042:[[39151]],64043:[[39164]],64044:[[39208]],64045:[[40372]],64046:[[37086]],64047:[[38583]],64048:[[20398]],64049:[[20711]],64050:[[20813]],64051:[[21193]],64052:[[21220]],64053:[[21329]],64054:[[21917]],64055:[[22022]],64056:[[22120]],64057:[[22592]],64058:[[22696]],64059:[[23652]],64060:[[23662]],64061:[[24724]],64062:[[24936]],64063:[[24974]],64064:[[25074]],64065:[[25935]],64066:[[26082]],64067:[[26257]],64068:[[26757]],64069:[[28023]],64070:[[28186]],64071:[[28450]],64072:[[29038]],64073:[[29227]],64074:[[29730]],64075:[[30865]],64076:[[31038]],64077:[[31049]],64078:[[31048]],64079:[[31056]],64080:[[31062]],64081:[[31069]],64082:[[31117]],64083:[[31118]],64084:[[31296]],64085:[[31361]],64086:[[31680]],64087:[[32244]],64088:[[32265]],64089:[[32321]],64090:[[32626]],64091:[[32773]],64092:[[33261]],64093:[[33401]],64094:[[33401]],64095:[[33879]],64096:[[35088]],64097:[[35222]],64098:[[35585]],64099:[[35641]],64100:[[36051]],64101:[[36104]],64102:[[36790]],64103:[[36920]],64104:[[38627]],64105:[[38911]],64106:[[38971]],64107:[[24693]],64108:[[148206]],64109:[[33304]],64112:[[20006]],64113:[[20917]],64114:[[20840]],64115:[[20352]],64116:[[20805]],64117:[[20864]],64118:[[21191]],64119:[[21242]],64120:[[21917]],64121:[[21845]],64122:[[21913]],64123:[[21986]],64124:[[22618]],64125:[[22707]],64126:[[22852]],64127:[[22868]],64128:[[23138]],64129:[[23336]],64130:[[24274]],64131:[[24281]],64132:[[24425]],64133:[[24493]],64134:[[24792]],64135:[[24910]],64136:[[24840]],64137:[[24974]],64138:[[24928]],64139:[[25074]],64140:[[25140]],64141:[[25540]],64142:[[25628]],64143:[[25682]],64144:[[25942]],64145:[[26228]],64146:[[26391]],64147:[[26395]],64148:[[26454]],64149:[[27513]],64150:[[27578]],64151:[[27969]],64152:[[28379]],64153:[[28363]],64154:[[28450]],64155:[[28702]],64156:[[29038]],64157:[[30631]],64158:[[29237]],64159:[[29359]],64160:[[29482]],64161:[[29809]],64162:[[29958]],64163:[[30011]],64164:[[30237]],64165:[[30239]],64166:[[30410]],64167:[[30427]],64168:[[30452]],64169:[[30538]],64170:[[30528]],64171:[[30924]],64172:[[31409]],64173:[[31680]],64174:[[31867]],64175:[[32091]],64176:[[32244]],64177:[[32574]],64178:[[32773]],64179:[[33618]],64180:[[33775]],64181:[[34681]],64182:[[35137]],64183:[[35206]],64184:[[35222]],64185:[[35519]],64186:[[35576]],64187:[[35531]],64188:[[35585]],64189:[[35582]],64190:[[35565]],64191:[[35641]],64192:[[35722]],64193:[[36104]],64194:[[36664]],64195:[[36978]],64196:[[37273]],64197:[[37494]],64198:[[38524]],64199:[[38627]],64200:[[38742]],64201:[[38875]],64202:[[38911]],64203:[[38923]],64204:[[38971]],64205:[[39698]],64206:[[40860]],64207:[[141386]],64208:[[141380]],64209:[[144341]],64210:[[15261]],64211:[[16408]],64212:[[16441]],64213:[[152137]],64214:[[154832]],64215:[[163539]],64216:[[40771]],64217:[[40846]],195072:[[38953]],195073:[[169398]],195074:[[39138]],195075:[[19251]],195076:[[39209]],195077:[[39335]],195078:[[39362]],195079:[[39422]],195080:[[19406]],195081:[[170800]],195082:[[39698]],195083:[[40000]],195084:[[40189]],195085:[[19662]],195086:[[19693]],195087:[[40295]],195088:[[172238]],195089:[[19704]],195090:[[172293]],195091:[[172558]],195092:[[172689]],195093:[[40635]],195094:[[19798]],195095:[[40697]],195096:[[40702]],195097:[[40709]],195098:[[40719]],195099:[[40726]],195100:[[40763]],195101:[[173568]]},
    64256:{64256:[[102,102],256],64257:[[102,105],256],64258:[[102,108],256],64259:[[102,102,105],256],64260:[[102,102,108],256],64261:[[383,116],256],64262:[[115,116],256],64275:[[1396,1398],256],64276:[[1396,1381],256],64277:[[1396,1387],256],64278:[[1406,1398],256],64279:[[1396,1389],256],64285:[[1497,1460],512],64286:[,26],64287:[[1522,1463],512],64288:[[1506],256],64289:[[1488],256],64290:[[1491],256],64291:[[1492],256],64292:[[1499],256],64293:[[1500],256],64294:[[1501],256],64295:[[1512],256],64296:[[1514],256],64297:[[43],256],64298:[[1513,1473],512],64299:[[1513,1474],512],64300:[[64329,1473],512],64301:[[64329,1474],512],64302:[[1488,1463],512],64303:[[1488,1464],512],64304:[[1488,1468],512],64305:[[1489,1468],512],64306:[[1490,1468],512],64307:[[1491,1468],512],64308:[[1492,1468],512],64309:[[1493,1468],512],64310:[[1494,1468],512],64312:[[1496,1468],512],64313:[[1497,1468],512],64314:[[1498,1468],512],64315:[[1499,1468],512],64316:[[1500,1468],512],64318:[[1502,1468],512],64320:[[1504,1468],512],64321:[[1505,1468],512],64323:[[1507,1468],512],64324:[[1508,1468],512],64326:[[1510,1468],512],64327:[[1511,1468],512],64328:[[1512,1468],512],64329:[[1513,1468],512],64330:[[1514,1468],512],64331:[[1493,1465],512],64332:[[1489,1471],512],64333:[[1499,1471],512],64334:[[1508,1471],512],64335:[[1488,1500],256],64336:[[1649],256],64337:[[1649],256],64338:[[1659],256],64339:[[1659],256],64340:[[1659],256],64341:[[1659],256],64342:[[1662],256],64343:[[1662],256],64344:[[1662],256],64345:[[1662],256],64346:[[1664],256],64347:[[1664],256],64348:[[1664],256],64349:[[1664],256],64350:[[1658],256],64351:[[1658],256],64352:[[1658],256],64353:[[1658],256],64354:[[1663],256],64355:[[1663],256],64356:[[1663],256],64357:[[1663],256],64358:[[1657],256],64359:[[1657],256],64360:[[1657],256],64361:[[1657],256],64362:[[1700],256],64363:[[1700],256],64364:[[1700],256],64365:[[1700],256],64366:[[1702],256],64367:[[1702],256],64368:[[1702],256],64369:[[1702],256],64370:[[1668],256],64371:[[1668],256],64372:[[1668],256],64373:[[1668],256],64374:[[1667],256],64375:[[1667],256],64376:[[1667],256],64377:[[1667],256],64378:[[1670],256],64379:[[1670],256],64380:[[1670],256],64381:[[1670],256],64382:[[1671],256],64383:[[1671],256],64384:[[1671],256],64385:[[1671],256],64386:[[1677],256],64387:[[1677],256],64388:[[1676],256],64389:[[1676],256],64390:[[1678],256],64391:[[1678],256],64392:[[1672],256],64393:[[1672],256],64394:[[1688],256],64395:[[1688],256],64396:[[1681],256],64397:[[1681],256],64398:[[1705],256],64399:[[1705],256],64400:[[1705],256],64401:[[1705],256],64402:[[1711],256],64403:[[1711],256],64404:[[1711],256],64405:[[1711],256],64406:[[1715],256],64407:[[1715],256],64408:[[1715],256],64409:[[1715],256],64410:[[1713],256],64411:[[1713],256],64412:[[1713],256],64413:[[1713],256],64414:[[1722],256],64415:[[1722],256],64416:[[1723],256],64417:[[1723],256],64418:[[1723],256],64419:[[1723],256],64420:[[1728],256],64421:[[1728],256],64422:[[1729],256],64423:[[1729],256],64424:[[1729],256],64425:[[1729],256],64426:[[1726],256],64427:[[1726],256],64428:[[1726],256],64429:[[1726],256],64430:[[1746],256],64431:[[1746],256],64432:[[1747],256],64433:[[1747],256],64467:[[1709],256],64468:[[1709],256],64469:[[1709],256],64470:[[1709],256],64471:[[1735],256],64472:[[1735],256],64473:[[1734],256],64474:[[1734],256],64475:[[1736],256],64476:[[1736],256],64477:[[1655],256],64478:[[1739],256],64479:[[1739],256],64480:[[1733],256],64481:[[1733],256],64482:[[1737],256],64483:[[1737],256],64484:[[1744],256],64485:[[1744],256],64486:[[1744],256],64487:[[1744],256],64488:[[1609],256],64489:[[1609],256],64490:[[1574,1575],256],64491:[[1574,1575],256],64492:[[1574,1749],256],64493:[[1574,1749],256],64494:[[1574,1608],256],64495:[[1574,1608],256],64496:[[1574,1735],256],64497:[[1574,1735],256],64498:[[1574,1734],256],64499:[[1574,1734],256],64500:[[1574,1736],256],64501:[[1574,1736],256],64502:[[1574,1744],256],64503:[[1574,1744],256],64504:[[1574,1744],256],64505:[[1574,1609],256],64506:[[1574,1609],256],64507:[[1574,1609],256],64508:[[1740],256],64509:[[1740],256],64510:[[1740],256],64511:[[1740],256]},
    64512:{64512:[[1574,1580],256],64513:[[1574,1581],256],64514:[[1574,1605],256],64515:[[1574,1609],256],64516:[[1574,1610],256],64517:[[1576,1580],256],64518:[[1576,1581],256],64519:[[1576,1582],256],64520:[[1576,1605],256],64521:[[1576,1609],256],64522:[[1576,1610],256],64523:[[1578,1580],256],64524:[[1578,1581],256],64525:[[1578,1582],256],64526:[[1578,1605],256],64527:[[1578,1609],256],64528:[[1578,1610],256],64529:[[1579,1580],256],64530:[[1579,1605],256],64531:[[1579,1609],256],64532:[[1579,1610],256],64533:[[1580,1581],256],64534:[[1580,1605],256],64535:[[1581,1580],256],64536:[[1581,1605],256],64537:[[1582,1580],256],64538:[[1582,1581],256],64539:[[1582,1605],256],64540:[[1587,1580],256],64541:[[1587,1581],256],64542:[[1587,1582],256],64543:[[1587,1605],256],64544:[[1589,1581],256],64545:[[1589,1605],256],64546:[[1590,1580],256],64547:[[1590,1581],256],64548:[[1590,1582],256],64549:[[1590,1605],256],64550:[[1591,1581],256],64551:[[1591,1605],256],64552:[[1592,1605],256],64553:[[1593,1580],256],64554:[[1593,1605],256],64555:[[1594,1580],256],64556:[[1594,1605],256],64557:[[1601,1580],256],64558:[[1601,1581],256],64559:[[1601,1582],256],64560:[[1601,1605],256],64561:[[1601,1609],256],64562:[[1601,1610],256],64563:[[1602,1581],256],64564:[[1602,1605],256],64565:[[1602,1609],256],64566:[[1602,1610],256],64567:[[1603,1575],256],64568:[[1603,1580],256],64569:[[1603,1581],256],64570:[[1603,1582],256],64571:[[1603,1604],256],64572:[[1603,1605],256],64573:[[1603,1609],256],64574:[[1603,1610],256],64575:[[1604,1580],256],64576:[[1604,1581],256],64577:[[1604,1582],256],64578:[[1604,1605],256],64579:[[1604,1609],256],64580:[[1604,1610],256],64581:[[1605,1580],256],64582:[[1605,1581],256],64583:[[1605,1582],256],64584:[[1605,1605],256],64585:[[1605,1609],256],64586:[[1605,1610],256],64587:[[1606,1580],256],64588:[[1606,1581],256],64589:[[1606,1582],256],64590:[[1606,1605],256],64591:[[1606,1609],256],64592:[[1606,1610],256],64593:[[1607,1580],256],64594:[[1607,1605],256],64595:[[1607,1609],256],64596:[[1607,1610],256],64597:[[1610,1580],256],64598:[[1610,1581],256],64599:[[1610,1582],256],64600:[[1610,1605],256],64601:[[1610,1609],256],64602:[[1610,1610],256],64603:[[1584,1648],256],64604:[[1585,1648],256],64605:[[1609,1648],256],64606:[[32,1612,1617],256],64607:[[32,1613,1617],256],64608:[[32,1614,1617],256],64609:[[32,1615,1617],256],64610:[[32,1616,1617],256],64611:[[32,1617,1648],256],64612:[[1574,1585],256],64613:[[1574,1586],256],64614:[[1574,1605],256],64615:[[1574,1606],256],64616:[[1574,1609],256],64617:[[1574,1610],256],64618:[[1576,1585],256],64619:[[1576,1586],256],64620:[[1576,1605],256],64621:[[1576,1606],256],64622:[[1576,1609],256],64623:[[1576,1610],256],64624:[[1578,1585],256],64625:[[1578,1586],256],64626:[[1578,1605],256],64627:[[1578,1606],256],64628:[[1578,1609],256],64629:[[1578,1610],256],64630:[[1579,1585],256],64631:[[1579,1586],256],64632:[[1579,1605],256],64633:[[1579,1606],256],64634:[[1579,1609],256],64635:[[1579,1610],256],64636:[[1601,1609],256],64637:[[1601,1610],256],64638:[[1602,1609],256],64639:[[1602,1610],256],64640:[[1603,1575],256],64641:[[1603,1604],256],64642:[[1603,1605],256],64643:[[1603,1609],256],64644:[[1603,1610],256],64645:[[1604,1605],256],64646:[[1604,1609],256],64647:[[1604,1610],256],64648:[[1605,1575],256],64649:[[1605,1605],256],64650:[[1606,1585],256],64651:[[1606,1586],256],64652:[[1606,1605],256],64653:[[1606,1606],256],64654:[[1606,1609],256],64655:[[1606,1610],256],64656:[[1609,1648],256],64657:[[1610,1585],256],64658:[[1610,1586],256],64659:[[1610,1605],256],64660:[[1610,1606],256],64661:[[1610,1609],256],64662:[[1610,1610],256],64663:[[1574,1580],256],64664:[[1574,1581],256],64665:[[1574,1582],256],64666:[[1574,1605],256],64667:[[1574,1607],256],64668:[[1576,1580],256],64669:[[1576,1581],256],64670:[[1576,1582],256],64671:[[1576,1605],256],64672:[[1576,1607],256],64673:[[1578,1580],256],64674:[[1578,1581],256],64675:[[1578,1582],256],64676:[[1578,1605],256],64677:[[1578,1607],256],64678:[[1579,1605],256],64679:[[1580,1581],256],64680:[[1580,1605],256],64681:[[1581,1580],256],64682:[[1581,1605],256],64683:[[1582,1580],256],64684:[[1582,1605],256],64685:[[1587,1580],256],64686:[[1587,1581],256],64687:[[1587,1582],256],64688:[[1587,1605],256],64689:[[1589,1581],256],64690:[[1589,1582],256],64691:[[1589,1605],256],64692:[[1590,1580],256],64693:[[1590,1581],256],64694:[[1590,1582],256],64695:[[1590,1605],256],64696:[[1591,1581],256],64697:[[1592,1605],256],64698:[[1593,1580],256],64699:[[1593,1605],256],64700:[[1594,1580],256],64701:[[1594,1605],256],64702:[[1601,1580],256],64703:[[1601,1581],256],64704:[[1601,1582],256],64705:[[1601,1605],256],64706:[[1602,1581],256],64707:[[1602,1605],256],64708:[[1603,1580],256],64709:[[1603,1581],256],64710:[[1603,1582],256],64711:[[1603,1604],256],64712:[[1603,1605],256],64713:[[1604,1580],256],64714:[[1604,1581],256],64715:[[1604,1582],256],64716:[[1604,1605],256],64717:[[1604,1607],256],64718:[[1605,1580],256],64719:[[1605,1581],256],64720:[[1605,1582],256],64721:[[1605,1605],256],64722:[[1606,1580],256],64723:[[1606,1581],256],64724:[[1606,1582],256],64725:[[1606,1605],256],64726:[[1606,1607],256],64727:[[1607,1580],256],64728:[[1607,1605],256],64729:[[1607,1648],256],64730:[[1610,1580],256],64731:[[1610,1581],256],64732:[[1610,1582],256],64733:[[1610,1605],256],64734:[[1610,1607],256],64735:[[1574,1605],256],64736:[[1574,1607],256],64737:[[1576,1605],256],64738:[[1576,1607],256],64739:[[1578,1605],256],64740:[[1578,1607],256],64741:[[1579,1605],256],64742:[[1579,1607],256],64743:[[1587,1605],256],64744:[[1587,1607],256],64745:[[1588,1605],256],64746:[[1588,1607],256],64747:[[1603,1604],256],64748:[[1603,1605],256],64749:[[1604,1605],256],64750:[[1606,1605],256],64751:[[1606,1607],256],64752:[[1610,1605],256],64753:[[1610,1607],256],64754:[[1600,1614,1617],256],64755:[[1600,1615,1617],256],64756:[[1600,1616,1617],256],64757:[[1591,1609],256],64758:[[1591,1610],256],64759:[[1593,1609],256],64760:[[1593,1610],256],64761:[[1594,1609],256],64762:[[1594,1610],256],64763:[[1587,1609],256],64764:[[1587,1610],256],64765:[[1588,1609],256],64766:[[1588,1610],256],64767:[[1581,1609],256]},
    64768:{64768:[[1581,1610],256],64769:[[1580,1609],256],64770:[[1580,1610],256],64771:[[1582,1609],256],64772:[[1582,1610],256],64773:[[1589,1609],256],64774:[[1589,1610],256],64775:[[1590,1609],256],64776:[[1590,1610],256],64777:[[1588,1580],256],64778:[[1588,1581],256],64779:[[1588,1582],256],64780:[[1588,1605],256],64781:[[1588,1585],256],64782:[[1587,1585],256],64783:[[1589,1585],256],64784:[[1590,1585],256],64785:[[1591,1609],256],64786:[[1591,1610],256],64787:[[1593,1609],256],64788:[[1593,1610],256],64789:[[1594,1609],256],64790:[[1594,1610],256],64791:[[1587,1609],256],64792:[[1587,1610],256],64793:[[1588,1609],256],64794:[[1588,1610],256],64795:[[1581,1609],256],64796:[[1581,1610],256],64797:[[1580,1609],256],64798:[[1580,1610],256],64799:[[1582,1609],256],64800:[[1582,1610],256],64801:[[1589,1609],256],64802:[[1589,1610],256],64803:[[1590,1609],256],64804:[[1590,1610],256],64805:[[1588,1580],256],64806:[[1588,1581],256],64807:[[1588,1582],256],64808:[[1588,1605],256],64809:[[1588,1585],256],64810:[[1587,1585],256],64811:[[1589,1585],256],64812:[[1590,1585],256],64813:[[1588,1580],256],64814:[[1588,1581],256],64815:[[1588,1582],256],64816:[[1588,1605],256],64817:[[1587,1607],256],64818:[[1588,1607],256],64819:[[1591,1605],256],64820:[[1587,1580],256],64821:[[1587,1581],256],64822:[[1587,1582],256],64823:[[1588,1580],256],64824:[[1588,1581],256],64825:[[1588,1582],256],64826:[[1591,1605],256],64827:[[1592,1605],256],64828:[[1575,1611],256],64829:[[1575,1611],256],64848:[[1578,1580,1605],256],64849:[[1578,1581,1580],256],64850:[[1578,1581,1580],256],64851:[[1578,1581,1605],256],64852:[[1578,1582,1605],256],64853:[[1578,1605,1580],256],64854:[[1578,1605,1581],256],64855:[[1578,1605,1582],256],64856:[[1580,1605,1581],256],64857:[[1580,1605,1581],256],64858:[[1581,1605,1610],256],64859:[[1581,1605,1609],256],64860:[[1587,1581,1580],256],64861:[[1587,1580,1581],256],64862:[[1587,1580,1609],256],64863:[[1587,1605,1581],256],64864:[[1587,1605,1581],256],64865:[[1587,1605,1580],256],64866:[[1587,1605,1605],256],64867:[[1587,1605,1605],256],64868:[[1589,1581,1581],256],64869:[[1589,1581,1581],256],64870:[[1589,1605,1605],256],64871:[[1588,1581,1605],256],64872:[[1588,1581,1605],256],64873:[[1588,1580,1610],256],64874:[[1588,1605,1582],256],64875:[[1588,1605,1582],256],64876:[[1588,1605,1605],256],64877:[[1588,1605,1605],256],64878:[[1590,1581,1609],256],64879:[[1590,1582,1605],256],64880:[[1590,1582,1605],256],64881:[[1591,1605,1581],256],64882:[[1591,1605,1581],256],64883:[[1591,1605,1605],256],64884:[[1591,1605,1610],256],64885:[[1593,1580,1605],256],64886:[[1593,1605,1605],256],64887:[[1593,1605,1605],256],64888:[[1593,1605,1609],256],64889:[[1594,1605,1605],256],64890:[[1594,1605,1610],256],64891:[[1594,1605,1609],256],64892:[[1601,1582,1605],256],64893:[[1601,1582,1605],256],64894:[[1602,1605,1581],256],64895:[[1602,1605,1605],256],64896:[[1604,1581,1605],256],64897:[[1604,1581,1610],256],64898:[[1604,1581,1609],256],64899:[[1604,1580,1580],256],64900:[[1604,1580,1580],256],64901:[[1604,1582,1605],256],64902:[[1604,1582,1605],256],64903:[[1604,1605,1581],256],64904:[[1604,1605,1581],256],64905:[[1605,1581,1580],256],64906:[[1605,1581,1605],256],64907:[[1605,1581,1610],256],64908:[[1605,1580,1581],256],64909:[[1605,1580,1605],256],64910:[[1605,1582,1580],256],64911:[[1605,1582,1605],256],64914:[[1605,1580,1582],256],64915:[[1607,1605,1580],256],64916:[[1607,1605,1605],256],64917:[[1606,1581,1605],256],64918:[[1606,1581,1609],256],64919:[[1606,1580,1605],256],64920:[[1606,1580,1605],256],64921:[[1606,1580,1609],256],64922:[[1606,1605,1610],256],64923:[[1606,1605,1609],256],64924:[[1610,1605,1605],256],64925:[[1610,1605,1605],256],64926:[[1576,1582,1610],256],64927:[[1578,1580,1610],256],64928:[[1578,1580,1609],256],64929:[[1578,1582,1610],256],64930:[[1578,1582,1609],256],64931:[[1578,1605,1610],256],64932:[[1578,1605,1609],256],64933:[[1580,1605,1610],256],64934:[[1580,1581,1609],256],64935:[[1580,1605,1609],256],64936:[[1587,1582,1609],256],64937:[[1589,1581,1610],256],64938:[[1588,1581,1610],256],64939:[[1590,1581,1610],256],64940:[[1604,1580,1610],256],64941:[[1604,1605,1610],256],64942:[[1610,1581,1610],256],64943:[[1610,1580,1610],256],64944:[[1610,1605,1610],256],64945:[[1605,1605,1610],256],64946:[[1602,1605,1610],256],64947:[[1606,1581,1610],256],64948:[[1602,1605,1581],256],64949:[[1604,1581,1605],256],64950:[[1593,1605,1610],256],64951:[[1603,1605,1610],256],64952:[[1606,1580,1581],256],64953:[[1605,1582,1610],256],64954:[[1604,1580,1605],256],64955:[[1603,1605,1605],256],64956:[[1604,1580,1605],256],64957:[[1606,1580,1581],256],64958:[[1580,1581,1610],256],64959:[[1581,1580,1610],256],64960:[[1605,1580,1610],256],64961:[[1601,1605,1610],256],64962:[[1576,1581,1610],256],64963:[[1603,1605,1605],256],64964:[[1593,1580,1605],256],64965:[[1589,1605,1605],256],64966:[[1587,1582,1610],256],64967:[[1606,1580,1610],256],65008:[[1589,1604,1746],256],65009:[[1602,1604,1746],256],65010:[[1575,1604,1604,1607],256],65011:[[1575,1603,1576,1585],256],65012:[[1605,1581,1605,1583],256],65013:[[1589,1604,1593,1605],256],65014:[[1585,1587,1608,1604],256],65015:[[1593,1604,1610,1607],256],65016:[[1608,1587,1604,1605],256],65017:[[1589,1604,1609],256],65018:[[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605],256],65019:[[1580,1604,32,1580,1604,1575,1604,1607],256],65020:[[1585,1740,1575,1604],256]},
    65024:{65040:[[44],256],65041:[[12289],256],65042:[[12290],256],65043:[[58],256],65044:[[59],256],65045:[[33],256],65046:[[63],256],65047:[[12310],256],65048:[[12311],256],65049:[[8230],256],65056:[,230],65057:[,230],65058:[,230],65059:[,230],65060:[,230],65061:[,230],65062:[,230],65063:[,220],65064:[,220],65065:[,220],65066:[,220],65067:[,220],65068:[,220],65069:[,220],65072:[[8229],256],65073:[[8212],256],65074:[[8211],256],65075:[[95],256],65076:[[95],256],65077:[[40],256],65078:[[41],256],65079:[[123],256],65080:[[125],256],65081:[[12308],256],65082:[[12309],256],65083:[[12304],256],65084:[[12305],256],65085:[[12298],256],65086:[[12299],256],65087:[[12296],256],65088:[[12297],256],65089:[[12300],256],65090:[[12301],256],65091:[[12302],256],65092:[[12303],256],65095:[[91],256],65096:[[93],256],65097:[[8254],256],65098:[[8254],256],65099:[[8254],256],65100:[[8254],256],65101:[[95],256],65102:[[95],256],65103:[[95],256],65104:[[44],256],65105:[[12289],256],65106:[[46],256],65108:[[59],256],65109:[[58],256],65110:[[63],256],65111:[[33],256],65112:[[8212],256],65113:[[40],256],65114:[[41],256],65115:[[123],256],65116:[[125],256],65117:[[12308],256],65118:[[12309],256],65119:[[35],256],65120:[[38],256],65121:[[42],256],65122:[[43],256],65123:[[45],256],65124:[[60],256],65125:[[62],256],65126:[[61],256],65128:[[92],256],65129:[[36],256],65130:[[37],256],65131:[[64],256],65136:[[32,1611],256],65137:[[1600,1611],256],65138:[[32,1612],256],65140:[[32,1613],256],65142:[[32,1614],256],65143:[[1600,1614],256],65144:[[32,1615],256],65145:[[1600,1615],256],65146:[[32,1616],256],65147:[[1600,1616],256],65148:[[32,1617],256],65149:[[1600,1617],256],65150:[[32,1618],256],65151:[[1600,1618],256],65152:[[1569],256],65153:[[1570],256],65154:[[1570],256],65155:[[1571],256],65156:[[1571],256],65157:[[1572],256],65158:[[1572],256],65159:[[1573],256],65160:[[1573],256],65161:[[1574],256],65162:[[1574],256],65163:[[1574],256],65164:[[1574],256],65165:[[1575],256],65166:[[1575],256],65167:[[1576],256],65168:[[1576],256],65169:[[1576],256],65170:[[1576],256],65171:[[1577],256],65172:[[1577],256],65173:[[1578],256],65174:[[1578],256],65175:[[1578],256],65176:[[1578],256],65177:[[1579],256],65178:[[1579],256],65179:[[1579],256],65180:[[1579],256],65181:[[1580],256],65182:[[1580],256],65183:[[1580],256],65184:[[1580],256],65185:[[1581],256],65186:[[1581],256],65187:[[1581],256],65188:[[1581],256],65189:[[1582],256],65190:[[1582],256],65191:[[1582],256],65192:[[1582],256],65193:[[1583],256],65194:[[1583],256],65195:[[1584],256],65196:[[1584],256],65197:[[1585],256],65198:[[1585],256],65199:[[1586],256],65200:[[1586],256],65201:[[1587],256],65202:[[1587],256],65203:[[1587],256],65204:[[1587],256],65205:[[1588],256],65206:[[1588],256],65207:[[1588],256],65208:[[1588],256],65209:[[1589],256],65210:[[1589],256],65211:[[1589],256],65212:[[1589],256],65213:[[1590],256],65214:[[1590],256],65215:[[1590],256],65216:[[1590],256],65217:[[1591],256],65218:[[1591],256],65219:[[1591],256],65220:[[1591],256],65221:[[1592],256],65222:[[1592],256],65223:[[1592],256],65224:[[1592],256],65225:[[1593],256],65226:[[1593],256],65227:[[1593],256],65228:[[1593],256],65229:[[1594],256],65230:[[1594],256],65231:[[1594],256],65232:[[1594],256],65233:[[1601],256],65234:[[1601],256],65235:[[1601],256],65236:[[1601],256],65237:[[1602],256],65238:[[1602],256],65239:[[1602],256],65240:[[1602],256],65241:[[1603],256],65242:[[1603],256],65243:[[1603],256],65244:[[1603],256],65245:[[1604],256],65246:[[1604],256],65247:[[1604],256],65248:[[1604],256],65249:[[1605],256],65250:[[1605],256],65251:[[1605],256],65252:[[1605],256],65253:[[1606],256],65254:[[1606],256],65255:[[1606],256],65256:[[1606],256],65257:[[1607],256],65258:[[1607],256],65259:[[1607],256],65260:[[1607],256],65261:[[1608],256],65262:[[1608],256],65263:[[1609],256],65264:[[1609],256],65265:[[1610],256],65266:[[1610],256],65267:[[1610],256],65268:[[1610],256],65269:[[1604,1570],256],65270:[[1604,1570],256],65271:[[1604,1571],256],65272:[[1604,1571],256],65273:[[1604,1573],256],65274:[[1604,1573],256],65275:[[1604,1575],256],65276:[[1604,1575],256]},
    65280:{65281:[[33],256],65282:[[34],256],65283:[[35],256],65284:[[36],256],65285:[[37],256],65286:[[38],256],65287:[[39],256],65288:[[40],256],65289:[[41],256],65290:[[42],256],65291:[[43],256],65292:[[44],256],65293:[[45],256],65294:[[46],256],65295:[[47],256],65296:[[48],256],65297:[[49],256],65298:[[50],256],65299:[[51],256],65300:[[52],256],65301:[[53],256],65302:[[54],256],65303:[[55],256],65304:[[56],256],65305:[[57],256],65306:[[58],256],65307:[[59],256],65308:[[60],256],65309:[[61],256],65310:[[62],256],65311:[[63],256],65312:[[64],256],65313:[[65],256],65314:[[66],256],65315:[[67],256],65316:[[68],256],65317:[[69],256],65318:[[70],256],65319:[[71],256],65320:[[72],256],65321:[[73],256],65322:[[74],256],65323:[[75],256],65324:[[76],256],65325:[[77],256],65326:[[78],256],65327:[[79],256],65328:[[80],256],65329:[[81],256],65330:[[82],256],65331:[[83],256],65332:[[84],256],65333:[[85],256],65334:[[86],256],65335:[[87],256],65336:[[88],256],65337:[[89],256],65338:[[90],256],65339:[[91],256],65340:[[92],256],65341:[[93],256],65342:[[94],256],65343:[[95],256],65344:[[96],256],65345:[[97],256],65346:[[98],256],65347:[[99],256],65348:[[100],256],65349:[[101],256],65350:[[102],256],65351:[[103],256],65352:[[104],256],65353:[[105],256],65354:[[106],256],65355:[[107],256],65356:[[108],256],65357:[[109],256],65358:[[110],256],65359:[[111],256],65360:[[112],256],65361:[[113],256],65362:[[114],256],65363:[[115],256],65364:[[116],256],65365:[[117],256],65366:[[118],256],65367:[[119],256],65368:[[120],256],65369:[[121],256],65370:[[122],256],65371:[[123],256],65372:[[124],256],65373:[[125],256],65374:[[126],256],65375:[[10629],256],65376:[[10630],256],65377:[[12290],256],65378:[[12300],256],65379:[[12301],256],65380:[[12289],256],65381:[[12539],256],65382:[[12530],256],65383:[[12449],256],65384:[[12451],256],65385:[[12453],256],65386:[[12455],256],65387:[[12457],256],65388:[[12515],256],65389:[[12517],256],65390:[[12519],256],65391:[[12483],256],65392:[[12540],256],65393:[[12450],256],65394:[[12452],256],65395:[[12454],256],65396:[[12456],256],65397:[[12458],256],65398:[[12459],256],65399:[[12461],256],65400:[[12463],256],65401:[[12465],256],65402:[[12467],256],65403:[[12469],256],65404:[[12471],256],65405:[[12473],256],65406:[[12475],256],65407:[[12477],256],65408:[[12479],256],65409:[[12481],256],65410:[[12484],256],65411:[[12486],256],65412:[[12488],256],65413:[[12490],256],65414:[[12491],256],65415:[[12492],256],65416:[[12493],256],65417:[[12494],256],65418:[[12495],256],65419:[[12498],256],65420:[[12501],256],65421:[[12504],256],65422:[[12507],256],65423:[[12510],256],65424:[[12511],256],65425:[[12512],256],65426:[[12513],256],65427:[[12514],256],65428:[[12516],256],65429:[[12518],256],65430:[[12520],256],65431:[[12521],256],65432:[[12522],256],65433:[[12523],256],65434:[[12524],256],65435:[[12525],256],65436:[[12527],256],65437:[[12531],256],65438:[[12441],256],65439:[[12442],256],65440:[[12644],256],65441:[[12593],256],65442:[[12594],256],65443:[[12595],256],65444:[[12596],256],65445:[[12597],256],65446:[[12598],256],65447:[[12599],256],65448:[[12600],256],65449:[[12601],256],65450:[[12602],256],65451:[[12603],256],65452:[[12604],256],65453:[[12605],256],65454:[[12606],256],65455:[[12607],256],65456:[[12608],256],65457:[[12609],256],65458:[[12610],256],65459:[[12611],256],65460:[[12612],256],65461:[[12613],256],65462:[[12614],256],65463:[[12615],256],65464:[[12616],256],65465:[[12617],256],65466:[[12618],256],65467:[[12619],256],65468:[[12620],256],65469:[[12621],256],65470:[[12622],256],65474:[[12623],256],65475:[[12624],256],65476:[[12625],256],65477:[[12626],256],65478:[[12627],256],65479:[[12628],256],65482:[[12629],256],65483:[[12630],256],65484:[[12631],256],65485:[[12632],256],65486:[[12633],256],65487:[[12634],256],65490:[[12635],256],65491:[[12636],256],65492:[[12637],256],65493:[[12638],256],65494:[[12639],256],65495:[[12640],256],65498:[[12641],256],65499:[[12642],256],65500:[[12643],256],65504:[[162],256],65505:[[163],256],65506:[[172],256],65507:[[175],256],65508:[[166],256],65509:[[165],256],65510:[[8361],256],65512:[[9474],256],65513:[[8592],256],65514:[[8593],256],65515:[[8594],256],65516:[[8595],256],65517:[[9632],256],65518:[[9675],256]}
    
    };
    
       /***** Module to export */
       var unorm = {
          nfc: nfc,
          nfd: nfd,
          nfkc: nfkc,
          nfkd: nfkd
       };
    
       /*globals module:true,define:true*/
    
       // CommonJS
       if (typeof module === "object") {
          module.exports = unorm;
    
       // AMD
       } else if (typeof define === "function" && define.amd) {
          define("unorm", function () {
             return unorm;
          });
    
       // Global
       } else {
          root.unorm = unorm;
       }
    
       /***** Export as shim for String::normalize method *****/
       /*
          http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#november_8_2013_draft_rev_21
    
          21.1.3.12 String.prototype.normalize(form="NFC")
          When the normalize method is called with one argument form, the following steps are taken:
    
          1. Let O be CheckObjectCoercible(this value).
          2. Let S be ToString(O).
          3. ReturnIfAbrupt(S).
          4. If form is not provided or undefined let form be "NFC".
          5. Let f be ToString(form).
          6. ReturnIfAbrupt(f).
          7. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw a RangeError Exception.
          8. Let ns be the String value is the result of normalizing S into the normalization form named by f as specified in Unicode Standard Annex #15, UnicodeNormalizatoin Forms.
          9. Return ns.
    
          The length property of the normalize method is 0.
    
          *NOTE* The normalize function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.
       */
        unorm.shimApplied = false;
    
       if (!String.prototype.normalize) {
          String.prototype.normalize = function(form) {
             var str = "" + this;
             form =  form === undefined ? "NFC" : form;
    
             if (form === "NFC") {
                return unorm.nfc(str);
             } else if (form === "NFD") {
                return unorm.nfd(str);
             } else if (form === "NFKC") {
                return unorm.nfkc(str);
             } else if (form === "NFKD") {
                return unorm.nfkd(str);
             } else {
                throw new RangeError("Invalid normalization form: " + form);
             }
          };
    
          unorm.shimApplied = true;
       }
    }(this));
    
    },{}],368:[function(require,module,exports){
    /*
     * Copyright Joyent, Inc. and other Node contributors.
     *
     * Permission is hereby granted, free of charge, to any person obtaining a
     * copy of this software and associated documentation files (the
     * "Software"), to deal in the Software without restriction, including
     * without limitation the rights to use, copy, modify, merge, publish,
     * distribute, sublicense, and/or sell copies of the Software, and to permit
     * persons to whom the Software is furnished to do so, subject to the
     * following conditions:
     *
     * The above copyright notice and this permission notice shall be included
     * in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
     * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     * USE OR OTHER DEALINGS IN THE SOFTWARE.
     */
    
    'use strict';
    
    var punycode = require('punycode');
    
    function Url() {
      this.protocol = null;
      this.slashes = null;
      this.auth = null;
      this.host = null;
      this.port = null;
      this.hostname = null;
      this.hash = null;
      this.search = null;
      this.query = null;
      this.pathname = null;
      this.path = null;
      this.href = null;
    }
    
    // Reference: RFC 3986, RFC 1808, RFC 2396
    
    /*
     * define these here so at least they only have to be
     * compiled once on the first module load.
     */
    var protocolPattern = /^([a-z0-9.+-]+:)/i,
      portPattern = /:[0-9]*$/,
    
      // Special case for a simple path URL
      simplePathPattern = /^(\/\/?(?!\/)[^?\s]*)(\?[^\s]*)?$/,
    
      /*
       * RFC 2396: characters reserved for delimiting URLs.
       * We actually just auto-escape these.
       */
      delims = [
        '<', '>', '"', '`', ' ', '\r', '\n', '\t'
      ],
    
      // RFC 2396: characters not allowed for various reasons.
      unwise = [
        '{', '}', '|', '\\', '^', '`'
      ].concat(delims),
    
      // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
      autoEscape = ['\''].concat(unwise),
      /*
       * Characters that are never ever allowed in a hostname.
       * Note that any invalid chars are also handled, but these
       * are the ones that are *expected* to be seen, so we fast-path
       * them.
       */
      nonHostChars = [
        '%', '/', '?', ';', '#'
      ].concat(autoEscape),
      hostEndingChars = [
        '/', '?', '#'
      ],
      hostnameMaxLen = 255,
      hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
      hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
      // protocols that can allow "unsafe" and "unwise" chars.
      unsafeProtocol = {
        javascript: true,
        'javascript:': true
      },
      // protocols that never have a hostname.
      hostlessProtocol = {
        javascript: true,
        'javascript:': true
      },
      // protocols that always contain a // bit.
      slashedProtocol = {
        http: true,
        https: true,
        ftp: true,
        gopher: true,
        file: true,
        'http:': true,
        'https:': true,
        'ftp:': true,
        'gopher:': true,
        'file:': true
      },
      querystring = require('qs');
    
    function urlParse(url, parseQueryString, slashesDenoteHost) {
      if (url && typeof url === 'object' && url instanceof Url) { return url; }
    
      var u = new Url();
      u.parse(url, parseQueryString, slashesDenoteHost);
      return u;
    }
    
    Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) {
      if (typeof url !== 'string') {
        throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
      }
    
      /*
       * Copy chrome, IE, opera backslash-handling behavior.
       * Back slashes before the query string get converted to forward slashes
       * See: https://code.google.com/p/chromium/issues/detail?id=25916
       */
      var queryIndex = url.indexOf('?'),
        splitter = queryIndex !== -1 && queryIndex < url.indexOf('#') ? '?' : '#',
        uSplit = url.split(splitter),
        slashRegex = /\\/g;
      uSplit[0] = uSplit[0].replace(slashRegex, '/');
      url = uSplit.join(splitter);
    
      var rest = url;
    
      /*
       * trim before proceeding.
       * This is to support parse stuff like "  http://foo.com  \n"
       */
      rest = rest.trim();
    
      if (!slashesDenoteHost && url.split('#').length === 1) {
        // Try fast path regexp
        var simplePath = simplePathPattern.exec(rest);
        if (simplePath) {
          this.path = rest;
          this.href = rest;
          this.pathname = simplePath[1];
          if (simplePath[2]) {
            this.search = simplePath[2];
            if (parseQueryString) {
              this.query = querystring.parse(this.search.substr(1));
            } else {
              this.query = this.search.substr(1);
            }
          } else if (parseQueryString) {
            this.search = '';
            this.query = {};
          }
          return this;
        }
      }
    
      var proto = protocolPattern.exec(rest);
      if (proto) {
        proto = proto[0];
        var lowerProto = proto.toLowerCase();
        this.protocol = lowerProto;
        rest = rest.substr(proto.length);
      }
    
      /*
       * figure out if it's got a host
       * user@server is *always* interpreted as a hostname, and url
       * resolution will treat //foo/bar as host=foo,path=bar because that's
       * how the browser resolves relative URLs.
       */
      if (slashesDenoteHost || proto || rest.match(/^\/\/[^@/]+@[^@/]+/)) {
        var slashes = rest.substr(0, 2) === '//';
        if (slashes && !(proto && hostlessProtocol[proto])) {
          rest = rest.substr(2);
          this.slashes = true;
        }
      }
    
      if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) {
    
        /*
         * there's a hostname.
         * the first instance of /, ?, ;, or # ends the host.
         *
         * If there is an @ in the hostname, then non-host chars *are* allowed
         * to the left of the last @ sign, unless some host-ending character
         * comes *before* the @-sign.
         * URLs are obnoxious.
         *
         * ex:
         * http://a@b@c/ => user:a@b host:c
         * http://a@b?@c => user:a host:c path:/?@c
         */
    
        /*
         * v0.12 TODO(isaacs): This is not quite how Chrome does things.
         * Review our test case against browsers more comprehensively.
         */
    
        // find the first instance of any hostEndingChars
        var hostEnd = -1;
        for (var i = 0; i < hostEndingChars.length; i++) {
          var hec = rest.indexOf(hostEndingChars[i]);
          if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
        }
    
        /*
         * at this point, either we have an explicit point where the
         * auth portion cannot go past, or the last @ char is the decider.
         */
        var auth, atSign;
        if (hostEnd === -1) {
          // atSign can be anywhere.
          atSign = rest.lastIndexOf('@');
        } else {
          /*
           * atSign must be in auth portion.
           * http://a@b/c@d => host:b auth:a path:/c@d
           */
          atSign = rest.lastIndexOf('@', hostEnd);
        }
    
        /*
         * Now we have a portion which is definitely the auth.
         * Pull that off.
         */
        if (atSign !== -1) {
          auth = rest.slice(0, atSign);
          rest = rest.slice(atSign + 1);
          this.auth = decodeURIComponent(auth);
        }
    
        // the host is the remaining to the left of the first non-host char
        hostEnd = -1;
        for (var i = 0; i < nonHostChars.length; i++) {
          var hec = rest.indexOf(nonHostChars[i]);
          if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { hostEnd = hec; }
        }
        // if we still have not hit it, then the entire thing is a host.
        if (hostEnd === -1) { hostEnd = rest.length; }
    
        this.host = rest.slice(0, hostEnd);
        rest = rest.slice(hostEnd);
    
        // pull out port.
        this.parseHost();
    
        /*
         * we've indicated that there is a hostname,
         * so even if it's empty, it has to be present.
         */
        this.hostname = this.hostname || '';
    
        /*
         * if hostname begins with [ and ends with ]
         * assume that it's an IPv6 address.
         */
        var ipv6Hostname = this.hostname[0] === '[' && this.hostname[this.hostname.length - 1] === ']';
    
        // validate a little.
        if (!ipv6Hostname) {
          var hostparts = this.hostname.split(/\./);
          for (var i = 0, l = hostparts.length; i < l; i++) {
            var part = hostparts[i];
            if (!part) { continue; }
            if (!part.match(hostnamePartPattern)) {
              var newpart = '';
              for (var j = 0, k = part.length; j < k; j++) {
                if (part.charCodeAt(j) > 127) {
                  /*
                   * we replace non-ASCII char with a temporary placeholder
                   * we need this to make sure size of hostname is not
                   * broken by replacing non-ASCII by nothing
                   */
                  newpart += 'x';
                } else {
                  newpart += part[j];
                }
              }
              // we test again with ASCII char only
              if (!newpart.match(hostnamePartPattern)) {
                var validParts = hostparts.slice(0, i);
                var notHost = hostparts.slice(i + 1);
                var bit = part.match(hostnamePartStart);
                if (bit) {
                  validParts.push(bit[1]);
                  notHost.unshift(bit[2]);
                }
                if (notHost.length) {
                  rest = '/' + notHost.join('.') + rest;
                }
                this.hostname = validParts.join('.');
                break;
              }
            }
          }
        }
    
        if (this.hostname.length > hostnameMaxLen) {
          this.hostname = '';
        } else {
          // hostnames are always lower case.
          this.hostname = this.hostname.toLowerCase();
        }
    
        if (!ipv6Hostname) {
          /*
           * IDNA Support: Returns a punycoded representation of "domain".
           * It only converts parts of the domain name that
           * have non-ASCII characters, i.e. it doesn't matter if
           * you call it with a domain that already is ASCII-only.
           */
          this.hostname = punycode.toASCII(this.hostname);
        }
    
        var p = this.port ? ':' + this.port : '';
        var h = this.hostname || '';
        this.host = h + p;
        this.href += this.host;
    
        /*
         * strip [ and ] from the hostname
         * the host field still retains them, though
         */
        if (ipv6Hostname) {
          this.hostname = this.hostname.substr(1, this.hostname.length - 2);
          if (rest[0] !== '/') {
            rest = '/' + rest;
          }
        }
      }
    
      /*
       * now rest is set to the post-host stuff.
       * chop off any delim chars.
       */
      if (!unsafeProtocol[lowerProto]) {
    
        /*
         * First, make 100% sure that any "autoEscape" chars get
         * escaped, even if encodeURIComponent doesn't think they
         * need to be.
         */
        for (var i = 0, l = autoEscape.length; i < l; i++) {
          var ae = autoEscape[i];
          if (rest.indexOf(ae) === -1) { continue; }
          var esc = encodeURIComponent(ae);
          if (esc === ae) {
            esc = escape(ae);
          }
          rest = rest.split(ae).join(esc);
        }
      }
    
      // chop off from the tail first.
      var hash = rest.indexOf('#');
      if (hash !== -1) {
        // got a fragment string.
        this.hash = rest.substr(hash);
        rest = rest.slice(0, hash);
      }
      var qm = rest.indexOf('?');
      if (qm !== -1) {
        this.search = rest.substr(qm);
        this.query = rest.substr(qm + 1);
        if (parseQueryString) {
          this.query = querystring.parse(this.query);
        }
        rest = rest.slice(0, qm);
      } else if (parseQueryString) {
        // no query string, but parseQueryString still requested
        this.search = '';
        this.query = {};
      }
      if (rest) { this.pathname = rest; }
      if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) {
        this.pathname = '/';
      }
    
      // to support http.request
      if (this.pathname || this.search) {
        var p = this.pathname || '';
        var s = this.search || '';
        this.path = p + s;
      }
    
      // finally, reconstruct the href based on what has been validated.
      this.href = this.format();
      return this;
    };
    
    // format a parsed object into a url string
    function urlFormat(obj) {
      /*
       * ensure it's an object, and not a string url.
       * If it's an obj, this is a no-op.
       * this way, you can call url_format() on strings
       * to clean up potentially wonky urls.
       */
      if (typeof obj === 'string') { obj = urlParse(obj); }
      if (!(obj instanceof Url)) { return Url.prototype.format.call(obj); }
      return obj.format();
    }
    
    Url.prototype.format = function () {
      var auth = this.auth || '';
      if (auth) {
        auth = encodeURIComponent(auth);
        auth = auth.replace(/%3A/i, ':');
        auth += '@';
      }
    
      var protocol = this.protocol || '',
        pathname = this.pathname || '',
        hash = this.hash || '',
        host = false,
        query = '';
    
      if (this.host) {
        host = auth + this.host;
      } else if (this.hostname) {
        host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']');
        if (this.port) {
          host += ':' + this.port;
        }
      }
    
      if (this.query && typeof this.query === 'object' && Object.keys(this.query).length) {
        query = querystring.stringify(this.query, {
          arrayFormat: 'repeat',
          addQueryPrefix: false
        });
      }
    
      var search = this.search || (query && ('?' + query)) || '';
    
      if (protocol && protocol.substr(-1) !== ':') { protocol += ':'; }
    
      /*
       * only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
       * unless they had them to begin with.
       */
      if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) {
        host = '//' + (host || '');
        if (pathname && pathname.charAt(0) !== '/') { pathname = '/' + pathname; }
      } else if (!host) {
        host = '';
      }
    
      if (hash && hash.charAt(0) !== '#') { hash = '#' + hash; }
      if (search && search.charAt(0) !== '?') { search = '?' + search; }
    
      pathname = pathname.replace(/[?#]/g, function (match) {
        return encodeURIComponent(match);
      });
      search = search.replace('#', '%23');
    
      return protocol + host + pathname + search + hash;
    };
    
    function urlResolve(source, relative) {
      return urlParse(source, false, true).resolve(relative);
    }
    
    Url.prototype.resolve = function (relative) {
      return this.resolveObject(urlParse(relative, false, true)).format();
    };
    
    function urlResolveObject(source, relative) {
      if (!source) { return relative; }
      return urlParse(source, false, true).resolveObject(relative);
    }
    
    Url.prototype.resolveObject = function (relative) {
      if (typeof relative === 'string') {
        var rel = new Url();
        rel.parse(relative, false, true);
        relative = rel;
      }
    
      var result = new Url();
      var tkeys = Object.keys(this);
      for (var tk = 0; tk < tkeys.length; tk++) {
        var tkey = tkeys[tk];
        result[tkey] = this[tkey];
      }
    
      /*
       * hash is always overridden, no matter what.
       * even href="" will remove it.
       */
      result.hash = relative.hash;
    
      // if the relative url is empty, then there's nothing left to do here.
      if (relative.href === '') {
        result.href = result.format();
        return result;
      }
    
      // hrefs like //foo/bar always cut to the protocol.
      if (relative.slashes && !relative.protocol) {
        // take everything except the protocol from relative
        var rkeys = Object.keys(relative);
        for (var rk = 0; rk < rkeys.length; rk++) {
          var rkey = rkeys[rk];
          if (rkey !== 'protocol') { result[rkey] = relative[rkey]; }
        }
    
        // urlParse appends trailing / to urls like http://www.example.com
        if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) {
          result.pathname = '/';
          result.path = result.pathname;
        }
    
        result.href = result.format();
        return result;
      }
    
      if (relative.protocol && relative.protocol !== result.protocol) {
        /*
         * if it's a known url protocol, then changing
         * the protocol does weird things
         * first, if it's not file:, then we MUST have a host,
         * and if there was a path
         * to begin with, then we MUST have a path.
         * if it is file:, then the host is dropped,
         * because that's known to be hostless.
         * anything else is assumed to be absolute.
         */
        if (!slashedProtocol[relative.protocol]) {
          var keys = Object.keys(relative);
          for (var v = 0; v < keys.length; v++) {
            var k = keys[v];
            result[k] = relative[k];
          }
          result.href = result.format();
          return result;
        }
    
        result.protocol = relative.protocol;
        if (!relative.host && !hostlessProtocol[relative.protocol]) {
          var relPath = (relative.pathname || '').split('/');
          while (relPath.length && !(relative.host = relPath.shift())) { }
          if (!relative.host) { relative.host = ''; }
          if (!relative.hostname) { relative.hostname = ''; }
          if (relPath[0] !== '') { relPath.unshift(''); }
          if (relPath.length < 2) { relPath.unshift(''); }
          result.pathname = relPath.join('/');
        } else {
          result.pathname = relative.pathname;
        }
        result.search = relative.search;
        result.query = relative.query;
        result.host = relative.host || '';
        result.auth = relative.auth;
        result.hostname = relative.hostname || relative.host;
        result.port = relative.port;
        // to support http.request
        if (result.pathname || result.search) {
          var p = result.pathname || '';
          var s = result.search || '';
          result.path = p + s;
        }
        result.slashes = result.slashes || relative.slashes;
        result.href = result.format();
        return result;
      }
    
      var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/',
        isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/',
        mustEndAbs = isRelAbs || isSourceAbs || (result.host && relative.pathname),
        removeAllDots = mustEndAbs,
        srcPath = result.pathname && result.pathname.split('/') || [],
        relPath = relative.pathname && relative.pathname.split('/') || [],
        psychotic = result.protocol && !slashedProtocol[result.protocol];
    
      /*
       * if the url is a non-slashed url, then relative
       * links like ../.. should be able
       * to crawl up to the hostname, as well.  This is strange.
       * result.protocol has already been set by now.
       * Later on, put the first path part into the host field.
       */
      if (psychotic) {
        result.hostname = '';
        result.port = null;
        if (result.host) {
          if (srcPath[0] === '') { srcPath[0] = result.host; } else { srcPath.unshift(result.host); }
        }
        result.host = '';
        if (relative.protocol) {
          relative.hostname = null;
          relative.port = null;
          if (relative.host) {
            if (relPath[0] === '') { relPath[0] = relative.host; } else { relPath.unshift(relative.host); }
          }
          relative.host = null;
        }
        mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
      }
    
      if (isRelAbs) {
        // it's absolute.
        result.host = relative.host || relative.host === '' ? relative.host : result.host;
        result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname;
        result.search = relative.search;
        result.query = relative.query;
        srcPath = relPath;
        // fall through to the dot-handling below.
      } else if (relPath.length) {
        /*
         * it's relative
         * throw away the existing file, and take the new path instead.
         */
        if (!srcPath) { srcPath = []; }
        srcPath.pop();
        srcPath = srcPath.concat(relPath);
        result.search = relative.search;
        result.query = relative.query;
      } else if (relative.search != null) {
        /*
         * just pull out the search.
         * like href='?foo'.
         * Put this after the other two cases because it simplifies the booleans
         */
        if (psychotic) {
          result.host = srcPath.shift();
          result.hostname = result.host;
          /*
           * occationaly the auth can get stuck only in host
           * this especially happens in cases like
           * url.resolveObject('mailto:local1@domain1', 'local2@domain2')
           */
          var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
          if (authInHost) {
            result.auth = authInHost.shift();
            result.hostname = authInHost.shift();
            result.host = result.hostname;
          }
        }
        result.search = relative.search;
        result.query = relative.query;
        // to support http.request
        if (result.pathname !== null || result.search !== null) {
          result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
        }
        result.href = result.format();
        return result;
      }
    
      if (!srcPath.length) {
        /*
         * no path at all.  easy.
         * we've already handled the other stuff above.
         */
        result.pathname = null;
        // to support http.request
        if (result.search) {
          result.path = '/' + result.search;
        } else {
          result.path = null;
        }
        result.href = result.format();
        return result;
      }
    
      /*
       * if a url ENDs in . or .., then it must get a trailing slash.
       * however, if it ends in anything else non-slashy,
       * then it must NOT get a trailing slash.
       */
      var last = srcPath.slice(-1)[0];
      var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === '';
    
      /*
       * strip single dots, resolve double dots to parent dir
       * if the path tries to go above the root, `up` ends up > 0
       */
      var up = 0;
      for (var i = srcPath.length; i >= 0; i--) {
        last = srcPath[i];
        if (last === '.') {
          srcPath.splice(i, 1);
        } else if (last === '..') {
          srcPath.splice(i, 1);
          up++;
        } else if (up) {
          srcPath.splice(i, 1);
          up--;
        }
      }
    
      // if the path is allowed to go above the root, restore leading ..s
      if (!mustEndAbs && !removeAllDots) {
        for (; up--; up) {
          srcPath.unshift('..');
        }
      }
    
      if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
        srcPath.unshift('');
      }
    
      if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
        srcPath.push('');
      }
    
      var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/');
    
      // put the host back
      if (psychotic) {
        result.hostname = isAbsolute ? '' : srcPath.length ? srcPath.shift() : '';
        result.host = result.hostname;
        /*
         * occationaly the auth can get stuck only in host
         * this especially happens in cases like
         * url.resolveObject('mailto:local1@domain1', 'local2@domain2')
         */
        var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false;
        if (authInHost) {
          result.auth = authInHost.shift();
          result.hostname = authInHost.shift();
          result.host = result.hostname;
        }
      }
    
      mustEndAbs = mustEndAbs || (result.host && srcPath.length);
    
      if (mustEndAbs && !isAbsolute) {
        srcPath.unshift('');
      }
    
      if (srcPath.length > 0) {
        result.pathname = srcPath.join('/');
      } else {
        result.pathname = null;
        result.path = null;
      }
    
      // to support request.http
      if (result.pathname !== null || result.search !== null) {
        result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : '');
      }
      result.auth = relative.auth || result.auth;
      result.slashes = result.slashes || relative.slashes;
      result.href = result.format();
      return result;
    };
    
    Url.prototype.parseHost = function () {
      var host = this.host;
      var port = portPattern.exec(host);
      if (port) {
        port = port[0];
        if (port !== ':') {
          this.port = port.substr(1);
        }
        host = host.substr(0, host.length - port.length);
      }
      if (host) { this.hostname = host; }
    };
    
    exports.parse = urlParse;
    exports.resolve = urlResolve;
    exports.resolveObject = urlResolveObject;
    exports.format = urlFormat;
    
    exports.Url = Url;
    
    },{"punycode":328,"qs":330}],369:[function(require,module,exports){
    (function (global){(function (){
    
    /**
     * Module exports.
     */
    
    module.exports = deprecate;
    
    /**
     * Mark that a method should not be used.
     * Returns a modified function which warns once by default.
     *
     * If `localStorage.noDeprecation = true` is set, then it is a no-op.
     *
     * If `localStorage.throwDeprecation = true` is set, then deprecated functions
     * will throw an Error when invoked.
     *
     * If `localStorage.traceDeprecation = true` is set, then deprecated functions
     * will invoke `console.trace()` instead of `console.error()`.
     *
     * @param {Function} fn - the function to deprecate
     * @param {String} msg - the string to print to the console when `fn` is invoked
     * @returns {Function} a new "deprecated" version of `fn`
     * @api public
     */
    
    function deprecate (fn, msg) {
      if (config('noDeprecation')) {
        return fn;
      }
    
      var warned = false;
      function deprecated() {
        if (!warned) {
          if (config('throwDeprecation')) {
            throw new Error(msg);
          } else if (config('traceDeprecation')) {
            console.trace(msg);
          } else {
            console.warn(msg);
          }
          warned = true;
        }
        return fn.apply(this, arguments);
      }
    
      return deprecated;
    }
    
    /**
     * Checks `localStorage` for boolean values for the given `name`.
     *
     * @param {String} name
     * @returns {Boolean}
     * @api private
     */
    
    function config (name) {
      // accessing global.localStorage can trigger a DOMException in sandboxed iframes
      try {
        if (!global.localStorage) return false;
      } catch (_) {
        return false;
      }
      var val = global.localStorage[name];
      if (null == val) return false;
      return String(val).toLowerCase() === 'true';
    }
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{}],370:[function(require,module,exports){
    arguments[4][26][0].apply(exports,arguments)
    },{"dup":26}],371:[function(require,module,exports){
    // Currently in sync with Node.js lib/internal/util/types.js
    // https://github.com/nodejs/node/commit/112cc7c27551254aa2b17098fb774867f05ed0d9
    
    'use strict';
    
    var isArgumentsObject = require('is-arguments');
    var isGeneratorFunction = require('is-generator-function');
    var whichTypedArray = require('which-typed-array');
    var isTypedArray = require('is-typed-array');
    
    function uncurryThis(f) {
      return f.call.bind(f);
    }
    
    var BigIntSupported = typeof BigInt !== 'undefined';
    var SymbolSupported = typeof Symbol !== 'undefined';
    
    var ObjectToString = uncurryThis(Object.prototype.toString);
    
    var numberValue = uncurryThis(Number.prototype.valueOf);
    var stringValue = uncurryThis(String.prototype.valueOf);
    var booleanValue = uncurryThis(Boolean.prototype.valueOf);
    
    if (BigIntSupported) {
      var bigIntValue = uncurryThis(BigInt.prototype.valueOf);
    }
    
    if (SymbolSupported) {
      var symbolValue = uncurryThis(Symbol.prototype.valueOf);
    }
    
    function checkBoxedPrimitive(value, prototypeValueOf) {
      if (typeof value !== 'object') {
        return false;
      }
      try {
        prototypeValueOf(value);
        return true;
      } catch(e) {
        return false;
      }
    }
    
    exports.isArgumentsObject = isArgumentsObject;
    exports.isGeneratorFunction = isGeneratorFunction;
    exports.isTypedArray = isTypedArray;
    
    // Taken from here and modified for better browser support
    // https://github.com/sindresorhus/p-is-promise/blob/cda35a513bda03f977ad5cde3a079d237e82d7ef/index.js
    function isPromise(input) {
        return (
            (
                typeof Promise !== 'undefined' &&
                input instanceof Promise
            ) ||
            (
                input !== null &&
                typeof input === 'object' &&
                typeof input.then === 'function' &&
                typeof input.catch === 'function'
            )
        );
    }
    exports.isPromise = isPromise;
    
    function isArrayBufferView(value) {
      if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
        return ArrayBuffer.isView(value);
      }
    
      return (
        isTypedArray(value) ||
        isDataView(value)
      );
    }
    exports.isArrayBufferView = isArrayBufferView;
    
    
    function isUint8Array(value) {
      return whichTypedArray(value) === 'Uint8Array';
    }
    exports.isUint8Array = isUint8Array;
    
    function isUint8ClampedArray(value) {
      return whichTypedArray(value) === 'Uint8ClampedArray';
    }
    exports.isUint8ClampedArray = isUint8ClampedArray;
    
    function isUint16Array(value) {
      return whichTypedArray(value) === 'Uint16Array';
    }
    exports.isUint16Array = isUint16Array;
    
    function isUint32Array(value) {
      return whichTypedArray(value) === 'Uint32Array';
    }
    exports.isUint32Array = isUint32Array;
    
    function isInt8Array(value) {
      return whichTypedArray(value) === 'Int8Array';
    }
    exports.isInt8Array = isInt8Array;
    
    function isInt16Array(value) {
      return whichTypedArray(value) === 'Int16Array';
    }
    exports.isInt16Array = isInt16Array;
    
    function isInt32Array(value) {
      return whichTypedArray(value) === 'Int32Array';
    }
    exports.isInt32Array = isInt32Array;
    
    function isFloat32Array(value) {
      return whichTypedArray(value) === 'Float32Array';
    }
    exports.isFloat32Array = isFloat32Array;
    
    function isFloat64Array(value) {
      return whichTypedArray(value) === 'Float64Array';
    }
    exports.isFloat64Array = isFloat64Array;
    
    function isBigInt64Array(value) {
      return whichTypedArray(value) === 'BigInt64Array';
    }
    exports.isBigInt64Array = isBigInt64Array;
    
    function isBigUint64Array(value) {
      return whichTypedArray(value) === 'BigUint64Array';
    }
    exports.isBigUint64Array = isBigUint64Array;
    
    function isMapToString(value) {
      return ObjectToString(value) === '[object Map]';
    }
    isMapToString.working = (
      typeof Map !== 'undefined' &&
      isMapToString(new Map())
    );
    
    function isMap(value) {
      if (typeof Map === 'undefined') {
        return false;
      }
    
      return isMapToString.working
        ? isMapToString(value)
        : value instanceof Map;
    }
    exports.isMap = isMap;
    
    function isSetToString(value) {
      return ObjectToString(value) === '[object Set]';
    }
    isSetToString.working = (
      typeof Set !== 'undefined' &&
      isSetToString(new Set())
    );
    function isSet(value) {
      if (typeof Set === 'undefined') {
        return false;
      }
    
      return isSetToString.working
        ? isSetToString(value)
        : value instanceof Set;
    }
    exports.isSet = isSet;
    
    function isWeakMapToString(value) {
      return ObjectToString(value) === '[object WeakMap]';
    }
    isWeakMapToString.working = (
      typeof WeakMap !== 'undefined' &&
      isWeakMapToString(new WeakMap())
    );
    function isWeakMap(value) {
      if (typeof WeakMap === 'undefined') {
        return false;
      }
    
      return isWeakMapToString.working
        ? isWeakMapToString(value)
        : value instanceof WeakMap;
    }
    exports.isWeakMap = isWeakMap;
    
    function isWeakSetToString(value) {
      return ObjectToString(value) === '[object WeakSet]';
    }
    isWeakSetToString.working = (
      typeof WeakSet !== 'undefined' &&
      isWeakSetToString(new WeakSet())
    );
    function isWeakSet(value) {
      return isWeakSetToString(value);
    }
    exports.isWeakSet = isWeakSet;
    
    function isArrayBufferToString(value) {
      return ObjectToString(value) === '[object ArrayBuffer]';
    }
    isArrayBufferToString.working = (
      typeof ArrayBuffer !== 'undefined' &&
      isArrayBufferToString(new ArrayBuffer())
    );
    function isArrayBuffer(value) {
      if (typeof ArrayBuffer === 'undefined') {
        return false;
      }
    
      return isArrayBufferToString.working
        ? isArrayBufferToString(value)
        : value instanceof ArrayBuffer;
    }
    exports.isArrayBuffer = isArrayBuffer;
    
    function isDataViewToString(value) {
      return ObjectToString(value) === '[object DataView]';
    }
    isDataViewToString.working = (
      typeof ArrayBuffer !== 'undefined' &&
      typeof DataView !== 'undefined' &&
      isDataViewToString(new DataView(new ArrayBuffer(1), 0, 1))
    );
    function isDataView(value) {
      if (typeof DataView === 'undefined') {
        return false;
      }
    
      return isDataViewToString.working
        ? isDataViewToString(value)
        : value instanceof DataView;
    }
    exports.isDataView = isDataView;
    
    // Store a copy of SharedArrayBuffer in case it's deleted elsewhere
    var SharedArrayBufferCopy = typeof SharedArrayBuffer !== 'undefined' ? SharedArrayBuffer : undefined;
    function isSharedArrayBufferToString(value) {
      return ObjectToString(value) === '[object SharedArrayBuffer]';
    }
    function isSharedArrayBuffer(value) {
      if (typeof SharedArrayBufferCopy === 'undefined') {
        return false;
      }
    
      if (typeof isSharedArrayBufferToString.working === 'undefined') {
        isSharedArrayBufferToString.working = isSharedArrayBufferToString(new SharedArrayBufferCopy());
      }
    
      return isSharedArrayBufferToString.working
        ? isSharedArrayBufferToString(value)
        : value instanceof SharedArrayBufferCopy;
    }
    exports.isSharedArrayBuffer = isSharedArrayBuffer;
    
    function isAsyncFunction(value) {
      return ObjectToString(value) === '[object AsyncFunction]';
    }
    exports.isAsyncFunction = isAsyncFunction;
    
    function isMapIterator(value) {
      return ObjectToString(value) === '[object Map Iterator]';
    }
    exports.isMapIterator = isMapIterator;
    
    function isSetIterator(value) {
      return ObjectToString(value) === '[object Set Iterator]';
    }
    exports.isSetIterator = isSetIterator;
    
    function isGeneratorObject(value) {
      return ObjectToString(value) === '[object Generator]';
    }
    exports.isGeneratorObject = isGeneratorObject;
    
    function isWebAssemblyCompiledModule(value) {
      return ObjectToString(value) === '[object WebAssembly.Module]';
    }
    exports.isWebAssemblyCompiledModule = isWebAssemblyCompiledModule;
    
    function isNumberObject(value) {
      return checkBoxedPrimitive(value, numberValue);
    }
    exports.isNumberObject = isNumberObject;
    
    function isStringObject(value) {
      return checkBoxedPrimitive(value, stringValue);
    }
    exports.isStringObject = isStringObject;
    
    function isBooleanObject(value) {
      return checkBoxedPrimitive(value, booleanValue);
    }
    exports.isBooleanObject = isBooleanObject;
    
    function isBigIntObject(value) {
      return BigIntSupported && checkBoxedPrimitive(value, bigIntValue);
    }
    exports.isBigIntObject = isBigIntObject;
    
    function isSymbolObject(value) {
      return SymbolSupported && checkBoxedPrimitive(value, symbolValue);
    }
    exports.isSymbolObject = isSymbolObject;
    
    function isBoxedPrimitive(value) {
      return (
        isNumberObject(value) ||
        isStringObject(value) ||
        isBooleanObject(value) ||
        isBigIntObject(value) ||
        isSymbolObject(value)
      );
    }
    exports.isBoxedPrimitive = isBoxedPrimitive;
    
    function isAnyArrayBuffer(value) {
      return typeof Uint8Array !== 'undefined' && (
        isArrayBuffer(value) ||
        isSharedArrayBuffer(value)
      );
    }
    exports.isAnyArrayBuffer = isAnyArrayBuffer;
    
    ['isProxy', 'isExternal', 'isModuleNamespaceObject'].forEach(function(method) {
      Object.defineProperty(exports, method, {
        enumerable: false,
        value: function() {
          throw new Error(method + ' is not supported in userland');
        }
      });
    });
    
    },{"is-arguments":183,"is-generator-function":186,"is-typed-array":187,"which-typed-array":373}],372:[function(require,module,exports){
    (function (process){(function (){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors ||
      function getOwnPropertyDescriptors(obj) {
        var keys = Object.keys(obj);
        var descriptors = {};
        for (var i = 0; i < keys.length; i++) {
          descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]);
        }
        return descriptors;
      };
    
    var formatRegExp = /%[sdj%]/g;
    exports.format = function(f) {
      if (!isString(f)) {
        var objects = [];
        for (var i = 0; i < arguments.length; i++) {
          objects.push(inspect(arguments[i]));
        }
        return objects.join(' ');
      }
    
      var i = 1;
      var args = arguments;
      var len = args.length;
      var str = String(f).replace(formatRegExp, function(x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch (x) {
          case '%s': return String(args[i++]);
          case '%d': return Number(args[i++]);
          case '%j':
            try {
              return JSON.stringify(args[i++]);
            } catch (_) {
              return '[Circular]';
            }
          default:
            return x;
        }
      });
      for (var x = args[i]; i < len; x = args[++i]) {
        if (isNull(x) || !isObject(x)) {
          str += ' ' + x;
        } else {
          str += ' ' + inspect(x);
        }
      }
      return str;
    };
    
    
    // Mark that a method should not be used.
    // Returns a modified function which warns once by default.
    // If --no-deprecation is set, then it is a no-op.
    exports.deprecate = function(fn, msg) {
      if (typeof process !== 'undefined' && process.noDeprecation === true) {
        return fn;
      }
    
      // Allow for deprecating things in the process of starting up.
      if (typeof process === 'undefined') {
        return function() {
          return exports.deprecate(fn, msg).apply(this, arguments);
        };
      }
    
      var warned = false;
      function deprecated() {
        if (!warned) {
          if (process.throwDeprecation) {
            throw new Error(msg);
          } else if (process.traceDeprecation) {
            console.trace(msg);
          } else {
            console.error(msg);
          }
          warned = true;
        }
        return fn.apply(this, arguments);
      }
    
      return deprecated;
    };
    
    
    var debugs = {};
    var debugEnvRegex = /^$/;
    
    if (process.env.NODE_DEBUG) {
      var debugEnv = process.env.NODE_DEBUG;
      debugEnv = debugEnv.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')
        .replace(/\*/g, '.*')
        .replace(/,/g, '$|^')
        .toUpperCase();
      debugEnvRegex = new RegExp('^' + debugEnv + '$', 'i');
    }
    exports.debuglog = function(set) {
      set = set.toUpperCase();
      if (!debugs[set]) {
        if (debugEnvRegex.test(set)) {
          var pid = process.pid;
          debugs[set] = function() {
            var msg = exports.format.apply(exports, arguments);
            console.error('%s %d: %s', set, pid, msg);
          };
        } else {
          debugs[set] = function() {};
        }
      }
      return debugs[set];
    };
    
    
    /**
     * Echos the value of a value. Trys to print the value out
     * in the best way possible given the different types.
     *
     * @param {Object} obj The object to print out.
     * @param {Object} opts Optional options object that alters the output.
     */
    /* legacy: obj, showHidden, depth, colors*/
    function inspect(obj, opts) {
      // default options
      var ctx = {
        seen: [],
        stylize: stylizeNoColor
      };
      // legacy...
      if (arguments.length >= 3) ctx.depth = arguments[2];
      if (arguments.length >= 4) ctx.colors = arguments[3];
      if (isBoolean(opts)) {
        // legacy...
        ctx.showHidden = opts;
      } else if (opts) {
        // got an "options" object
        exports._extend(ctx, opts);
      }
      // set default options
      if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
      if (isUndefined(ctx.depth)) ctx.depth = 2;
      if (isUndefined(ctx.colors)) ctx.colors = false;
      if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
      if (ctx.colors) ctx.stylize = stylizeWithColor;
      return formatValue(ctx, obj, ctx.depth);
    }
    exports.inspect = inspect;
    
    
    // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
    inspect.colors = {
      'bold' : [1, 22],
      'italic' : [3, 23],
      'underline' : [4, 24],
      'inverse' : [7, 27],
      'white' : [37, 39],
      'grey' : [90, 39],
      'black' : [30, 39],
      'blue' : [34, 39],
      'cyan' : [36, 39],
      'green' : [32, 39],
      'magenta' : [35, 39],
      'red' : [31, 39],
      'yellow' : [33, 39]
    };
    
    // Don't use 'blue' not visible on cmd.exe
    inspect.styles = {
      'special': 'cyan',
      'number': 'yellow',
      'boolean': 'yellow',
      'undefined': 'grey',
      'null': 'bold',
      'string': 'green',
      'date': 'magenta',
      // "name": intentionally not styling
      'regexp': 'red'
    };
    
    
    function stylizeWithColor(str, styleType) {
      var style = inspect.styles[styleType];
    
      if (style) {
        return '\u001b[' + inspect.colors[style][0] + 'm' + str +
               '\u001b[' + inspect.colors[style][1] + 'm';
      } else {
        return str;
      }
    }
    
    
    function stylizeNoColor(str, styleType) {
      return str;
    }
    
    
    function arrayToHash(array) {
      var hash = {};
    
      array.forEach(function(val, idx) {
        hash[val] = true;
      });
    
      return hash;
    }
    
    
    function formatValue(ctx, value, recurseTimes) {
      // Provide a hook for user-specified inspect functions.
      // Check that value is an object with an inspect function on it
      if (ctx.customInspect &&
          value &&
          isFunction(value.inspect) &&
          // Filter out the util module, it's inspect function is special
          value.inspect !== exports.inspect &&
          // Also filter out any prototype objects using the circular check.
          !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) {
          ret = formatValue(ctx, ret, recurseTimes);
        }
        return ret;
      }
    
      // Primitive types cannot have properties
      var primitive = formatPrimitive(ctx, value);
      if (primitive) {
        return primitive;
      }
    
      // Look up the keys of the object.
      var keys = Object.keys(value);
      var visibleKeys = arrayToHash(keys);
    
      if (ctx.showHidden) {
        keys = Object.getOwnPropertyNames(value);
      }
    
      // IE doesn't make error fields non-enumerable
      // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
      if (isError(value)
          && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
        return formatError(value);
      }
    
      // Some type of object without properties can be shortcutted.
      if (keys.length === 0) {
        if (isFunction(value)) {
          var name = value.name ? ': ' + value.name : '';
          return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        }
        if (isDate(value)) {
          return ctx.stylize(Date.prototype.toString.call(value), 'date');
        }
        if (isError(value)) {
          return formatError(value);
        }
      }
    
      var base = '', array = false, braces = ['{', '}'];
    
      // Make Array say that they are Array
      if (isArray(value)) {
        array = true;
        braces = ['[', ']'];
      }
    
      // Make functions say that they are functions
      if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
      }
    
      // Make RegExps say that they are RegExps
      if (isRegExp(value)) {
        base = ' ' + RegExp.prototype.toString.call(value);
      }
    
      // Make dates with properties first say the date
      if (isDate(value)) {
        base = ' ' + Date.prototype.toUTCString.call(value);
      }
    
      // Make error with message first say the error
      if (isError(value)) {
        base = ' ' + formatError(value);
      }
    
      if (keys.length === 0 && (!array || value.length == 0)) {
        return braces[0] + base + braces[1];
      }
    
      if (recurseTimes < 0) {
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        } else {
          return ctx.stylize('[Object]', 'special');
        }
      }
    
      ctx.seen.push(value);
    
      var output;
      if (array) {
        output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
      } else {
        output = keys.map(function(key) {
          return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
        });
      }
    
      ctx.seen.pop();
    
      return reduceToSingleString(output, base, braces);
    }
    
    
    function formatPrimitive(ctx, value) {
      if (isUndefined(value))
        return ctx.stylize('undefined', 'undefined');
      if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                                 .replace(/'/g, "\\'")
                                                 .replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
      }
      if (isNumber(value))
        return ctx.stylize('' + value, 'number');
      if (isBoolean(value))
        return ctx.stylize('' + value, 'boolean');
      // For some reason typeof null is "object", so special case here.
      if (isNull(value))
        return ctx.stylize('null', 'null');
    }
    
    
    function formatError(value) {
      return '[' + Error.prototype.toString.call(value) + ']';
    }
    
    
    function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
      var output = [];
      for (var i = 0, l = value.length; i < l; ++i) {
        if (hasOwnProperty(value, String(i))) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              String(i), true));
        } else {
          output.push('');
        }
      }
      keys.forEach(function(key) {
        if (!key.match(/^\d+$/)) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              key, true));
        }
      });
      return output;
    }
    
    
    function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
      var name, str, desc;
      desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
      if (desc.get) {
        if (desc.set) {
          str = ctx.stylize('[Getter/Setter]', 'special');
        } else {
          str = ctx.stylize('[Getter]', 'special');
        }
      } else {
        if (desc.set) {
          str = ctx.stylize('[Setter]', 'special');
        }
      }
      if (!hasOwnProperty(visibleKeys, key)) {
        name = '[' + key + ']';
      }
      if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
          if (isNull(recurseTimes)) {
            str = formatValue(ctx, desc.value, null);
          } else {
            str = formatValue(ctx, desc.value, recurseTimes - 1);
          }
          if (str.indexOf('\n') > -1) {
            if (array) {
              str = str.split('\n').map(function(line) {
                return '  ' + line;
              }).join('\n').slice(2);
            } else {
              str = '\n' + str.split('\n').map(function(line) {
                return '   ' + line;
              }).join('\n');
            }
          }
        } else {
          str = ctx.stylize('[Circular]', 'special');
        }
      }
      if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) {
          return str;
        }
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
          name = name.slice(1, -1);
          name = ctx.stylize(name, 'name');
        } else {
          name = name.replace(/'/g, "\\'")
                     .replace(/\\"/g, '"')
                     .replace(/(^"|"$)/g, "'");
          name = ctx.stylize(name, 'string');
        }
      }
    
      return name + ': ' + str;
    }
    
    
    function reduceToSingleString(output, base, braces) {
      var numLinesEst = 0;
      var length = output.reduce(function(prev, cur) {
        numLinesEst++;
        if (cur.indexOf('\n') >= 0) numLinesEst++;
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
      }, 0);
    
      if (length > 60) {
        return braces[0] +
               (base === '' ? '' : base + '\n ') +
               ' ' +
               output.join(',\n  ') +
               ' ' +
               braces[1];
      }
    
      return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
    }
    
    
    // NOTE: These type checking functions intentionally don't use `instanceof`
    // because it is fragile and can be easily faked with `Object.create()`.
    exports.types = require('./support/types');
    
    function isArray(ar) {
      return Array.isArray(ar);
    }
    exports.isArray = isArray;
    
    function isBoolean(arg) {
      return typeof arg === 'boolean';
    }
    exports.isBoolean = isBoolean;
    
    function isNull(arg) {
      return arg === null;
    }
    exports.isNull = isNull;
    
    function isNullOrUndefined(arg) {
      return arg == null;
    }
    exports.isNullOrUndefined = isNullOrUndefined;
    
    function isNumber(arg) {
      return typeof arg === 'number';
    }
    exports.isNumber = isNumber;
    
    function isString(arg) {
      return typeof arg === 'string';
    }
    exports.isString = isString;
    
    function isSymbol(arg) {
      return typeof arg === 'symbol';
    }
    exports.isSymbol = isSymbol;
    
    function isUndefined(arg) {
      return arg === void 0;
    }
    exports.isUndefined = isUndefined;
    
    function isRegExp(re) {
      return isObject(re) && objectToString(re) === '[object RegExp]';
    }
    exports.isRegExp = isRegExp;
    exports.types.isRegExp = isRegExp;
    
    function isObject(arg) {
      return typeof arg === 'object' && arg !== null;
    }
    exports.isObject = isObject;
    
    function isDate(d) {
      return isObject(d) && objectToString(d) === '[object Date]';
    }
    exports.isDate = isDate;
    exports.types.isDate = isDate;
    
    function isError(e) {
      return isObject(e) &&
          (objectToString(e) === '[object Error]' || e instanceof Error);
    }
    exports.isError = isError;
    exports.types.isNativeError = isError;
    
    function isFunction(arg) {
      return typeof arg === 'function';
    }
    exports.isFunction = isFunction;
    
    function isPrimitive(arg) {
      return arg === null ||
             typeof arg === 'boolean' ||
             typeof arg === 'number' ||
             typeof arg === 'string' ||
             typeof arg === 'symbol' ||  // ES6 symbol
             typeof arg === 'undefined';
    }
    exports.isPrimitive = isPrimitive;
    
    exports.isBuffer = require('./support/isBuffer');
    
    function objectToString(o) {
      return Object.prototype.toString.call(o);
    }
    
    
    function pad(n) {
      return n < 10 ? '0' + n.toString(10) : n.toString(10);
    }
    
    
    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
                  'Oct', 'Nov', 'Dec'];
    
    // 26 Feb 16:19:34
    function timestamp() {
      var d = new Date();
      var time = [pad(d.getHours()),
                  pad(d.getMinutes()),
                  pad(d.getSeconds())].join(':');
      return [d.getDate(), months[d.getMonth()], time].join(' ');
    }
    
    
    // log is just a thin wrapper to console.log that prepends a timestamp
    exports.log = function() {
      console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
    };
    
    
    /**
     * Inherit the prototype methods from one constructor into another.
     *
     * The Function.prototype.inherits from lang.js rewritten as a standalone
     * function (not on Function.prototype). NOTE: If this file is to be loaded
     * during bootstrapping this function needs to be rewritten using some native
     * functions as prototype setup using normal JavaScript does not work as
     * expected during bootstrapping (see mirror.js in r114903).
     *
     * @param {function} ctor Constructor function which needs to inherit the
     *     prototype.
     * @param {function} superCtor Constructor function to inherit prototype from.
     */
    exports.inherits = require('inherits');
    
    exports._extend = function(origin, add) {
      // Don't do anything if add isn't an object
      if (!add || !isObject(add)) return origin;
    
      var keys = Object.keys(add);
      var i = keys.length;
      while (i--) {
        origin[keys[i]] = add[keys[i]];
      }
      return origin;
    };
    
    function hasOwnProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }
    
    var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
    
    exports.promisify = function promisify(original) {
      if (typeof original !== 'function')
        throw new TypeError('The "original" argument must be of type Function');
    
      if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
        var fn = original[kCustomPromisifiedSymbol];
        if (typeof fn !== 'function') {
          throw new TypeError('The "util.promisify.custom" argument must be of type Function');
        }
        Object.defineProperty(fn, kCustomPromisifiedSymbol, {
          value: fn, enumerable: false, writable: false, configurable: true
        });
        return fn;
      }
    
      function fn() {
        var promiseResolve, promiseReject;
        var promise = new Promise(function (resolve, reject) {
          promiseResolve = resolve;
          promiseReject = reject;
        });
    
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
        args.push(function (err, value) {
          if (err) {
            promiseReject(err);
          } else {
            promiseResolve(value);
          }
        });
    
        try {
          original.apply(this, args);
        } catch (err) {
          promiseReject(err);
        }
    
        return promise;
      }
    
      Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
    
      if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, {
        value: fn, enumerable: false, writable: false, configurable: true
      });
      return Object.defineProperties(
        fn,
        getOwnPropertyDescriptors(original)
      );
    }
    
    exports.promisify.custom = kCustomPromisifiedSymbol
    
    function callbackifyOnRejected(reason, cb) {
      // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
      // Because `null` is a special error value in callbacks which means "no error
      // occurred", we error-wrap so the callback consumer can distinguish between
      // "the promise rejected with null" or "the promise fulfilled with undefined".
      if (!reason) {
        var newReason = new Error('Promise was rejected with a falsy value');
        newReason.reason = reason;
        reason = newReason;
      }
      return cb(reason);
    }
    
    function callbackify(original) {
      if (typeof original !== 'function') {
        throw new TypeError('The "original" argument must be of type Function');
      }
    
      // We DO NOT return the promise as it gives the user a false sense that
      // the promise is actually somehow related to the callback's execution
      // and that the callback throwing will reject the promise.
      function callbackified() {
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
    
        var maybeCb = args.pop();
        if (typeof maybeCb !== 'function') {
          throw new TypeError('The last argument must be of type Function');
        }
        var self = this;
        var cb = function() {
          return maybeCb.apply(self, arguments);
        };
        // In true node style we process the callback on `nextTick` with all the
        // implications (stack, `uncaughtException`, `async_hooks`)
        original.apply(this, args)
          .then(function(ret) { process.nextTick(cb.bind(null, null, ret)) },
                function(rej) { process.nextTick(callbackifyOnRejected.bind(null, rej, cb)) });
      }
    
      Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));
      Object.defineProperties(callbackified,
                              getOwnPropertyDescriptors(original));
      return callbackified;
    }
    exports.callbackify = callbackify;
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./support/isBuffer":370,"./support/types":371,"_process":321,"inherits":182}],373:[function(require,module,exports){
    (function (global){(function (){
    'use strict';
    
    var forEach = require('for-each');
    var availableTypedArrays = require('available-typed-arrays');
    var callBind = require('call-bind');
    var callBound = require('call-bind/callBound');
    var gOPD = require('gopd');
    
    var $toString = callBound('Object.prototype.toString');
    var hasToStringTag = require('has-tostringtag/shams')();
    
    var g = typeof globalThis === 'undefined' ? global : globalThis;
    var typedArrays = availableTypedArrays();
    
    var $slice = callBound('String.prototype.slice');
    var getPrototypeOf = Object.getPrototypeOf; // require('getprototypeof');
    
    var $indexOf = callBound('Array.prototype.indexOf', true) || function indexOf(array, value) {
        for (var i = 0; i < array.length; i += 1) {
            if (array[i] === value) {
                return i;
            }
        }
        return -1;
    };
    var cache = { __proto__: null };
    if (hasToStringTag && gOPD && getPrototypeOf) {
        forEach(typedArrays, function (typedArray) {
            var arr = new g[typedArray]();
            if (Symbol.toStringTag in arr) {
                var proto = getPrototypeOf(arr);
                var descriptor = gOPD(proto, Symbol.toStringTag);
                if (!descriptor) {
                    var superProto = getPrototypeOf(proto);
                    descriptor = gOPD(superProto, Symbol.toStringTag);
                }
                cache['$' + typedArray] = callBind(descriptor.get);
            }
        });
    } else {
        forEach(typedArrays, function (typedArray) {
            var arr = new g[typedArray]();
            cache['$' + typedArray] = callBind(arr.slice);
        });
    }
    
    var tryTypedArrays = function tryAllTypedArrays(value) {
        var found = false;
        forEach(cache, function (getter, typedArray) {
            if (!found) {
                try {
                    if ('$' + getter(value) === typedArray) {
                        found = $slice(typedArray, 1);
                    }
                } catch (e) { /**/ }
            }
        });
        return found;
    };
    
    var trySlices = function tryAllSlices(value) {
        var found = false;
        forEach(cache, function (getter, name) {
            if (!found) {
                try {
                    getter(value);
                    found = $slice(name, 1);
                } catch (e) { /**/ }
            }
        });
        return found;
    };
    
    module.exports = function whichTypedArray(value) {
        if (!value || typeof value !== 'object') { return false; }
        if (!hasToStringTag) {
            var tag = $slice($toString(value), 8, -1);
            if ($indexOf(typedArrays, tag) > -1) {
                return tag;
            }
            if (tag !== 'Object') {
                return false;
            }
            // node < 0.6 hits here on real Typed Arrays
            return trySlices(value);
        }
        if (!gOPD) { return null; } // unknown engine
        return tryTypedArrays(value);
    };
    
    }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    
    },{"available-typed-arrays":28,"call-bind":89,"call-bind/callBound":88,"for-each":136,"gopd":145,"has-tostringtag/shams":149}],374:[function(require,module,exports){
    // Returns a wrapper function that returns a wrapped callback
    // The wrapper function should do some stuff, and return a
    // presumably different callback function.
    // This makes sure that own properties are retained, so that
    // decorations and such are not lost along the way.
    module.exports = wrappy
    function wrappy (fn, cb) {
      if (fn && cb) return wrappy(fn)(cb)
    
      if (typeof fn !== 'function')
        throw new TypeError('need wrapper function')
    
      Object.keys(fn).forEach(function (k) {
        wrapper[k] = fn[k]
      })
    
      return wrapper
    
      function wrapper() {
        var args = new Array(arguments.length)
        for (var i = 0; i < args.length; i++) {
          args[i] = arguments[i]
        }
        var ret = fn.apply(this, args)
        var cb = args[args.length-1]
        if (typeof ret === 'function' && ret !== cb) {
          Object.keys(cb).forEach(function (k) {
            ret[k] = cb[k]
          })
        }
        return ret
      }
    }
    
    },{}],375:[function(require,module,exports){
    arguments[4][36][0].apply(exports,arguments)
    },{"dup":36}],376:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.APIMVC = void 0;
    const mvc = require("../mvc");
    const error_1 = require("../common/error");
    const net_1 = require("../net");
    const index_1 = require("./index");
    class APIMVC {
        constructor(apiNet, serverBase) {
            this.network = apiNet;
            if (apiNet == index_1.API_NET.MAIN) {
                this.serverBase = 'https://api.microvisionchain.com/open-api-mvc';
            }
            else {
                this.serverBase = 'https://mvcapi-testnet.cyber3.space';
            }
            if (serverBase) {
                this.serverBase = serverBase;
            }
        }
        authorize(options) {
            const { authorization, privateKey } = options;
            if (authorization) {
                if (authorization.indexOf('Bearer') != 0) {
                    this.authorization = `Bearer ${authorization}`;
                }
                else {
                    this.authorization = authorization;
                }
            }
            else {
                //https://github.com/metasv/metasv-client-signature
                this.privateKey = new mvc.PrivateKey(privateKey);
                this.publicKey = this.privateKey.toPublicKey();
            }
        }
        _getHeaders(path) {
            let headers = {};
            if (this.authorization) {
                headers = { authorization: this.authorization };
            }
            else if (this.privateKey) {
                const timestamp = Date.now();
                const nonce = Math.random().toString().substring(2, 12);
                const message = path + '_' + timestamp + '_' + nonce;
                const hash = mvc.crypto.Hash.sha256(Buffer.from(message));
                const sig = mvc.crypto.ECDSA.sign(hash, this.privateKey);
                const sigEncoded = sig.toBuffer().toString('base64');
                headers = {
                    'MetaSV-Timestamp': timestamp,
                    'MetaSV-Client-Pubkey': this.publicKey.toHex(),
                    'MetaSV-Nonce': nonce,
                    'MetaSV-Signature': sigEncoded,
                };
            }
            else {
                headers = {};
                // throw new CodeError(
                //   ErrCode.EC_SENSIBLE_API_ERROR,
                //   'MetaSV should be authorized to access api.'
                // )
            }
            headers.accept = 'application/json';
            return headers;
        }
        /**
         * @param {string} address
         * @param {?string} [flag]
         * @note finished
         */
        getUnspents(address, flag) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/utxo`;
                if (flag) {
                    path += `?flag=${flag}`;
                }
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                let ret = _res
                    .map((v) => ({
                    txId: v.txid,
                    outputIndex: v.outIndex,
                    satoshis: v.value,
                    address: address,
                    height: v.height,
                    flag: v.flag,
                }))
                    .filter((v) => Number(v.satoshis) > 1);
                return ret;
            });
        }
        getVins(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/vin/${txid}/detail`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * @param {string} hex
         * @note finished
         */
        broadcast(hex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/broadcast`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpPost(url, {
                    hex,
                }, {
                    headers: this._getHeaders(path),
                });
                if (!_res.txid) {
                    console.log(`广播出错：${_res.message.toString()}`);
                    throw new Error('broadcast error ' + _res.message.toString());
                }
                return _res.txid;
            });
        }
        /**
         * @param address
         * @note finished
         */
        getBalance(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return {
                    balance: _res.confirmed,
                    pendingBalance: _res.unconfirmed,
                };
            });
        }
        /**
         * @param {string} txid
         */
        getRawTxData(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                // let path = `/tx/${txid}/raw`
                let url = `https://www.metalet.space/wallet-api/v4/mvc/tx/raw`;
                let _res = yield net_1.Net.httpGet(url, {
                    net: this.network,
                    txId: txid,
                }, {});
                return _res.data.hex;
            });
        }
        /**
         * 快速查询txid是否存在
         * @param {string} txid
         */
        checkTxSeen(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/${txid}/seen`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * 通过FT合约CodeHash+溯源genesis获取某地址的utxo列表
         * @note finished
         */
        getFungibleTokenUnspents(codehash, genesis, address, size = 10) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {
                    codeHash: codehash,
                    genesis,
                }, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenAmount: v.valueString,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某FT的余额
         * @note finished
         */
        getFungibleTokenBalance(codehash, genesis, address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = {
                    balance: '0',
                    pendingBalance: '0',
                    utxoCount: 0,
                    decimal: 0,
                };
                if (_res.length > 0) {
                    ret = {
                        balance: _res[0].confirmedString,
                        pendingBalance: _res[0].unconfirmedString,
                        utxoCount: _res[0].utxoCount,
                        decimal: _res[0].decimal,
                    };
                }
                return ret;
            });
        }
        /**
         * 查询某人持有的FT Token列表。获得每个token的余额
         * @note finished
         */
        getFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let data = [];
                _res.forEach((v) => {
                    data.push({
                        codehash: v.codeHash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        symbol: v.symbol,
                        decimal: v.decimal,
                        balance: v.confirmedString,
                        pendingBalance: v.unconfirmedString,
                    });
                });
                return data;
            });
        }
        /**
         * 通过NFT合约CodeHash+溯源genesis获取某地址的utxo列表
         */
        getNonFungibleTokenUnspents(codehash, genesis, address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某NFT的UTXO
         */
        getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: v.address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }))[0];
                return ret;
            });
        }
        /**
         * 查询某人持有的所有NFT Token列表。获得持有的nft数量计数
         * @param {String} address
         * @returns
         */
        getNonFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/nft/summary/${address}`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, `request api failed. [url]:${url} [msg]:${msg}`);
                }
                let ret = [];
                data.forEach((v) => {
                    ret.push({
                        codehash: v.codehash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        count: v.count,
                        pendingCount: v.pendingCount,
                        metaTxId: v.metaTxId,
                        metaOutputIndex: v.metaOutputIndex,
                        supply: v.supply,
                    });
                });
                return ret;
            });
        }
        getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => {
                    return includesNotReady || v.isReady == true;
                })
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    contractAddress: v.contractAddress,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellList(codehash, genesis, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellListByAddress(address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    // .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash: v.codeHash,
                    genesis: v.genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }));
                return ret;
            });
        }
        getOutpointSpent(txId, index) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/tx/${txId}/out/${index}/spent`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    return null;
                }
                if (!data)
                    return null;
                return {
                    spentTxId: data.txid,
                    spentInputIndex: data.idx,
                };
            });
        }
        getXpubLiteUtxo(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/utxo`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
        getXpubLiteBalance(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/balance`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
    }
    exports.APIMVC = APIMVC;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/error":388,"../mvc":440,"../net":443,"./index":380,"buffer":84}],377:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.CYBER3 = void 0;
    const mvc = require("../mvc");
    const error_1 = require("../common/error");
    const net_1 = require("../net");
    const index_1 = require("./index");
    class CYBER3 {
        constructor(apiNet, serverBase) {
            this.network = apiNet;
            if (apiNet == index_1.API_NET.MAIN) {
                this.serverBase = 'https://mvcapi.cyber3.space';
            }
            else {
                this.serverBase = 'https://mvcapi-testnet.cyber3.space';
            }
            if (serverBase) {
                this.serverBase = serverBase;
            }
        }
        authorize(options) {
            const { authorization, privateKey } = options;
            if (authorization) {
                if (authorization.indexOf('Bearer') != 0) {
                    this.authorization = `Bearer ${authorization}`;
                }
                else {
                    this.authorization = authorization;
                }
            }
            else {
                //https://github.com/metasv/metasv-client-signature
                this.privateKey = new mvc.PrivateKey(privateKey);
                this.publicKey = this.privateKey.toPublicKey();
            }
        }
        _getHeaders(path) {
            let headers = {};
            if (this.authorization) {
                headers = { authorization: this.authorization };
            }
            else if (this.privateKey) {
                const timestamp = Date.now();
                const nonce = Math.random().toString().substring(2, 12);
                const message = path + '_' + timestamp + '_' + nonce;
                const hash = mvc.crypto.Hash.sha256(Buffer.from(message));
                const sig = mvc.crypto.ECDSA.sign(hash, this.privateKey);
                const sigEncoded = sig.toBuffer().toString('base64');
                headers = {
                    'MetaSV-Timestamp': timestamp,
                    'MetaSV-Client-Pubkey': this.publicKey.toHex(),
                    'MetaSV-Nonce': nonce,
                    'MetaSV-Signature': sigEncoded,
                };
            }
            else {
                headers = {};
                // throw new CodeError(
                //   ErrCode.EC_SENSIBLE_API_ERROR,
                //   'MetaSV should be authorized to access api.'
                // )
            }
            headers.accept = 'application/json';
            return headers;
        }
        /**
         * @param {string} address
         * @param {?string} [flag]
         * @note finished
         */
        getUnspents(address, flag) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/utxo`;
                if (flag) {
                    path += `?flag=${flag}`;
                }
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                let ret = _res
                    .map((v) => ({
                    txId: v.txid,
                    outputIndex: v.outIndex,
                    satoshis: v.value,
                    address: address,
                    height: v.height,
                    flag: v.flag,
                }))
                    .filter((v) => Number(v.satoshis) > 1);
                return ret;
            });
        }
        getVins(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/vin/${txid}/detail`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * @param {string} hex
         * @note finished
         */
        broadcast(hex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/broadcast`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpPost(url, {
                    hex,
                }, {
                    headers: this._getHeaders(path),
                });
                if (!_res.txid) {
                    console.log(`广播出错：${_res.message.toString()}`);
                    throw new Error('broadcast error ' + _res.message.toString());
                }
                return _res.txid;
            });
        }
        /**
         * @param address
         * @note finished
         */
        getBalance(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return {
                    balance: _res.confirmed,
                    pendingBalance: _res.unconfirmed,
                };
            });
        }
        /**
         * @param {string} txid
         */
        getRawTxData(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                // let path = `/tx/${txid}/raw`
                let url = `https://www.metalet.space/wallet-api/v4/mvc/tx/raw`;
                let _res = yield net_1.Net.httpGet(url, {
                    net: this.network,
                    txId: txid,
                }, {});
                return _res.data.hex;
            });
        }
        /**
         * 快速查询txid是否存在
         * @param {string} txid
         */
        checkTxSeen(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/${txid}/seen`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * 通过FT合约CodeHash+溯源genesis获取某地址的utxo列表
         * @note finished
         */
        getFungibleTokenUnspents(codehash, genesis, address, size = 10) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {
                    codeHash: codehash,
                    genesis,
                }, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenAmount: v.valueString,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某FT的余额
         * @note finished
         */
        getFungibleTokenBalance(codehash, genesis, address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = {
                    balance: '0',
                    pendingBalance: '0',
                    utxoCount: 0,
                    decimal: 0,
                };
                if (_res.length > 0) {
                    ret = {
                        balance: _res[0].confirmedString,
                        pendingBalance: _res[0].unconfirmedString,
                        utxoCount: _res[0].utxoCount,
                        decimal: _res[0].decimal,
                    };
                }
                return ret;
            });
        }
        /**
         * 查询某人持有的FT Token列表。获得每个token的余额
         * @note finished
         */
        getFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let data = [];
                _res.forEach((v) => {
                    data.push({
                        codehash: v.codeHash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        symbol: v.symbol,
                        decimal: v.decimal,
                        balance: v.confirmedString,
                        pendingBalance: v.unconfirmedString,
                    });
                });
                return data;
            });
        }
        /**
         * 通过NFT合约CodeHash+溯源genesis获取某地址的utxo列表
         */
        getNonFungibleTokenUnspents(codehash, genesis, address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某NFT的UTXO
         */
        getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: v.address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }))[0];
                return ret;
            });
        }
        /**
         * 查询某人持有的所有NFT Token列表。获得持有的nft数量计数
         * @param {String} address
         * @returns
         */
        getNonFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/nft/summary/${address}`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, `request api failed. [url]:${url} [msg]:${msg}`);
                }
                let ret = [];
                data.forEach((v) => {
                    ret.push({
                        codehash: v.codehash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        count: v.count,
                        pendingCount: v.pendingCount,
                        metaTxId: v.metaTxId,
                        metaOutputIndex: v.metaOutputIndex,
                        supply: v.supply,
                    });
                });
                return ret;
            });
        }
        getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => {
                    return includesNotReady || v.isReady == true;
                })
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    contractAddress: v.contractAddress,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellList(codehash, genesis, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellListByAddress(address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    // .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash: v.codeHash,
                    genesis: v.genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }));
                return ret;
            });
        }
        getOutpointSpent(txId, index) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/tx/${txId}/out/${index}/spent`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    return null;
                }
                if (!data)
                    return null;
                return {
                    spentTxId: data.txid,
                    spentInputIndex: data.idx,
                };
            });
        }
        getXpubLiteUtxo(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/utxo`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
        getXpubLiteBalance(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/balance`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
    }
    exports.CYBER3 = CYBER3;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/error":388,"../mvc":440,"../net":443,"./index":380,"buffer":84}],378:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.METALET = void 0;
    const mvc = require("../mvc");
    const error_1 = require("../common/error");
    const net_1 = require("../net");
    const index_1 = require("./index");
    class METALET {
        constructor(apiNet, serverBase) {
            this.network = apiNet;
            if (apiNet == index_1.API_NET.MAIN) {
                this.serverBase = 'https://mvcapi.cyber3.space';
            }
            else {
                this.serverBase = 'https://mvcapi-testnet.cyber3.space';
            }
            if (serverBase) {
                this.serverBase = serverBase;
            }
        }
        authorize(options) {
            const { authorization, privateKey } = options;
            if (authorization) {
                if (authorization.indexOf('Bearer') != 0) {
                    this.authorization = `Bearer ${authorization}`;
                }
                else {
                    this.authorization = authorization;
                }
            }
            else {
                //https://github.com/metasv/metasv-client-signature
                this.privateKey = new mvc.PrivateKey(privateKey);
                this.publicKey = this.privateKey.toPublicKey();
            }
        }
        _getHeaders(path) {
            let headers = {};
            if (this.authorization) {
                headers = { authorization: this.authorization };
            }
            else if (this.privateKey) {
                const timestamp = Date.now();
                const nonce = Math.random().toString().substring(2, 12);
                const message = path + '_' + timestamp + '_' + nonce;
                const hash = mvc.crypto.Hash.sha256(Buffer.from(message));
                const sig = mvc.crypto.ECDSA.sign(hash, this.privateKey);
                const sigEncoded = sig.toBuffer().toString('base64');
                headers = {
                    'MetaSV-Timestamp': timestamp,
                    'MetaSV-Client-Pubkey': this.publicKey.toHex(),
                    'MetaSV-Nonce': nonce,
                    'MetaSV-Signature': sigEncoded,
                };
            }
            else {
                headers = {};
                // throw new CodeError(
                //   ErrCode.EC_SENSIBLE_API_ERROR,
                //   'MetaSV should be authorized to access api.'
                // )
            }
            headers.accept = 'application/json';
            return headers;
        }
        /**
         * @param {string} address
         * @param {?string} [flag]
         * @note finished
         */
        getUnspents(address, flag) {
            return __awaiter(this, void 0, void 0, function* () {
                // let path = `/address/${address}/utxo`
                let path = `/mvc/address/utxo-list?net=${this.network}&address=${address}`;
                if (flag) {
                    path += `&flag=${flag}`;
                }
                let url = 'https://www.metalet.space/wallet-api/v4' + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.data.list
                    .map((v) => ({
                    txId: v.txid,
                    outputIndex: v.outIndex,
                    satoshis: v.value,
                    address: address,
                    height: v.height,
                    flag: v.flag,
                }))
                    .filter((v) => Number(v.satoshis) > 1);
                return ret;
            });
        }
        getVins(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/vin/${txid}/detail`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * @param {string} hex
         * @note finished
         */
        broadcast(hex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/broadcast`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpPost(url, {
                    hex,
                }, {
                    headers: this._getHeaders(path),
                });
                if (!_res.txid) {
                    console.log(`广播出错：${_res.message.toString()}`);
                    throw new Error('broadcast error ' + _res.message.toString());
                }
                return _res.txid;
            });
        }
        /**
         * @param address
         * @note finished
         */
        getBalance(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return {
                    balance: _res.confirmed,
                    pendingBalance: _res.unconfirmed,
                };
            });
        }
        /**
         * @param {string} txid
         */
        getRawTxData(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                // let path = `/tx/${txid}/raw`
                let url = `https://www.metalet.space/wallet-api/v4/mvc/tx/raw`;
                let _res = yield net_1.Net.httpGet(url, {
                    net: this.network,
                    txId: txid,
                }, {});
                return _res.data.hex;
            });
        }
        /**
         * 快速查询txid是否存在
         * @param {string} txid
         */
        checkTxSeen(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/${txid}/seen`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * 通过FT合约CodeHash+溯源genesis获取某地址的utxo列表
         * @note finished
         */
        getFungibleTokenUnspents(codehash, genesis, address, size = 10) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {
                    codeHash: codehash,
                    genesis,
                }, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenAmount: v.valueString,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某FT的余额
         * @note finished
         */
        getFungibleTokenBalance(codehash, genesis, address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = {
                    balance: '0',
                    pendingBalance: '0',
                    utxoCount: 0,
                    decimal: 0,
                };
                if (_res.length > 0) {
                    ret = {
                        balance: _res[0].confirmedString,
                        pendingBalance: _res[0].unconfirmedString,
                        utxoCount: _res[0].utxoCount,
                        decimal: _res[0].decimal,
                    };
                }
                return ret;
            });
        }
        /**
         * 查询某人持有的FT Token列表。获得每个token的余额
         * @note finished
         */
        getFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let data = [];
                _res.forEach((v) => {
                    data.push({
                        codehash: v.codeHash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        symbol: v.symbol,
                        decimal: v.decimal,
                        balance: v.confirmedString,
                        pendingBalance: v.unconfirmedString,
                    });
                });
                return data;
            });
        }
        /**
         * 通过NFT合约CodeHash+溯源genesis获取某地址的utxo列表
         */
        getNonFungibleTokenUnspents(codehash, genesis, address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某NFT的UTXO
         */
        getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: v.address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }))[0];
                return ret;
            });
        }
        /**
         * 查询某人持有的所有NFT Token列表。获得持有的nft数量计数
         * @param {String} address
         * @returns
         */
        getNonFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/nft/summary/${address}`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, `request api failed. [url]:${url} [msg]:${msg}`);
                }
                let ret = [];
                data.forEach((v) => {
                    ret.push({
                        codehash: v.codehash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        count: v.count,
                        pendingCount: v.pendingCount,
                        metaTxId: v.metaTxId,
                        metaOutputIndex: v.metaOutputIndex,
                        supply: v.supply,
                    });
                });
                return ret;
            });
        }
        getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => {
                    return includesNotReady || v.isReady == true;
                })
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    contractAddress: v.contractAddress,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellList(codehash, genesis, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellListByAddress(address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    // .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash: v.codeHash,
                    genesis: v.genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }));
                return ret;
            });
        }
        getOutpointSpent(txId, index) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/tx/${txId}/out/${index}/spent`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    return null;
                }
                if (!data)
                    return null;
                return {
                    spentTxId: data.txid,
                    spentInputIndex: data.idx,
                };
            });
        }
        getXpubLiteUtxo(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/utxo`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
        getXpubLiteBalance(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/balance`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
    }
    exports.METALET = METALET;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/error":388,"../mvc":440,"../net":443,"./index":380,"buffer":84}],379:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.MVC = void 0;
    const mvc = require("../mvc");
    const error_1 = require("../common/error");
    const net_1 = require("../net");
    const index_1 = require("./index");
    class MVC {
        constructor(apiNet, serverBase) {
            if (apiNet == index_1.API_NET.MAIN) {
                this.serverBase = 'https://mainnet.mvcapi.com';
            }
            else {
                this.serverBase = 'https://testnet.mvcapi.com';
            }
            if (serverBase) {
                this.serverBase = serverBase;
            }
        }
        authorize(options) {
            const { authorization, privateKey } = options;
            if (authorization) {
                if (authorization.indexOf('Bearer') != 0) {
                    this.authorization = `Bearer ${authorization}`;
                }
                else {
                    this.authorization = authorization;
                }
            }
            else {
                //https://github.com/metasv/metasv-client-signature
                this.privateKey = new mvc.PrivateKey(privateKey);
                this.publicKey = this.privateKey.toPublicKey();
            }
        }
        _getHeaders(path) {
            let headers = {};
            if (this.authorization) {
                headers = { authorization: this.authorization };
            }
            else if (this.privateKey) {
                const timestamp = Date.now();
                const nonce = Math.random().toString().substring(2, 12);
                const message = path + '_' + timestamp + '_' + nonce;
                const hash = mvc.crypto.Hash.sha256(Buffer.from(message));
                const sig = mvc.crypto.ECDSA.sign(hash, this.privateKey);
                const sigEncoded = sig.toBuffer().toString('base64');
                headers = {
                    'MetaSV-Timestamp': timestamp,
                    'MetaSV-Client-Pubkey': this.publicKey.toHex(),
                    'MetaSV-Nonce': nonce,
                    'MetaSV-Signature': sigEncoded,
                };
            }
            else {
                headers = {};
                // throw new CodeError(
                //   ErrCode.EC_SENSIBLE_API_ERROR,
                //   'MetaSV should be authorized to access api.'
                // )
            }
            headers.accept = 'application/json';
            return headers;
        }
        /**
         * @param {string} address
         * @param {?string} [flag]
         */
        getUnspents(address, flag) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/utxo`;
                if (flag) {
                    path += `?flag=${flag}`;
                }
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.outIndex,
                    satoshis: v.value,
                    address: address,
                    height: v.height,
                    flag: v.flag,
                }));
                return ret;
            });
        }
        getVins(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/vin/${txid}/detail`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * @param {string} hex
         */
        broadcast(hex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/broadcast`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpPost(url, {
                    hex,
                }, {
                    headers: this._getHeaders(path),
                });
                if (!_res.txid) {
                    console.log(`广播出错：${_res.message.toString()}`);
                    throw new Error('broadcast error ' + _res.message.toString());
                }
                return _res.txid;
            });
        }
        /**
         * @param {string} txid
         */
        getRawTxData(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/${txid}/raw`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res.hex;
            });
        }
        /**
         * 快速查询txid是否存在
         * @param {string} txid
         */
        checkTxSeen(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/tx/${txid}/seen`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return _res;
            });
        }
        /**
         * 通过FT合约CodeHash+溯源genesis获取某地址的utxo列表
         */
        getFungibleTokenUnspents(codehash, genesis, address, size = 10) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {
                    codeHash: codehash,
                    genesis,
                }, {
                    headers: this._getHeaders(path),
                });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenAmount: v.valueString,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某FT的余额
         */
        getFungibleTokenBalance(codehash, genesis, address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = {
                    balance: '0',
                    pendingBalance: '0',
                    utxoCount: 0,
                    decimal: 0,
                };
                if (_res.length > 0) {
                    ret = {
                        balance: _res[0].confirmedString,
                        pendingBalance: _res[0].unconfirmedString,
                        utxoCount: _res[0].utxoCount,
                        decimal: _res[0].decimal,
                    };
                }
                return ret;
            });
        }
        /**
         * 查询某人持有的FT Token列表。获得每个token的余额
         */
        getFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/ft/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let data = [];
                _res.forEach((v) => {
                    data.push({
                        codehash: v.codeHash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        symbol: v.symbol,
                        decimal: v.decimal,
                        balance: v.confirmedString,
                        pendingBalance: v.unconfirmedString,
                    });
                });
                return data;
            });
        }
        /**
         * 通过NFT合约CodeHash+溯源genesis获取某地址的utxo列表
         */
        getNonFungibleTokenUnspents(codehash, genesis, address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }));
                return ret;
            });
        }
        /**
         * 查询某人持有的某NFT的UTXO
         */
        getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res.map((v) => ({
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    tokenAddress: v.address,
                    tokenIndex: v.tokenIndex,
                    metaTxId: v.metaTxid,
                    metaOutputIndex: v.metaOutputIndex,
                }))[0];
                return ret;
            });
        }
        /**
         * 查询某人持有的所有NFT Token列表。获得持有的nft数量计数
         * @param {String} address
         * @returns
         */
        getNonFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/nft/summary/${address}`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, `request api failed. [url]:${url} [msg]:${msg}`);
                }
                let ret = [];
                data.forEach((v) => {
                    ret.push({
                        codehash: v.codehash,
                        genesis: v.genesis,
                        sensibleId: v.sensibleId,
                        count: v.count,
                        pendingCount: v.pendingCount,
                        metaTxId: v.metaTxId,
                        metaOutputIndex: v.metaOutputIndex,
                        supply: v.supply,
                    });
                });
                return ret;
            });
        }
        getBalance(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/address/${address}/balance`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
                return {
                    balance: _res.confirmed,
                    pendingBalance: _res.unconfirmed,
                };
            });
        }
        getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => {
                    return includesNotReady || v.isReady == true;
                })
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    contractAddress: v.contractAddress,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellList(codehash, genesis, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/genesis/${codehash}/${genesis}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash,
                    genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }))[0];
                return ret;
            });
        }
        getNftSellListByAddress(address, cursor = 0, size = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                let path = `/contract/nft/sell/address/${address}/utxo`;
                let url = this.serverBase + path;
                let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
                let ret = _res
                    // .filter((v) => v.isReady == true)
                    .map((v) => ({
                    codehash: v.codeHash,
                    genesis: v.genesis,
                    tokenIndex: v.tokenIndex,
                    txId: v.txid,
                    outputIndex: v.txIndex,
                    sellerAddress: v.address,
                    satoshisPrice: v.price,
                    price: v.price,
                }));
                return ret;
            });
        }
        getOutpointSpent(txId, index) {
            return __awaiter(this, void 0, void 0, function* () {
                let url = `https://api.sensiblequery.com/tx/${txId}/out/${index}/spent`;
                let _res = yield net_1.Net.httpGet(url, {});
                const { code, data, msg } = _res;
                if (code != 0) {
                    return null;
                }
                if (!data)
                    return null;
                return {
                    spentTxId: data.txid,
                    spentInputIndex: data.idx,
                };
            });
        }
        getXpubLiteUtxo(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/utxo`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
        getXpubLiteBalance(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                const path = `/xpubLite/${xpub}/balance`;
                const url = this.serverBase + path;
                return yield net_1.Net.httpGet(url, {}, {
                    headers: this._getHeaders(path),
                });
            });
        }
    }
    exports.MVC = MVC;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/error":388,"../mvc":440,"../net":443,"./index":380,"buffer":84}],380:[function(require,module,exports){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.Api = exports.API_TARGET = exports.API_NET = void 0;
    const CYBER3_1 = require("./CYBER3");
    const METALET_1 = require("./METALET");
    const MVC_1 = require("./MVC");
    const APIMVC_1 = require("./APIMVC");
    var API_NET;
    (function (API_NET) {
        API_NET["MAIN"] = "mainnet";
        API_NET["TEST"] = "testnet";
    })(API_NET = exports.API_NET || (exports.API_NET = {}));
    var API_TARGET;
    (function (API_TARGET) {
        API_TARGET["MVC"] = "mvcapi";
        API_TARGET["CYBER3"] = "cyber3";
        API_TARGET["METALET"] = "metalet";
        API_TARGET["APIMVC"] = "microvisionchain";
    })(API_TARGET = exports.API_TARGET || (exports.API_TARGET = {}));
    class Api {
        constructor(apiNet, apiTarget = API_TARGET.MVC, serverBase) {
            switch (apiTarget) {
                case API_TARGET.MVC: {
                    this.apiHandler = new MVC_1.MVC(apiNet, serverBase);
                    break;
                }
                case API_TARGET.CYBER3: {
                    this.apiHandler = new CYBER3_1.CYBER3(apiNet, serverBase);
                    break;
                }
                case API_TARGET.METALET: {
                    this.apiHandler = new METALET_1.METALET(apiNet, serverBase);
                    break;
                }
                case API_TARGET.APIMVC: {
                    this.apiHandler = new APIMVC_1.APIMVC(apiNet, serverBase);
                    break;
                }
                default: {
                    // this.apiHandler = new Sensible(apiTarget, apiNet, serverBase)
                    this.apiHandler = new MVC_1.MVC(apiNet, serverBase);
                    break;
                }
            }
        }
        /**
         * Authorization to use MetaSV
         * @param options
         * @returns
         */
        authorize(options) {
            return this.apiHandler.authorize(options);
        }
        getUnspents(address, flag) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getUnspents(address, flag);
            });
        }
        getBalance(address) {
            return __awaiter(this, void 0, void 0, function* () {
                let _res = yield this.apiHandler.getBalance(address);
                return { balance: _res.balance, pendingBalance: _res.pendingBalance };
            });
        }
        getRawTxData(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getRawTxData(txid);
            });
        }
        checkTxSeen(txid) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.checkTxSeen(txid);
            });
        }
        broadcast(hex) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.broadcast(hex);
            });
        }
        getFungibleTokenUnspents(codehash, genesis, address, size) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getFungibleTokenUnspents(codehash, genesis, address, size);
            });
        }
        getFungibleTokenBalance(codehash, genesis, address) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getFungibleTokenBalance(codehash, genesis, address);
            });
        }
        getFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getFungibleTokenSummary(address);
            });
        }
        getNonFungibleTokenUnspents(codehash, genesis, address, cursor, size) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNonFungibleTokenUnspents(codehash, genesis, address, cursor, size);
            });
        }
        getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex);
            });
        }
        getNonFungibleTokenSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNonFungibleTokenSummary(address);
            });
        }
        getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNftSellUtxo(codehash, genesis, tokenIndex, includesNotReady);
            });
        }
        getNftSellList(codehash, genesis, cursor, size) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNftSellList(codehash, genesis, cursor, size);
            });
        }
        getNftSellListByAddress(address, cursor, size) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getNftSellListByAddress(address, cursor, size);
            });
        }
        getOutpointSpent(txId, index) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getOutpointSpent(txId, index);
            });
        }
        getXpubLiteUtxo(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getXpubLiteUtxo(xpub);
            });
        }
        getXpubLiteBalance(xpub) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.apiHandler.getXpubLiteBalance(xpub);
            });
        }
    }
    exports.Api = Api;
    
    },{"./APIMVC":376,"./CYBER3":377,"./METALET":378,"./MVC":379}],381:[function(require,module,exports){
    const mvc = require('../mvc');
    var BN = mvc.crypto.BN;
    module.exports = BN;
    
    },{"../mvc":440}],382:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ContractAdapter = void 0;
    const mvc_scrypt_1 = require("mvc-scrypt");
    const mvc = require("../mvc");
    class ContractAdapter {
        constructor(contract) {
            this._contract = contract;
        }
        get lockingScript() {
            return this._contract.lockingScript;
        }
        get txContext() {
            return this._contract.txContext;
        }
        get dataPart() {
            return this._contract.dataPart;
        }
        get codePart() {
            return this._contract.codePart;
        }
        setTxContext(txContext) {
            this._contract.txContext = txContext;
        }
        setDataPart(dataPart) {
            this._contract.setDataPartInASM(dataPart);
        }
        //取OP_RETURN之前的hash
        getCodeHash() {
            let codePart = this.codePart.toBuffer();
            return (0, mvc_scrypt_1.toHex)(mvc.crypto.Hash.sha256ripemd160(codePart));
        }
        //取整体的hash
        getScriptHash() {
            return (0, mvc_scrypt_1.toHex)(mvc.crypto.Hash.sha256ripemd160(this.lockingScript.toBuffer()));
        }
    }
    exports.ContractAdapter = ContractAdapter;
    
    },{"../mvc":440,"mvc-scrypt":282}],383:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.DustCalculator = void 0;
    class DustCalculator {
        constructor(dustLimitFactor, dustAmount) {
            this.dustAmount = null;
            this.dustLimitFactor = dustLimitFactor;
            this.dustAmount = dustAmount;
        }
        getDustThreshold(s) {
            if (this.dustAmount) {
                return this.dustAmount;
            }
            else {
                return Math.ceil((Math.ceil((250 * (s + 9 + 148)) / 1000) * this.dustLimitFactor) / 100);
            }
        }
    }
    exports.DustCalculator = DustCalculator;
    
    },{}],384:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.Prevouts = void 0;
    const TokenUtil = require("./tokenUtil");
    class Prevouts {
        constructor() {
            this._buf = Buffer.alloc(0);
        }
        addVout(txId, outputIndex) {
            const txidBuf = TokenUtil.getTxIdBuf(txId);
            const indexBuf = TokenUtil.getUInt32Buf(outputIndex);
            this._buf = Buffer.concat([this._buf, txidBuf, indexBuf]);
        }
        toHex() {
            return this._buf.toString('hex');
        }
    }
    exports.Prevouts = Prevouts;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"./tokenUtil":390,"buffer":84}],385:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.SizeTransaction = void 0;
    function getVariableSize(n) {
        if (n < 0xfd) {
            return 1;
        }
        else if (n < 0x10000) {
            return 2 + 1;
        }
        else if (n < 0x100000000) {
            return 3 + 1;
        }
        else if (n < 0x10000000000000000) {
            return 4 + 1;
        }
    }
    var OutputType;
    (function (OutputType) {
        OutputType[OutputType["P2PKH"] = 0] = "P2PKH";
        OutputType[OutputType["OP_RETURN"] = 1] = "OP_RETURN";
        OutputType[OutputType["OTHER"] = 2] = "OTHER";
    })(OutputType || (OutputType = {}));
    var InputType;
    (function (InputType) {
        InputType[InputType["P2PKH"] = 0] = "P2PKH";
        InputType[InputType["OTHER"] = 1] = "OTHER";
    })(InputType || (InputType = {}));
    class SizeTransaction {
        constructor(feeRate, dustCalculator) {
            this.inputs = [];
            this.outputs = [];
            this.feeRate = feeRate;
            this.dustCalculator = dustCalculator;
        }
        addInput(unlockingScriptSize, satothis) {
            this.inputs.push({
                size: unlockingScriptSize,
                type: InputType.OTHER,
                satothis,
            });
        }
        addP2PKHInput() {
            this.inputs.push({ size: 107, type: InputType.P2PKH });
        }
        addOutput(lockingScriptSize) {
            this.outputs.push({ size: lockingScriptSize, type: OutputType.OTHER });
        }
        addOpReturnOutput(lockingScriptSize) {
            this.outputs.push({ size: lockingScriptSize, type: OutputType.OP_RETURN });
        }
        addP2PKHOutput() {
            this.outputs.push({ size: 25, type: OutputType.P2PKH });
        }
        getSize() {
            let sizeSum = 0;
            sizeSum += 4; //nVersionSize
            sizeSum += 1; //vinNum(vins should not more than 255)
            this.inputs.forEach((input) => {
                sizeSum += 32; //txid
                sizeSum += 4; //outputINex
                sizeSum += getVariableSize(input.size); //unlocking script length
                sizeSum += input.size; //unlocking script
                sizeSum += 4; //nSequence
            });
            sizeSum += 1; //voutNum
            this.outputs.forEach((output) => {
                sizeSum += 8; // satothis
                sizeSum += getVariableSize(output.size); //locking script length
                sizeSum += output.size; //locking script
            });
            sizeSum += 4; //nLockTime
            return sizeSum;
        }
        getFee() {
            let fee = 0;
            fee += Math.ceil(this.getSize() * this.feeRate);
            this.inputs.forEach((input) => {
                if (input.type == InputType.OTHER) {
                    fee -= input.satothis;
                }
            });
            this.outputs.forEach((output) => {
                if (output.type == OutputType.OTHER) {
                    fee += this.dustCalculator.getDustThreshold(output.size);
                }
            });
            if (fee < 0)
                return 0;
            return Math.ceil(fee);
        }
    }
    exports.SizeTransaction = SizeTransaction;
    
    },{}],386:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.checkArgument = void 0;
    const error_1 = require("./error");
    function checkArgument(condition, message) {
        if (!condition) {
            throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, `Invalid Argument: ` + message);
        }
    }
    exports.checkArgument = checkArgument;
    
    },{"./error":388}],387:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.dummyRabinPubKeyHashArray = exports.dummyRabinPubKey = exports.dummyPadding = exports.dummyPayload = exports.dummySigBE = exports.dummyTx = exports.dummyCodehash = exports.dummyPk = exports.dummyAddress = exports.dummyPrivateKey = exports.dummyTxId = void 0;
    const token_proto_1 = require("../mcp02/contract-proto/token.proto");
    const bn_js_1 = require("../bn.js");
    const mvc = require("../mvc");
    const TokenUtil = require("./tokenUtil");
    const network = 'mainnet';
    exports.dummyTxId = 'c776133a77886693ba2484fe12d6bdfb8f8bcb7a237e4a8a6d0f69c7d1879a08';
    exports.dummyPrivateKey = mvc.PrivateKey.fromWIF('L5k7xi4diSR8aWoGKojSNTnc3YMEXEoNpJEaGzqWimdKry6CFrzz');
    exports.dummyAddress = exports.dummyPrivateKey.toAddress(network);
    exports.dummyPk = exports.dummyPrivateKey.toPublicKey();
    exports.dummyCodehash = exports.dummyPk;
    exports.dummyTx = new mvc.Transaction('010000000146a476c09fa48d0db861dc5c9e28dc11f9262a89d057a03d8896e93458b82e0f010000006a47304402200b70b1feb364ffe0245c78a2d163fca4bfd808976acbbb3579ba71807bd9b307022074bf5058166902632987e68a3fc6e0d6e36def18c7c184acd50dfedfa72830d9412103ac3f50a7670cd94792a61992d98aeaba4681de7777997f23fdc1ff32438f267efeffffff02e8030000000000001976a9145008595623e5364f71fea7a4ddfc20c069a028a088ace4f00c00000000001976a914200fcbd6341db16487f566b4718879409c31ed0088ac3b960a00');
    exports.dummySigBE = '081ee271502451358f3ef61cea2c223980c4a45fd79073b2744e167ebd93bfaaf98458eca107126d2a8d1f450ba8f293f9a1031a68e686c43d369b6cebacb498d921b0cb60a4747a0a9a75d2bbd233e90cab3569029e9ba54a129521a8935d68539916fc4ff756a7a072a59f7698169301a92babe9c013c3db1e2c3ca2f603ac57218c1bb638dd4d7b4ed7816635dea15992e184db47b3266326d4b88dd352eb3bc2e944e630288a5add3734877dfa23e7755c19205c04bed91f5482e26e58a1629a33e55b2826454d36a030ca82119d257e10761974d64247e2c58ed2ec333cd03721cbb2784955077c2a53bc8f9500d2b6fdce061f8e3fb6287ec1b36705ee719c8905fbd32578db7a719f904a264a578c00ddb51425ff220f2ca4f01e744b37cc4712930f7cc82cd149bb3f00a98d6c98a0512a2a189c7adde27bb5374155b44a3b66493f7bde9a2c0e1e80a260b46f6e2d1d3f88669b422d4b8793b17286fd97b367e671d026f3d2e383b1e412fa830ddfbe2dcae6054ed8527064959263';
    exports.dummyPayload = '43c5967c870e31cc5fe07c626aa0cf52569d23d344afca15cc5156d88c1bb8dc0100000064ac9c0000000000af4a1ee6224ae65681fb0adb2e00b979c9926c1392848643ff517ac66c8ffd04a4028ac8eebc45951549c5867a338cf446372f1d';
    exports.dummyPadding = '0200';
    exports.dummyRabinPubKey = bn_js_1.BN.fromString('2c8c0117aa5edba9a4539e783b6a1bdbc1ad88ad5b57f3d9c5cba55001c45e1fedb877ebc7d49d1cfa8aa938ccb303c3a37732eb0296fee4a6642b0ff1976817b603404f64c41ec098f8cd908caf64b4a3aada220ff61e252ef6d775079b69451367eda8fdb37bc55c8bfd69610e1f31b9d421ff44e3a0cfa7b11f334374827256a0b91ce80c45ffb798798e7bd6b110134e1a3c3fa89855a19829aab3922f55da92000495737e99e0094e6c4dbcc4e8d8de5459355c21ff055d039a202076e4ca263b745a885ef292eec0b5a5255e6ecc45534897d9572c3ebe97d36626c7b1e775159e00b17d03bc6d127260e13a252afd89bab72e8daf893075f18c1840cb394f18a9817913a9462c6ffc8951bee50a05f38da4c9090a4d6868cb8c955e5efb4f3be4e7cf0be1c399d78a6f6dd26a0af8492dca67843c6da9915bae571aa9f4696418ab1520dd50dd05f5c0c7a51d2843bd4d9b6b3b79910e98f3d98099fd86d71b2fac290e32bdacb31943a8384a7668c32a66be127b74390b4b0dec6455', 16);
    let buf = Buffer.alloc(0);
    for (let i = 0; i < token_proto_1.SIGNER_NUM; i++) {
        buf = Buffer.concat([
            buf,
            mvc.crypto.Hash.sha256ripemd160(TokenUtil.toBufferLE(exports.dummyRabinPubKey.toString('hex'), TokenUtil.RABIN_SIG_LEN)),
        ]);
    }
    exports.dummyRabinPubKeyHashArray = buf;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../bn.js":381,"../mcp02/contract-proto/token.proto":435,"../mvc":440,"./tokenUtil":390,"buffer":84}],388:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ErrInfo = exports.ErrCode = exports.CodeError = void 0;
    class CodeError extends Error {
        constructor(code, msg) {
            super(msg);
            this.code = code;
            if (msg) {
                this.message = msg;
            }
            else {
                this.message = 'CodeError:' + code;
            }
        }
    }
    exports.CodeError = CodeError;
    var ErrCode;
    (function (ErrCode) {
        ErrCode[ErrCode["EC_OK"] = 0] = "EC_OK";
        ErrCode[ErrCode["EC_INNER_ERROR"] = -1] = "EC_INNER_ERROR";
        ErrCode[ErrCode["EC_INVALID_ARGUMENT"] = -2] = "EC_INVALID_ARGUMENT";
        ErrCode[ErrCode["EC_SENSIBLE_API_ERROR"] = -3] = "EC_SENSIBLE_API_ERROR";
        ErrCode[ErrCode["EC_INVALID_SIGNERS"] = -4] = "EC_INVALID_SIGNERS";
        //需要特殊处理
        ErrCode[ErrCode["EC_UTXOS_MORE_THAN_3"] = -100] = "EC_UTXOS_MORE_THAN_3";
        ErrCode[ErrCode["EC_TOO_MANY_FT_UTXOS"] = -101] = "EC_TOO_MANY_FT_UTXOS";
        ErrCode[ErrCode["EC_FIXED_TOKEN_SUPPLY"] = -102] = "EC_FIXED_TOKEN_SUPPLY";
        ErrCode[ErrCode["EC_CANNOT_BURN_NON_ZERO_ADDRESS"] = -103] = "EC_CANNOT_BURN_NON_ZERO_ADDRESS";
        //金额不足
        ErrCode[ErrCode["EC_INSUFFICIENT_MVC"] = -200] = "EC_INSUFFICIENT_MVC";
        ErrCode[ErrCode["EC_INSUFFICIENT_FT"] = -201] = "EC_INSUFFICIENT_FT";
        ErrCode[ErrCode["EC_NFT_NOT_ON_SELL"] = -300] = "EC_NFT_NOT_ON_SELL";
    })(ErrCode = exports.ErrCode || (exports.ErrCode = {}));
    exports.ErrInfo = {
        InvalidArgument: {
            code: ErrCode.EC_INVALID_ARGUMENT,
            message: '',
        },
    };
    
    },{}],389:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.hasProtoFlag = exports.getProtoVersion = exports.getProtoType = exports.getFlag = exports.getHeaderLen = exports.PROTO_TYPE = exports.HEADER_LEN = exports.PROTO_VERSION_OFFSET = exports.PROTO_VERSION_LEN = exports.PROTO_TYPE_OFFSET = exports.PROTO_TYPE_LEN = exports.PROTO_FLAG_OFFSET = exports.PROTO_FLAG_LEN = exports.PROTO_FLAG = exports.PROTO_SUFFIX = void 0;
    exports.PROTO_SUFFIX = 5;
    exports.PROTO_FLAG = Buffer.from('metacontract'); // 12
    exports.PROTO_FLAG_LEN = exports.PROTO_FLAG.length; // 12
    exports.PROTO_FLAG_OFFSET = exports.PROTO_FLAG_LEN + exports.PROTO_SUFFIX; // 12 + 5 = 17
    exports.PROTO_TYPE_LEN = 4;
    exports.PROTO_TYPE_OFFSET = exports.PROTO_FLAG_OFFSET + exports.PROTO_TYPE_LEN; // 17 + 4 = 21
    exports.PROTO_VERSION_LEN = 4;
    exports.PROTO_VERSION_OFFSET = exports.PROTO_TYPE_OFFSET + exports.PROTO_VERSION_LEN; // 21 + 4 = 25
    exports.HEADER_LEN = exports.PROTO_VERSION_OFFSET; // 25
    var PROTO_TYPE;
    (function (PROTO_TYPE) {
        PROTO_TYPE[PROTO_TYPE["FT"] = 1] = "FT";
        PROTO_TYPE[PROTO_TYPE["UNIQUE"] = 2] = "UNIQUE";
        PROTO_TYPE[PROTO_TYPE["NFT"] = 3] = "NFT";
        PROTO_TYPE[PROTO_TYPE["NFT_SELL"] = 65537] = "NFT_SELL";
    })(PROTO_TYPE = exports.PROTO_TYPE || (exports.PROTO_TYPE = {}));
    function getHeaderLen() {
        return exports.HEADER_LEN;
    }
    exports.getHeaderLen = getHeaderLen;
    function getFlag(script) {
        return script.slice(script.length - exports.PROTO_FLAG_OFFSET, script.length - exports.PROTO_SUFFIX);
    }
    exports.getFlag = getFlag;
    function getProtoType(script) {
        if (script.length < exports.PROTO_TYPE_OFFSET)
            return 0;
        return script.readUIntLE(script.length - exports.PROTO_TYPE_OFFSET, exports.PROTO_TYPE_LEN);
    }
    exports.getProtoType = getProtoType;
    function getProtoVersion(script) {
        if (script.length < exports.PROTO_VERSION_OFFSET)
            return 0;
        return script.readUIntLE(script.length - exports.PROTO_VERSION_OFFSET, exports.PROTO_VERSION_LEN);
    }
    exports.getProtoVersion = getProtoVersion;
    function hasProtoFlag(script) {
        const flag = getFlag(script);
        if (flag.compare(exports.PROTO_FLAG) === 0) {
            return true;
        }
        return false;
    }
    exports.hasProtoFlag = hasProtoFlag;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84}],390:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.getTxInfoHex = exports.getTxOutputProof = exports.getTxInputProof = exports.getTxidInfo = exports.getOpPushDataLen = exports.buildScriptData = exports.getEmptyTxOutputProof = exports.getOutpointBuf = exports.getRabinPubKeyHashArray = exports.getGenesisHashFromLockingScript = exports.getLockingScriptFromPreimage = exports.writeVarint = exports.getScriptHashBuf = exports.getTxIdBuf = exports.getUInt64Buf = exports.getUInt32Buf = exports.getUInt16Buf = exports.getUInt8Buf = exports.toBufferLE = exports.RABIN_SIG_LEN = void 0;
    const mvc = require("../mvc");
    const mvc_scrypt_1 = require("mvc-scrypt");
    const BN = require("../bn.js");
    exports.RABIN_SIG_LEN = 384;
    let toBufferLE = function (num, width) {
        const hex = num.toString(16);
        const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
        buffer.reverse();
        return buffer;
    };
    exports.toBufferLE = toBufferLE;
    let getUInt8Buf = function (amount) {
        const buf = Buffer.alloc(1, 0);
        buf.writeUInt8(amount);
        return buf;
    };
    exports.getUInt8Buf = getUInt8Buf;
    let getUInt16Buf = function (amount) {
        const buf = Buffer.alloc(2, 0);
        buf.writeUInt16LE(amount);
        return buf;
    };
    exports.getUInt16Buf = getUInt16Buf;
    let getUInt32Buf = function (index) {
        const buf = Buffer.alloc(4, 0);
        buf.writeUInt32LE(index);
        return buf;
    };
    exports.getUInt32Buf = getUInt32Buf;
    let getUInt64Buf = function (amount) {
        return new BN(amount.toString()).toBuffer({ endian: 'little', size: 8 });
    };
    exports.getUInt64Buf = getUInt64Buf;
    let getTxIdBuf = function (txid) {
        const buf = Buffer.from(txid, 'hex').reverse();
        return buf;
    };
    exports.getTxIdBuf = getTxIdBuf;
    let getScriptHashBuf = function (scriptBuf) {
        const buf = Buffer.from(mvc.crypto.Hash.sha256ripemd160(scriptBuf));
        return buf;
    };
    exports.getScriptHashBuf = getScriptHashBuf;
    let writeVarint = function (buf) {
        const n = buf.length;
        let header;
        let res = Buffer.alloc(0);
        if (n < 0xfd) {
            header = (0, exports.getUInt8Buf)(n);
        }
        else if (n < 0x10000) {
            header = Buffer.concat([Buffer.from('fd', 'hex'), (0, exports.getUInt16Buf)(n)]);
        }
        else if (n < 0x100000000) {
            header = Buffer.concat([Buffer.from('fe', 'hex'), (0, exports.getUInt32Buf)(n)]);
        }
        else if (n < 0x10000000000000000) {
            header = Buffer.concat([Buffer.from('ff', 'hex'), (0, exports.getUInt64Buf)(n)]);
        }
        return Buffer.concat([header, buf]);
    };
    exports.writeVarint = writeVarint;
    let getLockingScriptFromPreimage = function (buf) {
        if (!buf) {
            return;
        }
        const offset = 4 + 32 + 32 + 32 + 4;
        buf = buf.slice(offset, buf.length);
        const n = buf[0];
        buf = buf.slice(1, buf.length);
        let lockingScriptBuf;
        if (n < 0xfd) {
            let len = n;
            lockingScriptBuf = buf.slice(0, len);
        }
        else if (n == 0xfd) {
            let len = buf.slice(0, 2).readInt16LE(0);
            lockingScriptBuf = buf.slice(2, len + 2);
        }
        else if (n == 0xfe) {
            let len = buf.slice(0, 4).readInt32LE(0);
            lockingScriptBuf = buf.slice(4, len + 4);
        }
        else if (n == 0xff) {
            let len = Number(buf.slice(0, 8).readBigUInt64LE(0));
            lockingScriptBuf = buf.slice(8, len + 8);
        }
        return lockingScriptBuf;
    };
    exports.getLockingScriptFromPreimage = getLockingScriptFromPreimage;
    let getGenesisHashFromLockingScript = function (lockingScript) {
        let genesisHash;
        let c = 0;
        for (let i = 0; i < lockingScript.chunks.length; i++) {
            let chunk = lockingScript.chunks[i];
            if (chunk.buf && chunk.buf.length == 20) {
                c++;
                if (c == 11) {
                    genesisHash = chunk.buf;
                    break;
                }
            }
        }
        return genesisHash;
    };
    exports.getGenesisHashFromLockingScript = getGenesisHashFromLockingScript;
    let getRabinPubKeyHashArray = function (rabinPubKeys) {
        let buf = Buffer.alloc(0);
        for (let i = 0; i < rabinPubKeys.length; i++) {
            buf = Buffer.concat([
                buf,
                mvc.crypto.Hash.sha256ripemd160(this.toBufferLE(rabinPubKeys[i].toString(16), this.RABIN_SIG_LEN)),
            ]);
        }
        return buf;
    };
    exports.getRabinPubKeyHashArray = getRabinPubKeyHashArray;
    function getOutpointBuf(txid, index) {
        const txidBuf = Buffer.from(txid, 'hex').reverse();
        const indexBuf = Buffer.alloc(4, 0);
        indexBuf.writeUInt32LE(index);
        let buf = Buffer.concat([txidBuf, indexBuf]);
        return buf;
    }
    exports.getOutpointBuf = getOutpointBuf;
    const getEmptyTxOutputProof = function () {
        const data = {
            txHeader: new mvc_scrypt_1.Bytes(''),
            hashProof: new mvc_scrypt_1.Bytes(''),
            satoshiBytes: new mvc_scrypt_1.Bytes(''),
            scriptHash: new mvc_scrypt_1.Bytes(''),
        };
        return data;
    };
    exports.getEmptyTxOutputProof = getEmptyTxOutputProof;
    const buildScriptData = function (data) {
        let res = Buffer.concat([data, (0, exports.getUInt32Buf)(0), (0, exports.getUInt8Buf)(255)]);
        const pushDataLen = (0, exports.getOpPushDataLen)(res.length);
        res.writeUInt32LE(pushDataLen + data.length, data.length);
        return res;
    };
    exports.buildScriptData = buildScriptData;
    const getOpPushDataLen = function (dataLen) {
        if (dataLen <= 75) {
            return 1;
        }
        else if (dataLen <= 255) {
            return 2;
        }
        else if (dataLen <= 65535) {
            return 3;
        }
        else {
            return 5;
        }
    };
    exports.getOpPushDataLen = getOpPushDataLen;
    function getTxidInfo(tx) {
        const writer = new mvc.encoding.BufferWriter();
        writer.writeUInt32LE(tx.version);
        writer.writeUInt32LE(tx.nLockTime);
        writer.writeUInt32LE(tx.inputs.length);
        writer.writeUInt32LE(tx.outputs.length);
        const inputWriter = new mvc.encoding.BufferWriter();
        const inputWriter2 = new mvc.encoding.BufferWriter();
        for (const input of tx.inputs) {
            inputWriter.writeReverse(input.prevTxId);
            inputWriter.writeUInt32LE(input.outputIndex);
            inputWriter.writeUInt32LE(input.sequenceNumber);
            inputWriter2.write(mvc.crypto.Hash.sha256(input.script.toBuffer()));
        }
        const inputHashProof = inputWriter.toBuffer();
        writer.write(mvc.crypto.Hash.sha256(inputHashProof));
        writer.write(mvc.crypto.Hash.sha256(inputWriter2.toBuffer()));
        const outputWriter = new mvc.encoding.BufferWriter();
        for (const output of tx.outputs) {
            outputWriter.writeUInt64LEBN(output.satoshisBN);
            outputWriter.write(mvc.crypto.Hash.sha256(output.script.toBuffer()));
        }
        const outputHashProof = outputWriter.toBuffer();
        writer.write(mvc.crypto.Hash.sha256(outputHashProof));
        const txHeader = writer.toBuffer().toString('hex');
        return {
            txHeader,
            inputHashProof: inputHashProof.toString('hex'),
            outputHashProof: outputHashProof.toString('hex'),
        };
    }
    exports.getTxidInfo = getTxidInfo;
    const getTxInputProof = function (tx, inputIndex) {
        const info = getTxidInfo(tx);
        const txHeader = new mvc_scrypt_1.Bytes(info.txHeader);
        const input = tx.inputs[inputIndex];
        const res = {
            hashProof: new mvc_scrypt_1.Bytes(info.inputHashProof),
            txHash: new mvc_scrypt_1.Bytes(Buffer.from(input.prevTxId, 'hex')
                .reverse()
                .toString('hex')),
            outputIndexBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt32Buf)(input.outputIndex).toString('hex')),
            sequenceBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt32Buf)(input.sequenceNumber).toString('hex')),
        };
        return [res, txHeader];
    };
    exports.getTxInputProof = getTxInputProof;
    const getTxOutputProof = function (tx, outputIndex) {
        const info = getTxidInfo(tx);
        const output = tx.outputs[outputIndex];
        const res = {
            txHeader: new mvc_scrypt_1.Bytes(info.txHeader),
            hashProof: new mvc_scrypt_1.Bytes(info.outputHashProof),
            satoshiBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt64Buf)(output.satoshis).toString('hex')),
            scriptHash: new mvc_scrypt_1.Bytes(mvc.crypto.Hash.sha256(output.script.toBuffer()).toString('hex')),
        };
        return res;
    };
    exports.getTxOutputProof = getTxOutputProof;
    const getTxInfoHex = function (tx, outputIndex) {
        const info = getTxidInfo(tx);
        const output = tx.outputs[outputIndex];
        return {
            txHeader: info.txHeader,
            txHashProof: info.outputHashProof,
            txSatoshi: (0, exports.getUInt64Buf)(output.satoshis).toString('hex'),
        };
    };
    exports.getTxInfoHex = getTxInfoHex;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../bn.js":381,"../mvc":440,"buffer":84,"mvc-scrypt":282}],391:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.dumpTx = exports.sign = exports.numberToBuffer = exports.P2PKH_UNLOCK_SIZE = exports.PLACE_HOLDER_PUBKEY = exports.PLACE_HOLDER_SIG = exports.CONTRACT_TYPE = exports.getVarPushdataHeader = exports.isNull = exports.getDustThreshold = exports.sighashType = void 0;
    const mvc_scrypt_1 = require("mvc-scrypt");
    const mvc = require("../mvc");
    const TokenUtil = require("./tokenUtil");
    const Signature = mvc.crypto.Signature;
    exports.sighashType = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID;
    function getDustThreshold(lockingScriptSize) {
        return 1;
        // return 3 * Math.ceil((250 * (lockingScriptSize + 9 + 148)) / 1000);
    }
    exports.getDustThreshold = getDustThreshold;
    function isNull(val) {
        if (typeof val == 'undefined' || val == null || val == 'undefined') {
            return true;
        }
        else {
            return false;
        }
    }
    exports.isNull = isNull;
    function getVarPushdataHeader(n) {
        let header = '';
        if (n == 0) {
        }
        else if (n == 1) {
            //不处理这种情况，这里只考虑长脚本
        }
        else if (n < 76) {
            // Use direct push
            header = (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt8Buf(n));
        }
        else if (n <= 255) {
            header = '4c' + (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt8Buf(n));
        }
        else if (n <= 65535) {
            header = '4d' + (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt16Buf(n));
        }
        else {
            header = '4e' + (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt32Buf(n));
        }
        return Buffer.from(header, 'hex');
    }
    exports.getVarPushdataHeader = getVarPushdataHeader;
    var CONTRACT_TYPE;
    (function (CONTRACT_TYPE) {
        CONTRACT_TYPE[CONTRACT_TYPE["P2PKH"] = 0] = "P2PKH";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT"] = 1] = "BCP01_NFT";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT_GENESIS"] = 2] = "BCP01_NFT_GENESIS";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT_UNLOCK_CONTRACT_CHECK"] = 3] = "BCP01_NFT_UNLOCK_CONTRACT_CHECK";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN"] = 4] = "BCP02_TOKEN";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_GENESIS"] = 5] = "BCP02_TOKEN_GENESIS";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_TRANSFER_CHECK"] = 6] = "BCP02_TOKEN_TRANSFER_CHECK";
        CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_UNLOCK_CONTRACT_CHECK"] = 7] = "BCP02_TOKEN_UNLOCK_CONTRACT_CHECK";
        CONTRACT_TYPE[CONTRACT_TYPE["OTHER"] = 8] = "OTHER";
    })(CONTRACT_TYPE = exports.CONTRACT_TYPE || (exports.CONTRACT_TYPE = {}));
    exports.PLACE_HOLDER_SIG = '41682c2074686973206973206120706c61636520686f6c64657220616e642077696c6c206265207265706c6163656420696e207468652066696e616c207369676e61747572652e00';
    exports.PLACE_HOLDER_PUBKEY = '41682c2074686973206973206120706c61636520686f6c64657220616e64207769';
    exports.P2PKH_UNLOCK_SIZE = 1 + 1 + 72 + 1 + 33;
    function numberToBuffer(n) {
        let str = n.toString(16);
        if (str.length % 2 == 1) {
            str = '0' + str;
        }
        return Buffer.from(str, 'hex');
    }
    exports.numberToBuffer = numberToBuffer;
    function sign(tx, sigHashList, sigList) {
        sigHashList.forEach(({ inputIndex, contractType, sighashType }, index) => {
            let input = tx.inputs[inputIndex];
            let { publicKey, sig } = sigList[index];
            publicKey = new mvc.PublicKey(publicKey);
            let _sig = mvc.crypto.Signature.fromString(sig);
            _sig.nhashtype = sighashType;
            if (contractType == CONTRACT_TYPE.P2PKH) {
                const signature = new mvc.Transaction.Signature({
                    publicKey,
                    prevTxId: input.prevTxId,
                    outputIndex: input.outputIndex,
                    inputIndex: inputIndex,
                    signature: _sig,
                    sigtype: sighashType,
                });
                input.setScript(mvc.Script.buildPublicKeyHashIn(signature.publicKey, signature.signature.toDER(), signature.sigtype));
            }
            else {
                let _sig2 = _sig.toTxFormat();
                let oldSigHex = Buffer.concat([
                    numberToBuffer(exports.PLACE_HOLDER_SIG.length / 2),
                    Buffer.from(exports.PLACE_HOLDER_SIG, 'hex'),
                ]).toString('hex');
                let newSigHex = Buffer.concat([numberToBuffer(_sig2.length), _sig2]).toString('hex');
                let oldPubKeyHex = Buffer.concat([
                    numberToBuffer(exports.PLACE_HOLDER_PUBKEY.length / 2),
                    Buffer.from(exports.PLACE_HOLDER_PUBKEY, 'hex'),
                ]).toString('hex');
                const pubkeyBuffer = publicKey.toBuffer();
                let newPubKeyHex = Buffer.concat([
                    numberToBuffer(pubkeyBuffer.length),
                    pubkeyBuffer,
                ]).toString('hex');
                input.setScript(new mvc.Script(input.script.toHex().replace(oldSigHex, newSigHex).replace(oldPubKeyHex, newPubKeyHex)));
            }
        });
    }
    exports.sign = sign;
    function satoshisToMVC(satoshis) {
        return (satoshis / 100000000).toFixed(8);
    }
    function dumpTx(tx, network = 'mainnet') {
        const version = tx.version;
        const size = tx.toBuffer().length;
        const inputAmount = tx.inputs.reduce((pre, cur) => cur.output.satoshis + pre, 0);
        const outputAmount = tx.outputs.reduce((pre, cur) => cur.satoshis + pre, 0);
        let feePaid = inputAmount - outputAmount;
        const feeRate = (feePaid / size).toFixed(4);
        console.log(`
    =============================================================================================
    Summary
      txid:     ${tx.id}
      Size:     ${size}
      Fee Paid: ${satoshisToMVC(feePaid)}
      Fee Rate: ${feeRate} sat/B
      Detail:   ${tx.inputs.length} Inputs, ${tx.outputs.length} Outputs
    ----------------------------------------------------------------------------------------------
    ${tx.inputs
            .map((input, index) => {
            let type = '';
            if (input.output.script.isPublicKeyHashOut()) {
                type = 'standard';
            }
            else if (input.output.script.isSafeDataOut()) {
                type = 'OP_RETURN';
            }
            else {
                type = 'nonstandard';
            }
            let str = `
    =>${index}    ${type == 'standard'
                ? input.output.script.toAddress(network).toString()
                : type == 'OP_RETURN'
                    ? 'OP_RETURN' + ' '.repeat(34 - 9)
                    : 'nonstandard' + ' '.repeat(34 - 11)}    ${satoshisToMVC(input.output.satoshis)} MVC
           lock-size:   ${input.output.script.toBuffer().length}
           unlock-size: ${input.script.toBuffer().length}
           via ${input.prevTxId.toString('hex')} [${input.outputIndex}]
    `;
            return str;
        })
            .join('')}
    Input total: ${satoshisToMVC(tx.inputs.reduce((pre, cur) => pre + cur.output.satoshis, 0))} MVC
    ----------------------------------------------------------------------------------------------
    ${tx.outputs
            .map((output, index) => {
            let type = '';
            if (output.script.isPublicKeyHashOut()) {
                type = 'standard';
            }
            else if (output.script.isSafeDataOut()) {
                type = 'OP_RETURN';
            }
            else {
                type = 'nonstandard';
            }
            let str = `
    =>${index}    ${type == 'standard'
                ? output.script.toAddress(network).toString()
                : type == 'OP_RETURN'
                    ? 'OP_RETURN' + ' '.repeat(34 - 9)
                    : 'nonstandard' + ' '.repeat(34 - 11)}    ${satoshisToMVC(output.satoshis)} MVC
           size: ${output.script.toBuffer().length}
            `;
            return str;
        })
            .join('')}
    Output total: ${satoshisToMVC(tx.outputs.reduce((pre, cur) => pre + cur.satoshis, 0))} MVC
    =============================================================================================
         `);
    }
    exports.dumpTx = dumpTx;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../mvc":440,"./tokenUtil":390,"buffer":84,"mvc-scrypt":282}],392:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.getGenesisIdentifiers = exports.rebuildNftLockingScript = exports.createNftMintContract = exports.createNftGenesisContract = void 0;
    const nft_1 = require("../mcp01/contract-factory/nft");
    const nftGenesis_1 = require("../mcp01/contract-factory/nftGenesis");
    const __1 = require("..");
    const nftProto = require("../mcp01/contract-proto/nft.proto");
    const ftProto = require("../mcp02/contract-proto/token.proto");
    const protoheader_1 = require("../common/protoheader");
    const token_1 = require("../mcp02/contract-factory/token");
    const TokenUtil = require("../common/tokenUtil");
    const tokenGenesis_1 = require("../mcp02/contract-factory/tokenGenesis");
    function createNftGenesisContract({ totalSupply, address, }) {
        const totalSupplyInBn = new __1.BN(totalSupply.toString());
        const nftAddress = address.hashBuffer.toString('hex');
        const genesisContract = nftGenesis_1.NftGenesisFactory.createContract();
        genesisContract.setFormatedDataPart({
            totalSupply: totalSupplyInBn,
            nftAddress,
        });
        return genesisContract;
    }
    exports.createNftGenesisContract = createNftGenesisContract;
    function createNftMintContract({ version = 2, genesisHash, genesisContract, metaTxId, metaOutputIndex, sensibleID, receiverAddress, unlockContractCodeHashArray, }) {
        const nftAddress = receiverAddress.hashBuffer.toString('hex');
        const mintContract = nft_1.NftFactory.createContract(unlockContractCodeHashArray, version);
        mintContract.setFormatedDataPart({
            metaidOutpoint: {
                txid: metaTxId,
                index: metaOutputIndex,
            },
            nftAddress,
            totalSupply: genesisContract.getFormatedDataPart().totalSupply,
            tokenIndex: genesisContract.getFormatedDataPart().tokenIndex,
            genesisHash,
            sensibleID,
        });
        return mintContract;
    }
    exports.createNftMintContract = createNftMintContract;
    function rebuildNftLockingScript(nftUtxo, receiverAddress) {
        const nftScriptBuf = nftUtxo.lockingScript.toBuffer();
        let dataPart = nftProto.parseDataPart(nftScriptBuf);
        dataPart.protoType = protoheader_1.PROTO_TYPE.NFT;
        dataPart.protoVersion = nftProto.PROTO_VERSION;
        dataPart.nftAddress = receiverAddress.hashBuffer.toString('hex');
        return nftProto.updateScript(nftScriptBuf, dataPart);
    }
    exports.rebuildNftLockingScript = rebuildNftLockingScript;
    function getGenesisIdentifiers({ version = 2, genesisTx, purse, transferCheckCodeHashArray, unlockContractCodeHashArray, type, }) {
        let genesis, codehash, sensibleId;
        const proto = type === 'nft' ? nftProto : ftProto;
        const genesisOutputIndex = 0;
        const genesisTxId = genesisTx.id;
        const genesisLockingScript = genesisTx.outputs[genesisOutputIndex].script;
        let artifactContract;
        let genesisHash;
        if (type === 'nft') {
            artifactContract = nft_1.NftFactory.createContract(unlockContractCodeHashArray, version);
            const genesisContract = nftGenesis_1.NftGenesisFactory.createContract();
            genesisContract.setFormatedDataPartFromLockingScript(genesisLockingScript);
            genesisContract.setFormatedDataPart({
                sensibleID: {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                },
                tokenIndex: __1.BN.Zero,
            });
            genesisHash = genesisContract.getScriptHash();
            artifactContract.setFormatedDataPart({
                sensibleID: {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                },
                genesisHash,
                tokenAddress: purse.address.hashBuffer.toString('hex'),
            });
        }
        else {
            artifactContract = token_1.TokenFactory.createContract(transferCheckCodeHashArray, unlockContractCodeHashArray, version);
            let newGenesisContract = tokenGenesis_1.TokenGenesisFactory.createContract();
            newGenesisContract.setFormatedDataPartFromLockingScript(genesisLockingScript);
            newGenesisContract.setFormatedDataPart({
                sensibleID: {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                },
            });
            genesisHash = newGenesisContract.getScriptHash();
            artifactContract.setFormatedDataPart({
                sensibleID: {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                },
                genesisHash,
                tokenAmount: new __1.BN(0),
                tokenAddress: purse.address.hashBuffer.toString('hex'),
            });
        }
        let scriptBuf = artifactContract.lockingScript.toBuffer();
        genesis = proto.getQueryGenesis(scriptBuf);
        codehash = artifactContract.getCodeHash();
        sensibleId = TokenUtil.getOutpointBuf(genesisTxId, genesisOutputIndex).toString('hex');
        return { codehash, genesis, sensibleId };
    }
    exports.getGenesisIdentifiers = getGenesisIdentifiers;
    
    },{"..":395,"../common/protoheader":389,"../common/tokenUtil":390,"../mcp01/contract-factory/nft":407,"../mcp01/contract-factory/nftGenesis":408,"../mcp01/contract-proto/nft.proto":411,"../mcp02/contract-factory/token":431,"../mcp02/contract-factory/tokenGenesis":432,"../mcp02/contract-proto/token.proto":435}],393:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.createPrevGenesisTxOutputProof = exports.createGenesisTxInputProof = exports.createTxOutputProof = exports.createTxInputProof = exports.getTxidInfo = exports.getUInt64Buf = exports.getUInt32Buf = exports.getUInt16Buf = exports.getUInt8Buf = void 0;
    const scryptlib_1 = require("../scryptlib");
    const mvc_1 = require("../mvc");
    const __1 = require("..");
    const jsonDescr = require('../mcp01/contract-desc/txUtil_desc.json');
    const { TxInputProof, TxOutputProof } = (0, scryptlib_1.buildTypeClasses)(jsonDescr);
    let getUInt8Buf = function (amount) {
        const buf = Buffer.alloc(1, 0);
        buf.writeUInt8(amount);
        return buf;
    };
    exports.getUInt8Buf = getUInt8Buf;
    let getUInt16Buf = function (amount) {
        const buf = Buffer.alloc(2, 0);
        buf.writeUInt16LE(amount);
        return buf;
    };
    exports.getUInt16Buf = getUInt16Buf;
    let getUInt32Buf = function (index) {
        const buf = Buffer.alloc(4, 0);
        buf.writeUInt32LE(index);
        return buf;
    };
    exports.getUInt32Buf = getUInt32Buf;
    let getUInt64Buf = function (amount) {
        return new __1.BN(amount.toString()).toBuffer({ endian: 'little', size: 8 });
    };
    exports.getUInt64Buf = getUInt64Buf;
    function getTxidInfo(tx) {
        const writer = new mvc_1.encoding.BufferWriter();
        writer.writeUInt32LE(tx.version);
        writer.writeUInt32LE(tx.nLockTime);
        writer.writeUInt32LE(tx.inputs.length);
        writer.writeUInt32LE(tx.outputs.length);
        const inputWriter = new mvc_1.encoding.BufferWriter();
        const inputWriter2 = new mvc_1.encoding.BufferWriter();
        for (const input of tx.inputs) {
            inputWriter.writeReverse(input.prevTxId);
            inputWriter.writeUInt32LE(input.outputIndex);
            inputWriter.writeUInt32LE(input.sequenceNumber);
            inputWriter2.write(mvc_1.crypto.Hash.sha256(input.script.toBuffer()));
        }
        const inputHashProof = inputWriter.toBuffer();
        writer.write(mvc_1.crypto.Hash.sha256(inputHashProof));
        writer.write(mvc_1.crypto.Hash.sha256(inputWriter2.toBuffer()));
        const outputWriter = new mvc_1.encoding.BufferWriter();
        for (const output of tx.outputs) {
            outputWriter.writeUInt64LEBN(output.satoshisBN);
            outputWriter.write(mvc_1.crypto.Hash.sha256(output.script.toBuffer()));
        }
        const outputHashProof = outputWriter.toBuffer();
        writer.write(mvc_1.crypto.Hash.sha256(outputHashProof));
        const txHeader = writer.toBuffer().toString('hex');
        return {
            txHeader,
            inputHashProof: inputHashProof.toString('hex'),
            outputHashProof: outputHashProof.toString('hex'),
        };
    }
    exports.getTxidInfo = getTxidInfo;
    function createTxInputProof(tx, inputIndex) {
        const info = getTxidInfo(tx);
        const txHeader = new scryptlib_1.Bytes(info.txHeader);
        const input = tx.inputs[inputIndex];
        const res = {
            hashProof: new scryptlib_1.Bytes(info.inputHashProof),
            txHash: new scryptlib_1.Bytes(Buffer.from(input.prevTxId, 'hex')
                .reverse()
                .toString('hex')),
            outputIndexBytes: new scryptlib_1.Bytes((0, exports.getUInt32Buf)(input.outputIndex).toString('hex')),
            sequenceBytes: new scryptlib_1.Bytes((0, exports.getUInt32Buf)(input.sequenceNumber).toString('hex')),
        };
        return [res, txHeader];
    }
    exports.createTxInputProof = createTxInputProof;
    function createTxOutputProof(tx, outputIndex) {
        const info = getTxidInfo(tx);
        const output = tx.outputs[outputIndex];
        // console.log({
        //   sats: output.satoshis,
        //   satsInBytes: new Bytes(getUInt64Buf(output.satoshis).toString('hex')).toString('hex'),
        //   outputIndex,
        //   txId: tx.id,
        // })
        const res = {
            txHeader: new scryptlib_1.Bytes(info.txHeader),
            hashProof: new scryptlib_1.Bytes(info.outputHashProof),
            satoshiBytes: new scryptlib_1.Bytes((0, exports.getUInt64Buf)(output.satoshis).toString('hex')),
            scriptHash: new scryptlib_1.Bytes(mvc_1.crypto.Hash.sha256(output.script.toBuffer()).toString('hex')),
        };
        return res;
    }
    exports.createTxOutputProof = createTxOutputProof;
    function createGenesisTxInputProof(genesisUtxo) {
        const genesisTx = new mvc_1.Transaction(genesisUtxo.satotxInfo.txHex);
        const prevInputIndex = 0;
        const inputRes = createTxInputProof(genesisTx, prevInputIndex);
        const genesisTxInputProof = new TxInputProof(inputRes[0]);
        const genesisTxHeader = inputRes[1]; // TODO:
        return { genesisTxHeader, prevInputIndex, genesisTxInputProof };
    }
    exports.createGenesisTxInputProof = createGenesisTxInputProof;
    function createPrevGenesisTxOutputProof(genesisUtxo) {
        const preGenesisOutputIndex = genesisUtxo.satotxInfo.preOutputIndex;
        const preGenesisTx = new mvc_1.Transaction(genesisUtxo.satotxInfo.preTxHex);
        const prevOutputProof = createTxOutputProof(preGenesisTx, preGenesisOutputIndex);
        return {
            prevGenesisTxHeader: prevOutputProof.txHeader,
            prevTxOutputHashProof: prevOutputProof.hashProof,
            prevTxOutputSatoshiBytes: prevOutputProof.satoshiBytes,
        };
    }
    exports.createPrevGenesisTxOutputProof = createPrevGenesisTxOutputProof;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"..":395,"../mcp01/contract-desc/txUtil_desc.json":406,"../mvc":440,"../scryptlib":445,"buffer":84}],394:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.parseSensibleId = exports.getLatestGenesisInfo = exports.getNftInfo = exports.checkFeeRate = exports.unlockP2PKHInputs = exports.addChangeOutput = exports.addOpreturnOutput = exports.addContractOutput = exports.addContractInput = exports.addP2PKHInputs = exports.prepareUtxos = void 0;
    const mvc_1 = require("../mvc");
    const error_1 = require("../common/error");
    const utils_1 = require("../common/utils");
    const nftGenesis_1 = require("../mcp01/contract-factory/nftGenesis");
    const tokenGenesis_1 = require("../mcp02/contract-factory/tokenGenesis");
    const nftProto = require("../mcp01/contract-proto/nft.proto");
    const ftProto = require("../mcp02/contract-proto/token.proto");
    const mvc = require("../mvc");
    function prepareUtxos(purse, api, network, utxosInput) {
        return __awaiter(this, void 0, void 0, function* () {
            let utxoPrivateKeys = [];
            if (utxosInput) {
                utxosInput.forEach((utxo) => {
                    if (utxo.wif) {
                        let privateKey = mvc.PrivateKey.fromWIF(utxo.wif);
                        utxoPrivateKeys.push(privateKey);
                        utxo.address = privateKey.toAddress(network); //Compatible with the old version, only wif is provided but no address is provided
                    }
                });
                return {
                    utxos: utxosInput,
                    utxoPrivateKeys,
                };
            }
            const utxos = yield api.getUnspents(purse.address.toString());
            utxos.forEach((utxo) => {
                utxoPrivateKeys.push(purse.privateKey);
                utxo.address = new mvc_1.Address(utxo.address, network);
            });
            if (utxos.length == 0)
                throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, 'Insufficient balance.');
            return { utxos, utxoPrivateKeys };
        });
    }
    exports.prepareUtxos = prepareUtxos;
    function addP2PKHInputs(txComposer, utxos) {
        const p2pkhInputIndexes = utxos.map((utxo) => {
            const inputIndex = txComposer.appendP2PKHInput(utxo);
            txComposer.addSigHashInfo({
                inputIndex,
                address: utxo.address.toString(),
                sighashType: utils_1.sighashType,
                contractType: utils_1.CONTRACT_TYPE.P2PKH,
            });
            return inputIndex;
        });
        return p2pkhInputIndexes;
    }
    exports.addP2PKHInputs = addP2PKHInputs;
    function addContractInput(txComposer, contractUTxo, address, contractType) {
        const contractInputIndex = txComposer.appendInput(contractUTxo);
        txComposer.addSigHashInfo({
            inputIndex: contractInputIndex,
            address,
            sighashType: utils_1.sighashType,
            contractType,
        });
        return contractInputIndex;
    }
    exports.addContractInput = addContractInput;
    function addContractOutput({ txComposer, contract, lockingScript, dustCalculator, }) {
        if (!lockingScript) {
            lockingScript = contract.lockingScript;
        }
        const contractSize = lockingScript.toBuffer().length;
        const satoshis = dustCalculator.getDustThreshold(contractSize);
        return txComposer.appendOutput({
            lockingScript,
            satoshis,
        });
    }
    exports.addContractOutput = addContractOutput;
    function addOpreturnOutput(txComposer, opreturnData) {
        return txComposer.appendOpReturnOutput(opreturnData);
    }
    exports.addOpreturnOutput = addOpreturnOutput;
    function addChangeOutput(txComposer, changeAddress, feeb) {
        return txComposer.appendChangeOutput(changeAddress, feeb);
    }
    exports.addChangeOutput = addChangeOutput;
    function unlockP2PKHInputs(txComposer, inputIndexes, utxoPrivateKeys) {
        inputIndexes.forEach((inputIndex) => {
            let privateKey = utxoPrivateKeys.splice(0, 1)[0];
            txComposer.unlockP2PKHInput(privateKey, inputIndex);
        });
    }
    exports.unlockP2PKHInputs = unlockP2PKHInputs;
    function checkFeeRate(txComposer, feeb) {
        let feeRate = txComposer.getFeeRate();
        if (feeRate < feeb) {
            throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.The fee rate should not be less than ${feeb}, but in the end it is ${feeRate}.`);
        }
    }
    exports.checkFeeRate = checkFeeRate;
    function getNftInfo({ tokenIndex, codehash, genesis, api, network, }) {
        return __awaiter(this, void 0, void 0, function* () {
            let _res = yield api.getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex);
            let nftUtxo = {
                txId: _res.txId,
                outputIndex: _res.outputIndex,
                nftAddress: new mvc_1.Address(_res.tokenAddress, network),
            };
            return { nftUtxo };
        });
    }
    exports.getNftInfo = getNftInfo;
    // 获取最新的创世合约及tx信息
    function getLatestGenesisInfo({ sensibleId, api, address, type, }) {
        return __awaiter(this, void 0, void 0, function* () {
            const factory = type === 'nft' ? nftGenesis_1.NftGenesisFactory : tokenGenesis_1.TokenGenesisFactory;
            const proto = type === 'nft' ? nftProto : ftProto;
            let genesisContract = factory.createContract();
            let { genesisTxId, genesisOutputIndex } = parseSensibleId(sensibleId);
            let genesisUtxo = yield getLatestGenesisUtxo(proto, genesisContract.getCodeHash(), genesisTxId, genesisOutputIndex, api, address, type);
            if (!genesisUtxo) {
                throw new error_1.CodeError(error_1.ErrCode.EC_FIXED_TOKEN_SUPPLY, 'token supply is fixed');
            }
            let txHex = yield api.getRawTxData(genesisUtxo.txId);
            const tx = new mvc_1.Transaction(txHex);
            let preTxId = tx.inputs[0].prevTxId.toString('hex');
            let preOutputIndex = tx.inputs[0].outputIndex;
            let preTxHex = yield api.getRawTxData(preTxId);
            genesisUtxo.satotxInfo = {
                txId: genesisUtxo.txId,
                outputIndex: genesisUtxo.outputIndex,
                txHex,
                preTxId,
                preOutputIndex,
                preTxHex,
            };
            let output = tx.outputs[genesisUtxo.outputIndex];
            genesisUtxo.satoshis = output.satoshis;
            genesisUtxo.lockingScript = output.script;
            genesisContract.setFormatedDataPartFromLockingScript(genesisUtxo.lockingScript);
            return {
                genesisContract,
                genesisTxId,
                genesisOutputIndex,
                genesisUtxo,
            };
        });
    }
    exports.getLatestGenesisInfo = getLatestGenesisInfo;
    function getLatestGenesisUtxo(proto, codehash, genesisTxId, genesisOutputIndex, api, address, type) {
        return __awaiter(this, void 0, void 0, function* () {
            // 使用创世txid从接口获取该创世tx内容
            let unspent;
            let latestGenesisTxHex = yield api.getRawTxData(genesisTxId);
            let latestGenesisTx = new mvc_1.Transaction(latestGenesisTxHex);
            // 重新构建该创世脚本
            let scriptBuffer = latestGenesisTx.outputs[genesisOutputIndex].script.toBuffer();
            let originGenesis = proto.getQueryGenesis(scriptBuffer);
            // 找回utxo
            let genesisUtxos;
            if (type === 'nft') {
                genesisUtxos = yield api.getNonFungibleTokenUnspents(codehash, originGenesis, address.toString());
            }
            else {
                genesisUtxos = yield api.getFungibleTokenUnspents(codehash, originGenesis, address.toString());
            }
            unspent = genesisUtxos.find((v) => v.txId == genesisTxId && v.outputIndex == genesisOutputIndex);
            if (!unspent) {
                let _dataPartObj = proto.parseDataPart(scriptBuffer);
                _dataPartObj.sensibleID = {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                };
                let newScriptBuf = proto.updateScript(scriptBuffer, _dataPartObj);
                let issueGenesis = proto.getQueryGenesis(newScriptBuf);
                let issueUtxos;
                if (type === 'nft') {
                    issueUtxos = yield api.getNonFungibleTokenUnspents(codehash, issueGenesis, address.toString());
                }
                else {
                    issueUtxos = yield api.getFungibleTokenUnspents(codehash, issueGenesis, address.toString());
                }
                if (issueUtxos.length > 0) {
                    unspent = issueUtxos[0];
                }
            }
            if (unspent) {
                return {
                    txId: unspent.txId,
                    outputIndex: unspent.outputIndex,
                };
            }
        });
    }
    function parseSensibleId(sensibleId) {
        let sensibleIDBuf = Buffer.from(sensibleId, 'hex');
        let genesisTxId = sensibleIDBuf.slice(0, 32).reverse().toString('hex');
        let genesisOutputIndex = sensibleIDBuf.readUIntLE(32, 4);
        return {
            genesisTxId,
            genesisOutputIndex,
        };
    }
    exports.parseSensibleId = parseSensibleId;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/error":388,"../common/utils":391,"../mcp01/contract-factory/nftGenesis":408,"../mcp01/contract-proto/nft.proto":411,"../mcp02/contract-factory/tokenGenesis":432,"../mcp02/contract-proto/token.proto":435,"../mvc":440,"buffer":84}],395:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.FtManager = exports.NftManager = exports.SensibleFT = exports.SensibleNFT = exports.Wallet = exports.TxComposer = exports.TxDecoder = exports.OutputType = exports.Api = exports.API_TARGET = exports.API_NET = exports.Net = exports.mvc = exports.BN = void 0;
    const mcp01_1 = require("./mcp01");
    Object.defineProperty(exports, "NftManager", { enumerable: true, get: function () { return mcp01_1.NftManager; } });
    const mcp02_1 = require("./mcp02");
    Object.defineProperty(exports, "FtManager", { enumerable: true, get: function () { return mcp02_1.FtManager; } });
    const mvc = require("./mvc");
    exports.mvc = mvc;
    exports.BN = mvc.crypto.BN;
    var net_1 = require("./net");
    Object.defineProperty(exports, "Net", { enumerable: true, get: function () { return net_1.Net; } });
    var api_1 = require("./api");
    Object.defineProperty(exports, "API_NET", { enumerable: true, get: function () { return api_1.API_NET; } });
    Object.defineProperty(exports, "API_TARGET", { enumerable: true, get: function () { return api_1.API_TARGET; } });
    Object.defineProperty(exports, "Api", { enumerable: true, get: function () { return api_1.Api; } });
    var tx_decoder_1 = require("./tx-decoder");
    Object.defineProperty(exports, "OutputType", { enumerable: true, get: function () { return tx_decoder_1.OutputType; } });
    Object.defineProperty(exports, "TxDecoder", { enumerable: true, get: function () { return tx_decoder_1.TxDecoder; } });
    var tx_composer_1 = require("./tx-composer");
    Object.defineProperty(exports, "TxComposer", { enumerable: true, get: function () { return tx_composer_1.TxComposer; } });
    var wallet_1 = require("./wallet");
    Object.defineProperty(exports, "Wallet", { enumerable: true, get: function () { return wallet_1.Wallet; } });
    // 兼容
    const SensibleNFT = mcp01_1.NftManager;
    exports.SensibleNFT = SensibleNFT;
    const SensibleFT = mcp02_1.FtManager;
    exports.SensibleFT = SensibleFT;
    
    },{"./api":380,"./mcp01":415,"./mcp02":439,"./mvc":440,"./net":443,"./tx-composer":446,"./tx-decoder":447,"./wallet":448}],396:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.FtManager = exports.NftManager = exports.SensibleFT = exports.SensibleNFT = exports.Wallet = exports.TxComposer = exports.TxDecoder = exports.OutputType = exports.Api = exports.API_TARGET = exports.API_NET = exports.Net = exports.BN = exports.mvc = void 0;
    /**
     * When we browserify the source, buffer in elliptic/node_modules/bn.js is null.
     * Add the code to fix that.
     */
    if (typeof globalThis.window !== 'undefined') {
        var window = globalThis.window;
        if (typeof window.Buffer == 'undefined') {
            const Buffer = require('buffer/index').Buffer;
            window.Buffer = Buffer;
        }
    }
    const mvc = require("./mvc");
    exports.mvc = mvc;
    const BN = mvc.crypto.BN;
    exports.BN = BN;
    var net_1 = require("./net");
    Object.defineProperty(exports, "Net", { enumerable: true, get: function () { return net_1.Net; } });
    var api_1 = require("./api");
    Object.defineProperty(exports, "API_NET", { enumerable: true, get: function () { return api_1.API_NET; } });
    Object.defineProperty(exports, "API_TARGET", { enumerable: true, get: function () { return api_1.API_TARGET; } });
    Object.defineProperty(exports, "Api", { enumerable: true, get: function () { return api_1.Api; } });
    var tx_decoder_1 = require("./tx-decoder");
    Object.defineProperty(exports, "OutputType", { enumerable: true, get: function () { return tx_decoder_1.OutputType; } });
    Object.defineProperty(exports, "TxDecoder", { enumerable: true, get: function () { return tx_decoder_1.TxDecoder; } });
    var tx_composer_1 = require("./tx-composer");
    Object.defineProperty(exports, "TxComposer", { enumerable: true, get: function () { return tx_composer_1.TxComposer; } });
    var wallet_1 = require("./wallet");
    Object.defineProperty(exports, "Wallet", { enumerable: true, get: function () { return wallet_1.Wallet; } });
    const mcp01_1 = require("./mcp01");
    Object.defineProperty(exports, "NftManager", { enumerable: true, get: function () { return mcp01_1.NftManager; } });
    const mcp02_1 = require("./mcp02");
    Object.defineProperty(exports, "FtManager", { enumerable: true, get: function () { return mcp02_1.FtManager; } });
    const SensibleNFT = mcp01_1.NftManager;
    exports.SensibleNFT = SensibleNFT;
    const SensibleFT = mcp02_1.FtManager;
    exports.SensibleFT = SensibleFT;
    
    },{"./api":380,"./mcp01":415,"./mcp02":439,"./mvc":440,"./net":443,"./tx-composer":446,"./tx-decoder":447,"./wallet":448,"buffer/index":87}],397:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "Nft",
        "md5": "f67a31d2211d49fd7296a7c371367842",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "prevNftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "prevNftAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevNftTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "genesisScript",
                        "type": "bytes"
                    },
                    {
                        "name": "contractInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "contractTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckHashIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckScript",
                        "type": "bytes"
                    },
                    {
                        "name": "senderPubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "senderSig",
                        "type": "Sig"
                    },
                    {
                        "name": "receiverAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "operation",
                        "type": "int"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": [
                    {
                        "name": "unlockContractCodeHashArray",
                        "type": "bytes[5]"
                    }
                ]
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nft-v2.scrypt",
        "hex": "0176018801a901ac515301402097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c557954798501145593140000000000000000000000000000000000000000780124937601149376589376589376011493760124937652935501149376011493768b<unlockContractCodeHashArray[0]><unlockContractCodeHashArray[1]><unlockContractCodeHashArray[2]><unlockContractCodeHashArray[3]><unlockContractCodeHashArray[4]> ",
        "sourceMapFile": ""
    }
    },{}],398:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftGenesis",
        "md5": "a4ccbc179c9c215ca0ea4243222626f0",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "pubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "sig",
                        "type": "Sig"
                    },
                    {
                        "name": "genesisTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "prevInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "genesisTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevGenesisTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTxOutputHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTxOutputSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "genesisSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "nftSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftGenesis.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],399:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftSell",
        "md5": "d546c73b76c3a61fd075b09a27a71297",
        "structs": [],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "senderPubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "senderSig",
                        "type": "Sig"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "op",
                        "type": "int"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": [
                    {
                        "name": "senderAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "bsvRecAmount",
                        "type": "int"
                    },
                    {
                        "name": "nftCodeHash",
                        "type": "bytes"
                    },
                    {
                        "name": "nftID",
                        "type": "bytes"
                    }
                ]
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftSell.scrypt",
        "hex": "0176018801a901ac515301402097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c54795479850114559376012493760114937658937658937601149376012493765293<senderAddress><bsvRecAmount><nftCodeHash><nftID>00011879519c6354790118790117797e01147e787e0118797e0116797e777655797658805279768277007802fd009f6378516e8b80767682778c7f75007f77777777776778030000019f6301fd5279526e8b80767682778c7f75007f777777777e7767780500000000019f6301fe5279546e8b80767682778c7f75007f777777777e776778090000000000000000019f6301ff5279586e8b80767682778c7f75007f777777777e77686868687653797e7777777e7777777767011b79a9557988011a79011c79ad011c798277011d79786e6e5c79947f757777a97777547988011d79786e011179947f75785e79947f77a97777537988011d797857796f755d79947f75787e707f7553795e79940114937f777e77777776011c797658805279768277007802fd009f6378516e8b80767682778c7f75007f77777777776778030000019f6301fd5279526e8b80767682778c7f75007f777777777e7767780500000000019f6301fe5279546e8b80767682778c7f75007f777777777e776778090000000000000000019f6301ff5279586e8b80767682778c7f75007f777777777e77686868687653797e7777777e7777537a7577776876aa011e797682776e58947f75780128947f77777788011d795e7978011379011379210ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800206c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce081001157956795679aa7676517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01007e817757795679567956795679537956795479577995939521414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff006e6e9776009f636e936776687777777b757c6e5296a0636e7c947b757c6853798277527982775379012080517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01205279947f77545379935279930130787e527e54797e58797e527e53797e52797e57797e777777777777777777777777ab765779ac7777777777777777777777777777777777777777777777777777777777777777777777777777777777",
        "sourceMapFile": ""
    }
    },{}],400:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftUnlockContractCheck",
        "md5": "6040b90032e30bae312732ff4941cf4f",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "nftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "nftSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "txNftOutputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftOutputAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftUnlockContractCheck_100.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],401:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftUnlockContractCheck",
        "md5": "55a3ce7af7b39150a8d6b3891b89f077",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "nftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "nftSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "txNftOutputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftOutputAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftUnlockContractCheck_10.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],402:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftUnlockContractCheck",
        "md5": "c5819ca3bdcf6d2fece66c9bde74c4d7",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "nftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "nftSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "txNftOutputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftOutputAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftUnlockContractCheck_20.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],403:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftUnlockContractCheck",
        "md5": "27e82eced782796bdebe8420633e8025",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "nftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "nftSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "txNftOutputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftOutputAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftUnlockContractCheck_6.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],404:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "NftUnlockContractCheck",
        "md5": "666adb8e966719fe38379e24d40dda3a",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "nftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftScript",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "nftSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "txNftOutputIndex",
                        "type": "int"
                    },
                    {
                        "name": "nftOutputAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nftUnlockContractCheck.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],405:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "Nft",
        "md5": "fb91e6eb310c18474b3bebc8579696d8",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "NftProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "prevNftInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "prevNftAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "nftTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevNftTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "genesisScript",
                        "type": "bytes"
                    },
                    {
                        "name": "contractInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "contractTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckHashIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckScript",
                        "type": "bytes"
                    },
                    {
                        "name": "senderPubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "senderSig",
                        "type": "Sig"
                    },
                    {
                        "name": "receiverAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "nftOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "operation",
                        "type": "int"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": [
                    {
                        "name": "unlockContractCodeHashArray",
                        "type": "bytes[5]"
                    }
                ]
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/nft/nft.scrypt",
        "hex": "0176018801a901ac515301402097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c557954798501145593140000000000000000000000000000000000000000780124937601149376589376589376011493760124937652935501149376011493768b<unlockContractCodeHashArray[0]><unlockContractCodeHashArray[1]><unlockContractCodeHashArray[2]><unlockContractCodeHashArray[3]><unlockContractCodeHashArray[4]> ",
        "sourceMapFile": ""
    }
    },{}],406:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TxUtil",
        "md5": "2920f04d42c66cf433d55b6e738ee31e",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp01/contract/txUtil.scrypt",
        "hex": "",
        "sourceMapFile": ""
    }
    },{}],407:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.NftFactory = exports.Nft = void 0;
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const protoheader_1 = require("../../common/protoheader");
    const scryptlib_1 = require("../../scryptlib");
    const nftProto = require("../contract-proto/nft.proto");
    const nft_proto_1 = require("../contract-proto/nft.proto");
    const contractUtil_1 = require("../contractUtil");
    class Nft extends ContractAdapter_1.ContractAdapter {
        constructor(constuctParams, version = 2) {
            let desc = version === 2
                ? require('../contract-desc/nft-v2_desc.json')
                : require('../contract-desc/nft_desc.json');
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new ClassObj(constuctParams.unlockContractCodeHashArray);
            super(contract);
            this.constuctParams = constuctParams;
        }
        clone() {
            let contract = new Nft(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            this._formatedDataPart.protoVersion = nftProto.PROTO_VERSION;
            this._formatedDataPart.protoType = protoheader_1.PROTO_TYPE.NFT;
            super.setDataPart((0, scryptlib_1.toHex)(nftProto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        unlock({ txPreimage, prevouts, 
        // nft
        prevNftInputIndex, prevNftAddress, nftTxHeader, nftTxInputProof, prevNftTxProof, genesisScript, 
        // contract
        contractInputIndex, contractTxProof, 
        // unlockCheck
        amountCheckHashIndex, amountCheckInputIndex, amountCheckTxProof, amountCheckScrypt, 
        // sig
        senderPubKey, senderSig, 
        // output
        receiverAddress, nftOutputSatoshis, opReturnScript, changeAddress, changeSatoshis, 
        // checkInputIndex,
        // checkScriptTx,
        // checkScriptTxOutIndex,
        // lockContractInputIndex,
        // lockContractTx,
        // lockContractTxOutIndex,
        operation, }) {
            if (!genesisScript) {
                genesisScript = new scryptlib_1.Bytes('');
            }
            if (operation != nft_proto_1.NFT_OP_TYPE.TRANSFER) {
                senderPubKey = new scryptlib_1.PubKey('00');
                senderSig = new scryptlib_1.Sig('00');
                receiverAddress = new scryptlib_1.Bytes('');
                nftOutputSatoshis = new scryptlib_1.Int(0);
                opReturnScript = new scryptlib_1.Bytes('');
                changeAddress = new scryptlib_1.Ripemd160('00');
                changeSatoshis = new scryptlib_1.Int(0);
            }
            return this._contract.unlock(txPreimage, prevouts, 
            // nft
            prevNftInputIndex, prevNftAddress, nftTxHeader, nftTxInputProof, prevNftTxProof, genesisScript, 
            // contract
            contractInputIndex, contractTxProof, 
            // unlockCheck
            amountCheckHashIndex, amountCheckInputIndex, amountCheckTxProof, amountCheckScrypt, 
            // sig
            senderPubKey, senderSig, 
            // output
            receiverAddress, nftOutputSatoshis, opReturnScript, changeAddress, changeSatoshis, 
            // checkInputIndex,
            // checkScriptTx,
            // checkScriptTxOutIndex,
            // lockContractInputIndex,
            // lockContractTx,
            // lockContractTxOutIndex,
            operation);
        }
    }
    exports.Nft = Nft;
    class NftFactory {
        static getLockingScriptSize() {
            return this.lockingScriptSize;
        }
        static createContract(unlockContractCodeHashArray, version = 2) {
            return new Nft({
                unlockContractCodeHashArray,
            }, version);
        }
        static getDummyInstance() {
            let contract = this.createContract(contractUtil_1.ContractUtil.unlockContractCodeHashArray);
            contract.setFormatedDataPart({});
            return contract;
        }
        static calLockingScriptSize() {
            let contract = this.getDummyInstance();
            return contract.lockingScript.toBuffer().length;
        }
        static calUnlockingScriptSize(bsvInputLen, genesisScript, opreturnData, operation) {
            return 10000;
            // let opreturnScriptHex = ''
            // if (opreturnData) {
            //   let script = mvc.Script.buildSafeDataOut(opreturnData)
            //   opreturnScriptHex = script.toHex()
            // }
            // let contract = this.getDummyInstance()
            // const preimage = getPreimage(dummyTx, contract.lockingScript.toASM(), 1)
            // const sig = Buffer.from(PLACE_HOLDER_SIG, 'hex')
            // const rabinMsg = new Bytes(dummyPayload)
            // const rabinPaddingArray: Bytes[] = []
            // const rabinSigArray: Int[] = []
            // const rabinPubKeyIndexArray: number[] = []
            // const rabinPubKeyArray: Int[] = []
            // const nftInputIndex = 0
            // let prevouts = Buffer.alloc(0)
            // const indexBuf = TokenUtil.getUInt32Buf(0)
            // const txidBuf = TokenUtil.getTxIdBuf(dummyTxId)
            // for (let i = 0; i < 1 + bsvInputLen; i++) {
            //   prevouts = Buffer.concat([prevouts, txidBuf, indexBuf])
            // }
            // let unlockCheckContact = NftUnlockContractCheckFactory.getDummyInstance(
            //   NFT_UNLOCK_CONTRACT_TYPE.OUT_6
            // )
            // let checkScriptTx = new mvc.Transaction(dummyTx.serialize(true))
            // checkScriptTx.addOutput(
            //   new mvc.Transaction.Output({
            //     script: unlockCheckContact.lockingScript,
            //     satoshis: 10000,
            //   })
            // )
            // let sellContract = NftSellFactory.getDummyInstance()
            // let sellTx = new mvc.Transaction(dummyTx.serialize(true))
            // sellTx.addOutput(
            //   new mvc.Transaction.Output({
            //     script: sellContract.lockingScript,
            //     satoshis: 10000,
            //   })
            // )
            // let changeSatoshis = 0
            // let unlockedContract = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   prevouts: new Bytes(toHex(prevouts)),
            //   rabinMsg,
            //   rabinPaddingArray,
            //   rabinSigArray,
            //   rabinPubKeyIndexArray,
            //   rabinPubKeyVerifyArray: rabinPubKeyArray,
            //   rabinPubKeyHashArray: new Bytes(toHex(dummyRabinPubKeyHashArray)),
            //   prevNftAddress: new Bytes(toHex(dummyAddress.hashBuffer)),
            //   genesisScript,
            //   senderPubKey: new PubKey(toHex(dummyPk)),
            //   senderSig: new Sig(toHex(sig)),
            //   receiverAddress: new Bytes(toHex(dummyAddress.hashBuffer)),
            //   nftOutputSatoshis: new Int(0),
            //   opReturnScript: new Bytes(opreturnScriptHex),
            //   changeAddress: new Ripemd160(toHex(dummyAddress.hashBuffer)),
            //   changeSatoshis: new Int(changeSatoshis),
            //   checkInputIndex: 0,
            //   checkScriptTx: new Bytes(checkScriptTx.serialize(true)),
            //   checkScriptTxOutIndex: 0,
            //   lockContractInputIndex: 0,
            //   lockContractTx: new Bytes(sellTx.serialize(true)),
            //   lockContractTxOutIndex: 0,
            //   operation,
            // })
            // return (unlockedContract.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.NftFactory = NftFactory;
    
    },{"../../common/ContractAdapter":382,"../../common/protoheader":389,"../../scryptlib":445,"../contract-desc/nft-v2_desc.json":397,"../contract-desc/nft_desc.json":405,"../contract-proto/nft.proto":411,"../contractUtil":414}],408:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.NftGenesisFactory = exports.NftGenesis = void 0;
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const protoheader_1 = require("../../common/protoheader");
    const scryptlib_1 = require("../../scryptlib");
    const nftProto = require("../contract-proto/nft.proto");
    const genesisTokenIDTxid = '0000000000000000000000000000000000000000000000000000000000000000';
    class NftGenesis extends ContractAdapter_1.ContractAdapter {
        constructor() {
            const desc = require('../contract-desc/nftGenesis_desc.json');
            let GenesisContractClass = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new GenesisContractClass();
            super(contract);
        }
        clone() {
            let contract = new NftGenesis();
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            this._formatedDataPart.genesisHash = '';
            this._formatedDataPart.protoVersion = nftProto.PROTO_VERSION;
            this._formatedDataPart.protoType = protoheader_1.PROTO_TYPE.NFT;
            const dataPartHex = nftProto.newDataPart(this._formatedDataPart).toString('hex');
            super.setDataPart(dataPartHex);
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        setFormatedDataPartFromLockingScript(script) {
            let dataPart = nftProto.parseDataPart(script.toBuffer());
            this.setFormatedDataPart(dataPart);
        }
        isFirstGenesis() {
            return this.getFormatedDataPart().sensibleID.txid == genesisTokenIDTxid;
        }
        unlock({ txPreimage, 
        // sig
        pubKey, sig, 
        // GenesisTx Input Proof
        genesisTxHeader, prevInputIndex, genesisTxInputProof, 
        // Prev GenesisTx Output Proof
        prevGenesisTxHeader, prevTxOutputHashProof, prevTxOutputSatoshiBytes, 
        // output
        nftScript, genesisSatoshis, nftSatoshis, changeAddress, changeSatoshis, opReturnScript, }) {
            return this._contract.unlock(txPreimage, pubKey, sig, genesisTxHeader, prevInputIndex, genesisTxInputProof, prevGenesisTxHeader, prevTxOutputHashProof, prevTxOutputSatoshiBytes, nftScript, genesisSatoshis, nftSatoshis, changeAddress, changeSatoshis, opReturnScript);
        }
    }
    exports.NftGenesis = NftGenesis;
    class NftGenesisFactory {
        static getLockingScriptSize() {
            return this.lockingScriptSize;
        }
        static createContract() {
            return new NftGenesis();
        }
        static getDummyInstance() {
            let contract = this.createContract();
            contract.setFormatedDataPart({});
            return contract;
        }
        static calLockingScriptSize() {
            let contract = this.getDummyInstance();
            let size = contract.lockingScript.toBuffer().length;
            return size;
        }
        static calUnlockingScriptSize(opreturnData) {
            return 10000;
            // let opreturnScriptHex = ''
            // if (opreturnData) {
            //   let script = mvc.Script.buildSafeDataOut(opreturnData)
            //   opreturnScriptHex = script.toHex()
            // }
            // let contract = this.getDummyInstance()
            // let tokenContract = NftFactory.getDummyInstance()
            // const preimage = getPreimage(dummyTx, contract.lockingScript.toASM(), 1)
            // const sig = Buffer.from(PLACE_HOLDER_SIG, 'hex')
            // const rabinMsg = dummyPayload
            // const rabinPaddingArray = []
            // const rabinSigArray: Int[] = []
            // const rabinPubKeyIndexArray = []
            // const rabinPubKeyArray: Int[] = []
            // let unlockResult = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   sig: new Sig(toHex(sig)),
            //   rabinMsg: new Bytes(toHex(rabinMsg)),
            //   rabinPaddingArray,
            //   rabinSigArray,
            //   rabinPubKeyIndexArray,
            //   rabinPubKeyVerifyArray: rabinPubKeyArray,
            //   rabinPubKeyHashArray: new Bytes(toHex(dummyRabinPubKeyHashArray)),
            //   genesisSatoshis: 1000,
            //   nftScript: new Bytes(tokenContract.lockingScript.toHex()),
            //   nftSatoshis: 1000,
            //   changeAddress: new Ripemd160(toHex(dummyAddress.hashBuffer)),
            //   changeSatoshis: 1000,
            //   opReturnScript: new Bytes(opreturnScriptHex),
            // })
            // return (unlockResult.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.NftGenesisFactory = NftGenesisFactory;
    
    },{"../../common/ContractAdapter":382,"../../common/protoheader":389,"../../scryptlib":445,"../contract-desc/nftGenesis_desc.json":398,"../contract-proto/nft.proto":411}],409:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.NftSellFactory = exports.NftSell = exports.NFT_SELL_OP = void 0;
    const bn_js_1 = require("../../bn.js");
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const dummy_1 = require("../../common/dummy");
    const protoheader_1 = require("../../common/protoheader");
    const utils_1 = require("../../common/utils");
    const scryptlib_1 = require("../../scryptlib");
    const nftSellProto = require("../../mcp01/contract-proto/nftSell.proto");
    const nft_1 = require("./nft");
    var NFT_SELL_OP;
    (function (NFT_SELL_OP) {
        NFT_SELL_OP[NFT_SELL_OP["SELL"] = 1] = "SELL";
        NFT_SELL_OP[NFT_SELL_OP["CANCEL"] = 2] = "CANCEL";
    })(NFT_SELL_OP = exports.NFT_SELL_OP || (exports.NFT_SELL_OP = {}));
    class NftSell extends ContractAdapter_1.ContractAdapter {
        static getClass() {
            const desc = require('../contract-desc/nftSell_desc.json');
            let NftSellContractClass = (0, scryptlib_1.buildContractClass)(desc);
            return NftSellContractClass;
        }
        constructor(constuctParams) {
            let NftSellContractClass = NftSell.getClass();
            let contract = new NftSellContractClass(constuctParams.senderAddress, constuctParams.bsvRecAmount, constuctParams.nftCodeHash, constuctParams.nftID);
            super(contract);
            this.constuctParams = constuctParams;
        }
        static fromASM(asm) {
            let NftSellContractClass = NftSell.getClass();
            let contract = NftSellContractClass.fromASM(asm);
            let params = contract.scriptedConstructor.params;
            let senderAddress = params[0];
            let bsvRecAmount = parseInt(params[1].value);
            let nftCodeHash = params[2];
            let nftID = params[3];
            return new NftSell({ senderAddress, bsvRecAmount, nftCodeHash, nftID });
        }
        clone() {
            let contract = new NftSell(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            this._formatedDataPart.protoVersion = nftSellProto.PROTO_VERSION;
            this._formatedDataPart.protoType = protoheader_1.PROTO_TYPE.NFT_SELL;
            super.setDataPart((0, scryptlib_1.toHex)(nftSellProto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        setFormatedDataPartFromLockingScript(script) {
            let dataPart = nftSellProto.parseDataPart(script.toBuffer());
            this.setFormatedDataPart(dataPart);
        }
        unlock({ txPreimage, nftScript, // only cancel need
        senderPubKey, // only cancel need
        senderSig, // only cancel need
        nftOutputSatoshis, // only cancel need
        op, }) {
            if (op != NFT_SELL_OP.CANCEL) {
                nftScript = new scryptlib_1.Bytes('');
                senderPubKey = new scryptlib_1.PubKey('00');
                senderSig = new scryptlib_1.Sig('00');
                nftOutputSatoshis = 0;
            }
            return this._contract.unlock(txPreimage, nftScript, senderPubKey, senderSig, nftOutputSatoshis, op);
        }
    }
    exports.NftSell = NftSell;
    class NftSellFactory {
        static getLockingScriptSize() {
            return this.lockingScriptSize;
        }
        static createContract(senderAddress, bsvRecAmount, nftCodeHash, nftID) {
            return new NftSell({ senderAddress, bsvRecAmount, nftCodeHash, nftID });
        }
        static createFromASM(asm) {
            return NftSell.fromASM(asm);
        }
        static getDummyInstance() {
            let contract = this.createContract(new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(dummy_1.dummyAddress.hashBuffer)), 1000, new scryptlib_1.Bytes((0, scryptlib_1.toHex)(Buffer.alloc(20, 0))), new scryptlib_1.Bytes((0, scryptlib_1.toHex)(Buffer.alloc(36, 0))));
            return contract;
        }
        static calLockingScriptSize() {
            let contract = this.getDummyInstance();
            contract.setFormatedDataPart({
                codehash: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
                genesis: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
                tokenIndex: bn_js_1.BN.fromString('10000000000', 10),
                sellerAddress: (0, scryptlib_1.toHex)(dummy_1.dummyAddress.hashBuffer),
                satoshisPrice: bn_js_1.BN.fromString('100000000', 10),
                nftID: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
            });
            let size = contract.lockingScript.toBuffer().length;
            return size;
        }
        static calUnlockingScriptSize(op) {
            let contract = this.getDummyInstance();
            let nftContract = nft_1.NftFactory.getDummyInstance();
            const preimage = (0, scryptlib_1.getPreimage)(dummy_1.dummyTx, contract.lockingScript.toASM(), 1);
            const sig = Buffer.from(utils_1.PLACE_HOLDER_SIG, 'hex');
            let unlockResult = contract.unlock({
                txPreimage: new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)(preimage)),
                nftScript: new scryptlib_1.Bytes(nftContract.lockingScript.toHex()),
                senderPubKey: new scryptlib_1.PubKey((0, scryptlib_1.toHex)(dummy_1.dummyPk)),
                senderSig: new scryptlib_1.Sig((0, scryptlib_1.toHex)(sig)),
                nftOutputSatoshis: 1000,
                op,
            });
            return unlockResult.toScript().toBuffer().length;
        }
    }
    exports.NftSellFactory = NftSellFactory;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js":381,"../../common/ContractAdapter":382,"../../common/dummy":387,"../../common/protoheader":389,"../../common/utils":391,"../../mcp01/contract-proto/nftSell.proto":412,"../../scryptlib":445,"../contract-desc/nftSell_desc.json":399,"./nft":407,"buffer":84}],410:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.NftUnlockContractCheckFactory = exports.NFT_UNLOCK_CONTRACT_TYPE = exports.NftUnlockContractCheck = void 0;
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const dummy_1 = require("../../common/dummy");
    const scryptlib_1 = require("../../scryptlib");
    const unlockProto = require("../contract-proto/nftUnlockContractCheck.proto");
    class NftUnlockContractCheck extends ContractAdapter_1.ContractAdapter {
        constructor(constuctParams) {
            let desc;
            switch (constuctParams.unlockType) {
                case NFT_UNLOCK_CONTRACT_TYPE.OUT_3:
                    desc = require('../contract-desc/nftUnlockContractCheck_desc.json');
                    break;
                case NFT_UNLOCK_CONTRACT_TYPE.OUT_6:
                    desc = require('../contract-desc/nftUnlockContractCheck_6_desc.json');
                    break;
                case NFT_UNLOCK_CONTRACT_TYPE.OUT_10:
                    desc = require('../contract-desc/nftUnlockContractCheck_10_desc.json');
                    break;
                case NFT_UNLOCK_CONTRACT_TYPE.OUT_20:
                    desc = require('../contract-desc/nftUnlockContractCheck_20_desc.json');
                    break;
                case NFT_UNLOCK_CONTRACT_TYPE.OUT_100:
                    desc = require('../contract-desc/nftUnlockContractCheck_100_desc.json');
                    break;
                default:
                    throw 'invalid checkType';
            }
            const NftUnlockContractCheckClass = (0, scryptlib_1.buildContractClass)(desc);
            const unlockCheckContract = new NftUnlockContractCheckClass();
            super(unlockCheckContract);
            this.constuctParams = constuctParams;
        }
        clone() {
            let contract = new NftUnlockContractCheck(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            super.setDataPart((0, scryptlib_1.toHex)(unlockProto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        unlock({ txPreimage, prevouts, nftInputIndex, nftScript, nftTxHeader, nftTxHashProof, nftSatoshiBytes, nOutputs, txNftOutputIndex, nftOutputAddress, nftOutputSatoshis, otherOutputArray, }) {
            return this._contract.unlock(txPreimage, prevouts, 
            // nft
            nftInputIndex, nftScript, nftTxHeader, nftTxHashProof, nftSatoshiBytes, 
            // output
            nOutputs, txNftOutputIndex, nftOutputAddress, nftOutputSatoshis, otherOutputArray);
        }
    }
    exports.NftUnlockContractCheck = NftUnlockContractCheck;
    var NFT_UNLOCK_CONTRACT_TYPE;
    (function (NFT_UNLOCK_CONTRACT_TYPE) {
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["OUT_3"] = 1] = "OUT_3";
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["OUT_6"] = 2] = "OUT_6";
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["OUT_10"] = 3] = "OUT_10";
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["OUT_20"] = 4] = "OUT_20";
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["OUT_100"] = 5] = "OUT_100";
        NFT_UNLOCK_CONTRACT_TYPE[NFT_UNLOCK_CONTRACT_TYPE["UNSUPPORT"] = 6] = "UNSUPPORT";
    })(NFT_UNLOCK_CONTRACT_TYPE = exports.NFT_UNLOCK_CONTRACT_TYPE || (exports.NFT_UNLOCK_CONTRACT_TYPE = {}));
    let _unlockContractTypeInfos = [
        {
            type: NFT_UNLOCK_CONTRACT_TYPE.OUT_3,
            out: 3,
            lockingScriptSize: 0,
        },
        {
            type: NFT_UNLOCK_CONTRACT_TYPE.OUT_6,
            out: 6,
            lockingScriptSize: 0,
        },
        {
            type: NFT_UNLOCK_CONTRACT_TYPE.OUT_10,
            out: 10,
            lockingScriptSize: 0,
        },
        {
            type: NFT_UNLOCK_CONTRACT_TYPE.OUT_20,
            out: 20,
            lockingScriptSize: 0,
        },
        {
            type: NFT_UNLOCK_CONTRACT_TYPE.OUT_100,
            out: 100,
            lockingScriptSize: 0,
        },
    ];
    class NftUnlockContractCheckFactory {
        static getLockingScriptSize(unlockType) {
            return this.unlockContractTypeInfos.find((v) => v.type == unlockType).lockingScriptSize;
        }
        static getOptimumType(outCount) {
            if (outCount <= 3) {
                return NFT_UNLOCK_CONTRACT_TYPE.OUT_3;
            }
            else if (outCount <= 6) {
                return NFT_UNLOCK_CONTRACT_TYPE.OUT_6;
            }
            else if (outCount <= 10) {
                return NFT_UNLOCK_CONTRACT_TYPE.OUT_10;
            }
            else if (outCount <= 20) {
                return NFT_UNLOCK_CONTRACT_TYPE.OUT_20;
            }
            else if (outCount <= 100) {
                return NFT_UNLOCK_CONTRACT_TYPE.OUT_100;
            }
            else {
                return NFT_UNLOCK_CONTRACT_TYPE.UNSUPPORT;
            }
        }
        static createContract(unlockType) {
            return new NftUnlockContractCheck({ unlockType });
        }
        static getDummyInstance(unlockType) {
            let contract = this.createContract(unlockType);
            contract.setFormatedDataPart({
                nftID: dummy_1.dummyCodehash.toBuffer(),
                nftCodeHash: Buffer.from('0000000000000000000000000000000000000000', 'hex'),
            });
            return contract;
        }
        static calLockingScriptSize(unlockType) {
            let contract = this.getDummyInstance(unlockType);
            return contract.lockingScript.toBuffer().length;
        }
        static calUnlockingScriptSize(unlockType, prevouts, otherOutputArray) {
            return 10000; // TODO
            // let contract = this.getDummyInstance(unlockType)
            // let nftContractInstance = NftFactory.getDummyInstance()
            // const preimage = getPreimage(dummyTx, contract.lockingScript.toASM(), 1)
            // const rabinMsg = new Bytes(dummyPayload)
            // let paddingCountBuf = Buffer.alloc(2, 0)
            // paddingCountBuf.writeUInt16LE(dummyPadding.length / 2)
            // const padding = Buffer.alloc(dummyPadding.length / 2, 0)
            // padding.write(dummyPadding, 'hex')
            // const rabinPaddingArray: Bytes[] = []
            // const rabinSigArray: Int[] = []
            // const rabinPubKeyIndexArray: number[] = []
            // const rabinPubKeyArray: Int[] = []
            // let tokenAmount = Buffer.alloc(8)
            // tokenAmount.writeInt32BE(100000)
            // let unlockedContract = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   nftInputIndex: 0,
            //   nftScript: new Bytes(nftContractInstance.lockingScript.toHex()),
            //   prevouts: prevouts,
            //   rabinMsg: rabinMsg,
            //   rabinPaddingArray: rabinPaddingArray,
            //   rabinSigArray: rabinSigArray,
            //   rabinPubKeyIndexArray,
            //   rabinPubKeyVerifyArray: rabinPubKeyArray,
            //   rabinPubKeyHashArray: new Bytes(toHex(dummyRabinPubKeyHashArray)),
            //   nOutputs: 2,
            //   nftOutputIndex: 0,
            //   nftOutputAddress: new Bytes(toHex(dummyAddress.hashBuffer)),
            //   nftOutputSatoshis: 1000,
            //   otherOutputArray,
            // })
            // return (unlockedContract.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.NftUnlockContractCheckFactory = NftUnlockContractCheckFactory;
    NftUnlockContractCheckFactory.unlockContractTypeInfos = _unlockContractTypeInfos;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../common/ContractAdapter":382,"../../common/dummy":387,"../../scryptlib":445,"../contract-desc/nftUnlockContractCheck_100_desc.json":400,"../contract-desc/nftUnlockContractCheck_10_desc.json":401,"../contract-desc/nftUnlockContractCheck_20_desc.json":402,"../contract-desc/nftUnlockContractCheck_6_desc.json":403,"../contract-desc/nftUnlockContractCheck_desc.json":404,"../contract-proto/nftUnlockContractCheck.proto":413,"buffer":84}],411:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.getQuerySensibleID = exports.getQueryGenesis = exports.getQueryCodehash = exports.updateScript = exports.parseDataPart = exports.newDataPart = exports.getSensibleID = exports.getMetaidOutpoint = exports.getContractCodeHash = exports.getContractCode = exports.getNftAddress = exports.getTotalSupply = exports.getNftID = exports.getTokenIndex = exports.getGenesisHash = exports.EMPTY_ADDRESS = exports.GENESIS_TOKEN_ID = exports.PROTO_VERSION = exports.NFT_OP_TYPE = void 0;
    const mvc = require("../../mvc");
    const proto = require("../../common/protoheader");
    const Utils = require("../../common/utils");
    const scryptlib_1 = require("../../scryptlib");
    const BN = require("../../bn.js");
    const tokenUtil_1 = require("../../common/tokenUtil");
    var NFT_OP_TYPE;
    (function (NFT_OP_TYPE) {
        NFT_OP_TYPE[NFT_OP_TYPE["TRANSFER"] = 1] = "TRANSFER";
        NFT_OP_TYPE[NFT_OP_TYPE["UNLOCK_FROM_CONTRACT"] = 2] = "UNLOCK_FROM_CONTRACT";
    })(NFT_OP_TYPE = exports.NFT_OP_TYPE || (exports.NFT_OP_TYPE = {}));
    exports.PROTO_VERSION = 1;
    // <type specific data> + <proto header>
    // <proto header> = <type(4 bytes)> + <'sensible'(8 bytes)>
    //<nft type specific data> = <metaid_outpoint(36 bytes)> + <address(20 bytes)> + <totalSupply(8 bytes) + <tokenIndex(8 bytes)> + <genesisHash<20 bytes>) + + <sensibleID(36 bytes)>
    const SENSIBLE_ID_LEN = 36;
    const GENESIS_HASH_LEN = 20;
    const TOKEN_INDEX_LEN = 8;
    const NFT_ID_LEN = 20;
    const TOTAL_SUPPLY_LEN = 8;
    const NFT_ADDRESS_LEN = 20;
    const METAID_OUTPOINT_LEN = 36;
    const SENSIBLE_ID_OFFSET = SENSIBLE_ID_LEN + proto.getHeaderLen();
    const GENESIS_HASH_OFFSET = SENSIBLE_ID_OFFSET + GENESIS_HASH_LEN;
    const TOKEN_INDEX_OFFSET = GENESIS_HASH_OFFSET + TOKEN_INDEX_LEN;
    const TOTAL_SUPPLY_OFFSET = TOKEN_INDEX_OFFSET + TOTAL_SUPPLY_LEN;
    const NFT_ADDRESS_OFFSET = TOTAL_SUPPLY_OFFSET + NFT_ADDRESS_LEN;
    const METAID_OUTPOINT_OFFSET = NFT_ADDRESS_OFFSET + METAID_OUTPOINT_LEN;
    const DATA_LEN = METAID_OUTPOINT_OFFSET;
    // const OP_PUSH_LEN = 2
    // const DATA_LEN = METAID_OUTPOINT_OFFSET + OP_PUSH_LEN
    exports.GENESIS_TOKEN_ID = Buffer.alloc(NFT_ID_LEN, 0);
    exports.EMPTY_ADDRESS = Buffer.alloc(NFT_ADDRESS_LEN, 0);
    function getGenesisHash(script) {
        return script
            .slice(script.length - GENESIS_HASH_OFFSET, script.length - GENESIS_HASH_OFFSET + GENESIS_HASH_LEN)
            .toString('hex');
    }
    exports.getGenesisHash = getGenesisHash;
    function getTokenIndex(script) {
        if (script.length < TOKEN_INDEX_OFFSET)
            return BN.Zero;
        return BN.fromBuffer(script.slice(script.length - TOKEN_INDEX_OFFSET, script.length - TOKEN_INDEX_OFFSET + TOKEN_INDEX_LEN), { endian: 'little' });
    }
    exports.getTokenIndex = getTokenIndex;
    // sensibleID
    function getNftID(script) {
        return mvc.crypto.Hash.sha256ripemd160(script.slice(script.length - TOKEN_INDEX_OFFSET, script.length - proto.getHeaderLen()));
    }
    exports.getNftID = getNftID;
    function getTotalSupply(script) {
        if (script.length < TOTAL_SUPPLY_OFFSET)
            return BN.Zero;
        return BN.fromBuffer(script.slice(script.length - TOTAL_SUPPLY_OFFSET, script.length - TOTAL_SUPPLY_OFFSET + TOTAL_SUPPLY_LEN), { endian: 'little' });
    }
    exports.getTotalSupply = getTotalSupply;
    function getNftAddress(script) {
        if (script.length < NFT_ADDRESS_OFFSET)
            return '';
        return script
            .slice(script.length - NFT_ADDRESS_OFFSET, script.length - NFT_ADDRESS_OFFSET + NFT_ADDRESS_LEN)
            .toString('hex');
    }
    exports.getNftAddress = getNftAddress;
    function getContractCode(script) {
        return script.slice(0, script.length - DATA_LEN - Utils.getVarPushdataHeader(DATA_LEN).length);
    }
    exports.getContractCode = getContractCode;
    function getContractCodeHash(script) {
        return mvc.crypto.Hash.sha256ripemd160(getContractCode(script));
    }
    exports.getContractCodeHash = getContractCodeHash;
    function getMetaidOutpoint(script0) {
        if (script0.length < METAID_OUTPOINT_OFFSET)
            return { txid: '', index: 0 };
        let script = Buffer.from(script0);
        let metaidOutpointBuf = script.slice(script.length - METAID_OUTPOINT_OFFSET, script.length - METAID_OUTPOINT_OFFSET + METAID_OUTPOINT_LEN);
        let txid = metaidOutpointBuf.slice(0, 32).reverse().toString('hex'); //reverse会改变原对象
        let index = metaidOutpointBuf.readUIntLE(32, 4);
        let outpoint = { txid, index };
        return outpoint;
    }
    exports.getMetaidOutpoint = getMetaidOutpoint;
    function getSensibleID(script0) {
        if (script0.length < SENSIBLE_ID_OFFSET)
            return { txid: '', index: 0 };
        let script = Buffer.from(script0);
        let sensibleIDBuf = script.slice(script.length - SENSIBLE_ID_OFFSET, script.length - SENSIBLE_ID_OFFSET + SENSIBLE_ID_LEN);
        let txid = sensibleIDBuf.slice(0, 32).reverse().toString('hex'); //reverse会改变原对象
        let index = sensibleIDBuf.readUIntLE(32, 4);
        let outpoint = { txid, index };
        return outpoint;
    }
    exports.getSensibleID = getSensibleID;
    function newDataPart({ metaidOutpoint, nftAddress, totalSupply, tokenIndex, genesisHash, sensibleID, protoVersion, protoType, }) {
        let metaidOutpointBuf = Buffer.alloc(METAID_OUTPOINT_LEN, 0);
        if (metaidOutpoint && metaidOutpoint.txid) {
            const txidBuf = Buffer.from(metaidOutpoint.txid, 'hex').reverse();
            const indexBuf = Buffer.alloc(4, 0);
            indexBuf.writeUInt32LE(metaidOutpoint.index);
            metaidOutpointBuf = Buffer.concat([txidBuf, indexBuf]);
        }
        let nftAddressBuf = Buffer.alloc(NFT_ADDRESS_LEN, 0);
        if (nftAddress) {
            // nftAddressBuf.write(nftAddress, 'hex')
            nftAddressBuf = Buffer.from(nftAddress, 'hex');
        }
        let totalSupplyBuf = Buffer.alloc(TOTAL_SUPPLY_LEN, 0);
        if (totalSupply) {
            totalSupplyBuf = totalSupply
                .toBuffer({ endian: 'little', size: TOTAL_SUPPLY_LEN })
                .slice(0, TOTAL_SUPPLY_LEN);
        }
        let tokenIndexBuf = Buffer.alloc(TOKEN_INDEX_LEN, 0);
        if (tokenIndex) {
            tokenIndexBuf = tokenIndex.toBuffer({
                endian: 'little',
                size: TOKEN_INDEX_LEN,
            });
        }
        const genesisHashBuf = Buffer.alloc(GENESIS_HASH_LEN, 0);
        if (genesisHash) {
            genesisHashBuf.write(genesisHash, 'hex');
        }
        let sensibleIDBuf = Buffer.alloc(SENSIBLE_ID_LEN, 0);
        if (sensibleID) {
            const txidBuf = Buffer.from(sensibleID.txid, 'hex').reverse();
            const indexBuf = Buffer.alloc(4, 0);
            indexBuf.writeUInt32LE(sensibleID.index);
            sensibleIDBuf = Buffer.concat([txidBuf, indexBuf]);
        }
        const protoVersionBuf = Buffer.alloc(proto.PROTO_VERSION_LEN);
        if (protoVersion) {
            protoVersionBuf.writeUInt32LE(protoVersion);
        }
        const protoTypeBuf = Buffer.alloc(proto.PROTO_TYPE_LEN, 0);
        if (protoType) {
            protoTypeBuf.writeUInt32LE(protoType);
        }
        const buf = Buffer.concat([
            metaidOutpointBuf,
            nftAddressBuf,
            totalSupplyBuf,
            tokenIndexBuf,
            genesisHashBuf,
            sensibleIDBuf,
            protoVersionBuf,
            protoTypeBuf,
            proto.PROTO_FLAG,
        ]);
        return (0, tokenUtil_1.buildScriptData)(buf);
    }
    exports.newDataPart = newDataPart;
    function parseDataPart(scriptBuf) {
        let metaidOutpoint = getMetaidOutpoint(scriptBuf);
        let nftAddress = getNftAddress(scriptBuf);
        let totalSupply = getTotalSupply(scriptBuf);
        let tokenIndex = getTokenIndex(scriptBuf);
        let genesisHash = getGenesisHash(scriptBuf);
        let sensibleID = getSensibleID(scriptBuf);
        let protoVersion = proto.getProtoVersion(scriptBuf);
        let protoType = proto.getProtoType(scriptBuf);
        // const scriptHexLen = scriptBuf.toString('hex').length
        // const scriptLen = scriptBuf.length
        // const protoVersion1 = proto.getProtoVersion(scriptBuf)
        // const protoVersion2 = scriptBuf.toString('hex').slice(scriptHexLen - 40, scriptHexLen - 32)
        // const metacontract = Buffer.from('metacontract')
        // const metacontract2 = proto.getFlag(scriptBuf)
        // console.log(
        //   'parsing',
        //   scriptBuf.toString('hex'),
        //   scriptHexLen,
        //   scriptLen,
        //   protoVersion1,
        //   protoVersion2,
        //   metacontract.toString('hex'),
        //   metacontract2.toString('hex'),
        //   proto.PROTO_FLAG_LEN,
        //   proto.PROTO_FLAG.toString('hex')
        // )
        return {
            metaidOutpoint,
            nftAddress,
            totalSupply,
            tokenIndex,
            genesisHash,
            sensibleID,
            protoVersion,
            protoType,
        };
    }
    exports.parseDataPart = parseDataPart;
    function updateScript(scriptBuf, dataPartObj) {
        const firstBuf = scriptBuf.slice(0, scriptBuf.length - DATA_LEN);
        const dataPart = newDataPart(dataPartObj);
        return Buffer.concat([firstBuf, dataPart]);
    }
    exports.updateScript = updateScript;
    function getQueryCodehash(script) {
        return (0, scryptlib_1.toHex)(getContractCodeHash(script));
    }
    exports.getQueryCodehash = getQueryCodehash;
    function getQueryGenesis(script) {
        return (0, scryptlib_1.toHex)(mvc.crypto.Hash.sha256ripemd160(script.slice(script.length - GENESIS_HASH_OFFSET, script.length - proto.getHeaderLen())
        // [len - (20+36+25), len - 25]
        ));
    }
    exports.getQueryGenesis = getQueryGenesis;
    function getQuerySensibleID(script0) {
        let script = Buffer.from(script0);
        let sensibleIDBuf = script.slice(script.length - SENSIBLE_ID_OFFSET, script.length - SENSIBLE_ID_OFFSET + SENSIBLE_ID_LEN);
        return (0, scryptlib_1.toHex)(sensibleIDBuf);
    }
    exports.getQuerySensibleID = getQuerySensibleID;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js":381,"../../common/protoheader":389,"../../common/tokenUtil":390,"../../common/utils":391,"../../mvc":440,"../../scryptlib":445,"buffer":84}],412:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.parseDataPart = exports.newDataPart = exports.getCodeHash = exports.getGenesis = exports.getTokenIndex = exports.getSellerAddress = exports.getSatoshisPrice = exports.getNftID = exports.PROTO_VERSION = void 0;
    const tokenUtil_1 = require("../../common/tokenUtil");
    const BN = require("../../bn.js/index.js");
    const proto = require("../../common/protoheader");
    const scryptlib_1 = require("../../scryptlib");
    exports.PROTO_VERSION = 1;
    const NFT_ID_LEN = 20;
    const SATOSHIS_PRICE_LEN = 8;
    const SELLER_ADDRESS_LEN = 20;
    const TOKEN_INDEX_LEN = 8;
    const GENESIS_LEN = 20;
    const CODEHASH_LEN = 20;
    const NFT_ID_OFFSET = NFT_ID_LEN + proto.getHeaderLen();
    const SATOSHIS_PRICE_OFFSET = SATOSHIS_PRICE_LEN + NFT_ID_OFFSET;
    const SELLER_ADDRESS_OFFSET = SELLER_ADDRESS_LEN + SATOSHIS_PRICE_OFFSET;
    const TOKEN_INDEX_OFFSET = TOKEN_INDEX_LEN + SELLER_ADDRESS_OFFSET;
    const GENESIS_OFFSET = GENESIS_LEN + TOKEN_INDEX_OFFSET;
    const CODEHASH_OFFSET = CODEHASH_LEN + GENESIS_OFFSET;
    function getNftID(script) {
        return (0, scryptlib_1.toHex)(script.slice(script.length - NFT_ID_OFFSET, script.length - NFT_ID_OFFSET + NFT_ID_LEN));
    }
    exports.getNftID = getNftID;
    function getSatoshisPrice(script) {
        if (script.length < SATOSHIS_PRICE_OFFSET)
            return BN.Zero;
        return BN.fromBuffer(script.slice(script.length - SATOSHIS_PRICE_OFFSET, script.length - SATOSHIS_PRICE_OFFSET + SATOSHIS_PRICE_LEN), { endian: 'little' });
    }
    exports.getSatoshisPrice = getSatoshisPrice;
    function getSellerAddress(script) {
        if (script.length < SELLER_ADDRESS_OFFSET)
            return '';
        return script
            .slice(script.length - SELLER_ADDRESS_OFFSET, script.length - SELLER_ADDRESS_OFFSET + SELLER_ADDRESS_LEN)
            .toString('hex');
    }
    exports.getSellerAddress = getSellerAddress;
    function getTokenIndex(script) {
        if (script.length < TOKEN_INDEX_OFFSET)
            return BN.Zero;
        return BN.fromBuffer(script.slice(script.length - TOKEN_INDEX_OFFSET, script.length - TOKEN_INDEX_OFFSET + TOKEN_INDEX_LEN), { endian: 'little' });
    }
    exports.getTokenIndex = getTokenIndex;
    function getGenesis(script) {
        if (script.length < GENESIS_OFFSET)
            return '';
        return script
            .slice(script.length - GENESIS_OFFSET, script.length - GENESIS_OFFSET + GENESIS_LEN)
            .toString('hex');
    }
    exports.getGenesis = getGenesis;
    function getCodeHash(script) {
        if (script.length < CODEHASH_OFFSET)
            return '';
        return script
            .slice(script.length - CODEHASH_OFFSET, script.length - CODEHASH_OFFSET + CODEHASH_LEN)
            .toString('hex');
    }
    exports.getCodeHash = getCodeHash;
    function newDataPart({ codehash, genesis, tokenIndex, sellerAddress, satoshisPrice, nftID, protoVersion, protoType, }) {
        const codehashBuf = Buffer.alloc(20, 0);
        if (nftID) {
            codehashBuf.write(codehash, 'hex');
        }
        const genesisBuf = Buffer.alloc(20, 0);
        if (nftID) {
            genesisBuf.write(genesis, 'hex');
        }
        let tokenIndexBuf = Buffer.alloc(TOKEN_INDEX_LEN, 0);
        if (tokenIndex) {
            tokenIndexBuf = tokenIndex.toBuffer({ endian: 'little', size: 8 });
        }
        const sellerAddressBuf = Buffer.alloc(SELLER_ADDRESS_LEN, 0);
        if (sellerAddress) {
            sellerAddressBuf.write(sellerAddress, 'hex');
        }
        let priceBuf = Buffer.alloc(SATOSHIS_PRICE_LEN, 0);
        if (satoshisPrice) {
            priceBuf = satoshisPrice.toBuffer({ endian: 'little', size: 8 });
        }
        const nftIDBuf = Buffer.alloc(NFT_ID_LEN, 0);
        if (nftID) {
            nftIDBuf.write(nftID, 'hex');
        }
        const protoVersionBuf = Buffer.alloc(proto.PROTO_VERSION_LEN);
        if (protoVersion) {
            protoVersionBuf.writeUInt32LE(protoVersion);
        }
        const protoTypeBuf = Buffer.alloc(proto.PROTO_TYPE_LEN, 0);
        if (protoType) {
            protoTypeBuf.writeUInt32LE(protoType);
        }
        const buf = Buffer.concat([
            codehashBuf,
            genesisBuf,
            tokenIndexBuf,
            sellerAddressBuf,
            priceBuf,
            nftIDBuf,
            protoVersionBuf,
            protoTypeBuf,
            proto.PROTO_FLAG,
        ]);
        return (0, tokenUtil_1.buildScriptData)(buf);
    }
    exports.newDataPart = newDataPart;
    function parseDataPart(scriptBuf) {
        let codehash = getCodeHash(scriptBuf);
        let genesis = getGenesis(scriptBuf);
        let tokenIndex = getTokenIndex(scriptBuf);
        let sellerAddress = getSellerAddress(scriptBuf);
        let satoshisPrice = getSatoshisPrice(scriptBuf);
        let nftID = getNftID(scriptBuf);
        let protoVersion = proto.getProtoVersion(scriptBuf);
        let protoType = proto.getProtoType(scriptBuf);
        return {
            codehash,
            genesis,
            tokenIndex,
            sellerAddress,
            satoshisPrice,
            nftID,
            protoVersion,
            protoType,
        };
    }
    exports.parseDataPart = parseDataPart;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js/index.js":381,"../../common/protoheader":389,"../../common/tokenUtil":390,"../../scryptlib":445,"buffer":84}],413:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.parseDataPart = exports.newDataPart = exports.getNftCodehHash = exports.getNftID = void 0;
    const tokenUtil_1 = require("../../common/tokenUtil");
    const NFT_ID_LEN = 36;
    const NFT_CODE_HASH_LEN = 20;
    const DATA_VERSION_LEN = 5;
    const NFT_ID_OFFSET = DATA_VERSION_LEN + NFT_ID_LEN;
    const NFT_CODE_HASH_OFFSET = NFT_ID_OFFSET + NFT_CODE_HASH_LEN;
    function getNftID(script) {
        return script.slice(script.length - NFT_ID_OFFSET, script.length - NFT_ID_OFFSET + NFT_ID_LEN);
    }
    exports.getNftID = getNftID;
    function getNftCodehHash(script) {
        return script.slice(script.length - NFT_CODE_HASH_OFFSET, script.length - NFT_CODE_HASH_OFFSET + NFT_CODE_HASH_LEN);
    }
    exports.getNftCodehHash = getNftCodehHash;
    function newDataPart(dataPart) {
        const buf = Buffer.concat([dataPart.nftCodeHash, dataPart.nftID]);
        return (0, tokenUtil_1.buildScriptData)(buf);
    }
    exports.newDataPart = newDataPart;
    function parseDataPart(scriptBuf) {
        let nftID = getNftID(scriptBuf);
        let nftCodeHash = getNftCodehHash(scriptBuf);
        return {
            nftID,
            nftCodeHash,
        };
    }
    exports.parseDataPart = parseDataPart;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../common/tokenUtil":390,"buffer":84}],414:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ContractUtil = void 0;
    const mvc_scrypt_1 = require("mvc-scrypt");
    const nft_1 = require("./contract-factory/nft");
    const nftGenesis_1 = require("./contract-factory/nftGenesis");
    const nftSell_1 = require("./contract-factory/nftSell");
    const nftUnlockContractCheck_1 = require("./contract-factory/nftUnlockContractCheck");
    function getNftUnlockContractCheckCodeHashArray() {
        let contractArray = [
            nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_3),
            nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_6),
            nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_10),
            nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_20),
            nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_100),
        ];
        return contractArray.map((v) => v.getCodeHash());
    }
    class ContractUtil {
        static init(config) {
            if (config) {
                this.unlockContractCodeHashArray = config.unlockContractCodeHashArray.map((v) => new mvc_scrypt_1.Bytes(v));
                nftGenesis_1.NftGenesisFactory.lockingScriptSize = config.tokenGenesisSize;
                nft_1.NftFactory.lockingScriptSize = config.tokenSize;
                nftSell_1.NftSellFactory.lockingScriptSize = config.nftSellSize;
                nftUnlockContractCheck_1.NftUnlockContractCheckFactory.unlockContractTypeInfos.forEach((v, idx) => {
                    v.lockingScriptSize = config.unlockContractSizes[idx];
                });
            }
            else {
                this.unlockContractCodeHashArray = getNftUnlockContractCheckCodeHashArray().map((v) => new mvc_scrypt_1.Bytes(v));
                nftGenesis_1.NftGenesisFactory.lockingScriptSize = nftGenesis_1.NftGenesisFactory.calLockingScriptSize();
                nft_1.NftFactory.lockingScriptSize = nft_1.NftFactory.calLockingScriptSize();
                nftSell_1.NftSellFactory.lockingScriptSize = nftSell_1.NftSellFactory.calLockingScriptSize();
                nftUnlockContractCheck_1.NftUnlockContractCheckFactory.unlockContractTypeInfos.forEach((v, idx) => {
                    v.lockingScriptSize = nftUnlockContractCheck_1.NftUnlockContractCheckFactory.calLockingScriptSize(v.type);
                });
            }
            let tokenContract = nft_1.NftFactory.getDummyInstance();
            this.tokenCodeHash = tokenContract.getCodeHash();
        }
    }
    exports.ContractUtil = ContractUtil;
    
    },{"./contract-factory/nft":407,"./contract-factory/nftGenesis":408,"./contract-factory/nftSell":409,"./contract-factory/nftUnlockContractCheck":410,"mvc-scrypt":282}],415:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.NftManager = void 0;
    const DustCalculator_1 = require("../common/DustCalculator");
    const tx_composer_1 = require("../tx-composer");
    const mvc = require("../mvc");
    const __1 = require("..");
    const nftGenesis_1 = require("./contract-factory/nftGenesis");
    const nftSell_1 = require("./contract-factory/nftSell");
    const transactionHelpers_1 = require("../helpers/transactionHelpers");
    const nft_1 = require("./contract-factory/nft");
    const scryptlib_1 = require("../scryptlib");
    const mvc_1 = require("../mvc");
    const TokenUtil = require("../common/tokenUtil");
    const nftProto = require("./contract-proto/nft.proto");
    const nftSellProto = require("./contract-proto/nftSell.proto");
    const Signature = mvc.crypto.Signature;
    const contractUtil_1 = require("./contractUtil");
    const utils_1 = require("../common/utils");
    const Prevouts_1 = require("../common/Prevouts");
    const error_1 = require("../common/error");
    const SizeTransaction_1 = require("../common/SizeTransaction");
    const protoheader_1 = require("../common/protoheader");
    const contractHelpers_1 = require("../helpers/contractHelpers");
    const proofHelpers_1 = require("../helpers/proofHelpers");
    const constants_1 = require("../mcp02/constants");
    const nftUnlockContractCheck_1 = require("./contract-factory/nftUnlockContractCheck");
    const dummy_1 = require("../common/dummy");
    contractUtil_1.ContractUtil.init();
    const jsonDescr = require('./contract-desc/txUtil_desc.json');
    const { TxInputProof, TxOutputProof } = (0, scryptlib_1.buildTypeClasses)(jsonDescr);
    function determineCodehashVersion(codehash) {
        if (codehash == contractUtil_1.ContractUtil.tokenCodeHash) {
            return 2;
        }
        return 1;
    }
    class NftManager {
        get api() {
            return this._api;
        }
        get sensibleApi() {
            return this._api;
        }
        constructor({ purse, network = __1.API_NET.MAIN, apiTarget = __1.API_TARGET.MVC, apiHost, feeb = constants_1.FEEB, debug = false, }) {
            this.dustCalculator = new DustCalculator_1.DustCalculator(mvc_1.Transaction.DUST_AMOUNT, null);
            this.network = network;
            this._api = new __1.Api(network, apiTarget, apiHost);
            this.unlockContractCodeHashArray = contractUtil_1.ContractUtil.unlockContractCodeHashArray;
            if (feeb)
                this.feeb = feeb;
            this.debug = debug;
            if (purse) {
                const privateKey = mvc.PrivateKey.fromWIF(purse);
                const address = privateKey.toAddress(this.network);
                this.purse = {
                    privateKey,
                    address,
                };
            }
        }
        /**
         * Estimate the cost of genesis
         * The minimum cost required in the case of 10 utxo inputs
         * @param opreturnData
         * @param utxoMaxCount Maximum number of MVC UTXOs supported
         * @returns
         */
        getGenesisEstimateFee({ opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                stx.addOutput(nftGenesis_1.NftGenesisFactory.getLockingScriptSize());
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        getIssueEstimateFee({ sensibleId, opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const { genesisUtxo } = (yield (0, transactionHelpers_1.getLatestGenesisInfo)({
                    sensibleId,
                    api: this.api,
                    address: this.purse.address,
                    type: 'nft',
                }));
                return yield this._calIssueEstimateFee({
                    genesisUtxoSatoshis: genesisUtxo.satoshis,
                    opreturnData,
                    utxoMaxCount,
                });
            });
        }
        getTransferEstimateFee({ tokenIndex, codehash, genesis, opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                const genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                return yield this._calTransferEstimateFee({
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    genesisScript,
                    opreturnData,
                    utxoMaxCount,
                });
            });
        }
        genesis({ version = 2, genesisWif, totalSupply, opreturnData, utxos: utxosInput, changeAddress, noBroadcast = false, calcFee = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                if (calcFee) {
                    return {
                        fee: yield this.getGenesisEstimateFee({ opreturnData }),
                        feeb: this.feeb,
                    };
                }
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxos[0].address;
                }
                const { txComposer, genesisContract } = yield this.createGenesisTx({
                    totalSupply,
                    utxos,
                    utxoPrivateKeys,
                    opreturnData,
                    changeAddress,
                });
                if (calcFee) {
                    // const unlockSize =
                    //   txComposer.tx.inputs.filter((v) => v.output.script.isPublicKeyHashOut()).length *
                    //   P2PKH_UNLOCK_SIZE
                    // let fee = Math.ceil(
                    //   (txComposer.tx.toBuffer().length + unlockSize + mvc.Transaction.CHANGE_OUTPUT_MAX_SIZE) *
                    //     this.feeb
                    // )
                    let fee = Math.ceil(txComposer.tx._estimateSize() * this.feeb);
                    return { fee, feeb: this.feeb };
                }
                let txHex = txComposer.getRawHex();
                let txid;
                if (!noBroadcast) {
                    txid = yield this.api.broadcast(txHex);
                }
                let { codehash, genesis, sensibleId } = (0, contractHelpers_1.getGenesisIdentifiers)({
                    version,
                    genesisTx: txComposer.getTx(),
                    purse: this.purse,
                    unlockContractCodeHashArray: this.unlockContractCodeHashArray,
                    type: 'nft',
                });
                return {
                    codehash,
                    genesis,
                    sensibleId,
                    tx: txComposer.tx,
                    txid: txComposer.tx.id,
                    txHex,
                    genesisContract,
                    broadcastStatus: noBroadcast ? 'pending' : txid ? 'success' : 'fail',
                };
            });
        }
        createGenesisTx({ totalSupply, utxos, utxoPrivateKeys, opreturnData, changeAddress, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                // 构建合约
                const genesisContract = (0, contractHelpers_1.createNftGenesisContract)({ totalSupply, address: this.purse.address });
                // 添加付钱输入、添加创世输出、添加找零输出、解锁输入
                const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    contract: genesisContract,
                    dustCalculator: this.dustCalculator,
                });
                //  添加opreturn输出
                if (opreturnData) {
                    (0, transactionHelpers_1.addOpreturnOutput)(txComposer, opreturnData);
                }
                (0, transactionHelpers_1.addChangeOutput)(txComposer, changeAddress, this.feeb);
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                // 检查最终费率
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { txComposer, genesisContract };
            });
        }
        issue(options) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.mint(options);
            });
        }
        mint({ version = 2, sensibleId, metaTxId, metaOutputIndex, opreturnData, utxos: utxosInput, receiverAddress, changeAddress, noBroadcast = false, calcFee = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                if (calcFee) {
                    return {
                        fee: yield this.getIssueEstimateFee({ sensibleId, opreturnData }),
                        feeb: this.feeb,
                    };
                }
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                const genesisPrivateKey = this.purse.privateKey;
                const genesisPublicKey = genesisPrivateKey.toPublicKey();
                if (receiverAddress) {
                    receiverAddress = new mvc.Address(receiverAddress, this.network);
                }
                else {
                    receiverAddress = this.purse.address;
                }
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxos[0].address;
                }
                if (calcFee) {
                    return yield this.createMintTx({
                        version,
                        utxos,
                        utxoPrivateKeys,
                        sensibleId,
                        metaTxId,
                        metaOutputIndex,
                        opreturnData,
                        receiverAddress,
                        changeAddress,
                        calcFee,
                    });
                }
                const { txComposer, tokenIndex } = yield this.createMintTx({
                    version,
                    utxos,
                    utxoPrivateKeys,
                    sensibleId,
                    metaTxId,
                    metaOutputIndex,
                    opreturnData,
                    receiverAddress,
                    changeAddress,
                });
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    const res = yield this.api.broadcast(txHex);
                }
                return { txHex, txid: txComposer.getTxId(), tx: txComposer.getTx(), tokenIndex };
            });
        }
        transfer({ genesis, codehash, tokenIndex, senderWif, receiverAddress, opreturnData, utxos: utxosInput, noBroadcast = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const startTime = Date.now();
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                receiverAddress = new mvc.Address(receiverAddress, this.network);
                const { txComposer } = yield this.createTransferTx({
                    utxos,
                    utxoPrivateKeys,
                    genesis,
                    codehash,
                    tokenIndex,
                    receiverAddress,
                    opreturnData,
                });
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(txHex);
                }
                const runtime = Date.now() - startTime;
                return { txHex, txid: txComposer.getTxId(), tx: txComposer.getTx(), runtime };
            });
        }
        sell({ genesis, codehash, tokenIndex, sellerWif, price, changeAddress, opreturnData, utxos: utxosInput, noBroadcast = false, middleChangeAddress, middleWif, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const startTime = Date.now();
                // checkParamGenesis(genesis)
                // checkParamCodehash(codehash)
                // 检查售价：不能低于22000聪
                if (price < 22000) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'Selling Price must be greater than or equals to 22000 satoshis. 销售价格最低为22000聪。');
                }
                // 准备钱💰；utxo不能超过3个
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                if (utxos.length > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, '销售合约使用的utxo数量应当少于等于3个，请先归集utxo。MVC utxos should be no more than 3 in this operation, please merge it first.');
                }
                // 检查此NFT是否属于卖家
                const sellerPrivateKey = new mvc.PrivateKey(sellerWif);
                const sellerPublicKey = sellerPrivateKey.publicKey;
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                if (nftUtxo.nftAddress.toString() != sellerPublicKey.toAddress(this.network).toString()) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'nft销售者应当为nft持有者！nft seller should be the nft owner!');
                }
                // 准备找零地址
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxos[0].address;
                }
                // 准备中间找零地址
                let middlePrivateKey;
                if (middleChangeAddress) {
                    middleChangeAddress = new mvc.Address(middleChangeAddress, this.network);
                    middlePrivateKey = new mvc.PrivateKey(middleWif);
                }
                else {
                    middleChangeAddress = utxos[0].address;
                    middlePrivateKey = utxoPrivateKeys[0];
                }
                const { sellTxComposer, txComposer } = yield this.createSellTx({
                    utxos,
                    utxoPrivateKeys,
                    genesis,
                    codehash,
                    tokenIndex,
                    nftUtxo,
                    price,
                    opreturnData,
                    changeAddress,
                    middlePrivateKey,
                    middleChangeAddress,
                });
                let nftSellTxHex = sellTxComposer.getRawHex();
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(nftSellTxHex);
                    yield this.api.broadcast(txHex);
                }
                const runtime = Date.now() - startTime;
                return {
                    tx: txComposer.tx,
                    txHex,
                    txid: txComposer.tx.id,
                    sellTxId: sellTxComposer.getTxId(),
                    sellTx: sellTxComposer.getTx(),
                    sellTxHex: nftSellTxHex,
                    runtime,
                };
            });
        }
        cancelSell({ genesis, codehash, tokenIndex, sellerWif, sellUtxo, opreturnData, utxos: utxosInput, changeAddress, noBroadcast = false, middleChangeAddress, middlePrivateKey, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const startTime = Date.now();
                // checkParamGenesis(genesis)
                // checkParamCodehash(codehash)
                const sellerPrivateKey = new mvc.PrivateKey(sellerWif);
                // 准备钱💰；utxo不能超过3个
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                if (utxos.length > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, '下架合约使用的utxo数量应当少于等于3个，请先归集utxo。MVC utxos should be no more than 3 in this operation, please merge it first.');
                }
                // 准备找零地址
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxos[0].address;
                }
                // 准备中间找零地址
                if (middleChangeAddress) {
                    middleChangeAddress = new mvc.Address(middleChangeAddress, this.network);
                    middlePrivateKey = new mvc.PrivateKey(middlePrivateKey);
                }
                else {
                    middleChangeAddress = utxos[0].address;
                    middlePrivateKey = utxoPrivateKeys[0];
                }
                const { unlockCheckTxComposer, txComposer } = yield this.createCancelSellTx({
                    utxos,
                    utxoPrivateKeys,
                    genesis,
                    codehash,
                    tokenIndex,
                    sellUtxo,
                    sellerPrivateKey,
                    opreturnData,
                    changeAddress,
                    middlePrivateKey,
                    middleChangeAddress,
                });
                let unlockCheckTxHex = unlockCheckTxComposer.getRawHex();
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(unlockCheckTxHex);
                    yield this.api.broadcast(txHex);
                }
                const runtime = Date.now() - startTime;
                return {
                    tx: txComposer.tx,
                    txHex,
                    txid: txComposer.tx.id,
                    unlockCheckTxId: unlockCheckTxComposer.getTxId(),
                    unlockCheckTx: unlockCheckTxComposer.getTx(),
                    unlockCheckTxHex: unlockCheckTxHex,
                    runtime,
                };
            });
        }
        createCancelSellTx({ utxos, utxoPrivateKeys, genesis, codehash, tokenIndex, sellUtxo, sellerPrivateKey, opreturnData, changeAddress, middlePrivateKey, middleChangeAddress, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const version = determineCodehashVersion(codehash);
                // 第一步：找回并准备NFT Utxo
                // 1.1 找回nft Utxo
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                // 1.2 验证nft Utxo
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                // 第二步：找到并重建销售utxo
                // 2.1 查找销售utxo
                if (!sellUtxo) {
                    sellUtxo = yield this.api.getNftSellUtxo(codehash, genesis, tokenIndex);
                }
                if (!sellUtxo) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_NFT_NOT_ON_SELL, 'The NFT is not for sale because the corresponding SellUtxo cannot be found.');
                }
                // 2.2 重建销售utxo
                let nftAddress = sellerPrivateKey.toAddress(this.network);
                let nftSellTxHex = yield this.api.getRawTxData(sellUtxo.txId);
                let nftSellTx = new mvc.Transaction(nftSellTxHex);
                let nftSellUtxo = {
                    txId: sellUtxo.txId,
                    outputIndex: sellUtxo.outputIndex,
                    satoshis: nftSellTx.outputs[sellUtxo.outputIndex].satoshis,
                    lockingScript: nftSellTx.outputs[sellUtxo.outputIndex].script,
                };
                // 第三步：确保余额充足（需要构造三个交易）
                // let genesisScript = nftUtxo.preNftAddress.hashBuffer.equals(Buffer.alloc(20, 0))
                //   ? new Bytes(nftUtxo.preLockingScript.toHex())
                //   : new Bytes('')
                let genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                let estCancelSellFee = yield this._calCancelSellEstimateFee({
                    codehash,
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    nftSellUtxo,
                    genesisScript,
                    utxoMaxCount: utxos.length,
                    opreturnData,
                });
                if (balance < estCancelSellFee) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estCancelSellFee}, but only ${balance}.`);
                }
                // 第四步：构建解锁交易
                // 4.1 准备nft解锁数据
                let nftInput = nftUtxo;
                let nftID = nftProto.getNftID(nftInput.lockingScript.toBuffer());
                let unlockContract = nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_6);
                unlockContract.setFormatedDataPart({
                    nftCodeHash: Buffer.from(codehash, 'hex'),
                    nftID,
                });
                // 解锁合约交易构建器
                const unlockCheckTxComposer = new tx_composer_1.TxComposer();
                // 4.2 往解锁合约交易中塞钱💰
                const unlockCheck_p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(unlockCheckTxComposer, utxos);
                // 4.3 往解锁合约交易中添加解锁输出（重要）
                const unlockCheckOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer: unlockCheckTxComposer,
                    lockingScript: unlockContract.lockingScript,
                    dustCalculator: this.dustCalculator,
                });
                // 4.4 解锁交易找零
                let changeOutputIndex = (0, transactionHelpers_1.addChangeOutput)(unlockCheckTxComposer, middleChangeAddress, this.feeb);
                (0, transactionHelpers_1.unlockP2PKHInputs)(unlockCheckTxComposer, unlockCheck_p2pkhInputIndexes, utxoPrivateKeys);
                // 4.5 检查费率
                (0, transactionHelpers_1.checkFeeRate)(unlockCheckTxComposer, this.feeb);
                // 4.6 重新集结此次操作后的钱
                utxos = [
                    {
                        txId: unlockCheckTxComposer.getTxId(),
                        satoshis: unlockCheckTxComposer.getOutput(changeOutputIndex).satoshis,
                        outputIndex: changeOutputIndex,
                        address: middleChangeAddress,
                    },
                ];
                utxoPrivateKeys = utxos.map((v) => middlePrivateKey).filter((v) => v);
                // 4.7 构建解锁交易的Utxo
                let unlockCheckUtxo = {
                    txId: unlockCheckTxComposer.getTxId(),
                    outputIndex: unlockCheckOutputIndex,
                    satoshis: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).satoshis,
                    lockingScript: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).script,
                };
                // 第五步：构建NFT转移交易
                // 输入：1.销售 2.nft 3.钱 4.解锁合约
                // 输出：1.nft 2.opreturn 3.找零 (相比于buy，没有发给销售者的所得)
                // 转移合约交易构建器
                const txComposer = new tx_composer_1.TxComposer();
                let prevouts = new Prevouts_1.Prevouts();
                // 5.1 放入销售输入
                const sellInputIndex = txComposer.appendInput(nftSellUtxo);
                prevouts.addVout(nftSellUtxo.txId, nftSellUtxo.outputIndex);
                // 5.2 放入NFT输入
                const nftInputIndex = txComposer.appendInput(nftInput);
                prevouts.addVout(nftInput.txId, nftInput.outputIndex);
                // 5.3 放入钱输入
                const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                utxos.forEach((utxo) => {
                    prevouts.addVout(utxo.txId, utxo.outputIndex);
                });
                // 5.4 放入解锁合约输入
                const unlockCheckInputIndex = txComposer.appendInput(unlockCheckUtxo);
                prevouts.addVout(unlockCheckUtxo.txId, unlockCheckUtxo.outputIndex);
                // 5.5 重建销售合约
                let nftSellContract = nftSell_1.NftSellFactory.createContract(new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(new mvc.Address(sellUtxo.sellerAddress, this.network).hashBuffer)), sellUtxo.price, new scryptlib_1.Bytes(codehash), new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftID)));
                nftSellContract.setFormatedDataPart(nftSellProto.parseDataPart(nftSellUtxo.lockingScript.toBuffer()));
                // 5.6 不存在的啦（不用打销售款）
                // 5.7 添加nft输出
                // 5.7.1 构造nft脚本（将nft的所有权转移给销售者）
                const lockingScriptBuf = (0, contractHelpers_1.rebuildNftLockingScript)(nftInput, nftAddress);
                // 5.7.2 添加进输出
                const nftOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    lockingScript: mvc.Script.fromBuffer(lockingScriptBuf),
                    dustCalculator: this.dustCalculator,
                });
                // 5.8 添加opreturn输出
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = txComposer.appendOpReturnOutput(opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                // 5.9 解锁nft合约，并找零
                for (let c = 0; c < 2; c++) {
                    /** 5.9.1 解锁NFT合约 */
                    txComposer.clearChangeOutput();
                    const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                    const nftContract = nft_1.NftFactory.createContract(this.unlockContractCodeHashArray, version);
                    let dataPartObj = nftProto.parseDataPart(nftUtxo.lockingScript.toBuffer());
                    nftContract.setFormatedDataPart(dataPartObj);
                    // 准备数据
                    const prevNftInputIndex = nftUtxo.satotxInfo.preNftInputIndex;
                    const nftTx = new mvc.Transaction(nftUtxo.satotxInfo.txHex);
                    const inputRes = TokenUtil.getTxInputProof(nftTx, prevNftInputIndex);
                    const nftTxInputProof = new TxInputProof(inputRes[0]);
                    const nftTxHeader = inputRes[1];
                    const prevNftTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftUtxo.satotxInfo.preTx, nftUtxo.satotxInfo.preOutputIndex));
                    // 重要：解锁相关参数
                    const contractInputIndex = sellInputIndex;
                    const contractTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftSellTx, nftSellUtxo.outputIndex));
                    const amountCheckHashIndex = 1; // 对应out_6
                    const amountCheckInputIndex = unlockCheckInputIndex;
                    const unlockCheckTx = unlockCheckTxComposer.getTx();
                    const amountCheckTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(unlockCheckTx, unlockCheckOutputIndex));
                    const amountCheckScriptBuf = unlockCheckTx.outputs[unlockCheckOutputIndex].script.toBuffer();
                    const amountCheckScrypt = new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex'));
                    const unlockingContract = nftContract.unlock({
                        txPreimage: txComposer.getInputPreimage(nftInputIndex),
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        prevNftInputIndex,
                        prevNftAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftUtxo.preNftAddress.hashBuffer)),
                        nftTxHeader,
                        nftTxInputProof,
                        prevNftTxProof,
                        genesisScript,
                        contractInputIndex,
                        contractTxProof,
                        amountCheckHashIndex,
                        amountCheckInputIndex,
                        amountCheckTxProof,
                        amountCheckScrypt,
                        operation: nftProto.NFT_OP_TYPE.UNLOCK_FROM_CONTRACT,
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.tx,
                            inputIndex: nftInputIndex,
                            inputSatoshis: txComposer.getInput(nftInputIndex).output.satoshis,
                        };
                        let ret = unlockingContract.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(nftInputIndex).setScript(unlockingContract.toScript());
                    /** 5.9.1.5 其他输出 */
                    let otherOutputs = Buffer.alloc(0);
                    txComposer.tx.outputs.forEach((output, index) => {
                        if (index != nftOutputIndex) {
                            let outputBuf = output.toBufferWriter().toBuffer();
                            let lenBuf = Buffer.alloc(4);
                            lenBuf.writeUInt32LE(outputBuf.length);
                            otherOutputs = Buffer.concat([otherOutputs, lenBuf, outputBuf]);
                        }
                    });
                    /** 5.9.2 解锁检查合约 */
                    const nftOutputProof = (0, proofHelpers_1.createTxOutputProof)(nftTx, nftUtxo.satotxInfo.outputIndex);
                    let sub = unlockCheckUtxo.lockingScript;
                    sub = sub.subScript(0);
                    const txPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sub, unlockCheckUtxo.satoshis, unlockCheckInputIndex)));
                    let unlockCall = unlockContract.unlock({
                        txPreimage,
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        nftInputIndex,
                        nftScript: new scryptlib_1.Bytes(nftInput.lockingScript.toHex()),
                        nftTxHeader: nftOutputProof.txHeader,
                        nftTxHashProof: nftOutputProof.hashProof,
                        nftSatoshiBytes: nftOutputProof.satoshiBytes,
                        nOutputs: txComposer.tx.outputs.length,
                        txNftOutputIndex: nftOutputIndex,
                        nftOutputAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftAddress.hashBuffer)),
                        nftOutputSatoshis: txComposer.getOutput(nftOutputIndex).satoshis,
                        otherOutputArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(otherOutputs)),
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: unlockCheckInputIndex,
                            inputSatoshis: txComposer.getInput(unlockCheckInputIndex).output.satoshis,
                        };
                        let ret = unlockCall.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(unlockCheckInputIndex).setScript(unlockCall.toScript());
                    /** 5.9.3 解锁销售合约 */
                    let sellUtxo = txComposer.getInput(sellInputIndex).output;
                    let sellSubScript = sellUtxo.script;
                    sellSubScript = sellSubScript.subScript(0);
                    const sellTxPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sellSubScript, sellUtxo.satoshis, sellInputIndex, Signature.SIGHASH_SINGLE | Signature.SIGHASH_FORKID)));
                    const unlockCall2 = nftSellContract.unlock({
                        txPreimage: sellTxPreimage,
                        // 以下4个参数只有在cancelSell中才有
                        nftScript: new scryptlib_1.Bytes(nftInput.lockingScript.toHex()),
                        senderPubKey: new scryptlib_1.PubKey((0, scryptlib_1.toHex)(sellerPrivateKey.publicKey.toBuffer())),
                        senderSig: new scryptlib_1.Sig((0, scryptlib_1.toHex)(txComposer.getTxFormatSig(sellerPrivateKey, sellInputIndex))),
                        nftOutputSatoshis: txComposer.getOutput(nftOutputIndex).satoshis,
                        op: nftSell_1.NFT_SELL_OP.CANCEL,
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: sellInputIndex,
                            inputSatoshis: txComposer.getInput(sellInputIndex).output.satoshis,
                        };
                        let ret = unlockCall2.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(sellInputIndex).setScript(unlockCall2.toScript());
                }
                // 6. 解锁输入，检查费率
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { unlockCheckTxComposer, txComposer };
            });
        }
        buy({ genesis, codehash, tokenIndex, buyerWif, buyerAddress, sellUtxo, opreturnData, utxos: utxosInput, changeAddress, noBroadcast = false, middleChangeAddress, middleWif, publisherAddress, publisherFee, publisherFeeRate, creatorAddress, creatorFee, creatorFeeRate, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const startTime = Date.now();
                // checkParamGenesis(genesis)
                // checkParamCodehash(codehash)
                // 准备钱💰
                const { utxos, utxoPrivateKeys } = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                if (utxos.length > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, 'MVC utxos should be no more than 3 in this operation, please merge it first.');
                }
                if (!buyerAddress) {
                    const buyerPrivateKey = new mvc.PrivateKey(buyerWif);
                    buyerAddress = buyerPrivateKey.toAddress(this.network);
                }
                else {
                    buyerAddress = new mvc.Address(buyerAddress, this.network);
                }
                // 准备找零地址
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxos[0].address;
                }
                // 准备中间找零地址
                let middlePrivateKey;
                if (middleChangeAddress) {
                    middleChangeAddress = new mvc.Address(middleChangeAddress, this.network);
                    middlePrivateKey = new mvc.PrivateKey(middleWif);
                }
                else {
                    middleChangeAddress = utxos[0].address;
                    middlePrivateKey = utxoPrivateKeys[0];
                }
                // 查找销售utxo
                if (!sellUtxo) {
                    sellUtxo = yield this.api.getNftSellUtxo(codehash, genesis, tokenIndex);
                }
                if (!sellUtxo) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_NFT_NOT_ON_SELL, 'The NFT is not for sale because the corresponding SellUtxo cannot be found.');
                }
                const price = sellUtxo.price;
                // 检查发行者和创作者的地址和费率参数
                this._checkRoyaltyParams({
                    price,
                    publisherAddress,
                    publisherFee,
                    publisherFeeRate,
                    creatorAddress,
                    creatorFee,
                    creatorFeeRate,
                });
                let { unlockCheckTxComposer, txComposer } = yield this.createBuyTx({
                    utxos,
                    utxoPrivateKeys,
                    genesis,
                    codehash,
                    tokenIndex,
                    sellUtxo,
                    buyerAddress,
                    opreturnData,
                    changeAddress,
                    middlePrivateKey,
                    middleChangeAddress,
                    publisherAddress,
                    publisherFee,
                    publisherFeeRate,
                    creatorAddress,
                    creatorFee,
                    creatorFeeRate,
                });
                let unlockCheckTxHex = unlockCheckTxComposer.getRawHex();
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(unlockCheckTxHex);
                    yield this.api.broadcast(txHex);
                }
                const runtime = Date.now() - startTime;
                return {
                    tx: txComposer.tx,
                    txHex,
                    txid: txComposer.tx.id,
                    unlockCheckTxId: unlockCheckTxComposer.getTxId(),
                    unlockCheckTx: unlockCheckTxComposer.getTx(),
                    unlockCheckTxHex: unlockCheckTxHex,
                    runtime,
                };
            });
        }
        createBuyTx({ utxos, utxoPrivateKeys, genesis, codehash, tokenIndex, sellUtxo, buyerAddress, opreturnData, changeAddress, middlePrivateKey, middleChangeAddress, publisherAddress, publisherFee, publisherFeeRate, creatorAddress, creatorFee, creatorFeeRate, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const version = determineCodehashVersion(codehash);
                // 第一步：找回并准备NFT Utxo
                // 1.1 找回nft Utxo
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                // 1.2 验证nft Utxo
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                // 第二步：找到并重建销售utxo
                // 2.1 查找销售utxo的步骤在上面已经完成（为了拿到价格，进行版税费用检查）
                // 2.2 重建销售utxo
                let nftSellTxHex = yield this.api.getRawTxData(sellUtxo.txId);
                let nftSellTx = new mvc.Transaction(nftSellTxHex);
                let nftSellUtxo = {
                    txId: sellUtxo.txId,
                    outputIndex: sellUtxo.outputIndex,
                    satoshis: nftSellTx.outputs[sellUtxo.outputIndex].satoshis,
                    lockingScript: nftSellTx.outputs[sellUtxo.outputIndex].script,
                };
                // 第三步：确保余额充足（需要构造三个交易）
                const genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                let estBuyFee = yield this._calBuyEstimateFee({
                    codehash,
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    nftSellUtxo,
                    sellUtxo,
                    genesisScript,
                    utxoMaxCount: utxos.length,
                    opreturnData,
                });
                if (balance < estBuyFee) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estBuyFee}, but only ${balance}.`);
                }
                // 第四步：构建解锁交易
                // 4.1 准备nft解锁数据
                let nftInput = nftUtxo;
                let nftID = nftProto.getNftID(nftInput.lockingScript.toBuffer());
                let unlockContract = nftUnlockContractCheck_1.NftUnlockContractCheckFactory.createContract(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_6);
                unlockContract.setFormatedDataPart({
                    nftCodeHash: Buffer.from(codehash, 'hex'),
                    nftID,
                });
                // 解锁合约交易构建器
                const unlockCheckTxComposer = new tx_composer_1.TxComposer();
                // 4.2 往解锁合约交易中塞钱💰
                const unlockCheck_p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(unlockCheckTxComposer, utxos);
                // 4.3 往解锁合约交易中添加解锁输出（重要）
                const unlockCheckOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer: unlockCheckTxComposer,
                    lockingScript: unlockContract.lockingScript,
                    dustCalculator: this.dustCalculator,
                });
                // 4.4 解锁交易找零
                let changeOutputIndex = (0, transactionHelpers_1.addChangeOutput)(unlockCheckTxComposer, middleChangeAddress, this.feeb);
                (0, transactionHelpers_1.unlockP2PKHInputs)(unlockCheckTxComposer, unlockCheck_p2pkhInputIndexes, utxoPrivateKeys);
                // 4.5 检查费率
                (0, transactionHelpers_1.checkFeeRate)(unlockCheckTxComposer, this.feeb);
                // 4.6 重新集结此次操作后的钱
                utxos = [
                    {
                        txId: unlockCheckTxComposer.getTxId(),
                        satoshis: unlockCheckTxComposer.getOutput(changeOutputIndex).satoshis,
                        outputIndex: changeOutputIndex,
                        address: middleChangeAddress,
                    },
                ];
                utxoPrivateKeys = utxos.map((v) => middlePrivateKey).filter((v) => v);
                // 4.7 构建解锁交易的Utxo
                let unlockCheckUtxo = {
                    txId: unlockCheckTxComposer.getTxId(),
                    outputIndex: unlockCheckOutputIndex,
                    satoshis: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).satoshis,
                    lockingScript: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).script,
                };
                // 第五步：构建NFT转移交易
                // 输入：1.销售 2.nft 3.钱 4.解锁合约
                // 输出：1.销售者所得 (1.5 版税：发行者、创作者) 2.nft 3.opreturn 4.找零
                // 转移合约交易构建器
                const txComposer = new tx_composer_1.TxComposer();
                let prevouts = new Prevouts_1.Prevouts();
                // 5.1 放入销售输入
                const sellInputIndex = txComposer.appendInput(nftSellUtxo);
                prevouts.addVout(nftSellUtxo.txId, nftSellUtxo.outputIndex);
                // 5.2 放入NFT输入
                const nftInputIndex = txComposer.appendInput(nftInput);
                prevouts.addVout(nftInput.txId, nftInput.outputIndex);
                // 5.3 放入钱输入
                const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                utxos.forEach((utxo) => {
                    prevouts.addVout(utxo.txId, utxo.outputIndex);
                });
                // 5.4 放入解锁合约输入
                const unlockCheckInputIndex = txComposer.appendInput(unlockCheckUtxo);
                prevouts.addVout(unlockCheckUtxo.txId, unlockCheckUtxo.outputIndex);
                // 5.5 重建销售合约
                let nftSellContract = nftSell_1.NftSellFactory.createContract(new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(new mvc.Address(sellUtxo.sellerAddress, this.network).hashBuffer)), sellUtxo.price, new scryptlib_1.Bytes(codehash), new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftID)));
                const parsed = nftSellProto.parseDataPart(nftSellUtxo.lockingScript.toBuffer());
                nftSellContract.setFormatedDataPart(parsed);
                // 5.6 取得销售者地址，将销售所得构建输出
                const sellerAddress = mvc.Address.fromPublicKeyHash(Buffer.from(nftSellContract.constuctParams.senderAddress.value, 'hex'), this.network);
                const sellerSatoshis = nftSellContract.constuctParams.bsvRecAmount;
                txComposer.appendP2PKHOutput({
                    address: sellerAddress,
                    satoshis: sellerSatoshis,
                });
                // 5.6.5 版税：发行者、创作者
                if (publisherAddress) {
                    // 有发行者地址，则根据费用或费率构建发行者费用输出
                    const publisherAmount = publisherFee || Math.ceil(sellerSatoshis * publisherFeeRate);
                    txComposer.appendP2PKHOutput({
                        address: new mvc.Address(publisherAddress, this.network),
                        satoshis: publisherAmount,
                    });
                }
                if (creatorAddress) {
                    // 有创作者地址，则根据费用或费率构建创作者费用输出
                    const creatorAmount = creatorFee || Math.ceil(sellerSatoshis * creatorFeeRate);
                    txComposer.appendP2PKHOutput({
                        address: new mvc.Address(creatorAddress, this.network),
                        satoshis: creatorAmount,
                    });
                }
                // 5.7 添加nft输出
                // 5.7.1 构造nft脚本（将nft的所有权转移给买家）
                const lockingScriptBuf = (0, contractHelpers_1.rebuildNftLockingScript)(nftInput, buyerAddress);
                // 5.7.2 添加进输出
                const nftOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    lockingScript: mvc.Script.fromBuffer(lockingScriptBuf),
                    dustCalculator: this.dustCalculator,
                });
                // 5.8 添加opreturn输出
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = txComposer.appendOpReturnOutput(opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                // 5.9 解锁nft合约，并找零
                for (let c = 0; c < 2; c++) {
                    /** 5.9.1 解锁NFT合约 */
                    txComposer.clearChangeOutput();
                    const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                    const nftContract = nft_1.NftFactory.createContract(this.unlockContractCodeHashArray, version);
                    let dataPartObj = nftProto.parseDataPart(nftUtxo.lockingScript.toBuffer());
                    nftContract.setFormatedDataPart(dataPartObj);
                    // 准备数据
                    const prevNftInputIndex = nftUtxo.satotxInfo.preNftInputIndex;
                    const nftTx = new mvc.Transaction(nftUtxo.satotxInfo.txHex);
                    const inputRes = TokenUtil.getTxInputProof(nftTx, prevNftInputIndex);
                    const nftTxInputProof = new TxInputProof(inputRes[0]);
                    const nftTxHeader = inputRes[1];
                    const prevNftTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftUtxo.satotxInfo.preTx, nftUtxo.satotxInfo.preOutputIndex));
                    // 重要：解锁相关参数
                    const contractInputIndex = sellInputIndex;
                    const contractTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftSellTx, nftSellUtxo.outputIndex));
                    const amountCheckHashIndex = 1; // 对应out_6
                    const amountCheckInputIndex = unlockCheckInputIndex;
                    const unlockCheckTx = unlockCheckTxComposer.getTx();
                    const amountCheckTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(unlockCheckTx, unlockCheckOutputIndex));
                    const amountCheckScriptBuf = unlockCheckTx.outputs[unlockCheckOutputIndex].script.toBuffer();
                    const amountCheckScrypt = new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex'));
                    const unlockingContract = nftContract.unlock({
                        txPreimage: txComposer.getInputPreimage(nftInputIndex),
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        prevNftInputIndex,
                        prevNftAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftUtxo.preNftAddress.hashBuffer)),
                        nftTxHeader,
                        nftTxInputProof,
                        prevNftTxProof,
                        genesisScript,
                        contractInputIndex,
                        contractTxProof,
                        amountCheckHashIndex,
                        amountCheckInputIndex,
                        amountCheckTxProof,
                        amountCheckScrypt,
                        operation: nftProto.NFT_OP_TYPE.UNLOCK_FROM_CONTRACT,
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.tx,
                            inputIndex: nftInputIndex,
                            inputSatoshis: txComposer.getInput(nftInputIndex).output.satoshis,
                        };
                        let ret = unlockingContract.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(nftInputIndex).setScript(unlockingContract.toScript());
                    /** 5.9.1.5 其他输出 */
                    let otherOutputs = Buffer.alloc(0);
                    txComposer.tx.outputs.forEach((output, index) => {
                        if (index != nftOutputIndex) {
                            let outputBuf = output.toBufferWriter().toBuffer();
                            let lenBuf = Buffer.alloc(4);
                            lenBuf.writeUInt32LE(outputBuf.length);
                            otherOutputs = Buffer.concat([otherOutputs, lenBuf, outputBuf]);
                        }
                    });
                    /** 5.9.2 解锁检查合约 */
                    const nftOutputProof = (0, proofHelpers_1.createTxOutputProof)(nftTx, nftUtxo.satotxInfo.outputIndex);
                    let sub = unlockCheckUtxo.lockingScript;
                    sub = sub.subScript(0);
                    const txPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sub, unlockCheckUtxo.satoshis, unlockCheckInputIndex)));
                    let unlockCall = unlockContract.unlock({
                        // txPreimage: txComposer.getInputPreimage(unlockCheckInputIndex),
                        txPreimage,
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        nftInputIndex,
                        nftScript: new scryptlib_1.Bytes(nftInput.lockingScript.toHex()),
                        nftTxHeader: nftOutputProof.txHeader,
                        nftTxHashProof: nftOutputProof.hashProof,
                        nftSatoshiBytes: nftOutputProof.satoshiBytes,
                        nOutputs: txComposer.tx.outputs.length,
                        txNftOutputIndex: nftOutputIndex,
                        nftOutputAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(buyerAddress.hashBuffer)),
                        nftOutputSatoshis: txComposer.getOutput(nftOutputIndex).satoshis,
                        otherOutputArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(otherOutputs)),
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: unlockCheckInputIndex,
                            inputSatoshis: txComposer.getInput(unlockCheckInputIndex).output.satoshis,
                        };
                        let ret = unlockCall.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(unlockCheckInputIndex).setScript(unlockCall.toScript());
                    /** 5.9.3 解锁销售合约 */
                    let sellUtxo = txComposer.getInput(sellInputIndex).output;
                    let sellSubScript = sellUtxo.script;
                    sellSubScript = sellSubScript.subScript(0);
                    const sellTxPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sellSubScript, sellUtxo.satoshis, sellInputIndex, Signature.SIGHASH_SINGLE | Signature.SIGHASH_FORKID)));
                    const unlockCall2 = nftSellContract.unlock({
                        txPreimage: sellTxPreimage,
                        op: nftSell_1.NFT_SELL_OP.SELL,
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: sellInputIndex,
                            inputSatoshis: txComposer.getInput(sellInputIndex).output.satoshis,
                        };
                        let ret = unlockCall2.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(sellInputIndex).setScript(unlockCall2.toScript());
                }
                // 6. 解锁输入，检查费率
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { unlockCheckTxComposer, txComposer };
            });
        }
        createSellTx({ utxos, utxoPrivateKeys, genesis, codehash, tokenIndex, nftUtxo, price, opreturnData, changeAddress, middlePrivateKey, middleChangeAddress, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const priceNum = price;
                // 第一步：找回nft Utxo并验证，验证钱是否足够
                // 1.1 找回nft Utxo
                if (!nftUtxo) {
                    let nftRes = yield (0, transactionHelpers_1.getNftInfo)({
                        tokenIndex,
                        codehash,
                        genesis,
                        api: this.api,
                        network: this.network,
                    });
                    nftUtxo = nftRes.nftUtxo;
                }
                // 1.2 验证nft Utxo
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                // 1.3 确保余额充足（需要构造两个交易）
                const genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                const estSellFee = yield this._calSellEstimateFee({
                    utxoMaxCount: utxos.length,
                    opreturnData,
                });
                const estTransferFee = yield this._calTransferEstimateFee({
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    genesisScript,
                    opreturnData,
                    utxoMaxCount: utxos.length,
                });
                const totalFee = estSellFee + estTransferFee;
                if (balance < totalFee) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${totalFee}, but only ${balance}.`);
                }
                // 第二步：构造nft销售交易
                let sellTxComposer;
                let nftSellContract;
                {
                    const txComposer = new tx_composer_1.TxComposer();
                    // 2.1 塞入钱
                    const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                    // 2.2 添加销售输出
                    // 2.2.1 构造销售合约脚本
                    nftSellContract = nftSell_1.NftSellFactory.createContract(new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(nftUtxo.nftAddress.hashBuffer)), priceNum, new scryptlib_1.Bytes(codehash), new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftProto.getNftID(nftUtxo.lockingScript.toBuffer()))));
                    nftSellContract.setFormatedDataPart({
                        codehash,
                        genesis,
                        tokenIndex: __1.BN.fromString(tokenIndex, 10),
                        sellerAddress: (0, scryptlib_1.toHex)(nftUtxo.nftAddress.hashBuffer),
                        satoshisPrice: __1.BN.fromNumber(priceNum),
                        nftID: (0, scryptlib_1.toHex)(nftProto.getNftID(nftUtxo.lockingScript.toBuffer())),
                    });
                    // 2.2.2 添加输出
                    (0, transactionHelpers_1.addContractOutput)({
                        txComposer,
                        lockingScript: nftSellContract.lockingScript,
                        dustCalculator: this.dustCalculator,
                    });
                    // 2.3 添加找零输出
                    const changeOutputIndex = (0, transactionHelpers_1.addChangeOutput)(txComposer, middleChangeAddress, this.feeb);
                    (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                    // 2.4检查最终费率
                    (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                    // 2.5 重新获取钱
                    utxos = [
                        {
                            txId: txComposer.getTxId(),
                            satoshis: txComposer.getOutput(changeOutputIndex).satoshis,
                            outputIndex: changeOutputIndex,
                            address: middleChangeAddress,
                        },
                    ];
                    utxoPrivateKeys = utxos.map((v) => middlePrivateKey).filter((v) => v);
                    sellTxComposer = txComposer;
                }
                // 第三步：构造nft转移交易
                // 接收地址为销售合约地址
                const receiverAddress = new mvc.Address(TokenUtil.getScriptHashBuf(nftSellContract.lockingScript.toBuffer()), this.network);
                // 将销售合约txId写入opreturn
                if (typeof opreturnData === 'object' && opreturnData.constructor === Array) {
                    const data = opreturnData[5];
                    let parsed;
                    if (data) {
                        try {
                            parsed = JSON.parse(data);
                        }
                        catch (e) {
                            parsed = {};
                        }
                        parsed['sellContractTxId'] = sellTxComposer.getTxId();
                        opreturnData[5] = JSON.stringify(parsed);
                    }
                }
                const { txComposer } = yield this.createTransferTx({
                    genesis,
                    codehash,
                    tokenIndex,
                    nftUtxo,
                    utxos,
                    utxoPrivateKeys,
                    receiverAddress,
                    opreturnData,
                });
                return { sellTxComposer, txComposer };
            });
        }
        pretreatNftUtxo(nftUtxo, codehash, genesis) {
            return __awaiter(this, void 0, void 0, function* () {
                let txHex = yield this.api.getRawTxData(nftUtxo.txId);
                const tx = new mvc.Transaction(txHex);
                let tokenScript = tx.outputs[nftUtxo.outputIndex].script;
                let curDataPartObj = nftProto.parseDataPart(tokenScript.toBuffer());
                let preNftInputIndex = 0;
                let input = tx.inputs.find((input, inputIndex) => {
                    let script = new mvc.Script(input.script);
                    if (script.chunks.length > 0) {
                        const lockingScriptBuf = TokenUtil.getLockingScriptFromPreimage(script.chunks[0].buf);
                        if (lockingScriptBuf) {
                            if (nftProto.getQueryGenesis(lockingScriptBuf) == genesis) {
                                preNftInputIndex = inputIndex;
                                return true;
                            }
                            let dataPartObj = nftProto.parseDataPart(lockingScriptBuf);
                            dataPartObj.sensibleID = curDataPartObj.sensibleID;
                            dataPartObj.tokenIndex = __1.BN.Zero;
                            const newScriptBuf = nftProto.updateScript(lockingScriptBuf, dataPartObj);
                            let genesisHash = (0, scryptlib_1.toHex)(mvc.crypto.Hash.sha256ripemd160(newScriptBuf));
                            if (genesisHash == curDataPartObj.genesisHash) {
                                preNftInputIndex = inputIndex;
                                return true;
                            }
                        }
                    }
                });
                if (!input)
                    throw new error_1.CodeError(error_1.ErrCode.EC_INNER_ERROR, 'invalid nftUtxo');
                let preTxId = input.prevTxId.toString('hex');
                let preOutputIndex = input.outputIndex;
                let preTxHex = yield this.api.getRawTxData(preTxId);
                const preTx = new mvc.Transaction(preTxHex);
                nftUtxo.satotxInfo = {
                    txId: nftUtxo.txId,
                    outputIndex: nftUtxo.outputIndex,
                    txHex,
                    preTxId,
                    preNftInputIndex,
                    preOutputIndex,
                    preTxHex,
                    txInputsCount: tx.inputs.length,
                    preTx,
                };
                nftUtxo.preLockingScript = preTx.outputs[preOutputIndex].script;
                nftUtxo.lockingScript = tx.outputs[nftUtxo.outputIndex].script;
                nftUtxo.satoshis = tx.outputs[nftUtxo.outputIndex].satoshis;
                nftUtxo.preNftAddress = mvc.Address.fromPublicKeyHash(Buffer.from(nftProto.getNftAddress(preTx.outputs[preOutputIndex].script.toBuffer()), 'hex'), this.network);
                return nftUtxo;
            });
        }
        createTransferTx({ utxos, utxoPrivateKeys, genesis, codehash, tokenIndex, nftUtxo, opreturnData = null, receiverAddress, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                const changeAddress = this.purse.address;
                // prevouts
                let prevouts = new Prevouts_1.Prevouts();
                if (!nftUtxo) {
                    // 第一步：找回nft Utxo并验证，放入第一个输入
                    // 1.1 找回nft Utxo
                    const nftRes = yield (0, transactionHelpers_1.getNftInfo)({
                        tokenIndex,
                        codehash,
                        genesis,
                        api: this.api,
                        network: this.network,
                    });
                    nftUtxo = nftRes.nftUtxo;
                    // 1.2 验证nft Utxo
                    nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                }
                // 1.3 确保余额充足
                const genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                let estimateSatoshis = yield this._calTransferEstimateFee({
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    genesisScript,
                    opreturnData,
                    utxoMaxCount: utxos.length,
                });
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                // 1.4 构造nft输入
                const nftInput = nftUtxo;
                const nftAddress = this.purse.address.toString();
                const nftInputIndex = (0, transactionHelpers_1.addContractInput)(txComposer, nftInput, nftAddress, utils_1.CONTRACT_TYPE.BCP01_NFT_GENESIS);
                // 1.5 prevouts添加nft utxo
                prevouts.addVout(nftInput.txId, nftInput.outputIndex);
                // 第二步：付钱
                // 2.1 添加付钱输入
                const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                // 2.2 prevouts添加付钱utxo
                utxos.forEach((utxo) => {
                    prevouts.addVout(utxo.txId, utxo.outputIndex);
                });
                // 第三步：添加nft输出
                // 3.1 构造nft脚本
                const lockingScriptBuf = (0, contractHelpers_1.rebuildNftLockingScript)(nftUtxo, receiverAddress);
                // 3.2 添加nft输出
                const nftOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    lockingScript: mvc.Script.fromBuffer(lockingScriptBuf),
                    dustCalculator: this.dustCalculator,
                });
                // 第五步：如果有opreturn，添加opreturn输出
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = (0, transactionHelpers_1.addOpreturnOutput)(txComposer, opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                // 第六步：解锁nft合约，并找零
                this.unlockNftAndChange({
                    txComposer,
                    nftUtxo,
                    nftInputIndex,
                    codehash,
                    prevouts,
                    genesisScript,
                    nftOutputIndex,
                    receiverAddress,
                    changeAddress,
                    opreturnScriptHex,
                });
                // 第七步：解锁付钱输入
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                // 第八步：检查最终费率
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { txComposer };
            });
        }
        createMintTx({ version, utxos, utxoPrivateKeys, sensibleId, metaTxId, metaOutputIndex, opreturnData, receiverAddress, changeAddress, calcFee = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                // 输入：第一个为上一个创世，后面是付钱的utxo
                // 输出：第一个为更新的创世，第二个是nft，后面是找零
                // 第一步：找回创世utxo，放入第一个输入
                // 1.1 找回创世utxo
                const { genesisContract, genesisUtxo, genesisTxId, genesisOutputIndex } = (yield (0, transactionHelpers_1.getLatestGenesisInfo)({
                    sensibleId,
                    api: this.api,
                    address: this.purse.address,
                    type: 'nft',
                }));
                // 1.2 确保余额充足
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                let estimateSatoshis = yield this._calIssueEstimateFee({
                    genesisUtxoSatoshis: genesisUtxo.satoshis,
                    opreturnData,
                    utxoMaxCount: utxos.length,
                });
                if (calcFee) {
                    return {
                        fee: estimateSatoshis,
                        txid: txComposer.getTxId,
                        txHex: txComposer.getRawHex(),
                        tx: txComposer.getTx(),
                    };
                }
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                // 1.3 构造创世输入
                const genesisAddress = this.purse.address.toString(); // TODO: 他人创世
                const genesisInputIndex = (0, transactionHelpers_1.addContractInput)(txComposer, genesisUtxo, genesisAddress, utils_1.CONTRACT_TYPE.BCP01_NFT_GENESIS);
                // 第二步：添加付钱输入
                const p2pkhInputIndexes = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                // 第三步：复制创世合约，添加创世输出
                const sensibleID = {
                    txid: genesisTxId,
                    index: genesisOutputIndex,
                };
                // 到头（tokenIndex == totalSupply - 1）时，则不再添加创世输出
                const dataPart = genesisContract.getFormatedDataPart();
                const currentTokenIndex = dataPart.tokenIndex;
                const totalSupply = dataPart.totalSupply;
                let nextGenesisOutputIndex = -1;
                if (currentTokenIndex.lt(totalSupply.sub(__1.BN.One))) {
                    const nextGenesisContract = this.updateGenesisContract(genesisContract, sensibleID);
                    nextGenesisOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                        txComposer,
                        contract: nextGenesisContract,
                        dustCalculator: this.dustCalculator,
                    });
                }
                // 第四步：创建铸造合约，添加铸造输出
                const genesisHash = this.getGenesisHash(genesisContract, sensibleID);
                const mintContract = (0, contractHelpers_1.createNftMintContract)({
                    version,
                    genesisHash,
                    genesisContract,
                    metaTxId,
                    metaOutputIndex,
                    sensibleID,
                    receiverAddress,
                    unlockContractCodeHashArray: this.unlockContractCodeHashArray,
                });
                const mintOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    contract: mintContract,
                    dustCalculator: this.dustCalculator,
                });
                // 第五步：如果有opreturn，添加opreturn输出
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = (0, transactionHelpers_1.addOpreturnOutput)(txComposer, opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                // 第六步：添加找零输出，解锁创世合约输入
                this.unlockGenesisAndChange(txComposer, genesisUtxo, genesisContract, genesisInputIndex, nextGenesisOutputIndex, mintOutputIndex, changeAddress, opreturnScriptHex);
                // 第七步：解锁付钱输入
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexes, utxoPrivateKeys);
                // 第八步：检查最终费率
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                const tokenIndex = mintContract.getFormatedDataPart().tokenIndex.toString(10);
                return {
                    txComposer,
                    tokenIndex,
                };
            });
        }
        // 获取初始创世合约的哈希值供铸造合约使用
        getGenesisHash(genesisContract, sensibleID) {
            let originDataPart = genesisContract.getFormatedDataPart();
            genesisContract.setFormatedDataPart({
                sensibleID,
                tokenIndex: __1.BN.Zero,
            });
            let genesisHash = genesisContract.getScriptHash();
            // 恢复原始数据
            genesisContract.setFormatedDataPart(originDataPart);
            return genesisHash;
        }
        // 复制更新创世合约
        updateGenesisContract(genesisContract, sensibleID) {
            const genesisDataPart = genesisContract.getFormatedDataPart();
            if (genesisDataPart.tokenIndex.lt(genesisDataPart.totalSupply.sub(__1.BN.One))) {
                // genesisDataPart.tokenIndex = genesisDataPart.tokenIndex.add(BN.One)
                // genesisDataPart.sensibleID = sensibleID
                let nextGenesisContract = genesisContract.clone();
                nextGenesisContract.setFormatedDataPart(genesisDataPart);
                nextGenesisContract.setFormatedDataPart({
                    tokenIndex: genesisDataPart.tokenIndex.add(__1.BN.One),
                    sensibleID,
                });
                return nextGenesisContract;
            }
        }
        // 解锁创世合约并找零
        unlockGenesisAndChange(txComposer, genesisUtxo, genesisContract, genesisInputIndex, nextGenesisOutputIndex, nftOutputIndex, changeAddress, opreturnScriptHex) {
            const genesisPrivateKey = mvc.PrivateKey.fromWIF(this.purse.privateKey.toWIF());
            const genesisPublicKey = genesisPrivateKey.toPublicKey();
            const pubKey = new scryptlib_1.PubKey((0, scryptlib_1.toHex)(genesisPublicKey));
            const { genesisTxHeader, prevInputIndex, genesisTxInputProof } = (0, proofHelpers_1.createGenesisTxInputProof)(genesisUtxo);
            const { prevGenesisTxHeader, prevTxOutputHashProof, prevTxOutputSatoshiBytes } = (0, proofHelpers_1.createPrevGenesisTxOutputProof)(genesisUtxo);
            const genesisSatoshis = nextGenesisOutputIndex > -1 ? txComposer.getOutput(nextGenesisOutputIndex).satoshis : 0;
            for (let c = 0; c < 2; c++) {
                txComposer.clearChangeOutput();
                const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                const txPreimage = txComposer.getInputPreimage(genesisInputIndex);
                const sig = new scryptlib_1.Sig(genesisPrivateKey
                    ? (0, scryptlib_1.toHex)(txComposer.getTxFormatSig(genesisPrivateKey, genesisInputIndex))
                    : utils_1.PLACE_HOLDER_SIG);
                let unlockResult = genesisContract.unlock({
                    txPreimage,
                    pubKey,
                    sig,
                    // GenesisTx Input Proof
                    genesisTxHeader,
                    prevInputIndex,
                    genesisTxInputProof,
                    prevGenesisTxHeader,
                    prevTxOutputHashProof,
                    prevTxOutputSatoshiBytes,
                    nftScript: new scryptlib_1.Bytes(txComposer.getOutput(nftOutputIndex).script.toHex()),
                    genesisSatoshis,
                    nftSatoshis: txComposer.getOutput(nftOutputIndex).satoshis,
                    changeAddress: new scryptlib_1.Ripemd160(changeAddress.hashBuffer.toString('hex')),
                    changeSatoshis: changeOutputIndex != -1 ? txComposer.getOutput(changeOutputIndex).satoshis : 0,
                    opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
                });
                if (this.debug && genesisPrivateKey && c == 1) {
                    let ret = unlockResult.verify({
                        tx: txComposer.getTx(),
                        inputIndex: 0,
                        inputSatoshis: txComposer.getInput(genesisInputIndex).output.satoshis,
                    });
                    if (ret.success == false)
                        throw ret;
                }
                txComposer.getInput(genesisInputIndex).setScript(unlockResult.toScript());
            }
        }
        // 解锁NFT合约并找零
        unlockNftAndChange({ txComposer, nftUtxo, nftInputIndex, codehash, prevouts, genesisScript, nftOutputIndex, receiverAddress, changeAddress, opreturnScriptHex, }) {
            const version = determineCodehashVersion(codehash);
            const nftPrivateKey = this.purse.privateKey;
            const senderPubkey = nftPrivateKey.toPublicKey();
            for (let c = 0; c < 2; c++) {
                txComposer.clearChangeOutput();
                const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                const nftContract = nft_1.NftFactory.createContract(this.unlockContractCodeHashArray, version);
                let dataPartObj = nftProto.parseDataPart(nftUtxo.lockingScript.toBuffer());
                nftContract.setFormatedDataPart(dataPartObj);
                // 准备数据
                const prevNftInputIndex = nftUtxo.satotxInfo.preNftInputIndex;
                const nftTx = new mvc.Transaction(nftUtxo.satotxInfo.txHex);
                const inputRes = TokenUtil.getTxInputProof(nftTx, prevNftInputIndex);
                const nftTxInputProof = new TxInputProof(inputRes[0]);
                const nftTxHeader = inputRes[1];
                const prevNftTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftUtxo.satotxInfo.preTx, nftUtxo.satotxInfo.preOutputIndex));
                const contractInputIndex = 0;
                const contractTxProof = new TxOutputProof(TokenUtil.getEmptyTxOutputProof());
                const amountCheckOutputIndex = 0;
                // const amountCheckScriptBuf = amountCheckTx.outputs[amountCheckOutputIndex].script.toBuffer()
                const amountCheckScriptBuf = Buffer.alloc(0);
                const amountCheckHashIndex = 0;
                const amountCheckInputIndex = txComposer.getTx().inputs.length - 1;
                // const amountCheckTxProof = new TxOutputProof(
                //   TokenUtil.getTxOutputProof(amountCheckTx, amountCheckOutputIndex)
                // )
                const amountCheckTxProof = new TxOutputProof(TokenUtil.getEmptyTxOutputProof());
                const amountCheckScrypt = new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex'));
                const unlockingContract = nftContract.unlock({
                    txPreimage: txComposer.getInputPreimage(nftInputIndex),
                    prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                    prevNftInputIndex,
                    prevNftAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftUtxo.preNftAddress.hashBuffer)),
                    nftTxHeader,
                    nftTxInputProof,
                    prevNftTxProof,
                    genesisScript,
                    contractInputIndex,
                    contractTxProof,
                    amountCheckHashIndex,
                    amountCheckInputIndex,
                    amountCheckTxProof,
                    amountCheckScrypt,
                    senderPubKey: new scryptlib_1.PubKey((0, scryptlib_1.toHex)(senderPubkey)),
                    senderSig: new scryptlib_1.Sig((0, scryptlib_1.toHex)(txComposer.getTxFormatSig(nftPrivateKey, nftInputIndex))),
                    receiverAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(receiverAddress.hashBuffer)),
                    nftOutputSatoshis: new scryptlib_1.Int(txComposer.getOutput(nftOutputIndex).satoshis),
                    opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
                    changeAddress: new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(changeAddress.hashBuffer)),
                    changeSatoshis: new scryptlib_1.Int(changeOutputIndex != -1 ? txComposer.getOutput(changeOutputIndex).satoshis : 0),
                    operation: nftProto.NFT_OP_TYPE.TRANSFER,
                });
                if (this.debug && nftPrivateKey) {
                    let txContext = {
                        tx: txComposer.tx,
                        inputIndex: nftInputIndex,
                        inputSatoshis: txComposer.getInput(nftInputIndex).output.satoshis,
                    };
                    let ret = unlockingContract.verify(txContext);
                    if (ret.success == false)
                        throw ret;
                }
                txComposer.getInput(nftInputIndex).setScript(unlockingContract.toScript());
            }
        }
        // 解锁NFT合约并找零(合约)
        unlockNftAndChangeFromContract({ txComposer, nftUtxo, nftInputIndex, codehash, prevouts, genesisScript, nftOutputIndex, sellInputIndex, receiverAddress, changeAddress, opreturnScriptHex, }) {
            const version = determineCodehashVersion(codehash);
            const nftPrivateKey = this.purse.privateKey;
            const senderPubkey = nftPrivateKey.toPublicKey();
            for (let c = 0; c < 2; c++) {
                txComposer.clearChangeOutput();
                const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                const nftContract = nft_1.NftFactory.createContract(this.unlockContractCodeHashArray, version);
                let dataPartObj = nftProto.parseDataPart(nftUtxo.lockingScript.toBuffer());
                nftContract.setFormatedDataPart(dataPartObj);
                // 准备数据
                const prevNftInputIndex = nftUtxo.satotxInfo.preNftInputIndex;
                const nftTx = new mvc.Transaction(nftUtxo.satotxInfo.txHex);
                const inputRes = TokenUtil.getTxInputProof(nftTx, prevNftInputIndex);
                const nftTxInputProof = new TxInputProof(inputRes[0]);
                const nftTxHeader = inputRes[1];
                const prevNftTxProof = new TxOutputProof(TokenUtil.getTxOutputProof(nftUtxo.satotxInfo.preTx, nftUtxo.satotxInfo.preOutputIndex));
                // 重要：解锁相关参数
                const contractInputIndex = sellInputIndex;
                const contractTxProof = new TxOutputProof(TokenUtil.getEmptyTxOutputProof());
                const amountCheckOutputIndex = 0;
                // const amountCheckScriptBuf = amountCheckTx.outputs[amountCheckOutputIndex].script.toBuffer()
                const amountCheckScriptBuf = Buffer.alloc(0);
                const amountCheckHashIndex = 0;
                const amountCheckInputIndex = txComposer.getTx().inputs.length - 1;
                // const amountCheckTxProof = new TxOutputProof(
                //   TokenUtil.getTxOutputProof(amountCheckTx, amountCheckOutputIndex)
                // )
                const amountCheckTxProof = new TxOutputProof(TokenUtil.getEmptyTxOutputProof());
                const amountCheckScrypt = new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex'));
                const unlockingContract = nftContract.unlock({
                    txPreimage: txComposer.getInputPreimage(nftInputIndex),
                    prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                    prevNftInputIndex,
                    prevNftAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(nftUtxo.preNftAddress.hashBuffer)),
                    nftTxHeader,
                    nftTxInputProof,
                    prevNftTxProof,
                    genesisScript,
                    contractInputIndex,
                    contractTxProof,
                    amountCheckHashIndex,
                    amountCheckInputIndex,
                    amountCheckTxProof,
                    amountCheckScrypt,
                    senderPubKey: new scryptlib_1.PubKey((0, scryptlib_1.toHex)(senderPubkey)),
                    senderSig: new scryptlib_1.Sig((0, scryptlib_1.toHex)(txComposer.getTxFormatSig(nftPrivateKey, nftInputIndex))),
                    receiverAddress: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(receiverAddress.hashBuffer)),
                    nftOutputSatoshis: new scryptlib_1.Int(txComposer.getOutput(nftOutputIndex).satoshis),
                    opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
                    changeAddress: new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(changeAddress.hashBuffer)),
                    changeSatoshis: new scryptlib_1.Int(changeOutputIndex != -1 ? txComposer.getOutput(changeOutputIndex).satoshis : 0),
                    operation: nftProto.NFT_OP_TYPE.TRANSFER,
                });
                if (this.debug && nftPrivateKey) {
                    let txContext = {
                        tx: txComposer.tx,
                        inputIndex: nftInputIndex,
                        inputSatoshis: txComposer.getInput(nftInputIndex).output.satoshis,
                    };
                    let ret = unlockingContract.verify(txContext);
                    if (ret.success == false)
                        throw ret;
                }
                txComposer.getInput(nftInputIndex).setScript(unlockingContract.toScript());
            }
        }
        _calGenesisEstimateFee(totalSupply, opreturnData, feeb) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                const changeAddress = this.purse.address;
                // 构建合约
                const genesisContract = (0, contractHelpers_1.createNftGenesisContract)({ totalSupply, address: this.purse.address });
                if (opreturnData) {
                    (0, transactionHelpers_1.addOpreturnOutput)(txComposer, opreturnData);
                }
                const unlockSize = txComposer.tx.inputs.filter((v) => v.output.script.isPublicKeyHashOut()).length *
                    utils_1.P2PKH_UNLOCK_SIZE;
                let fee = Math.ceil((txComposer.tx.toBuffer().length + unlockSize + mvc.Transaction.CHANGE_OUTPUT_MAX_SIZE) * feeb);
                return fee;
            });
        }
        _calIssueEstimateFee({ genesisUtxoSatoshis, opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                stx.addInput(nftGenesis_1.NftGenesisFactory.calUnlockingScriptSize(opreturnData), genesisUtxoSatoshis);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                stx.addOutput(nftGenesis_1.NftGenesisFactory.getLockingScriptSize());
                stx.addOutput(nft_1.NftFactory.getLockingScriptSize());
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        _calTransferEstimateFee({ nftUtxoSatoshis, genesisScript, opreturnData, utxoMaxCount, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                stx.addInput(nft_1.NftFactory.calUnlockingScriptSize(p2pkhInputNum, genesisScript, opreturnData, nftProto.NFT_OP_TYPE.TRANSFER), nftUtxoSatoshis);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                stx.addOutput(nft_1.NftFactory.getLockingScriptSize());
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        static parseTokenScript(scriptBuf, network = __1.API_NET.MAIN) {
            if (!(0, protoheader_1.hasProtoFlag)(scriptBuf)) {
                return null;
            }
            const dataPart = nftProto.parseDataPart(scriptBuf);
            const nftAddress = mvc.Address.fromPublicKeyHash(Buffer.from(dataPart.nftAddress, 'hex'), network).toString();
            const genesis = nftProto.getQueryGenesis(scriptBuf);
            const codehash = nftProto.getQueryCodehash(scriptBuf);
            const sensibleId = nftProto.getQuerySensibleID(scriptBuf);
            return {
                codehash,
                genesis,
                sensibleId,
                metaidOutpoint: dataPart.metaidOutpoint,
                nftAddress,
                totalSupply: dataPart.totalSupply,
                tokenIndex: dataPart.tokenIndex,
                genesisHash: dataPart.genesisHash,
                sensibleID: dataPart.sensibleID,
                protoVersion: dataPart.protoVersion,
                protoType: dataPart.protoType,
            };
        }
        getCancelSellEstimateFee({ genesis, codehash, tokenIndex, sellerWif, sellUtxo, opreturnData, utxoMaxCount = 3, }) {
            return __awaiter(this, void 0, void 0, function* () {
                return 32000; // TODO
                // checkParamGenesis(genesis)
                // checkParamCodehash(codehash)
                const sellerPrivateKey = new mvc.PrivateKey(sellerWif);
                const sellerPublicKey = sellerPrivateKey.publicKey;
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                // 第二步：找到并重建销售utxo
                // 2.1 查找销售utxo
                if (!sellUtxo) {
                    sellUtxo = yield this.api.getNftSellUtxo(codehash, genesis, tokenIndex);
                }
                if (!sellUtxo) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_NFT_NOT_ON_SELL, 'The NFT is not for sale because the corresponding SellUtxo cannot be found.');
                }
                let nftSellTxHex = yield this.api.getRawTxData(sellUtxo.txId);
                let nftSellTx = new mvc.Transaction(nftSellTxHex);
                let nftSellUtxo = {
                    txId: sellUtxo.txId,
                    outputIndex: sellUtxo.outputIndex,
                    satoshis: nftSellTx.outputs[sellUtxo.outputIndex].satoshis,
                    lockingScript: nftSellTx.outputs[sellUtxo.outputIndex].script,
                };
                let genesisScript = new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex());
                let estimateSatoshis = yield this._calCancelSellEstimateFee({
                    codehash,
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    nftSellUtxo,
                    genesisScript,
                    utxoMaxCount,
                    opreturnData,
                });
                return estimateSatoshis;
            });
        }
        getBuyEstimateFee({ genesis, codehash, tokenIndex, buyerWif, sellUtxo, opreturnData, utxoMaxCount = 3, }) {
            return __awaiter(this, void 0, void 0, function* () {
                // checkParamGenesis(genesis)
                // checkParamCodehash(codehash)
                // 第二步：找到并重建销售utxo
                // 2.1 查找销售utxo
                if (!sellUtxo) {
                    sellUtxo = yield this.api.getNftSellUtxo(codehash, genesis, tokenIndex);
                }
                if (!sellUtxo) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_NFT_NOT_ON_SELL, 'The NFT is not for sale because the corresponding SellUtxo cannot be found.');
                }
                return Math.ceil(sellUtxo.price * 1.06) + 25000; // TODO
                let nftSellTxHex = yield this.api.getRawTxData(sellUtxo.txId);
                let nftSellTx = new mvc.Transaction(nftSellTxHex);
                let nftSellUtxo = {
                    txId: sellUtxo.txId,
                    outputIndex: sellUtxo.outputIndex,
                    satoshis: nftSellTx.outputs[sellUtxo.outputIndex].satoshis,
                    lockingScript: nftSellTx.outputs[sellUtxo.outputIndex].script,
                };
                const buyerPrivateKey = new mvc.PrivateKey(buyerWif);
                const buyerPublicKey = buyerPrivateKey.publicKey;
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                // 1.2 验证nft Utxo
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                let genesisScript = nftUtxo.preNftAddress.hashBuffer.equals(Buffer.alloc(20, 0))
                    ? new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex())
                    : new scryptlib_1.Bytes('');
                let estimateSatoshis = yield this._calBuyEstimateFee({
                    codehash,
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    nftSellUtxo,
                    sellUtxo,
                    genesisScript,
                    utxoMaxCount,
                    opreturnData,
                });
                return estimateSatoshis;
            });
        }
        getSellEstimateFee({ genesis, codehash, tokenIndex, senderWif, opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const senderPrivateKey = new mvc.PrivateKey(senderWif);
                const senderPublicKey = senderPrivateKey.publicKey;
                let { nftUtxo } = yield (0, transactionHelpers_1.getNftInfo)({
                    tokenIndex,
                    codehash,
                    genesis,
                    api: this.api,
                    network: this.network,
                });
                // 1.2 验证nft Utxo
                nftUtxo = yield this.pretreatNftUtxo(nftUtxo, codehash, genesis);
                let genesisScript = nftUtxo.preNftAddress.hashBuffer.equals(Buffer.alloc(20, 0))
                    ? new scryptlib_1.Bytes(nftUtxo.preLockingScript.toHex())
                    : new scryptlib_1.Bytes('');
                let estimateSatoshis1 = yield this._calSellEstimateFee({
                    utxoMaxCount,
                    opreturnData,
                });
                let estimateSatoshis2 = yield this._calTransferEstimateFee({
                    nftUtxoSatoshis: nftUtxo.satoshis,
                    genesisScript,
                    opreturnData,
                    utxoMaxCount: 1,
                });
                return estimateSatoshis1 + estimateSatoshis2 + 2000; // TODO
            });
        }
        _calSellEstimateFee({ utxoMaxCount, opreturnData, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                stx.addOutput(nftSell_1.NftSellFactory.getLockingScriptSize());
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        _calCancelSellEstimateFee({ codehash, nftUtxoSatoshis, nftSellUtxo, genesisScript, opreturnData, utxoMaxCount, }) {
            return __awaiter(this, void 0, void 0, function* () {
                return 25000; // TODO
            });
        }
        _calBuyEstimateFee({ codehash, nftUtxoSatoshis, nftSellUtxo, sellUtxo, genesisScript, opreturnData, utxoMaxCount, }) {
            return __awaiter(this, void 0, void 0, function* () {
                return Math.ceil(sellUtxo.price * 1.06) + 25000; // TODO
                let p2pkhInputNum = utxoMaxCount;
                if (p2pkhInputNum > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, 'Mvc utxos should be no more than 3 in this operation.');
                }
                let nftUnlockingSize = nft_1.NftFactory.calUnlockingScriptSize(p2pkhInputNum, genesisScript, opreturnData, nftProto.NFT_OP_TYPE.UNLOCK_FROM_CONTRACT);
                let nftSize = nft_1.NftFactory.getLockingScriptSize();
                let unlockContractSize = nftUnlockContractCheck_1.NftUnlockContractCheckFactory.getLockingScriptSize(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_6);
                let dataPart = nftSellProto.parseDataPart(nftSellUtxo.lockingScript.toBuffer());
                // let nftSellContract = NftSellFactory.createFromASM(
                //   nftSellUtxo.lockingScript.toASM()
                // );
                let nftSellContract = nftSell_1.NftSellFactory.createContract(new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(new mvc.Address(sellUtxo.sellerAddress, this.network).hashBuffer)), sellUtxo.price, new scryptlib_1.Bytes(codehash), new scryptlib_1.Bytes(dataPart.nftID));
                nftSellContract.setFormatedDataPart(nftSellProto.parseDataPart(nftSellUtxo.lockingScript.toBuffer()));
                let nftSellUnlockingSize = nftSell_1.NftSellFactory.calUnlockingScriptSize(nftSell_1.NFT_SELL_OP.SELL);
                let stx1 = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx1.addP2PKHInput();
                }
                stx1.addOutput(unlockContractSize);
                stx1.addP2PKHOutput();
                let stx2 = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                stx2.addInput(nftSellUnlockingSize, nftSellUtxo.satoshis);
                stx2.addInput(nftUnlockingSize, nftUtxoSatoshis);
                stx2.addP2PKHInput();
                let prevouts = new Prevouts_1.Prevouts();
                prevouts.addVout(dummy_1.dummyTxId, 0);
                prevouts.addVout(dummy_1.dummyTxId, 0);
                prevouts.addVout(dummy_1.dummyTxId, 0);
                prevouts.addVout(dummy_1.dummyTxId, 0);
                let otherOutputsLen = 0;
                if (opreturnData) {
                    otherOutputsLen =
                        otherOutputsLen + 4 + 8 + 4 + mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length;
                }
                otherOutputsLen = otherOutputsLen + 4 + 8 + 4 + 25;
                let otherOutputs = new scryptlib_1.Bytes((0, scryptlib_1.toHex)(Buffer.alloc(otherOutputsLen, 0)));
                let unlockContractUnlockingSize = nftUnlockContractCheck_1.NftUnlockContractCheckFactory.calUnlockingScriptSize(nftUnlockContractCheck_1.NFT_UNLOCK_CONTRACT_TYPE.OUT_6, new scryptlib_1.Bytes(prevouts.toHex()), otherOutputs);
                stx2.addInput(unlockContractUnlockingSize, this.dustCalculator.getDustThreshold(unlockContractSize));
                stx2.addP2PKHOutput();
                stx2.addOutput(nftSize);
                if (opreturnData) {
                    stx2.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx2.addP2PKHOutput();
                //dummy
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                stx2.addP2PKHInput();
                return stx1.getFee() + stx2.getFee() + nftSellContract.constuctParams.bsvRecAmount;
            });
        }
        _checkRoyaltyParams({ price, publisherAddress, publisherFee, publisherFeeRate, creatorAddress, creatorFee, creatorFeeRate, }) {
            // 1. 当地址不存在时，不允许设置费率或者固定费用
            if (!publisherAddress && (publisherFee || publisherFeeRate)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'publisherAddress is not set, but publisherFee or publisherFeeRate is set.');
            }
            if (!creatorAddress && (creatorFee || creatorFeeRate)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'creatorAddress is not set, but creatorFee or creatorFeeRate is set.');
            }
            // 2. 当地址存在时，必须设置费率或者固定费用，但不能同时设置
            if (publisherAddress && !publisherFee && !publisherFeeRate) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'publisherAddress is set, but publisherFee and publisherFeeRate are not set.');
            }
            if (publisherAddress && publisherFee && publisherFeeRate) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'publisherAddress is set, but publisherFee and publisherFeeRate are set.');
            }
            if (creatorAddress && !creatorFee && !creatorFeeRate) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'creatorAddress is set, but creatorFee and creatorFeeRate are not set.');
            }
            if (creatorAddress && creatorFee && creatorFeeRate) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'creatorAddress is set, but creatorFee and creatorFeeRate are set.');
            }
            // 3. 固定费用或用费率算出来的费用，必须大于等于粉尘限制（546）
            if (publisherFee && publisherFee < this.dustCalculator.getDustThreshold(1)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'publisherFee is too small. It should be at least 546 satoshis.');
            }
            if (publisherFeeRate && publisherFeeRate * price < this.dustCalculator.getDustThreshold(1)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'publisherFeeRate is too small. It should be at least 546 satoshis.');
            }
            if (creatorFee && creatorFee < this.dustCalculator.getDustThreshold(1)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'creatorFee is too small. It should be at least 546 satoshis.');
            }
            if (creatorFeeRate && creatorFeeRate * price < this.dustCalculator.getDustThreshold(1)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'creatorFeeRate is too small. It should be at least 546 satoshis.');
            }
            return true;
        }
    }
    exports.NftManager = NftManager;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"..":395,"../common/DustCalculator":383,"../common/Prevouts":384,"../common/SizeTransaction":385,"../common/dummy":387,"../common/error":388,"../common/protoheader":389,"../common/tokenUtil":390,"../common/utils":391,"../helpers/contractHelpers":392,"../helpers/proofHelpers":393,"../helpers/transactionHelpers":394,"../mcp02/constants":416,"../mvc":440,"../scryptlib":445,"../tx-composer":446,"./contract-desc/txUtil_desc.json":406,"./contract-factory/nft":407,"./contract-factory/nftGenesis":408,"./contract-factory/nftSell":409,"./contract-factory/nftUnlockContractCheck":410,"./contract-proto/nft.proto":411,"./contract-proto/nftSell.proto":412,"./contractUtil":414,"buffer":84}],416:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TX_VERSION = exports.BURN_ADDRESS = exports.FEEB = void 0;
    exports.FEEB = 1;
    // export const PROTO_FLAG = Buffer.from('metacontract')
    // export const PROTO_FLAG_LEN = PROTO_FLAG.length
    // export const HEADER_LEN = 20
    // export const HASH_ID_LEN = 20
    // export const HASH_LEN = 20
    // export const GENESISTX_ID_LEN = 36
    // export const AMOUNT_LEN = 8
    // export const ADDRESS_LEN = 20
    // export const GENESIS_FLAG_LEN = 1
    // export const DATA_VERSION_LEN = 5
    // export const UNIQUE_ID_LEN = 20
    // export const BLOCK_NUM_LEN = 4
    exports.BURN_ADDRESS = Buffer.alloc(20, 0);
    // export const PROTO_HEADER_OFFSET = DATA_VERSION_LEN + HEADER_LEN
    // export const NULL_GENESISTX_ID =
    //   '000000000000000000000000000000000000000000000000000000000000000000000000'
    // export const TOKEN_ID_LEN = 20
    // export const SENSIBLE_ID_LEN = 36
    // export const RABIN_PUBKEY_HASH_ARRAY_HASH_LEN = 20
    // export const GENESIS_HASH_LEN = 20
    // export const TOKEN_AMOUNT_LEN = 8
    // export const TOKEN_ADDRESS_LEN = 20
    // export const TOKEN_DECIMAL_LEN = 1
    // export const TOKEN_SYMBOL_LEN = 20
    // export const TOKEN_NAME_LEN = 40
    exports.TX_VERSION = 10;
    // export const SIG_HASH_ALL = mvc.crypto.Signature.SIGHASH_ALL | mvc.crypto.Signature.SIGHASH_FORKID
    // export const SIG_HASH_SINGLE =
    //   mvc.crypto.Signature.SIGHASH_SINGLE | mvc.crypto.Signature.SIGHASH_FORKID
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"buffer":84}],417:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "Token",
        "md5": "fa5d3953b0b913a8e05d2aed3b4477e7",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckHashIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckScript",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTokenInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "prevTokenAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTokenAmount",
                        "type": "int"
                    },
                    {
                        "name": "tokenTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevTokenTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "senderPubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "senderSig",
                        "type": "Sig"
                    },
                    {
                        "name": "contractInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "contractTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "operation",
                        "type": "int"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": [
                    {
                        "name": "transferAmountCheckCodeHashArray",
                        "type": "bytes[5]"
                    },
                    {
                        "name": "unlockAmountCheckCodeHashArray",
                        "type": "bytes[5]"
                    }
                ]
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/token-v2.scrypt",
        "hex": "515301402097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c557954798501145593140000000000000000000000000000000000000000780124937601149376589376011493768b76011493760128937652935501149376011493765493<transferAmountCheckCodeHashArray[0]><transferAmountCheckCodeHashArray[1]><transferAmountCheckCodeHashArray[2]><transferAmountCheckCodeHashArray[3]><transferAmountCheckCodeHashArray[4]><unlockAmountCheckCodeHashArray[0]><unlockAmountCheckCodeHashArray[1]><unlockAmountCheckCodeHashArray[2]><unlockAmountCheckCodeHashArray[3]><unlockAmountCheckCodeHashArray[4]>013b7976547f75777601007e81775a9d013a79aa013c797601247f75547f777788013b797601687f7700005279517f75007f7d7701fd87635379537f75517f777601007e8177537a757b7b5379535479937f75537f777b757c677601fe87635379557f75517f777601007e8177537a757b7b5379555479937f75557f777b757c677601ff87635379597f75517f777601007e8177537a757b7b5379595479937f75597f777b757c675379517f75007f777601007e8177537a757b7b5379515479937f75517f777b757c68686875777777768277012079519c636e6e011879947f7578011779947f77777776011979879169012879a97888012779012979ad7567012079529c636e6e011879947f7578011779947f77777776011979876476012379a688013d790127798b0124957f750127790124957f7701267901267901267901267954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d6d687567006968686e6e011a79940124937f7578011a79947f77777776012d79aa0130797e87646f756e011b79947f7578011a79947f77777776012b79a6875479547901377901377970011c79947f7552797e78586e8b80767682778c7f75007f777777777e54795479011f79947f777e7777777776a8012d798752796476675168696d6d68013e797601687f7501447f77777601337901377901307901307901307901307958790139790139790139790139795b7901207f755b79aa885a795a79557955795579557955795c7f75587f777601007e8177567901307f75607f77567952799f695579827752790128959d5579a878885479827701209d53798277549d547954797e53797e76577959798b0128957f7559790128957f77886d6d6d6d756f757e7656798764597959795979597954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d75686d6d6d6d6d6d75706e011c79940124937f7578011b79947f77a97777547954796e6e011879947f757777a97777014079013f79013f79013f79013f79013f79013f79013f79597959795c79014a790130795c795b798b0124957f755b790124957f775679a85879885a795a795a795a7954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d7556798277567958795279012479940114937f755279012479947f7788557958795279012479947f755279012379947f7788577978012279947f7578012179947f777601007e81770120797801145893959354935979537952799454937f7553795279947f777601007e81775579529c63527900a2695a7954795379947f75547953799452795495947f776f75549593537a757b7b5279787758798b54957f75587954957f777601007e8177587a75577a577a577a577a577a577a577a7567527900a0695679789f6968780078014ba1637551677802ff00a1635277677803ffff00a1635377675577686868775279935b7955795279947f75a976012479012479012479012479012479550119797600a26976559f699451958c6b6c766b796c756b6d6d756c876476011f79011f79011f79011f79011f79550119797600a26976559f699451958c6b6c766b796c756b6d6d756c876751686959790114795a798b0124957f755a790124957f77886d6d6d6d6d6d6d6d6d6d014179011e7978012379012379210ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800206c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce081001257956795679aa7676517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01007e817757795679567956795679537956795479577995939521414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff006e6e9776009f636e936776687777777b757c6e5296a0636e7c947b757c6853798277527982775379012080517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01205279947f77545379935279930130787e527e54797e58797e527e53797e52797e57797e777777777777777777777777765779ac7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777",
        "sourceMapFile": ""
    }
    },{}],418:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenGenesis",
        "md5": "9e138e480974c3147f0bb98de1b053ef",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "pubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "sig",
                        "type": "Sig"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "genesisTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "prevInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "genesisTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevGenesisTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTxOutputHashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTxOutputSatoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "genesisSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "tokenSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenGenesis.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],419:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenTransferCheck",
        "md5": "c333922ef492aa9d58e7365240d247b6",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenTransferCheck_10To10.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],420:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenTransferCheck",
        "md5": "e41a12f0b2a85feddce2f3f285ce332e",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenTransferCheck_20To3.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],421:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenTransferCheck",
        "md5": "e29cb0437578e4aa452cd835e58e6b1f",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenTransferCheck_3To100.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],422:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenTransferCheck",
        "md5": "94a0b90b08ad2905bbb5088dc94e2e8d",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenTransferCheck_6To6.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],423:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenTransferCheck",
        "md5": "421557877612399eca7ad07d56c310ed",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "changeAddress",
                        "type": "Ripemd160"
                    },
                    {
                        "name": "opReturnScript",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenTransferCheck.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],424:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenUnlockContractCheck",
        "md5": "c909a26523264d817d7d85e2a659b723",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "tokenOutputIndexArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenUnlockContractCheck_20To5.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],425:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenUnlockContractCheck",
        "md5": "4abc2f94608199c863e526aa6c09a093",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "tokenOutputIndexArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenUnlockContractCheck_3To100.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],426:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenUnlockContractCheck",
        "md5": "7d598946ea321178d731170b8d2e2481",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "tokenOutputIndexArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenUnlockContractCheck_4To8.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],427:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenUnlockContractCheck",
        "md5": "51295fc0edbdae6f59da06e2fe9626c2",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "tokenOutputIndexArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenUnlockContractCheck_8To12.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],428:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TokenUnlockContractCheck",
        "md5": "6870f1fecb67418511172ef8f9a27cce",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenScript",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHeaderArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxHashProofArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenSatoshiBytesArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAddressArray",
                        "type": "bytes"
                    },
                    {
                        "name": "inputTokenAmountArray",
                        "type": "bytes"
                    },
                    {
                        "name": "nOutputs",
                        "type": "int"
                    },
                    {
                        "name": "tokenOutputIndexArray",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenOutputSatoshis",
                        "type": "int"
                    },
                    {
                        "name": "otherOutputArray",
                        "type": "bytes"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/tokenUnlockContractCheck.scrypt",
        "hex": " ",
        "sourceMapFile": ""
    }
    },{}],429:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "Token",
        "md5": "2784cda7c2c25db5b8c98065e9884e09",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "ProtoHeader",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "AmountCheckProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TokenProto",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "Backtrace",
                "params": [],
                "properties": [],
                "genericTypes": []
            },
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "function",
                "name": "unlock",
                "index": 0,
                "params": [
                    {
                        "name": "txPreimage",
                        "type": "SigHashPreimage"
                    },
                    {
                        "name": "prevouts",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckHashIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "amountCheckTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "amountCheckScript",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTokenInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "prevTokenAddress",
                        "type": "bytes"
                    },
                    {
                        "name": "prevTokenAmount",
                        "type": "int"
                    },
                    {
                        "name": "tokenTxHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "tokenTxInputProof",
                        "type": "TxInputProof"
                    },
                    {
                        "name": "prevTokenTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "senderPubKey",
                        "type": "PubKey"
                    },
                    {
                        "name": "senderSig",
                        "type": "Sig"
                    },
                    {
                        "name": "contractInputIndex",
                        "type": "int"
                    },
                    {
                        "name": "contractTxProof",
                        "type": "TxOutputProof"
                    },
                    {
                        "name": "operation",
                        "type": "int"
                    }
                ]
            },
            {
                "type": "constructor",
                "params": [
                    {
                        "name": "transferAmountCheckCodeHashArray",
                        "type": "bytes[5]"
                    },
                    {
                        "name": "unlockAmountCheckCodeHashArray",
                        "type": "bytes[5]"
                    }
                ]
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/token/token.scrypt",
        "hex": "515301402097dfd76851bf465e8f715593b217714858bbe9570ff3bd5e33840a34e20ff0262102ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382201008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c557954798501145593140000000000000000000000000000000000000000780124937601149376589376011493768b76011493760128937652935501149376011493765493<transferAmountCheckCodeHashArray[0]><transferAmountCheckCodeHashArray[1]><transferAmountCheckCodeHashArray[2]><transferAmountCheckCodeHashArray[3]><transferAmountCheckCodeHashArray[4]><unlockAmountCheckCodeHashArray[0]><unlockAmountCheckCodeHashArray[1]><unlockAmountCheckCodeHashArray[2]><unlockAmountCheckCodeHashArray[3]><unlockAmountCheckCodeHashArray[4]>013b7976547f75777601007e81775a9d013a79aa013c797601247f75547f777788013b797601687f7700005279517f75007f7d7701fd87635379537f75517f777601007e8177537a757b7b5379535479937f75537f777b757c677601fe87635379557f75517f777601007e8177537a757b7b5379555479937f75557f777b757c677601ff87635379597f75517f777601007e8177537a757b7b5379595479937f75597f777b757c675379517f75007f777601007e8177537a757b7b5379515479937f75517f777b757c68686875777777768277012079519c636e6e011879947f7578011779947f77777776011979879169012879a97888012779012979ad7567012079529c636e6e011879947f7578011779947f77777776011979876476012379a688013d790127798b0124957f750127790124957f7701267901267901267901267954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d6d687567006968686e6e011a79940124937f7578011a79947f7777777601207f75012d79aa87646f756e011b79947f7578011a79947f77777776012b79a6875479547901377901377970011c79947f7552797e78586e8b80767682778c7f75007f777777777e54795479011f79947f777e7777777776a8012d798752796476675168696d6d68013e797601687f7501447f77777601337901377901307901307901307901307958790139790139790139790139795b7901207f755b79aa885a795a79557955795579557955795c7f75587f777601007e8177567901307f75607f77567952799f695579827752790128959d5579a878885479827701209d53798277549d547954797e53797e76577959798b0128957f7559790128957f77886d6d6d6d756f757e7656798764597959795979597954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d75686d6d6d6d6d6d75706e011c79940124937f7578011b79947f77a97777547954796e6e011879947f757777a97777014079013f79013f79013f79013f79013f79013f79013f79597959795c79014a790130795c795b798b0124957f755b790124957f775679a85879885a795a795a795a7954795479aa7801207f75887601207f777601007e81775579607f755c7f777601007e8177567901707f7501507f775679827752790128959d5679a878885479827701209d557955797e76587955798b0128957f7555790128957f77886d6d6d6d7556798277567958795279012479940114937f755279012479947f7788557958795279012479947f755279012379947f7788577978012279947f7578012179947f777601007e81770120797801145893959354935979537952799454937f7553795279947f777601007e81775579529c63527900a2695a7954795379947f75547953799452795495947f776f75549593537a757b7b5279787758798b54957f75587954957f777601007e8177587a75577a577a577a577a577a577a577a7567527900a0695679789f6968780078014ba1637551677802ff00a1635277677803ffff00a1635377675577686868775279935b7955795279947f75a976012479012479012479012479012479550119797600a26976559f699451958c6b6c766b796c756b6d6d756c876476011f79011f79011f79011f79011f79550119797600a26976559f699451958c6b6c766b796c756b6d6d756c876751686959790114795a798b0124957f755a790124957f77886d6d6d6d6d6d6d6d6d6d014179011e7978012379012379210ac407f0e4bd44bfc207355a778b046225a7068fc59ee7eda43ad905aadbffc800206c266b30e6a1319c66dc401e5bd6b432ba49688eecd118297041da8074ce081001257956795679aa7676517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01007e817757795679567956795679537956795479577995939521414136d08c5ed2bf3ba048afe6dcaebafeffffffffffffffffffffffffffffff006e6e9776009f636e936776687777777b757c6e5296a0636e7c947b757c6853798277527982775379012080517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f517f7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e7c7e01205279947f77545379935279930130787e527e54797e58797e527e53797e52797e57797e777777777777777777777777765779ac7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777",
        "sourceMapFile": ""
    }
    },{}],430:[function(require,module,exports){
    module.exports={
        "version": 9,
        "compilerVersion": "1.19.0+commit.72eaeba",
        "contract": "TxUtil",
        "md5": "2920f04d42c66cf433d55b6e738ee31e",
        "structs": [
            {
                "name": "LockingScriptParts",
                "params": [
                    {
                        "name": "code",
                        "type": "bytes"
                    },
                    {
                        "name": "data",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "OpPushData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "VarIntData",
                "params": [
                    {
                        "name": "len",
                        "type": "int"
                    },
                    {
                        "name": "value",
                        "type": "int"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxInputProof",
                "params": [
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "txHash",
                        "type": "bytes"
                    },
                    {
                        "name": "outputIndexBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "sequenceBytes",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            },
            {
                "name": "TxOutputProof",
                "params": [
                    {
                        "name": "txHeader",
                        "type": "bytes"
                    },
                    {
                        "name": "hashProof",
                        "type": "bytes"
                    },
                    {
                        "name": "satoshiBytes",
                        "type": "bytes"
                    },
                    {
                        "name": "scriptHash",
                        "type": "bytes"
                    }
                ],
                "genericTypes": []
            }
        ],
        "library": [
            {
                "name": "TxUtil",
                "params": [],
                "properties": [],
                "genericTypes": []
            }
        ],
        "alias": [],
        "abi": [
            {
                "type": "constructor",
                "params": []
            }
        ],
        "stateProps": [],
        "buildType": "debug",
        "file": "file:///Users/ivan/Codes/blockchain/meta-contract/src/mcp02/contract/txUtil.scrypt",
        "hex": "",
        "sourceMapFile": ""
    }
    },{}],431:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TokenFactory = exports.Token = void 0;
    const BN = require("../../bn.js");
    const mvc = require("../../mvc");
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const dummy_1 = require("../../common/dummy");
    const protoheader_1 = require("../../common/protoheader");
    const TokenUtil = require("../../common/tokenUtil");
    const utils_1 = require("../../common/utils");
    const scryptlib_1 = require("../../scryptlib");
    const ftProto = require("../contract-proto/token.proto");
    const contractUtil_1 = require("../contractUtil");
    class Token extends ContractAdapter_1.ContractAdapter {
        constructor(constuctParams, version = 2) {
            let desc = version === 2 ? require('../contract-desc/token-v2_desc.json') : require('../contract-desc/token_desc.json');
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new ClassObj(constuctParams.transferCheckCodeHashArray, constuctParams.unlockContractCodeHashArray);
            super(contract);
            this.constuctParams = constuctParams;
            this._formatedDataPart = {};
        }
        static fromASM(asm) {
            let desc = require('../contract-desc/token-v2_desc.json');
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = ClassObj.fromASM(asm);
            return contract;
        }
        clone() {
            let contract = new Token(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            this._formatedDataPart.protoVersion = ftProto.PROTO_VERSION;
            this._formatedDataPart.protoType = protoheader_1.PROTO_TYPE.FT;
            super.setDataPart((0, scryptlib_1.toHex)(ftProto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        unlock({ txPreimage, prevouts, 
        // token
        tokenInputIndex, prevTokenInputIndex, prevTokenAddress, prevTokenAmount, tokenTxHeader, tokenTxInputProof, prevTokenTxOutputProof, 
        // contract
        contractInputIndex, contractTxOutputProof, 
        // unlockCheck
        amountCheckHashIndex, amountCheckInputIndex, amountCheckTxOutputProofInfo, amountCheckScript, 
        // sig
        senderPubKey, senderSig, operation, }) {
            if (operation != ftProto.FT_OP_TYPE.TRANSFER) {
                senderPubKey = new scryptlib_1.PubKey('00');
                senderSig = new scryptlib_1.Sig('00');
            }
            return this._contract.unlock(txPreimage, prevouts, 
            // amountCheck
            tokenInputIndex, amountCheckHashIndex, amountCheckInputIndex, amountCheckTxOutputProofInfo, amountCheckScript, 
            // token
            prevTokenInputIndex, prevTokenAddress, prevTokenAmount, tokenTxHeader, tokenTxInputProof, prevTokenTxOutputProof, 
            // sig data
            senderPubKey, senderSig, 
            // contract
            contractInputIndex, contractTxOutputProof, 
            // op
            operation);
        }
        unlockOld({ txPreimage, tokenInputIndex, prevouts, rabinMsg, rabinPaddingArray, rabinSigArray, rabinPubKeyIndexArray, rabinPubKeyVerifyArray, rabinPubKeyHashArray, checkInputIndex, checkScriptTx, nReceivers, prevTokenAddress, prevTokenAmount, senderPubKey, senderSig, lockContractInputIndex, lockContractTx, operation, }) {
            if (operation != ftProto.FT_OP_TYPE.TRANSFER) {
                senderPubKey = new scryptlib_1.PubKey('');
                senderSig = new scryptlib_1.Sig('');
            }
            if (operation != ftProto.FT_OP_TYPE.UNLOCK_FROM_CONTRACT) {
                lockContractInputIndex = 0;
                lockContractTx = new scryptlib_1.Bytes('');
            }
            return this._contract.unlock(txPreimage, tokenInputIndex, prevouts, rabinMsg, rabinPaddingArray, rabinSigArray, rabinPubKeyIndexArray, rabinPubKeyVerifyArray, rabinPubKeyHashArray, checkInputIndex, checkScriptTx, nReceivers, prevTokenAddress, prevTokenAmount, senderPubKey, senderSig, lockContractInputIndex, lockContractTx, operation);
        }
    }
    exports.Token = Token;
    class TokenFactory {
        static getLockingScriptSize() {
            return this.lockingScriptSize;
        }
        static createContract(transferCheckCodeHashArray, unlockContractCodeHashArray, version = 2) {
            return new Token({
                transferCheckCodeHashArray,
                unlockContractCodeHashArray,
            }, version);
        }
        static getDummyInstance() {
            let contract = this.createContract(contractUtil_1.ContractUtil.transferCheckCodeHashArray, contractUtil_1.ContractUtil.unlockContractCodeHashArray);
            // contract.setFormatedDataPart({})
            contract.setDataPart('');
            return contract;
        }
        static calLockingScriptSize() {
            let contract = this.getDummyInstance();
            return contract.lockingScript.toBuffer().length;
        }
        static calUnlockingScriptSize(routeCheckContact, bsvInputLen, tokenInputLen, tokenOutputLen) {
            return 1000; // TODO:!!
            let contract = this.getDummyInstance();
            const preimage = (0, scryptlib_1.getPreimage)(dummy_1.dummyTx, contract.lockingScript.toASM(), 1);
            const sig = Buffer.from(utils_1.PLACE_HOLDER_SIG, 'hex');
            const rabinMsg = dummy_1.dummyPayload;
            const rabinPaddingArray = [];
            const rabinSigArray = [];
            const rabinPubKeyIndexArray = [];
            const rabinPubKeyArray = [];
            for (let i = 0; i < ftProto.SIGNER_VERIFY_NUM; i++) {
                rabinPaddingArray.push(new scryptlib_1.Bytes(dummy_1.dummyPadding));
                rabinSigArray.push(new scryptlib_1.Int(BN.fromString(dummy_1.dummySigBE, 16).toString(10)));
                rabinPubKeyIndexArray.push(i);
                rabinPubKeyArray.push(new scryptlib_1.Int(dummy_1.dummyRabinPubKey.toString(10)));
            }
            const tokenInputIndex = 0;
            let prevouts = Buffer.alloc(0);
            const indexBuf = TokenUtil.getUInt32Buf(0);
            const txidBuf = TokenUtil.getTxIdBuf(dummy_1.dummyTxId);
            for (let i = 0; i < tokenInputLen + bsvInputLen + 1; i++) {
                prevouts = Buffer.concat([prevouts, txidBuf, indexBuf]);
            }
            const routeCheckInputIndex = 0;
            let routeCheckTx = new mvc.Transaction(dummy_1.dummyTx.serialize(true));
            routeCheckTx.addOutput(new mvc.Transaction.Output({
                script: routeCheckContact.lockingScript,
                satoshis: 10000,
            }));
            return 1000;
            // let unlockedContract = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   prevouts: new Bytes(toHex(prevouts)),
            //   tokenInputIndex,
            //   prevTokenAddress: new Bytes(toHex(dummyAddress.hashBuffer)),
            //   prevTokenAmount: new Int('1000000000'),
            //   senderPubKey: new PubKey(toHex(dummyPk)),
            //   senderSig: new Sig(toHex(sig)),
            //   operation: ftProto.FT_OP_TYPE.TRANSFER,
            // })
            // return (unlockedContract.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.TokenFactory = TokenFactory;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js":381,"../../common/ContractAdapter":382,"../../common/dummy":387,"../../common/protoheader":389,"../../common/tokenUtil":390,"../../common/utils":391,"../../mvc":440,"../../scryptlib":445,"../contract-desc/token-v2_desc.json":417,"../contract-desc/token_desc.json":429,"../contract-proto/token.proto":435,"../contractUtil":438,"buffer":84}],432:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TokenGenesisFactory = exports.TokenGenesis = void 0;
    const mvc = require("../../mvc");
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const protoheader_1 = require("../../common/protoheader");
    const scryptlib_1 = require("../../scryptlib");
    const ftProto = require("../contract-proto/token.proto");
    const token_1 = require("./token");
    const genesisTokenIDTxid = '0000000000000000000000000000000000000000000000000000000000000000';
    class TokenGenesis extends ContractAdapter_1.ContractAdapter {
        // constructor(constuctParams: { pubKey: mvc.PublicKey }) {
        constructor(constuctParams) {
            let desc = require('../contract-desc/tokenGenesis_desc.json');
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new ClassObj();
            super(contract);
            this.constuctParams = constuctParams;
            this._formatedDataPart = {};
        }
        clone() {
            let contract = new TokenGenesis(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            this._formatedDataPart.genesisHash = '';
            this._formatedDataPart.protoVersion = ftProto.PROTO_VERSION;
            this._formatedDataPart.protoType = protoheader_1.PROTO_TYPE.FT;
            super.setDataPart((0, scryptlib_1.toHex)(ftProto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        setFormatedDataPartFromLockingScript(script) {
            let dataPart = ftProto.parseDataPart(script.toBuffer());
            this.setFormatedDataPart(dataPart);
        }
        isFirstGenesis() {
            return this.getFormatedDataPart().sensibleID.txid == genesisTokenIDTxid;
        }
        unlock({ txPreimage, pubKey, sig, tokenScript, 
        // GenesisTx Input Proof
        genesisTxHeader, prevInputIndex, genesisTxInputProof, 
        // Prev GenesisTx Output Proof
        prevGenesisTxHeader, prevTxOutputHashProof, prevTxOutputSatoshiBytes, genesisSatoshis, tokenSatoshis, changeAddress, changeSatoshis, opReturnScript, }) {
            return this._contract.unlock(txPreimage, pubKey, sig, tokenScript, genesisTxHeader, prevInputIndex, genesisTxInputProof, prevGenesisTxHeader, prevTxOutputHashProof, prevTxOutputSatoshiBytes, genesisSatoshis, tokenSatoshis, changeAddress, changeSatoshis, opReturnScript);
        }
    }
    exports.TokenGenesis = TokenGenesis;
    class TokenGenesisFactory {
        static getLockingScriptSize() {
            return this.lockingScriptSize;
        }
        /**
         * create genesis contract
         * @param {Object} issuerPubKey issuer public key used to unlocking genesis contract
         * @param {string} tokenName the token name
         * @param {string} tokenSymbol the token symbol
         * @param {number} decimalNum the token amount decimal number
         * @returns
         */
        static createContract() {
            return new TokenGenesis({});
        }
        static getDummyInstance() {
            let contract = this.createContract();
            // contract.setFormatedDataPart({}) // TODO:
            contract.setDataPart('');
            return contract;
        }
        static calLockingScriptSize() {
            let contract = this.getDummyInstance();
            let size = contract.lockingScript.toBuffer().length;
            return size;
        }
        static calUnlockingScriptSize(opreturnData) {
            let opreturnScriptHex = '';
            if (opreturnData) {
                let script = mvc.Script.buildSafeDataOut(opreturnData);
                opreturnScriptHex = script.toHex();
            }
            let contract = this.getDummyInstance();
            let tokenContract = token_1.TokenFactory.getDummyInstance();
            // const preimage = getPreimage(dummyTx, contract.lockingScript.toASM(), 1) // TODO: fix dummy
            return 10000;
            // let unlockResult = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   sig: new Sig(toHex(sig)),
            //   rabinMsg: new Bytes(toHex(rabinMsg)),
            //   rabinPaddingArray,
            //   rabinSigArray,
            //   rabinPubKeyIndexArray,
            //   rabinPubKeyVerifyArray,
            //   rabinPubKeyHashArray: new Bytes(toHex(dummyRabinPubKeyHashArray)),
            //   genesisSatoshis: 1000,
            //   tokenScript: new Bytes(tokenContract.lockingScript.toHex()),
            //   tokenSatoshis: 1000,
            //   changeAddress: new Ripemd160(toHex(dummyAddress.hashBuffer)),
            //   changeSatoshis: 1000,
            //   opReturnScript: new Bytes(opreturnScriptHex),
            // })
            // return (unlockResult.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.TokenGenesisFactory = TokenGenesisFactory;
    
    },{"../../common/ContractAdapter":382,"../../common/protoheader":389,"../../mvc":440,"../../scryptlib":445,"../contract-desc/tokenGenesis_desc.json":418,"../contract-proto/token.proto":435,"./token":431}],433:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TokenTransferCheckFactory = exports.TokenTransferCheck = exports.TOKEN_TRANSFER_TYPE = void 0;
    const BN = require("../../bn.js");
    const mvc = require("../../mvc");
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const dummy_1 = require("../../common/dummy");
    const TokenUtil = require("../../common/tokenUtil");
    const utils_1 = require("../../common/utils");
    const scryptlib_1 = require("../../scryptlib");
    const token_proto_1 = require("../contract-proto/token.proto");
    const proto = require("../contract-proto/tokenTransferCheck.proto");
    const token_1 = require("./token");
    var TOKEN_TRANSFER_TYPE;
    (function (TOKEN_TRANSFER_TYPE) {
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_3_OUT_3"] = 1] = "IN_3_OUT_3";
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_6_OUT_6"] = 2] = "IN_6_OUT_6";
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_10_OUT_10"] = 3] = "IN_10_OUT_10";
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_20_OUT_3"] = 4] = "IN_20_OUT_3";
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["IN_3_OUT_100"] = 5] = "IN_3_OUT_100";
        TOKEN_TRANSFER_TYPE[TOKEN_TRANSFER_TYPE["UNSUPPORT"] = 6] = "UNSUPPORT";
    })(TOKEN_TRANSFER_TYPE = exports.TOKEN_TRANSFER_TYPE || (exports.TOKEN_TRANSFER_TYPE = {}));
    let _tokenTransferTypeInfos = [
        {
            type: TOKEN_TRANSFER_TYPE.IN_3_OUT_3,
            in: 3,
            out: 3,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_TRANSFER_TYPE.IN_6_OUT_6,
            in: 6,
            out: 6,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_TRANSFER_TYPE.IN_10_OUT_10,
            in: 10,
            out: 10,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_TRANSFER_TYPE.IN_20_OUT_3,
            in: 20,
            out: 3,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_TRANSFER_TYPE.IN_3_OUT_100,
            in: 3,
            out: 100,
            lockingScriptSize: 0,
        },
    ];
    class TokenTransferCheck extends ContractAdapter_1.ContractAdapter {
        constructor(constuctParams) {
            let desc;
            switch (constuctParams.checkType) {
                case TOKEN_TRANSFER_TYPE.IN_3_OUT_3:
                    desc = require('../contract-desc/tokenTransferCheck_desc.json');
                    break;
                case TOKEN_TRANSFER_TYPE.IN_6_OUT_6:
                    desc = require('../contract-desc/tokenTransferCheck_6To6_desc.json');
                    break;
                case TOKEN_TRANSFER_TYPE.IN_10_OUT_10:
                    desc = require('../contract-desc/tokenTransferCheck_10To10_desc.json');
                    break;
                case TOKEN_TRANSFER_TYPE.IN_3_OUT_100:
                    desc = require('../contract-desc/tokenTransferCheck_3To100_desc.json');
                    break;
                case TOKEN_TRANSFER_TYPE.IN_20_OUT_3:
                    desc = require('../contract-desc/tokenTransferCheck_20To3_desc.json');
                    break;
                default:
                    throw 'invalid checkType';
            }
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new ClassObj();
            super(contract);
            this.constuctParams = constuctParams;
            this._formatedDataPart = {};
        }
        clone() {
            let contract = new TokenTransferCheck(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            super.setDataPart((0, scryptlib_1.toHex)(proto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        unlock({ txPreimage, prevouts, tokenScript, tokenTxHeaderArray, tokenTxHashProofArray, tokenSatoshiBytesArray, inputTokenAddressArray, inputTokenAmountArray, 
        // receiverSatoshiArray,
        tokenOutputSatoshis, changeSatoshis, changeAddress, opReturnScript, }) {
            return this._contract.unlock(txPreimage, prevouts, tokenScript, 
            // token
            tokenTxHeaderArray, tokenTxHashProofArray, tokenSatoshiBytesArray, inputTokenAddressArray, inputTokenAmountArray, 
            // receiverSatoshiArray,
            tokenOutputSatoshis, 
            // same
            changeSatoshis, changeAddress, opReturnScript);
        }
    }
    exports.TokenTransferCheck = TokenTransferCheck;
    class TokenTransferCheckFactory {
        static getLockingScriptSize(checkType) {
            return this.tokenTransferTypeInfos.find((v) => v.type == checkType).lockingScriptSize;
        }
        static getOptimumType(inCount, outCount) {
            let typeInfo = this.tokenTransferTypeInfos.find((v) => inCount <= v.in && outCount <= v.out);
            if (!typeInfo) {
                return TOKEN_TRANSFER_TYPE.UNSUPPORT;
            }
            return typeInfo.type;
        }
        static createContract(tokenTransferType) {
            return new TokenTransferCheck({ checkType: tokenTransferType });
        }
        static getDummyInstance(checkType) {
            let v = this.tokenTransferTypeInfos.find((v) => v.type == checkType);
            let tokenInputArray = new Array(v.in).fill(0);
            let tokenOutputArray = new Array(v.out).fill({
                address: dummy_1.dummyAddress,
                tokenAmount: BN.Zero,
            });
            let contract = this.createContract(v.type);
            contract.setFormatedDataPart({
                nSenders: tokenInputArray.length,
                receiverTokenAmountArray: tokenOutputArray.map((v) => v.tokenAmount),
                receiverArray: tokenOutputArray.map((v) => v.address),
                nReceivers: tokenOutputArray.length,
                tokenCodeHash: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
                tokenID: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
            });
            return contract;
        }
        static calLockingScriptSize(checkType) {
            let contract = this.getDummyInstance(checkType);
            return contract.lockingScript.toBuffer().length;
        }
        static calUnlockingScriptSize(checkType, bsvInputLen, tokenInputLen, tokenOutputLen, opreturnData) {
            return 1000; // TODO:!!!
            let opreturnScriptHex = '';
            if (opreturnData) {
                let script = mvc.Script.buildSafeDataOut(opreturnData);
                opreturnScriptHex = script.toHex();
            }
            let contract = this.getDummyInstance(checkType);
            let tokenContractInstance = token_1.TokenFactory.getDummyInstance();
            const preimage = (0, scryptlib_1.getPreimage)(dummy_1.dummyTx, contract.lockingScript.toASM(), 1);
            const sig = Buffer.from(utils_1.PLACE_HOLDER_SIG, 'hex');
            const rabinMsg = dummy_1.dummyPayload;
            let checkRabinMsgArray = Buffer.alloc(0);
            let checkRabinSigArray = Buffer.alloc(0);
            let checkRabinPaddingArray = Buffer.alloc(0);
            let paddingCountBuf = Buffer.alloc(2, 0);
            paddingCountBuf.writeUInt16LE(dummy_1.dummyPadding.length / 2);
            const padding = Buffer.alloc(dummy_1.dummyPadding.length / 2, 0);
            padding.write(dummy_1.dummyPadding, 'hex');
            const rabinPaddingArray = [];
            const rabinSigArray = [];
            const rabinPubKeyIndexArray = [];
            const rabinPubKeyArray = [];
            const sigBuf = TokenUtil.toBufferLE(dummy_1.dummySigBE, TokenUtil.RABIN_SIG_LEN);
            let inputTokenAddressArray = Buffer.alloc(0);
            let inputTokenAmountArray = Buffer.alloc(0);
            let tokenAmount = Buffer.alloc(8);
            tokenAmount.writeInt32BE(100000);
            for (let i = 0; i < tokenInputLen; i++) {
                inputTokenAddressArray = Buffer.concat([inputTokenAddressArray, dummy_1.dummyAddress.toBuffer()]);
                inputTokenAmountArray = Buffer.concat([inputTokenAmountArray, tokenAmount]);
                for (let j = 0; j < token_proto_1.SIGNER_VERIFY_NUM; j++) {
                    if (j == 0) {
                        checkRabinMsgArray = Buffer.concat([checkRabinMsgArray, Buffer.from(dummy_1.dummyPayload, 'hex')]);
                    }
                    checkRabinSigArray = Buffer.concat([checkRabinSigArray, sigBuf]);
                    checkRabinPaddingArray = Buffer.concat([checkRabinPaddingArray, paddingCountBuf, padding]);
                }
            }
            for (let i = 0; i < token_proto_1.SIGNER_VERIFY_NUM; i++) {
                rabinPaddingArray.push(new scryptlib_1.Bytes(dummy_1.dummyPadding));
                rabinSigArray.push(new scryptlib_1.Int(BN.fromString(dummy_1.dummySigBE, 16).toString(10)));
                rabinPubKeyIndexArray.push(i);
                rabinPubKeyArray.push(new scryptlib_1.Int(dummy_1.dummyRabinPubKey.toString(10)));
            }
            const tokenInputIndex = 0;
            let prevouts = Buffer.alloc(0);
            const indexBuf = TokenUtil.getUInt32Buf(0);
            const txidBuf = TokenUtil.getTxIdBuf(dummy_1.dummyTxId);
            for (let i = 0; i < tokenInputLen + bsvInputLen + 1; i++) {
                prevouts = Buffer.concat([prevouts, txidBuf, indexBuf]);
            }
            let receiverSatoshiArray = Buffer.alloc(0);
            for (let i = 0; i < tokenOutputLen; i++) {
                receiverSatoshiArray = Buffer.concat([receiverSatoshiArray, Buffer.alloc(8)]);
            }
            return 1000;
            // let unlockedContract = contract.unlock({
            //   txPreimage: new SigHashPreimage(toHex(preimage)),
            //   tokenScript: new Bytes(tokenContractInstance.lockingScript.toHex()),
            //   prevouts: new Bytes(toHex(prevouts)),
            //   rabinMsgArray: new Bytes(toHex(checkRabinMsgArray)),
            //   rabinPaddingArray: new Bytes(toHex(checkRabinPaddingArray)),
            //   rabinSigArray: new Bytes(toHex(checkRabinSigArray)),
            //   rabinPubKeyIndexArray,
            //   rabinPubKeyVerifyArray: rabinPubKeyArray,
            //   rabinPubKeyHashArray: new Bytes(toHex(dummyRabinPubKeyHashArray)),
            //   inputTokenAddressArray: new Bytes(toHex(inputTokenAddressArray)),
            //   inputTokenAmountArray: new Bytes(toHex(inputTokenAmountArray)),
            //   receiverSatoshiArray: new Bytes(toHex(receiverSatoshiArray)),
            //   changeSatoshis: new Int(1000),
            //   changeAddress: new Ripemd160(toHex(dummyAddress.hashBuffer)),
            //   opReturnScript: new Bytes(opreturnScriptHex),
            // })
            // return (unlockedContract.toScript() as mvc.Script).toBuffer().length
        }
    }
    exports.TokenTransferCheckFactory = TokenTransferCheckFactory;
    TokenTransferCheckFactory.tokenTransferTypeInfos = _tokenTransferTypeInfos;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js":381,"../../common/ContractAdapter":382,"../../common/dummy":387,"../../common/tokenUtil":390,"../../common/utils":391,"../../mvc":440,"../../scryptlib":445,"../contract-desc/tokenTransferCheck_10To10_desc.json":419,"../contract-desc/tokenTransferCheck_20To3_desc.json":420,"../contract-desc/tokenTransferCheck_3To100_desc.json":421,"../contract-desc/tokenTransferCheck_6To6_desc.json":422,"../contract-desc/tokenTransferCheck_desc.json":423,"../contract-proto/token.proto":435,"../contract-proto/tokenTransferCheck.proto":436,"./token":431,"buffer":84}],434:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TokenUnlockContractCheckFactory = exports.TokenUnlockContractCheck = exports.TOKEN_UNLOCK_TYPE = void 0;
    const ContractAdapter_1 = require("../../common/ContractAdapter");
    const scryptlib_1 = require("../../scryptlib");
    const proto = require("../contract-proto/tokenUnlockContractCheck.proto");
    const dummy_1 = require("../../common/dummy");
    var TOKEN_UNLOCK_TYPE;
    (function (TOKEN_UNLOCK_TYPE) {
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["IN_2_OUT_5"] = 1] = "IN_2_OUT_5";
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["IN_4_OUT_8"] = 2] = "IN_4_OUT_8";
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["IN_8_OUT_12"] = 3] = "IN_8_OUT_12";
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["IN_3_OUT_100"] = 4] = "IN_3_OUT_100";
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["IN_20_OUT_5"] = 5] = "IN_20_OUT_5";
        TOKEN_UNLOCK_TYPE[TOKEN_UNLOCK_TYPE["UNSUPPORT"] = 6] = "UNSUPPORT";
    })(TOKEN_UNLOCK_TYPE = exports.TOKEN_UNLOCK_TYPE || (exports.TOKEN_UNLOCK_TYPE = {}));
    const _tokenUnlockTypeInfos = [
        {
            type: TOKEN_UNLOCK_TYPE.IN_2_OUT_5,
            in: 2,
            out: 5,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_UNLOCK_TYPE.IN_4_OUT_8,
            in: 4,
            out: 8,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_UNLOCK_TYPE.IN_3_OUT_100,
            in: 3,
            out: 100,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_UNLOCK_TYPE.IN_8_OUT_12,
            in: 8,
            out: 12,
            lockingScriptSize: 0,
        },
        {
            type: TOKEN_UNLOCK_TYPE.IN_20_OUT_5,
            in: 20,
            out: 5,
            lockingScriptSize: 0,
        },
    ];
    class TokenUnlockContractCheck extends ContractAdapter_1.ContractAdapter {
        constructor(constuctParams) {
            let desc;
            switch (constuctParams.unlockType) {
                case TOKEN_UNLOCK_TYPE.IN_2_OUT_5:
                    desc = require('../contract-desc/tokenUnlockContractCheck_desc.json');
                    break;
                case TOKEN_UNLOCK_TYPE.IN_4_OUT_8:
                    desc = require('../contract-desc/tokenUnlockContractCheck_4To8_desc.json');
                    break;
                case TOKEN_UNLOCK_TYPE.IN_8_OUT_12:
                    desc = require('../contract-desc/tokenUnlockContractCheck_8To12_desc.json');
                    break;
                case TOKEN_UNLOCK_TYPE.IN_3_OUT_100:
                    desc = require('../contract-desc/tokenUnlockContractCheck_3To100_desc.json');
                    break;
                case TOKEN_UNLOCK_TYPE.IN_20_OUT_5:
                    desc = require('../contract-desc/tokenUnlockContractCheck_20To5_desc.json');
                    break;
                default:
                    throw 'invalid unlockType';
            }
            let ClassObj = (0, scryptlib_1.buildContractClass)(desc);
            let contract = new ClassObj();
            super(contract);
            this.constuctParams = constuctParams;
            this._formatedDataPart = {};
        }
        clone() {
            let contract = new TokenUnlockContractCheck(this.constuctParams);
            contract.setFormatedDataPart(this.getFormatedDataPart());
            return contract;
        }
        setFormatedDataPart(dataPart) {
            this._formatedDataPart = Object.assign({}, this._formatedDataPart, dataPart);
            super.setDataPart((0, scryptlib_1.toHex)(proto.newDataPart(this._formatedDataPart)));
        }
        getFormatedDataPart() {
            return this._formatedDataPart;
        }
        unlock({ txPreimage, prevouts, tokenScript, tokenTxHeaderArray, tokenTxHashProofArray, tokenSatoshiBytesArray, inputTokenAddressArray, inputTokenAmountArray, nOutputs, tokenOutputIndexArray, tokenOutputSatoshis, otherOutputArray, }) {
            return this._contract.unlock(txPreimage, prevouts, tokenScript, tokenTxHeaderArray, tokenTxHashProofArray, tokenSatoshiBytesArray, inputTokenAddressArray, inputTokenAmountArray, nOutputs, tokenOutputIndexArray, tokenOutputSatoshis, otherOutputArray);
        }
    }
    exports.TokenUnlockContractCheck = TokenUnlockContractCheck;
    class TokenUnlockContractCheckFactory {
        static getOptimumType(inCount, outCount) {
            if (inCount <= 2 && outCount <= 5) {
                return TOKEN_UNLOCK_TYPE.IN_2_OUT_5;
            }
            else if (inCount <= 4 && outCount <= 8) {
                return TOKEN_UNLOCK_TYPE.IN_4_OUT_8;
            }
            else if (inCount <= 8 && outCount <= 12) {
                return TOKEN_UNLOCK_TYPE.IN_8_OUT_12;
            }
            else if (inCount <= 20 && outCount <= 5) {
                return TOKEN_UNLOCK_TYPE.IN_20_OUT_5;
            }
            else if (inCount <= 3 && outCount <= 100) {
                return TOKEN_UNLOCK_TYPE.IN_3_OUT_100;
            }
            else {
                return TOKEN_UNLOCK_TYPE.UNSUPPORT;
            }
        }
        static createContract(unlockType) {
            return new TokenUnlockContractCheck({ unlockType });
        }
        static getLockingScriptSize(unlockType) {
            return this.tokenUnlockTypeInfos.find((v) => v.type == unlockType).lockingScriptSize;
        }
        static calUnlockingScriptSize(checkType, mvcInputLen, tokenInputLen, tokenOutputLen, opreturnData) {
            // todo finish this
            return 1000;
        }
        static getDummyInstance(unlockType) {
            let v = this.tokenUnlockTypeInfos.find((v) => v.type == unlockType);
            let tokenInputArray = new Array(v.in).fill(0);
            let contract = this.createContract(v.type);
            contract.setFormatedDataPart({
                inputTokenIndexArray: tokenInputArray,
                tokenCodeHash: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
                tokenID: (0, scryptlib_1.toHex)(dummy_1.dummyCodehash),
                receiverTokenAmountArray: [],
                receiverArray: [],
                nReceivers: 0,
                nSender: tokenInputArray.length,
            });
            return contract;
        }
    }
    exports.TokenUnlockContractCheckFactory = TokenUnlockContractCheckFactory;
    TokenUnlockContractCheckFactory.tokenUnlockTypeInfos = _tokenUnlockTypeInfos;
    
    },{"../../common/ContractAdapter":382,"../../common/dummy":387,"../../scryptlib":445,"../contract-desc/tokenUnlockContractCheck_20To5_desc.json":424,"../contract-desc/tokenUnlockContractCheck_3To100_desc.json":425,"../contract-desc/tokenUnlockContractCheck_4To8_desc.json":426,"../contract-desc/tokenUnlockContractCheck_8To12_desc.json":427,"../contract-desc/tokenUnlockContractCheck_desc.json":428,"../contract-proto/tokenUnlockContractCheck.proto":437}],435:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.getQuerySensibleID = exports.getQueryGenesis = exports.getQueryCodehash = exports.updateScript = exports.parseDataPart = exports.newDataPart = exports.genGenesisTxid = exports.getUInt32Buf = exports.getTxIdBuf = exports.getNewTokenScript = exports.getDataPart = exports.getContractCodeHash = exports.getContractCode = exports.getTokenName = exports.getTokenSymbol = exports.getDecimalNum = exports.getTokenAddress = exports.getGenesisHash = exports.getSensibleID = exports.getTokenID = exports.getTokenAmount = exports.getHeaderLen = exports.GENESIS_FLAG = exports.FT_OP_TYPE = exports.OP_UNLOCK_FROM_CONTRACT = exports.OP_TRANSFER = exports.SIGNER_VERIFY_NUM = exports.SIGNER_NUM = exports.PROTO_VERSION = void 0;
    const BN = require("../../bn.js");
    const mvc = require("../../mvc");
    const proto = require("../../common/protoheader");
    const scryptlib_1 = require("../../scryptlib");
    const tokenUtil_1 = require("../../common/tokenUtil");
    exports.PROTO_VERSION = 1;
    exports.SIGNER_NUM = 5;
    exports.SIGNER_VERIFY_NUM = 3;
    // <op_pushdata> + <type specific data> + <proto header> + <data_len(4 bytes)> + <version(1 bytes)>
    // <token type specific data> = <name(40 bytes)> + <symbol(20 bytes)> + <decimal(1 bytes)> + <address(20 bytes)> + <token amount(8 bytes)> + <genesisHash(20 bytes)> + <genesisTxid(36 bytes)>
    // name 40
    // symbol 20
    // decimal 1
    // address 20
    // token amount/token value 8
    // genesis hash 20
    // genesis txid 36
    // token version // 4
    // token type // 4
    // protp flag // 12
    /**
     * 对应上面10个参数
     * */
    const TOKEN_NAME_LEN = 40;
    const TOKEN_SYMBOL_LEN = 20;
    const DECIMAL_NUM_LEN = 1;
    const TOKEN_ADDRESS_LEN = 20;
    const TOKEN_AMOUNT_LEN = 8;
    const GENESIS_HASH_LEN = 20;
    const SENSIBLE_ID_LEN = 36; // genesis txid
    // proto.PROTO_VERSION_LEN
    // proto.PROTO_TYPE_LEN
    // proto.PROTO_FLAG_LEN
    const GENESISTX_ID_OFFSET = SENSIBLE_ID_LEN + proto.getHeaderLen();
    const GENESIS_HASH_OFFSET = GENESISTX_ID_OFFSET + GENESIS_HASH_LEN;
    const TOKEN_AMOUNT_OFFSET = GENESIS_HASH_OFFSET + TOKEN_AMOUNT_LEN;
    const TOKEN_ADDRESS_OFFSET = TOKEN_AMOUNT_OFFSET + TOKEN_ADDRESS_LEN;
    const DECIMAL_NUM_OFFSET = TOKEN_ADDRESS_OFFSET + DECIMAL_NUM_LEN;
    const TOKEN_SYMBOL_OFFSET = DECIMAL_NUM_OFFSET + TOKEN_SYMBOL_LEN;
    const TOKEN_NAME_OFFSET = TOKEN_SYMBOL_OFFSET + TOKEN_NAME_LEN;
    const OP_PUSH_LEN = 2;
    const TOKEN_HEADER_LEN = TOKEN_NAME_OFFSET;
    const DATA_LEN = TOKEN_HEADER_LEN + OP_PUSH_LEN;
    exports.OP_TRANSFER = 1;
    exports.OP_UNLOCK_FROM_CONTRACT = 2;
    var FT_OP_TYPE;
    (function (FT_OP_TYPE) {
        FT_OP_TYPE[FT_OP_TYPE["TRANSFER"] = 1] = "TRANSFER";
        FT_OP_TYPE[FT_OP_TYPE["UNLOCK_FROM_CONTRACT"] = 2] = "UNLOCK_FROM_CONTRACT";
    })(FT_OP_TYPE = exports.FT_OP_TYPE || (exports.FT_OP_TYPE = {}));
    var GENESIS_FLAG;
    (function (GENESIS_FLAG) {
        GENESIS_FLAG[GENESIS_FLAG["FALSE"] = 0] = "FALSE";
        GENESIS_FLAG[GENESIS_FLAG["TRUE"] = 1] = "TRUE";
    })(GENESIS_FLAG = exports.GENESIS_FLAG || (exports.GENESIS_FLAG = {}));
    function getHeaderLen() {
        return TOKEN_HEADER_LEN;
    }
    exports.getHeaderLen = getHeaderLen;
    function getTokenAmount(script) {
        if (script.length < TOKEN_AMOUNT_OFFSET)
            return BN.Zero;
        return BN.fromBuffer(script.slice(script.length - TOKEN_AMOUNT_OFFSET, script.length - TOKEN_AMOUNT_OFFSET + TOKEN_AMOUNT_LEN), { endian: 'little' });
    }
    exports.getTokenAmount = getTokenAmount;
    function getTokenID(script) {
        return mvc.crypto.Hash.sha256ripemd160(script.slice(script.length - GENESIS_HASH_OFFSET, script.length - proto.getHeaderLen()));
    }
    exports.getTokenID = getTokenID;
    function getSensibleID(script0) {
        if (script0.length < GENESISTX_ID_OFFSET)
            return { txid: '', index: 0 };
        let script = Buffer.from(script0);
        let sensibleIDBuf = script.slice(script.length - GENESISTX_ID_OFFSET, script.length - GENESISTX_ID_OFFSET + SENSIBLE_ID_LEN);
        let txid = sensibleIDBuf.slice(0, 32).reverse().toString('hex'); //reverse会改变原对象
        let index = sensibleIDBuf.readUIntLE(32, 4);
        let sensibleID = { txid, index };
        return sensibleID;
    }
    exports.getSensibleID = getSensibleID;
    function getGenesisHash(script) {
        return script
            .slice(script.length - GENESIS_HASH_OFFSET, 
        // script.length - GENESIS_HASH_OFFSET + GENESISTX_ID_OFFSET
        script.length - GENESIS_HASH_OFFSET + GENESIS_HASH_LEN)
            .toString('hex');
    }
    exports.getGenesisHash = getGenesisHash;
    function getTokenAddress(script) {
        if (script.length < TOKEN_ADDRESS_OFFSET)
            return '';
        return script
            .slice(script.length - TOKEN_ADDRESS_OFFSET, script.length - TOKEN_ADDRESS_OFFSET + TOKEN_ADDRESS_LEN)
            .toString('hex');
    }
    exports.getTokenAddress = getTokenAddress;
    function getDecimalNum(script) {
        if (script.length < DECIMAL_NUM_OFFSET)
            return 0;
        return script.readUIntLE(script.length - DECIMAL_NUM_OFFSET, DECIMAL_NUM_LEN);
    }
    exports.getDecimalNum = getDecimalNum;
    function getTokenSymbol(script) {
        if (script.length < TOKEN_SYMBOL_OFFSET)
            return '';
        let buf = script.slice(script.length - TOKEN_SYMBOL_OFFSET, script.length - TOKEN_SYMBOL_OFFSET + TOKEN_SYMBOL_LEN);
        return buf.toString();
    }
    exports.getTokenSymbol = getTokenSymbol;
    function getTokenName(script) {
        if (script.length < TOKEN_NAME_OFFSET)
            return '';
        let buf = script.slice(script.length - TOKEN_NAME_OFFSET, script.length - TOKEN_NAME_OFFSET + TOKEN_NAME_LEN);
        return buf.toString();
    }
    exports.getTokenName = getTokenName;
    function getContractCode(script) {
        return script.slice(0, script.length - DATA_LEN);
    }
    exports.getContractCode = getContractCode;
    function getContractCodeHash(script) {
        return mvc.crypto.Hash.sha256ripemd160(getContractCode(script));
    }
    exports.getContractCodeHash = getContractCodeHash;
    function getDataPart(script) {
        return script.slice(script.length - TOKEN_HEADER_LEN, script.length);
    }
    exports.getDataPart = getDataPart;
    function getNewTokenScript(scriptBuf, address, tokenAmount) {
        const amountBuf = tokenAmount.toBuffer({ endian: 'little', size: 8 });
        const firstBuf = scriptBuf.slice(0, scriptBuf.length - TOKEN_ADDRESS_OFFSET);
        const newScript = Buffer.concat([
            firstBuf,
            address,
            amountBuf,
            scriptBuf.slice(scriptBuf.length - GENESIS_HASH_OFFSET, scriptBuf.length),
        ]);
        return newScript;
    }
    exports.getNewTokenScript = getNewTokenScript;
    const getTxIdBuf = function (txid) {
        const buf = Buffer.from(txid, 'hex').reverse();
        return buf;
    };
    exports.getTxIdBuf = getTxIdBuf;
    const getUInt32Buf = function (index) {
        const buf = Buffer.alloc(4, 0);
        buf.writeUInt32LE(index);
        return buf;
    };
    exports.getUInt32Buf = getUInt32Buf;
    const genGenesisTxid = function (txid, index) {
        return Buffer.concat([(0, exports.getTxIdBuf)(txid), (0, exports.getUInt32Buf)(index)]).toString('hex');
    };
    exports.genGenesisTxid = genGenesisTxid;
    function newDataPart({ tokenName, tokenSymbol, decimalNum, tokenAddress, tokenAmount, genesisHash, sensibleID, protoVersion, protoType, }) {
        const tokenNameBuf = Buffer.alloc(TOKEN_NAME_LEN, 0);
        if (tokenName) {
            tokenNameBuf.write(tokenName);
        }
        const tokenSymbolBuf = Buffer.alloc(TOKEN_SYMBOL_LEN, 0);
        if (tokenSymbol) {
            tokenSymbolBuf.write(tokenSymbol);
        }
        const decimalBuf = Buffer.alloc(DECIMAL_NUM_LEN, 0);
        if (decimalNum) {
            decimalBuf.writeUInt8(decimalNum);
        }
        let tokenAmountBuf = Buffer.alloc(TOKEN_AMOUNT_LEN, 0);
        if (tokenAmount) {
            tokenAmountBuf = tokenAmount
                .toBuffer({ endian: 'little', size: TOKEN_AMOUNT_LEN })
                .slice(0, TOKEN_AMOUNT_LEN);
        }
        const genesisHashBuf = Buffer.alloc(GENESIS_HASH_LEN, 0);
        if (genesisHash) {
            genesisHashBuf.write(genesisHash, 'hex');
        }
        // TODO 同样是36位,只是换了个名字叫 genesis txid
        let sensibleIDBuf = Buffer.alloc(SENSIBLE_ID_LEN, 0);
        if (sensibleID) {
            const txidBuf = Buffer.from(sensibleID.txid, 'hex').reverse();
            const indexBuf = Buffer.alloc(4, 0);
            indexBuf.writeUInt32LE(sensibleID.index);
            sensibleIDBuf = Buffer.concat([txidBuf, indexBuf]);
        }
        const protoTypeBuf = Buffer.alloc(proto.PROTO_TYPE_LEN, 0);
        if (protoType) {
            protoTypeBuf.writeUInt32LE(protoType);
        }
        const protoVersionBuf = Buffer.alloc(proto.PROTO_VERSION_LEN);
        if (protoVersion) {
            protoVersionBuf.writeUInt32LE(protoVersion);
        }
        let tokenAddressBuf = Buffer.alloc(TOKEN_ADDRESS_LEN, 0);
        if (tokenAddress) {
            tokenAddressBuf = Buffer.from(tokenAddress, 'hex');
        }
        const buf = Buffer.concat([
            // 新版结构变化
            tokenNameBuf,
            tokenSymbolBuf,
            decimalBuf,
            tokenAddressBuf,
            tokenAmountBuf,
            genesisHashBuf,
            sensibleIDBuf,
            protoVersionBuf,
            protoTypeBuf,
            proto.PROTO_FLAG,
            // 旧版做法
            // tokenNameBuf,
            // tokenSymbolBuf,
            // genesisFlagBuf,
            // decimalBuf,
            // tokenAddressBuf,
            // tokenAmountBuf,
            // genesisHashBuf,
            // rabinPubKeyHashArrayHashBuf,
            // sensibleIDBuf,
            // protoVersionBuf,
            // protoTypeBuf,
            // proto.PROTO_FLAG,
        ]);
        return (0, tokenUtil_1.buildScriptData)(buf);
    }
    exports.newDataPart = newDataPart;
    function parseDataPart(scriptBuf) {
        let tokenName = getTokenName(scriptBuf);
        let tokenSymbol = getTokenSymbol(scriptBuf);
        let decimalNum = getDecimalNum(scriptBuf);
        let tokenAddress = getTokenAddress(scriptBuf);
        let tokenAmount = getTokenAmount(scriptBuf);
        let genesisHash = getGenesisHash(scriptBuf);
        let sensibleID = getSensibleID(scriptBuf);
        let protoVersion = proto.getProtoVersion(scriptBuf);
        let protoType = proto.getProtoType(scriptBuf);
        return {
            tokenName,
            tokenSymbol,
            decimalNum,
            tokenAddress,
            tokenAmount,
            genesisHash,
            sensibleID,
            protoVersion,
            protoType,
        };
    }
    exports.parseDataPart = parseDataPart;
    function updateScript(scriptBuf, dataPartObj) {
        const firstBuf = scriptBuf.slice(0, scriptBuf.length - TOKEN_HEADER_LEN);
        const dataPart = newDataPart(dataPartObj);
        return Buffer.concat([firstBuf, dataPart]);
    }
    exports.updateScript = updateScript;
    function getQueryCodehash(script) {
        return (0, scryptlib_1.toHex)(getContractCodeHash(script));
    }
    exports.getQueryCodehash = getQueryCodehash;
    function getQueryGenesis(script) {
        return (0, scryptlib_1.toHex)(getTokenID(script));
    }
    exports.getQueryGenesis = getQueryGenesis;
    function getQuerySensibleID(script0) {
        let script = Buffer.from(script0);
        let sensibleIDBuf = script.slice(script.length - GENESISTX_ID_OFFSET, script.length - GENESISTX_ID_OFFSET + SENSIBLE_ID_LEN);
        return (0, scryptlib_1.toHex)(sensibleIDBuf);
    }
    exports.getQuerySensibleID = getQuerySensibleID;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../bn.js":381,"../../common/protoheader":389,"../../common/tokenUtil":390,"../../mvc":440,"../../scryptlib":445,"buffer":84}],436:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.newDataPart = void 0;
    const TokenUtil = require("../../common/tokenUtil");
    const NFT_ID_LEN = 20;
    const NFT_CODE_HASH_LEN = 20;
    const DATA_VERSION_LEN = 5;
    const NFT_ID_OFFSET = DATA_VERSION_LEN + NFT_ID_LEN;
    const NFT_CODE_HASH_OFFSET = NFT_ID_OFFSET + NFT_CODE_HASH_LEN;
    function newDataPart(dataPart) {
        let nSendersBuf = TokenUtil.getUInt32Buf(dataPart.nSenders);
        let receiverTokenAmountArrayBuf = Buffer.alloc(0);
        dataPart.receiverTokenAmountArray.forEach((tokenAmount) => {
            receiverTokenAmountArrayBuf = Buffer.concat([
                receiverTokenAmountArrayBuf,
                tokenAmount.toBuffer({ endian: 'little', size: 8 }),
            ]);
        });
        let receiverArrayBuf = Buffer.alloc(0);
        dataPart.receiverArray.map((address) => {
            receiverArrayBuf = Buffer.concat([receiverArrayBuf, address.hashBuffer]);
        });
        let nReceiversBuf = TokenUtil.getUInt32Buf(dataPart.nReceivers);
        let tokenCodeHashBuf = Buffer.from(dataPart.tokenCodeHash, 'hex');
        let tokenIDBuf = Buffer.from(dataPart.tokenID, 'hex');
        const buf = Buffer.concat([
            nSendersBuf,
            receiverTokenAmountArrayBuf,
            receiverArrayBuf,
            nReceiversBuf,
            tokenCodeHashBuf,
            tokenIDBuf,
        ]);
        return TokenUtil.buildScriptData(buf);
    }
    exports.newDataPart = newDataPart;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../common/tokenUtil":390,"buffer":84}],437:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.newDataPart = void 0;
    const TokenUtil = require("../../common/tokenUtil");
    const NFT_ID_LEN = 36;
    const NFT_CODE_HASH_LEN = 20;
    const NFT_ID_OFFSET = 0 + NFT_ID_LEN;
    const NFT_CODE_HASH_OFFSET = NFT_ID_OFFSET + NFT_CODE_HASH_LEN;
    function newDataPart(dataPart) {
        let inputTokenIndexArrayBuf = Buffer.alloc(0);
        dataPart.inputTokenIndexArray.forEach((tokenIndex) => {
            inputTokenIndexArrayBuf = Buffer.concat([
                inputTokenIndexArrayBuf,
                TokenUtil.getUInt32Buf(tokenIndex),
            ]);
        });
        let receiverArrayBuf = Buffer.alloc(0);
        dataPart.receiverArray.map((address) => {
            receiverArrayBuf = Buffer.concat([receiverArrayBuf, address.hashBuffer]);
        });
        let nSenderBuf = TokenUtil.getUInt32Buf(dataPart.nSender);
        let nReceiversBuf = TokenUtil.getUInt32Buf(dataPart.nReceivers);
        let tokenCodeHashBuf = Buffer.from(dataPart.tokenCodeHash, 'hex');
        let tokenIDBuf = Buffer.from(dataPart.tokenID, 'hex');
        const buf = Buffer.concat([
            inputTokenIndexArrayBuf,
            nSenderBuf,
            receiverArrayBuf,
            nReceiversBuf,
            tokenCodeHashBuf,
            tokenIDBuf,
        ]);
        return TokenUtil.buildScriptData(buf);
    }
    exports.newDataPart = newDataPart;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../../common/tokenUtil":390,"buffer":84}],438:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ContractUtil = void 0;
    const mvc_scrypt_1 = require("mvc-scrypt");
    const token_1 = require("./contract-factory/token");
    const tokenGenesis_1 = require("./contract-factory/tokenGenesis");
    const tokenTransferCheck_1 = require("./contract-factory/tokenTransferCheck");
    const tokenUnlockContractCheck_1 = require("./contract-factory/tokenUnlockContractCheck");
    // import BN = require('../bn.js')
    function getTokenTransferCheckCodeHashArray() {
        let contractArray = [
            tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.IN_3_OUT_3),
            tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.IN_6_OUT_6),
            tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.IN_10_OUT_10),
            tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.IN_20_OUT_3),
            tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.IN_3_OUT_100),
        ];
        return contractArray.map((v) => v.getCodeHash());
    }
    function getTokenUnlockContractCheckCodeHashArray() {
        let contractArray = [
            tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.IN_2_OUT_5),
            tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.IN_4_OUT_8),
            tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.IN_8_OUT_12),
            tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.IN_20_OUT_5),
            tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.IN_3_OUT_100),
        ];
        return contractArray.map((v) => v.getCodeHash());
    }
    class ContractUtil {
        static init(config) {
            if (config) {
                this.transferCheckCodeHashArray = config.transferCheckCodeHashArray.map((v) => new mvc_scrypt_1.Bytes(v));
                this.unlockContractCodeHashArray = config.unlockContractCodeHashArray.map((v) => new mvc_scrypt_1.Bytes(v));
                tokenGenesis_1.TokenGenesisFactory.lockingScriptSize = config.tokenGenesisSize;
                token_1.TokenFactory.lockingScriptSize = config.tokenSize;
                tokenTransferCheck_1.TokenTransferCheckFactory.tokenTransferTypeInfos.forEach((v, idx) => {
                    v.lockingScriptSize = config.tokenTransferCheckSizes[idx];
                });
            }
            else {
                this.transferCheckCodeHashArray = getTokenTransferCheckCodeHashArray().map((v) => new mvc_scrypt_1.Bytes(v));
                this.unlockContractCodeHashArray = getTokenUnlockContractCheckCodeHashArray().map((v) => new mvc_scrypt_1.Bytes(v));
                tokenGenesis_1.TokenGenesisFactory.lockingScriptSize = tokenGenesis_1.TokenGenesisFactory.calLockingScriptSize();
                token_1.TokenFactory.lockingScriptSize = token_1.TokenFactory.calLockingScriptSize();
                tokenTransferCheck_1.TokenTransferCheckFactory.tokenTransferTypeInfos.forEach((v, idx) => {
                    v.lockingScriptSize = tokenTransferCheck_1.TokenTransferCheckFactory.calLockingScriptSize(v.type);
                });
            }
            let tokenContract = token_1.TokenFactory.getDummyInstance();
            tokenContract.setDataPart('');
            let scriptBuf = tokenContract.lockingScript.toBuffer();
            let genesisContract = tokenGenesis_1.TokenGenesisFactory.getDummyInstance();
            genesisContract.setDataPart('');
            this.tokenGenesisCodeHash = genesisContract.getCodeHash();
            // this.tokenCodeHash = toHex(mvc.crypto.Hash.sha256ripemd160(scriptBuf))
            this.tokenCodeHash = tokenContract.getCodeHash();
        }
    }
    exports.ContractUtil = ContractUtil;
    
    },{"./contract-factory/token":431,"./contract-factory/tokenGenesis":432,"./contract-factory/tokenTransferCheck":433,"./contract-factory/tokenUnlockContractCheck":434,"mvc-scrypt":282}],439:[function(require,module,exports){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.FtManager = exports.sighashType = void 0;
    const scryptlib_1 = require("../scryptlib");
    const error_1 = require("../common/error");
    const mvc = require("../mvc");
    const __1 = require("..");
    const constants_1 = require("./constants");
    const BN = require("../bn.js");
    const TokenUtil = require("../common/tokenUtil");
    const tokenUtil_1 = require("../common/tokenUtil");
    const $ = require("../common/argumentCheck");
    const Prevouts_1 = require("../common/Prevouts");
    const tx_composer_1 = require("../tx-composer");
    const token_1 = require("./contract-factory/token");
    const contractUtil_1 = require("./contractUtil");
    const utils_1 = require("../common/utils");
    const tokenGenesis_1 = require("./contract-factory/tokenGenesis");
    const tokenTransferCheck_1 = require("./contract-factory/tokenTransferCheck");
    const ftProto = require("./contract-proto/token.proto");
    const DustCalculator_1 = require("../common/DustCalculator");
    const SizeTransaction_1 = require("../common/SizeTransaction");
    const transactionHelpers_1 = require("../helpers/transactionHelpers");
    const contractHelpers_1 = require("../helpers/contractHelpers");
    const dummy_1 = require("../common/dummy");
    const protoheader_1 = require("../common/protoheader");
    const tokenUnlockContractCheck_1 = require("../mcp02/contract-factory/tokenUnlockContractCheck");
    const buffer_1 = require("buffer");
    const jsonDescr = require('./contract-desc/txUtil_desc.json');
    const { TxInputProof, TxOutputProof } = (0, scryptlib_1.buildTypeClasses)(jsonDescr);
    const Signature = mvc.crypto.Signature;
    const _ = mvc.deps._;
    exports.sighashType = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID;
    contractUtil_1.ContractUtil.init();
    function checkParamGenesis(genesis) {
        $.checkArgument(_.isString(genesis), 'Invalid Argument: genesis should be a string');
        $.checkArgument(genesis.length == 40, `Invalid Argument: genesis.length must be 40`);
    }
    function checkParamCodehash(codehash) {
        $.checkArgument(_.isString(codehash), 'Invalid Argument: codehash should be a string');
        $.checkArgument(codehash.length == 40, `Invalid Argument: codehash.length must be 40`);
        $.checkArgument(codehash == contractUtil_1.ContractUtil.tokenCodeHash ||
            codehash == contractUtil_1.ContractUtil.tokenGenesisCodeHash ||
            codehash === '57344f46cc0d0c8dfea7af3300b1b3a0f4216c04' ||
            codehash === 'a2421f1e90c6048c36745edd44fad682e8644693' ||
            codehash === 'e205939ad9956673ce7da9fbd40514b30f66dc35' ||
            codehash === 'c9cc7bbd1010b44873959a8b1a2bcedeb62302b7', `a valid codehash should be ${contractUtil_1.ContractUtil.tokenCodeHash}, but the provided is ${codehash} `);
    }
    function determineCodehashVersion(codehash) {
        if (codehash == contractUtil_1.ContractUtil.tokenCodeHash) {
            return 2;
        }
        return 1;
    }
    function checkParamReceivers(receivers) {
        const ErrorName = 'ReceiversFormatError';
        if ((0, utils_1.isNull)(receivers)) {
            throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, `${ErrorName}: param should not be null`);
        }
        if (receivers.length > 0) {
            let receiver = receivers[0];
            if ((0, utils_1.isNull)(receiver.address) || (0, utils_1.isNull)(receiver.amount)) {
                throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, `${ErrorName}-valid format example
          [
            {
              address: "mtjjuRuA84b2qVyo28AyJQ8AoUmpbWEqs3",
              amount: "1000",
            },
          ]
          `);
            }
            let amount = new BN(receiver.amount.toString());
            if (amount.lten(0)) {
                throw `receiver amount must greater than 0 but now is ${receiver.amount}`;
            }
        }
    }
    function parseSensibleID(sensibleID) {
        let sensibleIDBuf = buffer_1.Buffer.from(sensibleID, 'hex');
        let genesisTxId = sensibleIDBuf.slice(0, 32).reverse().toString('hex');
        let genesisOutputIndex = sensibleIDBuf.readUIntLE(32, 4);
        return {
            genesisTxId,
            genesisOutputIndex,
        };
    }
    class FtManager {
        get api() {
            return this._api;
        }
        get sensibleApi() {
            return this._api;
        }
        constructor({ network = __1.API_NET.MAIN, apiTarget = __1.API_TARGET.CYBER3, purse, feeb = constants_1.FEEB, apiHost, dustLimitFactor = 300, dustAmount, debug = false, }) {
            // 初始化API
            this.network = network;
            this._api = new __1.Api(network, apiTarget, apiHost);
            // 初始化钱包
            if (purse) {
                const privateKey = mvc.PrivateKey.fromWIF(purse);
                const address = privateKey.toAddress(network);
                this.purse = {
                    privateKey,
                    address,
                };
            }
            // 初始化零地址
            this.zeroAddress = new mvc.Address(constants_1.BURN_ADDRESS, network);
            this.dustCalculator = new DustCalculator_1.DustCalculator(dustLimitFactor, dustAmount);
            this.transferCheckCodeHashArray = contractUtil_1.ContractUtil.transferCheckCodeHashArray;
            this.unlockContractCodeHashArray = contractUtil_1.ContractUtil.unlockContractCodeHashArray;
            // 初始化费率
            this.feeb = feeb;
            this.debug = debug;
        }
        /**
         * Create a transaction for genesis
         * @param tokenName token name, limited to 20 bytes
         * @param tokenSymbol the token symbol, limited to 10 bytes
         * @param decimalNum the decimal number, range 0-255
         * @param utxos (Optional) specify mvc utxos
         * @param changeAddress (Optional) specify mvc changeAddress
         * @param opreturnData (Optional) append an opReturn output
         * @param genesisWif the private key of the token genesiser
         * @param noBroadcast (Optional) whether not to broadcast the transaction, the default is false
         * @returns
         */
        genesis({ version = 2, tokenName, tokenSymbol, decimalNum, utxos: utxosInput, changeAddress, opreturnData, genesisWif, noBroadcast = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                // validate params
                $.checkArgument(_.isString(tokenName) && buffer_1.Buffer.from(tokenName).length <= 40, `tokenName should be a string and not be larger than 40 bytes`);
                $.checkArgument(_.isString(tokenSymbol) && buffer_1.Buffer.from(tokenSymbol).length <= 10, 'tokenSymbol should be a string and not be larger than 10 bytes');
                $.checkArgument(_.isNumber(decimalNum) && decimalNum >= 0 && decimalNum <= 255, 'decimalNum should be a number and must be between 0 and 255');
                $.checkArgument(_.isNumber(version) && version >= 1 && version <= 2, 'version should be a number and must be between 1 and 2');
                const utxoInfo = yield (0, transactionHelpers_1.prepareUtxos)(this.purse, this.api, this.network, utxosInput);
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxoInfo.utxos[0].address;
                }
                const tokenAddress = genesisWif
                    ? mvc.PrivateKey.fromWIF(genesisWif).toAddress(this.network)
                    : this.purse.address;
                let { txComposer } = yield this._genesis({
                    tokenName,
                    tokenSymbol,
                    decimalNum,
                    utxos: utxoInfo.utxos,
                    utxoPrivateKeys: utxoInfo.utxoPrivateKeys,
                    changeAddress: changeAddress,
                    tokenAddress: tokenAddress.hashBuffer.toString('hex'),
                    opreturnData,
                });
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(txHex);
                }
                let { codehash, genesis, sensibleId } = (0, contractHelpers_1.getGenesisIdentifiers)({
                    version,
                    genesisTx: txComposer.getTx(),
                    purse: { address: tokenAddress, privateKey: this.purse.privateKey },
                    transferCheckCodeHashArray: this.transferCheckCodeHashArray,
                    unlockContractCodeHashArray: this.unlockContractCodeHashArray,
                    type: 'ft',
                });
                return {
                    txHex,
                    txid: txComposer.getTxId(),
                    tx: txComposer.getTx(),
                    codehash,
                    genesis,
                    sensibleId,
                };
            });
        }
        issue(options) {
            return __awaiter(this, void 0, void 0, function* () {
                return this.mint(options);
            });
        }
        mint({ version = 2, sensibleId, genesisWif, receiverAddress, tokenAmount, allowIncreaseMints = true, utxos, changeAddress, opreturnData, noBroadcast = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                $.checkArgument(sensibleId, 'sensibleId is required');
                $.checkArgument(genesisWif, 'genesisWif is required');
                $.checkArgument(receiverAddress, 'receiverAddress is required');
                $.checkArgument(tokenAmount, 'tokenAmount is required');
                const utxoInfo = yield this._pretreatUtxos(utxos);
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxoInfo.utxos[0].address;
                }
                let genesisPrivateKey = new mvc.PrivateKey(genesisWif);
                let genesisPublicKey = genesisPrivateKey.toPublicKey();
                receiverAddress = new mvc.Address(receiverAddress, this.network);
                tokenAmount = new BN(tokenAmount.toString());
                let { txComposer } = yield this._mint({
                    version,
                    sensibleId,
                    receiverAddress,
                    tokenAmount,
                    allowIncreaseMints,
                    utxos: utxoInfo.utxos,
                    utxoPrivateKeys: utxoInfo.utxoPrivateKeys,
                    changeAddress,
                    opreturnData,
                    genesisPrivateKey,
                    genesisPublicKey,
                });
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(txHex);
                }
                return { txHex, txid: txComposer.getTxId(), tx: txComposer.getTx() };
            });
        }
        _mint({ version, sensibleId, receiverAddress, tokenAmount, allowIncreaseMints = true, utxos, utxoPrivateKeys, changeAddress, opreturnData, genesisPrivateKey, genesisPublicKey, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const genesisAddress = genesisPrivateKey.toAddress(this.network).toString();
                let { genesisContract, genesisTxId, genesisOutputIndex, genesisUtxo } = yield this._prepareMintUtxo({
                    sensibleId,
                    genesisAddress,
                });
                let balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                let estimateSatoshis = yield this._calMintEstimateFee({
                    genesisUtxoSatoshis: genesisUtxo.satoshis,
                    opreturnData,
                    allowIncreaseMints,
                    utxoMaxCount: utxos.length,
                });
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                let newGenesisContract = genesisContract.clone();
                newGenesisContract.setFormatedDataPart({
                    sensibleID: {
                        txid: genesisTxId,
                        index: genesisOutputIndex,
                    },
                });
                let tokenContract = token_1.TokenFactory.createContract(this.transferCheckCodeHashArray, this.unlockContractCodeHashArray, version);
                tokenContract.setFormatedDataPart(Object.assign({}, newGenesisContract.getFormatedDataPart(), {
                    tokenAddress: (0, scryptlib_1.toHex)(receiverAddress.hashBuffer),
                    tokenAmount,
                    genesisHash: newGenesisContract.getScriptHash(),
                }));
                const txComposer = new tx_composer_1.TxComposer();
                const genesisInputIndex = (0, transactionHelpers_1.addContractInput)(txComposer, genesisUtxo, genesisPublicKey.toAddress(this.network).toString(), utils_1.CONTRACT_TYPE.BCP02_TOKEN_GENESIS);
                const p2pkhInputIndexs = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                //If increase issues is allowed, add a new issue contract as the first output
                let newGenesisOutputIndex = -1;
                if (allowIncreaseMints) {
                    newGenesisOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                        txComposer,
                        contract: newGenesisContract,
                        dustCalculator: this.dustCalculator,
                    });
                }
                const tokenOutputIndex = (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    contract: tokenContract,
                    dustCalculator: this.dustCalculator,
                });
                //If there is opReturn, add it to the output
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = (0, transactionHelpers_1.addOpreturnOutput)(txComposer, opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                const prevInputIndex = 0; // TODO: 0?
                const genesisTx = genesisUtxo.satotxInfo.tx;
                const inputRes = TokenUtil.getTxInputProof(genesisTx, prevInputIndex);
                const genesisTxInputProof = new TxInputProof(inputRes[0]);
                const genesisTxHeader = inputRes[1]; // TODO:
                // Find a valid preGenesisTx
                const genesisTxInput = genesisTx.inputs[prevInputIndex];
                const preGenesisOutputIndex = genesisTxInput.outputIndex;
                const preGenesisTxId = genesisTxInput.prevTxId.toString('hex');
                const preGenesisTxHex = yield this.api.getRawTxData(preGenesisTxId);
                const preGenesisTx = new mvc.Transaction(preGenesisTxHex);
                const prevOutputProof = TokenUtil.getTxOutputProof(preGenesisTx, preGenesisOutputIndex);
                const pubKey = new scryptlib_1.PubKey(genesisPublicKey.toHex());
                //The first round of calculations get the exact size of the final transaction, and then change again
                //Due to the change, the script needs to be unlocked again in the second round
                //let the fee to be exact in the second round
                for (let c = 0; c < 2; c++) {
                    // TODO: 取消两轮？
                    txComposer.clearChangeOutput();
                    const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb);
                    let unlockResult = genesisContract.unlock({
                        txPreimage: txComposer.getInputPreimage(genesisInputIndex),
                        pubKey,
                        sig: new scryptlib_1.Sig(genesisPrivateKey
                            ? (0, scryptlib_1.toHex)(txComposer.getTxFormatSig(genesisPrivateKey, genesisInputIndex))
                            : utils_1.PLACE_HOLDER_SIG),
                        tokenScript: new scryptlib_1.Bytes(txComposer.getOutput(tokenOutputIndex).script.toHex()),
                        // GenesisTx Input Proof
                        genesisTxHeader,
                        prevInputIndex,
                        genesisTxInputProof,
                        // Prev GenesisTx Output Proof
                        prevGenesisTxHeader: prevOutputProof.txHeader,
                        prevTxOutputHashProof: prevOutputProof.hashProof,
                        prevTxOutputSatoshiBytes: prevOutputProof.satoshiBytes,
                        genesisSatoshis: newGenesisOutputIndex != -1 ? txComposer.getOutput(newGenesisOutputIndex).satoshis : 0,
                        tokenSatoshis: txComposer.getOutput(tokenOutputIndex).satoshis,
                        changeSatoshis: changeOutputIndex != -1 ? txComposer.getOutput(changeOutputIndex).satoshis : 0,
                        changeAddress: new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(changeAddress.hashBuffer)),
                        opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
                    });
                    // const txContext = {
                    //   tx: txComposer.getTx(),
                    //   inputIndex: 0,
                    //   inputSatoshis: txComposer.getOutput(newGenesisOutputIndex).satoshis,
                    // }
                    // const verify = unlockResult.verify(txContext)
                    // console.log({ verify })
                    if (this.debug && genesisPrivateKey && c == 1) {
                        let ret = unlockResult.verify({
                            tx: txComposer.tx,
                            inputIndex: genesisInputIndex,
                            inputSatoshis: txComposer.getInput(genesisInputIndex).output.satoshis,
                        });
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(genesisInputIndex).setScript(unlockResult.toScript());
                }
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexs, utxoPrivateKeys);
                // if (utxoPrivateKeys && utxoPrivateKeys.length > 0) {
                //   p2pkhInputIndexs.forEach((inputIndex) => {
                //     let privateKey = utxoPrivateKeys.splice(0, 1)[0]
                //     txComposer.unlockP2PKHInput(privateKey, inputIndex)
                //   })
                // }
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { txComposer };
            });
        }
        _prepareMintUtxo({ sensibleId, genesisAddress, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let genesisContract = tokenGenesis_1.TokenGenesisFactory.createContract();
                //Looking for UTXO for issue
                let { genesisTxId, genesisOutputIndex } = parseSensibleID(sensibleId);
                let genesisUtxo = yield this._getMintUtxo(genesisContract.getCodeHash(), genesisTxId, genesisOutputIndex, genesisAddress);
                if (!genesisUtxo) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_FIXED_TOKEN_SUPPLY, 'token supply is fixed');
                }
                let txHex = yield this.api.getRawTxData(genesisUtxo.txId);
                const tx = new mvc.Transaction(txHex);
                let preTxId = tx.inputs[0].prevTxId.toString('hex');
                let preOutputIndex = tx.inputs[0].outputIndex;
                let preTxHex = yield this.api.getRawTxData(preTxId);
                genesisUtxo.satotxInfo = {
                    txId: genesisUtxo.txId,
                    outputIndex: genesisUtxo.outputIndex,
                    txHex,
                    preTxId,
                    preOutputIndex,
                    preTxHex,
                    tx,
                };
                let output = tx.outputs[genesisUtxo.outputIndex];
                genesisUtxo.satoshis = output.satoshis;
                genesisUtxo.lockingScript = output.script;
                genesisContract.setFormatedDataPartFromLockingScript(genesisUtxo.lockingScript);
                return {
                    genesisContract,
                    genesisTxId,
                    genesisOutputIndex,
                    genesisUtxo,
                };
            });
        }
        _getMintUtxo(codehash, genesisTxId, genesisOutputIndex, genesisAddress) {
            return __awaiter(this, void 0, void 0, function* () {
                let unspent;
                let firstGenesisTxHex = yield this.api.getRawTxData(genesisTxId);
                let firstGenesisTx = new mvc.Transaction(firstGenesisTxHex);
                let scriptBuffer = firstGenesisTx.outputs[genesisOutputIndex].script.toBuffer();
                let originGenesis = ftProto.getQueryGenesis(scriptBuffer);
                let genesisUtxos = yield this.api.getFungibleTokenUnspents(codehash, originGenesis, genesisAddress);
                unspent = genesisUtxos.find((v) => v.txId == genesisTxId && v.outputIndex == genesisOutputIndex);
                if (!unspent) {
                    let _dataPartObj = ftProto.parseDataPart(scriptBuffer);
                    _dataPartObj.sensibleID = {
                        txid: genesisTxId,
                        index: genesisOutputIndex,
                    };
                    let newScriptBuf = ftProto.updateScript(scriptBuffer, _dataPartObj);
                    let issueGenesis = ftProto.getQueryGenesis(newScriptBuf);
                    let issueUtxos = yield this.api.getFungibleTokenUnspents(codehash, issueGenesis, genesisAddress);
                    if (issueUtxos.length > 0) {
                        unspent = issueUtxos[0];
                    }
                }
                if (unspent) {
                    return {
                        txId: unspent.txId,
                        outputIndex: unspent.outputIndex,
                    };
                }
            });
        }
        _calMintEstimateFee({ genesisUtxoSatoshis, opreturnData, allowIncreaseMints = true, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                stx.addInput(tokenGenesis_1.TokenGenesisFactory.calUnlockingScriptSize(opreturnData), genesisUtxoSatoshis);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                if (allowIncreaseMints) {
                    stx.addOutput(tokenGenesis_1.TokenGenesisFactory.getLockingScriptSize());
                }
                stx.addOutput(token_1.TokenFactory.getLockingScriptSize());
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        merge({ codehash, genesis, ownerWif, utxos, changeAddress, noBroadcast = false, opreturnData, }) {
            return __awaiter(this, void 0, void 0, function* () {
                $.checkArgument(ownerWif, 'ownerWif is required');
                return yield this.transfer({
                    codehash,
                    genesis,
                    senderWif: ownerWif,
                    utxos,
                    changeAddress,
                    isMerge: true,
                    noBroadcast,
                    receivers: [],
                    opreturnData,
                });
            });
        }
        totalMerge({ codehash, genesis, ownerWif, changeAddress, opreturnData, }) {
            return __awaiter(this, void 0, void 0, function* () {
                $.checkArgument(ownerWif, 'ownerWif is required');
                const ownerPublicKey = mvc.PrivateKey.fromWIF(ownerWif).toPublicKey();
                const txids = [];
                while (true) {
                    const ftUtxos = yield this.api.getFungibleTokenUnspents(codehash, genesis, ownerPublicKey.toAddress(this.network).toString(), 20);
                    if (ftUtxos.length <= 1) {
                        break;
                    }
                    const paramFtUtxos = ftUtxos.map((v) => {
                        return {
                            txId: v.txId,
                            outputIndex: v.outputIndex,
                            tokenAddress: v.tokenAddress,
                            tokenAmount: v.tokenAmount,
                            wif: ownerWif,
                        };
                    });
                    const { txid } = yield this.transfer({
                        codehash,
                        genesis,
                        senderWif: ownerWif,
                        ftUtxos: paramFtUtxos,
                        changeAddress,
                        isMerge: true,
                        receivers: [],
                        opreturnData,
                    });
                    txids.push(txid);
                    // sleep 1s
                    yield new Promise((resolve) => setTimeout(resolve, 1000));
                }
                return { txids };
            });
        }
        _pretreatUtxos(paramUtxos) {
            return __awaiter(this, void 0, void 0, function* () {
                let utxoPrivateKeys = [];
                let utxos = [];
                //If utxos are not provided, use purse to fetch utxos
                if (!paramUtxos) {
                    if (!this.purse)
                        throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'Utxos or Purse must be provided.');
                    paramUtxos = yield this.api.getUnspents(this.purse.address.toString());
                    paramUtxos.forEach((v) => {
                        utxoPrivateKeys.push(this.purse.privateKey);
                    });
                }
                else {
                    paramUtxos.forEach((v) => {
                        if (v.wif) {
                            let privateKey = new mvc.PrivateKey(v.wif);
                            utxoPrivateKeys.push(privateKey);
                            v.address = privateKey.toAddress(this.network).toString(); //Compatible with the old version, only wif is provided but no address is provided
                        }
                    });
                }
                paramUtxos.forEach((v) => {
                    utxos.push({
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                        address: new mvc.Address(v.address, this.network),
                    });
                });
                if (utxos.length == 0)
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, 'Insufficient balance.');
                return { utxos, utxoPrivateKeys };
            });
        }
        /**
         * Estimate the cost of genesis
         * @param opreturnData
         * @param utxoMaxCount Maximum number of MVC UTXOs supported
         * @returns
         */
        getGenesisEstimateFee({ opreturnData, utxoMaxCount = 10, }) {
            return __awaiter(this, void 0, void 0, function* () {
                const p2pkhInputNum = utxoMaxCount;
                const sizeOfTokenGenesis = tokenGenesis_1.TokenGenesisFactory.getLockingScriptSize();
                let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
                for (let i = 0; i < p2pkhInputNum; i++) {
                    stx.addP2PKHInput();
                }
                stx.addOutput(sizeOfTokenGenesis);
                if (opreturnData) {
                    stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
                }
                stx.addP2PKHOutput();
                return stx.getFee();
            });
        }
        _genesis({ tokenName, tokenSymbol, decimalNum, utxos, utxoPrivateKeys, changeAddress, tokenAddress, opreturnData, }) {
            return __awaiter(this, void 0, void 0, function* () {
                //create genesis contract
                let genesisContract = tokenGenesis_1.TokenGenesisFactory.createContract();
                genesisContract.setFormatedDataPart({
                    tokenName,
                    tokenSymbol,
                    decimalNum,
                    tokenAddress,
                });
                let estimateSatoshis = yield this.getGenesisEstimateFee({
                    opreturnData,
                    utxoMaxCount: utxos.length,
                });
                const balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                const txComposer = new tx_composer_1.TxComposer();
                const p2pkhInputIndexs = (0, transactionHelpers_1.addP2PKHInputs)(txComposer, utxos);
                (0, transactionHelpers_1.addContractOutput)({
                    txComposer,
                    contract: genesisContract,
                    dustCalculator: this.dustCalculator,
                });
                //If there is opReturn, add it to the second output
                if (opreturnData) {
                    txComposer.appendOpReturnOutput(opreturnData);
                }
                (0, transactionHelpers_1.addChangeOutput)(txComposer, changeAddress, this.feeb);
                (0, transactionHelpers_1.unlockP2PKHInputs)(txComposer, p2pkhInputIndexs, utxoPrivateKeys);
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { txComposer };
            });
        }
        transfer({ codehash, genesis, receivers, senderWif, ftUtxos, ftChangeAddress, utxos, changeAddress, middleChangeAddress, middlePrivateKey, minUtxoSet = true, isMerge, opreturnData, noBroadcast = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                checkParamGenesis(genesis);
                checkParamCodehash(codehash);
                checkParamReceivers(receivers);
                const version = determineCodehashVersion(codehash);
                let senderPrivateKey;
                let senderPublicKey;
                if (senderWif) {
                    senderPrivateKey = new mvc.PrivateKey(senderWif);
                }
                let utxoInfo = yield this._pretreatUtxos(utxos);
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxoInfo.utxos[0].address;
                }
                if (middleChangeAddress) {
                    middleChangeAddress = new mvc.Address(middleChangeAddress, this.network);
                    middlePrivateKey = new mvc.PrivateKey(middlePrivateKey);
                }
                else {
                    middleChangeAddress = utxoInfo.utxos[0].address;
                    middlePrivateKey = utxoInfo.utxoPrivateKeys[0];
                }
                let ftUtxoInfo = yield this._pretreatFtUtxos(ftUtxos, codehash, genesis, senderPrivateKey, senderPublicKey);
                if (ftChangeAddress) {
                    ftChangeAddress = new mvc.Address(ftChangeAddress, this.network);
                }
                else {
                    ftChangeAddress = ftUtxoInfo.ftUtxos[0].tokenAddress;
                }
                let { txComposer, transferCheckTxComposer } = yield this._transfer({
                    version,
                    codehash,
                    genesis,
                    receivers,
                    ftUtxos: ftUtxoInfo.ftUtxos,
                    ftPrivateKeys: ftUtxoInfo.ftUtxoPrivateKeys,
                    ftChangeAddress,
                    utxos: utxoInfo.utxos,
                    utxoPrivateKeys: utxoInfo.utxoPrivateKeys,
                    changeAddress,
                    opreturnData,
                    isMerge,
                    middleChangeAddress,
                    middlePrivateKey,
                    minUtxoSet,
                });
                let routeCheckTxHex = transferCheckTxComposer.getRawHex();
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(routeCheckTxHex);
                    yield this.api.broadcast(txHex);
                }
                return {
                    tx: txComposer.getTx(),
                    txHex,
                    routeCheckTx: transferCheckTxComposer.getTx(),
                    routeCheckTxHex,
                    txid: txComposer.getTxId(),
                };
            });
        }
        /**
         * burn token
         * @param codehash token codehash
         * @param genesis token genesis
         * @param ftUtxos ft utxos to burn, must be sent to zero address
         * @param utxos fee provider utxos
         * @param utxoPrivateKey fee provider utxo private key
         * @param changeAddress satoshi change address
         * @param opreturnData opreturn data
         * @param noBroadcast if true, will not broadcast tx
         */
        burn({ codehash, genesis, ftUtxos, utxos, utxoPrivateKey, changeAddress, opreturnData, noBroadcast = false, }) {
            return __awaiter(this, void 0, void 0, function* () {
                checkParamGenesis(genesis);
                checkParamCodehash(codehash);
                const version = determineCodehashVersion(codehash);
                let utxoInfo = yield this._pretreatUtxos(utxos);
                if (changeAddress) {
                    changeAddress = new mvc.Address(changeAddress, this.network);
                }
                else {
                    changeAddress = utxoInfo.utxos[0].address;
                }
                let ftUtxoInfo = yield this._pretreatFtUtxos(ftUtxos, codehash, genesis);
                let { unlockCheckTxComposer, txComposer } = yield this._burn({
                    version,
                    genesis,
                    ftUtxos: ftUtxoInfo.ftUtxos,
                    utxos: utxoInfo.utxos,
                    utxoPrivateKey: utxoInfo.utxoPrivateKeys[0],
                    changeAddress,
                    opreturnData,
                });
                let routeCheckTxHex = unlockCheckTxComposer.getRawHex();
                let txHex = txComposer.getRawHex();
                if (!noBroadcast) {
                    yield this.api.broadcast(routeCheckTxHex);
                    yield this.api.broadcast(txHex);
                }
                return {
                    tx: txComposer.getTx(),
                    txHex,
                    routeCheckTx: unlockCheckTxComposer.getTx(),
                    routeCheckTxHex,
                    txid: txComposer.getTxId(),
                };
            });
        }
        _pretreatFtUtxos(paramFtUtxos, codehash, genesis, senderPrivateKey, senderPublicKey) {
            return __awaiter(this, void 0, void 0, function* () {
                let ftUtxos = [];
                let ftUtxoPrivateKeys = [];
                let publicKeys = [];
                if (!paramFtUtxos) {
                    if (senderPrivateKey) {
                        senderPublicKey = senderPrivateKey.toPublicKey();
                    }
                    if (!senderPublicKey)
                        throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'ftUtxos or senderPublicKey or senderPrivateKey must be provided.');
                    paramFtUtxos = yield this.api.getFungibleTokenUnspents(codehash, genesis, senderPublicKey.toAddress(this.network).toString(), 20);
                    paramFtUtxos.forEach((v) => {
                        if (senderPrivateKey) {
                            ftUtxoPrivateKeys.push(senderPrivateKey);
                        }
                        publicKeys.push(senderPublicKey);
                    });
                }
                else {
                    paramFtUtxos.forEach((v) => {
                        if (v.wif) {
                            let privateKey = new mvc.PrivateKey(v.wif);
                            ftUtxoPrivateKeys.push(privateKey);
                            publicKeys.push(privateKey.toPublicKey());
                        }
                    });
                }
                paramFtUtxos.forEach((v, index) => {
                    ftUtxos.push({
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        tokenAddress: new mvc.Address(v.tokenAddress, this.network),
                        tokenAmount: new BN(v.tokenAmount.toString()),
                        publicKey: publicKeys[index],
                    });
                });
                if (ftUtxos.length == 0)
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_FT, 'Insufficient token.');
                return { ftUtxos, ftUtxoPrivateKeys };
            });
        }
        /**
         * prepare transfer tokens, decide which transfer pattern to use, preprocess ft utxos(fetch previous transactions for tx building)
         * @param codehash codehash of token
         * @param genesis genesis of token
         * @param receivers token receivers, will be ignored if isMerge is true
         * @param ftUtxos input ft utxos
         * @param ftChangeAddress change address of ft
         * @param isMerge merge utxos, if true, all the token will be merged into one utxo and send to the change address
         * @param minUtxoSet if true, will use minimum utxo set as possible
         * @private
         */
        _prepareTransferTokens({ codehash, genesis, receivers, ftUtxos, ftChangeAddress, isMerge, minUtxoSet, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let mergeUtxos = [];
                let mergeTokenAmountSum = BN.Zero;
                if (isMerge) {
                    mergeUtxos = ftUtxos.slice(0, 20);
                    mergeTokenAmountSum = mergeUtxos.reduce((pre, cur) => cur.tokenAmount.add(pre), BN.Zero);
                    receivers = [
                        {
                            address: ftChangeAddress.toString(),
                            amount: mergeTokenAmountSum.toString(),
                        },
                    ];
                }
                let tokenOutputArray = receivers.map((v) => ({
                    address: new mvc.Address(v.address, this.network),
                    tokenAmount: new BN(v.amount.toString()),
                }));
                let outputTokenAmountSum = tokenOutputArray.reduce((pre, cur) => cur.tokenAmount.add(pre), BN.Zero);
                let inputTokenAmountSum = BN.Zero;
                let _ftUtxos = [];
                for (let i = 0; i < ftUtxos.length; i++) {
                    let ftUtxo = ftUtxos[i];
                    _ftUtxos.push(ftUtxo);
                    inputTokenAmountSum = ftUtxo.tokenAmount.add(inputTokenAmountSum);
                    if (minUtxoSet && inputTokenAmountSum.gte(outputTokenAmountSum)) {
                        break;
                    }
                }
                if (isMerge) {
                    _ftUtxos = mergeUtxos;
                    inputTokenAmountSum = mergeTokenAmountSum;
                    if (mergeTokenAmountSum.eq(BN.Zero)) {
                        throw new error_1.CodeError(error_1.ErrCode.EC_INNER_ERROR, 'No utxos to merge.');
                    }
                }
                //Decide whether to change the token
                let changeTokenAmount = inputTokenAmountSum.sub(outputTokenAmountSum);
                if (changeTokenAmount.gt(BN.Zero)) {
                    tokenOutputArray.push({
                        address: ftChangeAddress,
                        tokenAmount: changeTokenAmount,
                    });
                }
                if (inputTokenAmountSum.lt(outputTokenAmountSum)) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_FT, `Insufficient token. Need ${outputTokenAmountSum} But only ${inputTokenAmountSum}`);
                }
                ftUtxos = _ftUtxos;
                yield this.perfectFtUtxosInfo(ftUtxos, genesis);
                let tokenInputArray = ftUtxos;
                //Choose a transfer plan
                let inputLength = tokenInputArray.length;
                let outputLength = tokenOutputArray.length;
                let tokenTransferType = tokenTransferCheck_1.TokenTransferCheckFactory.getOptimumType(inputLength, outputLength);
                if (tokenTransferType == tokenTransferCheck_1.TOKEN_TRANSFER_TYPE.UNSUPPORT) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_TOO_MANY_FT_UTXOS, 'Too many token-utxos, should merge them to continue.');
                }
                return {
                    tokenInputArray,
                    tokenOutputArray,
                    tokenTransferType,
                };
            });
        }
        /**
         * prepare burn tokens,preprocess ft utxos(fetch previous transactions for tx building)
         * @param codehash codehash of token
         * @param genesis genesis of token
         * @param ftUtxos input ft utxos
         * @private
         */
        _prepareBurnTokens({ genesis, ftUtxos }) {
            return __awaiter(this, void 0, void 0, function* () {
                let inputTokenAmountSum = BN.Zero;
                let _ftUtxos = [];
                for (let i = 0; i < ftUtxos.length; i++) {
                    let ftUtxo = ftUtxos[i];
                    _ftUtxos.push(ftUtxo);
                    inputTokenAmountSum = ftUtxo.tokenAmount.add(inputTokenAmountSum);
                }
                ftUtxos = _ftUtxos;
                yield this.perfectFtUtxosInfo(ftUtxos, genesis);
                let tokenInputArray = ftUtxos;
                // burn tx have only one output to receive satoshi
                let tokenUnlockType = tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.getOptimumType(ftUtxos.length, 1);
                if (tokenUnlockType == tokenUnlockContractCheck_1.TOKEN_UNLOCK_TYPE.UNSUPPORT) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_TOO_MANY_FT_UTXOS, 'Too many token-utxos, should merge them to continue.');
                }
                return {
                    tokenInputArray,
                    tokenUnlockType,
                };
            });
        }
        /**
         * Fetch previous transactions for each ft utxo
         * @param ftUtxos ft utxos
         * @param genesis genesis of token
         * @private
         */
        perfectFtUtxosInfo(ftUtxos, genesis) {
            return __awaiter(this, void 0, void 0, function* () {
                //Cache txHex to prevent redundant queries
                let cachedHexs = {};
                //Get txHex
                for (let i = 0; i < ftUtxos.length; i++) {
                    let ftUtxo = ftUtxos[i];
                    if (!cachedHexs[ftUtxo.txId]) {
                        cachedHexs[ftUtxo.txId] = {
                            waitingRes: this.api.getRawTxData(ftUtxo.txId), //async request
                        };
                    }
                }
                for (let id in cachedHexs) {
                    //Wait for all async requests to complete
                    if (cachedHexs[id].waitingRes && !cachedHexs[id].hex) {
                        cachedHexs[id].hex = yield cachedHexs[id].waitingRes;
                    }
                }
                ftUtxos.forEach((v) => {
                    v.satotxInfo = v.satotxInfo || {};
                    v.satotxInfo.txHex = cachedHexs[v.txId].hex;
                    v.satotxInfo.txId = v.txId;
                    v.satotxInfo.outputIndex = v.outputIndex;
                });
                //Get preTxHex
                let curDataPartObj;
                for (let i = 0; i < ftUtxos.length; i++) {
                    let ftUtxo = ftUtxos[i];
                    const tx = new mvc.Transaction(ftUtxo.satotxInfo.txHex);
                    if (!curDataPartObj) {
                        let tokenScript = tx.outputs[ftUtxo.outputIndex].script;
                        curDataPartObj = ftProto.parseDataPart(tokenScript.toBuffer());
                    }
                    //Find a valid preTx
                    let prevTokenInputIndex = 0;
                    let input = tx.inputs.find((input, inputIndex) => {
                        let script = new mvc.Script(input.script);
                        if (script.chunks.length > 0) {
                            const lockingScriptBuf = TokenUtil.getLockingScriptFromPreimage(script.chunks[0].buf);
                            if (lockingScriptBuf) {
                                if (ftProto.getQueryGenesis(lockingScriptBuf) == genesis) {
                                    prevTokenInputIndex = inputIndex;
                                    return true;
                                }
                                let dataPartObj = ftProto.parseDataPart(lockingScriptBuf);
                                dataPartObj.sensibleID = curDataPartObj.sensibleID;
                                const newScriptBuf = ftProto.updateScript(lockingScriptBuf, dataPartObj);
                                let genesisHash = (0, scryptlib_1.toHex)(mvc.crypto.Hash.sha256ripemd160(newScriptBuf));
                                if (genesisHash == curDataPartObj.genesisHash) {
                                    prevTokenInputIndex = inputIndex;
                                    return true;
                                }
                            }
                        }
                    });
                    if (!input) {
                        throw new error_1.CodeError(error_1.ErrCode.EC_INNER_ERROR, 'There is no valid preTx of the ftUtxo. ');
                    }
                    let preTxId = input.prevTxId.toString('hex');
                    let preOutputIndex = input.outputIndex;
                    ftUtxo.satotxInfo.preTxId = preTxId;
                    ftUtxo.satotxInfo.preOutputIndex = preOutputIndex;
                    ftUtxo.satotxInfo.txInputsCount = tx.inputs.length;
                    ftUtxo.satoshis = tx.outputs[ftUtxo.outputIndex].satoshis;
                    ftUtxo.lockingScript = tx.outputs[ftUtxo.outputIndex].script;
                    // 新增字段 prevTokenInputIndex, prevTokenOutputIndex
                    ftUtxo.prevTokenOutputIndex = input.outputIndex;
                    ftUtxo.prevTokenInputIndex = prevTokenInputIndex;
                    if (!cachedHexs[preTxId]) {
                        cachedHexs[preTxId] = {
                            waitingRes: this.api.getRawTxData(preTxId),
                        };
                    }
                }
                for (let id in cachedHexs) {
                    //Wait for all async requests to complete
                    if (cachedHexs[id].waitingRes && !cachedHexs[id].hex) {
                        cachedHexs[id].hex = yield cachedHexs[id].waitingRes;
                    }
                }
                ftUtxos.forEach((v) => {
                    v.satotxInfo.preTxHex = cachedHexs[v.satotxInfo.preTxId].hex;
                    const preTx = new mvc.Transaction(v.satotxInfo.preTxHex);
                    let dataPartObj = ftProto.parseDataPart(preTx.outputs[v.satotxInfo.preOutputIndex].script.toBuffer());
                    v.preTokenAmount = new BN(dataPartObj.tokenAmount.toString());
                    if (dataPartObj.tokenAddress == '0000000000000000000000000000000000000000') {
                        v.preTokenAddress = this.zeroAddress;
                    }
                    else {
                        v.preTokenAddress = mvc.Address.fromPublicKeyHash(buffer_1.Buffer.from(dataPartObj.tokenAddress, 'hex'), this.network);
                    }
                    v.preLockingScript = preTx.outputs[v.satotxInfo.preOutputIndex].script;
                    // 新增字段 prevTokenTx,
                    v.prevTokenTx = preTx;
                });
                return ftUtxos;
            });
        }
        /**
         * composite a token transfer transaction and amount check transaction
         * @param codehash codehash of the token
         * @param genesis genesis of the token
         * @param receivers token receivers
         * @param ftUtxos input ftUtxos
         * @param ftPrivateKeys private keys of ftUtxos
         * @param ftChangeAddress change address of ftUtxos
         * @param utxos utxos for paying fee
         * @param utxoPrivateKeys private keys of utxos(fee paying)
         * @param changeAddress change address of utxos(fee paying)
         * @param middlePrivateKey
         * @param middleChangeAddress
         * @param isMerge whether to merge the token utxos
         * @param opreturnData opreturn data to be added to the transaction
         * @param minUtxoSet
         * @private
         */
        _transfer({ version, codehash, genesis, receivers, ftUtxos, ftPrivateKeys, ftChangeAddress, utxos, utxoPrivateKeys, changeAddress, middlePrivateKey, middleChangeAddress, isMerge, opreturnData, minUtxoSet, }) {
            return __awaiter(this, void 0, void 0, function* () {
                // limit the number of fee paying utxos
                if (utxos.length > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, 'Mvc utxos should be no more than 3 in the transfer operation, please merge it first ');
                }
                if (!middleChangeAddress) {
                    middleChangeAddress = utxos[0].address;
                    middlePrivateKey = utxoPrivateKeys[0];
                }
                // preprocess the ftUtxos, fetch previous tx hex and parse the token amount. decide the token transfer type.
                let { tokenInputArray, tokenOutputArray, tokenTransferType } = yield this._prepareTransferTokens({
                    codehash,
                    genesis,
                    receivers,
                    ftUtxos,
                    ftChangeAddress,
                    isMerge,
                    minUtxoSet,
                });
                // calculate the fee
                let estimateSatoshis = this._calTransferEstimateFee({
                    p2pkhInputNum: utxos.length,
                    tokenInputArray,
                    tokenOutputArray,
                    tokenTransferType,
                    opreturnData,
                });
                // if fee is not enough, throw error
                const balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                ftUtxos = tokenInputArray;
                const defaultFtUtxo = tokenInputArray[0];
                const ftUtxoTx = new mvc.Transaction(defaultFtUtxo.satotxInfo.txHex);
                const tokenLockingScript = ftUtxoTx.outputs[defaultFtUtxo.outputIndex].script;
                //create transferCheck contract
                let tokenTransferCheckContract = tokenTransferCheck_1.TokenTransferCheckFactory.createContract(tokenTransferType);
                tokenTransferCheckContract.setFormatedDataPart({
                    nSenders: tokenInputArray.length,
                    receiverTokenAmountArray: tokenOutputArray.map((v) => v.tokenAmount),
                    receiverArray: tokenOutputArray.map((v) => v.address),
                    nReceivers: tokenOutputArray.length,
                    tokenCodeHash: (0, scryptlib_1.toHex)(ftProto.getContractCodeHash(tokenLockingScript.toBuffer())),
                    tokenID: (0, scryptlib_1.toHex)(ftProto.getTokenID(tokenLockingScript.toBuffer())),
                });
                const transferCheckTxComposer = new tx_composer_1.TxComposer();
                // add utxo to provide fee for transfer check transaction
                const transferCheck_p2pkhInputIndexs = utxos.map((utxo) => {
                    const inputIndex = transferCheckTxComposer.appendP2PKHInput(utxo);
                    transferCheckTxComposer.addSigHashInfo({
                        inputIndex,
                        address: utxo.address.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.P2PKH,
                    });
                    return inputIndex;
                });
                // add outputs for transfer check transaction
                const transferCheckOutputIndex = transferCheckTxComposer.appendOutput({
                    lockingScript: tokenTransferCheckContract.lockingScript,
                    satoshis: this.getDustThreshold(tokenTransferCheckContract.lockingScript.toBuffer().length),
                });
                // add change output for transfer check transaction
                let changeOutputIndex = transferCheckTxComposer.appendChangeOutput(middleChangeAddress, this.feeb);
                // unlock the fee utxo for transfer check transaction
                let unsignSigPlaceHolderSize = 0;
                if (utxoPrivateKeys && utxoPrivateKeys.length > 0) {
                    transferCheck_p2pkhInputIndexs.forEach((inputIndex) => {
                        let privateKey = utxoPrivateKeys.splice(0, 1)[0];
                        transferCheckTxComposer.unlockP2PKHInput(privateKey, inputIndex);
                    });
                }
                else {
                    //To supplement the size calculation when unsigned
                    transferCheck_p2pkhInputIndexs.forEach((v) => {
                        unsignSigPlaceHolderSize += utils_1.P2PKH_UNLOCK_SIZE;
                    });
                    //Each ftUtxo need to unlock with the size
                    unsignSigPlaceHolderSize = unsignSigPlaceHolderSize * ftUtxos.length;
                }
                // change utxo to the output of transfer check transaction
                utxos = [
                    {
                        txId: transferCheckTxComposer.getTxId(),
                        satoshis: transferCheckTxComposer.getOutput(changeOutputIndex).satoshis,
                        outputIndex: changeOutputIndex,
                        address: middleChangeAddress,
                    },
                ];
                utxoPrivateKeys = utxos.map((v) => middlePrivateKey).filter((v) => v);
                // transfer check utxo in order to unlock the token utxo
                let transferCheckUtxo = {
                    txId: transferCheckTxComposer.getTxId(),
                    outputIndex: transferCheckOutputIndex,
                    satoshis: transferCheckTxComposer.getOutput(transferCheckOutputIndex).satoshis,
                    lockingScript: transferCheckTxComposer.getOutput(transferCheckOutputIndex).script,
                };
                // build token transfer transaction
                const txComposer = new tx_composer_1.TxComposer();
                let prevouts = new Prevouts_1.Prevouts();
                // concat the token addresses and amounts for check
                let inputTokenScript;
                let inputTokenAmountArray = buffer_1.Buffer.alloc(0);
                let inputTokenAddressArray = buffer_1.Buffer.alloc(0);
                const ftUtxoInputIndexs = ftUtxos.map((ftUtxo) => {
                    const inputIndex = txComposer.appendInput(ftUtxo);
                    prevouts.addVout(ftUtxo.txId, ftUtxo.outputIndex);
                    txComposer.addSigHashInfo({
                        inputIndex,
                        address: ftUtxo.tokenAddress.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.BCP02_TOKEN,
                    });
                    inputTokenScript = ftUtxo.lockingScript;
                    inputTokenAddressArray = buffer_1.Buffer.concat([inputTokenAddressArray, ftUtxo.tokenAddress.hashBuffer]);
                    inputTokenAmountArray = buffer_1.Buffer.concat([
                        inputTokenAmountArray,
                        ftUtxo.tokenAmount.toBuffer({
                            endian: 'little',
                            size: 8,
                        }),
                    ]);
                    return inputIndex;
                });
                //tx addInput utxo
                const p2pkhInputIndexs = utxos.map((utxo) => {
                    const inputIndex = txComposer.appendP2PKHInput(utxo);
                    prevouts.addVout(utxo.txId, utxo.outputIndex);
                    txComposer.addSigHashInfo({
                        inputIndex,
                        address: utxo.address.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.P2PKH,
                    });
                    return inputIndex;
                });
                //添加transferCheck为最后一个输入
                const transferCheckInputIndex = txComposer.appendInput(transferCheckUtxo);
                prevouts.addVout(transferCheckUtxo.txId, transferCheckUtxo.outputIndex);
                // concat the token addresses and amounts for check
                let receiverArray = buffer_1.Buffer.alloc(0);
                let receiverTokenAmountArray = buffer_1.Buffer.alloc(0);
                let outputSatoshiArray = buffer_1.Buffer.alloc(0);
                const tokenOutputLen = tokenOutputArray.length;
                for (let i = 0; i < tokenOutputLen; i++) {
                    const tokenOutput = tokenOutputArray[i];
                    const address = tokenOutput.address;
                    const outputTokenAmount = tokenOutput.tokenAmount;
                    const lockingScriptBuf = ftProto.getNewTokenScript(inputTokenScript.toBuffer(), address.hashBuffer, outputTokenAmount);
                    let outputIndex = txComposer.appendOutput({
                        lockingScript: mvc.Script.fromBuffer(lockingScriptBuf),
                        satoshis: this.getDustThreshold(lockingScriptBuf.length),
                    });
                    receiverArray = buffer_1.Buffer.concat([receiverArray, address.hashBuffer]);
                    const tokenBuf = outputTokenAmount.toBuffer({
                        endian: 'little',
                        size: 8,
                    });
                    receiverTokenAmountArray = buffer_1.Buffer.concat([receiverTokenAmountArray, tokenBuf]);
                    const satoshiBuf = BN.fromNumber(txComposer.getOutput(outputIndex).satoshis).toBuffer({
                        endian: 'little',
                        size: 8,
                    });
                    outputSatoshiArray = buffer_1.Buffer.concat([outputSatoshiArray, satoshiBuf]);
                }
                //tx addOutput OpReturn
                let opreturnScriptHex = '';
                if (opreturnData) {
                    const opreturnOutputIndex = txComposer.appendOpReturnOutput(opreturnData);
                    opreturnScriptHex = txComposer.getOutput(opreturnOutputIndex).script.toHex();
                }
                //The first round of calculations get the exact size of the final transaction, and then change again
                //Due to the change, the script needs to be unlocked again in the second round
                //let the fee be exact in the second round
                for (let c = 0; c < 2; c++) {
                    txComposer.clearChangeOutput();
                    const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb, unsignSigPlaceHolderSize);
                    let tokenTxHeaderArray = buffer_1.Buffer.alloc(0);
                    let tokenTxHashProofArray = buffer_1.Buffer.alloc(0);
                    let tokenSatoshiBytesArray = buffer_1.Buffer.alloc(0);
                    // process each ft utxo input, unlock the token utxo
                    ftUtxoInputIndexs.forEach((inputIndex, idx) => {
                        let ftUtxo = ftUtxos[idx];
                        let senderPrivateKey = ftPrivateKeys[idx];
                        let dataPartObj = ftProto.parseDataPart(ftUtxo.lockingScript.toBuffer());
                        const dataPart = ftProto.newDataPart(dataPartObj);
                        const tokenContract = token_1.TokenFactory.createContract(this.transferCheckCodeHashArray, this.unlockContractCodeHashArray, version);
                        const amountCheckTx = transferCheckTxComposer.getTx();
                        const amountCheckOutputIndex = 0;
                        const amountCheckTxOutputProofInfo = new TxOutputProof(TokenUtil.getTxOutputProof(amountCheckTx, amountCheckOutputIndex));
                        const amountCheckScriptBuf = amountCheckTx.outputs[amountCheckOutputIndex].script.toBuffer();
                        const prevTokenInputIndex = ftUtxo.prevTokenInputIndex; // ???
                        const prevTokenAddress = new scryptlib_1.Bytes((0, scryptlib_1.toHex)(ftUtxo.preTokenAddress.hashBuffer));
                        // const prevTokenAddress = new Bytes(TokenProto.getTokenAddress(scriptBuf).toString('hex'))
                        const prevTokenAmount = BigInt(ftUtxo.preTokenAmount.toString(10));
                        // const prevTokenAmount = TokenProto.getTokenAmount(scriptBuf)
                        const tokenTx = new mvc.Transaction(ftUtxo.satotxInfo.txHex);
                        const inputRes = TokenUtil.getTxInputProof(tokenTx, prevTokenInputIndex);
                        const tokenTxInputProof = new TxInputProof(inputRes[0]);
                        const tokenTxHeader = inputRes[1]; // TODO:
                        const prevTokenTxOutputProof = new TxOutputProof(TokenUtil.getTxOutputProof(ftUtxo.prevTokenTx, ftUtxo.prevTokenOutputIndex));
                        const tokenTxInfoHex = TokenUtil.getTxInfoHex(tokenTx, ftUtxo.outputIndex);
                        tokenTxHeaderArray = buffer_1.Buffer.concat([tokenTxHeaderArray, buffer_1.Buffer.from(tokenTxInfoHex.txHeader, 'hex')]);
                        const hashProofBuf = buffer_1.Buffer.from(tokenTxInfoHex.txHashProof, 'hex');
                        tokenTxHashProofArray = buffer_1.Buffer.concat([
                            tokenTxHashProofArray,
                            TokenUtil.getUInt32Buf(hashProofBuf.length),
                            hashProofBuf,
                        ]);
                        tokenSatoshiBytesArray = buffer_1.Buffer.concat([
                            tokenSatoshiBytesArray,
                            buffer_1.Buffer.from(tokenTxInfoHex.txSatoshi, 'hex'),
                        ]);
                        // unlockFromContract
                        const contractTxOutputProof = new TxOutputProof(TokenUtil.getEmptyTxOutputProof());
                        tokenContract.setDataPart((0, scryptlib_1.toHex)(dataPart));
                        // unlock the token utxo
                        const unlockingContract = tokenContract.unlock({
                            txPreimage: txComposer.getInputPreimage(inputIndex),
                            prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                            tokenInputIndex: inputIndex,
                            amountCheckHashIndex: tokenTransferType - 1,
                            amountCheckInputIndex: txComposer.getTx().inputs.length - 1,
                            amountCheckTxOutputProofInfo,
                            amountCheckScript: new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex')),
                            prevTokenInputIndex,
                            prevTokenAddress,
                            prevTokenAmount,
                            tokenTxHeader,
                            tokenTxInputProof,
                            prevTokenTxOutputProof,
                            senderPubKey: new scryptlib_1.PubKey(ftUtxo.publicKey ? ftUtxo.publicKey.toHex() : utils_1.PLACE_HOLDER_PUBKEY),
                            senderSig: new scryptlib_1.Sig(senderPrivateKey
                                ? (0, scryptlib_1.toHex)(txComposer.getTxFormatSig(senderPrivateKey, inputIndex))
                                : utils_1.PLACE_HOLDER_SIG),
                            // contractInputIndex: transferCheckInputIndex,
                            // contractTxOutputProof,
                            contractInputIndex: 0,
                            contractTxOutputProof,
                            // checkInputIndex: transferCheckInputIndex,
                            // checkScriptTx: new Bytes(transferCheckTx.serialize(true)),
                            // nReceivers: tokenOutputLen,
                            operation: ftProto.OP_TRANSFER,
                        });
                        if (this.debug && senderPrivateKey) {
                            let txContext = {
                                tx: txComposer.getTx(),
                                inputIndex: inputIndex,
                                inputSatoshis: txComposer.getInput(inputIndex).output.satoshis,
                            };
                            let ret = unlockingContract.verify(txContext);
                            if (!ret.success)
                                throw ret;
                        }
                        txComposer.getInput(inputIndex).setScript(unlockingContract.toScript());
                    });
                    const tokenOutputSatoshis = txComposer.getOutput(0).satoshis;
                    let sub = transferCheckUtxo.lockingScript;
                    sub = sub.subScript(0);
                    const txPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sub, transferCheckUtxo.satoshis, transferCheckInputIndex
                    // Signature.SIGHASH_ALL
                    )));
                    // unlock the token transfer check utxo
                    let unlockingContract = tokenTransferCheckContract.unlock({
                        // txPreimage: txComposer.getInputPreimage(transferCheckInputIndex),
                        txPreimage,
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        tokenScript: new scryptlib_1.Bytes(inputTokenScript.toHex()),
                        tokenTxHeaderArray: new scryptlib_1.Bytes(tokenTxHeaderArray.toString('hex')),
                        tokenTxHashProofArray: new scryptlib_1.Bytes(tokenTxHashProofArray.toString('hex')),
                        tokenSatoshiBytesArray: new scryptlib_1.Bytes(tokenSatoshiBytesArray.toString('hex')),
                        inputTokenAddressArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAddressArray)),
                        inputTokenAmountArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAmountArray)),
                        // receiverSatoshiArray: new Bytes(toHex(outputSatoshiArray)),
                        tokenOutputSatoshis,
                        // same
                        changeSatoshis: new scryptlib_1.Int(changeOutputIndex != -1 ? txComposer.getOutput(changeOutputIndex).satoshis : 0),
                        changeAddress: new scryptlib_1.Ripemd160((0, scryptlib_1.toHex)(changeAddress.hashBuffer)),
                        opReturnScript: new scryptlib_1.Bytes(opreturnScriptHex),
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: transferCheckInputIndex,
                            inputSatoshis: txComposer.getInput(transferCheckInputIndex).output.satoshis,
                        };
                        let ret = unlockingContract.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(transferCheckInputIndex).setScript(unlockingContract.toScript());
                }
                if (utxoPrivateKeys && utxoPrivateKeys.length > 0) {
                    p2pkhInputIndexs.forEach((inputIndex) => {
                        let privateKey = utxoPrivateKeys.splice(0, 1)[0];
                        txComposer.unlockP2PKHInput(privateKey, inputIndex);
                    });
                }
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { transferCheckTxComposer, txComposer };
            });
        }
        /**
         * burn the provided ft utxos, the utxo must be sent to the zero address in order to burn
         * @param codehash codehash of the token
         * @param genesis genesis of the token
         * @param ftUtxos ft utxos to burn(must be transferred to the zero address)
         * @param utxos utxos to pay the fee
         * @param utxoPrivateKey private keys of the utxos(fee paying utxos)
         * @param changeAddress the address to receive the change satoshis
         * @param opreturnData opreturn data
         * @private
         * @returns {Promise<{transferCheckTxComposer: TxComposer, txComposer: TxComposer}>}
         */
        _burn({ version, genesis, ftUtxos, utxos, utxoPrivateKey, changeAddress, opreturnData, }) {
            return __awaiter(this, void 0, void 0, function* () {
                if (utxos.length == 0) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, 'Mvc utxos should not be empty in the burn operation');
                }
                // limit the number of fee paying utxos
                if (utxos.length > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, 'Mvc utxos should be no more than 3 in the transfer operation, please merge it first ');
                }
                if (!utxoPrivateKey) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INVALID_ARGUMENT, 'No private key detected for the utxos, please provide the private key for the utxos ');
                }
                // check the ftUtxos must be sent to the zero address
                ftUtxos.forEach((ftUtxo) => {
                    if (!ftUtxo.tokenAddress.hashBuffer.equals(constants_1.BURN_ADDRESS)) {
                        throw new error_1.CodeError(error_1.ErrCode.EC_CANNOT_BURN_NON_ZERO_ADDRESS, 'All ftUtxo must be sent to the zero address in order to burn');
                    }
                });
                // preprocess the ftUtxos, fetch previous tx hex and parse the token amount. decide the token unlock type.
                const { tokenInputArray, tokenUnlockType } = yield this._prepareBurnTokens({
                    genesis,
                    ftUtxos,
                });
                // calculate the fee
                let estimateSatoshis = this._calBurnEstimateFee({
                    p2pkhInputNum: utxos.length,
                    tokenInputArray,
                    opreturnData,
                    tokenUnlockType,
                });
                // if fee is not enough, throw error
                const balance = utxos.reduce((pre, cur) => pre + cur.satoshis, 0);
                if (balance < estimateSatoshis) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_INSUFFICIENT_MVC, `Insufficient balance.It take more than ${estimateSatoshis}, but only ${balance}.`);
                }
                ftUtxos = tokenInputArray;
                const defaultFtUtxo = tokenInputArray[0];
                const ftUtxoTx = new mvc.Transaction(defaultFtUtxo.satotxInfo.txHex);
                const tokenLockingScript = ftUtxoTx.outputs[defaultFtUtxo.outputIndex].script;
                //create transferCheck contract
                let tokenUnlockCheckContract = tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.createContract(tokenUnlockType);
                const inputTokenIndexArray = [];
                for (let i = 0; i < tokenInputArray.length; i++) {
                    inputTokenIndexArray.push(i);
                }
                tokenUnlockCheckContract.setFormatedDataPart({
                    inputTokenIndexArray: inputTokenIndexArray,
                    nSender: tokenInputArray.length,
                    tokenCodeHash: (0, scryptlib_1.toHex)(ftProto.getContractCodeHash(tokenLockingScript.toBuffer())),
                    tokenID: (0, scryptlib_1.toHex)(ftProto.getTokenID(tokenLockingScript.toBuffer())),
                    nReceivers: 0,
                    receiverTokenAmountArray: [],
                    receiverArray: [],
                });
                // create unlock check transaction
                const unlockCheckTxComposer = new tx_composer_1.TxComposer();
                // add utxo to provide fee for transfer check transaction
                const unlockCheckP2pkhInputIndices = utxos.map((utxo) => {
                    const inputIndex = unlockCheckTxComposer.appendP2PKHInput(utxo);
                    unlockCheckTxComposer.addSigHashInfo({
                        inputIndex,
                        address: utxo.address.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.P2PKH,
                    });
                    return inputIndex;
                });
                // add outputs for unlock check transaction
                const unlockCheckOutputIndex = unlockCheckTxComposer.appendOutput({
                    lockingScript: tokenUnlockCheckContract.lockingScript,
                    satoshis: this.getDustThreshold(tokenUnlockCheckContract.lockingScript.toBuffer().length),
                });
                // add change
                let unlockCheckChangeOutputIndex = unlockCheckTxComposer.appendChangeOutput(utxos[0].address, this.feeb);
                // unlock the fee utxo for unlock check transaction
                unlockCheckP2pkhInputIndices.forEach((inputIndex) => {
                    unlockCheckTxComposer.unlockP2PKHInput(utxoPrivateKey, inputIndex);
                });
                let unsignSigPlaceHolderSize = 0;
                // unlock check utxo in order to unlock the token utxo
                let unlockCheckUtxo = {
                    txId: unlockCheckTxComposer.getTxId(),
                    outputIndex: unlockCheckOutputIndex,
                    satoshis: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).satoshis,
                    lockingScript: unlockCheckTxComposer.getOutput(unlockCheckOutputIndex).script,
                };
                // change fee utxo to the output of unlock check transaction
                utxos = [
                    {
                        txId: unlockCheckTxComposer.getTxId(),
                        satoshis: unlockCheckTxComposer.getOutput(unlockCheckChangeOutputIndex).satoshis,
                        outputIndex: unlockCheckChangeOutputIndex,
                        address: utxos[0].address,
                    },
                ];
                // build token burn transaction
                const txComposer = new tx_composer_1.TxComposer();
                let prevouts = new Prevouts_1.Prevouts();
                // concat the token addresses and amounts for check
                let inputTokenScript;
                let inputTokenAmountArray = buffer_1.Buffer.alloc(0);
                let inputTokenAddressArray = buffer_1.Buffer.alloc(0);
                const ftUtxoInputIndexs = ftUtxos.map((ftUtxo) => {
                    const inputIndex = txComposer.appendInput(ftUtxo);
                    prevouts.addVout(ftUtxo.txId, ftUtxo.outputIndex);
                    txComposer.addSigHashInfo({
                        inputIndex,
                        address: ftUtxo.tokenAddress.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.BCP02_TOKEN,
                    });
                    inputTokenScript = ftUtxo.lockingScript;
                    inputTokenAddressArray = buffer_1.Buffer.concat([inputTokenAddressArray, ftUtxo.tokenAddress.hashBuffer]);
                    inputTokenAmountArray = buffer_1.Buffer.concat([
                        inputTokenAmountArray,
                        ftUtxo.tokenAmount.toBuffer({
                            endian: 'little',
                            size: 8,
                        }),
                    ]);
                    return inputIndex;
                });
                //tx addInput utxo
                const p2pkhInputIndexs = utxos.map((utxo) => {
                    const inputIndex = txComposer.appendP2PKHInput(utxo);
                    prevouts.addVout(utxo.txId, utxo.outputIndex);
                    txComposer.addSigHashInfo({
                        inputIndex,
                        address: utxo.address.toString(),
                        sighashType: exports.sighashType,
                        contractType: utils_1.CONTRACT_TYPE.P2PKH,
                    });
                    return inputIndex;
                });
                //添加unlockCheck为最后一个输入
                const unlockCheckInputIndex = txComposer.appendInput(unlockCheckUtxo);
                prevouts.addVout(unlockCheckUtxo.txId, unlockCheckUtxo.outputIndex);
                // // concat the token addresses and amounts for check
                // // no receiver for token burn
                // let receiverArray = Buffer.alloc(0)
                // let receiverTokenAmountArray = Buffer.alloc(0)
                // let outputSatoshiArray = Buffer.alloc(0)
                //tx addOutput OpReturn
                if (opreturnData) {
                    txComposer.appendOpReturnOutput(opreturnData);
                }
                //The first round of calculations get the exact size of the final transaction, and then change again
                //Due to the change, the script needs to be unlocked again in the second round
                //let the fee be exact in the second round
                for (let c = 0; c < 2; c++) {
                    txComposer.clearChangeOutput();
                    const changeOutputIndex = txComposer.appendChangeOutput(changeAddress, this.feeb, unsignSigPlaceHolderSize);
                    let tokenTxHeaderArray = buffer_1.Buffer.alloc(0);
                    let tokenTxHashProofArray = buffer_1.Buffer.alloc(0);
                    let tokenSatoshiBytesArray = buffer_1.Buffer.alloc(0);
                    // unlockFromContract
                    const contractTxOutputProof = (0, tokenUtil_1.getTxOutputProof)(unlockCheckTxComposer.getTx(), unlockCheckOutputIndex);
                    // process each ft utxo input, unlock the token utxo
                    ftUtxoInputIndexs.forEach((inputIndex, idx) => {
                        let ftUtxo = ftUtxos[idx];
                        let dataPartObj = ftProto.parseDataPart(ftUtxo.lockingScript.toBuffer());
                        const dataPart = ftProto.newDataPart(dataPartObj);
                        const tokenContract = token_1.TokenFactory.createContract(this.transferCheckCodeHashArray, this.unlockContractCodeHashArray, version);
                        tokenContract.setDataPart((0, scryptlib_1.toHex)(dataPart));
                        const amountCheckTx = unlockCheckTxComposer.getTx();
                        const amountCheckOutputIndex = 0;
                        const amountCheckTxOutputProofInfo = new TxOutputProof(TokenUtil.getTxOutputProof(amountCheckTx, amountCheckOutputIndex));
                        const amountCheckScriptBuf = amountCheckTx.outputs[amountCheckOutputIndex].script.toBuffer();
                        // previous tx check
                        const prevTokenInputIndex = ftUtxo.prevTokenInputIndex;
                        const prevTokenAddress = new scryptlib_1.Bytes((0, scryptlib_1.toHex)(ftUtxo.preTokenAddress.hashBuffer));
                        const prevTokenAmount = BigInt(ftUtxo.preTokenAmount.toString(10));
                        const tokenTx = new mvc.Transaction(ftUtxo.satotxInfo.txHex);
                        const inputRes = TokenUtil.getTxInputProof(tokenTx, prevTokenInputIndex);
                        const tokenTxInputProof = new TxInputProof(inputRes[0]);
                        const tokenTxHeader = inputRes[1];
                        const prevTokenTxOutputProof = new TxOutputProof(TokenUtil.getTxOutputProof(ftUtxo.prevTokenTx, ftUtxo.prevTokenOutputIndex));
                        const tokenTxInfoHex = TokenUtil.getTxInfoHex(tokenTx, ftUtxo.outputIndex);
                        tokenTxHeaderArray = buffer_1.Buffer.concat([tokenTxHeaderArray, buffer_1.Buffer.from(tokenTxInfoHex.txHeader, 'hex')]);
                        const hashProofBuf = buffer_1.Buffer.from(tokenTxInfoHex.txHashProof, 'hex');
                        tokenTxHashProofArray = buffer_1.Buffer.concat([
                            tokenTxHashProofArray,
                            TokenUtil.getUInt32Buf(hashProofBuf.length),
                            hashProofBuf,
                        ]);
                        tokenSatoshiBytesArray = buffer_1.Buffer.concat([
                            tokenSatoshiBytesArray,
                            buffer_1.Buffer.from(tokenTxInfoHex.txSatoshi, 'hex'),
                        ]);
                        // unlock the token utxo
                        const unlockingContract = tokenContract.unlock({
                            txPreimage: txComposer.getInputPreimage(inputIndex),
                            prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                            tokenInputIndex: inputIndex,
                            amountCheckHashIndex: tokenUnlockType - 1,
                            amountCheckInputIndex: txComposer.getTx().inputs.length - 1,
                            amountCheckTxOutputProofInfo,
                            amountCheckScript: new scryptlib_1.Bytes(amountCheckScriptBuf.toString('hex')),
                            prevTokenInputIndex,
                            prevTokenAddress,
                            prevTokenAmount,
                            tokenTxHeader,
                            tokenTxInputProof,
                            prevTokenTxOutputProof,
                            senderPubKey: new scryptlib_1.PubKey(utils_1.PLACE_HOLDER_PUBKEY),
                            senderSig: new scryptlib_1.Sig(utils_1.PLACE_HOLDER_SIG),
                            contractInputIndex: unlockCheckInputIndex,
                            contractTxOutputProof: new TxOutputProof(contractTxOutputProof),
                            operation: ftProto.OP_UNLOCK_FROM_CONTRACT,
                        });
                        txComposer.getInput(inputIndex).setScript(unlockingContract.toScript());
                        if (this.debug) {
                            let txContext = {
                                tx: txComposer.getTx(),
                                inputIndex: inputIndex,
                                inputSatoshis: txComposer.getInput(inputIndex).output.satoshis,
                            };
                            let ret = unlockingContract.verify(txContext);
                            if (!ret.success)
                                throw ret;
                        }
                    });
                    // since the token is burned, the token output satoshi is 0
                    const tokenOutputSatoshis = 0;
                    const tokenOutputIndexArray = buffer_1.Buffer.alloc(0);
                    const changeOutput = txComposer.getTx().outputs[changeOutputIndex];
                    // prepare change output array for the unlock check utxo
                    const otherOutputBuff = buffer_1.Buffer.concat([
                        (0, tokenUtil_1.getUInt64Buf)(changeOutput.satoshis),
                        (0, tokenUtil_1.writeVarint)(changeOutput.script.toBuffer()),
                    ]);
                    // write size and output data
                    let otherOutputArray = buffer_1.Buffer.alloc(0);
                    otherOutputArray = buffer_1.Buffer.concat([
                        otherOutputArray,
                        (0, tokenUtil_1.getUInt32Buf)(otherOutputBuff.length),
                        otherOutputBuff,
                    ]);
                    let sub = unlockCheckUtxo.lockingScript;
                    sub = sub.subScript(0);
                    const txPreimage = new scryptlib_1.SigHashPreimage((0, scryptlib_1.toHex)((0, scryptlib_1.getPreimage)(txComposer.getTx(), sub, unlockCheckUtxo.satoshis, unlockCheckInputIndex
                    // Signature.SIGHASH_ALL
                    )));
                    // unlock the token transfer check utxo
                    let unlockingContract = tokenUnlockCheckContract.unlock({
                        // txPreimage: txComposer.getInputPreimage(transferCheckInputIndex),
                        txPreimage,
                        prevouts: new scryptlib_1.Bytes(prevouts.toHex()),
                        tokenScript: new scryptlib_1.Bytes(inputTokenScript.toHex()),
                        tokenTxHeaderArray: new scryptlib_1.Bytes(tokenTxHeaderArray.toString('hex')),
                        tokenTxHashProofArray: new scryptlib_1.Bytes(tokenTxHashProofArray.toString('hex')),
                        tokenSatoshiBytesArray: new scryptlib_1.Bytes(tokenSatoshiBytesArray.toString('hex')),
                        inputTokenAddressArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAddressArray)),
                        inputTokenAmountArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(inputTokenAmountArray)),
                        nOutputs: txComposer.getTx().outputs.length,
                        tokenOutputIndexArray: new scryptlib_1.Bytes(tokenOutputIndexArray.toString('hex')),
                        tokenOutputSatoshis,
                        otherOutputArray: new scryptlib_1.Bytes((0, scryptlib_1.toHex)(otherOutputArray)),
                    });
                    if (this.debug) {
                        let txContext = {
                            tx: txComposer.getTx(),
                            inputIndex: unlockCheckInputIndex,
                            inputSatoshis: txComposer.getInput(unlockCheckInputIndex).output.satoshis,
                        };
                        let ret = unlockingContract.verify(txContext);
                        if (ret.success == false)
                            throw ret;
                    }
                    txComposer.getInput(unlockCheckInputIndex).setScript(unlockingContract.toScript());
                }
                p2pkhInputIndexs.forEach((inputIndex) => {
                    txComposer.unlockP2PKHInput(utxoPrivateKey, inputIndex);
                });
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return { unlockCheckTxComposer, txComposer };
            });
        }
        /**
         * calculate transfer fee for ft transfer
         * @param p2pkhInputNum
         * @param tokenInputArray
         * @param tokenOutputArray
         * @param tokenTransferType
         * @param opreturnData
         * @private
         */
        _calTransferEstimateFee({ p2pkhInputNum = 10, tokenInputArray, tokenOutputArray, tokenTransferType, opreturnData, }) {
            let inputTokenNum = tokenInputArray.length;
            let outputTokenNum = tokenOutputArray.length;
            let dummyTransferCheckContract = tokenTransferCheck_1.TokenTransferCheckFactory.getDummyInstance(tokenTransferType);
            let routeCheckLockingSize = tokenTransferCheck_1.TokenTransferCheckFactory.getLockingScriptSize(tokenTransferType);
            let routeCheckUnlockingSize = tokenTransferCheck_1.TokenTransferCheckFactory.calUnlockingScriptSize(tokenTransferType, p2pkhInputNum, inputTokenNum, outputTokenNum, opreturnData);
            let tokenUnlockingSize = token_1.TokenFactory.calUnlockingScriptSize(dummyTransferCheckContract, p2pkhInputNum, inputTokenNum, outputTokenNum);
            let tokenLockingSize = token_1.TokenFactory.getLockingScriptSize();
            let stx1 = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
            for (let i = 0; i < p2pkhInputNum; i++) {
                stx1.addP2PKHInput();
            }
            stx1.addOutput(routeCheckLockingSize);
            stx1.addP2PKHOutput();
            let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
            for (let i = 0; i < inputTokenNum; i++) {
                stx.addInput(tokenUnlockingSize, tokenInputArray[i].satoshis);
            }
            for (let i = 0; i < p2pkhInputNum; i++) {
                stx.addP2PKHInput();
            }
            stx.addInput(routeCheckUnlockingSize, this.dustCalculator.getDustThreshold(routeCheckLockingSize));
            for (let i = 0; i < outputTokenNum; i++) {
                stx.addOutput(tokenLockingSize);
            }
            if (opreturnData) {
                stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
            }
            stx.addP2PKHOutput();
            return stx1.getFee() + stx.getFee();
        }
        /**
         * calculate transfer fee for ft burn
         * this includes the fee for transfer check tx
         * @param p2pkhInputNum
         * @param tokenInputArray
         * @param opreturnData
         * @param tokenUnlockType
         * @private
         */
        _calBurnEstimateFee({ p2pkhInputNum = 10, tokenInputArray, opreturnData, tokenUnlockType, }) {
            let inputTokenNum = tokenInputArray.length;
            let dummyTransferCheckContract = tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.getDummyInstance(tokenUnlockType);
            let routeCheckLockingSize = tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.getLockingScriptSize(tokenUnlockType);
            let routeCheckUnlockingSize = tokenUnlockContractCheck_1.TokenUnlockContractCheckFactory.calUnlockingScriptSize(tokenUnlockType, p2pkhInputNum, inputTokenNum, 1, opreturnData);
            let tokenUnlockingSize = token_1.TokenFactory.calUnlockingScriptSize(dummyTransferCheckContract, p2pkhInputNum, inputTokenNum, 0);
            let stx1 = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
            for (let i = 0; i < p2pkhInputNum; i++) {
                stx1.addP2PKHInput();
            }
            stx1.addOutput(routeCheckLockingSize);
            stx1.addP2PKHOutput();
            let stx = new SizeTransaction_1.SizeTransaction(this.feeb, this.dustCalculator);
            for (let i = 0; i < inputTokenNum; i++) {
                stx.addInput(tokenUnlockingSize, tokenInputArray[i].satoshis);
            }
            for (let i = 0; i < p2pkhInputNum; i++) {
                stx.addP2PKHInput();
            }
            stx.addInput(routeCheckUnlockingSize, this.dustCalculator.getDustThreshold(routeCheckLockingSize));
            if (opreturnData) {
                stx.addOpReturnOutput(mvc.Script.buildSafeDataOut(opreturnData).toBuffer().length);
            }
            stx.addP2PKHOutput();
            return stx1.getFee() + stx.getFee();
        }
        getDustThreshold(size) {
            return this.dustCalculator.getDustThreshold(size);
        }
        getBalance({ codehash, genesis, address, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let { balance, pendingBalance } = yield this.api.getFungibleTokenBalance(codehash, genesis, address);
                return BN.fromString(balance, 10).add(BN.fromString(pendingBalance, 10)).toString();
            });
        }
        /**
         * Query token balance detail
         * @param codehash
         * @param genesis
         * @param address
         * @returns
         */
        getBalanceDetail({ codehash, genesis, address, }) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield this.api.getFungibleTokenBalance(codehash, genesis, address);
            });
        }
        /**
         * Query the Token list under this address. Get the balance of each token
         * @param address
         * @returns
         */
        getSummary(address) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield this.api.getFungibleTokenSummary(address);
            });
        }
        getFtUtxos(codehash, genesis, address, count = 20) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield this.api.getFungibleTokenUnspents(codehash, genesis, address, count);
            });
        }
        getMergeEstimateFee({ codehash, genesis, ownerWif, ownerPublicKey, ftUtxos, ftChangeAddress, opreturnData, utxoMaxCount = 3, minUtxoSet = true, }) {
            return __awaiter(this, void 0, void 0, function* () {
                return yield this.getTransferEstimateFee({
                    codehash,
                    genesis,
                    senderWif: ownerWif,
                    senderPublicKey: ownerPublicKey,
                    ftUtxos,
                    ftChangeAddress,
                    opreturnData,
                    receivers: [],
                    isMerge: true,
                    utxoMaxCount,
                    minUtxoSet,
                });
            });
        }
        getTransferEstimateFee({ codehash, genesis, receivers, senderWif, senderPrivateKey, senderPublicKey, ftUtxos, ftChangeAddress, isMerge, opreturnData, utxoMaxCount = 3, minUtxoSet = true, }) {
            return __awaiter(this, void 0, void 0, function* () {
                let p2pkhInputNum = utxoMaxCount;
                if (p2pkhInputNum > 3) {
                    throw new error_1.CodeError(error_1.ErrCode.EC_UTXOS_MORE_THAN_3, 'Mvc utxos should be no more than 3 in the transfer operation. ');
                }
                if (senderWif) {
                    senderPrivateKey = mvc.PrivateKey.fromWIF(senderWif);
                    senderPublicKey = senderPrivateKey.toPublicKey();
                }
                else if (senderPrivateKey) {
                    senderPrivateKey = new mvc.PrivateKey(senderPrivateKey);
                    senderPublicKey = senderPrivateKey.toPublicKey();
                }
                else if (senderPublicKey) {
                    senderPublicKey = new mvc.PublicKey(senderPublicKey);
                }
                let utxos = [];
                for (let i = 0; i < p2pkhInputNum; i++) {
                    utxos.push({
                        txId: dummy_1.dummyTxId,
                        outputIndex: i,
                        satoshis: 1000,
                        address: this.zeroAddress,
                    });
                }
                let ftUtxoInfo = yield this._pretreatFtUtxos(ftUtxos, codehash, genesis, senderPrivateKey, senderPublicKey);
                if (ftChangeAddress) {
                    ftChangeAddress = new mvc.Address(ftChangeAddress, this.network);
                }
                else {
                    ftChangeAddress = ftUtxoInfo.ftUtxos[0].tokenAddress;
                }
                let { tokenInputArray, tokenOutputArray, tokenTransferType } = yield this._prepareTransferTokens({
                    codehash,
                    genesis,
                    receivers,
                    ftUtxos: ftUtxoInfo.ftUtxos,
                    ftChangeAddress,
                    isMerge,
                    minUtxoSet,
                });
                let estimateSatoshis = this._calTransferEstimateFee({
                    p2pkhInputNum: utxos.length,
                    tokenInputArray,
                    tokenOutputArray,
                    tokenTransferType,
                    opreturnData,
                });
                return estimateSatoshis;
            });
        }
        static parseTokenScript(scriptBuf, network = __1.API_NET.MAIN) {
            if (!(0, protoheader_1.hasProtoFlag)(scriptBuf)) {
                return null;
            }
            const dataPart = ftProto.parseDataPart(scriptBuf);
            const tokenAddress = mvc.Address.fromPublicKeyHash(buffer_1.Buffer.from(dataPart.tokenAddress, 'hex'), network).toString();
            const genesis = ftProto.getQueryGenesis(scriptBuf);
            const codehash = ftProto.getQueryCodehash(scriptBuf);
            const sensibleId = ftProto.getQuerySensibleID(scriptBuf);
            return {
                codehash,
                genesis,
                sensibleId,
                tokenName: dataPart.tokenName,
                tokenSymbol: dataPart.tokenSymbol,
                decimalNum: dataPart.decimalNum,
                tokenAddress,
                tokenAmount: dataPart.tokenAmount,
                genesisHash: dataPart.genesisHash,
                sensibleID: dataPart.sensibleID,
                protoVersion: dataPart.protoVersion,
                protoType: dataPart.protoType,
            };
        }
    }
    exports.FtManager = FtManager;
    
    },{"..":395,"../bn.js":381,"../common/DustCalculator":383,"../common/Prevouts":384,"../common/SizeTransaction":385,"../common/argumentCheck":386,"../common/dummy":387,"../common/error":388,"../common/protoheader":389,"../common/tokenUtil":390,"../common/utils":391,"../helpers/contractHelpers":392,"../helpers/transactionHelpers":394,"../mcp02/contract-factory/tokenUnlockContractCheck":434,"../mvc":440,"../scryptlib":445,"../tx-composer":446,"./constants":416,"./contract-desc/txUtil_desc.json":430,"./contract-factory/token":431,"./contract-factory/tokenGenesis":432,"./contract-factory/tokenTransferCheck":433,"./contract-proto/token.proto":435,"./contractUtil":438,"buffer":84}],440:[function(require,module,exports){
    const { mvc } = require('../scryptlib');
    const Message = require('mvc-lib/message');
    const Mnemonic = require('mvc-lib/mnemonic');
    const ECIES = require('mvc-lib/ecies');
    mvc.Script.Interpreter.MAX_SCRIPT_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
    mvc.Script.Interpreter.MAXIMUM_ELEMENT_SIZE = Number.MAX_SAFE_INTEGER;
    mvc.Message = Message;
    mvc.Mnemonic = Mnemonic;
    mvc.ECIES = ECIES;
    module.exports = mvc;
    
    },{"../scryptlib":445,"mvc-lib/ecies":198,"mvc-lib/message":273,"mvc-lib/mnemonic":274}],441:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.BrowserNet = void 0;
    const _1 = require(".");
    const Utils = require("./utils");
    var HttpMethod;
    (function (HttpMethod) {
        HttpMethod["GET"] = "GET";
        HttpMethod["POST"] = "POST";
    })(HttpMethod || (HttpMethod = {}));
    class BrowserNet {
        static httpGet(url, params, cb, config) {
            let str = '';
            let cnt = 0;
            for (var id in params) {
                if (cnt != 0)
                    str += '&';
                str += id + '=' + params[id];
                cnt++;
            }
            if (str) {
                url += '?' + str;
            }
            config = config || {};
            let headers = config.headers || {};
            let timeout = config.timeout || _1.Net.timeout;
            let reqData = {
                uri: url,
                method: HttpMethod.GET,
                timeout,
                gzip: true,
                headers,
            };
            // const handlerCallback = (resolve: Function, reject: Function) => {
            //   this._xmlRequest(reqData, (err: any, body: any) => {
            //     if (err) {
            //       reject(err)
            //       return
            //     }
            //     if (typeof body == 'string') {
            //       try {
            //         body = JSON.parse(body)
            //       } catch (e) {}
            //     }
            //     resolve(body)
            //   })
            // }
            if (typeof cb === 'function') {
                this.handleCallback((result) => Utils.invokeCallback(cb, null, result), (err) => Utils.invokeCallback(cb, err), reqData);
                return;
            }
            return new Promise((resolve, reject) => {
                this.handleCallback(resolve, reject, reqData);
            });
        }
        static httpPost(url, params, cb, config) {
            return __awaiter(this, void 0, void 0, function* () {
                let postData;
                config = config || {};
                let headers = config.headers || {};
                let timeout = config.timeout || _1.Net.timeout;
                headers['content-type'] = headers['content-type'] || 'application/json';
                if (headers['content-type'] == 'application/x-www-form-urlencoded') {
                    let arr = [];
                    for (var id in params) {
                        arr.push(`${id}=${params[id]}`);
                    }
                    postData = arr.join('&');
                }
                else if (headers['content-type'] == 'text/plain') {
                    postData = params;
                }
                else {
                    postData = JSON.stringify(params);
                }
                if (headers['content-encoding'] == 'gzip') {
                    postData = yield Utils.gzip(Buffer.from(postData));
                }
                const reqData = {
                    uri: url,
                    method: HttpMethod.POST,
                    body: postData,
                    headers: headers,
                    timeout: timeout,
                    gzip: true,
                };
                // const handlerCallback = (resolve: Function, reject: Function) => {
                //   this._xmlRequest(reqData, (err: any, body: any) => {
                //     if (err) {
                //       reject(err)
                //       return
                //     }
                //     if (typeof body == 'string') {
                //       try {
                //         body = JSON.parse(body)
                //       } catch (e) {}
                //     }
                //     resolve(body)
                //   })
                // }
                if (typeof cb === 'function') {
                    this.handleCallback((result) => Utils.invokeCallback(cb, null, result), (err) => Utils.invokeCallback(cb, err), reqData);
                    return;
                }
                return new Promise((resolve, reject) => {
                    this.handleCallback(resolve, reject, reqData);
                });
            });
        }
    }
    exports.BrowserNet = BrowserNet;
    // static _xmlRequest(reqConfig: ReqConfig, callback: Function) {
    //   const { uri, method, timeout, body } = reqConfig
    //   let hasCallbacked = false
    //   var xhr = new XMLHttpRequest()
    //   xhr.open(method, uri, true)
    //   for (var id in reqConfig.headers) {
    //     xhr.setRequestHeader(id, reqConfig.headers[id])
    //   }
    //   xhr.onload = function () {
    //     if (hasCallbacked) return
    //     hasCallbacked = true
    //     if (xhr.status >= 200 && xhr.status <= 207) {
    //       callback(null, xhr.responseText)
    //     } else {
    //       callback('EC_REQ_FAILED')
    //     }
    //   }
    //   xhr.ontimeout = function () {
    //     if (hasCallbacked) return
    //     hasCallbacked = true
    //     callback('EC_REQ_TIMEOUT')
    //   }
    //   xhr.onerror = function () {
    //     if (hasCallbacked) return
    //     hasCallbacked = true
    //     callback('EC_REQ_FAILED')
    //   }
    //   xhr.timeout = timeout
    //   if (method == 'POST') {
    //     xhr.send(body)
    //   } else {
    //     xhr.send()
    //   }
    // }
    BrowserNet.handleCallback = (resolve, reject, reqData) => {
        const url = reqData.uri;
        const options = reqData;
        options.compress = reqData.gzip;
        delete options.uri;
        delete options.gzip;
        fetch(url, options)
            .then((res) => {
            if (res.status >= 200 && res.status < 300) {
                resolve(res.json());
            }
            else {
                reject('EC_REQ_FAILED');
            }
        })
            .catch((err) => {
            console.log('request failed.', reqData);
            reject(err);
        });
    };
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{".":443,"./utils":444,"buffer":84}],442:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.ServerNet = void 0;
    const _1 = require(".");
    const Utils = require("./utils");
    const node_fetch_1 = require("node-fetch");
    var HttpMethod;
    (function (HttpMethod) {
        HttpMethod["GET"] = "GET";
        HttpMethod["POST"] = "POST";
    })(HttpMethod || (HttpMethod = {}));
    class ServerNet {
        static httpGet(url, params, cb, config) {
            let str = '';
            let cnt = 0;
            for (var id in params) {
                if (cnt != 0)
                    str += '&';
                str += id + '=' + params[id];
                cnt++;
            }
            if (str) {
                url += '?' + str;
            }
            config = config || {};
            let headers = config.headers || {};
            let timeout = config.timeout || _1.Net.timeout;
            let reqData = {
                uri: url,
                method: HttpMethod.GET,
                timeout,
                gzip: true,
                headers,
            };
            if (typeof cb === 'function') {
                this.handleCallback((result) => Utils.invokeCallback(cb, null, result), (err) => Utils.invokeCallback(cb, err), reqData);
                return;
            }
            return new Promise((resolve, reject) => {
                this.handleCallback(resolve, reject, reqData);
            });
        }
        static httpPost(url, params, cb, config) {
            return __awaiter(this, void 0, void 0, function* () {
                let postData;
                config = config || {};
                let headers = config.headers || {};
                let timeout = config.timeout || _1.Net.timeout;
                headers['content-type'] = headers['content-type'] || 'application/json';
                if (headers['content-type'] == 'application/x-www-form-urlencoded') {
                    let arr = [];
                    for (var id in params) {
                        arr.push(`${id}=${params[id]}`);
                    }
                    postData = arr.join('&');
                }
                else if (headers['content-type'] == 'text/plain') {
                    postData = params;
                }
                else {
                    postData = JSON.stringify(params);
                }
                if (headers['content-encoding'] == 'gzip') {
                    postData = yield Utils.gzip(Buffer.from(postData));
                }
                const reqData = {
                    uri: url,
                    method: HttpMethod.POST,
                    body: postData,
                    headers: headers,
                    timeout: timeout,
                    gzip: true,
                };
                if (typeof cb === 'function') {
                    this.handleCallback((result) => Utils.invokeCallback(cb, null, result), (err) => Utils.invokeCallback(cb, err), reqData);
                    return;
                }
                return new Promise((resolve, reject) => {
                    this.handleCallback(resolve, reject, reqData);
                });
            });
        }
    }
    exports.ServerNet = ServerNet;
    ServerNet.handleCallback = (resolve, reject, reqData) => {
        const url = reqData.uri;
        const options = reqData;
        options.compress = reqData.gzip;
        delete options.uri;
        delete options.gzip;
        (0, node_fetch_1.default)(url, options)
            .then((res) => {
            if (res.status >= 200 && res.status < 300) {
                resolve(res.json());
            }
            else {
                console.log('request failed.', reqData);
                reject(new Error(`RequestError: statuCode:${res.statusCode} statusMessage:${res.statusMessage} body:${res.json()}`));
            }
        })
            .catch((err) => {
            console.log('request failed.', reqData);
            reject(err);
        });
    };
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{".":443,"./utils":444,"buffer":84,"node-fetch":288}],443:[function(require,module,exports){
    (function (process){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.Net = void 0;
    const BrowserNet_1 = require("./BrowserNet");
    const ServerNet_1 = require("./ServerNet");
    function toLowerHeader(headers) {
        let newHeaders = {};
        for (var id in headers) {
            let lowerId = id.toLowerCase();
            newHeaders[lowerId] = headers[id];
        }
        return newHeaders;
    }
    class Net {
        static httpGet(url, params, config) {
            if (config && config.headers) {
                config.headers = toLowerHeader(config.headers);
            }
            let _process = process;
            if (!_process.browser) {
                return ServerNet_1.ServerNet.httpGet(url, params, null, config);
            }
            else {
                if (config && config.headers) {
                    //remove unsafe header,should be added in browser
                    delete config.headers['accept-encoding'];
                }
                return BrowserNet_1.BrowserNet.httpGet(url, params, null, config);
            }
        }
        static httpPost(url, params, config) {
            if (config && config.headers) {
                config.headers = toLowerHeader(config.headers);
            }
            let _process = process;
            if (!_process.browser) {
                return ServerNet_1.ServerNet.httpPost(url, params, null, config);
            }
            else {
                if (config && config.headers) {
                    delete config.headers['accept-encoding'];
                }
                return BrowserNet_1.BrowserNet.httpPost(url, params, null, config);
            }
        }
    }
    exports.Net = Net;
    //default timeout
    Net.timeout = 3 * 60 * 1000;
    
    }).call(this)}).call(this,require('_process'))
    
    },{"./BrowserNet":441,"./ServerNet":442,"_process":321}],444:[function(require,module,exports){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.gzip = exports.invokeCallback = void 0;
    const zlib = require("zlib");
    /**
     * Check and invoke callback function
     */
    const invokeCallback = function (...args) {
        let cb = arguments[0];
        if (!!cb && typeof cb === 'function') {
            cb.apply(null, Array.prototype.slice.call(arguments, 1));
        }
    };
    exports.invokeCallback = invokeCallback;
    function gzip(data) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                zlib.gzip(data, (err, val) => {
                    if (err) {
                        reject(err);
                        return;
                    }
                    resolve(val);
                });
            });
        });
    }
    exports.gzip = gzip;
    
    },{"zlib":82}],445:[function(require,module,exports){
    const scryptlib = require('mvc-scrypt');
    module.exports = scryptlib;
    
    },{"mvc-scrypt":282}],446:[function(require,module,exports){
    (function (Buffer){(function (){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TxComposer = exports.sighashType = void 0;
    const mvc = require("../mvc");
    const utils_1 = require("../common/utils");
    const mvc_scrypt_1 = require("mvc-scrypt");
    const Signature = mvc.crypto.Signature;
    exports.sighashType = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID;
    const P2PKH_UNLOCK_SIZE = 1 + 1 + 71 + 1 + 33;
    const P2PKH_DUST_AMOUNT = 1;
    const MIN_FEE_AMOUNT = 56;
    const TX_VERSION = 10;
    class TxComposer {
        constructor(tx) {
            this.sigHashList = [];
            this.changeOutputIndex = -1;
            this.tx = tx || new mvc.Transaction();
            this.tx.version = TX_VERSION;
        }
        toObject() {
            let composer = {
                tx: this.tx.toObject(),
                txPrevOutputs: this.tx.inputs.map((v) => {
                    return v.output ? v.output.toObject() : null;
                }),
                sigHashList: this.sigHashList,
                changeOutputIndex: this.changeOutputIndex,
            };
            return composer;
        }
        serialize() {
            return JSON.stringify(this.toObject());
        }
        static deserialize(composerStr) {
            let composerObj = JSON.parse(composerStr);
            let txObj = composerObj.tx;
            let tx = new mvc.Transaction();
            txObj.inputs.forEach((v, index) => {
                const input = new mvc.Transaction.Input(v);
                if (composerObj.txPrevOutputs[index]) {
                    input.output = new mvc.Transaction.Output(composerObj.txPrevOutputs[index]);
                }
                tx.addInput(new mvc.Transaction.Input(v));
            });
            txObj.outputs.forEach((v) => {
                tx.addOutput(new mvc.Transaction.Output(v));
            });
            tx.nLockTime = txObj.nLockTime;
            tx.version = txObj.version;
            let txComposer = new TxComposer(tx);
            txComposer.sigHashList = composerObj.sigHashList;
            txComposer.changeOutputIndex = composerObj.changeOutputIndex;
            return txComposer;
        }
        static fromObject(composerObj) {
            let txObj = composerObj.tx;
            let tx = new mvc.Transaction();
            txObj.inputs.forEach((v) => {
                tx.addInput(new mvc.Transaction.Input(v));
            });
            txObj.outputs.forEach((v) => {
                tx.addOutput(new mvc.Transaction.Output(v));
            });
            tx.nLockTime = txObj.nLockTime;
            tx.version = txObj.version;
            let txComposer = new TxComposer(tx);
            txComposer.sigHashList = composerObj.sigHashList;
            txComposer.changeOutputIndex = composerObj.changeOutputIndex;
            return txComposer;
        }
        getRawHex() {
            return this.tx.serialize(true);
        }
        getTx() {
            return this.tx;
        }
        getTxId() {
            return this.tx.id;
        }
        getInput(inputIndex) {
            return this.tx.inputs[inputIndex];
        }
        getOutput(outputIndex) {
            return this.tx.outputs[outputIndex];
        }
        appendP2PKHInput(utxo) {
            this.tx.addInput(new mvc.Transaction.Input.PublicKeyHash({
                output: new mvc.Transaction.Output({
                    script: mvc.Script.buildPublicKeyHashOut(utxo.address),
                    satoshis: utxo.satoshis,
                }),
                prevTxId: utxo.txId,
                outputIndex: utxo.outputIndex,
                script: mvc.Script.empty(),
            }));
            const inputIndex = this.tx.inputs.length - 1;
            return inputIndex;
        }
        appendInput(input) {
            this.tx.addInput(new mvc.Transaction.Input({
                output: new mvc.Transaction.Output({
                    script: input.lockingScript,
                    satoshis: input.satoshis,
                }),
                prevTxId: input.txId,
                outputIndex: input.outputIndex,
                script: mvc.Script.empty(),
            }));
            const inputIndex = this.tx.inputs.length - 1;
            return inputIndex;
        }
        appendP2PKHOutput(output) {
            this.tx.addOutput(new mvc.Transaction.Output({
                script: new mvc.Script(output.address),
                satoshis: output.satoshis,
            }));
            const outputIndex = this.tx.outputs.length - 1;
            return outputIndex;
        }
        appendOutput(output) {
            this.tx.addOutput(new mvc.Transaction.Output({
                script: output.lockingScript,
                satoshis: output.satoshis,
            }));
            const outputIndex = this.tx.outputs.length - 1;
            return outputIndex;
        }
        appendOpReturnOutput(opreturnData) {
            this.tx.addOutput(new mvc.Transaction.Output({
                script: mvc.Script.buildSafeDataOut(opreturnData),
                satoshis: 0,
            }));
            const outputIndex = this.tx.outputs.length - 1;
            return outputIndex;
        }
        clearChangeOutput() {
            if (this.changeOutputIndex != -1) {
                this.tx.outputs.splice(this.changeOutputIndex, 1);
                this.changeOutputIndex = 0;
            }
        }
        appendChangeOutput(changeAddress, feeb = 0.05, extraSize = 0) {
            //Calculate the fee and determine whether to change
            //If there is change, it will be output in the last item
            const unlockSize = this.tx.inputs.filter((v) => v.output.script.isPublicKeyHashOut()).length * P2PKH_UNLOCK_SIZE;
            // plus 1 to avoid weird fee calculation mismatch
            let fee = Math.ceil((this.tx.toBuffer().length + unlockSize + extraSize + mvc.Transaction.CHANGE_OUTPUT_MAX_SIZE) * feeb) + 1;
            let changeAmount = this.getUnspentValue() - fee;
            if (changeAmount >= P2PKH_DUST_AMOUNT) {
                this.changeOutputIndex = this.appendP2PKHOutput({
                    address: changeAddress,
                    satoshis: changeAmount,
                });
            }
            else {
                this.changeOutputIndex = -1;
            }
            return this.changeOutputIndex;
        }
        unlockP2PKHInput(privateKey, inputIndex, sigtype = exports.sighashType) {
            const tx = this.tx;
            const sig = new mvc.Transaction.Signature({
                publicKey: privateKey.publicKey,
                prevTxId: tx.inputs[inputIndex].prevTxId,
                outputIndex: tx.inputs[inputIndex].outputIndex,
                inputIndex,
                signature: mvc.Transaction.Sighash.sign(tx, privateKey, sigtype, inputIndex, tx.inputs[inputIndex].output.script, tx.inputs[inputIndex].output.satoshisBN),
                sigtype,
            });
            tx.inputs[inputIndex].setScript(mvc.Script.buildPublicKeyHashIn(sig.publicKey, sig.signature.toDER(), sig.sigtype));
        }
        getTxFormatSig(privateKey, inputIndex, sigtype = exports.sighashType) {
            let sig = (0, mvc_scrypt_1.signTx)(this.tx, privateKey, this.getInput(inputIndex).output.script, this.getInput(inputIndex).output.satoshis, inputIndex, sigtype);
            return sig;
        }
        getInputPreimage(inputIndex, sigtype = exports.sighashType) {
            return (0, mvc_scrypt_1.getPreimage)(this.tx, this.getInput(inputIndex).output.script, this.getInput(inputIndex).output.satoshis, inputIndex, sigtype);
        }
        getUnspentValue() {
            const inputAmount = this.tx.inputs.reduce((pre, cur) => cur.output.satoshis + pre, 0);
            const outputAmount = this.tx.outputs.reduce((pre, cur) => cur.satoshis + pre, 0);
            let unspentAmount = inputAmount - outputAmount;
            return unspentAmount;
        }
        getFeeRate() {
            let unspent = this.getUnspentValue();
            let txSize = this.tx.toBuffer().length;
            return unspent / txSize;
        }
        getSigHashLit() {
            this.sigHashList.forEach((v) => {
                v.sighash = (0, mvc_scrypt_1.toHex)(mvc.Transaction.Sighash.sighash(this.tx, v.sighashType, v.inputIndex, this.getInput(v.inputIndex).output.script, this.getInput(v.inputIndex).output.satoshisBN));
            });
            return this.sigHashList;
        }
        addSigHashInfo({ inputIndex, address, sighashType, contractType, }) {
            this.sigHashList.push({
                inputIndex,
                address,
                sighash: '',
                sighashType,
                contractType,
            });
        }
        getPrevoutsHash() {
            let prevouts = Buffer.alloc(0);
            this.tx.inputs.forEach((input) => {
                const indexBuf = Buffer.alloc(4, 0);
                indexBuf.writeUInt32LE(input.outputIndex);
                prevouts = Buffer.concat([prevouts, Buffer.from(input.prevTxId).reverse(), indexBuf]);
            });
            return mvc.crypto.Hash.sha256sha256(prevouts).toString('hex');
        }
        dumpTx(network) {
            (0, utils_1.dumpTx)(this.tx, network);
        }
    }
    exports.TxComposer = TxComposer;
    
    }).call(this)}).call(this,require("buffer").Buffer)
    
    },{"../common/utils":391,"../mvc":440,"buffer":84,"mvc-scrypt":282}],447:[function(require,module,exports){
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.TxDecoder = exports.OutputType = void 0;
    const proto = require("../common/protoheader");
    const api_1 = require("../api");
    const __1 = require("..");
    var OutputType;
    (function (OutputType) {
        OutputType[OutputType["SENSIBLE_NFT"] = 0] = "SENSIBLE_NFT";
        OutputType[OutputType["SENSIBLE_FT"] = 1] = "SENSIBLE_FT";
        OutputType[OutputType["P2PKH"] = 2] = "P2PKH";
        OutputType[OutputType["OP_RETURN"] = 3] = "OP_RETURN";
        OutputType[OutputType["UNKNOWN"] = 4] = "UNKNOWN";
    })(OutputType = exports.OutputType || (exports.OutputType = {}));
    class TxDecoder {
        static decodeOutput(output, network) {
            let scriptBuf = output.script.toBuffer();
            if (proto.hasProtoFlag(scriptBuf)) {
                let protoType = proto.getProtoType(scriptBuf);
                if (protoType == proto.PROTO_TYPE.NFT) {
                    return {
                        type: OutputType.SENSIBLE_NFT,
                        satoshis: output.satoshis,
                        data: __1.NftManager.parseTokenScript(scriptBuf, network),
                    };
                }
                else if (protoType == proto.PROTO_TYPE.FT) {
                    return {
                        type: OutputType.SENSIBLE_FT,
                        satoshis: output.satoshis,
                        data: __1.FtManager.parseTokenScript(scriptBuf, network),
                    };
                }
                else {
                    return {
                        type: OutputType.UNKNOWN,
                        satoshis: output.satoshis,
                    };
                }
            }
            else if (output.script.isPublicKeyHashOut()) {
                return {
                    type: OutputType.P2PKH,
                    satoshis: output.satoshis,
                    address: output.script.toAddress(network).toString(),
                };
            }
            else if (output.script.isSafeDataOut()) {
                return {
                    type: OutputType.OP_RETURN,
                    satoshis: 0,
                };
            }
            else {
                return {
                    type: OutputType.UNKNOWN,
                    satoshis: output.satoshis,
                };
            }
        }
        static decodeTx(tx, network = api_1.API_NET.MAIN) {
            let inputs = [];
            tx.inputs.forEach((v) => {
                if (v.output) {
                    inputs.push(this.decodeOutput(v.output, network));
                }
            });
            let outputs = [];
            tx.outputs.forEach((v) => {
                outputs.push(this.decodeOutput(v, network));
            });
            let fee = inputs.reduce((pre, cur) => pre + cur.satoshis, 0) -
                outputs.reduce((pre, cur) => pre + cur.satoshis, 0);
            return {
                txId: tx.id,
                inputs,
                outputs,
                fee,
            };
        }
    }
    exports.TxDecoder = TxDecoder;
    
    },{"..":395,"../api":380,"../common/protoheader":389}],448:[function(require,module,exports){
    "use strict";
    var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.Wallet = void 0;
    const mvc = require("../mvc");
    const utils_1 = require("../common/utils");
    const api_1 = require("../api");
    const tx_composer_1 = require("../tx-composer");
    const transactionHelpers_1 = require("../helpers/transactionHelpers");
    class Wallet {
        constructor(wif, network = api_1.API_NET.MAIN, feeb = 1, apiTarget = api_1.API_TARGET.MVC, apiUrl) {
            if (wif) {
                this.privateKey = mvc.PrivateKey.fromWIF(wif);
            }
            else {
                this.privateKey = mvc.PrivateKey.fromRandom(network);
            }
            this.address = this.privateKey.toAddress(network);
            this.blockChainApi = new api_1.Api(network, apiTarget, apiUrl);
            this.feeb = feeb;
            this.network = network;
        }
        get api() {
            return this.blockChainApi;
        }
        getUnspents() {
            return __awaiter(this, void 0, void 0, function* () {
                return yield this.blockChainApi.getUnspents(this.address.toString());
            });
        }
        getUtxos() {
            return __awaiter(this, void 0, void 0, function* () {
                return this.getUnspents();
            });
        }
        getBalance() {
            return __awaiter(this, void 0, void 0, function* () {
                let { pendingBalance, balance } = yield this.blockChainApi.getBalance(this.address.toString());
                return balance + pendingBalance;
            });
        }
        send(address, amount, options) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                let utxos = yield this.blockChainApi.getUnspents(this.address.toString());
                const pickedUtxos = this.pickUtxo(utxos, amount);
                pickedUtxos.forEach((v) => {
                    txComposer.appendP2PKHInput({
                        address: new mvc.Address(v.address, this.network),
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                    });
                });
                txComposer.appendP2PKHOutput({
                    address: new mvc.Address(address, this.network),
                    satoshis: amount,
                });
                txComposer.appendChangeOutput(this.address, this.feeb);
                pickedUtxos.forEach((v, index) => {
                    txComposer.unlockP2PKHInput(this.privateKey, index);
                });
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return yield this.broadcastTxComposer(txComposer, options);
            });
        }
        sendArray(receivers, utxos, options) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                if (!utxos) {
                    utxos = yield this.blockChainApi.getUnspents(this.address.toString());
                }
                utxos.forEach((v) => {
                    txComposer.appendP2PKHInput({
                        address: new mvc.Address(v.address, this.network),
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                    });
                });
                receivers.forEach((v) => {
                    txComposer.appendP2PKHOutput({
                        address: new mvc.Address(v.address, this.network),
                        satoshis: v.amount,
                    });
                });
                txComposer.appendChangeOutput(this.address, this.feeb);
                utxos.forEach((v, index) => {
                    txComposer.unlockP2PKHInput(this.privateKey, index);
                });
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return yield this.broadcastTxComposer(txComposer, options);
            });
        }
        merge(options) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                let utxos = [];
                let currentUtxos = yield this.blockChainApi.getUnspents(this.address.toString());
                while (currentUtxos.length) {
                    utxos = [...utxos, ...currentUtxos];
                    const flag = currentUtxos[currentUtxos.length - 1].flag;
                    currentUtxos = yield this.blockChainApi.getUnspents(this.address.toString(), flag);
                }
                utxos.forEach((v) => {
                    txComposer.appendP2PKHInput({
                        address: new mvc.Address(v.address, this.network),
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                    });
                });
                txComposer.appendChangeOutput(this.address, this.feeb);
                utxos.forEach((v, index) => {
                    txComposer.unlockP2PKHInput(this.privateKey, index);
                });
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return yield this.broadcastTxComposer(txComposer, options);
            });
        }
        // evenly split all amount into utxo shares, this will increase parallel for wallet
        // minShareValue is used to guarantee single share value won't be too small
        // the last share will cover the tx fee
        evenSplit(shares, minShareValue = 0, options) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                const utxos = yield this.blockChainApi.getUnspents(this.address.toString());
                const sumAmount = utxos.map((utxo) => utxo.satoshis).reduce((a, b) => a + b, 0);
                utxos.forEach((v) => {
                    txComposer.appendP2PKHInput({
                        address: new mvc.Address(v.address, this.network),
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                    });
                });
                const shareValue = Math.floor(sumAmount / shares);
                if (shareValue < minShareValue) {
                    throw new Error(`"Share value ${shareValue} is less than minShareValue ${minShareValue}"`);
                }
                for (let i = 0; i < shares - 1; i++) {
                    txComposer.appendP2PKHOutput({ address: this.address, satoshis: shareValue });
                }
                txComposer.appendChangeOutput(this.address, this.feeb);
                utxos.forEach((v, index) => {
                    txComposer.unlockP2PKHInput(this.privateKey, index);
                });
                (0, transactionHelpers_1.checkFeeRate)(txComposer, this.feeb);
                return yield this.broadcastTxComposer(txComposer, options);
            });
        }
        broadcastTxComposer(txComposer, options) {
            return __awaiter(this, void 0, void 0, function* () {
                const { noBroadcast, dump } = options || {};
                if (dump) {
                    (0, utils_1.dumpTx)(txComposer.getTx(), this.network);
                }
                if (noBroadcast) {
                    return {
                        txId: txComposer.getTx().id,
                        txHex: txComposer.getRawHex(),
                    };
                }
                const txId = yield this.blockChainApi.broadcast(txComposer.getRawHex());
                return {
                    txId,
                    txHex: txComposer.getRawHex(),
                };
            });
        }
        sendOpReturn(opreturnData, options) {
            return __awaiter(this, void 0, void 0, function* () {
                const txComposer = new tx_composer_1.TxComposer();
                // pick enough amount for writing opreturn
                const amountRequired = this.feeb * mvc.Script.buildSafeDataOut(opreturnData).getData().length + 100;
                let utxos = yield this.blockChainApi.getUnspents(this.address.toString());
                // pick enough utxo instead of all utxo
                const pickedUtxo = this.pickUtxo(utxos, amountRequired);
                pickedUtxo.forEach((v) => {
                    txComposer.appendP2PKHInput({
                        address: new mvc.Address(v.address, this.network),
                        txId: v.txId,
                        outputIndex: v.outputIndex,
                        satoshis: v.satoshis,
                    });
                });
                txComposer.appendOpReturnOutput(opreturnData);
                txComposer.appendChangeOutput(this.address, this.feeb);
                pickedUtxo.forEach((v, index) => {
                    txComposer.unlockP2PKHInput(this.privateKey, index);
                });
                return yield this.broadcastTxComposer(txComposer, options);
            });
        }
        // pick utxo enough to pay amount and fee, use confirmed utxo in priority
        // shuffle confirmed utxo for higher concurrency
        pickUtxo(utxos, amount) {
            // amount + 2 outputs + buffer
            let requiredAmount = amount + 34 * 2 * this.feeb + 100;
            const candidateUtxos = [];
            // split utxo to confirmed and unconfirmed and shuffle them
            const confirmedUtxos = utxos
                .filter((utxo) => {
                return utxo.height > 0;
            })
                .sort(() => Math.random() - 0.5);
            const unconfirmedUtxos = utxos
                .filter((utxo) => {
                return utxo.height <= 0 || utxo.height === null || utxo.height === undefined;
            })
                .sort(() => Math.random() - 0.5);
            let current = 0;
            // use confirmed first
            for (let utxo of confirmedUtxos) {
                current += Number(utxo.satoshis);
                // add input fee
                requiredAmount += this.feeb * utils_1.P2PKH_UNLOCK_SIZE;
                candidateUtxos.push(utxo);
                if (current > requiredAmount) {
                    return candidateUtxos;
                }
            }
            for (let utxo of unconfirmedUtxos) {
                current += Number(utxo.satoshis);
                // add input fee
                requiredAmount += this.feeb * utils_1.P2PKH_UNLOCK_SIZE;
                candidateUtxos.push(utxo);
                if (current > requiredAmount) {
                    return candidateUtxos;
                }
            }
            return candidateUtxos;
        }
    }
    exports.Wallet = Wallet;
    
    },{"../api":380,"../common/utils":391,"../helpers/transactionHelpers":394,"../mvc":440,"../tx-composer":446}]},{},[396])
    
    var _r=_m(396);_g.MetaIDJs=_r;return _r;})})(typeof window!=='undefined'?window:(typeof global!=='undefined'?global:(typeof self!=='undefined'?self:this)));//# sourceMappingURL=metaid.umd.js.map
    