Greasy Fork

dmzjDecrypt

解析 dmzj v4 api 返回数据

目前为 2023-05-26 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/467177/1195841/dmzjDecrypt.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.dmzjDecrypt = factory());
})(this, (function () {
    var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
    function int2char(n) {
        return BI_RM.charAt(n);
    }
    //#region BIT_OPERATIONS
    // (public) this & a
    function op_and(x, y) {
        return x & y;
    }
    // (public) this | a
    function op_or(x, y) {
        return x | y;
    }
    // (public) this ^ a
    function op_xor(x, y) {
        return x ^ y;
    }
    // (public) this & ~a
    function op_andnot(x, y) {
        return x & ~y;
    }
    // return index of lowest 1-bit in x, x < 2^31
    function lbit(x) {
        if (x == 0) {
            return -1;
        }
        var r = 0;
        if ((x & 0xffff) == 0) {
            x >>= 16;
            r += 16;
        }
        if ((x & 0xff) == 0) {
            x >>= 8;
            r += 8;
        }
        if ((x & 0xf) == 0) {
            x >>= 4;
            r += 4;
        }
        if ((x & 3) == 0) {
            x >>= 2;
            r += 2;
        }
        if ((x & 1) == 0) {
            ++r;
        }
        return r;
    }
    // return number of 1 bits in x
    function cbit(x) {
        var r = 0;
        while (x != 0) {
            x &= x - 1;
            ++r;
        }
        return r;
    }
    //#endregion BIT_OPERATIONS

    // Copyright (c) 2005  Tom Wu
    // Bits per digit
    var dbits;
    // JavaScript engine analysis
    var canary = 0xdeadbeefcafe;
    var j_lm = ((canary & 0xffffff) == 0xefcafe);
    //#region
    var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
    var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
    //#endregion
    // (public) Constructor
    var BigInteger = /** @class */ (function () {
        function BigInteger(a, b, c) {
            if (a != null) {
                if ("number" == typeof a) {
                    this.fromNumber(a, b, c);
                }
                else if (b == null && "string" != typeof a) {
                    this.fromString(a, 256);
                }
                else {
                    this.fromString(a, b);
                }
            }
        }
        //#region PUBLIC
        // BigInteger.prototype.toString = bnToString;
        // (public) return string representation in given radix
        BigInteger.prototype.toString = function (b) {
            if (this.s < 0) {
                return "-" + this.negate().toString(b);
            }
            var k;
            if (b == 16) {
                k = 4;
            }
            else if (b == 8) {
                k = 3;
            }
            else if (b == 2) {
                k = 1;
            }
            else if (b == 32) {
                k = 5;
            }
            else if (b == 4) {
                k = 2;
            }
            else {
                return this.toRadix(b);
            }
            var km = (1 << k) - 1;
            var d;
            var m = false;
            var r = "";
            var i = this.t;
            var p = this.DB - (i * this.DB) % k;
            if (i-- > 0) {
                if (p < this.DB && (d = this[i] >> p) > 0) {
                    m = true;
                    r = int2char(d);
                }
                while (i >= 0) {
                    if (p < k) {
                        d = (this[i] & ((1 << p) - 1)) << (k - p);
                        d |= this[--i] >> (p += this.DB - k);
                    }
                    else {
                        d = (this[i] >> (p -= k)) & km;
                        if (p <= 0) {
                            p += this.DB;
                            --i;
                        }
                    }
                    if (d > 0) {
                        m = true;
                    }
                    if (m) {
                        r += int2char(d);
                    }
                }
            }
            return m ? r : "0";
        };
        // BigInteger.prototype.negate = bnNegate;
        // (public) -this
        BigInteger.prototype.negate = function () {
            var r = nbi();
            BigInteger.ZERO.subTo(this, r);
            return r;
        };
        // BigInteger.prototype.abs = bnAbs;
        // (public) |this|
        BigInteger.prototype.abs = function () {
            return (this.s < 0) ? this.negate() : this;
        };
        // BigInteger.prototype.compareTo = bnCompareTo;
        // (public) return + if this > a, - if this < a, 0 if equal
        BigInteger.prototype.compareTo = function (a) {
            var r = this.s - a.s;
            if (r != 0) {
                return r;
            }
            var i = this.t;
            r = i - a.t;
            if (r != 0) {
                return (this.s < 0) ? -r : r;
            }
            while (--i >= 0) {
                if ((r = this[i] - a[i]) != 0) {
                    return r;
                }
            }
            return 0;
        };
        // BigInteger.prototype.bitLength = bnBitLength;
        // (public) return the number of bits in "this"
        BigInteger.prototype.bitLength = function () {
            if (this.t <= 0) {
                return 0;
            }
            return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
        };
        // BigInteger.prototype.mod = bnMod;
        // (public) this mod a
        BigInteger.prototype.mod = function (a) {
            var r = nbi();
            this.abs().divRemTo(a, null, r);
            if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
                a.subTo(r, r);
            }
            return r;
        };
        // BigInteger.prototype.modPowInt = bnModPowInt;
        // (public) this^e % m, 0 <= e < 2^32
        BigInteger.prototype.modPowInt = function (e, m) {
            var z;
            if (e < 256 || m.isEven()) {
                z = new Classic(m);
            }
            else {
                z = new Montgomery(m);
            }
            return this.exp(e, z);
        };
        // BigInteger.prototype.clone = bnClone;
        // (public)
        BigInteger.prototype.clone = function () {
            var r = nbi();
            this.copyTo(r);
            return r;
        };
        // BigInteger.prototype.intValue = bnIntValue;
        // (public) return value as integer
        BigInteger.prototype.intValue = function () {
            if (this.s < 0) {
                if (this.t == 1) {
                    return this[0] - this.DV;
                }
                else if (this.t == 0) {
                    return -1;
                }
            }
            else if (this.t == 1) {
                return this[0];
            }
            else if (this.t == 0) {
                return 0;
            }
            // assumes 16 < DB < 32
            return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
        };
        // BigInteger.prototype.byteValue = bnByteValue;
        // (public) return value as byte
        BigInteger.prototype.byteValue = function () {
            return (this.t == 0) ? this.s : (this[0] << 24) >> 24;
        };
        // BigInteger.prototype.shortValue = bnShortValue;
        // (public) return value as short (assumes DB>=16)
        BigInteger.prototype.shortValue = function () {
            return (this.t == 0) ? this.s : (this[0] << 16) >> 16;
        };
        // BigInteger.prototype.signum = bnSigNum;
        // (public) 0 if this == 0, 1 if this > 0
        BigInteger.prototype.signum = function () {
            if (this.s < 0) {
                return -1;
            }
            else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
                return 0;
            }
            else {
                return 1;
            }
        };
        // BigInteger.prototype.toByteArray = bnToByteArray;
        // (public) convert to bigendian byte array
        BigInteger.prototype.toByteArray = function () {
            var i = this.t;
            var r = [];
            r[0] = this.s;
            var p = this.DB - (i * this.DB) % 8;
            var d;
            var k = 0;
            if (i-- > 0) {
                if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) {
                    r[k++] = d | (this.s << (this.DB - p));
                }
                while (i >= 0) {
                    if (p < 8) {
                        d = (this[i] & ((1 << p) - 1)) << (8 - p);
                        d |= this[--i] >> (p += this.DB - 8);
                    }
                    else {
                        d = (this[i] >> (p -= 8)) & 0xff;
                        if (p <= 0) {
                            p += this.DB;
                            --i;
                        }
                    }
                    if ((d & 0x80) != 0) {
                        d |= -256;
                    }
                    if (k == 0 && (this.s & 0x80) != (d & 0x80)) {
                        ++k;
                    }
                    if (k > 0 || d != this.s) {
                        r[k++] = d;
                    }
                }
            }
            return r;
        };
        // BigInteger.prototype.equals = bnEquals;
        BigInteger.prototype.equals = function (a) {
            return (this.compareTo(a) == 0);
        };
        // BigInteger.prototype.min = bnMin;
        BigInteger.prototype.min = function (a) {
            return (this.compareTo(a) < 0) ? this : a;
        };
        // BigInteger.prototype.max = bnMax;
        BigInteger.prototype.max = function (a) {
            return (this.compareTo(a) > 0) ? this : a;
        };
        // BigInteger.prototype.and = bnAnd;
        BigInteger.prototype.and = function (a) {
            var r = nbi();
            this.bitwiseTo(a, op_and, r);
            return r;
        };
        // BigInteger.prototype.or = bnOr;
        BigInteger.prototype.or = function (a) {
            var r = nbi();
            this.bitwiseTo(a, op_or, r);
            return r;
        };
        // BigInteger.prototype.xor = bnXor;
        BigInteger.prototype.xor = function (a) {
            var r = nbi();
            this.bitwiseTo(a, op_xor, r);
            return r;
        };
        // BigInteger.prototype.andNot = bnAndNot;
        BigInteger.prototype.andNot = function (a) {
            var r = nbi();
            this.bitwiseTo(a, op_andnot, r);
            return r;
        };
        // BigInteger.prototype.not = bnNot;
        // (public) ~this
        BigInteger.prototype.not = function () {
            var r = nbi();
            for (var i = 0; i < this.t; ++i) {
                r[i] = this.DM & ~this[i];
            }
            r.t = this.t;
            r.s = ~this.s;
            return r;
        };
        // BigInteger.prototype.shiftLeft = bnShiftLeft;
        // (public) this << n
        BigInteger.prototype.shiftLeft = function (n) {
            var r = nbi();
            if (n < 0) {
                this.rShiftTo(-n, r);
            }
            else {
                this.lShiftTo(n, r);
            }
            return r;
        };
        // BigInteger.prototype.shiftRight = bnShiftRight;
        // (public) this >> n
        BigInteger.prototype.shiftRight = function (n) {
            var r = nbi();
            if (n < 0) {
                this.lShiftTo(-n, r);
            }
            else {
                this.rShiftTo(n, r);
            }
            return r;
        };
        // BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
        // (public) returns index of lowest 1-bit (or -1 if none)
        BigInteger.prototype.getLowestSetBit = function () {
            for (var i = 0; i < this.t; ++i) {
                if (this[i] != 0) {
                    return i * this.DB + lbit(this[i]);
                }
            }
            if (this.s < 0) {
                return this.t * this.DB;
            }
            return -1;
        };
        // BigInteger.prototype.bitCount = bnBitCount;
        // (public) return number of set bits
        BigInteger.prototype.bitCount = function () {
            var r = 0;
            var x = this.s & this.DM;
            for (var i = 0; i < this.t; ++i) {
                r += cbit(this[i] ^ x);
            }
            return r;
        };
        // BigInteger.prototype.testBit = bnTestBit;
        // (public) true iff nth bit is set
        BigInteger.prototype.testBit = function (n) {
            var j = Math.floor(n / this.DB);
            if (j >= this.t) {
                return (this.s != 0);
            }
            return ((this[j] & (1 << (n % this.DB))) != 0);
        };
        // BigInteger.prototype.setBit = bnSetBit;
        // (public) this | (1<<n)
        BigInteger.prototype.setBit = function (n) {
            return this.changeBit(n, op_or);
        };
        // BigInteger.prototype.clearBit = bnClearBit;
        // (public) this & ~(1<<n)
        BigInteger.prototype.clearBit = function (n) {
            return this.changeBit(n, op_andnot);
        };
        // BigInteger.prototype.flipBit = bnFlipBit;
        // (public) this ^ (1<<n)
        BigInteger.prototype.flipBit = function (n) {
            return this.changeBit(n, op_xor);
        };
        // BigInteger.prototype.add = bnAdd;
        // (public) this + a
        BigInteger.prototype.add = function (a) {
            var r = nbi();
            this.addTo(a, r);
            return r;
        };
        // BigInteger.prototype.subtract = bnSubtract;
        // (public) this - a
        BigInteger.prototype.subtract = function (a) {
            var r = nbi();
            this.subTo(a, r);
            return r;
        };
        // BigInteger.prototype.multiply = bnMultiply;
        // (public) this * a
        BigInteger.prototype.multiply = function (a) {
            var r = nbi();
            this.multiplyTo(a, r);
            return r;
        };
        // BigInteger.prototype.divide = bnDivide;
        // (public) this / a
        BigInteger.prototype.divide = function (a) {
            var r = nbi();
            this.divRemTo(a, r, null);
            return r;
        };
        // BigInteger.prototype.remainder = bnRemainder;
        // (public) this % a
        BigInteger.prototype.remainder = function (a) {
            var r = nbi();
            this.divRemTo(a, null, r);
            return r;
        };
        // BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
        // (public) [this/a,this%a]
        BigInteger.prototype.divideAndRemainder = function (a) {
            var q = nbi();
            var r = nbi();
            this.divRemTo(a, q, r);
            return [q, r];
        };
        // BigInteger.prototype.modPow = bnModPow;
        // (public) this^e % m (HAC 14.85)
        BigInteger.prototype.modPow = function (e, m) {
            var i = e.bitLength();
            var k;
            var r = nbv(1);
            var z;
            if (i <= 0) {
                return r;
            }
            else if (i < 18) {
                k = 1;
            }
            else if (i < 48) {
                k = 3;
            }
            else if (i < 144) {
                k = 4;
            }
            else if (i < 768) {
                k = 5;
            }
            else {
                k = 6;
            }
            if (i < 8) {
                z = new Classic(m);
            }
            else if (m.isEven()) {
                z = new Barrett(m);
            }
            else {
                z = new Montgomery(m);
            }
            // precomputation
            var g = [];
            var n = 3;
            var k1 = k - 1;
            var km = (1 << k) - 1;
            g[1] = z.convert(this);
            if (k > 1) {
                var g2 = nbi();
                z.sqrTo(g[1], g2);
                while (n <= km) {
                    g[n] = nbi();
                    z.mulTo(g2, g[n - 2], g[n]);
                    n += 2;
                }
            }
            var j = e.t - 1;
            var w;
            var is1 = true;
            var r2 = nbi();
            var t;
            i = nbits(e[j]) - 1;
            while (j >= 0) {
                if (i >= k1) {
                    w = (e[j] >> (i - k1)) & km;
                }
                else {
                    w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
                    if (j > 0) {
                        w |= e[j - 1] >> (this.DB + i - k1);
                    }
                }
                n = k;
                while ((w & 1) == 0) {
                    w >>= 1;
                    --n;
                }
                if ((i -= n) < 0) {
                    i += this.DB;
                    --j;
                }
                if (is1) { // ret == 1, don't bother squaring or multiplying it
                    g[w].copyTo(r);
                    is1 = false;
                }
                else {
                    while (n > 1) {
                        z.sqrTo(r, r2);
                        z.sqrTo(r2, r);
                        n -= 2;
                    }
                    if (n > 0) {
                        z.sqrTo(r, r2);
                    }
                    else {
                        t = r;
                        r = r2;
                        r2 = t;
                    }
                    z.mulTo(r2, g[w], r);
                }
                while (j >= 0 && (e[j] & (1 << i)) == 0) {
                    z.sqrTo(r, r2);
                    t = r;
                    r = r2;
                    r2 = t;
                    if (--i < 0) {
                        i = this.DB - 1;
                        --j;
                    }
                }
            }
            return z.revert(r);
        };
        // BigInteger.prototype.modInverse = bnModInverse;
        // (public) 1/this % m (HAC 14.61)
        BigInteger.prototype.modInverse = function (m) {
            var ac = m.isEven();
            if ((this.isEven() && ac) || m.signum() == 0) {
                return BigInteger.ZERO;
            }
            var u = m.clone();
            var v = this.clone();
            var a = nbv(1);
            var b = nbv(0);
            var c = nbv(0);
            var d = nbv(1);
            while (u.signum() != 0) {
                while (u.isEven()) {
                    u.rShiftTo(1, u);
                    if (ac) {
                        if (!a.isEven() || !b.isEven()) {
                            a.addTo(this, a);
                            b.subTo(m, b);
                        }
                        a.rShiftTo(1, a);
                    }
                    else if (!b.isEven()) {
                        b.subTo(m, b);
                    }
                    b.rShiftTo(1, b);
                }
                while (v.isEven()) {
                    v.rShiftTo(1, v);
                    if (ac) {
                        if (!c.isEven() || !d.isEven()) {
                            c.addTo(this, c);
                            d.subTo(m, d);
                        }
                        c.rShiftTo(1, c);
                    }
                    else if (!d.isEven()) {
                        d.subTo(m, d);
                    }
                    d.rShiftTo(1, d);
                }
                if (u.compareTo(v) >= 0) {
                    u.subTo(v, u);
                    if (ac) {
                        a.subTo(c, a);
                    }
                    b.subTo(d, b);
                }
                else {
                    v.subTo(u, v);
                    if (ac) {
                        c.subTo(a, c);
                    }
                    d.subTo(b, d);
                }
            }
            if (v.compareTo(BigInteger.ONE) != 0) {
                return BigInteger.ZERO;
            }
            if (d.compareTo(m) >= 0) {
                return d.subtract(m);
            }
            if (d.signum() < 0) {
                d.addTo(m, d);
            }
            else {
                return d;
            }
            if (d.signum() < 0) {
                return d.add(m);
            }
            else {
                return d;
            }
        };
        // BigInteger.prototype.pow = bnPow;
        // (public) this^e
        BigInteger.prototype.pow = function (e) {
            return this.exp(e, new NullExp());
        };
        // BigInteger.prototype.gcd = bnGCD;
        // (public) gcd(this,a) (HAC 14.54)
        BigInteger.prototype.gcd = function (a) {
            var x = (this.s < 0) ? this.negate() : this.clone();
            var y = (a.s < 0) ? a.negate() : a.clone();
            if (x.compareTo(y) < 0) {
                var t = x;
                x = y;
                y = t;
            }
            var i = x.getLowestSetBit();
            var g = y.getLowestSetBit();
            if (g < 0) {
                return x;
            }
            if (i < g) {
                g = i;
            }
            if (g > 0) {
                x.rShiftTo(g, x);
                y.rShiftTo(g, y);
            }
            while (x.signum() > 0) {
                if ((i = x.getLowestSetBit()) > 0) {
                    x.rShiftTo(i, x);
                }
                if ((i = y.getLowestSetBit()) > 0) {
                    y.rShiftTo(i, y);
                }
                if (x.compareTo(y) >= 0) {
                    x.subTo(y, x);
                    x.rShiftTo(1, x);
                }
                else {
                    y.subTo(x, y);
                    y.rShiftTo(1, y);
                }
            }
            if (g > 0) {
                y.lShiftTo(g, y);
            }
            return y;
        };
        // BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
        // (public) test primality with certainty >= 1-.5^t
        BigInteger.prototype.isProbablePrime = function (t) {
            var i;
            var x = this.abs();
            if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
                for (i = 0; i < lowprimes.length; ++i) {
                    if (x[0] == lowprimes[i]) {
                        return true;
                    }
                }
                return false;
            }
            if (x.isEven()) {
                return false;
            }
            i = 1;
            while (i < lowprimes.length) {
                var m = lowprimes[i];
                var j = i + 1;
                while (j < lowprimes.length && m < lplim) {
                    m *= lowprimes[j++];
                }
                m = x.modInt(m);
                while (i < j) {
                    if (m % lowprimes[i++] == 0) {
                        return false;
                    }
                }
            }
            return x.millerRabin(t);
        };
        //#endregion PUBLIC
        //#region PROTECTED
        // BigInteger.prototype.copyTo = bnpCopyTo;
        // (protected) copy this to r
        BigInteger.prototype.copyTo = function (r) {
            for (var i = this.t - 1; i >= 0; --i) {
                r[i] = this[i];
            }
            r.t = this.t;
            r.s = this.s;
        };
        // BigInteger.prototype.fromInt = bnpFromInt;
        // (protected) set from integer value x, -DV <= x < DV
        BigInteger.prototype.fromInt = function (x) {
            this.t = 1;
            this.s = (x < 0) ? -1 : 0;
            if (x > 0) {
                this[0] = x;
            }
            else if (x < -1) {
                this[0] = x + this.DV;
            }
            else {
                this.t = 0;
            }
        };
        // BigInteger.prototype.fromString = bnpFromString;
        // (protected) set from string and radix
        BigInteger.prototype.fromString = function (s, b) {
            var k;
            if (b == 16) {
                k = 4;
            }
            else if (b == 8) {
                k = 3;
            }
            else if (b == 256) {
                k = 8;
                /* byte array */
            }
            else if (b == 2) {
                k = 1;
            }
            else if (b == 32) {
                k = 5;
            }
            else if (b == 4) {
                k = 2;
            }
            else {
                this.fromRadix(s, b);
                return;
            }
            this.t = 0;
            this.s = 0;
            var i = s.length;
            var mi = false;
            var sh = 0;
            while (--i >= 0) {
                var x = (k == 8) ? (+s[i]) & 0xff : intAt(s, i);
                if (x < 0) {
                    if (s.charAt(i) == "-") {
                        mi = true;
                    }
                    continue;
                }
                mi = false;
                if (sh == 0) {
                    this[this.t++] = x;
                }
                else if (sh + k > this.DB) {
                    this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
                    this[this.t++] = (x >> (this.DB - sh));
                }
                else {
                    this[this.t - 1] |= x << sh;
                }
                sh += k;
                if (sh >= this.DB) {
                    sh -= this.DB;
                }
            }
            if (k == 8 && ((+s[0]) & 0x80) != 0) {
                this.s = -1;
                if (sh > 0) {
                    this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
                }
            }
            this.clamp();
            if (mi) {
                BigInteger.ZERO.subTo(this, this);
            }
        };
        // BigInteger.prototype.clamp = bnpClamp;
        // (protected) clamp off excess high words
        BigInteger.prototype.clamp = function () {
            var c = this.s & this.DM;
            while (this.t > 0 && this[this.t - 1] == c) {
                --this.t;
            }
        };
        // BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
        // (protected) r = this << n*DB
        BigInteger.prototype.dlShiftTo = function (n, r) {
            var i;
            for (i = this.t - 1; i >= 0; --i) {
                r[i + n] = this[i];
            }
            for (i = n - 1; i >= 0; --i) {
                r[i] = 0;
            }
            r.t = this.t + n;
            r.s = this.s;
        };
        // BigInteger.prototype.drShiftTo = bnpDRShiftTo;
        // (protected) r = this >> n*DB
        BigInteger.prototype.drShiftTo = function (n, r) {
            for (var i = n; i < this.t; ++i) {
                r[i - n] = this[i];
            }
            r.t = Math.max(this.t - n, 0);
            r.s = this.s;
        };
        // BigInteger.prototype.lShiftTo = bnpLShiftTo;
        // (protected) r = this << n
        BigInteger.prototype.lShiftTo = function (n, r) {
            var bs = n % this.DB;
            var cbs = this.DB - bs;
            var bm = (1 << cbs) - 1;
            var ds = Math.floor(n / this.DB);
            var c = (this.s << bs) & this.DM;
            for (var i = this.t - 1; i >= 0; --i) {
                r[i + ds + 1] = (this[i] >> cbs) | c;
                c = (this[i] & bm) << bs;
            }
            for (var i = ds - 1; i >= 0; --i) {
                r[i] = 0;
            }
            r[ds] = c;
            r.t = this.t + ds + 1;
            r.s = this.s;
            r.clamp();
        };
        // BigInteger.prototype.rShiftTo = bnpRShiftTo;
        // (protected) r = this >> n
        BigInteger.prototype.rShiftTo = function (n, r) {
            r.s = this.s;
            var ds = Math.floor(n / this.DB);
            if (ds >= this.t) {
                r.t = 0;
                return;
            }
            var bs = n % this.DB;
            var cbs = this.DB - bs;
            var bm = (1 << bs) - 1;
            r[0] = this[ds] >> bs;
            for (var i = ds + 1; i < this.t; ++i) {
                r[i - ds - 1] |= (this[i] & bm) << cbs;
                r[i - ds] = this[i] >> bs;
            }
            if (bs > 0) {
                r[this.t - ds - 1] |= (this.s & bm) << cbs;
            }
            r.t = this.t - ds;
            r.clamp();
        };
        // BigInteger.prototype.subTo = bnpSubTo;
        // (protected) r = this - a
        BigInteger.prototype.subTo = function (a, r) {
            var i = 0;
            var c = 0;
            var m = Math.min(a.t, this.t);
            while (i < m) {
                c += this[i] - a[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            if (a.t < this.t) {
                c -= a.s;
                while (i < this.t) {
                    c += this[i];
                    r[i++] = c & this.DM;
                    c >>= this.DB;
                }
                c += this.s;
            }
            else {
                c += this.s;
                while (i < a.t) {
                    c -= a[i];
                    r[i++] = c & this.DM;
                    c >>= this.DB;
                }
                c -= a.s;
            }
            r.s = (c < 0) ? -1 : 0;
            if (c < -1) {
                r[i++] = this.DV + c;
            }
            else if (c > 0) {
                r[i++] = c;
            }
            r.t = i;
            r.clamp();
        };
        // BigInteger.prototype.multiplyTo = bnpMultiplyTo;
        // (protected) r = this * a, r != this,a (HAC 14.12)
        // "this" should be the larger one if appropriate.
        BigInteger.prototype.multiplyTo = function (a, r) {
            var x = this.abs();
            var y = a.abs();
            var i = x.t;
            r.t = i + y.t;
            while (--i >= 0) {
                r[i] = 0;
            }
            for (i = 0; i < y.t; ++i) {
                r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
            }
            r.s = 0;
            r.clamp();
            if (this.s != a.s) {
                BigInteger.ZERO.subTo(r, r);
            }
        };
        // BigInteger.prototype.squareTo = bnpSquareTo;
        // (protected) r = this^2, r != this (HAC 14.16)
        BigInteger.prototype.squareTo = function (r) {
            var x = this.abs();
            var i = r.t = 2 * x.t;
            while (--i >= 0) {
                r[i] = 0;
            }
            for (i = 0; i < x.t - 1; ++i) {
                var c = x.am(i, x[i], r, 2 * i, 0, 1);
                if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
                    r[i + x.t] -= x.DV;
                    r[i + x.t + 1] = 1;
                }
            }
            if (r.t > 0) {
                r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
            }
            r.s = 0;
            r.clamp();
        };
        // BigInteger.prototype.divRemTo = bnpDivRemTo;
        // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
        // r != q, this != m.  q or r may be null.
        BigInteger.prototype.divRemTo = function (m, q, r) {
            var pm = m.abs();
            if (pm.t <= 0) {
                return;
            }
            var pt = this.abs();
            if (pt.t < pm.t) {
                if (q != null) {
                    q.fromInt(0);
                }
                if (r != null) {
                    this.copyTo(r);
                }
                return;
            }
            if (r == null) {
                r = nbi();
            }
            var y = nbi();
            var ts = this.s;
            var ms = m.s;
            var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
            if (nsh > 0) {
                pm.lShiftTo(nsh, y);
                pt.lShiftTo(nsh, r);
            }
            else {
                pm.copyTo(y);
                pt.copyTo(r);
            }
            var ys = y.t;
            var y0 = y[ys - 1];
            if (y0 == 0) {
                return;
            }
            var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
            var d1 = this.FV / yt;
            var d2 = (1 << this.F1) / yt;
            var e = 1 << this.F2;
            var i = r.t;
            var j = i - ys;
            var t = (q == null) ? nbi() : q;
            y.dlShiftTo(j, t);
            if (r.compareTo(t) >= 0) {
                r[r.t++] = 1;
                r.subTo(t, r);
            }
            BigInteger.ONE.dlShiftTo(ys, t);
            t.subTo(y, y); // "negative" y so we can replace sub with am later
            while (y.t < ys) {
                y[y.t++] = 0;
            }
            while (--j >= 0) {
                // Estimate quotient digit
                var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
                if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
                    y.dlShiftTo(j, t);
                    r.subTo(t, r);
                    while (r[i] < --qd) {
                        r.subTo(t, r);
                    }
                }
            }
            if (q != null) {
                r.drShiftTo(ys, q);
                if (ts != ms) {
                    BigInteger.ZERO.subTo(q, q);
                }
            }
            r.t = ys;
            r.clamp();
            if (nsh > 0) {
                r.rShiftTo(nsh, r);
            } // Denormalize remainder
            if (ts < 0) {
                BigInteger.ZERO.subTo(r, r);
            }
        };
        // BigInteger.prototype.invDigit = bnpInvDigit;
        // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
        // justification:
        //         xy == 1 (mod m)
        //         xy =  1+km
        //   xy(2-xy) = (1+km)(1-km)
        // x[y(2-xy)] = 1-k^2m^2
        // x[y(2-xy)] == 1 (mod m^2)
        // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
        // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
        // JS multiply "overflows" differently from C/C++, so care is needed here.
        BigInteger.prototype.invDigit = function () {
            if (this.t < 1) {
                return 0;
            }
            var x = this[0];
            if ((x & 1) == 0) {
                return 0;
            }
            var y = x & 3; // y == 1/x mod 2^2
            y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
            y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
            y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
            // last step - calculate inverse mod DV directly;
            // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
            y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
            // we really want the negative inverse, and -DV < y < DV
            return (y > 0) ? this.DV - y : -y;
        };
        // BigInteger.prototype.isEven = bnpIsEven;
        // (protected) true iff this is even
        BigInteger.prototype.isEven = function () {
            return ((this.t > 0) ? (this[0] & 1) : this.s) == 0;
        };
        // BigInteger.prototype.exp = bnpExp;
        // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
        BigInteger.prototype.exp = function (e, z) {
            if (e > 0xffffffff || e < 1) {
                return BigInteger.ONE;
            }
            var r = nbi();
            var r2 = nbi();
            var g = z.convert(this);
            var i = nbits(e) - 1;
            g.copyTo(r);
            while (--i >= 0) {
                z.sqrTo(r, r2);
                if ((e & (1 << i)) > 0) {
                    z.mulTo(r2, g, r);
                }
                else {
                    var t = r;
                    r = r2;
                    r2 = t;
                }
            }
            return z.revert(r);
        };
        // BigInteger.prototype.chunkSize = bnpChunkSize;
        // (protected) return x s.t. r^x < DV
        BigInteger.prototype.chunkSize = function (r) {
            return Math.floor(Math.LN2 * this.DB / Math.log(r));
        };
        // BigInteger.prototype.toRadix = bnpToRadix;
        // (protected) convert to radix string
        BigInteger.prototype.toRadix = function (b) {
            if (b == null) {
                b = 10;
            }
            if (this.signum() == 0 || b < 2 || b > 36) {
                return "0";
            }
            var cs = this.chunkSize(b);
            var a = Math.pow(b, cs);
            var d = nbv(a);
            var y = nbi();
            var z = nbi();
            var r = "";
            this.divRemTo(d, y, z);
            while (y.signum() > 0) {
                r = (a + z.intValue()).toString(b).substr(1) + r;
                y.divRemTo(d, y, z);
            }
            return z.intValue().toString(b) + r;
        };
        // BigInteger.prototype.fromRadix = bnpFromRadix;
        // (protected) convert from radix string
        BigInteger.prototype.fromRadix = function (s, b) {
            this.fromInt(0);
            if (b == null) {
                b = 10;
            }
            var cs = this.chunkSize(b);
            var d = Math.pow(b, cs);
            var mi = false;
            var j = 0;
            var w = 0;
            for (var i = 0; i < s.length; ++i) {
                var x = intAt(s, i);
                if (x < 0) {
                    if (s.charAt(i) == "-" && this.signum() == 0) {
                        mi = true;
                    }
                    continue;
                }
                w = b * w + x;
                if (++j >= cs) {
                    this.dMultiply(d);
                    this.dAddOffset(w, 0);
                    j = 0;
                    w = 0;
                }
            }
            if (j > 0) {
                this.dMultiply(Math.pow(b, j));
                this.dAddOffset(w, 0);
            }
            if (mi) {
                BigInteger.ZERO.subTo(this, this);
            }
        };
        // BigInteger.prototype.fromNumber = bnpFromNumber;
        // (protected) alternate constructor
        BigInteger.prototype.fromNumber = function (a, b, c) {
            if ("number" == typeof b) {
                // new BigInteger(int,int,RNG)
                if (a < 2) {
                    this.fromInt(1);
                }
                else {
                    this.fromNumber(a, c);
                    if (!this.testBit(a - 1)) {
                        // force MSB set
                        this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
                    }
                    if (this.isEven()) {
                        this.dAddOffset(1, 0);
                    } // force odd
                    while (!this.isProbablePrime(b)) {
                        this.dAddOffset(2, 0);
                        if (this.bitLength() > a) {
                            this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
                        }
                    }
                }
            }
            else {
                // new BigInteger(int,RNG)
                var x = [];
                var t = a & 7;
                x.length = (a >> 3) + 1;
                b.nextBytes(x);
                if (t > 0) {
                    x[0] &= ((1 << t) - 1);
                }
                else {
                    x[0] = 0;
                }
                this.fromString(x, 256);
            }
        };
        // BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
        // (protected) r = this op a (bitwise)
        BigInteger.prototype.bitwiseTo = function (a, op, r) {
            var i;
            var f;
            var m = Math.min(a.t, this.t);
            for (i = 0; i < m; ++i) {
                r[i] = op(this[i], a[i]);
            }
            if (a.t < this.t) {
                f = a.s & this.DM;
                for (i = m; i < this.t; ++i) {
                    r[i] = op(this[i], f);
                }
                r.t = this.t;
            }
            else {
                f = this.s & this.DM;
                for (i = m; i < a.t; ++i) {
                    r[i] = op(f, a[i]);
                }
                r.t = a.t;
            }
            r.s = op(this.s, a.s);
            r.clamp();
        };
        // BigInteger.prototype.changeBit = bnpChangeBit;
        // (protected) this op (1<<n)
        BigInteger.prototype.changeBit = function (n, op) {
            var r = BigInteger.ONE.shiftLeft(n);
            this.bitwiseTo(r, op, r);
            return r;
        };
        // BigInteger.prototype.addTo = bnpAddTo;
        // (protected) r = this + a
        BigInteger.prototype.addTo = function (a, r) {
            var i = 0;
            var c = 0;
            var m = Math.min(a.t, this.t);
            while (i < m) {
                c += this[i] + a[i];
                r[i++] = c & this.DM;
                c >>= this.DB;
            }
            if (a.t < this.t) {
                c += a.s;
                while (i < this.t) {
                    c += this[i];
                    r[i++] = c & this.DM;
                    c >>= this.DB;
                }
                c += this.s;
            }
            else {
                c += this.s;
                while (i < a.t) {
                    c += a[i];
                    r[i++] = c & this.DM;
                    c >>= this.DB;
                }
                c += a.s;
            }
            r.s = (c < 0) ? -1 : 0;
            if (c > 0) {
                r[i++] = c;
            }
            else if (c < -1) {
                r[i++] = this.DV + c;
            }
            r.t = i;
            r.clamp();
        };
        // BigInteger.prototype.dMultiply = bnpDMultiply;
        // (protected) this *= n, this >= 0, 1 < n < DV
        BigInteger.prototype.dMultiply = function (n) {
            this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
            ++this.t;
            this.clamp();
        };
        // BigInteger.prototype.dAddOffset = bnpDAddOffset;
        // (protected) this += n << w words, this >= 0
        BigInteger.prototype.dAddOffset = function (n, w) {
            if (n == 0) {
                return;
            }
            while (this.t <= w) {
                this[this.t++] = 0;
            }
            this[w] += n;
            while (this[w] >= this.DV) {
                this[w] -= this.DV;
                if (++w >= this.t) {
                    this[this.t++] = 0;
                }
                ++this[w];
            }
        };
        // BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
        // (protected) r = lower n words of "this * a", a.t <= n
        // "this" should be the larger one if appropriate.
        BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
            var i = Math.min(this.t + a.t, n);
            r.s = 0; // assumes a,this >= 0
            r.t = i;
            while (i > 0) {
                r[--i] = 0;
            }
            for (var j = r.t - this.t; i < j; ++i) {
                r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
            }
            for (var j = Math.min(a.t, n); i < j; ++i) {
                this.am(0, a[i], r, i, 0, n - i);
            }
            r.clamp();
        };
        // BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
        // (protected) r = "this * a" without lower n words, n > 0
        // "this" should be the larger one if appropriate.
        BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
            --n;
            var i = r.t = this.t + a.t - n;
            r.s = 0; // assumes a,this >= 0
            while (--i >= 0) {
                r[i] = 0;
            }
            for (i = Math.max(n - this.t, 0); i < a.t; ++i) {
                r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
            }
            r.clamp();
            r.drShiftTo(1, r);
        };
        // BigInteger.prototype.modInt = bnpModInt;
        // (protected) this % n, n < 2^26
        BigInteger.prototype.modInt = function (n) {
            if (n <= 0) {
                return 0;
            }
            var d = this.DV % n;
            var r = (this.s < 0) ? n - 1 : 0;
            if (this.t > 0) {
                if (d == 0) {
                    r = this[0] % n;
                }
                else {
                    for (var i = this.t - 1; i >= 0; --i) {
                        r = (d * r + this[i]) % n;
                    }
                }
            }
            return r;
        };
        // BigInteger.prototype.millerRabin = bnpMillerRabin;
        // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
        BigInteger.prototype.millerRabin = function (t) {
            var n1 = this.subtract(BigInteger.ONE);
            var k = n1.getLowestSetBit();
            if (k <= 0) {
                return false;
            }
            var r = n1.shiftRight(k);
            t = (t + 1) >> 1;
            if (t > lowprimes.length) {
                t = lowprimes.length;
            }
            var a = nbi();
            for (var i = 0; i < t; ++i) {
                // Pick bases at random, instead of starting at 2
                a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
                var y = a.modPow(r, this);
                if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
                    var j = 1;
                    while (j++ < k && y.compareTo(n1) != 0) {
                        y = y.modPowInt(2, this);
                        if (y.compareTo(BigInteger.ONE) == 0) {
                            return false;
                        }
                    }
                    if (y.compareTo(n1) != 0) {
                        return false;
                    }
                }
            }
            return true;
        };
        // BigInteger.prototype.square = bnSquare;
        // (public) this^2
        BigInteger.prototype.square = function () {
            var r = nbi();
            this.squareTo(r);
            return r;
        };
        //#region ASYNC
        // Public API method
        BigInteger.prototype.gcda = function (a, callback) {
            var x = (this.s < 0) ? this.negate() : this.clone();
            var y = (a.s < 0) ? a.negate() : a.clone();
            if (x.compareTo(y) < 0) {
                var t = x;
                x = y;
                y = t;
            }
            var i = x.getLowestSetBit();
            var g = y.getLowestSetBit();
            if (g < 0) {
                callback(x);
                return;
            }
            if (i < g) {
                g = i;
            }
            if (g > 0) {
                x.rShiftTo(g, x);
                y.rShiftTo(g, y);
            }
            // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
            var gcda1 = function () {
                if ((i = x.getLowestSetBit()) > 0) {
                    x.rShiftTo(i, x);
                }
                if ((i = y.getLowestSetBit()) > 0) {
                    y.rShiftTo(i, y);
                }
                if (x.compareTo(y) >= 0) {
                    x.subTo(y, x);
                    x.rShiftTo(1, x);
                }
                else {
                    y.subTo(x, y);
                    y.rShiftTo(1, y);
                }
                if (!(x.signum() > 0)) {
                    if (g > 0) {
                        y.lShiftTo(g, y);
                    }
                    setTimeout(function () { callback(y); }, 0); // escape
                }
                else {
                    setTimeout(gcda1, 0);
                }
            };
            setTimeout(gcda1, 10);
        };
        // (protected) alternate constructor
        BigInteger.prototype.fromNumberAsync = function (a, b, c, callback) {
            if ("number" == typeof b) {
                if (a < 2) {
                    this.fromInt(1);
                }
                else {
                    this.fromNumber(a, c);
                    if (!this.testBit(a - 1)) {
                        this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
                    }
                    if (this.isEven()) {
                        this.dAddOffset(1, 0);
                    }
                    var bnp_1 = this;
                    var bnpfn1_1 = function () {
                        bnp_1.dAddOffset(2, 0);
                        if (bnp_1.bitLength() > a) {
                            bnp_1.subTo(BigInteger.ONE.shiftLeft(a - 1), bnp_1);
                        }
                        if (bnp_1.isProbablePrime(b)) {
                            setTimeout(function () { callback(); }, 0); // escape
                        }
                        else {
                            setTimeout(bnpfn1_1, 0);
                        }
                    };
                    setTimeout(bnpfn1_1, 0);
                }
            }
            else {
                var x = [];
                var t = a & 7;
                x.length = (a >> 3) + 1;
                b.nextBytes(x);
                if (t > 0) {
                    x[0] &= ((1 << t) - 1);
                }
                else {
                    x[0] = 0;
                }
                this.fromString(x, 256);
            }
        };
        return BigInteger;
    }());
    //#region REDUCERS
    //#region NullExp
    var NullExp = /** @class */ (function () {
        function NullExp() {
        }
        // NullExp.prototype.convert = nNop;
        NullExp.prototype.convert = function (x) {
            return x;
        };
        // NullExp.prototype.revert = nNop;
        NullExp.prototype.revert = function (x) {
            return x;
        };
        // NullExp.prototype.mulTo = nMulTo;
        NullExp.prototype.mulTo = function (x, y, r) {
            x.multiplyTo(y, r);
        };
        // NullExp.prototype.sqrTo = nSqrTo;
        NullExp.prototype.sqrTo = function (x, r) {
            x.squareTo(r);
        };
        return NullExp;
    }());
    // Modular reduction using "classic" algorithm
    var Classic = /** @class */ (function () {
        function Classic(m) {
            this.m = m;
        }
        // Classic.prototype.convert = cConvert;
        Classic.prototype.convert = function (x) {
            if (x.s < 0 || x.compareTo(this.m) >= 0) {
                return x.mod(this.m);
            }
            else {
                return x;
            }
        };
        // Classic.prototype.revert = cRevert;
        Classic.prototype.revert = function (x) {
            return x;
        };
        // Classic.prototype.reduce = cReduce;
        Classic.prototype.reduce = function (x) {
            x.divRemTo(this.m, null, x);
        };
        // Classic.prototype.mulTo = cMulTo;
        Classic.prototype.mulTo = function (x, y, r) {
            x.multiplyTo(y, r);
            this.reduce(r);
        };
        // Classic.prototype.sqrTo = cSqrTo;
        Classic.prototype.sqrTo = function (x, r) {
            x.squareTo(r);
            this.reduce(r);
        };
        return Classic;
    }());
    //#endregion
    //#region Montgomery
    // Montgomery reduction
    var Montgomery = /** @class */ (function () {
        function Montgomery(m) {
            this.m = m;
            this.mp = m.invDigit();
            this.mpl = this.mp & 0x7fff;
            this.mph = this.mp >> 15;
            this.um = (1 << (m.DB - 15)) - 1;
            this.mt2 = 2 * m.t;
        }
        // Montgomery.prototype.convert = montConvert;
        // xR mod m
        Montgomery.prototype.convert = function (x) {
            var r = nbi();
            x.abs().dlShiftTo(this.m.t, r);
            r.divRemTo(this.m, null, r);
            if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
                this.m.subTo(r, r);
            }
            return r;
        };
        // Montgomery.prototype.revert = montRevert;
        // x/R mod m
        Montgomery.prototype.revert = function (x) {
            var r = nbi();
            x.copyTo(r);
            this.reduce(r);
            return r;
        };
        // Montgomery.prototype.reduce = montReduce;
        // x = x/R mod m (HAC 14.32)
        Montgomery.prototype.reduce = function (x) {
            while (x.t <= this.mt2) {
                // pad x so am has enough room later
                x[x.t++] = 0;
            }
            for (var i = 0; i < this.m.t; ++i) {
                // faster way of calculating u0 = x[i]*mp mod DV
                var j = x[i] & 0x7fff;
                var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
                // use am to combine the multiply-shift-add into one call
                j = i + this.m.t;
                x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
                // propagate carry
                while (x[j] >= x.DV) {
                    x[j] -= x.DV;
                    x[++j]++;
                }
            }
            x.clamp();
            x.drShiftTo(this.m.t, x);
            if (x.compareTo(this.m) >= 0) {
                x.subTo(this.m, x);
            }
        };
        // Montgomery.prototype.mulTo = montMulTo;
        // r = "xy/R mod m"; x,y != r
        Montgomery.prototype.mulTo = function (x, y, r) {
            x.multiplyTo(y, r);
            this.reduce(r);
        };
        // Montgomery.prototype.sqrTo = montSqrTo;
        // r = "x^2/R mod m"; x != r
        Montgomery.prototype.sqrTo = function (x, r) {
            x.squareTo(r);
            this.reduce(r);
        };
        return Montgomery;
    }());
    //#endregion Montgomery
    //#region Barrett
    // Barrett modular reduction
    var Barrett = /** @class */ (function () {
        function Barrett(m) {
            this.m = m;
            // setup Barrett
            this.r2 = nbi();
            this.q3 = nbi();
            BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
            this.mu = this.r2.divide(m);
        }
        // Barrett.prototype.convert = barrettConvert;
        Barrett.prototype.convert = function (x) {
            if (x.s < 0 || x.t > 2 * this.m.t) {
                return x.mod(this.m);
            }
            else if (x.compareTo(this.m) < 0) {
                return x;
            }
            else {
                var r = nbi();
                x.copyTo(r);
                this.reduce(r);
                return r;
            }
        };
        // Barrett.prototype.revert = barrettRevert;
        Barrett.prototype.revert = function (x) {
            return x;
        };
        // Barrett.prototype.reduce = barrettReduce;
        // x = x mod m (HAC 14.42)
        Barrett.prototype.reduce = function (x) {
            x.drShiftTo(this.m.t - 1, this.r2);
            if (x.t > this.m.t + 1) {
                x.t = this.m.t + 1;
                x.clamp();
            }
            this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
            this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
            while (x.compareTo(this.r2) < 0) {
                x.dAddOffset(1, this.m.t + 1);
            }
            x.subTo(this.r2, x);
            while (x.compareTo(this.m) >= 0) {
                x.subTo(this.m, x);
            }
        };
        // Barrett.prototype.mulTo = barrettMulTo;
        // r = x*y mod m; x,y != r
        Barrett.prototype.mulTo = function (x, y, r) {
            x.multiplyTo(y, r);
            this.reduce(r);
        };
        // Barrett.prototype.sqrTo = barrettSqrTo;
        // r = x^2 mod m; x != r
        Barrett.prototype.sqrTo = function (x, r) {
            x.squareTo(r);
            this.reduce(r);
        };
        return Barrett;
    }());
    //#endregion
    //#endregion REDUCERS
    // return new, unset BigInteger
    function nbi() { return new BigInteger(null); }
    function parseBigInt(str, r) {
        return new BigInteger(str, r);
    }
    // am: Compute w_j += (x*this_i), propagate carries,
    // c is initial carry, returns final carry.
    // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
    // We need to select the fastest one that works in this environment.
    var inBrowser = typeof navigator !== "undefined";
    if (inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
        // am2 avoids a big mult-and-extract completely.
        // Max digit bits should be <= 30 because we do bitwise ops
        // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
        BigInteger.prototype.am = function am2(i, x, w, j, c, n) {
            var xl = x & 0x7fff;
            var xh = x >> 15;
            while (--n >= 0) {
                var l = this[i] & 0x7fff;
                var h = this[i++] >> 15;
                var m = xh * l + h * xl;
                l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
                c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
                w[j++] = l & 0x3fffffff;
            }
            return c;
        };
        dbits = 30;
    }
    else if (inBrowser && j_lm && (navigator.appName != "Netscape")) {
        // am1: use a single mult and divide to get the high bits,
        // max digit bits should be 26 because
        // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
        BigInteger.prototype.am = function am1(i, x, w, j, c, n) {
            while (--n >= 0) {
                var v = x * this[i++] + w[j] + c;
                c = Math.floor(v / 0x4000000);
                w[j++] = v & 0x3ffffff;
            }
            return c;
        };
        dbits = 26;
    }
    else { // Mozilla/Netscape seems to prefer am3
        // Alternately, set max digit bits to 28 since some
        // browsers slow down when dealing with 32-bit numbers.
        BigInteger.prototype.am = function am3(i, x, w, j, c, n) {
            var xl = x & 0x3fff;
            var xh = x >> 14;
            while (--n >= 0) {
                var l = this[i] & 0x3fff;
                var h = this[i++] >> 14;
                var m = xh * l + h * xl;
                l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
                c = (l >> 28) + (m >> 14) + xh * h;
                w[j++] = l & 0xfffffff;
            }
            return c;
        };
        dbits = 28;
    }
    BigInteger.prototype.DB = dbits;
    BigInteger.prototype.DM = ((1 << dbits) - 1);
    BigInteger.prototype.DV = (1 << dbits);
    var BI_FP = 52;
    BigInteger.prototype.FV = Math.pow(2, BI_FP);
    BigInteger.prototype.F1 = BI_FP - dbits;
    BigInteger.prototype.F2 = 2 * dbits - BI_FP;
    // Digit conversions
    var BI_RC = [];
    var rr;
    var vv;
    rr = "0".charCodeAt(0);
    for (vv = 0; vv <= 9; ++vv) {
        BI_RC[rr++] = vv;
    }
    rr = "a".charCodeAt(0);
    for (vv = 10; vv < 36; ++vv) {
        BI_RC[rr++] = vv;
    }
    rr = "A".charCodeAt(0);
    for (vv = 10; vv < 36; ++vv) {
        BI_RC[rr++] = vv;
    }
    function intAt(s, i) {
        var c = BI_RC[s.charCodeAt(i)];
        return (c == null) ? -1 : c;
    }
    // return bigint initialized to value
    function nbv(i) {
        var r = nbi();
        r.fromInt(i);
        return r;
    }
    // returns bit length of the integer x
    function nbits(x) {
        var r = 1;
        var t;
        if ((t = x >>> 16) != 0) {
            x = t;
            r += 16;
        }
        if ((t = x >> 8) != 0) {
            x = t;
            r += 8;
        }
        if ((t = x >> 4) != 0) {
            x = t;
            r += 4;
        }
        if ((t = x >> 2) != 0) {
            x = t;
            r += 2;
        }
        if ((t = x >> 1) != 0) {
            x = t;
            r += 1;
        }
        return r;
    }
    // "constants"
    BigInteger.ZERO = nbv(0);
    BigInteger.ONE = nbv(1);

    var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var b64pad = "=";
    function hex2b64(h) {
        var i;
        var c;
        var ret = "";
        for (i = 0; i + 3 <= h.length; i += 3) {
            c = parseInt(h.substring(i, i + 3), 16);
            ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
        }
        if (i + 1 == h.length) {
            c = parseInt(h.substring(i, i + 1), 16);
            ret += b64map.charAt(c << 2);
        }
        else if (i + 2 == h.length) {
            c = parseInt(h.substring(i, i + 2), 16);
            ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
        }
        while ((ret.length & 3) > 0) {
            ret += b64pad;
        }
        return ret;
    }
    // convert a base64 string to hex
    function b64tohex(s) {
        var ret = "";
        var i;
        var k = 0; // b64 state, 0-3
        var slop = 0;
        for (i = 0; i < s.length; ++i) {
            if (s.charAt(i) == b64pad) {
                break;
            }
            var v = b64map.indexOf(s.charAt(i));
            if (v < 0) {
                continue;
            }
            if (k == 0) {
                ret += int2char(v >> 2);
                slop = v & 3;
                k = 1;
            }
            else if (k == 1) {
                ret += int2char((slop << 2) | (v >> 4));
                slop = v & 0xf;
                k = 2;
            }
            else if (k == 2) {
                ret += int2char(slop);
                ret += int2char(v >> 2);
                slop = v & 3;
                k = 3;
            }
            else {
                ret += int2char((slop << 2) | (v >> 4));
                ret += int2char(v & 0xf);
                k = 0;
            }
        }
        if (k == 1) {
            ret += int2char(slop << 2);
        }
        return ret;
    }
    // convert a base64 string to a byte/number array
    function b64toBA(s) {
        // piggyback on b64tohex for now, optimize later
        var h = b64tohex(s);
        var i;
        var a = [];
        for (i = 0; 2 * i < h.length; ++i) {
            a[i] = parseInt(h.substring(2 * i, 2 * i + 2), 16);
        }
        return a;
    }

    // Hex JavaScript decoder
    // Copyright (c) 2008-2013 Lapo Luchini <[email protected]>
    // Permission to use, copy, modify, and/or distribute this software for any
    // purpose with or without fee is hereby granted, provided that the above
    // copyright notice and this permission notice appear in all copies.
    //
    // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
    var decoder$1;
    var Hex = {
        decode: function (a) {
            var i;
            if (decoder$1 === undefined) {
                var hex = "0123456789ABCDEF";
                var ignore = " \f\n\r\t\u00A0\u2028\u2029";
                decoder$1 = {};
                for (i = 0; i < 16; ++i) {
                    decoder$1[hex.charAt(i)] = i;
                }
                hex = hex.toLowerCase();
                for (i = 10; i < 16; ++i) {
                    decoder$1[hex.charAt(i)] = i;
                }
                for (i = 0; i < ignore.length; ++i) {
                    decoder$1[ignore.charAt(i)] = -1;
                }
            }
            var out = [];
            var bits = 0;
            var char_count = 0;
            for (i = 0; i < a.length; ++i) {
                var c = a.charAt(i);
                if (c == "=") {
                    break;
                }
                c = decoder$1[c];
                if (c == -1) {
                    continue;
                }
                if (c === undefined) {
                    throw new Error("Illegal character at offset " + i);
                }
                bits |= c;
                if (++char_count >= 2) {
                    out[out.length] = bits;
                    bits = 0;
                    char_count = 0;
                }
                else {
                    bits <<= 4;
                }
            }
            if (char_count) {
                throw new Error("Hex encoding incomplete: 4 bits missing");
            }
            return out;
        }
    };

    // Base64 JavaScript decoder
    // Copyright (c) 2008-2013 Lapo Luchini <[email protected]>
    // Permission to use, copy, modify, and/or distribute this software for any
    // purpose with or without fee is hereby granted, provided that the above
    // copyright notice and this permission notice appear in all copies.
    //
    // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
    var decoder;
    var Base64 = {
        decode: function (a) {
            var i;
            if (decoder === undefined) {
                var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                var ignore = "= \f\n\r\t\u00A0\u2028\u2029";
                decoder = Object.create(null);
                for (i = 0; i < 64; ++i) {
                    decoder[b64.charAt(i)] = i;
                }
                decoder['-'] = 62; //+
                decoder['_'] = 63; //-
                for (i = 0; i < ignore.length; ++i) {
                    decoder[ignore.charAt(i)] = -1;
                }
            }
            var out = [];
            var bits = 0;
            var char_count = 0;
            for (i = 0; i < a.length; ++i) {
                var c = a.charAt(i);
                if (c == "=") {
                    break;
                }
                c = decoder[c];
                if (c == -1) {
                    continue;
                }
                if (c === undefined) {
                    throw new Error("Illegal character at offset " + i);
                }
                bits |= c;
                if (++char_count >= 4) {
                    out[out.length] = (bits >> 16);
                    out[out.length] = (bits >> 8) & 0xFF;
                    out[out.length] = bits & 0xFF;
                    bits = 0;
                    char_count = 0;
                }
                else {
                    bits <<= 6;
                }
            }
            switch (char_count) {
                case 1:
                    throw new Error("Base64 encoding incomplete: at least 2 bits missing");
                case 2:
                    out[out.length] = (bits >> 10);
                    break;
                case 3:
                    out[out.length] = (bits >> 16);
                    out[out.length] = (bits >> 8) & 0xFF;
                    break;
            }
            return out;
        },
        re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,
        unarmor: function (a) {
            var m = Base64.re.exec(a);
            if (m) {
                if (m[1]) {
                    a = m[1];
                }
                else if (m[2]) {
                    a = m[2];
                }
                else {
                    throw new Error("RegExp out of sync");
                }
            }
            return Base64.decode(a);
        }
    };

    // Big integer base-10 printing library
    // Copyright (c) 2014 Lapo Luchini <[email protected]>
    // Permission to use, copy, modify, and/or distribute this software for any
    // purpose with or without fee is hereby granted, provided that the above
    // copyright notice and this permission notice appear in all copies.
    //
    // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
    var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256
    var Int10 = /** @class */ (function () {
        function Int10(value) {
            this.buf = [+value || 0];
        }
        Int10.prototype.mulAdd = function (m, c) {
            // assert(m <= 256)
            var b = this.buf;
            var l = b.length;
            var i;
            var t;
            for (i = 0; i < l; ++i) {
                t = b[i] * m + c;
                if (t < max) {
                    c = 0;
                }
                else {
                    c = 0 | (t / max);
                    t -= c * max;
                }
                b[i] = t;
            }
            if (c > 0) {
                b[i] = c;
            }
        };
        Int10.prototype.sub = function (c) {
            // assert(m <= 256)
            var b = this.buf;
            var l = b.length;
            var i;
            var t;
            for (i = 0; i < l; ++i) {
                t = b[i] - c;
                if (t < 0) {
                    t += max;
                    c = 1;
                }
                else {
                    c = 0;
                }
                b[i] = t;
            }
            while (b[b.length - 1] === 0) {
                b.pop();
            }
        };
        Int10.prototype.toString = function (base) {
            if ((base || 10) != 10) {
                throw new Error("only base 10 is supported");
            }
            var b = this.buf;
            var s = b[b.length - 1].toString();
            for (var i = b.length - 2; i >= 0; --i) {
                s += (max + b[i]).toString().substring(1);
            }
            return s;
        };
        Int10.prototype.valueOf = function () {
            var b = this.buf;
            var v = 0;
            for (var i = b.length - 1; i >= 0; --i) {
                v = v * max + b[i];
            }
            return v;
        };
        Int10.prototype.simplify = function () {
            var b = this.buf;
            return (b.length == 1) ? b[0] : this;
        };
        return Int10;
    }());

    // ASN.1 JavaScript decoder
    var ellipsis = "\u2026";
    var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
    var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
    function stringCut(str, len) {
        if (str.length > len) {
            str = str.substring(0, len) + ellipsis;
        }
        return str;
    }
    var Stream = /** @class */ (function () {
        function Stream(enc, pos) {
            this.hexDigits = "0123456789ABCDEF";
            if (enc instanceof Stream) {
                this.enc = enc.enc;
                this.pos = enc.pos;
            }
            else {
                // enc should be an array or a binary string
                this.enc = enc;
                this.pos = pos;
            }
        }
        Stream.prototype.get = function (pos) {
            if (pos === undefined) {
                pos = this.pos++;
            }
            if (pos >= this.enc.length) {
                throw new Error("Requesting byte offset ".concat(pos, " on a stream of length ").concat(this.enc.length));
            }
            return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];
        };
        Stream.prototype.hexByte = function (b) {
            return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
        };
        Stream.prototype.hexDump = function (start, end, raw) {
            var s = "";
            for (var i = start; i < end; ++i) {
                s += this.hexByte(this.get(i));
                if (raw !== true) {
                    switch (i & 0xF) {
                        case 0x7:
                            s += "  ";
                            break;
                        case 0xF:
                            s += "\n";
                            break;
                        default:
                            s += " ";
                    }
                }
            }
            return s;
        };
        Stream.prototype.isASCII = function (start, end) {
            for (var i = start; i < end; ++i) {
                var c = this.get(i);
                if (c < 32 || c > 176) {
                    return false;
                }
            }
            return true;
        };
        Stream.prototype.parseStringISO = function (start, end) {
            var s = "";
            for (var i = start; i < end; ++i) {
                s += String.fromCharCode(this.get(i));
            }
            return s;
        };
        Stream.prototype.parseStringUTF = function (start, end) {
            var s = "";
            for (var i = start; i < end;) {
                var c = this.get(i++);
                if (c < 128) {
                    s += String.fromCharCode(c);
                }
                else if ((c > 191) && (c < 224)) {
                    s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));
                }
                else {
                    s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));
                }
            }
            return s;
        };
        Stream.prototype.parseStringBMP = function (start, end) {
            var str = "";
            var hi;
            var lo;
            for (var i = start; i < end;) {
                hi = this.get(i++);
                lo = this.get(i++);
                str += String.fromCharCode((hi << 8) | lo);
            }
            return str;
        };
        Stream.prototype.parseTime = function (start, end, shortYear) {
            var s = this.parseStringISO(start, end);
            var m = (shortYear ? reTimeS : reTimeL).exec(s);
            if (!m) {
                return "Unrecognized time: " + s;
            }
            if (shortYear) {
                // to avoid querying the timer, use the fixed range [1970, 2069]
                // it will conform with ITU X.400 [-10, +40] sliding window until 2030
                m[1] = +m[1];
                m[1] += (+m[1] < 70) ? 2000 : 1900;
            }
            s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
            if (m[5]) {
                s += ":" + m[5];
                if (m[6]) {
                    s += ":" + m[6];
                    if (m[7]) {
                        s += "." + m[7];
                    }
                }
            }
            if (m[8]) {
                s += " UTC";
                if (m[8] != "Z") {
                    s += m[8];
                    if (m[9]) {
                        s += ":" + m[9];
                    }
                }
            }
            return s;
        };
        Stream.prototype.parseInteger = function (start, end) {
            var v = this.get(start);
            var neg = (v > 127);
            var pad = neg ? 255 : 0;
            var len;
            var s = "";
            // skip unuseful bits (not allowed in DER)
            while (v == pad && ++start < end) {
                v = this.get(start);
            }
            len = end - start;
            if (len === 0) {
                return neg ? -1 : 0;
            }
            // show bit length of huge integers
            if (len > 4) {
                s = v;
                len <<= 3;
                while (((+s ^ pad) & 0x80) == 0) {
                    s = +s << 1;
                    --len;
                }
                s = "(" + len + " bit)\n";
            }
            // decode the integer
            if (neg) {
                v = v - 256;
            }
            var n = new Int10(v);
            for (var i = start + 1; i < end; ++i) {
                n.mulAdd(256, this.get(i));
            }
            return s + n.toString();
        };
        Stream.prototype.parseBitString = function (start, end, maxLength) {
            var unusedBit = this.get(start);
            var lenBit = ((end - start - 1) << 3) - unusedBit;
            var intro = "(" + lenBit + " bit)\n";
            var s = "";
            for (var i = start + 1; i < end; ++i) {
                var b = this.get(i);
                var skip = (i == end - 1) ? unusedBit : 0;
                for (var j = 7; j >= skip; --j) {
                    s += (b >> j) & 1 ? "1" : "0";
                }
                if (s.length > maxLength) {
                    return intro + stringCut(s, maxLength);
                }
            }
            return intro + s;
        };
        Stream.prototype.parseOctetString = function (start, end, maxLength) {
            if (this.isASCII(start, end)) {
                return stringCut(this.parseStringISO(start, end), maxLength);
            }
            var len = end - start;
            var s = "(" + len + " byte)\n";
            maxLength /= 2; // we work in bytes
            if (len > maxLength) {
                end = start + maxLength;
            }
            for (var i = start; i < end; ++i) {
                s += this.hexByte(this.get(i));
            }
            if (len > maxLength) {
                s += ellipsis;
            }
            return s;
        };
        Stream.prototype.parseOID = function (start, end, maxLength) {
            var s = "";
            var n = new Int10();
            var bits = 0;
            for (var i = start; i < end; ++i) {
                var v = this.get(i);
                n.mulAdd(128, v & 0x7F);
                bits += 7;
                if (!(v & 0x80)) { // finished
                    if (s === "") {
                        n = n.simplify();
                        if (n instanceof Int10) {
                            n.sub(80);
                            s = "2." + n.toString();
                        }
                        else {
                            var m = n < 80 ? n < 40 ? 0 : 1 : 2;
                            s = m + "." + (n - m * 40);
                        }
                    }
                    else {
                        s += "." + n.toString();
                    }
                    if (s.length > maxLength) {
                        return stringCut(s, maxLength);
                    }
                    n = new Int10();
                    bits = 0;
                }
            }
            if (bits > 0) {
                s += ".incomplete";
            }
            return s;
        };
        return Stream;
    }());
    var ASN1 = /** @class */ (function () {
        function ASN1(stream, header, length, tag, sub) {
            if (!(tag instanceof ASN1Tag)) {
                throw new Error("Invalid tag value.");
            }
            this.stream = stream;
            this.header = header;
            this.length = length;
            this.tag = tag;
            this.sub = sub;
        }
        ASN1.prototype.typeName = function () {
            switch (this.tag.tagClass) {
                case 0: // universal
                    switch (this.tag.tagNumber) {
                        case 0x00:
                            return "EOC";
                        case 0x01:
                            return "BOOLEAN";
                        case 0x02:
                            return "INTEGER";
                        case 0x03:
                            return "BIT_STRING";
                        case 0x04:
                            return "OCTET_STRING";
                        case 0x05:
                            return "NULL";
                        case 0x06:
                            return "OBJECT_IDENTIFIER";
                        case 0x07:
                            return "ObjectDescriptor";
                        case 0x08:
                            return "EXTERNAL";
                        case 0x09:
                            return "REAL";
                        case 0x0A:
                            return "ENUMERATED";
                        case 0x0B:
                            return "EMBEDDED_PDV";
                        case 0x0C:
                            return "UTF8String";
                        case 0x10:
                            return "SEQUENCE";
                        case 0x11:
                            return "SET";
                        case 0x12:
                            return "NumericString";
                        case 0x13:
                            return "PrintableString"; // ASCII subset
                        case 0x14:
                            return "TeletexString"; // aka T61String
                        case 0x15:
                            return "VideotexString";
                        case 0x16:
                            return "IA5String"; // ASCII
                        case 0x17:
                            return "UTCTime";
                        case 0x18:
                            return "GeneralizedTime";
                        case 0x19:
                            return "GraphicString";
                        case 0x1A:
                            return "VisibleString"; // ASCII subset
                        case 0x1B:
                            return "GeneralString";
                        case 0x1C:
                            return "UniversalString";
                        case 0x1E:
                            return "BMPString";
                    }
                    return "Universal_" + this.tag.tagNumber.toString();
                case 1:
                    return "Application_" + this.tag.tagNumber.toString();
                case 2:
                    return "[" + this.tag.tagNumber.toString() + "]"; // Context
                case 3:
                    return "Private_" + this.tag.tagNumber.toString();
            }
        };
        ASN1.prototype.content = function (maxLength) {
            if (this.tag === undefined) {
                return null;
            }
            if (maxLength === undefined) {
                maxLength = Infinity;
            }
            var content = this.posContent();
            var len = Math.abs(this.length);
            if (!this.tag.isUniversal()) {
                if (this.sub !== null) {
                    return "(" + this.sub.length + " elem)";
                }
                return this.stream.parseOctetString(content, content + len, maxLength);
            }
            switch (this.tag.tagNumber) {
                case 0x01: // BOOLEAN
                    return (this.stream.get(content) === 0) ? "false" : "true";
                case 0x02: // INTEGER
                    return this.stream.parseInteger(content, content + len);
                case 0x03: // BIT_STRING
                    return this.sub ? "(" + this.sub.length + " elem)" :
                        this.stream.parseBitString(content, content + len, maxLength);
                case 0x04: // OCTET_STRING
                    return this.sub ? "(" + this.sub.length + " elem)" :
                        this.stream.parseOctetString(content, content + len, maxLength);
                // case 0x05: // NULL
                case 0x06: // OBJECT_IDENTIFIER
                    return this.stream.parseOID(content, content + len, maxLength);
                // case 0x07: // ObjectDescriptor
                // case 0x08: // EXTERNAL
                // case 0x09: // REAL
                // case 0x0A: // ENUMERATED
                // case 0x0B: // EMBEDDED_PDV
                case 0x10: // SEQUENCE
                case 0x11: // SET
                    if (this.sub !== null) {
                        return "(" + this.sub.length + " elem)";
                    }
                    else {
                        return "(no elem)";
                    }
                case 0x0C: // UTF8String
                    return stringCut(this.stream.parseStringUTF(content, content + len), maxLength);
                case 0x12: // NumericString
                case 0x13: // PrintableString
                case 0x14: // TeletexString
                case 0x15: // VideotexString
                case 0x16: // IA5String
                // case 0x19: // GraphicString
                case 0x1A: // VisibleString
                    // case 0x1B: // GeneralString
                    // case 0x1C: // UniversalString
                    return stringCut(this.stream.parseStringISO(content, content + len), maxLength);
                case 0x1E: // BMPString
                    return stringCut(this.stream.parseStringBMP(content, content + len), maxLength);
                case 0x17: // UTCTime
                case 0x18: // GeneralizedTime
                    return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
            }
            return null;
        };
        ASN1.prototype.toString = function () {
            return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]";
        };
        ASN1.prototype.toPrettyString = function (indent) {
            if (indent === undefined) {
                indent = "";
            }
            var s = indent + this.typeName() + " @" + this.stream.pos;
            if (this.length >= 0) {
                s += "+";
            }
            s += this.length;
            if (this.tag.tagConstructed) {
                s += " (constructed)";
            }
            else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) {
                s += " (encapsulates)";
            }
            s += "\n";
            if (this.sub !== null) {
                indent += "  ";
                for (var i = 0, max = this.sub.length; i < max; ++i) {
                    s += this.sub[i].toPrettyString(indent);
                }
            }
            return s;
        };
        ASN1.prototype.posStart = function () {
            return this.stream.pos;
        };
        ASN1.prototype.posContent = function () {
            return this.stream.pos + this.header;
        };
        ASN1.prototype.posEnd = function () {
            return this.stream.pos + this.header + Math.abs(this.length);
        };
        ASN1.prototype.toHexString = function () {
            return this.stream.hexDump(this.posStart(), this.posEnd(), true);
        };
        ASN1.decodeLength = function (stream) {
            var buf = stream.get();
            var len = buf & 0x7F;
            if (len == buf) {
                return len;
            }
            // no reason to use Int10, as it would be a huge buffer anyways
            if (len > 6) {
                throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1));
            }
            if (len === 0) {
                return null;
            } // undefined
            buf = 0;
            for (var i = 0; i < len; ++i) {
                buf = (buf * 256) + stream.get();
            }
            return buf;
        };
        /**
         * Retrieve the hexadecimal value (as a string) of the current ASN.1 element
         * @returns {string}
         * @public
         */
        ASN1.prototype.getHexStringValue = function () {
            var hexString = this.toHexString();
            var offset = this.header * 2;
            var length = this.length * 2;
            return hexString.substr(offset, length);
        };
        ASN1.decode = function (str) {
            var stream;
            if (!(str instanceof Stream)) {
                stream = new Stream(str, 0);
            }
            else {
                stream = str;
            }
            var streamStart = new Stream(stream);
            var tag = new ASN1Tag(stream);
            var len = ASN1.decodeLength(stream);
            var start = stream.pos;
            var header = start - streamStart.pos;
            var sub = null;
            var getSub = function () {
                var ret = [];
                if (len !== null) {
                    // definite length
                    var end = start + len;
                    while (stream.pos < end) {
                        ret[ret.length] = ASN1.decode(stream);
                    }
                    if (stream.pos != end) {
                        throw new Error("Content size is not correct for container starting at offset " + start);
                    }
                }
                else {
                    // undefined length
                    try {
                        for (;;) {
                            var s = ASN1.decode(stream);
                            if (s.tag.isEOC()) {
                                break;
                            }
                            ret[ret.length] = s;
                        }
                        len = start - stream.pos; // undefined lengths are represented as negative values
                    }
                    catch (e) {
                        throw new Error("Exception while decoding undefined length content: " + e);
                    }
                }
                return ret;
            };
            if (tag.tagConstructed) {
                // must have valid content
                sub = getSub();
            }
            else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
                // sometimes BitString and OctetString are used to encapsulate ASN.1
                try {
                    if (tag.tagNumber == 0x03) {
                        if (stream.get() != 0) {
                            throw new Error("BIT STRINGs with unused bits cannot encapsulate.");
                        }
                    }
                    sub = getSub();
                    for (var i = 0; i < sub.length; ++i) {
                        if (sub[i].tag.isEOC()) {
                            throw new Error("EOC is not supposed to be actual content.");
                        }
                    }
                }
                catch (e) {
                    // but silently ignore when they don't
                    sub = null;
                }
            }
            if (sub === null) {
                if (len === null) {
                    throw new Error("We can't skip over an invalid tag with undefined length at offset " + start);
                }
                stream.pos = start + Math.abs(len);
            }
            return new ASN1(streamStart, header, len, tag, sub);
        };
        return ASN1;
    }());
    var ASN1Tag = /** @class */ (function () {
        function ASN1Tag(stream) {
            var buf = stream.get();
            this.tagClass = buf >> 6;
            this.tagConstructed = ((buf & 0x20) !== 0);
            this.tagNumber = buf & 0x1F;
            if (this.tagNumber == 0x1F) { // long tag
                var n = new Int10();
                do {
                    buf = stream.get();
                    n.mulAdd(128, buf & 0x7F);
                } while (buf & 0x80);
                this.tagNumber = n.simplify();
            }
        }
        ASN1Tag.prototype.isUniversal = function () {
            return this.tagClass === 0x00;
        };
        ASN1Tag.prototype.isEOC = function () {
            return this.tagClass === 0x00 && this.tagNumber === 0x00;
        };
        return ASN1Tag;
    }());

    // prng4.js - uses Arcfour as a PRNG
    var Arcfour = /** @class */ (function () {
        function Arcfour() {
            this.i = 0;
            this.j = 0;
            this.S = [];
        }
        // Arcfour.prototype.init = ARC4init;
        // Initialize arcfour context from key, an array of ints, each from [0..255]
        Arcfour.prototype.init = function (key) {
            var i;
            var j;
            var t;
            for (i = 0; i < 256; ++i) {
                this.S[i] = i;
            }
            j = 0;
            for (i = 0; i < 256; ++i) {
                j = (j + this.S[i] + key[i % key.length]) & 255;
                t = this.S[i];
                this.S[i] = this.S[j];
                this.S[j] = t;
            }
            this.i = 0;
            this.j = 0;
        };
        // Arcfour.prototype.next = ARC4next;
        Arcfour.prototype.next = function () {
            var t;
            this.i = (this.i + 1) & 255;
            this.j = (this.j + this.S[this.i]) & 255;
            t = this.S[this.i];
            this.S[this.i] = this.S[this.j];
            this.S[this.j] = t;
            return this.S[(t + this.S[this.i]) & 255];
        };
        return Arcfour;
    }());
    // Plug in your RNG constructor here
    function prng_newstate() {
        return new Arcfour();
    }
    // Pool size must be a multiple of 4 and greater than 32.
    // An array of bytes the size of the pool will be passed to init()
    var rng_psize = 256;

    // Random number generator - requires a PRNG backend, e.g. prng4.js
    var rng_state;
    var rng_pool = null;
    var rng_pptr;
    // Initialize the pool with junk if needed.
    if (rng_pool == null) {
        rng_pool = [];
        rng_pptr = 0;
        var t = void 0;
        if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {
            // Extract entropy (2048 bits) from RNG if available
            var z = new Uint32Array(256);
            window.crypto.getRandomValues(z);
            for (t = 0; t < z.length; ++t) {
                rng_pool[rng_pptr++] = z[t] & 255;
            }
        }
        // Use mouse events for entropy, if we do not have enough entropy by the time
        // we need it, entropy will be generated by Math.random.
        var count = 0;
        var onMouseMoveListener_1 = function (ev) {
            count = count || 0;
            if (count >= 256 || rng_pptr >= rng_psize) {
                if (window.removeEventListener) {
                    window.removeEventListener("mousemove", onMouseMoveListener_1, false);
                }
                else if (window.detachEvent) {
                    window.detachEvent("onmousemove", onMouseMoveListener_1);
                }
                return;
            }
            try {
                var mouseCoordinates = ev.x + ev.y;
                rng_pool[rng_pptr++] = mouseCoordinates & 255;
                count += 1;
            }
            catch (e) {
                // Sometimes Firefox will deny permission to access event properties for some reason. Ignore.
            }
        };
        if (typeof window !== 'undefined') {
            if (window.addEventListener) {
                window.addEventListener("mousemove", onMouseMoveListener_1, false);
            }
            else if (window.attachEvent) {
                window.attachEvent("onmousemove", onMouseMoveListener_1);
            }
        }
    }
    function rng_get_byte() {
        if (rng_state == null) {
            rng_state = prng_newstate();
            // At this point, we may not have collected enough entropy.  If not, fall back to Math.random
            while (rng_pptr < rng_psize) {
                var random = Math.floor(65536 * Math.random());
                rng_pool[rng_pptr++] = random & 255;
            }
            rng_state.init(rng_pool);
            for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
                rng_pool[rng_pptr] = 0;
            }
            rng_pptr = 0;
        }
        // TODO: allow reseeding after first request
        return rng_state.next();
    }
    var SecureRandom = /** @class */ (function () {
        function SecureRandom() {
        }
        SecureRandom.prototype.nextBytes = function (ba) {
            for (var i = 0; i < ba.length; ++i) {
                ba[i] = rng_get_byte();
            }
        };
        return SecureRandom;
    }());

    // Depends on jsbn.js and rng.js
    // function linebrk(s,n) {
    //   var ret = "";
    //   var i = 0;
    //   while(i + n < s.length) {
    //     ret += s.substring(i,i+n) + "\n";
    //     i += n;
    //   }
    //   return ret + s.substring(i,s.length);
    // }
    // function byte2Hex(b) {
    //   if(b < 0x10)
    //     return "0" + b.toString(16);
    //   else
    //     return b.toString(16);
    // }
    function pkcs1pad1(s, n) {
        if (n < s.length + 22) {
            console.error("Message too long for RSA");
            return null;
        }
        var len = n - s.length - 6;
        var filler = "";
        for (var f = 0; f < len; f += 2) {
            filler += "ff";
        }
        var m = "0001" + filler + "00" + s;
        return parseBigInt(m, 16);
    }
    // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
    function pkcs1pad2(s, n) {
        if (n < s.length + 11) { // TODO: fix for utf-8
            console.error("Message too long for RSA");
            return null;
        }
        var ba = [];
        var i = s.length - 1;
        while (i >= 0 && n > 0) {
            var c = s.charCodeAt(i--);
            if (c < 128) { // encode using utf-8
                ba[--n] = c;
            }
            else if ((c > 127) && (c < 2048)) {
                ba[--n] = (c & 63) | 128;
                ba[--n] = (c >> 6) | 192;
            }
            else {
                ba[--n] = (c & 63) | 128;
                ba[--n] = ((c >> 6) & 63) | 128;
                ba[--n] = (c >> 12) | 224;
            }
        }
        ba[--n] = 0;
        var rng = new SecureRandom();
        var x = [];
        while (n > 2) { // random non-zero pad
            x[0] = 0;
            while (x[0] == 0) {
                rng.nextBytes(x);
            }
            ba[--n] = x[0];
        }
        ba[--n] = 2;
        ba[--n] = 0;
        return new BigInteger(ba);
    }
    // "empty" RSA key constructor
    var RSAKey = /** @class */ (function () {
        function RSAKey() {
            this.n = null;
            this.e = 0;
            this.d = null;
            this.p = null;
            this.q = null;
            this.dmp1 = null;
            this.dmq1 = null;
            this.coeff = null;
        }
        //#region PROTECTED
        // protected
        // RSAKey.prototype.doPublic = RSADoPublic;
        // Perform raw public operation on "x": return x^e (mod n)
        RSAKey.prototype.doPublic = function (x) {
            return x.modPowInt(this.e, this.n);
        };
        // RSAKey.prototype.doPrivate = RSADoPrivate;
        // Perform raw private operation on "x": return x^d (mod n)
        RSAKey.prototype.doPrivate = function (x) {
            if (this.p == null || this.q == null) {
                return x.modPow(this.d, this.n);
            }
            // TODO: re-calculate any missing CRT params
            var xp = x.mod(this.p).modPow(this.dmp1, this.p);
            var xq = x.mod(this.q).modPow(this.dmq1, this.q);
            while (xp.compareTo(xq) < 0) {
                xp = xp.add(this.p);
            }
            return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
        };
        //#endregion PROTECTED
        //#region PUBLIC
        // RSAKey.prototype.setPublic = RSASetPublic;
        // Set the public key fields N and e from hex strings
        RSAKey.prototype.setPublic = function (N, E) {
            if (N != null && E != null && N.length > 0 && E.length > 0) {
                this.n = parseBigInt(N, 16);
                this.e = parseInt(E, 16);
            }
            else {
                console.error("Invalid RSA public key");
            }
        };
        // RSAKey.prototype.encrypt = RSAEncrypt;
        // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
        RSAKey.prototype.encrypt = function (text) {
            var maxLength = (this.n.bitLength() + 7) >> 3;
            var m = pkcs1pad2(text, maxLength);
            if (m == null) {
                return null;
            }
            var c = this.doPublic(m);
            if (c == null) {
                return null;
            }
            var h = c.toString(16);
            var length = h.length;
            // fix zero before result
            for (var i = 0; i < maxLength * 2 - length; i++) {
                h = "0" + h;
            }
            return h;
        };
        // RSAKey.prototype.setPrivate = RSASetPrivate;
        // Set the private key fields N, e, and d from hex strings
        RSAKey.prototype.setPrivate = function (N, E, D) {
            if (N != null && E != null && N.length > 0 && E.length > 0) {
                this.n = parseBigInt(N, 16);
                this.e = parseInt(E, 16);
                this.d = parseBigInt(D, 16);
            }
            else {
                console.error("Invalid RSA private key");
            }
        };
        // RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
        // Set the private key fields N, e, d and CRT params from hex strings
        RSAKey.prototype.setPrivateEx = function (N, E, D, P, Q, DP, DQ, C) {
            if (N != null && E != null && N.length > 0 && E.length > 0) {
                this.n = parseBigInt(N, 16);
                this.e = parseInt(E, 16);
                this.d = parseBigInt(D, 16);
                this.p = parseBigInt(P, 16);
                this.q = parseBigInt(Q, 16);
                this.dmp1 = parseBigInt(DP, 16);
                this.dmq1 = parseBigInt(DQ, 16);
                this.coeff = parseBigInt(C, 16);
            }
            else {
                console.error("Invalid RSA private key");
            }
        };
        // RSAKey.prototype.generate = RSAGenerate;
        // Generate a new random private key B bits long, using public expt E
        RSAKey.prototype.generate = function (B, E) {
            var rng = new SecureRandom();
            var qs = B >> 1;
            this.e = parseInt(E, 16);
            var ee = new BigInteger(E, 16);
            for (;;) {
                for (;;) {
                    this.p = new BigInteger(B - qs, 1, rng);
                    if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) {
                        break;
                    }
                }
                for (;;) {
                    this.q = new BigInteger(qs, 1, rng);
                    if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) {
                        break;
                    }
                }
                if (this.p.compareTo(this.q) <= 0) {
                    var t = this.p;
                    this.p = this.q;
                    this.q = t;
                }
                var p1 = this.p.subtract(BigInteger.ONE);
                var q1 = this.q.subtract(BigInteger.ONE);
                var phi = p1.multiply(q1);
                if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
                    this.n = this.p.multiply(this.q);
                    this.d = ee.modInverse(phi);
                    this.dmp1 = this.d.mod(p1);
                    this.dmq1 = this.d.mod(q1);
                    this.coeff = this.q.modInverse(this.p);
                    break;
                }
            }
        };
        // RSAKey.prototype.decrypt = RSADecrypt;
        // Return the PKCS#1 RSA decryption of "ctext".
        // "ctext" is an even-length hex string and the output is a plain string.
        RSAKey.prototype.decrypt = function (ctext) {
            var c = parseBigInt(ctext, 16);
            var m = this.doPrivate(c);
            if (m == null) {
                return null;
            }
            return pkcs1unpad2$1(m, (this.n.bitLength() + 7) >> 3);
        };
        // Generate a new random private key B bits long, using public expt E
        RSAKey.prototype.generateAsync = function (B, E, callback) {
            var rng = new SecureRandom();
            var qs = B >> 1;
            this.e = parseInt(E, 16);
            var ee = new BigInteger(E, 16);
            var rsa = this;
            // These functions have non-descript names because they were originally for(;;) loops.
            // I don't know about cryptography to give them better names than loop1-4.
            var loop1 = function () {
                var loop4 = function () {
                    if (rsa.p.compareTo(rsa.q) <= 0) {
                        var t = rsa.p;
                        rsa.p = rsa.q;
                        rsa.q = t;
                    }
                    var p1 = rsa.p.subtract(BigInteger.ONE);
                    var q1 = rsa.q.subtract(BigInteger.ONE);
                    var phi = p1.multiply(q1);
                    if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
                        rsa.n = rsa.p.multiply(rsa.q);
                        rsa.d = ee.modInverse(phi);
                        rsa.dmp1 = rsa.d.mod(p1);
                        rsa.dmq1 = rsa.d.mod(q1);
                        rsa.coeff = rsa.q.modInverse(rsa.p);
                        setTimeout(function () { callback(); }, 0); // escape
                    }
                    else {
                        setTimeout(loop1, 0);
                    }
                };
                var loop3 = function () {
                    rsa.q = nbi();
                    rsa.q.fromNumberAsync(qs, 1, rng, function () {
                        rsa.q.subtract(BigInteger.ONE).gcda(ee, function (r) {
                            if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
                                setTimeout(loop4, 0);
                            }
                            else {
                                setTimeout(loop3, 0);
                            }
                        });
                    });
                };
                var loop2 = function () {
                    rsa.p = nbi();
                    rsa.p.fromNumberAsync(B - qs, 1, rng, function () {
                        rsa.p.subtract(BigInteger.ONE).gcda(ee, function (r) {
                            if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
                                setTimeout(loop3, 0);
                            }
                            else {
                                setTimeout(loop2, 0);
                            }
                        });
                    });
                };
                setTimeout(loop2, 0);
            };
            setTimeout(loop1, 0);
        };
        RSAKey.prototype.sign = function (text, digestMethod, digestName) {
            var header = getDigestHeader(digestName);
            var digest = header + digestMethod(text).toString();
            var m = pkcs1pad1(digest, this.n.bitLength() / 4);
            if (m == null) {
                return null;
            }
            var c = this.doPrivate(m);
            if (c == null) {
                return null;
            }
            var h = c.toString(16);
            if ((h.length & 1) == 0) {
                return h;
            }
            else {
                return "0" + h;
            }
        };
        RSAKey.prototype.verify = function (text, signature, digestMethod) {
            var c = parseBigInt(signature, 16);
            var m = this.doPublic(c);
            if (m == null) {
                return null;
            }
            var unpadded = m.toString(16).replace(/^1f+00/, "");
            var digest = removeDigestHeader(unpadded);
            return digest == digestMethod(text).toString();
        };
        return RSAKey;
    }());
    // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
    function pkcs1unpad2$1(d, n) {
        var b = d.toByteArray();
        var i = 0;
        while (i < b.length && b[i] == 0) {
            ++i;
        }
        if (b.length - i != n - 1 || b[i] != 2) {
            return null;
        }
        ++i;
        while (b[i] != 0) {
            if (++i >= b.length) {
                return null;
            }
        }
        var ret = "";
        while (++i < b.length) {
            var c = b[i] & 255;
            if (c < 128) { // utf-8 decode
                ret += String.fromCharCode(c);
            }
            else if ((c > 191) && (c < 224)) {
                ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
                ++i;
            }
            else {
                ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
                i += 2;
            }
        }
        return ret;
    }
    // https://tools.ietf.org/html/rfc3447#page-43
    var DIGEST_HEADERS = {
        md2: "3020300c06082a864886f70d020205000410",
        md5: "3020300c06082a864886f70d020505000410",
        sha1: "3021300906052b0e03021a05000414",
        sha224: "302d300d06096086480165030402040500041c",
        sha256: "3031300d060960864801650304020105000420",
        sha384: "3041300d060960864801650304020205000430",
        sha512: "3051300d060960864801650304020305000440",
        ripemd160: "3021300906052b2403020105000414"
    };
    function getDigestHeader(name) {
        return DIGEST_HEADERS[name] || "";
    }
    function removeDigestHeader(str) {
        for (var name_1 in DIGEST_HEADERS) {
            if (DIGEST_HEADERS.hasOwnProperty(name_1)) {
                var header = DIGEST_HEADERS[name_1];
                var len = header.length;
                if (str.substr(0, len) == header) {
                    return str.substr(len);
                }
            }
        }
        return str;
    }
    // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
    // function RSAEncryptB64(text) {
    //  var h = this.encrypt(text);
    //  if(h) return hex2b64(h); else return null;
    // }
    // public
    // RSAKey.prototype.encrypt_b64 = RSAEncryptB64;

    /*!
    Copyright (c) 2011, Yahoo! Inc. All rights reserved.
    Code licensed under the BSD License:
    http://developer.yahoo.com/yui/license.html
    version: 2.9.0
    */
    var YAHOO = {};
    YAHOO.lang = {
        /**
         * Utility to set up the prototype, constructor and superclass properties to
         * support an inheritance strategy that can chain constructors and methods.
         * Static members will not be inherited.
         *
         * @method extend
         * @static
         * @param {Function} subc   the object to modify
         * @param {Function} superc the object to inherit
         * @param {Object} overrides  additional properties/methods to add to the
         *                              subclass prototype.  These will override the
         *                              matching items obtained from the superclass
         *                              if present.
         */
        extend: function (subc, superc, overrides) {
            if (!superc || !subc) {
                throw new Error("YAHOO.lang.extend failed, please check that " +
                    "all dependencies are included.");
            }
            var F = function () { };
            F.prototype = superc.prototype;
            subc.prototype = new F();
            subc.prototype.constructor = subc;
            subc.superclass = superc.prototype;
            if (superc.prototype.constructor == Object.prototype.constructor) {
                superc.prototype.constructor = superc;
            }
            if (overrides) {
                var i;
                for (i in overrides) {
                    subc.prototype[i] = overrides[i];
                }
                /*
                 * IE will not enumerate native functions in a derived object even if the
                 * function was overridden.  This is a workaround for specific functions
                 * we care about on the Object prototype.
                 * @property _IEEnumFix
                 * @param {Function} r  the object to receive the augmentation
                 * @param {Function} s  the object that supplies the properties to augment
                 * @static
                 * @private
                 */
                var _IEEnumFix = function () { }, ADD = ["toString", "valueOf"];
                try {
                    if (/MSIE/.test(navigator.userAgent)) {
                        _IEEnumFix = function (r, s) {
                            for (i = 0; i < ADD.length; i = i + 1) {
                                var fname = ADD[i], f = s[fname];
                                if (typeof f === 'function' && f != Object.prototype[fname]) {
                                    r[fname] = f;
                                }
                            }
                        };
                    }
                }
                catch (ex) { }
                ;
                _IEEnumFix(subc.prototype, overrides);
            }
        }
    };

    /* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license
     */
    /**
     * @fileOverview
     * @name asn1-1.0.js
     * @author Kenji Urushima [email protected]
     * @version asn1 1.0.13 (2017-Jun-02)
     * @since jsrsasign 2.1
     * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
     */
    /**
     * kjur's class library name space
     * <p>
     * This name space provides following name spaces:
     * <ul>
     * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>
     * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>
     * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature
     * class and utilities</li>
     * </ul>
     * </p>
     * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
     * @name KJUR
     * @namespace kjur's class library name space
     */
    var KJUR = {};
    /**
     * kjur's ASN.1 class library name space
     * <p>
     * This is ITU-T X.690 ASN.1 DER encoder class library and
     * class structure and methods is very similar to
     * org.bouncycastle.asn1 package of
     * well known BouncyCaslte Cryptography Library.
     * <h4>PROVIDING ASN.1 PRIMITIVES</h4>
     * Here are ASN.1 DER primitive classes.
     * <ul>
     * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>
     * <li>0x02 {@link KJUR.asn1.DERInteger}</li>
     * <li>0x03 {@link KJUR.asn1.DERBitString}</li>
     * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>
     * <li>0x05 {@link KJUR.asn1.DERNull}</li>
     * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>
     * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>
     * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>
     * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>
     * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>
     * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>
     * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>
     * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>
     * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>
     * <li>0x30 {@link KJUR.asn1.DERSequence}</li>
     * <li>0x31 {@link KJUR.asn1.DERSet}</li>
     * </ul>
     * <h4>OTHER ASN.1 CLASSES</h4>
     * <ul>
     * <li>{@link KJUR.asn1.ASN1Object}</li>
     * <li>{@link KJUR.asn1.DERAbstractString}</li>
     * <li>{@link KJUR.asn1.DERAbstractTime}</li>
     * <li>{@link KJUR.asn1.DERAbstractStructured}</li>
     * <li>{@link KJUR.asn1.DERTaggedObject}</li>
     * </ul>
     * <h4>SUB NAME SPACES</h4>
     * <ul>
     * <li>{@link KJUR.asn1.cades} - CAdES long term signature format</li>
     * <li>{@link KJUR.asn1.cms} - Cryptographic Message Syntax</li>
     * <li>{@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)</li>
     * <li>{@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format</li>
     * <li>{@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL</li>
     * </ul>
     * </p>
     * NOTE: Please ignore method summary and document of this namespace.
     * This caused by a bug of jsdoc2.
     * @name KJUR.asn1
     * @namespace
     */
    if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1)
        KJUR.asn1 = {};
    /**
     * ASN1 utilities class
     * @name KJUR.asn1.ASN1Util
     * @class ASN1 utilities class
     * @since asn1 1.0.2
     */
    KJUR.asn1.ASN1Util = new function () {
        this.integerToByteHex = function (i) {
            var h = i.toString(16);
            if ((h.length % 2) == 1)
                h = '0' + h;
            return h;
        };
        this.bigIntToMinTwosComplementsHex = function (bigIntegerValue) {
            var h = bigIntegerValue.toString(16);
            if (h.substr(0, 1) != '-') {
                if (h.length % 2 == 1) {
                    h = '0' + h;
                }
                else {
                    if (!h.match(/^[0-7]/)) {
                        h = '00' + h;
                    }
                }
            }
            else {
                var hPos = h.substr(1);
                var xorLen = hPos.length;
                if (xorLen % 2 == 1) {
                    xorLen += 1;
                }
                else {
                    if (!h.match(/^[0-7]/)) {
                        xorLen += 2;
                    }
                }
                var hMask = '';
                for (var i = 0; i < xorLen; i++) {
                    hMask += 'f';
                }
                var biMask = new BigInteger(hMask, 16);
                var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
                h = biNeg.toString(16).replace(/^-/, '');
            }
            return h;
        };
        /**
         * get PEM string from hexadecimal data and header string
         * @name getPEMStringFromHex
         * @memberOf KJUR.asn1.ASN1Util
         * @function
         * @param {String} dataHex hexadecimal string of PEM body
         * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')
         * @return {String} PEM formatted string of input data
         * @description
         * This method converts a hexadecimal string to a PEM string with
         * a specified header. Its line break will be CRLF("\r\n").
         * @example
         * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');
         * // value of pem will be:
         * -----BEGIN PRIVATE KEY-----
         * YWFh
         * -----END PRIVATE KEY-----
         */
        this.getPEMStringFromHex = function (dataHex, pemHeader) {
            return hextopem(dataHex, pemHeader);
        };
        /**
         * generate ASN1Object specifed by JSON parameters
         * @name newObject
         * @memberOf KJUR.asn1.ASN1Util
         * @function
         * @param {Array} param JSON parameter to generate ASN1Object
         * @return {KJUR.asn1.ASN1Object} generated object
         * @since asn1 1.0.3
         * @description
         * generate any ASN1Object specified by JSON param
         * including ASN.1 primitive or structured.
         * Generally 'param' can be described as follows:
         * <blockquote>
         * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}
         * </blockquote>
         * 'TYPE-OF-ASN1OBJ' can be one of following symbols:
         * <ul>
         * <li>'bool' - DERBoolean</li>
         * <li>'int' - DERInteger</li>
         * <li>'bitstr' - DERBitString</li>
         * <li>'octstr' - DEROctetString</li>
         * <li>'null' - DERNull</li>
         * <li>'oid' - DERObjectIdentifier</li>
         * <li>'enum' - DEREnumerated</li>
         * <li>'utf8str' - DERUTF8String</li>
         * <li>'numstr' - DERNumericString</li>
         * <li>'prnstr' - DERPrintableString</li>
         * <li>'telstr' - DERTeletexString</li>
         * <li>'ia5str' - DERIA5String</li>
         * <li>'utctime' - DERUTCTime</li>
         * <li>'gentime' - DERGeneralizedTime</li>
         * <li>'seq' - DERSequence</li>
         * <li>'set' - DERSet</li>
         * <li>'tag' - DERTaggedObject</li>
         * </ul>
         * @example
         * newObject({'prnstr': 'aaa'});
         * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})
         * // ASN.1 Tagged Object
         * newObject({'tag': {'tag': 'a1',
         *                    'explicit': true,
         *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});
         * // more simple representation of ASN.1 Tagged Object
         * newObject({'tag': ['a1',
         *                    true,
         *                    {'seq': [
         *                      {'int': 3},
         *                      {'prnstr': 'aaa'}]}
         *                   ]});
         */
        this.newObject = function (param) {
            var _KJUR = KJUR, _KJUR_asn1 = _KJUR.asn1, _DERBoolean = _KJUR_asn1.DERBoolean, _DERInteger = _KJUR_asn1.DERInteger, _DERBitString = _KJUR_asn1.DERBitString, _DEROctetString = _KJUR_asn1.DEROctetString, _DERNull = _KJUR_asn1.DERNull, _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier, _DEREnumerated = _KJUR_asn1.DEREnumerated, _DERUTF8String = _KJUR_asn1.DERUTF8String, _DERNumericString = _KJUR_asn1.DERNumericString, _DERPrintableString = _KJUR_asn1.DERPrintableString, _DERTeletexString = _KJUR_asn1.DERTeletexString, _DERIA5String = _KJUR_asn1.DERIA5String, _DERUTCTime = _KJUR_asn1.DERUTCTime, _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime, _DERSequence = _KJUR_asn1.DERSequence, _DERSet = _KJUR_asn1.DERSet, _DERTaggedObject = _KJUR_asn1.DERTaggedObject, _newObject = _KJUR_asn1.ASN1Util.newObject;
            var keys = Object.keys(param);
            if (keys.length != 1)
                throw "key of param shall be only one.";
            var key = keys[0];
            if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
                throw "undefined key: " + key;
            if (key == "bool")
                return new _DERBoolean(param[key]);
            if (key == "int")
                return new _DERInteger(param[key]);
            if (key == "bitstr")
                return new _DERBitString(param[key]);
            if (key == "octstr")
                return new _DEROctetString(param[key]);
            if (key == "null")
                return new _DERNull(param[key]);
            if (key == "oid")
                return new _DERObjectIdentifier(param[key]);
            if (key == "enum")
                return new _DEREnumerated(param[key]);
            if (key == "utf8str")
                return new _DERUTF8String(param[key]);
            if (key == "numstr")
                return new _DERNumericString(param[key]);
            if (key == "prnstr")
                return new _DERPrintableString(param[key]);
            if (key == "telstr")
                return new _DERTeletexString(param[key]);
            if (key == "ia5str")
                return new _DERIA5String(param[key]);
            if (key == "utctime")
                return new _DERUTCTime(param[key]);
            if (key == "gentime")
                return new _DERGeneralizedTime(param[key]);
            if (key == "seq") {
                var paramList = param[key];
                var a = [];
                for (var i = 0; i < paramList.length; i++) {
                    var asn1Obj = _newObject(paramList[i]);
                    a.push(asn1Obj);
                }
                return new _DERSequence({ 'array': a });
            }
            if (key == "set") {
                var paramList = param[key];
                var a = [];
                for (var i = 0; i < paramList.length; i++) {
                    var asn1Obj = _newObject(paramList[i]);
                    a.push(asn1Obj);
                }
                return new _DERSet({ 'array': a });
            }
            if (key == "tag") {
                var tagParam = param[key];
                if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
                    tagParam.length == 3) {
                    var obj = _newObject(tagParam[2]);
                    return new _DERTaggedObject({ tag: tagParam[0],
                        explicit: tagParam[1],
                        obj: obj });
                }
                else {
                    var newParam = {};
                    if (tagParam.explicit !== undefined)
                        newParam.explicit = tagParam.explicit;
                    if (tagParam.tag !== undefined)
                        newParam.tag = tagParam.tag;
                    if (tagParam.obj === undefined)
                        throw "obj shall be specified for 'tag'.";
                    newParam.obj = _newObject(tagParam.obj);
                    return new _DERTaggedObject(newParam);
                }
            }
        };
        /**
         * get encoded hexadecimal string of ASN1Object specifed by JSON parameters
         * @name jsonToASN1HEX
         * @memberOf KJUR.asn1.ASN1Util
         * @function
         * @param {Array} param JSON parameter to generate ASN1Object
         * @return hexadecimal string of ASN1Object
         * @since asn1 1.0.4
         * @description
         * As for ASN.1 object representation of JSON object,
         * please see {@link newObject}.
         * @example
         * jsonToASN1HEX({'prnstr': 'aaa'});
         */
        this.jsonToASN1HEX = function (param) {
            var asn1Obj = this.newObject(param);
            return asn1Obj.getEncodedHex();
        };
    };
    /**
     * get dot noted oid number string from hexadecimal value of OID
     * @name oidHexToInt
     * @memberOf KJUR.asn1.ASN1Util
     * @function
     * @param {String} hex hexadecimal value of object identifier
     * @return {String} dot noted string of object identifier
     * @since jsrsasign 4.8.3 asn1 1.0.7
     * @description
     * This static method converts from hexadecimal string representation of
     * ASN.1 value of object identifier to oid number string.
     * @example
     * KJUR.asn1.ASN1Util.oidHexToInt('550406') &rarr; "2.5.4.6"
     */
    KJUR.asn1.ASN1Util.oidHexToInt = function (hex) {
        var s = "";
        var i01 = parseInt(hex.substr(0, 2), 16);
        var i0 = Math.floor(i01 / 40);
        var i1 = i01 % 40;
        var s = i0 + "." + i1;
        var binbuf = "";
        for (var i = 2; i < hex.length; i += 2) {
            var value = parseInt(hex.substr(i, 2), 16);
            var bin = ("00000000" + value.toString(2)).slice(-8);
            binbuf = binbuf + bin.substr(1, 7);
            if (bin.substr(0, 1) == "0") {
                var bi = new BigInteger(binbuf, 2);
                s = s + "." + bi.toString(10);
                binbuf = "";
            }
        }
        ;
        return s;
    };
    /**
     * get hexadecimal value of object identifier from dot noted oid value
     * @name oidIntToHex
     * @memberOf KJUR.asn1.ASN1Util
     * @function
     * @param {String} oidString dot noted string of object identifier
     * @return {String} hexadecimal value of object identifier
     * @since jsrsasign 4.8.3 asn1 1.0.7
     * @description
     * This static method converts from object identifier value string.
     * to hexadecimal string representation of it.
     * @example
     * KJUR.asn1.ASN1Util.oidIntToHex("2.5.4.6") &rarr; "550406"
     */
    KJUR.asn1.ASN1Util.oidIntToHex = function (oidString) {
        var itox = function (i) {
            var h = i.toString(16);
            if (h.length == 1)
                h = '0' + h;
            return h;
        };
        var roidtox = function (roid) {
            var h = '';
            var bi = new BigInteger(roid, 10);
            var b = bi.toString(2);
            var padLen = 7 - b.length % 7;
            if (padLen == 7)
                padLen = 0;
            var bPad = '';
            for (var i = 0; i < padLen; i++)
                bPad += '0';
            b = bPad + b;
            for (var i = 0; i < b.length - 1; i += 7) {
                var b8 = b.substr(i, 7);
                if (i != b.length - 7)
                    b8 = '1' + b8;
                h += itox(parseInt(b8, 2));
            }
            return h;
        };
        if (!oidString.match(/^[0-9.]+$/)) {
            throw "malformed oid string: " + oidString;
        }
        var h = '';
        var a = oidString.split('.');
        var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
        h += itox(i0);
        a.splice(0, 2);
        for (var i = 0; i < a.length; i++) {
            h += roidtox(a[i]);
        }
        return h;
    };
    // ********************************************************************
    //  Abstract ASN.1 Classes
    // ********************************************************************
    // ********************************************************************
    /**
     * base class for ASN.1 DER encoder object
     * @name KJUR.asn1.ASN1Object
     * @class base class for ASN.1 DER encoder object
     * @property {Boolean} isModified flag whether internal data was changed
     * @property {String} hTLV hexadecimal string of ASN.1 TLV
     * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)
     * @property {String} hL hexadecimal string of ASN.1 TLV length(L)
     * @property {String} hV hexadecimal string of ASN.1 TLV value(V)
     * @description
     */
    KJUR.asn1.ASN1Object = function () {
        var isModified = true;
        var hTLV = null;
        var hT = '00';
        var hL = '00';
        var hV = '';
        /**
         * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)
         * @name getLengthHexFromValue
         * @memberOf KJUR.asn1.ASN1Object#
         * @function
         * @return {String} hexadecimal string of ASN.1 TLV length(L)
         */
        this.getLengthHexFromValue = function () {
            if (typeof this.hV == "undefined" || this.hV == null) {
                throw "this.hV is null or undefined.";
            }
            if (this.hV.length % 2 == 1) {
                throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
            }
            var n = this.hV.length / 2;
            var hN = n.toString(16);
            if (hN.length % 2 == 1) {
                hN = "0" + hN;
            }
            if (n < 128) {
                return hN;
            }
            else {
                var hNlen = hN.length / 2;
                if (hNlen > 15) {
                    throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
                }
                var head = 128 + hNlen;
                return head.toString(16) + hN;
            }
        };
        /**
         * get hexadecimal string of ASN.1 TLV bytes
         * @name getEncodedHex
         * @memberOf KJUR.asn1.ASN1Object#
         * @function
         * @return {String} hexadecimal string of ASN.1 TLV
         */
        this.getEncodedHex = function () {
            if (this.hTLV == null || this.isModified) {
                this.hV = this.getFreshValueHex();
                this.hL = this.getLengthHexFromValue();
                this.hTLV = this.hT + this.hL + this.hV;
                this.isModified = false;
                //alert("first time: " + this.hTLV);
            }
            return this.hTLV;
        };
        /**
         * get hexadecimal string of ASN.1 TLV value(V) bytes
         * @name getValueHex
         * @memberOf KJUR.asn1.ASN1Object#
         * @function
         * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes
         */
        this.getValueHex = function () {
            this.getEncodedHex();
            return this.hV;
        };
        this.getFreshValueHex = function () {
            return '';
        };
    };
    // == BEGIN DERAbstractString ================================================
    /**
     * base class for ASN.1 DER string classes
     * @name KJUR.asn1.DERAbstractString
     * @class base class for ASN.1 DER string classes
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @property {String} s internal string of value
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>str - specify initial ASN.1 value(V) by a string</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     */
    KJUR.asn1.DERAbstractString = function (params) {
        KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
        var s = null;
        var hV = null;
        /**
         * get string value of this string object
         * @name getString
         * @memberOf KJUR.asn1.DERAbstractString#
         * @function
         * @return {String} string value of this string object
         */
        this.getString = function () {
            return this.s;
        };
        /**
         * set value by a string
         * @name setString
         * @memberOf KJUR.asn1.DERAbstractString#
         * @function
         * @param {String} newS value by a string to set
         */
        this.setString = function (newS) {
            this.hTLV = null;
            this.isModified = true;
            this.s = newS;
            this.hV = stohex(this.s);
        };
        /**
         * set value by a hexadecimal string
         * @name setStringHex
         * @memberOf KJUR.asn1.DERAbstractString#
         * @function
         * @param {String} newHexString value by a hexadecimal string to set
         */
        this.setStringHex = function (newHexString) {
            this.hTLV = null;
            this.isModified = true;
            this.s = null;
            this.hV = newHexString;
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params == "string") {
                this.setString(params);
            }
            else if (typeof params['str'] != "undefined") {
                this.setString(params['str']);
            }
            else if (typeof params['hex'] != "undefined") {
                this.setStringHex(params['hex']);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
    // == END   DERAbstractString ================================================
    // == BEGIN DERAbstractTime ==================================================
    /**
     * base class for ASN.1 DER Generalized/UTCTime class
     * @name KJUR.asn1.DERAbstractTime
     * @class base class for ASN.1 DER Generalized/UTCTime class
     * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
     * @extends KJUR.asn1.ASN1Object
     * @description
     * @see KJUR.asn1.ASN1Object - superclass
     */
    KJUR.asn1.DERAbstractTime = function (params) {
        KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
        var s = null;
        var date = null;
        // --- PRIVATE METHODS --------------------
        this.localDateToUTC = function (d) {
            utc = d.getTime() + (d.getTimezoneOffset() * 60000);
            var utcDate = new Date(utc);
            return utcDate;
        };
        /*
         * format date string by Data object
         * @name formatDate
         * @memberOf KJUR.asn1.AbstractTime;
         * @param {Date} dateObject
         * @param {string} type 'utc' or 'gen'
         * @param {boolean} withMillis flag for with millisections or not
         * @description
         * 'withMillis' flag is supported from asn1 1.0.6.
         */
        this.formatDate = function (dateObject, type, withMillis) {
            var pad = this.zeroPadding;
            var d = this.localDateToUTC(dateObject);
            var year = String(d.getFullYear());
            if (type == 'utc')
                year = year.substr(2, 2);
            var month = pad(String(d.getMonth() + 1), 2);
            var day = pad(String(d.getDate()), 2);
            var hour = pad(String(d.getHours()), 2);
            var min = pad(String(d.getMinutes()), 2);
            var sec = pad(String(d.getSeconds()), 2);
            var s = year + month + day + hour + min + sec;
            if (withMillis === true) {
                var millis = d.getMilliseconds();
                if (millis != 0) {
                    var sMillis = pad(String(millis), 3);
                    sMillis = sMillis.replace(/[0]+$/, "");
                    s = s + "." + sMillis;
                }
            }
            return s + "Z";
        };
        this.zeroPadding = function (s, len) {
            if (s.length >= len)
                return s;
            return new Array(len - s.length + 1).join('0') + s;
        };
        // --- PUBLIC METHODS --------------------
        /**
         * get string value of this string object
         * @name getString
         * @memberOf KJUR.asn1.DERAbstractTime#
         * @function
         * @return {String} string value of this time object
         */
        this.getString = function () {
            return this.s;
        };
        /**
         * set value by a string
         * @name setString
         * @memberOf KJUR.asn1.DERAbstractTime#
         * @function
         * @param {String} newS value by a string to set such like "130430235959Z"
         */
        this.setString = function (newS) {
            this.hTLV = null;
            this.isModified = true;
            this.s = newS;
            this.hV = stohex(newS);
        };
        /**
         * set value by a Date object
         * @name setByDateValue
         * @memberOf KJUR.asn1.DERAbstractTime#
         * @function
         * @param {Integer} year year of date (ex. 2013)
         * @param {Integer} month month of date between 1 and 12 (ex. 12)
         * @param {Integer} day day of month
         * @param {Integer} hour hours of date
         * @param {Integer} min minutes of date
         * @param {Integer} sec seconds of date
         */
        this.setByDateValue = function (year, month, day, hour, min, sec) {
            var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
            this.setByDate(dateObject);
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
    };
    YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
    // == END   DERAbstractTime ==================================================
    // == BEGIN DERAbstractStructured ============================================
    /**
     * base class for ASN.1 DER structured class
     * @name KJUR.asn1.DERAbstractStructured
     * @class base class for ASN.1 DER structured class
     * @property {Array} asn1Array internal array of ASN1Object
     * @extends KJUR.asn1.ASN1Object
     * @description
     * @see KJUR.asn1.ASN1Object - superclass
     */
    KJUR.asn1.DERAbstractStructured = function (params) {
        KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
        var asn1Array = null;
        /**
         * set value by array of ASN1Object
         * @name setByASN1ObjectArray
         * @memberOf KJUR.asn1.DERAbstractStructured#
         * @function
         * @param {array} asn1ObjectArray array of ASN1Object to set
         */
        this.setByASN1ObjectArray = function (asn1ObjectArray) {
            this.hTLV = null;
            this.isModified = true;
            this.asn1Array = asn1ObjectArray;
        };
        /**
         * append an ASN1Object to internal array
         * @name appendASN1Object
         * @memberOf KJUR.asn1.DERAbstractStructured#
         * @function
         * @param {ASN1Object} asn1Object to add
         */
        this.appendASN1Object = function (asn1Object) {
            this.hTLV = null;
            this.isModified = true;
            this.asn1Array.push(asn1Object);
        };
        this.asn1Array = new Array();
        if (typeof params != "undefined") {
            if (typeof params['array'] != "undefined") {
                this.asn1Array = params['array'];
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
    // ********************************************************************
    //  ASN.1 Object Classes
    // ********************************************************************
    // ********************************************************************
    /**
     * class for ASN.1 DER Boolean
     * @name KJUR.asn1.DERBoolean
     * @class class for ASN.1 DER Boolean
     * @extends KJUR.asn1.ASN1Object
     * @description
     * @see KJUR.asn1.ASN1Object - superclass
     */
    KJUR.asn1.DERBoolean = function () {
        KJUR.asn1.DERBoolean.superclass.constructor.call(this);
        this.hT = "01";
        this.hTLV = "0101ff";
    };
    YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER Integer
     * @name KJUR.asn1.DERInteger
     * @class class for ASN.1 DER Integer
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>int - specify initial ASN.1 value(V) by integer value</li>
     * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     */
    KJUR.asn1.DERInteger = function (params) {
        KJUR.asn1.DERInteger.superclass.constructor.call(this);
        this.hT = "02";
        /**
         * set value by Tom Wu's BigInteger object
         * @name setByBigInteger
         * @memberOf KJUR.asn1.DERInteger#
         * @function
         * @param {BigInteger} bigIntegerValue to set
         */
        this.setByBigInteger = function (bigIntegerValue) {
            this.hTLV = null;
            this.isModified = true;
            this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
        };
        /**
         * set value by integer value
         * @name setByInteger
         * @memberOf KJUR.asn1.DERInteger
         * @function
         * @param {Integer} integer value to set
         */
        this.setByInteger = function (intValue) {
            var bi = new BigInteger(String(intValue), 10);
            this.setByBigInteger(bi);
        };
        /**
         * set value by integer value
         * @name setValueHex
         * @memberOf KJUR.asn1.DERInteger#
         * @function
         * @param {String} hexadecimal string of integer value
         * @description
         * <br/>
         * NOTE: Value shall be represented by minimum octet length of
         * two's complement representation.
         * @example
         * new KJUR.asn1.DERInteger(123);
         * new KJUR.asn1.DERInteger({'int': 123});
         * new KJUR.asn1.DERInteger({'hex': '1fad'});
         */
        this.setValueHex = function (newHexString) {
            this.hV = newHexString;
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params['bigint'] != "undefined") {
                this.setByBigInteger(params['bigint']);
            }
            else if (typeof params['int'] != "undefined") {
                this.setByInteger(params['int']);
            }
            else if (typeof params == "number") {
                this.setByInteger(params);
            }
            else if (typeof params['hex'] != "undefined") {
                this.setValueHex(params['hex']);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER encoded BitString primitive
     * @name KJUR.asn1.DERBitString
     * @class class for ASN.1 DER encoded BitString primitive
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>bin - specify binary string (ex. '10111')</li>
     * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
     * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
     * <li>obj - specify {@link KJUR.asn1.ASN1Util.newObject}
     * argument for "BitString encapsulates" structure.</li>
     * </ul>
     * NOTE1: 'params' can be omitted.<br/>
     * NOTE2: 'obj' parameter have been supported since
     * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).<br/>
     * @example
     * // default constructor
     * o = new KJUR.asn1.DERBitString();
     * // initialize with binary string
     * o = new KJUR.asn1.DERBitString({bin: "1011"});
     * // initialize with boolean array
     * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]});
     * // initialize with hexadecimal string (04 is unused bits)
     * o = new KJUR.asn1.DEROctetString({hex: "04bac0"});
     * // initialize with ASN1Util.newObject argument for encapsulated
     * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
     * // above generates a ASN.1 data like this:
     * // BIT STRING, encapsulates {
     * //   SEQUENCE {
     * //     INTEGER 3
     * //     PrintableString 'aaa'
     * //     }
     * //   }
     */
    KJUR.asn1.DERBitString = function (params) {
        if (params !== undefined && typeof params.obj !== "undefined") {
            var o = KJUR.asn1.ASN1Util.newObject(params.obj);
            params.hex = "00" + o.getEncodedHex();
        }
        KJUR.asn1.DERBitString.superclass.constructor.call(this);
        this.hT = "03";
        /**
         * set ASN.1 value(V) by a hexadecimal string including unused bits
         * @name setHexValueIncludingUnusedBits
         * @memberOf KJUR.asn1.DERBitString#
         * @function
         * @param {String} newHexStringIncludingUnusedBits
         */
        this.setHexValueIncludingUnusedBits = function (newHexStringIncludingUnusedBits) {
            this.hTLV = null;
            this.isModified = true;
            this.hV = newHexStringIncludingUnusedBits;
        };
        /**
         * set ASN.1 value(V) by unused bit and hexadecimal string of value
         * @name setUnusedBitsAndHexValue
         * @memberOf KJUR.asn1.DERBitString#
         * @function
         * @param {Integer} unusedBits
         * @param {String} hValue
         */
        this.setUnusedBitsAndHexValue = function (unusedBits, hValue) {
            if (unusedBits < 0 || 7 < unusedBits) {
                throw "unused bits shall be from 0 to 7: u = " + unusedBits;
            }
            var hUnusedBits = "0" + unusedBits;
            this.hTLV = null;
            this.isModified = true;
            this.hV = hUnusedBits + hValue;
        };
        /**
         * set ASN.1 DER BitString by binary string<br/>
         * @name setByBinaryString
         * @memberOf KJUR.asn1.DERBitString#
         * @function
         * @param {String} binaryString binary value string (i.e. '10111')
         * @description
         * Its unused bits will be calculated automatically by length of
         * 'binaryValue'. <br/>
         * NOTE: Trailing zeros '0' will be ignored.
         * @example
         * o = new KJUR.asn1.DERBitString();
         * o.setByBooleanArray("01011");
         */
        this.setByBinaryString = function (binaryString) {
            binaryString = binaryString.replace(/0+$/, '');
            var unusedBits = 8 - binaryString.length % 8;
            if (unusedBits == 8)
                unusedBits = 0;
            for (var i = 0; i <= unusedBits; i++) {
                binaryString += '0';
            }
            var h = '';
            for (var i = 0; i < binaryString.length - 1; i += 8) {
                var b = binaryString.substr(i, 8);
                var x = parseInt(b, 2).toString(16);
                if (x.length == 1)
                    x = '0' + x;
                h += x;
            }
            this.hTLV = null;
            this.isModified = true;
            this.hV = '0' + unusedBits + h;
        };
        /**
         * set ASN.1 TLV value(V) by an array of boolean<br/>
         * @name setByBooleanArray
         * @memberOf KJUR.asn1.DERBitString#
         * @function
         * @param {array} booleanArray array of boolean (ex. [true, false, true])
         * @description
         * NOTE: Trailing falses will be ignored in the ASN.1 DER Object.
         * @example
         * o = new KJUR.asn1.DERBitString();
         * o.setByBooleanArray([false, true, false, true, true]);
         */
        this.setByBooleanArray = function (booleanArray) {
            var s = '';
            for (var i = 0; i < booleanArray.length; i++) {
                if (booleanArray[i] == true) {
                    s += '1';
                }
                else {
                    s += '0';
                }
            }
            this.setByBinaryString(s);
        };
        /**
         * generate an array of falses with specified length<br/>
         * @name newFalseArray
         * @memberOf KJUR.asn1.DERBitString
         * @function
         * @param {Integer} nLength length of array to generate
         * @return {array} array of boolean falses
         * @description
         * This static method may be useful to initialize boolean array.
         * @example
         * o = new KJUR.asn1.DERBitString();
         * o.newFalseArray(3) &rarr; [false, false, false]
         */
        this.newFalseArray = function (nLength) {
            var a = new Array(nLength);
            for (var i = 0; i < nLength; i++) {
                a[i] = false;
            }
            return a;
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
                this.setHexValueIncludingUnusedBits(params);
            }
            else if (typeof params['hex'] != "undefined") {
                this.setHexValueIncludingUnusedBits(params['hex']);
            }
            else if (typeof params['bin'] != "undefined") {
                this.setByBinaryString(params['bin']);
            }
            else if (typeof params['array'] != "undefined") {
                this.setByBooleanArray(params['array']);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER OctetString<br/>
     * @name KJUR.asn1.DEROctetString
     * @class class for ASN.1 DER OctetString
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * This class provides ASN.1 OctetString simple type.<br/>
     * Supported "params" attributes are:
     * <ul>
     * <li>str - to set a string as a value</li>
     * <li>hex - to set a hexadecimal string as a value</li>
     * <li>obj - to set a encapsulated ASN.1 value by JSON object
     * which is defined in {@link KJUR.asn1.ASN1Util.newObject}</li>
     * </ul>
     * NOTE: A parameter 'obj' have been supported
     * for "OCTET STRING, encapsulates" structure.
     * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
     * @see KJUR.asn1.DERAbstractString - superclass
     * @example
     * // default constructor
     * o = new KJUR.asn1.DEROctetString();
     * // initialize with string
     * o = new KJUR.asn1.DEROctetString({str: "aaa"});
     * // initialize with hexadecimal string
     * o = new KJUR.asn1.DEROctetString({hex: "616161"});
     * // initialize with ASN1Util.newObject argument
     * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
     * // above generates a ASN.1 data like this:
     * // OCTET STRING, encapsulates {
     * //   SEQUENCE {
     * //     INTEGER 3
     * //     PrintableString 'aaa'
     * //     }
     * //   }
     */
    KJUR.asn1.DEROctetString = function (params) {
        if (params !== undefined && typeof params.obj !== "undefined") {
            var o = KJUR.asn1.ASN1Util.newObject(params.obj);
            params.hex = o.getEncodedHex();
        }
        KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
        this.hT = "04";
    };
    YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER Null
     * @name KJUR.asn1.DERNull
     * @class class for ASN.1 DER Null
     * @extends KJUR.asn1.ASN1Object
     * @description
     * @see KJUR.asn1.ASN1Object - superclass
     */
    KJUR.asn1.DERNull = function () {
        KJUR.asn1.DERNull.superclass.constructor.call(this);
        this.hT = "05";
        this.hTLV = "0500";
    };
    YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER ObjectIdentifier
     * @name KJUR.asn1.DERObjectIdentifier
     * @class class for ASN.1 DER ObjectIdentifier
     * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     */
    KJUR.asn1.DERObjectIdentifier = function (params) {
        var itox = function (i) {
            var h = i.toString(16);
            if (h.length == 1)
                h = '0' + h;
            return h;
        };
        var roidtox = function (roid) {
            var h = '';
            var bi = new BigInteger(roid, 10);
            var b = bi.toString(2);
            var padLen = 7 - b.length % 7;
            if (padLen == 7)
                padLen = 0;
            var bPad = '';
            for (var i = 0; i < padLen; i++)
                bPad += '0';
            b = bPad + b;
            for (var i = 0; i < b.length - 1; i += 7) {
                var b8 = b.substr(i, 7);
                if (i != b.length - 7)
                    b8 = '1' + b8;
                h += itox(parseInt(b8, 2));
            }
            return h;
        };
        KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
        this.hT = "06";
        /**
         * set value by a hexadecimal string
         * @name setValueHex
         * @memberOf KJUR.asn1.DERObjectIdentifier#
         * @function
         * @param {String} newHexString hexadecimal value of OID bytes
         */
        this.setValueHex = function (newHexString) {
            this.hTLV = null;
            this.isModified = true;
            this.s = null;
            this.hV = newHexString;
        };
        /**
         * set value by a OID string<br/>
         * @name setValueOidString
         * @memberOf KJUR.asn1.DERObjectIdentifier#
         * @function
         * @param {String} oidString OID string (ex. 2.5.4.13)
         * @example
         * o = new KJUR.asn1.DERObjectIdentifier();
         * o.setValueOidString("2.5.4.13");
         */
        this.setValueOidString = function (oidString) {
            if (!oidString.match(/^[0-9.]+$/)) {
                throw "malformed oid string: " + oidString;
            }
            var h = '';
            var a = oidString.split('.');
            var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
            h += itox(i0);
            a.splice(0, 2);
            for (var i = 0; i < a.length; i++) {
                h += roidtox(a[i]);
            }
            this.hTLV = null;
            this.isModified = true;
            this.s = null;
            this.hV = h;
        };
        /**
         * set value by a OID name
         * @name setValueName
         * @memberOf KJUR.asn1.DERObjectIdentifier#
         * @function
         * @param {String} oidName OID name (ex. 'serverAuth')
         * @since 1.0.1
         * @description
         * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
         * Otherwise raise error.
         * @example
         * o = new KJUR.asn1.DERObjectIdentifier();
         * o.setValueName("serverAuth");
         */
        this.setValueName = function (oidName) {
            var oid = KJUR.asn1.x509.OID.name2oid(oidName);
            if (oid !== '') {
                this.setValueOidString(oid);
            }
            else {
                throw "DERObjectIdentifier oidName undefined: " + oidName;
            }
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (params !== undefined) {
            if (typeof params === "string") {
                if (params.match(/^[0-2].[0-9.]+$/)) {
                    this.setValueOidString(params);
                }
                else {
                    this.setValueName(params);
                }
            }
            else if (params.oid !== undefined) {
                this.setValueOidString(params.oid);
            }
            else if (params.hex !== undefined) {
                this.setValueHex(params.hex);
            }
            else if (params.name !== undefined) {
                this.setValueName(params.name);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER Enumerated
     * @name KJUR.asn1.DEREnumerated
     * @class class for ASN.1 DER Enumerated
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>int - specify initial ASN.1 value(V) by integer value</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     * @example
     * new KJUR.asn1.DEREnumerated(123);
     * new KJUR.asn1.DEREnumerated({int: 123});
     * new KJUR.asn1.DEREnumerated({hex: '1fad'});
     */
    KJUR.asn1.DEREnumerated = function (params) {
        KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
        this.hT = "0a";
        /**
         * set value by Tom Wu's BigInteger object
         * @name setByBigInteger
         * @memberOf KJUR.asn1.DEREnumerated#
         * @function
         * @param {BigInteger} bigIntegerValue to set
         */
        this.setByBigInteger = function (bigIntegerValue) {
            this.hTLV = null;
            this.isModified = true;
            this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
        };
        /**
         * set value by integer value
         * @name setByInteger
         * @memberOf KJUR.asn1.DEREnumerated#
         * @function
         * @param {Integer} integer value to set
         */
        this.setByInteger = function (intValue) {
            var bi = new BigInteger(String(intValue), 10);
            this.setByBigInteger(bi);
        };
        /**
         * set value by integer value
         * @name setValueHex
         * @memberOf KJUR.asn1.DEREnumerated#
         * @function
         * @param {String} hexadecimal string of integer value
         * @description
         * <br/>
         * NOTE: Value shall be represented by minimum octet length of
         * two's complement representation.
         */
        this.setValueHex = function (newHexString) {
            this.hV = newHexString;
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params['int'] != "undefined") {
                this.setByInteger(params['int']);
            }
            else if (typeof params == "number") {
                this.setByInteger(params);
            }
            else if (typeof params['hex'] != "undefined") {
                this.setValueHex(params['hex']);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
    // ********************************************************************
    /**
     * class for ASN.1 DER UTF8String
     * @name KJUR.asn1.DERUTF8String
     * @class class for ASN.1 DER UTF8String
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * @see KJUR.asn1.DERAbstractString - superclass
     */
    KJUR.asn1.DERUTF8String = function (params) {
        KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
        this.hT = "0c";
    };
    YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER NumericString
     * @name KJUR.asn1.DERNumericString
     * @class class for ASN.1 DER NumericString
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * @see KJUR.asn1.DERAbstractString - superclass
     */
    KJUR.asn1.DERNumericString = function (params) {
        KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
        this.hT = "12";
    };
    YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER PrintableString
     * @name KJUR.asn1.DERPrintableString
     * @class class for ASN.1 DER PrintableString
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * @see KJUR.asn1.DERAbstractString - superclass
     */
    KJUR.asn1.DERPrintableString = function (params) {
        KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
        this.hT = "13";
    };
    YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER TeletexString
     * @name KJUR.asn1.DERTeletexString
     * @class class for ASN.1 DER TeletexString
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * @see KJUR.asn1.DERAbstractString - superclass
     */
    KJUR.asn1.DERTeletexString = function (params) {
        KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
        this.hT = "14";
    };
    YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER IA5String
     * @name KJUR.asn1.DERIA5String
     * @class class for ASN.1 DER IA5String
     * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
     * @extends KJUR.asn1.DERAbstractString
     * @description
     * @see KJUR.asn1.DERAbstractString - superclass
     */
    KJUR.asn1.DERIA5String = function (params) {
        KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
        this.hT = "16";
    };
    YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
    // ********************************************************************
    /**
     * class for ASN.1 DER UTCTime
     * @name KJUR.asn1.DERUTCTime
     * @class class for ASN.1 DER UTCTime
     * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
     * @extends KJUR.asn1.DERAbstractTime
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * <li>date - specify Date object.</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     * <h4>EXAMPLES</h4>
     * @example
     * d1 = new KJUR.asn1.DERUTCTime();
     * d1.setString('130430125959Z');
     *
     * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
     * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
     * d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
     */
    KJUR.asn1.DERUTCTime = function (params) {
        KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
        this.hT = "17";
        /**
         * set value by a Date object<br/>
         * @name setByDate
         * @memberOf KJUR.asn1.DERUTCTime#
         * @function
         * @param {Date} dateObject Date object to set ASN.1 value(V)
         * @example
         * o = new KJUR.asn1.DERUTCTime();
         * o.setByDate(new Date("2016/12/31"));
         */
        this.setByDate = function (dateObject) {
            this.hTLV = null;
            this.isModified = true;
            this.date = dateObject;
            this.s = this.formatDate(this.date, 'utc');
            this.hV = stohex(this.s);
        };
        this.getFreshValueHex = function () {
            if (typeof this.date == "undefined" && typeof this.s == "undefined") {
                this.date = new Date();
                this.s = this.formatDate(this.date, 'utc');
                this.hV = stohex(this.s);
            }
            return this.hV;
        };
        if (params !== undefined) {
            if (params.str !== undefined) {
                this.setString(params.str);
            }
            else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
                this.setString(params);
            }
            else if (params.hex !== undefined) {
                this.setStringHex(params.hex);
            }
            else if (params.date !== undefined) {
                this.setByDate(params.date);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
    // ********************************************************************
    /**
     * class for ASN.1 DER GeneralizedTime
     * @name KJUR.asn1.DERGeneralizedTime
     * @class class for ASN.1 DER GeneralizedTime
     * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
     * @property {Boolean} withMillis flag to show milliseconds or not
     * @extends KJUR.asn1.DERAbstractTime
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
     * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
     * <li>date - specify Date object.</li>
     * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
     * </ul>
     * NOTE1: 'params' can be omitted.
     * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
     */
    KJUR.asn1.DERGeneralizedTime = function (params) {
        KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
        this.hT = "18";
        this.withMillis = false;
        /**
         * set value by a Date object
         * @name setByDate
         * @memberOf KJUR.asn1.DERGeneralizedTime#
         * @function
         * @param {Date} dateObject Date object to set ASN.1 value(V)
         * @example
         * When you specify UTC time, use 'Date.UTC' method like this:<br/>
         * o1 = new DERUTCTime();
         * o1.setByDate(date);
         *
         * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
         */
        this.setByDate = function (dateObject) {
            this.hTLV = null;
            this.isModified = true;
            this.date = dateObject;
            this.s = this.formatDate(this.date, 'gen', this.withMillis);
            this.hV = stohex(this.s);
        };
        this.getFreshValueHex = function () {
            if (this.date === undefined && this.s === undefined) {
                this.date = new Date();
                this.s = this.formatDate(this.date, 'gen', this.withMillis);
                this.hV = stohex(this.s);
            }
            return this.hV;
        };
        if (params !== undefined) {
            if (params.str !== undefined) {
                this.setString(params.str);
            }
            else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
                this.setString(params);
            }
            else if (params.hex !== undefined) {
                this.setStringHex(params.hex);
            }
            else if (params.date !== undefined) {
                this.setByDate(params.date);
            }
            if (params.millis === true) {
                this.withMillis = true;
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
    // ********************************************************************
    /**
     * class for ASN.1 DER Sequence
     * @name KJUR.asn1.DERSequence
     * @class class for ASN.1 DER Sequence
     * @extends KJUR.asn1.DERAbstractStructured
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>array - specify array of ASN1Object to set elements of content</li>
     * </ul>
     * NOTE: 'params' can be omitted.
     */
    KJUR.asn1.DERSequence = function (params) {
        KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
        this.hT = "30";
        this.getFreshValueHex = function () {
            var h = '';
            for (var i = 0; i < this.asn1Array.length; i++) {
                var asn1Obj = this.asn1Array[i];
                h += asn1Obj.getEncodedHex();
            }
            this.hV = h;
            return this.hV;
        };
    };
    YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
    // ********************************************************************
    /**
     * class for ASN.1 DER Set
     * @name KJUR.asn1.DERSet
     * @class class for ASN.1 DER Set
     * @extends KJUR.asn1.DERAbstractStructured
     * @description
     * <br/>
     * As for argument 'params' for constructor, you can specify one of
     * following properties:
     * <ul>
     * <li>array - specify array of ASN1Object to set elements of content</li>
     * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
     * </ul>
     * NOTE1: 'params' can be omitted.<br/>
     * NOTE2: sortflag is supported since 1.0.5.
     */
    KJUR.asn1.DERSet = function (params) {
        KJUR.asn1.DERSet.superclass.constructor.call(this, params);
        this.hT = "31";
        this.sortFlag = true; // item shall be sorted only in ASN.1 DER
        this.getFreshValueHex = function () {
            var a = new Array();
            for (var i = 0; i < this.asn1Array.length; i++) {
                var asn1Obj = this.asn1Array[i];
                a.push(asn1Obj.getEncodedHex());
            }
            if (this.sortFlag == true)
                a.sort();
            this.hV = a.join('');
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params.sortflag != "undefined" &&
                params.sortflag == false)
                this.sortFlag = false;
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
    // ********************************************************************
    /**
     * class for ASN.1 DER TaggedObject
     * @name KJUR.asn1.DERTaggedObject
     * @class class for ASN.1 DER TaggedObject
     * @extends KJUR.asn1.ASN1Object
     * @description
     * <br/>
     * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
     * For example, if you find '[1]' tag in a ASN.1 dump,
     * 'tagNoHex' will be 'a1'.
     * <br/>
     * As for optional argument 'params' for constructor, you can specify *ANY* of
     * following properties:
     * <ul>
     * <li>explicit - specify true if this is explicit tag otherwise false
     *     (default is 'true').</li>
     * <li>tag - specify tag (default is 'a0' which means [0])</li>
     * <li>obj - specify ASN1Object which is tagged</li>
     * </ul>
     * @example
     * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
     * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
     * hex = d2.getEncodedHex();
     */
    KJUR.asn1.DERTaggedObject = function (params) {
        KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
        this.hT = "a0";
        this.hV = '';
        this.isExplicit = true;
        this.asn1Object = null;
        /**
         * set value by an ASN1Object
         * @name setString
         * @memberOf KJUR.asn1.DERTaggedObject#
         * @function
         * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
         * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
         * @param {ASN1Object} asn1Object ASN.1 to encapsulate
         */
        this.setASN1Object = function (isExplicitFlag, tagNoHex, asn1Object) {
            this.hT = tagNoHex;
            this.isExplicit = isExplicitFlag;
            this.asn1Object = asn1Object;
            if (this.isExplicit) {
                this.hV = this.asn1Object.getEncodedHex();
                this.hTLV = null;
                this.isModified = true;
            }
            else {
                this.hV = null;
                this.hTLV = asn1Object.getEncodedHex();
                this.hTLV = this.hTLV.replace(/^../, tagNoHex);
                this.isModified = false;
            }
        };
        this.getFreshValueHex = function () {
            return this.hV;
        };
        if (typeof params != "undefined") {
            if (typeof params['tag'] != "undefined") {
                this.hT = params['tag'];
            }
            if (typeof params['explicit'] != "undefined") {
                this.isExplicit = params['explicit'];
            }
            if (typeof params['obj'] != "undefined") {
                this.asn1Object = params['obj'];
                this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
            }
        }
    };
    YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);

    var __extends = (undefined && undefined.__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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            if (typeof b !== "function" && b !== null)
                throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    /**
     * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object.
     * This object is just a decorator for parsing the key parameter
     * @param {string|Object} key - The key in string format, or an object containing
     * the parameters needed to build a RSAKey object.
     * @constructor
     */
    var JSEncryptRSAKey = /** @class */ (function (_super) {
        __extends(JSEncryptRSAKey, _super);
        function JSEncryptRSAKey(key) {
            var _this = _super.call(this) || this;
            // Call the super constructor.
            //  RSAKey.call(this);
            // If a key key was provided.
            if (key) {
                // If this is a string...
                if (typeof key === "string") {
                    _this.parseKey(key);
                }
                else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) ||
                    JSEncryptRSAKey.hasPublicKeyProperty(key)) {
                    // Set the values for the key.
                    _this.parsePropertiesFrom(key);
                }
            }
            return _this;
        }
        /**
         * Method to parse a pem encoded string containing both a public or private key.
         * The method will translate the pem encoded string in a der encoded string and
         * will parse private key and public key parameters. This method accepts public key
         * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).
         *
         * @todo Check how many rsa formats use the same format of pkcs #1.
         *
         * The format is defined as:
         * PublicKeyInfo ::= SEQUENCE {
         *   algorithm       AlgorithmIdentifier,
         *   PublicKey       BIT STRING
         * }
         * Where AlgorithmIdentifier is:
         * AlgorithmIdentifier ::= SEQUENCE {
         *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
         *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
         * }
         * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
         * RSAPublicKey ::= SEQUENCE {
         *   modulus           INTEGER,  -- n
         *   publicExponent    INTEGER   -- e
         * }
         * it's possible to examine the structure of the keys obtained from openssl using
         * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/
         * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer
         * @private
         */
        JSEncryptRSAKey.prototype.parseKey = function (pem) {
            try {
                var modulus = 0;
                var public_exponent = 0;
                var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/;
                var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem);
                var asn1 = ASN1.decode(der);
                // Fixes a bug with OpenSSL 1.0+ private keys
                if (asn1.sub.length === 3) {
                    asn1 = asn1.sub[2].sub[0];
                }
                if (asn1.sub.length === 9) {
                    // Parse the private key.
                    modulus = asn1.sub[1].getHexStringValue(); // bigint
                    this.n = parseBigInt(modulus, 16);
                    public_exponent = asn1.sub[2].getHexStringValue(); // int
                    this.e = parseInt(public_exponent, 16);
                    var private_exponent = asn1.sub[3].getHexStringValue(); // bigint
                    this.d = parseBigInt(private_exponent, 16);
                    var prime1 = asn1.sub[4].getHexStringValue(); // bigint
                    this.p = parseBigInt(prime1, 16);
                    var prime2 = asn1.sub[5].getHexStringValue(); // bigint
                    this.q = parseBigInt(prime2, 16);
                    var exponent1 = asn1.sub[6].getHexStringValue(); // bigint
                    this.dmp1 = parseBigInt(exponent1, 16);
                    var exponent2 = asn1.sub[7].getHexStringValue(); // bigint
                    this.dmq1 = parseBigInt(exponent2, 16);
                    var coefficient = asn1.sub[8].getHexStringValue(); // bigint
                    this.coeff = parseBigInt(coefficient, 16);
                }
                else if (asn1.sub.length === 2) {
                    if (asn1.sub[0].sub) {
                        // Parse ASN.1 SubjectPublicKeyInfo type as defined by X.509
                        var bit_string = asn1.sub[1];
                        var sequence = bit_string.sub[0];
                        modulus = sequence.sub[0].getHexStringValue();
                        this.n = parseBigInt(modulus, 16);
                        public_exponent = sequence.sub[1].getHexStringValue();
                        this.e = parseInt(public_exponent, 16);
                    }
                    else {
                        // Parse ASN.1 RSAPublicKey type as defined by PKCS #1
                        modulus = asn1.sub[0].getHexStringValue();
                        this.n = parseBigInt(modulus, 16);
                        public_exponent = asn1.sub[1].getHexStringValue();
                        this.e = parseInt(public_exponent, 16);
                    }
                }
                else {
                    return false;
                }
                return true;
            }
            catch (ex) {
                return false;
            }
        };
        /**
         * Translate rsa parameters in a hex encoded string representing the rsa key.
         *
         * The translation follow the ASN.1 notation :
         * RSAPrivateKey ::= SEQUENCE {
         *   version           Version,
         *   modulus           INTEGER,  -- n
         *   publicExponent    INTEGER,  -- e
         *   privateExponent   INTEGER,  -- d
         *   prime1            INTEGER,  -- p
         *   prime2            INTEGER,  -- q
         *   exponent1         INTEGER,  -- d mod (p1)
         *   exponent2         INTEGER,  -- d mod (q-1)
         *   coefficient       INTEGER,  -- (inverse of q) mod p
         * }
         * @returns {string}  DER Encoded String representing the rsa private key
         * @private
         */
        JSEncryptRSAKey.prototype.getPrivateBaseKey = function () {
            var options = {
                array: [
                    new KJUR.asn1.DERInteger({ int: 0 }),
                    new KJUR.asn1.DERInteger({ bigint: this.n }),
                    new KJUR.asn1.DERInteger({ int: this.e }),
                    new KJUR.asn1.DERInteger({ bigint: this.d }),
                    new KJUR.asn1.DERInteger({ bigint: this.p }),
                    new KJUR.asn1.DERInteger({ bigint: this.q }),
                    new KJUR.asn1.DERInteger({ bigint: this.dmp1 }),
                    new KJUR.asn1.DERInteger({ bigint: this.dmq1 }),
                    new KJUR.asn1.DERInteger({ bigint: this.coeff }),
                ],
            };
            var seq = new KJUR.asn1.DERSequence(options);
            return seq.getEncodedHex();
        };
        /**
         * base64 (pem) encoded version of the DER encoded representation
         * @returns {string} pem encoded representation without header and footer
         * @public
         */
        JSEncryptRSAKey.prototype.getPrivateBaseKeyB64 = function () {
            return hex2b64(this.getPrivateBaseKey());
        };
        /**
         * Translate rsa parameters in a hex encoded string representing the rsa public key.
         * The representation follow the ASN.1 notation :
         * PublicKeyInfo ::= SEQUENCE {
         *   algorithm       AlgorithmIdentifier,
         *   PublicKey       BIT STRING
         * }
         * Where AlgorithmIdentifier is:
         * AlgorithmIdentifier ::= SEQUENCE {
         *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
         *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
         * }
         * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
         * RSAPublicKey ::= SEQUENCE {
         *   modulus           INTEGER,  -- n
         *   publicExponent    INTEGER   -- e
         * }
         * @returns {string} DER Encoded String representing the rsa public key
         * @private
         */
        JSEncryptRSAKey.prototype.getPublicBaseKey = function () {
            var first_sequence = new KJUR.asn1.DERSequence({
                array: [
                    new KJUR.asn1.DERObjectIdentifier({ oid: "1.2.840.113549.1.1.1" }),
                    new KJUR.asn1.DERNull(),
                ],
            });
            var second_sequence = new KJUR.asn1.DERSequence({
                array: [
                    new KJUR.asn1.DERInteger({ bigint: this.n }),
                    new KJUR.asn1.DERInteger({ int: this.e }),
                ],
            });
            var bit_string = new KJUR.asn1.DERBitString({
                hex: "00" + second_sequence.getEncodedHex(),
            });
            var seq = new KJUR.asn1.DERSequence({
                array: [first_sequence, bit_string],
            });
            return seq.getEncodedHex();
        };
        /**
         * base64 (pem) encoded version of the DER encoded representation
         * @returns {string} pem encoded representation without header and footer
         * @public
         */
        JSEncryptRSAKey.prototype.getPublicBaseKeyB64 = function () {
            return hex2b64(this.getPublicBaseKey());
        };
        /**
         * wrap the string in block of width chars. The default value for rsa keys is 64
         * characters.
         * @param {string} str the pem encoded string without header and footer
         * @param {Number} [width=64] - the length the string has to be wrapped at
         * @returns {string}
         * @private
         */
        JSEncryptRSAKey.wordwrap = function (str, width) {
            width = width || 64;
            if (!str) {
                return str;
            }
            var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})";
            return str.match(RegExp(regex, "g")).join("\n");
        };
        /**
         * Retrieve the pem encoded private key
         * @returns {string} the pem encoded private key with header/footer
         * @public
         */
        JSEncryptRSAKey.prototype.getPrivateKey = function () {
            var key = "-----BEGIN RSA PRIVATE KEY-----\n";
            key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "\n";
            key += "-----END RSA PRIVATE KEY-----";
            return key;
        };
        /**
         * Retrieve the pem encoded public key
         * @returns {string} the pem encoded public key with header/footer
         * @public
         */
        JSEncryptRSAKey.prototype.getPublicKey = function () {
            var key = "-----BEGIN PUBLIC KEY-----\n";
            key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "\n";
            key += "-----END PUBLIC KEY-----";
            return key;
        };
        /**
         * Check if the object contains the necessary parameters to populate the rsa modulus
         * and public exponent parameters.
         * @param {Object} [obj={}] - An object that may contain the two public key
         * parameters
         * @returns {boolean} true if the object contains both the modulus and the public exponent
         * properties (n and e)
         * @todo check for types of n and e. N should be a parseable bigInt object, E should
         * be a parseable integer number
         * @private
         */
        JSEncryptRSAKey.hasPublicKeyProperty = function (obj) {
            obj = obj || {};
            return obj.hasOwnProperty("n") && obj.hasOwnProperty("e");
        };
        /**
         * Check if the object contains ALL the parameters of an RSA key.
         * @param {Object} [obj={}] - An object that may contain nine rsa key
         * parameters
         * @returns {boolean} true if the object contains all the parameters needed
         * @todo check for types of the parameters all the parameters but the public exponent
         * should be parseable bigint objects, the public exponent should be a parseable integer number
         * @private
         */
        JSEncryptRSAKey.hasPrivateKeyProperty = function (obj) {
            obj = obj || {};
            return (obj.hasOwnProperty("n") &&
                obj.hasOwnProperty("e") &&
                obj.hasOwnProperty("d") &&
                obj.hasOwnProperty("p") &&
                obj.hasOwnProperty("q") &&
                obj.hasOwnProperty("dmp1") &&
                obj.hasOwnProperty("dmq1") &&
                obj.hasOwnProperty("coeff"));
        };
        /**
         * Parse the properties of obj in the current rsa object. Obj should AT LEAST
         * include the modulus and public exponent (n, e) parameters.
         * @param {Object} obj - the object containing rsa parameters
         * @private
         */
        JSEncryptRSAKey.prototype.parsePropertiesFrom = function (obj) {
            this.n = obj.n;
            this.e = obj.e;
            if (obj.hasOwnProperty("d")) {
                this.d = obj.d;
                this.p = obj.p;
                this.q = obj.q;
                this.dmp1 = obj.dmp1;
                this.dmq1 = obj.dmq1;
                this.coeff = obj.coeff;
            }
        };
        return JSEncryptRSAKey;
    }(RSAKey));

    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    function getDefaultExportFromCjs (x) {
    	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
    }

    function getDefaultExportFromNamespaceIfPresent (n) {
    	return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n;
    }

    function getDefaultExportFromNamespaceIfNotNamed (n) {
    	return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n;
    }

    function getAugmentedNamespace(n) {
      if (n.__esModule) return n;
      var f = n.default;
    	if (typeof f == "function") {
    		var a = function a () {
    			if (this instanceof a) {
    				var args = [null];
    				args.push.apply(args, arguments);
    				var Ctor = Function.bind.apply(f, args);
    				return new Ctor();
    			}
    			return f.apply(this, arguments);
    		};
    		a.prototype = f.prototype;
      } else a = {};
      Object.defineProperty(a, '__esModule', {value: true});
    	Object.keys(n).forEach(function (k) {
    		var d = Object.getOwnPropertyDescriptor(n, k);
    		Object.defineProperty(a, k, d.get ? d : {
    			enumerable: true,
    			get: function () {
    				return n[k];
    			}
    		});
    	});
    	return a;
    }

    var src$1 = {exports: {}};

    var indexLight$2 = {exports: {}};

    var indexMinimal$1 = {};

    var minimal = {};

    var aspromise;
    var hasRequiredAspromise;

    function requireAspromise () {
    	if (hasRequiredAspromise) return aspromise;
    	hasRequiredAspromise = 1;
    	"use strict";
    	aspromise = asPromise;

    	/**
    	 * Callback as used by {@link util.asPromise}.
    	 * @typedef asPromiseCallback
    	 * @type {function}
    	 * @param {Error|null} error Error, if any
    	 * @param {...*} params Additional arguments
    	 * @returns {undefined}
    	 */

    	/**
    	 * Returns a promise from a node-style callback function.
    	 * @memberof util
    	 * @param {asPromiseCallback} fn Function to call
    	 * @param {*} ctx Function context
    	 * @param {...*} params Function arguments
    	 * @returns {Promise<*>} Promisified function
    	 */
    	function asPromise(fn, ctx/*, varargs */) {
    	    var params  = new Array(arguments.length - 1),
    	        offset  = 0,
    	        index   = 2,
    	        pending = true;
    	    while (index < arguments.length)
    	        params[offset++] = arguments[index++];
    	    return new Promise(function executor(resolve, reject) {
    	        params[offset] = function callback(err/*, varargs */) {
    	            if (pending) {
    	                pending = false;
    	                if (err)
    	                    reject(err);
    	                else {
    	                    var params = new Array(arguments.length - 1),
    	                        offset = 0;
    	                    while (offset < params.length)
    	                        params[offset++] = arguments[offset];
    	                    resolve.apply(null, params);
    	                }
    	            }
    	        };
    	        try {
    	            fn.apply(ctx || null, params);
    	        } catch (err) {
    	            if (pending) {
    	                pending = false;
    	                reject(err);
    	            }
    	        }
    	    });
    	}
    	return aspromise;
    }

    var base64$1 = {};

    var hasRequiredBase64;

    function requireBase64 () {
    	if (hasRequiredBase64) return base64$1;
    	hasRequiredBase64 = 1;
    	(function (exports) {
    		"use strict";

    		/**
    		 * A minimal base64 implementation for number arrays.
    		 * @memberof util
    		 * @namespace
    		 */
    		var base64 = exports;

    		/**
    		 * Calculates the byte length of a base64 encoded string.
    		 * @param {string} string Base64 encoded string
    		 * @returns {number} Byte length
    		 */
    		base64.length = function length(string) {
    		    var p = string.length;
    		    if (!p)
    		        return 0;
    		    var n = 0;
    		    while (--p % 4 > 1 && string.charAt(p) === "=")
    		        ++n;
    		    return Math.ceil(string.length * 3) / 4 - n;
    		};

    		// Base64 encoding table
    		var b64 = new Array(64);

    		// Base64 decoding table
    		var s64 = new Array(123);

    		// 65..90, 97..122, 48..57, 43, 47
    		for (var i = 0; i < 64;)
    		    s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;

    		/**
    		 * Encodes a buffer to a base64 encoded string.
    		 * @param {Uint8Array} buffer Source buffer
    		 * @param {number} start Source start
    		 * @param {number} end Source end
    		 * @returns {string} Base64 encoded string
    		 */
    		base64.encode = function encode(buffer, start, end) {
    		    var parts = null,
    		        chunk = [];
    		    var i = 0, // output index
    		        j = 0, // goto index
    		        t;     // temporary
    		    while (start < end) {
    		        var b = buffer[start++];
    		        switch (j) {
    		            case 0:
    		                chunk[i++] = b64[b >> 2];
    		                t = (b & 3) << 4;
    		                j = 1;
    		                break;
    		            case 1:
    		                chunk[i++] = b64[t | b >> 4];
    		                t = (b & 15) << 2;
    		                j = 2;
    		                break;
    		            case 2:
    		                chunk[i++] = b64[t | b >> 6];
    		                chunk[i++] = b64[b & 63];
    		                j = 0;
    		                break;
    		        }
    		        if (i > 8191) {
    		            (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
    		            i = 0;
    		        }
    		    }
    		    if (j) {
    		        chunk[i++] = b64[t];
    		        chunk[i++] = 61;
    		        if (j === 1)
    		            chunk[i++] = 61;
    		    }
    		    if (parts) {
    		        if (i)
    		            parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
    		        return parts.join("");
    		    }
    		    return String.fromCharCode.apply(String, chunk.slice(0, i));
    		};

    		var invalidEncoding = "invalid encoding";

    		/**
    		 * Decodes a base64 encoded string to a buffer.
    		 * @param {string} string Source string
    		 * @param {Uint8Array} buffer Destination buffer
    		 * @param {number} offset Destination offset
    		 * @returns {number} Number of bytes written
    		 * @throws {Error} If encoding is invalid
    		 */
    		base64.decode = function decode(string, buffer, offset) {
    		    var start = offset;
    		    var j = 0, // goto index
    		        t;     // temporary
    		    for (var i = 0; i < string.length;) {
    		        var c = string.charCodeAt(i++);
    		        if (c === 61 && j > 1)
    		            break;
    		        if ((c = s64[c]) === undefined)
    		            throw Error(invalidEncoding);
    		        switch (j) {
    		            case 0:
    		                t = c;
    		                j = 1;
    		                break;
    		            case 1:
    		                buffer[offset++] = t << 2 | (c & 48) >> 4;
    		                t = c;
    		                j = 2;
    		                break;
    		            case 2:
    		                buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
    		                t = c;
    		                j = 3;
    		                break;
    		            case 3:
    		                buffer[offset++] = (t & 3) << 6 | c;
    		                j = 0;
    		                break;
    		        }
    		    }
    		    if (j === 1)
    		        throw Error(invalidEncoding);
    		    return offset - start;
    		};

    		/**
    		 * Tests if the specified string appears to be base64 encoded.
    		 * @param {string} string String to test
    		 * @returns {boolean} `true` if probably base64 encoded, otherwise false
    		 */
    		base64.test = function test(string) {
    		    return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
    		}; 
    	} (base64$1));
    	return base64$1;
    }

    var eventemitter;
    var hasRequiredEventemitter;

    function requireEventemitter () {
    	if (hasRequiredEventemitter) return eventemitter;
    	hasRequiredEventemitter = 1;
    	"use strict";
    	eventemitter = EventEmitter;

    	/**
    	 * Constructs a new event emitter instance.
    	 * @classdesc A minimal event emitter.
    	 * @memberof util
    	 * @constructor
    	 */
    	function EventEmitter() {

    	    /**
    	     * Registered listeners.
    	     * @type {Object.<string,*>}
    	     * @private
    	     */
    	    this._listeners = {};
    	}

    	/**
    	 * Registers an event listener.
    	 * @param {string} evt Event name
    	 * @param {function} fn Listener
    	 * @param {*} [ctx] Listener context
    	 * @returns {util.EventEmitter} `this`
    	 */
    	EventEmitter.prototype.on = function on(evt, fn, ctx) {
    	    (this._listeners[evt] || (this._listeners[evt] = [])).push({
    	        fn  : fn,
    	        ctx : ctx || this
    	    });
    	    return this;
    	};

    	/**
    	 * Removes an event listener or any matching listeners if arguments are omitted.
    	 * @param {string} [evt] Event name. Removes all listeners if omitted.
    	 * @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted.
    	 * @returns {util.EventEmitter} `this`
    	 */
    	EventEmitter.prototype.off = function off(evt, fn) {
    	    if (evt === undefined)
    	        this._listeners = {};
    	    else {
    	        if (fn === undefined)
    	            this._listeners[evt] = [];
    	        else {
    	            var listeners = this._listeners[evt];
    	            for (var i = 0; i < listeners.length;)
    	                if (listeners[i].fn === fn)
    	                    listeners.splice(i, 1);
    	                else
    	                    ++i;
    	        }
    	    }
    	    return this;
    	};

    	/**
    	 * Emits an event by calling its listeners with the specified arguments.
    	 * @param {string} evt Event name
    	 * @param {...*} args Arguments
    	 * @returns {util.EventEmitter} `this`
    	 */
    	EventEmitter.prototype.emit = function emit(evt) {
    	    var listeners = this._listeners[evt];
    	    if (listeners) {
    	        var args = [],
    	            i = 1;
    	        for (; i < arguments.length;)
    	            args.push(arguments[i++]);
    	        for (i = 0; i < listeners.length;)
    	            listeners[i].fn.apply(listeners[i++].ctx, args);
    	    }
    	    return this;
    	};
    	return eventemitter;
    }

    var float;
    var hasRequiredFloat;

    function requireFloat () {
    	if (hasRequiredFloat) return float;
    	hasRequiredFloat = 1;
    	"use strict";

    	float = factory(factory);

    	/**
    	 * Reads / writes floats / doubles from / to buffers.
    	 * @name util.float
    	 * @namespace
    	 */

    	/**
    	 * Writes a 32 bit float to a buffer using little endian byte order.
    	 * @name util.float.writeFloatLE
    	 * @function
    	 * @param {number} val Value to write
    	 * @param {Uint8Array} buf Target buffer
    	 * @param {number} pos Target buffer offset
    	 * @returns {undefined}
    	 */

    	/**
    	 * Writes a 32 bit float to a buffer using big endian byte order.
    	 * @name util.float.writeFloatBE
    	 * @function
    	 * @param {number} val Value to write
    	 * @param {Uint8Array} buf Target buffer
    	 * @param {number} pos Target buffer offset
    	 * @returns {undefined}
    	 */

    	/**
    	 * Reads a 32 bit float from a buffer using little endian byte order.
    	 * @name util.float.readFloatLE
    	 * @function
    	 * @param {Uint8Array} buf Source buffer
    	 * @param {number} pos Source buffer offset
    	 * @returns {number} Value read
    	 */

    	/**
    	 * Reads a 32 bit float from a buffer using big endian byte order.
    	 * @name util.float.readFloatBE
    	 * @function
    	 * @param {Uint8Array} buf Source buffer
    	 * @param {number} pos Source buffer offset
    	 * @returns {number} Value read
    	 */

    	/**
    	 * Writes a 64 bit double to a buffer using little endian byte order.
    	 * @name util.float.writeDoubleLE
    	 * @function
    	 * @param {number} val Value to write
    	 * @param {Uint8Array} buf Target buffer
    	 * @param {number} pos Target buffer offset
    	 * @returns {undefined}
    	 */

    	/**
    	 * Writes a 64 bit double to a buffer using big endian byte order.
    	 * @name util.float.writeDoubleBE
    	 * @function
    	 * @param {number} val Value to write
    	 * @param {Uint8Array} buf Target buffer
    	 * @param {number} pos Target buffer offset
    	 * @returns {undefined}
    	 */

    	/**
    	 * Reads a 64 bit double from a buffer using little endian byte order.
    	 * @name util.float.readDoubleLE
    	 * @function
    	 * @param {Uint8Array} buf Source buffer
    	 * @param {number} pos Source buffer offset
    	 * @returns {number} Value read
    	 */

    	/**
    	 * Reads a 64 bit double from a buffer using big endian byte order.
    	 * @name util.float.readDoubleBE
    	 * @function
    	 * @param {Uint8Array} buf Source buffer
    	 * @param {number} pos Source buffer offset
    	 * @returns {number} Value read
    	 */

    	// Factory function for the purpose of node-based testing in modified global environments
    	function factory(exports) {

    	    // float: typed array
    	    if (typeof Float32Array !== "undefined") (function() {

    	        var f32 = new Float32Array([ -0 ]),
    	            f8b = new Uint8Array(f32.buffer),
    	            le  = f8b[3] === 128;

    	        function writeFloat_f32_cpy(val, buf, pos) {
    	            f32[0] = val;
    	            buf[pos    ] = f8b[0];
    	            buf[pos + 1] = f8b[1];
    	            buf[pos + 2] = f8b[2];
    	            buf[pos + 3] = f8b[3];
    	        }

    	        function writeFloat_f32_rev(val, buf, pos) {
    	            f32[0] = val;
    	            buf[pos    ] = f8b[3];
    	            buf[pos + 1] = f8b[2];
    	            buf[pos + 2] = f8b[1];
    	            buf[pos + 3] = f8b[0];
    	        }

    	        /* istanbul ignore next */
    	        exports.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev;
    	        /* istanbul ignore next */
    	        exports.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy;

    	        function readFloat_f32_cpy(buf, pos) {
    	            f8b[0] = buf[pos    ];
    	            f8b[1] = buf[pos + 1];
    	            f8b[2] = buf[pos + 2];
    	            f8b[3] = buf[pos + 3];
    	            return f32[0];
    	        }

    	        function readFloat_f32_rev(buf, pos) {
    	            f8b[3] = buf[pos    ];
    	            f8b[2] = buf[pos + 1];
    	            f8b[1] = buf[pos + 2];
    	            f8b[0] = buf[pos + 3];
    	            return f32[0];
    	        }

    	        /* istanbul ignore next */
    	        exports.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev;
    	        /* istanbul ignore next */
    	        exports.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy;

    	    // float: ieee754
    	    })(); else (function() {

    	        function writeFloat_ieee754(writeUint, val, buf, pos) {
    	            var sign = val < 0 ? 1 : 0;
    	            if (sign)
    	                val = -val;
    	            if (val === 0)
    	                writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos);
    	            else if (isNaN(val))
    	                writeUint(2143289344, buf, pos);
    	            else if (val > 3.4028234663852886e+38) // +-Infinity
    	                writeUint((sign << 31 | 2139095040) >>> 0, buf, pos);
    	            else if (val < 1.1754943508222875e-38) // denormal
    	                writeUint((sign << 31 | Math.round(val / 1.401298464324817e-45)) >>> 0, buf, pos);
    	            else {
    	                var exponent = Math.floor(Math.log(val) / Math.LN2),
    	                    mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607;
    	                writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos);
    	            }
    	        }

    	        exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);
    	        exports.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE);

    	        function readFloat_ieee754(readUint, buf, pos) {
    	            var uint = readUint(buf, pos),
    	                sign = (uint >> 31) * 2 + 1,
    	                exponent = uint >>> 23 & 255,
    	                mantissa = uint & 8388607;
    	            return exponent === 255
    	                ? mantissa
    	                ? NaN
    	                : sign * Infinity
    	                : exponent === 0 // denormal
    	                ? sign * 1.401298464324817e-45 * mantissa
    	                : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608);
    	        }

    	        exports.readFloatLE = readFloat_ieee754.bind(null, readUintLE);
    	        exports.readFloatBE = readFloat_ieee754.bind(null, readUintBE);

    	    })();

    	    // double: typed array
    	    if (typeof Float64Array !== "undefined") (function() {

    	        var f64 = new Float64Array([-0]),
    	            f8b = new Uint8Array(f64.buffer),
    	            le  = f8b[7] === 128;

    	        function writeDouble_f64_cpy(val, buf, pos) {
    	            f64[0] = val;
    	            buf[pos    ] = f8b[0];
    	            buf[pos + 1] = f8b[1];
    	            buf[pos + 2] = f8b[2];
    	            buf[pos + 3] = f8b[3];
    	            buf[pos + 4] = f8b[4];
    	            buf[pos + 5] = f8b[5];
    	            buf[pos + 6] = f8b[6];
    	            buf[pos + 7] = f8b[7];
    	        }

    	        function writeDouble_f64_rev(val, buf, pos) {
    	            f64[0] = val;
    	            buf[pos    ] = f8b[7];
    	            buf[pos + 1] = f8b[6];
    	            buf[pos + 2] = f8b[5];
    	            buf[pos + 3] = f8b[4];
    	            buf[pos + 4] = f8b[3];
    	            buf[pos + 5] = f8b[2];
    	            buf[pos + 6] = f8b[1];
    	            buf[pos + 7] = f8b[0];
    	        }

    	        /* istanbul ignore next */
    	        exports.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev;
    	        /* istanbul ignore next */
    	        exports.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy;

    	        function readDouble_f64_cpy(buf, pos) {
    	            f8b[0] = buf[pos    ];
    	            f8b[1] = buf[pos + 1];
    	            f8b[2] = buf[pos + 2];
    	            f8b[3] = buf[pos + 3];
    	            f8b[4] = buf[pos + 4];
    	            f8b[5] = buf[pos + 5];
    	            f8b[6] = buf[pos + 6];
    	            f8b[7] = buf[pos + 7];
    	            return f64[0];
    	        }

    	        function readDouble_f64_rev(buf, pos) {
    	            f8b[7] = buf[pos    ];
    	            f8b[6] = buf[pos + 1];
    	            f8b[5] = buf[pos + 2];
    	            f8b[4] = buf[pos + 3];
    	            f8b[3] = buf[pos + 4];
    	            f8b[2] = buf[pos + 5];
    	            f8b[1] = buf[pos + 6];
    	            f8b[0] = buf[pos + 7];
    	            return f64[0];
    	        }

    	        /* istanbul ignore next */
    	        exports.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev;
    	        /* istanbul ignore next */
    	        exports.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy;

    	    // double: ieee754
    	    })(); else (function() {

    	        function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) {
    	            var sign = val < 0 ? 1 : 0;
    	            if (sign)
    	                val = -val;
    	            if (val === 0) {
    	                writeUint(0, buf, pos + off0);
    	                writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + off1);
    	            } else if (isNaN(val)) {
    	                writeUint(0, buf, pos + off0);
    	                writeUint(2146959360, buf, pos + off1);
    	            } else if (val > 1.7976931348623157e+308) { // +-Infinity
    	                writeUint(0, buf, pos + off0);
    	                writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1);
    	            } else {
    	                var mantissa;
    	                if (val < 2.2250738585072014e-308) { // denormal
    	                    mantissa = val / 5e-324;
    	                    writeUint(mantissa >>> 0, buf, pos + off0);
    	                    writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1);
    	                } else {
    	                    var exponent = Math.floor(Math.log(val) / Math.LN2);
    	                    if (exponent === 1024)
    	                        exponent = 1023;
    	                    mantissa = val * Math.pow(2, -exponent);
    	                    writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0);
    	                    writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1);
    	                }
    	            }
    	        }

    	        exports.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4);
    	        exports.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0);

    	        function readDouble_ieee754(readUint, off0, off1, buf, pos) {
    	            var lo = readUint(buf, pos + off0),
    	                hi = readUint(buf, pos + off1);
    	            var sign = (hi >> 31) * 2 + 1,
    	                exponent = hi >>> 20 & 2047,
    	                mantissa = 4294967296 * (hi & 1048575) + lo;
    	            return exponent === 2047
    	                ? mantissa
    	                ? NaN
    	                : sign * Infinity
    	                : exponent === 0 // denormal
    	                ? sign * 5e-324 * mantissa
    	                : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496);
    	        }

    	        exports.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4);
    	        exports.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0);

    	    })();

    	    return exports;
    	}

    	// uint helpers

    	function writeUintLE(val, buf, pos) {
    	    buf[pos    ] =  val        & 255;
    	    buf[pos + 1] =  val >>> 8  & 255;
    	    buf[pos + 2] =  val >>> 16 & 255;
    	    buf[pos + 3] =  val >>> 24;
    	}

    	function writeUintBE(val, buf, pos) {
    	    buf[pos    ] =  val >>> 24;
    	    buf[pos + 1] =  val >>> 16 & 255;
    	    buf[pos + 2] =  val >>> 8  & 255;
    	    buf[pos + 3] =  val        & 255;
    	}

    	function readUintLE(buf, pos) {
    	    return (buf[pos    ]
    	          | buf[pos + 1] << 8
    	          | buf[pos + 2] << 16
    	          | buf[pos + 3] << 24) >>> 0;
    	}

    	function readUintBE(buf, pos) {
    	    return (buf[pos    ] << 24
    	          | buf[pos + 1] << 16
    	          | buf[pos + 2] << 8
    	          | buf[pos + 3]) >>> 0;
    	}
    	return float;
    }

    var inquire_1;
    var hasRequiredInquire;

    function requireInquire () {
    	if (hasRequiredInquire) return inquire_1;
    	hasRequiredInquire = 1;
    	"use strict";
    	inquire_1 = inquire;

    	/**
    	 * Requires a module only if available.
    	 * @memberof util
    	 * @param {string} moduleName Module to require
    	 * @returns {?Object} Required module if available and not empty, otherwise `null`
    	 */
    	function inquire(moduleName) {
    	    try {
    	        var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
    	        if (mod && (mod.length || Object.keys(mod).length))
    	            return mod;
    	    } catch (e) {} // eslint-disable-line no-empty
    	    return null;
    	}
    	return inquire_1;
    }

    var utf8$2 = {};

    var hasRequiredUtf8;

    function requireUtf8 () {
    	if (hasRequiredUtf8) return utf8$2;
    	hasRequiredUtf8 = 1;
    	(function (exports) {
    		"use strict";

    		/**
    		 * A minimal UTF8 implementation for number arrays.
    		 * @memberof util
    		 * @namespace
    		 */
    		var utf8 = exports;

    		/**
    		 * Calculates the UTF8 byte length of a string.
    		 * @param {string} string String
    		 * @returns {number} Byte length
    		 */
    		utf8.length = function utf8_length(string) {
    		    var len = 0,
    		        c = 0;
    		    for (var i = 0; i < string.length; ++i) {
    		        c = string.charCodeAt(i);
    		        if (c < 128)
    		            len += 1;
    		        else if (c < 2048)
    		            len += 2;
    		        else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
    		            ++i;
    		            len += 4;
    		        } else
    		            len += 3;
    		    }
    		    return len;
    		};

    		/**
    		 * Reads UTF8 bytes as a string.
    		 * @param {Uint8Array} buffer Source buffer
    		 * @param {number} start Source start
    		 * @param {number} end Source end
    		 * @returns {string} String read
    		 */
    		utf8.read = function utf8_read(buffer, start, end) {
    		    var len = end - start;
    		    if (len < 1)
    		        return "";
    		    var parts = null,
    		        chunk = [],
    		        i = 0, // char offset
    		        t;     // temporary
    		    while (start < end) {
    		        t = buffer[start++];
    		        if (t < 128)
    		            chunk[i++] = t;
    		        else if (t > 191 && t < 224)
    		            chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
    		        else if (t > 239 && t < 365) {
    		            t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
    		            chunk[i++] = 0xD800 + (t >> 10);
    		            chunk[i++] = 0xDC00 + (t & 1023);
    		        } else
    		            chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
    		        if (i > 8191) {
    		            (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
    		            i = 0;
    		        }
    		    }
    		    if (parts) {
    		        if (i)
    		            parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
    		        return parts.join("");
    		    }
    		    return String.fromCharCode.apply(String, chunk.slice(0, i));
    		};

    		/**
    		 * Writes a string as UTF8 bytes.
    		 * @param {string} string Source string
    		 * @param {Uint8Array} buffer Destination buffer
    		 * @param {number} offset Destination offset
    		 * @returns {number} Bytes written
    		 */
    		utf8.write = function utf8_write(string, buffer, offset) {
    		    var start = offset,
    		        c1, // character 1
    		        c2; // character 2
    		    for (var i = 0; i < string.length; ++i) {
    		        c1 = string.charCodeAt(i);
    		        if (c1 < 128) {
    		            buffer[offset++] = c1;
    		        } else if (c1 < 2048) {
    		            buffer[offset++] = c1 >> 6       | 192;
    		            buffer[offset++] = c1       & 63 | 128;
    		        } else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
    		            c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
    		            ++i;
    		            buffer[offset++] = c1 >> 18      | 240;
    		            buffer[offset++] = c1 >> 12 & 63 | 128;
    		            buffer[offset++] = c1 >> 6  & 63 | 128;
    		            buffer[offset++] = c1       & 63 | 128;
    		        } else {
    		            buffer[offset++] = c1 >> 12      | 224;
    		            buffer[offset++] = c1 >> 6  & 63 | 128;
    		            buffer[offset++] = c1       & 63 | 128;
    		        }
    		    }
    		    return offset - start;
    		}; 
    	} (utf8$2));
    	return utf8$2;
    }

    var pool_1;
    var hasRequiredPool;

    function requirePool () {
    	if (hasRequiredPool) return pool_1;
    	hasRequiredPool = 1;
    	"use strict";
    	pool_1 = pool;

    	/**
    	 * An allocator as used by {@link util.pool}.
    	 * @typedef PoolAllocator
    	 * @type {function}
    	 * @param {number} size Buffer size
    	 * @returns {Uint8Array} Buffer
    	 */

    	/**
    	 * A slicer as used by {@link util.pool}.
    	 * @typedef PoolSlicer
    	 * @type {function}
    	 * @param {number} start Start offset
    	 * @param {number} end End offset
    	 * @returns {Uint8Array} Buffer slice
    	 * @this {Uint8Array}
    	 */

    	/**
    	 * A general purpose buffer pool.
    	 * @memberof util
    	 * @function
    	 * @param {PoolAllocator} alloc Allocator
    	 * @param {PoolSlicer} slice Slicer
    	 * @param {number} [size=8192] Slab size
    	 * @returns {PoolAllocator} Pooled allocator
    	 */
    	function pool(alloc, slice, size) {
    	    var SIZE   = size || 8192;
    	    var MAX    = SIZE >>> 1;
    	    var slab   = null;
    	    var offset = SIZE;
    	    return function pool_alloc(size) {
    	        if (size < 1 || size > MAX)
    	            return alloc(size);
    	        if (offset + size > SIZE) {
    	            slab = alloc(SIZE);
    	            offset = 0;
    	        }
    	        var buf = slice.call(slab, offset, offset += size);
    	        if (offset & 7) // align to 32 bit
    	            offset = (offset | 7) + 1;
    	        return buf;
    	    };
    	}
    	return pool_1;
    }

    var longbits;
    var hasRequiredLongbits;

    function requireLongbits () {
    	if (hasRequiredLongbits) return longbits;
    	hasRequiredLongbits = 1;
    	"use strict";
    	longbits = LongBits;

    	var util = requireMinimal();

    	/**
    	 * Constructs new long bits.
    	 * @classdesc Helper class for working with the low and high bits of a 64 bit value.
    	 * @memberof util
    	 * @constructor
    	 * @param {number} lo Low 32 bits, unsigned
    	 * @param {number} hi High 32 bits, unsigned
    	 */
    	function LongBits(lo, hi) {

    	    // note that the casts below are theoretically unnecessary as of today, but older statically
    	    // generated converter code might still call the ctor with signed 32bits. kept for compat.

    	    /**
    	     * Low bits.
    	     * @type {number}
    	     */
    	    this.lo = lo >>> 0;

    	    /**
    	     * High bits.
    	     * @type {number}
    	     */
    	    this.hi = hi >>> 0;
    	}

    	/**
    	 * Zero bits.
    	 * @memberof util.LongBits
    	 * @type {util.LongBits}
    	 */
    	var zero = LongBits.zero = new LongBits(0, 0);

    	zero.toNumber = function() { return 0; };
    	zero.zzEncode = zero.zzDecode = function() { return this; };
    	zero.length = function() { return 1; };

    	/**
    	 * Zero hash.
    	 * @memberof util.LongBits
    	 * @type {string}
    	 */
    	var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0";

    	/**
    	 * Constructs new long bits from the specified number.
    	 * @param {number} value Value
    	 * @returns {util.LongBits} Instance
    	 */
    	LongBits.fromNumber = function fromNumber(value) {
    	    if (value === 0)
    	        return zero;
    	    var sign = value < 0;
    	    if (sign)
    	        value = -value;
    	    var lo = value >>> 0,
    	        hi = (value - lo) / 4294967296 >>> 0;
    	    if (sign) {
    	        hi = ~hi >>> 0;
    	        lo = ~lo >>> 0;
    	        if (++lo > 4294967295) {
    	            lo = 0;
    	            if (++hi > 4294967295)
    	                hi = 0;
    	        }
    	    }
    	    return new LongBits(lo, hi);
    	};

    	/**
    	 * Constructs new long bits from a number, long or string.
    	 * @param {Long|number|string} value Value
    	 * @returns {util.LongBits} Instance
    	 */
    	LongBits.from = function from(value) {
    	    if (typeof value === "number")
    	        return LongBits.fromNumber(value);
    	    if (util.isString(value)) {
    	        /* istanbul ignore else */
    	        if (util.Long)
    	            value = util.Long.fromString(value);
    	        else
    	            return LongBits.fromNumber(parseInt(value, 10));
    	    }
    	    return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero;
    	};

    	/**
    	 * Converts this long bits to a possibly unsafe JavaScript number.
    	 * @param {boolean} [unsigned=false] Whether unsigned or not
    	 * @returns {number} Possibly unsafe number
    	 */
    	LongBits.prototype.toNumber = function toNumber(unsigned) {
    	    if (!unsigned && this.hi >>> 31) {
    	        var lo = ~this.lo + 1 >>> 0,
    	            hi = ~this.hi     >>> 0;
    	        if (!lo)
    	            hi = hi + 1 >>> 0;
    	        return -(lo + hi * 4294967296);
    	    }
    	    return this.lo + this.hi * 4294967296;
    	};

    	/**
    	 * Converts this long bits to a long.
    	 * @param {boolean} [unsigned=false] Whether unsigned or not
    	 * @returns {Long} Long
    	 */
    	LongBits.prototype.toLong = function toLong(unsigned) {
    	    return util.Long
    	        ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned))
    	        /* istanbul ignore next */
    	        : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) };
    	};

    	var charCodeAt = String.prototype.charCodeAt;

    	/**
    	 * Constructs new long bits from the specified 8 characters long hash.
    	 * @param {string} hash Hash
    	 * @returns {util.LongBits} Bits
    	 */
    	LongBits.fromHash = function fromHash(hash) {
    	    if (hash === zeroHash)
    	        return zero;
    	    return new LongBits(
    	        ( charCodeAt.call(hash, 0)
    	        | charCodeAt.call(hash, 1) << 8
    	        | charCodeAt.call(hash, 2) << 16
    	        | charCodeAt.call(hash, 3) << 24) >>> 0
    	    ,
    	        ( charCodeAt.call(hash, 4)
    	        | charCodeAt.call(hash, 5) << 8
    	        | charCodeAt.call(hash, 6) << 16
    	        | charCodeAt.call(hash, 7) << 24) >>> 0
    	    );
    	};

    	/**
    	 * Converts this long bits to a 8 characters long hash.
    	 * @returns {string} Hash
    	 */
    	LongBits.prototype.toHash = function toHash() {
    	    return String.fromCharCode(
    	        this.lo        & 255,
    	        this.lo >>> 8  & 255,
    	        this.lo >>> 16 & 255,
    	        this.lo >>> 24      ,
    	        this.hi        & 255,
    	        this.hi >>> 8  & 255,
    	        this.hi >>> 16 & 255,
    	        this.hi >>> 24
    	    );
    	};

    	/**
    	 * Zig-zag encodes this long bits.
    	 * @returns {util.LongBits} `this`
    	 */
    	LongBits.prototype.zzEncode = function zzEncode() {
    	    var mask =   this.hi >> 31;
    	    this.hi  = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
    	    this.lo  = ( this.lo << 1                   ^ mask) >>> 0;
    	    return this;
    	};

    	/**
    	 * Zig-zag decodes this long bits.
    	 * @returns {util.LongBits} `this`
    	 */
    	LongBits.prototype.zzDecode = function zzDecode() {
    	    var mask = -(this.lo & 1);
    	    this.lo  = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
    	    this.hi  = ( this.hi >>> 1                  ^ mask) >>> 0;
    	    return this;
    	};

    	/**
    	 * Calculates the length of this longbits when encoded as a varint.
    	 * @returns {number} Length
    	 */
    	LongBits.prototype.length = function length() {
    	    var part0 =  this.lo,
    	        part1 = (this.lo >>> 28 | this.hi << 4) >>> 0,
    	        part2 =  this.hi >>> 24;
    	    return part2 === 0
    	         ? part1 === 0
    	           ? part0 < 16384
    	             ? part0 < 128 ? 1 : 2
    	             : part0 < 2097152 ? 3 : 4
    	           : part1 < 16384
    	             ? part1 < 128 ? 5 : 6
    	             : part1 < 2097152 ? 7 : 8
    	         : part2 < 128 ? 9 : 10;
    	};
    	return longbits;
    }

    var hasRequiredMinimal;

    function requireMinimal () {
    	if (hasRequiredMinimal) return minimal;
    	hasRequiredMinimal = 1;
    	(function (exports) {
    		"use strict";
    		var util = exports;

    		// used to return a Promise where callback is omitted
    		util.asPromise = requireAspromise();

    		// converts to / from base64 encoded strings
    		util.base64 = requireBase64();

    		// base class of rpc.Service
    		util.EventEmitter = requireEventemitter();

    		// float handling accross browsers
    		util.float = requireFloat();

    		// requires modules optionally and hides the call from bundlers
    		util.inquire = requireInquire();

    		// converts to / from utf8 encoded strings
    		util.utf8 = requireUtf8();

    		// provides a node-like buffer pool in the browser
    		util.pool = requirePool();

    		// utility to work with the low and high bits of a 64 bit value
    		util.LongBits = requireLongbits();

    		/**
    		 * Whether running within node or not.
    		 * @memberof util
    		 * @type {boolean}
    		 */
    		util.isNode = Boolean(typeof commonjsGlobal !== "undefined"
    		                   && commonjsGlobal
    		                   && commonjsGlobal.process
    		                   && commonjsGlobal.process.versions
    		                   && commonjsGlobal.process.versions.node);

    		/**
    		 * Global object reference.
    		 * @memberof util
    		 * @type {Object}
    		 */
    		util.global = util.isNode && commonjsGlobal
    		           || typeof window !== "undefined" && window
    		           || typeof self   !== "undefined" && self
    		           || commonjsGlobal; // eslint-disable-line no-invalid-this

    		/**
    		 * An immuable empty array.
    		 * @memberof util
    		 * @type {Array.<*>}
    		 * @const
    		 */
    		util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes

    		/**
    		 * An immutable empty object.
    		 * @type {Object}
    		 * @const
    		 */
    		util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes

    		/**
    		 * Tests if the specified value is an integer.
    		 * @function
    		 * @param {*} value Value to test
    		 * @returns {boolean} `true` if the value is an integer
    		 */
    		util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) {
    		    return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
    		};

    		/**
    		 * Tests if the specified value is a string.
    		 * @param {*} value Value to test
    		 * @returns {boolean} `true` if the value is a string
    		 */
    		util.isString = function isString(value) {
    		    return typeof value === "string" || value instanceof String;
    		};

    		/**
    		 * Tests if the specified value is a non-null object.
    		 * @param {*} value Value to test
    		 * @returns {boolean} `true` if the value is a non-null object
    		 */
    		util.isObject = function isObject(value) {
    		    return value && typeof value === "object";
    		};

    		/**
    		 * Checks if a property on a message is considered to be present.
    		 * This is an alias of {@link util.isSet}.
    		 * @function
    		 * @param {Object} obj Plain object or message instance
    		 * @param {string} prop Property name
    		 * @returns {boolean} `true` if considered to be present, otherwise `false`
    		 */
    		util.isset =

    		/**
    		 * Checks if a property on a message is considered to be present.
    		 * @param {Object} obj Plain object or message instance
    		 * @param {string} prop Property name
    		 * @returns {boolean} `true` if considered to be present, otherwise `false`
    		 */
    		util.isSet = function isSet(obj, prop) {
    		    var value = obj[prop];
    		    if (value != null && obj.hasOwnProperty(prop)) // eslint-disable-line eqeqeq, no-prototype-builtins
    		        return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
    		    return false;
    		};

    		/**
    		 * Any compatible Buffer instance.
    		 * This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
    		 * @interface Buffer
    		 * @extends Uint8Array
    		 */

    		/**
    		 * Node's Buffer class if available.
    		 * @type {Constructor<Buffer>}
    		 */
    		util.Buffer = (function() {
    		    try {
    		        var Buffer = util.inquire("buffer").Buffer;
    		        // refuse to use non-node buffers if not explicitly assigned (perf reasons):
    		        return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
    		    } catch (e) {
    		        /* istanbul ignore next */
    		        return null;
    		    }
    		})();

    		// Internal alias of or polyfull for Buffer.from.
    		util._Buffer_from = null;

    		// Internal alias of or polyfill for Buffer.allocUnsafe.
    		util._Buffer_allocUnsafe = null;

    		/**
    		 * Creates a new buffer of whatever type supported by the environment.
    		 * @param {number|number[]} [sizeOrArray=0] Buffer size or number array
    		 * @returns {Uint8Array|Buffer} Buffer
    		 */
    		util.newBuffer = function newBuffer(sizeOrArray) {
    		    /* istanbul ignore next */
    		    return typeof sizeOrArray === "number"
    		        ? util.Buffer
    		            ? util._Buffer_allocUnsafe(sizeOrArray)
    		            : new util.Array(sizeOrArray)
    		        : util.Buffer
    		            ? util._Buffer_from(sizeOrArray)
    		            : typeof Uint8Array === "undefined"
    		                ? sizeOrArray
    		                : new Uint8Array(sizeOrArray);
    		};

    		/**
    		 * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
    		 * @type {Constructor<Uint8Array>}
    		 */
    		util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;

    		/**
    		 * Any compatible Long instance.
    		 * This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
    		 * @interface Long
    		 * @property {number} low Low bits
    		 * @property {number} high High bits
    		 * @property {boolean} unsigned Whether unsigned or not
    		 */

    		/**
    		 * Long.js's Long class if available.
    		 * @type {Constructor<Long>}
    		 */
    		util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long
    		         || /* istanbul ignore next */ util.global.Long
    		         || util.inquire("long");

    		/**
    		 * Regular expression used to verify 2 bit (`bool`) map keys.
    		 * @type {RegExp}
    		 * @const
    		 */
    		util.key2Re = /^true|false|0|1$/;

    		/**
    		 * Regular expression used to verify 32 bit (`int32` etc.) map keys.
    		 * @type {RegExp}
    		 * @const
    		 */
    		util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;

    		/**
    		 * Regular expression used to verify 64 bit (`int64` etc.) map keys.
    		 * @type {RegExp}
    		 * @const
    		 */
    		util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;

    		/**
    		 * Converts a number or long to an 8 characters long hash string.
    		 * @param {Long|number} value Value to convert
    		 * @returns {string} Hash
    		 */
    		util.longToHash = function longToHash(value) {
    		    return value
    		        ? util.LongBits.from(value).toHash()
    		        : util.LongBits.zeroHash;
    		};

    		/**
    		 * Converts an 8 characters long hash string to a long or number.
    		 * @param {string} hash Hash
    		 * @param {boolean} [unsigned=false] Whether unsigned or not
    		 * @returns {Long|number} Original value
    		 */
    		util.longFromHash = function longFromHash(hash, unsigned) {
    		    var bits = util.LongBits.fromHash(hash);
    		    if (util.Long)
    		        return util.Long.fromBits(bits.lo, bits.hi, unsigned);
    		    return bits.toNumber(Boolean(unsigned));
    		};

    		/**
    		 * Merges the properties of the source object into the destination object.
    		 * @memberof util
    		 * @param {Object.<string,*>} dst Destination object
    		 * @param {Object.<string,*>} src Source object
    		 * @param {boolean} [ifNotSet=false] Merges only if the key is not already set
    		 * @returns {Object.<string,*>} Destination object
    		 */
    		function merge(dst, src, ifNotSet) { // used by converters
    		    for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
    		        if (dst[keys[i]] === undefined || !ifNotSet)
    		            dst[keys[i]] = src[keys[i]];
    		    return dst;
    		}

    		util.merge = merge;

    		/**
    		 * Converts the first character of a string to lower case.
    		 * @param {string} str String to convert
    		 * @returns {string} Converted string
    		 */
    		util.lcFirst = function lcFirst(str) {
    		    return str.charAt(0).toLowerCase() + str.substring(1);
    		};

    		/**
    		 * Creates a custom error constructor.
    		 * @memberof util
    		 * @param {string} name Error name
    		 * @returns {Constructor<Error>} Custom error constructor
    		 */
    		function newError(name) {

    		    function CustomError(message, properties) {

    		        if (!(this instanceof CustomError))
    		            return new CustomError(message, properties);

    		        // Error.call(this, message);
    		        // ^ just returns a new error instance because the ctor can be called as a function

    		            		        /* istanbul ignore next */
    		        if (Error.captureStackTrace) // node
    		            Error.captureStackTrace(this, CustomError);
    		        else
    		            Object.defineProperty(this, "stack", { value: new Error().stack || "" });

    		        if (properties)
    		            merge(this, properties);
    		    }

    		    CustomError.prototype = Object.create(Error.prototype, {
    		        constructor: {
    		            value: CustomError,
    		            writable: true,
    		            enumerable: false,
    		            configurable: true,
    		        },
    		        name: {
    		            get: function get() { return name; },
    		            set: undefined,
    		            enumerable: false,
    		            // configurable: false would accurately preserve the behavior of
    		            // the original, but I'm guessing that was not intentional.
    		            // For an actual error subclass, this property would
    		            // be configurable.
    		            configurable: true,
    		        },
    		        toString: {
    		            value: function value() { return this.name + ": " + this.message; },
    		            writable: true,
    		            enumerable: false,
    		            configurable: true,
    		        },
    		    });

    		    return CustomError;
    		}

    		util.newError = newError;

    		/**
    		 * Constructs a new protocol error.
    		 * @classdesc Error subclass indicating a protocol specifc error.
    		 * @memberof util
    		 * @extends Error
    		 * @template T extends Message<T>
    		 * @constructor
    		 * @param {string} message Error message
    		 * @param {Object.<string,*>} [properties] Additional properties
    		 * @example
    		 * try {
    		 *     MyMessage.decode(someBuffer); // throws if required fields are missing
    		 * } catch (e) {
    		 *     if (e instanceof ProtocolError && e.instance)
    		 *         console.log("decoded so far: " + JSON.stringify(e.instance));
    		 * }
    		 */
    		util.ProtocolError = newError("ProtocolError");

    		/**
    		 * So far decoded message instance.
    		 * @name util.ProtocolError#instance
    		 * @type {Message<T>}
    		 */

    		/**
    		 * A OneOf getter as returned by {@link util.oneOfGetter}.
    		 * @typedef OneOfGetter
    		 * @type {function}
    		 * @returns {string|undefined} Set field name, if any
    		 */

    		/**
    		 * Builds a getter for a oneof's present field name.
    		 * @param {string[]} fieldNames Field names
    		 * @returns {OneOfGetter} Unbound getter
    		 */
    		util.oneOfGetter = function getOneOf(fieldNames) {
    		    var fieldMap = {};
    		    for (var i = 0; i < fieldNames.length; ++i)
    		        fieldMap[fieldNames[i]] = 1;

    		    /**
    		     * @returns {string|undefined} Set field name, if any
    		     * @this Object
    		     * @ignore
    		     */
    		    return function() { // eslint-disable-line consistent-return
    		        for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i)
    		            if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null)
    		                return keys[i];
    		    };
    		};

    		/**
    		 * A OneOf setter as returned by {@link util.oneOfSetter}.
    		 * @typedef OneOfSetter
    		 * @type {function}
    		 * @param {string|undefined} value Field name
    		 * @returns {undefined}
    		 */

    		/**
    		 * Builds a setter for a oneof's present field name.
    		 * @param {string[]} fieldNames Field names
    		 * @returns {OneOfSetter} Unbound setter
    		 */
    		util.oneOfSetter = function setOneOf(fieldNames) {

    		    /**
    		     * @param {string} name Field name
    		     * @returns {undefined}
    		     * @this Object
    		     * @ignore
    		     */
    		    return function(name) {
    		        for (var i = 0; i < fieldNames.length; ++i)
    		            if (fieldNames[i] !== name)
    		                delete this[fieldNames[i]];
    		    };
    		};

    		/**
    		 * Default conversion options used for {@link Message#toJSON} implementations.
    		 *
    		 * These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely:
    		 *
    		 * - Longs become strings
    		 * - Enums become string keys
    		 * - Bytes become base64 encoded strings
    		 * - (Sub-)Messages become plain objects
    		 * - Maps become plain objects with all string keys
    		 * - Repeated fields become arrays
    		 * - NaN and Infinity for float and double fields become strings
    		 *
    		 * @type {IConversionOptions}
    		 * @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json
    		 */
    		util.toJSONOptions = {
    		    longs: String,
    		    enums: String,
    		    bytes: String,
    		    json: true
    		};

    		// Sets up buffer utility according to the environment (called in index-minimal)
    		util._configure = function() {
    		    var Buffer = util.Buffer;
    		    /* istanbul ignore if */
    		    if (!Buffer) {
    		        util._Buffer_from = util._Buffer_allocUnsafe = null;
    		        return;
    		    }
    		    // because node 4.x buffers are incompatible & immutable
    		    // see: https://github.com/dcodeIO/protobuf.js/pull/665
    		    util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from ||
    		        /* istanbul ignore next */
    		        function Buffer_from(value, encoding) {
    		            return new Buffer(value, encoding);
    		        };
    		    util._Buffer_allocUnsafe = Buffer.allocUnsafe ||
    		        /* istanbul ignore next */
    		        function Buffer_allocUnsafe(size) {
    		            return new Buffer(size);
    		        };
    		}; 
    	} (minimal));
    	return minimal;
    }

    "use strict";
    var writer = Writer$1;

    var util$7      = requireMinimal();

    var BufferWriter$1; // cyclic

    var LongBits$1  = util$7.LongBits,
        base64    = util$7.base64,
        utf8$1      = util$7.utf8;

    /**
     * Constructs a new writer operation instance.
     * @classdesc Scheduled writer operation.
     * @constructor
     * @param {function(*, Uint8Array, number)} fn Function to call
     * @param {number} len Value byte length
     * @param {*} val Value to write
     * @ignore
     */
    function Op(fn, len, val) {

        /**
         * Function to call.
         * @type {function(Uint8Array, number, *)}
         */
        this.fn = fn;

        /**
         * Value byte length.
         * @type {number}
         */
        this.len = len;

        /**
         * Next operation.
         * @type {Writer.Op|undefined}
         */
        this.next = undefined;

        /**
         * Value to write.
         * @type {*}
         */
        this.val = val; // type varies
    }

    /* istanbul ignore next */
    function noop() {} // eslint-disable-line no-empty-function

    /**
     * Constructs a new writer state instance.
     * @classdesc Copied writer state.
     * @memberof Writer
     * @constructor
     * @param {Writer} writer Writer to copy state from
     * @ignore
     */
    function State(writer) {

        /**
         * Current head.
         * @type {Writer.Op}
         */
        this.head = writer.head;

        /**
         * Current tail.
         * @type {Writer.Op}
         */
        this.tail = writer.tail;

        /**
         * Current buffer length.
         * @type {number}
         */
        this.len = writer.len;

        /**
         * Next state.
         * @type {State|null}
         */
        this.next = writer.states;
    }

    /**
     * Constructs a new writer instance.
     * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`.
     * @constructor
     */
    function Writer$1() {

        /**
         * Current length.
         * @type {number}
         */
        this.len = 0;

        /**
         * Operations head.
         * @type {Object}
         */
        this.head = new Op(noop, 0, 0);

        /**
         * Operations tail
         * @type {Object}
         */
        this.tail = this.head;

        /**
         * Linked forked states.
         * @type {Object|null}
         */
        this.states = null;

        // When a value is written, the writer calculates its byte length and puts it into a linked
        // list of operations to perform when finish() is called. This both allows us to allocate
        // buffers of the exact required size and reduces the amount of work we have to do compared
        // to first calculating over objects and then encoding over objects. In our case, the encoding
        // part is just a linked list walk calling operations with already prepared values.
    }

    var create$1 = function create() {
        return util$7.Buffer
            ? function create_buffer_setup() {
                return (Writer$1.create = function create_buffer() {
                    return new BufferWriter$1();
                })();
            }
            /* istanbul ignore next */
            : function create_array() {
                return new Writer$1();
            };
    };

    /**
     * Creates a new writer.
     * @function
     * @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer}
     */
    Writer$1.create = create$1();

    /**
     * Allocates a buffer of the specified size.
     * @param {number} size Buffer size
     * @returns {Uint8Array} Buffer
     */
    Writer$1.alloc = function alloc(size) {
        return new util$7.Array(size);
    };

    // Use Uint8Array buffer pool in the browser, just like node does with buffers
    /* istanbul ignore else */
    if (util$7.Array !== Array)
        Writer$1.alloc = util$7.pool(Writer$1.alloc, util$7.Array.prototype.subarray);

    /**
     * Pushes a new operation to the queue.
     * @param {function(Uint8Array, number, *)} fn Function to call
     * @param {number} len Value byte length
     * @param {number} val Value to write
     * @returns {Writer} `this`
     * @private
     */
    Writer$1.prototype._push = function push(fn, len, val) {
        this.tail = this.tail.next = new Op(fn, len, val);
        this.len += len;
        return this;
    };

    function writeByte(val, buf, pos) {
        buf[pos] = val & 255;
    }

    function writeVarint32(val, buf, pos) {
        while (val > 127) {
            buf[pos++] = val & 127 | 128;
            val >>>= 7;
        }
        buf[pos] = val;
    }

    /**
     * Constructs a new varint writer operation instance.
     * @classdesc Scheduled varint writer operation.
     * @extends Op
     * @constructor
     * @param {number} len Value byte length
     * @param {number} val Value to write
     * @ignore
     */
    function VarintOp(len, val) {
        this.len = len;
        this.next = undefined;
        this.val = val;
    }

    VarintOp.prototype = Object.create(Op.prototype);
    VarintOp.prototype.fn = writeVarint32;

    /**
     * Writes an unsigned 32 bit value as a varint.
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.uint32 = function write_uint32(value) {
        // here, the call to this.push has been inlined and a varint specific Op subclass is used.
        // uint32 is by far the most frequently used operation and benefits significantly from this.
        this.len += (this.tail = this.tail.next = new VarintOp(
            (value = value >>> 0)
                    < 128       ? 1
            : value < 16384     ? 2
            : value < 2097152   ? 3
            : value < 268435456 ? 4
            :                     5,
        value)).len;
        return this;
    };

    /**
     * Writes a signed 32 bit value as a varint.
     * @function
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.int32 = function write_int32(value) {
        return value < 0
            ? this._push(writeVarint64, 10, LongBits$1.fromNumber(value)) // 10 bytes per spec
            : this.uint32(value);
    };

    /**
     * Writes a 32 bit value as a varint, zig-zag encoded.
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.sint32 = function write_sint32(value) {
        return this.uint32((value << 1 ^ value >> 31) >>> 0);
    };

    function writeVarint64(val, buf, pos) {
        while (val.hi) {
            buf[pos++] = val.lo & 127 | 128;
            val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0;
            val.hi >>>= 7;
        }
        while (val.lo > 127) {
            buf[pos++] = val.lo & 127 | 128;
            val.lo = val.lo >>> 7;
        }
        buf[pos++] = val.lo;
    }

    /**
     * Writes an unsigned 64 bit value as a varint.
     * @param {Long|number|string} value Value to write
     * @returns {Writer} `this`
     * @throws {TypeError} If `value` is a string and no long library is present.
     */
    Writer$1.prototype.uint64 = function write_uint64(value) {
        var bits = LongBits$1.from(value);
        return this._push(writeVarint64, bits.length(), bits);
    };

    /**
     * Writes a signed 64 bit value as a varint.
     * @function
     * @param {Long|number|string} value Value to write
     * @returns {Writer} `this`
     * @throws {TypeError} If `value` is a string and no long library is present.
     */
    Writer$1.prototype.int64 = Writer$1.prototype.uint64;

    /**
     * Writes a signed 64 bit value as a varint, zig-zag encoded.
     * @param {Long|number|string} value Value to write
     * @returns {Writer} `this`
     * @throws {TypeError} If `value` is a string and no long library is present.
     */
    Writer$1.prototype.sint64 = function write_sint64(value) {
        var bits = LongBits$1.from(value).zzEncode();
        return this._push(writeVarint64, bits.length(), bits);
    };

    /**
     * Writes a boolish value as a varint.
     * @param {boolean} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.bool = function write_bool(value) {
        return this._push(writeByte, 1, value ? 1 : 0);
    };

    function writeFixed32(val, buf, pos) {
        buf[pos    ] =  val         & 255;
        buf[pos + 1] =  val >>> 8   & 255;
        buf[pos + 2] =  val >>> 16  & 255;
        buf[pos + 3] =  val >>> 24;
    }

    /**
     * Writes an unsigned 32 bit value as fixed 32 bits.
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.fixed32 = function write_fixed32(value) {
        return this._push(writeFixed32, 4, value >>> 0);
    };

    /**
     * Writes a signed 32 bit value as fixed 32 bits.
     * @function
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.sfixed32 = Writer$1.prototype.fixed32;

    /**
     * Writes an unsigned 64 bit value as fixed 64 bits.
     * @param {Long|number|string} value Value to write
     * @returns {Writer} `this`
     * @throws {TypeError} If `value` is a string and no long library is present.
     */
    Writer$1.prototype.fixed64 = function write_fixed64(value) {
        var bits = LongBits$1.from(value);
        return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);
    };

    /**
     * Writes a signed 64 bit value as fixed 64 bits.
     * @function
     * @param {Long|number|string} value Value to write
     * @returns {Writer} `this`
     * @throws {TypeError} If `value` is a string and no long library is present.
     */
    Writer$1.prototype.sfixed64 = Writer$1.prototype.fixed64;

    /**
     * Writes a float (32 bit).
     * @function
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.float = function write_float(value) {
        return this._push(util$7.float.writeFloatLE, 4, value);
    };

    /**
     * Writes a double (64 bit float).
     * @function
     * @param {number} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.double = function write_double(value) {
        return this._push(util$7.float.writeDoubleLE, 8, value);
    };

    var writeBytes = util$7.Array.prototype.set
        ? function writeBytes_set(val, buf, pos) {
            buf.set(val, pos); // also works for plain array values
        }
        /* istanbul ignore next */
        : function writeBytes_for(val, buf, pos) {
            for (var i = 0; i < val.length; ++i)
                buf[pos + i] = val[i];
        };

    /**
     * Writes a sequence of bytes.
     * @param {Uint8Array|string} value Buffer or base64 encoded string to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.bytes = function write_bytes(value) {
        var len = value.length >>> 0;
        if (!len)
            return this._push(writeByte, 1, 0);
        if (util$7.isString(value)) {
            var buf = Writer$1.alloc(len = base64.length(value));
            base64.decode(value, buf, 0);
            value = buf;
        }
        return this.uint32(len)._push(writeBytes, len, value);
    };

    /**
     * Writes a string.
     * @param {string} value Value to write
     * @returns {Writer} `this`
     */
    Writer$1.prototype.string = function write_string(value) {
        var len = utf8$1.length(value);
        return len
            ? this.uint32(len)._push(utf8$1.write, len, value)
            : this._push(writeByte, 1, 0);
    };

    /**
     * Forks this writer's state by pushing it to a stack.
     * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.
     * @returns {Writer} `this`
     */
    Writer$1.prototype.fork = function fork() {
        this.states = new State(this);
        this.head = this.tail = new Op(noop, 0, 0);
        this.len = 0;
        return this;
    };

    /**
     * Resets this instance to the last state.
     * @returns {Writer} `this`
     */
    Writer$1.prototype.reset = function reset() {
        if (this.states) {
            this.head   = this.states.head;
            this.tail   = this.states.tail;
            this.len    = this.states.len;
            this.states = this.states.next;
        } else {
            this.head = this.tail = new Op(noop, 0, 0);
            this.len  = 0;
        }
        return this;
    };

    /**
     * Resets to the last state and appends the fork state's current write length as a varint followed by its operations.
     * @returns {Writer} `this`
     */
    Writer$1.prototype.ldelim = function ldelim() {
        var head = this.head,
            tail = this.tail,
            len  = this.len;
        this.reset().uint32(len);
        if (len) {
            this.tail.next = head.next; // skip noop
            this.tail = tail;
            this.len += len;
        }
        return this;
    };

    /**
     * Finishes the write operation.
     * @returns {Uint8Array} Finished buffer
     */
    Writer$1.prototype.finish = function finish() {
        var head = this.head.next, // skip noop
            buf  = this.constructor.alloc(this.len),
            pos  = 0;
        while (head) {
            head.fn(head.val, buf, pos);
            pos += head.len;
            head = head.next;
        }
        // this.head = this.tail = null;
        return buf;
    };

    Writer$1._configure = function(BufferWriter_) {
        BufferWriter$1 = BufferWriter_;
        Writer$1.create = create$1();
        BufferWriter$1._configure();
    };

    const writer$1 = /*@__PURE__*/getDefaultExportFromCjs(writer);

    "use strict";
    var writer_buffer = BufferWriter;

    // extends Writer
    var Writer = writer;
    (BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter;

    var util$6 = requireMinimal();

    /**
     * Constructs a new buffer writer instance.
     * @classdesc Wire format writer using node buffers.
     * @extends Writer
     * @constructor
     */
    function BufferWriter() {
        Writer.call(this);
    }

    BufferWriter._configure = function () {
        /**
         * Allocates a buffer of the specified size.
         * @function
         * @param {number} size Buffer size
         * @returns {Buffer} Buffer
         */
        BufferWriter.alloc = util$6._Buffer_allocUnsafe;

        BufferWriter.writeBytesBuffer = util$6.Buffer && util$6.Buffer.prototype instanceof Uint8Array && util$6.Buffer.prototype.set.name === "set"
            ? function writeBytesBuffer_set(val, buf, pos) {
              buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited)
              // also works for plain array values
            }
            /* istanbul ignore next */
            : function writeBytesBuffer_copy(val, buf, pos) {
              if (val.copy) // Buffer values
                val.copy(buf, pos, 0, val.length);
              else for (var i = 0; i < val.length;) // plain array values
                buf[pos++] = val[i++];
            };
    };


    /**
     * @override
     */
    BufferWriter.prototype.bytes = function write_bytes_buffer(value) {
        if (util$6.isString(value))
            value = util$6._Buffer_from(value, "base64");
        var len = value.length >>> 0;
        this.uint32(len);
        if (len)
            this._push(BufferWriter.writeBytesBuffer, len, value);
        return this;
    };

    function writeStringBuffer(val, buf, pos) {
        if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions)
            util$6.utf8.write(val, buf, pos);
        else if (buf.utf8Write)
            buf.utf8Write(val, pos);
        else
            buf.write(val, pos);
    }

    /**
     * @override
     */
    BufferWriter.prototype.string = function write_string_buffer(value) {
        var len = util$6.Buffer.byteLength(value);
        this.uint32(len);
        if (len)
            this._push(writeStringBuffer, len, value);
        return this;
    };


    /**
     * Finishes the write operation.
     * @name BufferWriter#finish
     * @function
     * @returns {Buffer} Finished buffer
     */

    BufferWriter._configure();

    const writer_buffer$1 = /*@__PURE__*/getDefaultExportFromCjs(writer_buffer);

    "use strict";
    var reader = Reader$1;

    var util$5      = requireMinimal();

    var BufferReader$1; // cyclic

    var LongBits  = util$5.LongBits,
        utf8      = util$5.utf8;

    /* istanbul ignore next */
    function indexOutOfRange(reader, writeLength) {
        return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len);
    }

    /**
     * Constructs a new reader instance using the specified buffer.
     * @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`.
     * @constructor
     * @param {Uint8Array} buffer Buffer to read from
     */
    function Reader$1(buffer) {

        /**
         * Read buffer.
         * @type {Uint8Array}
         */
        this.buf = buffer;

        /**
         * Read buffer position.
         * @type {number}
         */
        this.pos = 0;

        /**
         * Read buffer length.
         * @type {number}
         */
        this.len = buffer.length;
    }

    var create_array = typeof Uint8Array !== "undefined"
        ? function create_typed_array(buffer) {
            if (buffer instanceof Uint8Array || Array.isArray(buffer))
                return new Reader$1(buffer);
            throw Error("illegal buffer");
        }
        /* istanbul ignore next */
        : function create_array(buffer) {
            if (Array.isArray(buffer))
                return new Reader$1(buffer);
            throw Error("illegal buffer");
        };

    var create = function create() {
        return util$5.Buffer
            ? function create_buffer_setup(buffer) {
                return (Reader$1.create = function create_buffer(buffer) {
                    return util$5.Buffer.isBuffer(buffer)
                        ? new BufferReader$1(buffer)
                        /* istanbul ignore next */
                        : create_array(buffer);
                })(buffer);
            }
            /* istanbul ignore next */
            : create_array;
    };

    /**
     * Creates a new reader using the specified buffer.
     * @function
     * @param {Uint8Array|Buffer} buffer Buffer to read from
     * @returns {Reader|BufferReader} A {@link BufferReader} if `buffer` is a Buffer, otherwise a {@link Reader}
     * @throws {Error} If `buffer` is not a valid buffer
     */
    Reader$1.create = create();

    Reader$1.prototype._slice = util$5.Array.prototype.subarray || /* istanbul ignore next */ util$5.Array.prototype.slice;

    /**
     * Reads a varint as an unsigned 32 bit value.
     * @function
     * @returns {number} Value read
     */
    Reader$1.prototype.uint32 = (function read_uint32_setup() {
        var value = 4294967295; // optimizer type-hint, tends to deopt otherwise (?!)
        return function read_uint32() {
            value = (         this.buf[this.pos] & 127       ) >>> 0; if (this.buf[this.pos++] < 128) return value;
            value = (value | (this.buf[this.pos] & 127) <<  7) >>> 0; if (this.buf[this.pos++] < 128) return value;
            value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; if (this.buf[this.pos++] < 128) return value;
            value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; if (this.buf[this.pos++] < 128) return value;
            value = (value | (this.buf[this.pos] &  15) << 28) >>> 0; if (this.buf[this.pos++] < 128) return value;

            /* istanbul ignore if */
            if ((this.pos += 5) > this.len) {
                this.pos = this.len;
                throw indexOutOfRange(this, 10);
            }
            return value;
        };
    })();

    /**
     * Reads a varint as a signed 32 bit value.
     * @returns {number} Value read
     */
    Reader$1.prototype.int32 = function read_int32() {
        return this.uint32() | 0;
    };

    /**
     * Reads a zig-zag encoded varint as a signed 32 bit value.
     * @returns {number} Value read
     */
    Reader$1.prototype.sint32 = function read_sint32() {
        var value = this.uint32();
        return value >>> 1 ^ -(value & 1) | 0;
    };

    /* eslint-disable no-invalid-this */

    function readLongVarint() {
        // tends to deopt with local vars for octet etc.
        var bits = new LongBits(0, 0);
        var i = 0;
        if (this.len - this.pos > 4) { // fast route (lo)
            for (; i < 4; ++i) {
                // 1st..4th
                bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
                if (this.buf[this.pos++] < 128)
                    return bits;
            }
            // 5th
            bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0;
            bits.hi = (bits.hi | (this.buf[this.pos] & 127) >>  4) >>> 0;
            if (this.buf[this.pos++] < 128)
                return bits;
            i = 0;
        } else {
            for (; i < 3; ++i) {
                /* istanbul ignore if */
                if (this.pos >= this.len)
                    throw indexOutOfRange(this);
                // 1st..3th
                bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
                if (this.buf[this.pos++] < 128)
                    return bits;
            }
            // 4th
            bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0;
            return bits;
        }
        if (this.len - this.pos > 4) { // fast route (hi)
            for (; i < 5; ++i) {
                // 6th..10th
                bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
                if (this.buf[this.pos++] < 128)
                    return bits;
            }
        } else {
            for (; i < 5; ++i) {
                /* istanbul ignore if */
                if (this.pos >= this.len)
                    throw indexOutOfRange(this);
                // 6th..10th
                bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
                if (this.buf[this.pos++] < 128)
                    return bits;
            }
        }
        /* istanbul ignore next */
        throw Error("invalid varint encoding");
    }

    /* eslint-enable no-invalid-this */

    /**
     * Reads a varint as a signed 64 bit value.
     * @name Reader#int64
     * @function
     * @returns {Long} Value read
     */

    /**
     * Reads a varint as an unsigned 64 bit value.
     * @name Reader#uint64
     * @function
     * @returns {Long} Value read
     */

    /**
     * Reads a zig-zag encoded varint as a signed 64 bit value.
     * @name Reader#sint64
     * @function
     * @returns {Long} Value read
     */

    /**
     * Reads a varint as a boolean.
     * @returns {boolean} Value read
     */
    Reader$1.prototype.bool = function read_bool() {
        return this.uint32() !== 0;
    };

    function readFixed32_end(buf, end) { // note that this uses `end`, not `pos`
        return (buf[end - 4]
              | buf[end - 3] << 8
              | buf[end - 2] << 16
              | buf[end - 1] << 24) >>> 0;
    }

    /**
     * Reads fixed 32 bits as an unsigned 32 bit integer.
     * @returns {number} Value read
     */
    Reader$1.prototype.fixed32 = function read_fixed32() {

        /* istanbul ignore if */
        if (this.pos + 4 > this.len)
            throw indexOutOfRange(this, 4);

        return readFixed32_end(this.buf, this.pos += 4);
    };

    /**
     * Reads fixed 32 bits as a signed 32 bit integer.
     * @returns {number} Value read
     */
    Reader$1.prototype.sfixed32 = function read_sfixed32() {

        /* istanbul ignore if */
        if (this.pos + 4 > this.len)
            throw indexOutOfRange(this, 4);

        return readFixed32_end(this.buf, this.pos += 4) | 0;
    };

    /* eslint-disable no-invalid-this */

    function readFixed64(/* this: Reader */) {

        /* istanbul ignore if */
        if (this.pos + 8 > this.len)
            throw indexOutOfRange(this, 8);

        return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4));
    }

    /* eslint-enable no-invalid-this */

    /**
     * Reads fixed 64 bits.
     * @name Reader#fixed64
     * @function
     * @returns {Long} Value read
     */

    /**
     * Reads zig-zag encoded fixed 64 bits.
     * @name Reader#sfixed64
     * @function
     * @returns {Long} Value read
     */

    /**
     * Reads a float (32 bit) as a number.
     * @function
     * @returns {number} Value read
     */
    Reader$1.prototype.float = function read_float() {

        /* istanbul ignore if */
        if (this.pos + 4 > this.len)
            throw indexOutOfRange(this, 4);

        var value = util$5.float.readFloatLE(this.buf, this.pos);
        this.pos += 4;
        return value;
    };

    /**
     * Reads a double (64 bit float) as a number.
     * @function
     * @returns {number} Value read
     */
    Reader$1.prototype.double = function read_double() {

        /* istanbul ignore if */
        if (this.pos + 8 > this.len)
            throw indexOutOfRange(this, 4);

        var value = util$5.float.readDoubleLE(this.buf, this.pos);
        this.pos += 8;
        return value;
    };

    /**
     * Reads a sequence of bytes preceeded by its length as a varint.
     * @returns {Uint8Array} Value read
     */
    Reader$1.prototype.bytes = function read_bytes() {
        var length = this.uint32(),
            start  = this.pos,
            end    = this.pos + length;

        /* istanbul ignore if */
        if (end > this.len)
            throw indexOutOfRange(this, length);

        this.pos += length;
        if (Array.isArray(this.buf)) // plain array
            return this.buf.slice(start, end);
        return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1
            ? new this.buf.constructor(0)
            : this._slice.call(this.buf, start, end);
    };

    /**
     * Reads a string preceeded by its byte length as a varint.
     * @returns {string} Value read
     */
    Reader$1.prototype.string = function read_string() {
        var bytes = this.bytes();
        return utf8.read(bytes, 0, bytes.length);
    };

    /**
     * Skips the specified number of bytes if specified, otherwise skips a varint.
     * @param {number} [length] Length if known, otherwise a varint is assumed
     * @returns {Reader} `this`
     */
    Reader$1.prototype.skip = function skip(length) {
        if (typeof length === "number") {
            /* istanbul ignore if */
            if (this.pos + length > this.len)
                throw indexOutOfRange(this, length);
            this.pos += length;
        } else {
            do {
                /* istanbul ignore if */
                if (this.pos >= this.len)
                    throw indexOutOfRange(this);
            } while (this.buf[this.pos++] & 128);
        }
        return this;
    };

    /**
     * Skips the next element of the specified wire type.
     * @param {number} wireType Wire type received
     * @returns {Reader} `this`
     */
    Reader$1.prototype.skipType = function(wireType) {
        switch (wireType) {
            case 0:
                this.skip();
                break;
            case 1:
                this.skip(8);
                break;
            case 2:
                this.skip(this.uint32());
                break;
            case 3:
                while ((wireType = this.uint32() & 7) !== 4) {
                    this.skipType(wireType);
                }
                break;
            case 5:
                this.skip(4);
                break;

            /* istanbul ignore next */
            default:
                throw Error("invalid wire type " + wireType + " at offset " + this.pos);
        }
        return this;
    };

    Reader$1._configure = function(BufferReader_) {
        BufferReader$1 = BufferReader_;
        Reader$1.create = create();
        BufferReader$1._configure();

        var fn = util$5.Long ? "toLong" : /* istanbul ignore next */ "toNumber";
        util$5.merge(Reader$1.prototype, {

            int64: function read_int64() {
                return readLongVarint.call(this)[fn](false);
            },

            uint64: function read_uint64() {
                return readLongVarint.call(this)[fn](true);
            },

            sint64: function read_sint64() {
                return readLongVarint.call(this).zzDecode()[fn](false);
            },

            fixed64: function read_fixed64() {
                return readFixed64.call(this)[fn](true);
            },

            sfixed64: function read_sfixed64() {
                return readFixed64.call(this)[fn](false);
            }

        });
    };

    const reader$1 = /*@__PURE__*/getDefaultExportFromCjs(reader);

    "use strict";
    var reader_buffer = BufferReader;

    // extends Reader
    var Reader = reader;
    (BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader;

    var util$4 = requireMinimal();

    /**
     * Constructs a new buffer reader instance.
     * @classdesc Wire format reader using node buffers.
     * @extends Reader
     * @constructor
     * @param {Buffer} buffer Buffer to read from
     */
    function BufferReader(buffer) {
        Reader.call(this, buffer);

        /**
         * Read buffer.
         * @name BufferReader#buf
         * @type {Buffer}
         */
    }

    BufferReader._configure = function () {
        /* istanbul ignore else */
        if (util$4.Buffer)
            BufferReader.prototype._slice = util$4.Buffer.prototype.slice;
    };


    /**
     * @override
     */
    BufferReader.prototype.string = function read_string_buffer() {
        var len = this.uint32(); // modifies pos
        return this.buf.utf8Slice
            ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len))
            : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len));
    };

    /**
     * Reads a sequence of bytes preceeded by its length as a varint.
     * @name BufferReader#bytes
     * @function
     * @returns {Buffer} Value read
     */

    BufferReader._configure();

    const reader_buffer$1 = /*@__PURE__*/getDefaultExportFromCjs(reader_buffer);

    var rpc$1 = {};

    "use strict";
    var service$1 = Service$1;

    var util$3 = requireMinimal();

    // Extends EventEmitter
    (Service$1.prototype = Object.create(util$3.EventEmitter.prototype)).constructor = Service$1;

    /**
     * A service method callback as used by {@link rpc.ServiceMethod|ServiceMethod}.
     *
     * Differs from {@link RPCImplCallback} in that it is an actual callback of a service method which may not return `response = null`.
     * @typedef rpc.ServiceMethodCallback
     * @template TRes extends Message<TRes>
     * @type {function}
     * @param {Error|null} error Error, if any
     * @param {TRes} [response] Response message
     * @returns {undefined}
     */

    /**
     * A service method part of a {@link rpc.Service} as created by {@link Service.create}.
     * @typedef rpc.ServiceMethod
     * @template TReq extends Message<TReq>
     * @template TRes extends Message<TRes>
     * @type {function}
     * @param {TReq|Properties<TReq>} request Request message or plain object
     * @param {rpc.ServiceMethodCallback<TRes>} [callback] Node-style callback called with the error, if any, and the response message
     * @returns {Promise<Message<TRes>>} Promise if `callback` has been omitted, otherwise `undefined`
     */

    /**
     * Constructs a new RPC service instance.
     * @classdesc An RPC service as returned by {@link Service#create}.
     * @exports rpc.Service
     * @extends util.EventEmitter
     * @constructor
     * @param {RPCImpl} rpcImpl RPC implementation
     * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
     * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
     */
    function Service$1(rpcImpl, requestDelimited, responseDelimited) {

        if (typeof rpcImpl !== "function")
            throw TypeError("rpcImpl must be a function");

        util$3.EventEmitter.call(this);

        /**
         * RPC implementation. Becomes `null` once the service is ended.
         * @type {RPCImpl|null}
         */
        this.rpcImpl = rpcImpl;

        /**
         * Whether requests are length-delimited.
         * @type {boolean}
         */
        this.requestDelimited = Boolean(requestDelimited);

        /**
         * Whether responses are length-delimited.
         * @type {boolean}
         */
        this.responseDelimited = Boolean(responseDelimited);
    }

    /**
     * Calls a service method through {@link rpc.Service#rpcImpl|rpcImpl}.
     * @param {Method|rpc.ServiceMethod<TReq,TRes>} method Reflected or static method
     * @param {Constructor<TReq>} requestCtor Request constructor
     * @param {Constructor<TRes>} responseCtor Response constructor
     * @param {TReq|Properties<TReq>} request Request message or plain object
     * @param {rpc.ServiceMethodCallback<TRes>} callback Service callback
     * @returns {undefined}
     * @template TReq extends Message<TReq>
     * @template TRes extends Message<TRes>
     */
    Service$1.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) {

        if (!request)
            throw TypeError("request must be specified");

        var self = this;
        if (!callback)
            return util$3.asPromise(rpcCall, self, method, requestCtor, responseCtor, request);

        if (!self.rpcImpl) {
            setTimeout(function() { callback(Error("already ended")); }, 0);
            return undefined;
        }

        try {
            return self.rpcImpl(
                method,
                requestCtor[self.requestDelimited ? "encodeDelimited" : "encode"](request).finish(),
                function rpcCallback(err, response) {

                    if (err) {
                        self.emit("error", err, method);
                        return callback(err);
                    }

                    if (response === null) {
                        self.end(/* endedByRPC */ true);
                        return undefined;
                    }

                    if (!(response instanceof responseCtor)) {
                        try {
                            response = responseCtor[self.responseDelimited ? "decodeDelimited" : "decode"](response);
                        } catch (err) {
                            self.emit("error", err, method);
                            return callback(err);
                        }
                    }

                    self.emit("data", response, method);
                    return callback(null, response);
                }
            );
        } catch (err) {
            self.emit("error", err, method);
            setTimeout(function() { callback(err); }, 0);
            return undefined;
        }
    };

    /**
     * Ends this service and emits the `end` event.
     * @param {boolean} [endedByRPC=false] Whether the service has been ended by the RPC implementation.
     * @returns {rpc.Service} `this`
     */
    Service$1.prototype.end = function end(endedByRPC) {
        if (this.rpcImpl) {
            if (!endedByRPC) // signal end to rpcImpl
                this.rpcImpl(null, null, null);
            this.rpcImpl = null;
            this.emit("end").off();
        }
        return this;
    };

    const service$2 = /*@__PURE__*/getDefaultExportFromCjs(service$1);

    (function (exports) {
    	"use strict";

    	/**
    	 * Streaming RPC helpers.
    	 * @namespace
    	 */
    	var rpc = exports;

    	/**
    	 * RPC implementation passed to {@link Service#create} performing a service request on network level, i.e. by utilizing http requests or websockets.
    	 * @typedef RPCImpl
    	 * @type {function}
    	 * @param {Method|rpc.ServiceMethod<Message<{}>,Message<{}>>} method Reflected or static method being called
    	 * @param {Uint8Array} requestData Request data
    	 * @param {RPCImplCallback} callback Callback function
    	 * @returns {undefined}
    	 * @example
    	 * function rpcImpl(method, requestData, callback) {
    	 *     if (protobuf.util.lcFirst(method.name) !== "myMethod") // compatible with static code
    	 *         throw Error("no such method");
    	 *     asynchronouslyObtainAResponse(requestData, function(err, responseData) {
    	 *         callback(err, responseData);
    	 *     });
    	 * }
    	 */

    	/**
    	 * Node-style callback as used by {@link RPCImpl}.
    	 * @typedef RPCImplCallback
    	 * @type {function}
    	 * @param {Error|null} error Error, if any, otherwise `null`
    	 * @param {Uint8Array|null} [response] Response data or `null` to signal end of stream, if there hasn't been an error
    	 * @returns {undefined}
    	 */

    	rpc.Service = service$1; 
    } (rpc$1));

    const rpc = /*@__PURE__*/getDefaultExportFromCjs(rpc$1);

    "use strict";
    var roots = {};

    /**
     * Named roots.
     * This is where pbjs stores generated structures (the option `-r, --root` specifies a name).
     * Can also be used manually to make roots available across modules.
     * @name roots
     * @type {Object.<string,Root>}
     * @example
     * // pbjs -r myroot -o compiled.js ...
     *
     * // in another module:
     * require("./compiled.js");
     *
     * // in any subsequent module:
     * var root = protobuf.roots["myroot"];
     */

    const roots$1 = /*@__PURE__*/getDefaultExportFromCjs(roots);

    (function (exports) {
    	"use strict";
    	var protobuf = exports;

    	/**
    	 * Build type, one of `"full"`, `"light"` or `"minimal"`.
    	 * @name build
    	 * @type {string}
    	 * @const
    	 */
    	protobuf.build = "minimal";

    	// Serialization
    	protobuf.Writer       = writer;
    	protobuf.BufferWriter = writer_buffer;
    	protobuf.Reader       = reader;
    	protobuf.BufferReader = reader_buffer;

    	// Utility
    	protobuf.util         = requireMinimal();
    	protobuf.rpc          = rpc$1;
    	protobuf.roots        = roots;
    	protobuf.configure    = configure;

    	/* istanbul ignore next */
    	/**
    	 * Reconfigures the library according to the environment.
    	 * @returns {undefined}
    	 */
    	function configure() {
    	    protobuf.util._configure();
    	    protobuf.Writer._configure(protobuf.BufferWriter);
    	    protobuf.Reader._configure(protobuf.BufferReader);
    	}

    	// Set up buffer utility according to the environment
    	configure(); 
    } (indexMinimal$1));

    const indexMinimal = /*@__PURE__*/getDefaultExportFromCjs(indexMinimal$1);

    var util$2 = {exports: {}};

    var codegen_1;
    var hasRequiredCodegen;

    function requireCodegen () {
    	if (hasRequiredCodegen) return codegen_1;
    	hasRequiredCodegen = 1;
    	"use strict";
    	codegen_1 = codegen;

    	/**
    	 * Begins generating a function.
    	 * @memberof util
    	 * @param {string[]} functionParams Function parameter names
    	 * @param {string} [functionName] Function name if not anonymous
    	 * @returns {Codegen} Appender that appends code to the function's body
    	 */
    	function codegen(functionParams, functionName) {

    	    /* istanbul ignore if */
    	    if (typeof functionParams === "string") {
    	        functionName = functionParams;
    	        functionParams = undefined;
    	    }

    	    var body = [];

    	    /**
    	     * Appends code to the function's body or finishes generation.
    	     * @typedef Codegen
    	     * @type {function}
    	     * @param {string|Object.<string,*>} [formatStringOrScope] Format string or, to finish the function, an object of additional scope variables, if any
    	     * @param {...*} [formatParams] Format parameters
    	     * @returns {Codegen|Function} Itself or the generated function if finished
    	     * @throws {Error} If format parameter counts do not match
    	     */

    	    function Codegen(formatStringOrScope) {
    	        // note that explicit array handling below makes this ~50% faster

    	        // finish the function
    	        if (typeof formatStringOrScope !== "string") {
    	            var source = toString();
    	            if (codegen.verbose)
    	                console.log("codegen: " + source); // eslint-disable-line no-console
    	            source = "return " + source;
    	            if (formatStringOrScope) {
    	                var scopeKeys   = Object.keys(formatStringOrScope),
    	                    scopeParams = new Array(scopeKeys.length + 1),
    	                    scopeValues = new Array(scopeKeys.length),
    	                    scopeOffset = 0;
    	                while (scopeOffset < scopeKeys.length) {
    	                    scopeParams[scopeOffset] = scopeKeys[scopeOffset];
    	                    scopeValues[scopeOffset] = formatStringOrScope[scopeKeys[scopeOffset++]];
    	                }
    	                scopeParams[scopeOffset] = source;
    	                return Function.apply(null, scopeParams).apply(null, scopeValues); // eslint-disable-line no-new-func
    	            }
    	            return Function(source)(); // eslint-disable-line no-new-func
    	        }

    	        // otherwise append to body
    	        var formatParams = new Array(arguments.length - 1),
    	            formatOffset = 0;
    	        while (formatOffset < formatParams.length)
    	            formatParams[formatOffset] = arguments[++formatOffset];
    	        formatOffset = 0;
    	        formatStringOrScope = formatStringOrScope.replace(/%([%dfijs])/g, function replace($0, $1) {
    	            var value = formatParams[formatOffset++];
    	            switch ($1) {
    	                case "d": case "f": return String(Number(value));
    	                case "i": return String(Math.floor(value));
    	                case "j": return JSON.stringify(value);
    	                case "s": return String(value);
    	            }
    	            return "%";
    	        });
    	        if (formatOffset !== formatParams.length)
    	            throw Error("parameter count mismatch");
    	        body.push(formatStringOrScope);
    	        return Codegen;
    	    }

    	    function toString(functionNameOverride) {
    	        return "function " + (functionNameOverride || functionName || "") + "(" + (functionParams && functionParams.join(",") || "") + "){\n  " + body.join("\n  ") + "\n}";
    	    }

    	    Codegen.toString = toString;
    	    return Codegen;
    	}

    	/**
    	 * Begins generating a function.
    	 * @memberof util
    	 * @function codegen
    	 * @param {string} [functionName] Function name if not anonymous
    	 * @returns {Codegen} Appender that appends code to the function's body
    	 * @variation 2
    	 */

    	/**
    	 * When set to `true`, codegen will log generated code to console. Useful for debugging.
    	 * @name util.codegen.verbose
    	 * @type {boolean}
    	 */
    	codegen.verbose = false;
    	return codegen_1;
    }

    var fetch_1;
    var hasRequiredFetch;

    function requireFetch () {
    	if (hasRequiredFetch) return fetch_1;
    	hasRequiredFetch = 1;
    	"use strict";
    	fetch_1 = fetch;

    	var asPromise = requireAspromise(),
    	    inquire   = requireInquire();

    	var fs = inquire("fs");

    	/**
    	 * Node-style callback as used by {@link util.fetch}.
    	 * @typedef FetchCallback
    	 * @type {function}
    	 * @param {?Error} error Error, if any, otherwise `null`
    	 * @param {string} [contents] File contents, if there hasn't been an error
    	 * @returns {undefined}
    	 */

    	/**
    	 * Options as used by {@link util.fetch}.
    	 * @typedef FetchOptions
    	 * @type {Object}
    	 * @property {boolean} [binary=false] Whether expecting a binary response
    	 * @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
    	 */

    	/**
    	 * Fetches the contents of a file.
    	 * @memberof util
    	 * @param {string} filename File path or url
    	 * @param {FetchOptions} options Fetch options
    	 * @param {FetchCallback} callback Callback function
    	 * @returns {undefined}
    	 */
    	function fetch(filename, options, callback) {
    	    if (typeof options === "function") {
    	        callback = options;
    	        options = {};
    	    } else if (!options)
    	        options = {};

    	    if (!callback)
    	        return asPromise(fetch, this, filename, options); // eslint-disable-line no-invalid-this

    	    // if a node-like filesystem is present, try it first but fall back to XHR if nothing is found.
    	    if (!options.xhr && fs && fs.readFile)
    	        return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
    	            return err && typeof XMLHttpRequest !== "undefined"
    	                ? fetch.xhr(filename, options, callback)
    	                : err
    	                ? callback(err)
    	                : callback(null, options.binary ? contents : contents.toString("utf8"));
    	        });

    	    // use the XHR version otherwise.
    	    return fetch.xhr(filename, options, callback);
    	}

    	/**
    	 * Fetches the contents of a file.
    	 * @name util.fetch
    	 * @function
    	 * @param {string} path File path or url
    	 * @param {FetchCallback} callback Callback function
    	 * @returns {undefined}
    	 * @variation 2
    	 */

    	/**
    	 * Fetches the contents of a file.
    	 * @name util.fetch
    	 * @function
    	 * @param {string} path File path or url
    	 * @param {FetchOptions} [options] Fetch options
    	 * @returns {Promise<string|Uint8Array>} Promise
    	 * @variation 3
    	 */

    	/**/
    	fetch.xhr = function fetch_xhr(filename, options, callback) {
    	    var xhr = new XMLHttpRequest();
    	    xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {

    	        if (xhr.readyState !== 4)
    	            return undefined;

    	        // local cors security errors return status 0 / empty string, too. afaik this cannot be
    	        // reliably distinguished from an actually empty file for security reasons. feel free
    	        // to send a pull request if you are aware of a solution.
    	        if (xhr.status !== 0 && xhr.status !== 200)
    	            return callback(Error("status " + xhr.status));

    	        // if binary data is expected, make sure that some sort of array is returned, even if
    	        // ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
    	        if (options.binary) {
    	            var buffer = xhr.response;
    	            if (!buffer) {
    	                buffer = [];
    	                for (var i = 0; i < xhr.responseText.length; ++i)
    	                    buffer.push(xhr.responseText.charCodeAt(i) & 255);
    	            }
    	            return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
    	        }
    	        return callback(null, xhr.responseText);
    	    };

    	    if (options.binary) {
    	        // ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
    	        if ("overrideMimeType" in xhr)
    	            xhr.overrideMimeType("text/plain; charset=x-user-defined");
    	        xhr.responseType = "arraybuffer";
    	    }

    	    xhr.open("GET", filename);
    	    xhr.send();
    	};
    	return fetch_1;
    }

    var path = {};

    var hasRequiredPath;

    function requirePath () {
    	if (hasRequiredPath) return path;
    	hasRequiredPath = 1;
    	(function (exports) {
    		"use strict";

    		/**
    		 * A minimal path module to resolve Unix, Windows and URL paths alike.
    		 * @memberof util
    		 * @namespace
    		 */
    		var path = exports;

    		var isAbsolute =
    		/**
    		 * Tests if the specified path is absolute.
    		 * @param {string} path Path to test
    		 * @returns {boolean} `true` if path is absolute
    		 */
    		path.isAbsolute = function isAbsolute(path) {
    		    return /^(?:\/|\w+:)/.test(path);
    		};

    		var normalize =
    		/**
    		 * Normalizes the specified path.
    		 * @param {string} path Path to normalize
    		 * @returns {string} Normalized path
    		 */
    		path.normalize = function normalize(path) {
    		    path = path.replace(/\\/g, "/")
    		               .replace(/\/{2,}/g, "/");
    		    var parts    = path.split("/"),
    		        absolute = isAbsolute(path),
    		        prefix   = "";
    		    if (absolute)
    		        prefix = parts.shift() + "/";
    		    for (var i = 0; i < parts.length;) {
    		        if (parts[i] === "..") {
    		            if (i > 0 && parts[i - 1] !== "..")
    		                parts.splice(--i, 2);
    		            else if (absolute)
    		                parts.splice(i, 1);
    		            else
    		                ++i;
    		        } else if (parts[i] === ".")
    		            parts.splice(i, 1);
    		        else
    		            ++i;
    		    }
    		    return prefix + parts.join("/");
    		};

    		/**
    		 * Resolves the specified include path against the specified origin path.
    		 * @param {string} originPath Path to the origin file
    		 * @param {string} includePath Include path relative to origin path
    		 * @param {boolean} [alreadyNormalized=false] `true` if both paths are already known to be normalized
    		 * @returns {string} Path to the include file
    		 */
    		path.resolve = function resolve(originPath, includePath, alreadyNormalized) {
    		    if (!alreadyNormalized)
    		        includePath = normalize(includePath);
    		    if (isAbsolute(includePath))
    		        return includePath;
    		    if (!alreadyNormalized)
    		        originPath = normalize(originPath);
    		    return (originPath = originPath.replace(/(?:\/|^)[^/]+$/, "")).length ? normalize(originPath + "/" + includePath) : includePath;
    		}; 
    	} (path));
    	return path;
    }

    var types$1 = {};

    var hasRequiredTypes;

    function requireTypes () {
    	if (hasRequiredTypes) return types$1;
    	hasRequiredTypes = 1;
    	(function (exports) {
    		"use strict";

    		/**
    		 * Common type constants.
    		 * @namespace
    		 */
    		var types = exports;

    		var util = requireUtil();

    		var s = [
    		    "double",   // 0
    		    "float",    // 1
    		    "int32",    // 2
    		    "uint32",   // 3
    		    "sint32",   // 4
    		    "fixed32",  // 5
    		    "sfixed32", // 6
    		    "int64",    // 7
    		    "uint64",   // 8
    		    "sint64",   // 9
    		    "fixed64",  // 10
    		    "sfixed64", // 11
    		    "bool",     // 12
    		    "string",   // 13
    		    "bytes"     // 14
    		];

    		function bake(values, offset) {
    		    var i = 0, o = {};
    		    offset |= 0;
    		    while (i < values.length) o[s[i + offset]] = values[i++];
    		    return o;
    		}

    		/**
    		 * Basic type wire types.
    		 * @type {Object.<string,number>}
    		 * @const
    		 * @property {number} double=1 Fixed64 wire type
    		 * @property {number} float=5 Fixed32 wire type
    		 * @property {number} int32=0 Varint wire type
    		 * @property {number} uint32=0 Varint wire type
    		 * @property {number} sint32=0 Varint wire type
    		 * @property {number} fixed32=5 Fixed32 wire type
    		 * @property {number} sfixed32=5 Fixed32 wire type
    		 * @property {number} int64=0 Varint wire type
    		 * @property {number} uint64=0 Varint wire type
    		 * @property {number} sint64=0 Varint wire type
    		 * @property {number} fixed64=1 Fixed64 wire type
    		 * @property {number} sfixed64=1 Fixed64 wire type
    		 * @property {number} bool=0 Varint wire type
    		 * @property {number} string=2 Ldelim wire type
    		 * @property {number} bytes=2 Ldelim wire type
    		 */
    		types.basic = bake([
    		    /* double   */ 1,
    		    /* float    */ 5,
    		    /* int32    */ 0,
    		    /* uint32   */ 0,
    		    /* sint32   */ 0,
    		    /* fixed32  */ 5,
    		    /* sfixed32 */ 5,
    		    /* int64    */ 0,
    		    /* uint64   */ 0,
    		    /* sint64   */ 0,
    		    /* fixed64  */ 1,
    		    /* sfixed64 */ 1,
    		    /* bool     */ 0,
    		    /* string   */ 2,
    		    /* bytes    */ 2
    		]);

    		/**
    		 * Basic type defaults.
    		 * @type {Object.<string,*>}
    		 * @const
    		 * @property {number} double=0 Double default
    		 * @property {number} float=0 Float default
    		 * @property {number} int32=0 Int32 default
    		 * @property {number} uint32=0 Uint32 default
    		 * @property {number} sint32=0 Sint32 default
    		 * @property {number} fixed32=0 Fixed32 default
    		 * @property {number} sfixed32=0 Sfixed32 default
    		 * @property {number} int64=0 Int64 default
    		 * @property {number} uint64=0 Uint64 default
    		 * @property {number} sint64=0 Sint32 default
    		 * @property {number} fixed64=0 Fixed64 default
    		 * @property {number} sfixed64=0 Sfixed64 default
    		 * @property {boolean} bool=false Bool default
    		 * @property {string} string="" String default
    		 * @property {Array.<number>} bytes=Array(0) Bytes default
    		 * @property {null} message=null Message default
    		 */
    		types.defaults = bake([
    		    /* double   */ 0,
    		    /* float    */ 0,
    		    /* int32    */ 0,
    		    /* uint32   */ 0,
    		    /* sint32   */ 0,
    		    /* fixed32  */ 0,
    		    /* sfixed32 */ 0,
    		    /* int64    */ 0,
    		    /* uint64   */ 0,
    		    /* sint64   */ 0,
    		    /* fixed64  */ 0,
    		    /* sfixed64 */ 0,
    		    /* bool     */ false,
    		    /* string   */ "",
    		    /* bytes    */ util.emptyArray,
    		    /* message  */ null
    		]);

    		/**
    		 * Basic long type wire types.
    		 * @type {Object.<string,number>}
    		 * @const
    		 * @property {number} int64=0 Varint wire type
    		 * @property {number} uint64=0 Varint wire type
    		 * @property {number} sint64=0 Varint wire type
    		 * @property {number} fixed64=1 Fixed64 wire type
    		 * @property {number} sfixed64=1 Fixed64 wire type
    		 */
    		types.long = bake([
    		    /* int64    */ 0,
    		    /* uint64   */ 0,
    		    /* sint64   */ 0,
    		    /* fixed64  */ 1,
    		    /* sfixed64 */ 1
    		], 7);

    		/**
    		 * Allowed types for map keys with their associated wire type.
    		 * @type {Object.<string,number>}
    		 * @const
    		 * @property {number} int32=0 Varint wire type
    		 * @property {number} uint32=0 Varint wire type
    		 * @property {number} sint32=0 Varint wire type
    		 * @property {number} fixed32=5 Fixed32 wire type
    		 * @property {number} sfixed32=5 Fixed32 wire type
    		 * @property {number} int64=0 Varint wire type
    		 * @property {number} uint64=0 Varint wire type
    		 * @property {number} sint64=0 Varint wire type
    		 * @property {number} fixed64=1 Fixed64 wire type
    		 * @property {number} sfixed64=1 Fixed64 wire type
    		 * @property {number} bool=0 Varint wire type
    		 * @property {number} string=2 Ldelim wire type
    		 */
    		types.mapKey = bake([
    		    /* int32    */ 0,
    		    /* uint32   */ 0,
    		    /* sint32   */ 0,
    		    /* fixed32  */ 5,
    		    /* sfixed32 */ 5,
    		    /* int64    */ 0,
    		    /* uint64   */ 0,
    		    /* sint64   */ 0,
    		    /* fixed64  */ 1,
    		    /* sfixed64 */ 1,
    		    /* bool     */ 0,
    		    /* string   */ 2
    		], 2);

    		/**
    		 * Allowed types for packed repeated fields with their associated wire type.
    		 * @type {Object.<string,number>}
    		 * @const
    		 * @property {number} double=1 Fixed64 wire type
    		 * @property {number} float=5 Fixed32 wire type
    		 * @property {number} int32=0 Varint wire type
    		 * @property {number} uint32=0 Varint wire type
    		 * @property {number} sint32=0 Varint wire type
    		 * @property {number} fixed32=5 Fixed32 wire type
    		 * @property {number} sfixed32=5 Fixed32 wire type
    		 * @property {number} int64=0 Varint wire type
    		 * @property {number} uint64=0 Varint wire type
    		 * @property {number} sint64=0 Varint wire type
    		 * @property {number} fixed64=1 Fixed64 wire type
    		 * @property {number} sfixed64=1 Fixed64 wire type
    		 * @property {number} bool=0 Varint wire type
    		 */
    		types.packed = bake([
    		    /* double   */ 1,
    		    /* float    */ 5,
    		    /* int32    */ 0,
    		    /* uint32   */ 0,
    		    /* sint32   */ 0,
    		    /* fixed32  */ 5,
    		    /* sfixed32 */ 5,
    		    /* int64    */ 0,
    		    /* uint64   */ 0,
    		    /* sint64   */ 0,
    		    /* fixed64  */ 1,
    		    /* sfixed64 */ 1,
    		    /* bool     */ 0
    		]); 
    	} (types$1));
    	return types$1;
    }

    var field;
    var hasRequiredField;

    function requireField () {
    	if (hasRequiredField) return field;
    	hasRequiredField = 1;
    	"use strict";
    	field = Field;

    	// extends ReflectionObject
    	var ReflectionObject = requireObject();
    	((Field.prototype = Object.create(ReflectionObject.prototype)).constructor = Field).className = "Field";

    	var Enum  = require_enum(),
    	    types = requireTypes(),
    	    util  = requireUtil();

    	var Type; // cyclic

    	var ruleRe = /^required|optional|repeated$/;

    	/**
    	 * Constructs a new message field instance. Note that {@link MapField|map fields} have their own class.
    	 * @name Field
    	 * @classdesc Reflected message field.
    	 * @extends FieldBase
    	 * @constructor
    	 * @param {string} name Unique name within its namespace
    	 * @param {number} id Unique id within its namespace
    	 * @param {string} type Value type
    	 * @param {string|Object.<string,*>} [rule="optional"] Field rule
    	 * @param {string|Object.<string,*>} [extend] Extended type if different from parent
    	 * @param {Object.<string,*>} [options] Declared options
    	 */

    	/**
    	 * Constructs a field from a field descriptor.
    	 * @param {string} name Field name
    	 * @param {IField} json Field descriptor
    	 * @returns {Field} Created field
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	Field.fromJSON = function fromJSON(name, json) {
    	    return new Field(name, json.id, json.type, json.rule, json.extend, json.options, json.comment);
    	};

    	/**
    	 * Not an actual constructor. Use {@link Field} instead.
    	 * @classdesc Base class of all reflected message fields. This is not an actual class but here for the sake of having consistent type definitions.
    	 * @exports FieldBase
    	 * @extends ReflectionObject
    	 * @constructor
    	 * @param {string} name Unique name within its namespace
    	 * @param {number} id Unique id within its namespace
    	 * @param {string} type Value type
    	 * @param {string|Object.<string,*>} [rule="optional"] Field rule
    	 * @param {string|Object.<string,*>} [extend] Extended type if different from parent
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @param {string} [comment] Comment associated with this field
    	 */
    	function Field(name, id, type, rule, extend, options, comment) {

    	    if (util.isObject(rule)) {
    	        comment = extend;
    	        options = rule;
    	        rule = extend = undefined;
    	    } else if (util.isObject(extend)) {
    	        comment = options;
    	        options = extend;
    	        extend = undefined;
    	    }

    	    ReflectionObject.call(this, name, options);

    	    if (!util.isInteger(id) || id < 0)
    	        throw TypeError("id must be a non-negative integer");

    	    if (!util.isString(type))
    	        throw TypeError("type must be a string");

    	    if (rule !== undefined && !ruleRe.test(rule = rule.toString().toLowerCase()))
    	        throw TypeError("rule must be a string rule");

    	    if (extend !== undefined && !util.isString(extend))
    	        throw TypeError("extend must be a string");

    	    /**
    	     * Field rule, if any.
    	     * @type {string|undefined}
    	     */
    	    if (rule === "proto3_optional") {
    	        rule = "optional";
    	    }
    	    this.rule = rule && rule !== "optional" ? rule : undefined; // toJSON

    	    /**
    	     * Field type.
    	     * @type {string}
    	     */
    	    this.type = type; // toJSON

    	    /**
    	     * Unique field id.
    	     * @type {number}
    	     */
    	    this.id = id; // toJSON, marker

    	    /**
    	     * Extended type if different from parent.
    	     * @type {string|undefined}
    	     */
    	    this.extend = extend || undefined; // toJSON

    	    /**
    	     * Whether this field is required.
    	     * @type {boolean}
    	     */
    	    this.required = rule === "required";

    	    /**
    	     * Whether this field is optional.
    	     * @type {boolean}
    	     */
    	    this.optional = !this.required;

    	    /**
    	     * Whether this field is repeated.
    	     * @type {boolean}
    	     */
    	    this.repeated = rule === "repeated";

    	    /**
    	     * Whether this field is a map or not.
    	     * @type {boolean}
    	     */
    	    this.map = false;

    	    /**
    	     * Message this field belongs to.
    	     * @type {Type|null}
    	     */
    	    this.message = null;

    	    /**
    	     * OneOf this field belongs to, if any,
    	     * @type {OneOf|null}
    	     */
    	    this.partOf = null;

    	    /**
    	     * The field type's default value.
    	     * @type {*}
    	     */
    	    this.typeDefault = null;

    	    /**
    	     * The field's default value on prototypes.
    	     * @type {*}
    	     */
    	    this.defaultValue = null;

    	    /**
    	     * Whether this field's value should be treated as a long.
    	     * @type {boolean}
    	     */
    	    this.long = util.Long ? types.long[type] !== undefined : /* istanbul ignore next */ false;

    	    /**
    	     * Whether this field's value is a buffer.
    	     * @type {boolean}
    	     */
    	    this.bytes = type === "bytes";

    	    /**
    	     * Resolved type if not a basic type.
    	     * @type {Type|Enum|null}
    	     */
    	    this.resolvedType = null;

    	    /**
    	     * Sister-field within the extended type if a declaring extension field.
    	     * @type {Field|null}
    	     */
    	    this.extensionField = null;

    	    /**
    	     * Sister-field within the declaring namespace if an extended field.
    	     * @type {Field|null}
    	     */
    	    this.declaringField = null;

    	    /**
    	     * Internally remembers whether this field is packed.
    	     * @type {boolean|null}
    	     * @private
    	     */
    	    this._packed = null;

    	    /**
    	     * Comment for this field.
    	     * @type {string|null}
    	     */
    	    this.comment = comment;
    	}

    	/**
    	 * Determines whether this field is packed. Only relevant when repeated and working with proto2.
    	 * @name Field#packed
    	 * @type {boolean}
    	 * @readonly
    	 */
    	Object.defineProperty(Field.prototype, "packed", {
    	    get: function() {
    	        // defaults to packed=true if not explicity set to false
    	        if (this._packed === null)
    	            this._packed = this.getOption("packed") !== false;
    	        return this._packed;
    	    }
    	});

    	/**
    	 * @override
    	 */
    	Field.prototype.setOption = function setOption(name, value, ifNotSet) {
    	    if (name === "packed") // clear cached before setting
    	        this._packed = null;
    	    return ReflectionObject.prototype.setOption.call(this, name, value, ifNotSet);
    	};

    	/**
    	 * Field descriptor.
    	 * @interface IField
    	 * @property {string} [rule="optional"] Field rule
    	 * @property {string} type Field type
    	 * @property {number} id Field id
    	 * @property {Object.<string,*>} [options] Field options
    	 */

    	/**
    	 * Extension field descriptor.
    	 * @interface IExtensionField
    	 * @extends IField
    	 * @property {string} extend Extended type
    	 */

    	/**
    	 * Converts this field to a field descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IField} Field descriptor
    	 */
    	Field.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "rule"    , this.rule !== "optional" && this.rule || undefined,
    	        "type"    , this.type,
    	        "id"      , this.id,
    	        "extend"  , this.extend,
    	        "options" , this.options,
    	        "comment" , keepComments ? this.comment : undefined
    	    ]);
    	};

    	/**
    	 * Resolves this field's type references.
    	 * @returns {Field} `this`
    	 * @throws {Error} If any reference cannot be resolved
    	 */
    	Field.prototype.resolve = function resolve() {

    	    if (this.resolved)
    	        return this;

    	    if ((this.typeDefault = types.defaults[this.type]) === undefined) { // if not a basic type, resolve it
    	        this.resolvedType = (this.declaringField ? this.declaringField.parent : this.parent).lookupTypeOrEnum(this.type);
    	        if (this.resolvedType instanceof Type)
    	            this.typeDefault = null;
    	        else // instanceof Enum
    	            this.typeDefault = this.resolvedType.values[Object.keys(this.resolvedType.values)[0]]; // first defined
    	    } else if (this.options && this.options.proto3_optional) {
    	        // proto3 scalar value marked optional; should default to null
    	        this.typeDefault = null;
    	    }

    	    // use explicitly set default value if present
    	    if (this.options && this.options["default"] != null) {
    	        this.typeDefault = this.options["default"];
    	        if (this.resolvedType instanceof Enum && typeof this.typeDefault === "string")
    	            this.typeDefault = this.resolvedType.values[this.typeDefault];
    	    }

    	    // remove unnecessary options
    	    if (this.options) {
    	        if (this.options.packed === true || this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
    	            delete this.options.packed;
    	        if (!Object.keys(this.options).length)
    	            this.options = undefined;
    	    }

    	    // convert to internal data type if necesssary
    	    if (this.long) {
    	        this.typeDefault = util.Long.fromNumber(this.typeDefault, this.type.charAt(0) === "u");

    	        /* istanbul ignore else */
    	        if (Object.freeze)
    	            Object.freeze(this.typeDefault); // long instances are meant to be immutable anyway (i.e. use small int cache that even requires it)

    	    } else if (this.bytes && typeof this.typeDefault === "string") {
    	        var buf;
    	        if (util.base64.test(this.typeDefault))
    	            util.base64.decode(this.typeDefault, buf = util.newBuffer(util.base64.length(this.typeDefault)), 0);
    	        else
    	            util.utf8.write(this.typeDefault, buf = util.newBuffer(util.utf8.length(this.typeDefault)), 0);
    	        this.typeDefault = buf;
    	    }

    	    // take special care of maps and repeated fields
    	    if (this.map)
    	        this.defaultValue = util.emptyObject;
    	    else if (this.repeated)
    	        this.defaultValue = util.emptyArray;
    	    else
    	        this.defaultValue = this.typeDefault;

    	    // ensure proper value on prototype
    	    if (this.parent instanceof Type)
    	        this.parent.ctor.prototype[this.name] = this.defaultValue;

    	    return ReflectionObject.prototype.resolve.call(this);
    	};

    	/**
    	 * Decorator function as returned by {@link Field.d} and {@link MapField.d} (TypeScript).
    	 * @typedef FieldDecorator
    	 * @type {function}
    	 * @param {Object} prototype Target prototype
    	 * @param {string} fieldName Field name
    	 * @returns {undefined}
    	 */

    	/**
    	 * Field decorator (TypeScript).
    	 * @name Field.d
    	 * @function
    	 * @param {number} fieldId Field id
    	 * @param {"double"|"float"|"int32"|"uint32"|"sint32"|"fixed32"|"sfixed32"|"int64"|"uint64"|"sint64"|"fixed64"|"sfixed64"|"string"|"bool"|"bytes"|Object} fieldType Field type
    	 * @param {"optional"|"required"|"repeated"} [fieldRule="optional"] Field rule
    	 * @param {T} [defaultValue] Default value
    	 * @returns {FieldDecorator} Decorator function
    	 * @template T extends number | number[] | Long | Long[] | string | string[] | boolean | boolean[] | Uint8Array | Uint8Array[] | Buffer | Buffer[]
    	 */
    	Field.d = function decorateField(fieldId, fieldType, fieldRule, defaultValue) {

    	    // submessage: decorate the submessage and use its name as the type
    	    if (typeof fieldType === "function")
    	        fieldType = util.decorateType(fieldType).name;

    	    // enum reference: create a reflected copy of the enum and keep reuseing it
    	    else if (fieldType && typeof fieldType === "object")
    	        fieldType = util.decorateEnum(fieldType).name;

    	    return function fieldDecorator(prototype, fieldName) {
    	        util.decorateType(prototype.constructor)
    	            .add(new Field(fieldName, fieldId, fieldType, fieldRule, { "default": defaultValue }));
    	    };
    	};

    	/**
    	 * Field decorator (TypeScript).
    	 * @name Field.d
    	 * @function
    	 * @param {number} fieldId Field id
    	 * @param {Constructor<T>|string} fieldType Field type
    	 * @param {"optional"|"required"|"repeated"} [fieldRule="optional"] Field rule
    	 * @returns {FieldDecorator} Decorator function
    	 * @template T extends Message<T>
    	 * @variation 2
    	 */
    	// like Field.d but without a default value

    	// Sets up cyclic dependencies (called in index-light)
    	Field._configure = function configure(Type_) {
    	    Type = Type_;
    	};
    	return field;
    }

    var oneof;
    var hasRequiredOneof;

    function requireOneof () {
    	if (hasRequiredOneof) return oneof;
    	hasRequiredOneof = 1;
    	"use strict";
    	oneof = OneOf;

    	// extends ReflectionObject
    	var ReflectionObject = requireObject();
    	((OneOf.prototype = Object.create(ReflectionObject.prototype)).constructor = OneOf).className = "OneOf";

    	var Field = requireField(),
    	    util  = requireUtil();

    	/**
    	 * Constructs a new oneof instance.
    	 * @classdesc Reflected oneof.
    	 * @extends ReflectionObject
    	 * @constructor
    	 * @param {string} name Oneof name
    	 * @param {string[]|Object.<string,*>} [fieldNames] Field names
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @param {string} [comment] Comment associated with this field
    	 */
    	function OneOf(name, fieldNames, options, comment) {
    	    if (!Array.isArray(fieldNames)) {
    	        options = fieldNames;
    	        fieldNames = undefined;
    	    }
    	    ReflectionObject.call(this, name, options);

    	    /* istanbul ignore if */
    	    if (!(fieldNames === undefined || Array.isArray(fieldNames)))
    	        throw TypeError("fieldNames must be an Array");

    	    /**
    	     * Field names that belong to this oneof.
    	     * @type {string[]}
    	     */
    	    this.oneof = fieldNames || []; // toJSON, marker

    	    /**
    	     * Fields that belong to this oneof as an array for iteration.
    	     * @type {Field[]}
    	     * @readonly
    	     */
    	    this.fieldsArray = []; // declared readonly for conformance, possibly not yet added to parent

    	    /**
    	     * Comment for this field.
    	     * @type {string|null}
    	     */
    	    this.comment = comment;
    	}

    	/**
    	 * Oneof descriptor.
    	 * @interface IOneOf
    	 * @property {Array.<string>} oneof Oneof field names
    	 * @property {Object.<string,*>} [options] Oneof options
    	 */

    	/**
    	 * Constructs a oneof from a oneof descriptor.
    	 * @param {string} name Oneof name
    	 * @param {IOneOf} json Oneof descriptor
    	 * @returns {OneOf} Created oneof
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	OneOf.fromJSON = function fromJSON(name, json) {
    	    return new OneOf(name, json.oneof, json.options, json.comment);
    	};

    	/**
    	 * Converts this oneof to a oneof descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IOneOf} Oneof descriptor
    	 */
    	OneOf.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "options" , this.options,
    	        "oneof"   , this.oneof,
    	        "comment" , keepComments ? this.comment : undefined
    	    ]);
    	};

    	/**
    	 * Adds the fields of the specified oneof to the parent if not already done so.
    	 * @param {OneOf} oneof The oneof
    	 * @returns {undefined}
    	 * @inner
    	 * @ignore
    	 */
    	function addFieldsToParent(oneof) {
    	    if (oneof.parent)
    	        for (var i = 0; i < oneof.fieldsArray.length; ++i)
    	            if (!oneof.fieldsArray[i].parent)
    	                oneof.parent.add(oneof.fieldsArray[i]);
    	}

    	/**
    	 * Adds a field to this oneof and removes it from its current parent, if any.
    	 * @param {Field} field Field to add
    	 * @returns {OneOf} `this`
    	 */
    	OneOf.prototype.add = function add(field) {

    	    /* istanbul ignore if */
    	    if (!(field instanceof Field))
    	        throw TypeError("field must be a Field");

    	    if (field.parent && field.parent !== this.parent)
    	        field.parent.remove(field);
    	    this.oneof.push(field.name);
    	    this.fieldsArray.push(field);
    	    field.partOf = this; // field.parent remains null
    	    addFieldsToParent(this);
    	    return this;
    	};

    	/**
    	 * Removes a field from this oneof and puts it back to the oneof's parent.
    	 * @param {Field} field Field to remove
    	 * @returns {OneOf} `this`
    	 */
    	OneOf.prototype.remove = function remove(field) {

    	    /* istanbul ignore if */
    	    if (!(field instanceof Field))
    	        throw TypeError("field must be a Field");

    	    var index = this.fieldsArray.indexOf(field);

    	    /* istanbul ignore if */
    	    if (index < 0)
    	        throw Error(field + " is not a member of " + this);

    	    this.fieldsArray.splice(index, 1);
    	    index = this.oneof.indexOf(field.name);

    	    /* istanbul ignore else */
    	    if (index > -1) // theoretical
    	        this.oneof.splice(index, 1);

    	    field.partOf = null;
    	    return this;
    	};

    	/**
    	 * @override
    	 */
    	OneOf.prototype.onAdd = function onAdd(parent) {
    	    ReflectionObject.prototype.onAdd.call(this, parent);
    	    var self = this;
    	    // Collect present fields
    	    for (var i = 0; i < this.oneof.length; ++i) {
    	        var field = parent.get(this.oneof[i]);
    	        if (field && !field.partOf) {
    	            field.partOf = self;
    	            self.fieldsArray.push(field);
    	        }
    	    }
    	    // Add not yet present fields
    	    addFieldsToParent(this);
    	};

    	/**
    	 * @override
    	 */
    	OneOf.prototype.onRemove = function onRemove(parent) {
    	    for (var i = 0, field; i < this.fieldsArray.length; ++i)
    	        if ((field = this.fieldsArray[i]).parent)
    	            field.parent.remove(field);
    	    ReflectionObject.prototype.onRemove.call(this, parent);
    	};

    	/**
    	 * Decorator function as returned by {@link OneOf.d} (TypeScript).
    	 * @typedef OneOfDecorator
    	 * @type {function}
    	 * @param {Object} prototype Target prototype
    	 * @param {string} oneofName OneOf name
    	 * @returns {undefined}
    	 */

    	/**
    	 * OneOf decorator (TypeScript).
    	 * @function
    	 * @param {...string} fieldNames Field names
    	 * @returns {OneOfDecorator} Decorator function
    	 * @template T extends string
    	 */
    	OneOf.d = function decorateOneOf() {
    	    var fieldNames = new Array(arguments.length),
    	        index = 0;
    	    while (index < arguments.length)
    	        fieldNames[index] = arguments[index++];
    	    return function oneOfDecorator(prototype, oneofName) {
    	        util.decorateType(prototype.constructor)
    	            .add(new OneOf(oneofName, fieldNames));
    	        Object.defineProperty(prototype, oneofName, {
    	            get: util.oneOfGetter(fieldNames),
    	            set: util.oneOfSetter(fieldNames)
    	        });
    	    };
    	};
    	return oneof;
    }

    var namespace;
    var hasRequiredNamespace;

    function requireNamespace () {
    	if (hasRequiredNamespace) return namespace;
    	hasRequiredNamespace = 1;
    	"use strict";
    	namespace = Namespace;

    	// extends ReflectionObject
    	var ReflectionObject = requireObject();
    	((Namespace.prototype = Object.create(ReflectionObject.prototype)).constructor = Namespace).className = "Namespace";

    	var Field    = requireField(),
    	    util     = requireUtil(),
    	    OneOf    = requireOneof();

    	var Type,    // cyclic
    	    Service,
    	    Enum;

    	/**
    	 * Constructs a new namespace instance.
    	 * @name Namespace
    	 * @classdesc Reflected namespace.
    	 * @extends NamespaceBase
    	 * @constructor
    	 * @param {string} name Namespace name
    	 * @param {Object.<string,*>} [options] Declared options
    	 */

    	/**
    	 * Constructs a namespace from JSON.
    	 * @memberof Namespace
    	 * @function
    	 * @param {string} name Namespace name
    	 * @param {Object.<string,*>} json JSON object
    	 * @returns {Namespace} Created namespace
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	Namespace.fromJSON = function fromJSON(name, json) {
    	    return new Namespace(name, json.options).addJSON(json.nested);
    	};

    	/**
    	 * Converts an array of reflection objects to JSON.
    	 * @memberof Namespace
    	 * @param {ReflectionObject[]} array Object array
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {Object.<string,*>|undefined} JSON object or `undefined` when array is empty
    	 */
    	function arrayToJSON(array, toJSONOptions) {
    	    if (!(array && array.length))
    	        return undefined;
    	    var obj = {};
    	    for (var i = 0; i < array.length; ++i)
    	        obj[array[i].name] = array[i].toJSON(toJSONOptions);
    	    return obj;
    	}

    	Namespace.arrayToJSON = arrayToJSON;

    	/**
    	 * Tests if the specified id is reserved.
    	 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
    	 * @param {number} id Id to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Namespace.isReservedId = function isReservedId(reserved, id) {
    	    if (reserved)
    	        for (var i = 0; i < reserved.length; ++i)
    	            if (typeof reserved[i] !== "string" && reserved[i][0] <= id && reserved[i][1] > id)
    	                return true;
    	    return false;
    	};

    	/**
    	 * Tests if the specified name is reserved.
    	 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names
    	 * @param {string} name Name to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Namespace.isReservedName = function isReservedName(reserved, name) {
    	    if (reserved)
    	        for (var i = 0; i < reserved.length; ++i)
    	            if (reserved[i] === name)
    	                return true;
    	    return false;
    	};

    	/**
    	 * Not an actual constructor. Use {@link Namespace} instead.
    	 * @classdesc Base class of all reflection objects containing nested objects. This is not an actual class but here for the sake of having consistent type definitions.
    	 * @exports NamespaceBase
    	 * @extends ReflectionObject
    	 * @abstract
    	 * @constructor
    	 * @param {string} name Namespace name
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @see {@link Namespace}
    	 */
    	function Namespace(name, options) {
    	    ReflectionObject.call(this, name, options);

    	    /**
    	     * Nested objects by name.
    	     * @type {Object.<string,ReflectionObject>|undefined}
    	     */
    	    this.nested = undefined; // toJSON

    	    /**
    	     * Cached nested objects as an array.
    	     * @type {ReflectionObject[]|null}
    	     * @private
    	     */
    	    this._nestedArray = null;
    	}

    	function clearCache(namespace) {
    	    namespace._nestedArray = null;
    	    return namespace;
    	}

    	/**
    	 * Nested objects of this namespace as an array for iteration.
    	 * @name NamespaceBase#nestedArray
    	 * @type {ReflectionObject[]}
    	 * @readonly
    	 */
    	Object.defineProperty(Namespace.prototype, "nestedArray", {
    	    get: function() {
    	        return this._nestedArray || (this._nestedArray = util.toArray(this.nested));
    	    }
    	});

    	/**
    	 * Namespace descriptor.
    	 * @interface INamespace
    	 * @property {Object.<string,*>} [options] Namespace options
    	 * @property {Object.<string,AnyNestedObject>} [nested] Nested object descriptors
    	 */

    	/**
    	 * Any extension field descriptor.
    	 * @typedef AnyExtensionField
    	 * @type {IExtensionField|IExtensionMapField}
    	 */

    	/**
    	 * Any nested object descriptor.
    	 * @typedef AnyNestedObject
    	 * @type {IEnum|IType|IService|AnyExtensionField|INamespace|IOneOf}
    	 */

    	/**
    	 * Converts this namespace to a namespace descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {INamespace} Namespace descriptor
    	 */
    	Namespace.prototype.toJSON = function toJSON(toJSONOptions) {
    	    return util.toObject([
    	        "options" , this.options,
    	        "nested"  , arrayToJSON(this.nestedArray, toJSONOptions)
    	    ]);
    	};

    	/**
    	 * Adds nested objects to this namespace from nested object descriptors.
    	 * @param {Object.<string,AnyNestedObject>} nestedJson Any nested object descriptors
    	 * @returns {Namespace} `this`
    	 */
    	Namespace.prototype.addJSON = function addJSON(nestedJson) {
    	    var ns = this;
    	    /* istanbul ignore else */
    	    if (nestedJson) {
    	        for (var names = Object.keys(nestedJson), i = 0, nested; i < names.length; ++i) {
    	            nested = nestedJson[names[i]];
    	            ns.add( // most to least likely
    	                ( nested.fields !== undefined
    	                ? Type.fromJSON
    	                : nested.values !== undefined
    	                ? Enum.fromJSON
    	                : nested.methods !== undefined
    	                ? Service.fromJSON
    	                : nested.id !== undefined
    	                ? Field.fromJSON
    	                : Namespace.fromJSON )(names[i], nested)
    	            );
    	        }
    	    }
    	    return this;
    	};

    	/**
    	 * Gets the nested object of the specified name.
    	 * @param {string} name Nested object name
    	 * @returns {ReflectionObject|null} The reflection object or `null` if it doesn't exist
    	 */
    	Namespace.prototype.get = function get(name) {
    	    return this.nested && this.nested[name]
    	        || null;
    	};

    	/**
    	 * Gets the values of the nested {@link Enum|enum} of the specified name.
    	 * This methods differs from {@link Namespace#get|get} in that it returns an enum's values directly and throws instead of returning `null`.
    	 * @param {string} name Nested enum name
    	 * @returns {Object.<string,number>} Enum values
    	 * @throws {Error} If there is no such enum
    	 */
    	Namespace.prototype.getEnum = function getEnum(name) {
    	    if (this.nested && this.nested[name] instanceof Enum)
    	        return this.nested[name].values;
    	    throw Error("no such enum: " + name);
    	};

    	/**
    	 * Adds a nested object to this namespace.
    	 * @param {ReflectionObject} object Nested object to add
    	 * @returns {Namespace} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If there is already a nested object with this name
    	 */
    	Namespace.prototype.add = function add(object) {

    	    if (!(object instanceof Field && object.extend !== undefined || object instanceof Type  || object instanceof OneOf || object instanceof Enum || object instanceof Service || object instanceof Namespace))
    	        throw TypeError("object must be a valid nested object");

    	    if (!this.nested)
    	        this.nested = {};
    	    else {
    	        var prev = this.get(object.name);
    	        if (prev) {
    	            if (prev instanceof Namespace && object instanceof Namespace && !(prev instanceof Type || prev instanceof Service)) {
    	                // replace plain namespace but keep existing nested elements and options
    	                var nested = prev.nestedArray;
    	                for (var i = 0; i < nested.length; ++i)
    	                    object.add(nested[i]);
    	                this.remove(prev);
    	                if (!this.nested)
    	                    this.nested = {};
    	                object.setOptions(prev.options, true);

    	            } else
    	                throw Error("duplicate name '" + object.name + "' in " + this);
    	        }
    	    }
    	    this.nested[object.name] = object;
    	    object.onAdd(this);
    	    return clearCache(this);
    	};

    	/**
    	 * Removes a nested object from this namespace.
    	 * @param {ReflectionObject} object Nested object to remove
    	 * @returns {Namespace} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If `object` is not a member of this namespace
    	 */
    	Namespace.prototype.remove = function remove(object) {

    	    if (!(object instanceof ReflectionObject))
    	        throw TypeError("object must be a ReflectionObject");
    	    if (object.parent !== this)
    	        throw Error(object + " is not a member of " + this);

    	    delete this.nested[object.name];
    	    if (!Object.keys(this.nested).length)
    	        this.nested = undefined;

    	    object.onRemove(this);
    	    return clearCache(this);
    	};

    	/**
    	 * Defines additial namespaces within this one if not yet existing.
    	 * @param {string|string[]} path Path to create
    	 * @param {*} [json] Nested types to create from JSON
    	 * @returns {Namespace} Pointer to the last namespace created or `this` if path is empty
    	 */
    	Namespace.prototype.define = function define(path, json) {

    	    if (util.isString(path))
    	        path = path.split(".");
    	    else if (!Array.isArray(path))
    	        throw TypeError("illegal path");
    	    if (path && path.length && path[0] === "")
    	        throw Error("path must be relative");

    	    var ptr = this;
    	    while (path.length > 0) {
    	        var part = path.shift();
    	        if (ptr.nested && ptr.nested[part]) {
    	            ptr = ptr.nested[part];
    	            if (!(ptr instanceof Namespace))
    	                throw Error("path conflicts with non-namespace objects");
    	        } else
    	            ptr.add(ptr = new Namespace(part));
    	    }
    	    if (json)
    	        ptr.addJSON(json);
    	    return ptr;
    	};

    	/**
    	 * Resolves this namespace's and all its nested objects' type references. Useful to validate a reflection tree, but comes at a cost.
    	 * @returns {Namespace} `this`
    	 */
    	Namespace.prototype.resolveAll = function resolveAll() {
    	    var nested = this.nestedArray, i = 0;
    	    while (i < nested.length)
    	        if (nested[i] instanceof Namespace)
    	            nested[i++].resolveAll();
    	        else
    	            nested[i++].resolve();
    	    return this.resolve();
    	};

    	/**
    	 * Recursively looks up the reflection object matching the specified path in the scope of this namespace.
    	 * @param {string|string[]} path Path to look up
    	 * @param {*|Array.<*>} filterTypes Filter types, any combination of the constructors of `protobuf.Type`, `protobuf.Enum`, `protobuf.Service` etc.
    	 * @param {boolean} [parentAlreadyChecked=false] If known, whether the parent has already been checked
    	 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found
    	 */
    	Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChecked) {

    	    /* istanbul ignore next */
    	    if (typeof filterTypes === "boolean") {
    	        parentAlreadyChecked = filterTypes;
    	        filterTypes = undefined;
    	    } else if (filterTypes && !Array.isArray(filterTypes))
    	        filterTypes = [ filterTypes ];

    	    if (util.isString(path) && path.length) {
    	        if (path === ".")
    	            return this.root;
    	        path = path.split(".");
    	    } else if (!path.length)
    	        return this;

    	    // Start at root if path is absolute
    	    if (path[0] === "")
    	        return this.root.lookup(path.slice(1), filterTypes);

    	    // Test if the first part matches any nested object, and if so, traverse if path contains more
    	    var found = this.get(path[0]);
    	    if (found) {
    	        if (path.length === 1) {
    	            if (!filterTypes || filterTypes.indexOf(found.constructor) > -1)
    	                return found;
    	        } else if (found instanceof Namespace && (found = found.lookup(path.slice(1), filterTypes, true)))
    	            return found;

    	    // Otherwise try each nested namespace
    	    } else
    	        for (var i = 0; i < this.nestedArray.length; ++i)
    	            if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i].lookup(path, filterTypes, true)))
    	                return found;

    	    // If there hasn't been a match, try again at the parent
    	    if (this.parent === null || parentAlreadyChecked)
    	        return null;
    	    return this.parent.lookup(path, filterTypes);
    	};

    	/**
    	 * Looks up the reflection object at the specified path, relative to this namespace.
    	 * @name NamespaceBase#lookup
    	 * @function
    	 * @param {string|string[]} path Path to look up
    	 * @param {boolean} [parentAlreadyChecked=false] Whether the parent has already been checked
    	 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found
    	 * @variation 2
    	 */
    	// lookup(path: string, [parentAlreadyChecked: boolean])

    	/**
    	 * Looks up the {@link Type|type} at the specified path, relative to this namespace.
    	 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.
    	 * @param {string|string[]} path Path to look up
    	 * @returns {Type} Looked up type
    	 * @throws {Error} If `path` does not point to a type
    	 */
    	Namespace.prototype.lookupType = function lookupType(path) {
    	    var found = this.lookup(path, [ Type ]);
    	    if (!found)
    	        throw Error("no such type: " + path);
    	    return found;
    	};

    	/**
    	 * Looks up the values of the {@link Enum|enum} at the specified path, relative to this namespace.
    	 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.
    	 * @param {string|string[]} path Path to look up
    	 * @returns {Enum} Looked up enum
    	 * @throws {Error} If `path` does not point to an enum
    	 */
    	Namespace.prototype.lookupEnum = function lookupEnum(path) {
    	    var found = this.lookup(path, [ Enum ]);
    	    if (!found)
    	        throw Error("no such Enum '" + path + "' in " + this);
    	    return found;
    	};

    	/**
    	 * Looks up the {@link Type|type} or {@link Enum|enum} at the specified path, relative to this namespace.
    	 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.
    	 * @param {string|string[]} path Path to look up
    	 * @returns {Type} Looked up type or enum
    	 * @throws {Error} If `path` does not point to a type or enum
    	 */
    	Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path) {
    	    var found = this.lookup(path, [ Type, Enum ]);
    	    if (!found)
    	        throw Error("no such Type or Enum '" + path + "' in " + this);
    	    return found;
    	};

    	/**
    	 * Looks up the {@link Service|service} at the specified path, relative to this namespace.
    	 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.
    	 * @param {string|string[]} path Path to look up
    	 * @returns {Service} Looked up service
    	 * @throws {Error} If `path` does not point to a service
    	 */
    	Namespace.prototype.lookupService = function lookupService(path) {
    	    var found = this.lookup(path, [ Service ]);
    	    if (!found)
    	        throw Error("no such Service '" + path + "' in " + this);
    	    return found;
    	};

    	// Sets up cyclic dependencies (called in index-light)
    	Namespace._configure = function(Type_, Service_, Enum_) {
    	    Type    = Type_;
    	    Service = Service_;
    	    Enum    = Enum_;
    	};
    	return namespace;
    }

    var mapfield;
    var hasRequiredMapfield;

    function requireMapfield () {
    	if (hasRequiredMapfield) return mapfield;
    	hasRequiredMapfield = 1;
    	"use strict";
    	mapfield = MapField;

    	// extends Field
    	var Field = requireField();
    	((MapField.prototype = Object.create(Field.prototype)).constructor = MapField).className = "MapField";

    	var types   = requireTypes(),
    	    util    = requireUtil();

    	/**
    	 * Constructs a new map field instance.
    	 * @classdesc Reflected map field.
    	 * @extends FieldBase
    	 * @constructor
    	 * @param {string} name Unique name within its namespace
    	 * @param {number} id Unique id within its namespace
    	 * @param {string} keyType Key type
    	 * @param {string} type Value type
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @param {string} [comment] Comment associated with this field
    	 */
    	function MapField(name, id, keyType, type, options, comment) {
    	    Field.call(this, name, id, type, undefined, undefined, options, comment);

    	    /* istanbul ignore if */
    	    if (!util.isString(keyType))
    	        throw TypeError("keyType must be a string");

    	    /**
    	     * Key type.
    	     * @type {string}
    	     */
    	    this.keyType = keyType; // toJSON, marker

    	    /**
    	     * Resolved key type if not a basic type.
    	     * @type {ReflectionObject|null}
    	     */
    	    this.resolvedKeyType = null;

    	    // Overrides Field#map
    	    this.map = true;
    	}

    	/**
    	 * Map field descriptor.
    	 * @interface IMapField
    	 * @extends {IField}
    	 * @property {string} keyType Key type
    	 */

    	/**
    	 * Extension map field descriptor.
    	 * @interface IExtensionMapField
    	 * @extends IMapField
    	 * @property {string} extend Extended type
    	 */

    	/**
    	 * Constructs a map field from a map field descriptor.
    	 * @param {string} name Field name
    	 * @param {IMapField} json Map field descriptor
    	 * @returns {MapField} Created map field
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	MapField.fromJSON = function fromJSON(name, json) {
    	    return new MapField(name, json.id, json.keyType, json.type, json.options, json.comment);
    	};

    	/**
    	 * Converts this map field to a map field descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IMapField} Map field descriptor
    	 */
    	MapField.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "keyType" , this.keyType,
    	        "type"    , this.type,
    	        "id"      , this.id,
    	        "extend"  , this.extend,
    	        "options" , this.options,
    	        "comment" , keepComments ? this.comment : undefined
    	    ]);
    	};

    	/**
    	 * @override
    	 */
    	MapField.prototype.resolve = function resolve() {
    	    if (this.resolved)
    	        return this;

    	    // Besides a value type, map fields have a key type that may be "any scalar type except for floating point types and bytes"
    	    if (types.mapKey[this.keyType] === undefined)
    	        throw Error("invalid key type: " + this.keyType);

    	    return Field.prototype.resolve.call(this);
    	};

    	/**
    	 * Map field decorator (TypeScript).
    	 * @name MapField.d
    	 * @function
    	 * @param {number} fieldId Field id
    	 * @param {"int32"|"uint32"|"sint32"|"fixed32"|"sfixed32"|"int64"|"uint64"|"sint64"|"fixed64"|"sfixed64"|"bool"|"string"} fieldKeyType Field key type
    	 * @param {"double"|"float"|"int32"|"uint32"|"sint32"|"fixed32"|"sfixed32"|"int64"|"uint64"|"sint64"|"fixed64"|"sfixed64"|"bool"|"string"|"bytes"|Object|Constructor<{}>} fieldValueType Field value type
    	 * @returns {FieldDecorator} Decorator function
    	 * @template T extends { [key: string]: number | Long | string | boolean | Uint8Array | Buffer | number[] | Message<{}> }
    	 */
    	MapField.d = function decorateMapField(fieldId, fieldKeyType, fieldValueType) {

    	    // submessage value: decorate the submessage and use its name as the type
    	    if (typeof fieldValueType === "function")
    	        fieldValueType = util.decorateType(fieldValueType).name;

    	    // enum reference value: create a reflected copy of the enum and keep reuseing it
    	    else if (fieldValueType && typeof fieldValueType === "object")
    	        fieldValueType = util.decorateEnum(fieldValueType).name;

    	    return function mapFieldDecorator(prototype, fieldName) {
    	        util.decorateType(prototype.constructor)
    	            .add(new MapField(fieldName, fieldId, fieldKeyType, fieldValueType));
    	    };
    	};
    	return mapfield;
    }

    var method;
    var hasRequiredMethod;

    function requireMethod () {
    	if (hasRequiredMethod) return method;
    	hasRequiredMethod = 1;
    	"use strict";
    	method = Method;

    	// extends ReflectionObject
    	var ReflectionObject = requireObject();
    	((Method.prototype = Object.create(ReflectionObject.prototype)).constructor = Method).className = "Method";

    	var util = requireUtil();

    	/**
    	 * Constructs a new service method instance.
    	 * @classdesc Reflected service method.
    	 * @extends ReflectionObject
    	 * @constructor
    	 * @param {string} name Method name
    	 * @param {string|undefined} type Method type, usually `"rpc"`
    	 * @param {string} requestType Request message type
    	 * @param {string} responseType Response message type
    	 * @param {boolean|Object.<string,*>} [requestStream] Whether the request is streamed
    	 * @param {boolean|Object.<string,*>} [responseStream] Whether the response is streamed
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @param {string} [comment] The comment for this method
    	 * @param {Object.<string,*>} [parsedOptions] Declared options, properly parsed into an object
    	 */
    	function Method(name, type, requestType, responseType, requestStream, responseStream, options, comment, parsedOptions) {

    	    /* istanbul ignore next */
    	    if (util.isObject(requestStream)) {
    	        options = requestStream;
    	        requestStream = responseStream = undefined;
    	    } else if (util.isObject(responseStream)) {
    	        options = responseStream;
    	        responseStream = undefined;
    	    }

    	    /* istanbul ignore if */
    	    if (!(type === undefined || util.isString(type)))
    	        throw TypeError("type must be a string");

    	    /* istanbul ignore if */
    	    if (!util.isString(requestType))
    	        throw TypeError("requestType must be a string");

    	    /* istanbul ignore if */
    	    if (!util.isString(responseType))
    	        throw TypeError("responseType must be a string");

    	    ReflectionObject.call(this, name, options);

    	    /**
    	     * Method type.
    	     * @type {string}
    	     */
    	    this.type = type || "rpc"; // toJSON

    	    /**
    	     * Request type.
    	     * @type {string}
    	     */
    	    this.requestType = requestType; // toJSON, marker

    	    /**
    	     * Whether requests are streamed or not.
    	     * @type {boolean|undefined}
    	     */
    	    this.requestStream = requestStream ? true : undefined; // toJSON

    	    /**
    	     * Response type.
    	     * @type {string}
    	     */
    	    this.responseType = responseType; // toJSON

    	    /**
    	     * Whether responses are streamed or not.
    	     * @type {boolean|undefined}
    	     */
    	    this.responseStream = responseStream ? true : undefined; // toJSON

    	    /**
    	     * Resolved request type.
    	     * @type {Type|null}
    	     */
    	    this.resolvedRequestType = null;

    	    /**
    	     * Resolved response type.
    	     * @type {Type|null}
    	     */
    	    this.resolvedResponseType = null;

    	    /**
    	     * Comment for this method
    	     * @type {string|null}
    	     */
    	    this.comment = comment;

    	    /**
    	     * Options properly parsed into an object
    	     */
    	    this.parsedOptions = parsedOptions;
    	}

    	/**
    	 * Method descriptor.
    	 * @interface IMethod
    	 * @property {string} [type="rpc"] Method type
    	 * @property {string} requestType Request type
    	 * @property {string} responseType Response type
    	 * @property {boolean} [requestStream=false] Whether requests are streamed
    	 * @property {boolean} [responseStream=false] Whether responses are streamed
    	 * @property {Object.<string,*>} [options] Method options
    	 * @property {string} comment Method comments
    	 * @property {Object.<string,*>} [parsedOptions] Method options properly parsed into an object
    	 */

    	/**
    	 * Constructs a method from a method descriptor.
    	 * @param {string} name Method name
    	 * @param {IMethod} json Method descriptor
    	 * @returns {Method} Created method
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	Method.fromJSON = function fromJSON(name, json) {
    	    return new Method(name, json.type, json.requestType, json.responseType, json.requestStream, json.responseStream, json.options, json.comment, json.parsedOptions);
    	};

    	/**
    	 * Converts this method to a method descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IMethod} Method descriptor
    	 */
    	Method.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "type"           , this.type !== "rpc" && /* istanbul ignore next */ this.type || undefined,
    	        "requestType"    , this.requestType,
    	        "requestStream"  , this.requestStream,
    	        "responseType"   , this.responseType,
    	        "responseStream" , this.responseStream,
    	        "options"        , this.options,
    	        "comment"        , keepComments ? this.comment : undefined,
    	        "parsedOptions"  , this.parsedOptions,
    	    ]);
    	};

    	/**
    	 * @override
    	 */
    	Method.prototype.resolve = function resolve() {

    	    /* istanbul ignore if */
    	    if (this.resolved)
    	        return this;

    	    this.resolvedRequestType = this.parent.lookupType(this.requestType);
    	    this.resolvedResponseType = this.parent.lookupType(this.responseType);

    	    return ReflectionObject.prototype.resolve.call(this);
    	};
    	return method;
    }

    var service;
    var hasRequiredService;

    function requireService () {
    	if (hasRequiredService) return service;
    	hasRequiredService = 1;
    	"use strict";
    	service = Service;

    	// extends Namespace
    	var Namespace = requireNamespace();
    	((Service.prototype = Object.create(Namespace.prototype)).constructor = Service).className = "Service";

    	var Method = requireMethod(),
    	    util   = requireUtil(),
    	    rpc    = rpc$1;

    	/**
    	 * Constructs a new service instance.
    	 * @classdesc Reflected service.
    	 * @extends NamespaceBase
    	 * @constructor
    	 * @param {string} name Service name
    	 * @param {Object.<string,*>} [options] Service options
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	function Service(name, options) {
    	    Namespace.call(this, name, options);

    	    /**
    	     * Service methods.
    	     * @type {Object.<string,Method>}
    	     */
    	    this.methods = {}; // toJSON, marker

    	    /**
    	     * Cached methods as an array.
    	     * @type {Method[]|null}
    	     * @private
    	     */
    	    this._methodsArray = null;
    	}

    	/**
    	 * Service descriptor.
    	 * @interface IService
    	 * @extends INamespace
    	 * @property {Object.<string,IMethod>} methods Method descriptors
    	 */

    	/**
    	 * Constructs a service from a service descriptor.
    	 * @param {string} name Service name
    	 * @param {IService} json Service descriptor
    	 * @returns {Service} Created service
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	Service.fromJSON = function fromJSON(name, json) {
    	    var service = new Service(name, json.options);
    	    /* istanbul ignore else */
    	    if (json.methods)
    	        for (var names = Object.keys(json.methods), i = 0; i < names.length; ++i)
    	            service.add(Method.fromJSON(names[i], json.methods[names[i]]));
    	    if (json.nested)
    	        service.addJSON(json.nested);
    	    service.comment = json.comment;
    	    return service;
    	};

    	/**
    	 * Converts this service to a service descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IService} Service descriptor
    	 */
    	Service.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "options" , inherited && inherited.options || undefined,
    	        "methods" , Namespace.arrayToJSON(this.methodsArray, toJSONOptions) || /* istanbul ignore next */ {},
    	        "nested"  , inherited && inherited.nested || undefined,
    	        "comment" , keepComments ? this.comment : undefined
    	    ]);
    	};

    	/**
    	 * Methods of this service as an array for iteration.
    	 * @name Service#methodsArray
    	 * @type {Method[]}
    	 * @readonly
    	 */
    	Object.defineProperty(Service.prototype, "methodsArray", {
    	    get: function() {
    	        return this._methodsArray || (this._methodsArray = util.toArray(this.methods));
    	    }
    	});

    	function clearCache(service) {
    	    service._methodsArray = null;
    	    return service;
    	}

    	/**
    	 * @override
    	 */
    	Service.prototype.get = function get(name) {
    	    return this.methods[name]
    	        || Namespace.prototype.get.call(this, name);
    	};

    	/**
    	 * @override
    	 */
    	Service.prototype.resolveAll = function resolveAll() {
    	    var methods = this.methodsArray;
    	    for (var i = 0; i < methods.length; ++i)
    	        methods[i].resolve();
    	    return Namespace.prototype.resolve.call(this);
    	};

    	/**
    	 * @override
    	 */
    	Service.prototype.add = function add(object) {

    	    /* istanbul ignore if */
    	    if (this.get(object.name))
    	        throw Error("duplicate name '" + object.name + "' in " + this);

    	    if (object instanceof Method) {
    	        this.methods[object.name] = object;
    	        object.parent = this;
    	        return clearCache(this);
    	    }
    	    return Namespace.prototype.add.call(this, object);
    	};

    	/**
    	 * @override
    	 */
    	Service.prototype.remove = function remove(object) {
    	    if (object instanceof Method) {

    	        /* istanbul ignore if */
    	        if (this.methods[object.name] !== object)
    	            throw Error(object + " is not a member of " + this);

    	        delete this.methods[object.name];
    	        object.parent = null;
    	        return clearCache(this);
    	    }
    	    return Namespace.prototype.remove.call(this, object);
    	};

    	/**
    	 * Creates a runtime service using the specified rpc implementation.
    	 * @param {RPCImpl} rpcImpl RPC implementation
    	 * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
    	 * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
    	 * @returns {rpc.Service} RPC service. Useful where requests and/or responses are streamed.
    	 */
    	Service.prototype.create = function create(rpcImpl, requestDelimited, responseDelimited) {
    	    var rpcService = new rpc.Service(rpcImpl, requestDelimited, responseDelimited);
    	    for (var i = 0, method; i < /* initializes */ this.methodsArray.length; ++i) {
    	        var methodName = util.lcFirst((method = this._methodsArray[i]).resolve().name).replace(/[^$\w_]/g, "");
    	        rpcService[methodName] = util.codegen(["r","c"], util.isReserved(methodName) ? methodName + "_" : methodName)("return this.rpcCall(m,q,s,r,c)")({
    	            m: method,
    	            q: method.resolvedRequestType.ctor,
    	            s: method.resolvedResponseType.ctor
    	        });
    	    }
    	    return rpcService;
    	};
    	return service;
    }

    "use strict";
    var message$1 = Message;

    var util$1 = requireMinimal();

    /**
     * Constructs a new message instance.
     * @classdesc Abstract runtime message.
     * @constructor
     * @param {Properties<T>} [properties] Properties to set
     * @template T extends object = object
     */
    function Message(properties) {
        // not used internally
        if (properties)
            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                this[keys[i]] = properties[keys[i]];
    }

    /**
     * Reference to the reflected type.
     * @name Message.$type
     * @type {Type}
     * @readonly
     */

    /**
     * Reference to the reflected type.
     * @name Message#$type
     * @type {Type}
     * @readonly
     */

    /*eslint-disable valid-jsdoc*/

    /**
     * Creates a new message of this type using the specified properties.
     * @param {Object.<string,*>} [properties] Properties to set
     * @returns {Message<T>} Message instance
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.create = function create(properties) {
        return this.$type.create(properties);
    };

    /**
     * Encodes a message of this type.
     * @param {T|Object.<string,*>} message Message to encode
     * @param {Writer} [writer] Writer to use
     * @returns {Writer} Writer
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.encode = function encode(message, writer) {
        return this.$type.encode(message, writer);
    };

    /**
     * Encodes a message of this type preceeded by its length as a varint.
     * @param {T|Object.<string,*>} message Message to encode
     * @param {Writer} [writer] Writer to use
     * @returns {Writer} Writer
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.encodeDelimited = function encodeDelimited(message, writer) {
        return this.$type.encodeDelimited(message, writer);
    };

    /**
     * Decodes a message of this type.
     * @name Message.decode
     * @function
     * @param {Reader|Uint8Array} reader Reader or buffer to decode
     * @returns {T} Decoded message
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.decode = function decode(reader) {
        return this.$type.decode(reader);
    };

    /**
     * Decodes a message of this type preceeded by its length as a varint.
     * @name Message.decodeDelimited
     * @function
     * @param {Reader|Uint8Array} reader Reader or buffer to decode
     * @returns {T} Decoded message
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.decodeDelimited = function decodeDelimited(reader) {
        return this.$type.decodeDelimited(reader);
    };

    /**
     * Verifies a message of this type.
     * @name Message.verify
     * @function
     * @param {Object.<string,*>} message Plain object to verify
     * @returns {string|null} `null` if valid, otherwise the reason why it is not
     */
    Message.verify = function verify(message) {
        return this.$type.verify(message);
    };

    /**
     * Creates a new message of this type from a plain object. Also converts values to their respective internal types.
     * @param {Object.<string,*>} object Plain object
     * @returns {T} Message instance
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.fromObject = function fromObject(object) {
        return this.$type.fromObject(object);
    };

    /**
     * Creates a plain object from a message of this type. Also converts values to other types if specified.
     * @param {T} message Message instance
     * @param {IConversionOptions} [options] Conversion options
     * @returns {Object.<string,*>} Plain object
     * @template T extends Message<T>
     * @this Constructor<T>
     */
    Message.toObject = function toObject(message, options) {
        return this.$type.toObject(message, options);
    };

    /**
     * Converts this message to JSON.
     * @returns {Object.<string,*>} JSON object
     */
    Message.prototype.toJSON = function toJSON() {
        return this.$type.toObject(this, util$1.toJSONOptions);
    };

    /*eslint-enable valid-jsdoc*/

    const message$2 = /*@__PURE__*/getDefaultExportFromCjs(message$1);

    var decoder_1;
    var hasRequiredDecoder;

    function requireDecoder () {
    	if (hasRequiredDecoder) return decoder_1;
    	hasRequiredDecoder = 1;
    	"use strict";
    	decoder_1 = decoder;

    	var Enum    = require_enum(),
    	    types   = requireTypes(),
    	    util    = requireUtil();

    	function missing(field) {
    	    return "missing required '" + field.name + "'";
    	}

    	/**
    	 * Generates a decoder specific to the specified message type.
    	 * @param {Type} mtype Message type
    	 * @returns {Codegen} Codegen instance
    	 */
    	function decoder(mtype) {
    	    /* eslint-disable no-unexpected-multiline */
    	    var gen = util.codegen(["r", "l"], mtype.name + "$decode")
    	    ("if(!(r instanceof Reader))")
    	        ("r=Reader.create(r)")
    	    ("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k,value" : ""))
    	    ("while(r.pos<c){")
    	        ("var t=r.uint32()");
    	    if (mtype.group) gen
    	        ("if((t&7)===4)")
    	            ("break");
    	    gen
    	        ("switch(t>>>3){");

    	    var i = 0;
    	    for (; i < /* initializes */ mtype.fieldsArray.length; ++i) {
    	        var field = mtype._fieldsArray[i].resolve(),
    	            type  = field.resolvedType instanceof Enum ? "int32" : field.type,
    	            ref   = "m" + util.safeProp(field.name); gen
    	            ("case %i: {", field.id);

    	        // Map fields
    	        if (field.map) { gen
    	                ("if(%s===util.emptyObject)", ref)
    	                    ("%s={}", ref)
    	                ("var c2 = r.uint32()+r.pos");

    	            if (types.defaults[field.keyType] !== undefined) gen
    	                ("k=%j", types.defaults[field.keyType]);
    	            else gen
    	                ("k=null");

    	            if (types.defaults[type] !== undefined) gen
    	                ("value=%j", types.defaults[type]);
    	            else gen
    	                ("value=null");

    	            gen
    	                ("while(r.pos<c2){")
    	                    ("var tag2=r.uint32()")
    	                    ("switch(tag2>>>3){")
    	                        ("case 1: k=r.%s(); break", field.keyType)
    	                        ("case 2:");

    	            if (types.basic[type] === undefined) gen
    	                            ("value=types[%i].decode(r,r.uint32())", i); // can't be groups
    	            else gen
    	                            ("value=r.%s()", type);

    	            gen
    	                            ("break")
    	                        ("default:")
    	                            ("r.skipType(tag2&7)")
    	                            ("break")
    	                    ("}")
    	                ("}");

    	            if (types.long[field.keyType] !== undefined) gen
    	                ("%s[typeof k===\"object\"?util.longToHash(k):k]=value", ref);
    	            else gen
    	                ("%s[k]=value", ref);

    	        // Repeated fields
    	        } else if (field.repeated) { gen

    	                ("if(!(%s&&%s.length))", ref, ref)
    	                    ("%s=[]", ref);

    	            // Packable (always check for forward and backward compatiblity)
    	            if (types.packed[type] !== undefined) gen
    	                ("if((t&7)===2){")
    	                    ("var c2=r.uint32()+r.pos")
    	                    ("while(r.pos<c2)")
    	                        ("%s.push(r.%s())", ref, type)
    	                ("}else");

    	            // Non-packed
    	            if (types.basic[type] === undefined) gen(field.resolvedType.group
    	                    ? "%s.push(types[%i].decode(r))"
    	                    : "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
    	            else gen
    	                    ("%s.push(r.%s())", ref, type);

    	        // Non-repeated
    	        } else if (types.basic[type] === undefined) gen(field.resolvedType.group
    	                ? "%s=types[%i].decode(r)"
    	                : "%s=types[%i].decode(r,r.uint32())", ref, i);
    	        else gen
    	                ("%s=r.%s()", ref, type);
    	        gen
    	                ("break")
    	            ("}");
    	        // Unknown fields
    	    } gen
    	            ("default:")
    	                ("r.skipType(t&7)")
    	                ("break")

    	        ("}")
    	    ("}");

    	    // Field presence
    	    for (i = 0; i < mtype._fieldsArray.length; ++i) {
    	        var rfield = mtype._fieldsArray[i];
    	        if (rfield.required) gen
    	    ("if(!m.hasOwnProperty(%j))", rfield.name)
    	        ("throw util.ProtocolError(%j,{instance:m})", missing(rfield));
    	    }

    	    return gen
    	    ("return m");
    	    /* eslint-enable no-unexpected-multiline */
    	}
    	return decoder_1;
    }

    var verifier_1;
    var hasRequiredVerifier;

    function requireVerifier () {
    	if (hasRequiredVerifier) return verifier_1;
    	hasRequiredVerifier = 1;
    	"use strict";
    	verifier_1 = verifier;

    	var Enum      = require_enum(),
    	    util      = requireUtil();

    	function invalid(field, expected) {
    	    return field.name + ": " + expected + (field.repeated && expected !== "array" ? "[]" : field.map && expected !== "object" ? "{k:"+field.keyType+"}" : "") + " expected";
    	}

    	/**
    	 * Generates a partial value verifier.
    	 * @param {Codegen} gen Codegen instance
    	 * @param {Field} field Reflected field
    	 * @param {number} fieldIndex Field index
    	 * @param {string} ref Variable reference
    	 * @returns {Codegen} Codegen instance
    	 * @ignore
    	 */
    	function genVerifyValue(gen, field, fieldIndex, ref) {
    	    /* eslint-disable no-unexpected-multiline */
    	    if (field.resolvedType) {
    	        if (field.resolvedType instanceof Enum) { gen
    	            ("switch(%s){", ref)
    	                ("default:")
    	                    ("return%j", invalid(field, "enum value"));
    	            for (var keys = Object.keys(field.resolvedType.values), j = 0; j < keys.length; ++j) gen
    	                ("case %i:", field.resolvedType.values[keys[j]]);
    	            gen
    	                    ("break")
    	            ("}");
    	        } else {
    	            gen
    	            ("{")
    	                ("var e=types[%i].verify(%s);", fieldIndex, ref)
    	                ("if(e)")
    	                    ("return%j+e", field.name + ".")
    	            ("}");
    	        }
    	    } else {
    	        switch (field.type) {
    	            case "int32":
    	            case "uint32":
    	            case "sint32":
    	            case "fixed32":
    	            case "sfixed32": gen
    	                ("if(!util.isInteger(%s))", ref)
    	                    ("return%j", invalid(field, "integer"));
    	                break;
    	            case "int64":
    	            case "uint64":
    	            case "sint64":
    	            case "fixed64":
    	            case "sfixed64": gen
    	                ("if(!util.isInteger(%s)&&!(%s&&util.isInteger(%s.low)&&util.isInteger(%s.high)))", ref, ref, ref, ref)
    	                    ("return%j", invalid(field, "integer|Long"));
    	                break;
    	            case "float":
    	            case "double": gen
    	                ("if(typeof %s!==\"number\")", ref)
    	                    ("return%j", invalid(field, "number"));
    	                break;
    	            case "bool": gen
    	                ("if(typeof %s!==\"boolean\")", ref)
    	                    ("return%j", invalid(field, "boolean"));
    	                break;
    	            case "string": gen
    	                ("if(!util.isString(%s))", ref)
    	                    ("return%j", invalid(field, "string"));
    	                break;
    	            case "bytes": gen
    	                ("if(!(%s&&typeof %s.length===\"number\"||util.isString(%s)))", ref, ref, ref)
    	                    ("return%j", invalid(field, "buffer"));
    	                break;
    	        }
    	    }
    	    return gen;
    	    /* eslint-enable no-unexpected-multiline */
    	}

    	/**
    	 * Generates a partial key verifier.
    	 * @param {Codegen} gen Codegen instance
    	 * @param {Field} field Reflected field
    	 * @param {string} ref Variable reference
    	 * @returns {Codegen} Codegen instance
    	 * @ignore
    	 */
    	function genVerifyKey(gen, field, ref) {
    	    /* eslint-disable no-unexpected-multiline */
    	    switch (field.keyType) {
    	        case "int32":
    	        case "uint32":
    	        case "sint32":
    	        case "fixed32":
    	        case "sfixed32": gen
    	            ("if(!util.key32Re.test(%s))", ref)
    	                ("return%j", invalid(field, "integer key"));
    	            break;
    	        case "int64":
    	        case "uint64":
    	        case "sint64":
    	        case "fixed64":
    	        case "sfixed64": gen
    	            ("if(!util.key64Re.test(%s))", ref) // see comment above: x is ok, d is not
    	                ("return%j", invalid(field, "integer|Long key"));
    	            break;
    	        case "bool": gen
    	            ("if(!util.key2Re.test(%s))", ref)
    	                ("return%j", invalid(field, "boolean key"));
    	            break;
    	    }
    	    return gen;
    	    /* eslint-enable no-unexpected-multiline */
    	}

    	/**
    	 * Generates a verifier specific to the specified message type.
    	 * @param {Type} mtype Message type
    	 * @returns {Codegen} Codegen instance
    	 */
    	function verifier(mtype) {
    	    /* eslint-disable no-unexpected-multiline */

    	    var gen = util.codegen(["m"], mtype.name + "$verify")
    	    ("if(typeof m!==\"object\"||m===null)")
    	        ("return%j", "object expected");
    	    var oneofs = mtype.oneofsArray,
    	        seenFirstField = {};
    	    if (oneofs.length) gen
    	    ("var p={}");

    	    for (var i = 0; i < /* initializes */ mtype.fieldsArray.length; ++i) {
    	        var field = mtype._fieldsArray[i].resolve(),
    	            ref   = "m" + util.safeProp(field.name);

    	        if (field.optional) gen
    	        ("if(%s!=null&&m.hasOwnProperty(%j)){", ref, field.name); // !== undefined && !== null

    	        // map fields
    	        if (field.map) { gen
    	            ("if(!util.isObject(%s))", ref)
    	                ("return%j", invalid(field, "object"))
    	            ("var k=Object.keys(%s)", ref)
    	            ("for(var i=0;i<k.length;++i){");
    	                genVerifyKey(gen, field, "k[i]");
    	                genVerifyValue(gen, field, i, ref + "[k[i]]")
    	            ("}");

    	        // repeated fields
    	        } else if (field.repeated) { gen
    	            ("if(!Array.isArray(%s))", ref)
    	                ("return%j", invalid(field, "array"))
    	            ("for(var i=0;i<%s.length;++i){", ref);
    	                genVerifyValue(gen, field, i, ref + "[i]")
    	            ("}");

    	        // required or present fields
    	        } else {
    	            if (field.partOf) {
    	                var oneofProp = util.safeProp(field.partOf.name);
    	                if (seenFirstField[field.partOf.name] === 1) gen
    	            ("if(p%s===1)", oneofProp)
    	                ("return%j", field.partOf.name + ": multiple values");
    	                seenFirstField[field.partOf.name] = 1;
    	                gen
    	            ("p%s=1", oneofProp);
    	            }
    	            genVerifyValue(gen, field, i, ref);
    	        }
    	        if (field.optional) gen
    	        ("}");
    	    }
    	    return gen
    	    ("return null");
    	    /* eslint-enable no-unexpected-multiline */
    	}
    	return verifier_1;
    }

    var converter = {};

    var hasRequiredConverter;

    function requireConverter () {
    	if (hasRequiredConverter) return converter;
    	hasRequiredConverter = 1;
    	(function (exports) {
    		"use strict";
    		/**
    		 * Runtime message from/to plain object converters.
    		 * @namespace
    		 */
    		var converter = exports;

    		var Enum = require_enum(),
    		    util = requireUtil();

    		/**
    		 * Generates a partial value fromObject conveter.
    		 * @param {Codegen} gen Codegen instance
    		 * @param {Field} field Reflected field
    		 * @param {number} fieldIndex Field index
    		 * @param {string} prop Property reference
    		 * @returns {Codegen} Codegen instance
    		 * @ignore
    		 */
    		function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
    		    var defaultAlreadyEmitted = false;
    		    /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		    if (field.resolvedType) {
    		        if (field.resolvedType instanceof Enum) { gen
    		            ("switch(d%s){", prop);
    		            for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) {
    		                // enum unknown values passthrough
    		                if (values[keys[i]] === field.typeDefault && !defaultAlreadyEmitted) { gen
    		                    ("default:")
    		                        ("if(typeof(d%s)===\"number\"){m%s=d%s;break}", prop, prop, prop);
    		                    if (!field.repeated) gen // fallback to default value only for
    		                                             // arrays, to avoid leaving holes.
    		                        ("break");           // for non-repeated fields, just ignore
    		                    defaultAlreadyEmitted = true;
    		                }
    		                gen
    		                ("case%j:", keys[i])
    		                ("case %i:", values[keys[i]])
    		                    ("m%s=%j", prop, values[keys[i]])
    		                    ("break");
    		            } gen
    		            ("}");
    		        } else gen
    		            ("if(typeof d%s!==\"object\")", prop)
    		                ("throw TypeError(%j)", field.fullName + ": object expected")
    		            ("m%s=types[%i].fromObject(d%s)", prop, fieldIndex, prop);
    		    } else {
    		        var isUnsigned = false;
    		        switch (field.type) {
    		            case "double":
    		            case "float": gen
    		                ("m%s=Number(d%s)", prop, prop); // also catches "NaN", "Infinity"
    		                break;
    		            case "uint32":
    		            case "fixed32": gen
    		                ("m%s=d%s>>>0", prop, prop);
    		                break;
    		            case "int32":
    		            case "sint32":
    		            case "sfixed32": gen
    		                ("m%s=d%s|0", prop, prop);
    		                break;
    		            case "uint64":
    		                isUnsigned = true;
    		                // eslint-disable-line no-fallthrough
    		            case "int64":
    		            case "sint64":
    		            case "fixed64":
    		            case "sfixed64": gen
    		                ("if(util.Long)")
    		                    ("(m%s=util.Long.fromValue(d%s)).unsigned=%j", prop, prop, isUnsigned)
    		                ("else if(typeof d%s===\"string\")", prop)
    		                    ("m%s=parseInt(d%s,10)", prop, prop)
    		                ("else if(typeof d%s===\"number\")", prop)
    		                    ("m%s=d%s", prop, prop)
    		                ("else if(typeof d%s===\"object\")", prop)
    		                    ("m%s=new util.LongBits(d%s.low>>>0,d%s.high>>>0).toNumber(%s)", prop, prop, prop, isUnsigned ? "true" : "");
    		                break;
    		            case "bytes": gen
    		                ("if(typeof d%s===\"string\")", prop)
    		                    ("util.base64.decode(d%s,m%s=util.newBuffer(util.base64.length(d%s)),0)", prop, prop, prop)
    		                ("else if(d%s.length >= 0)", prop)
    		                    ("m%s=d%s", prop, prop);
    		                break;
    		            case "string": gen
    		                ("m%s=String(d%s)", prop, prop);
    		                break;
    		            case "bool": gen
    		                ("m%s=Boolean(d%s)", prop, prop);
    		                break;
    		            /* default: gen
    		                ("m%s=d%s", prop, prop);
    		                break; */
    		        }
    		    }
    		    return gen;
    		    /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		}

    		/**
    		 * Generates a plain object to runtime message converter specific to the specified message type.
    		 * @param {Type} mtype Message type
    		 * @returns {Codegen} Codegen instance
    		 */
    		converter.fromObject = function fromObject(mtype) {
    		    /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		    var fields = mtype.fieldsArray;
    		    var gen = util.codegen(["d"], mtype.name + "$fromObject")
    		    ("if(d instanceof this.ctor)")
    		        ("return d");
    		    if (!fields.length) return gen
    		    ("return new this.ctor");
    		    gen
    		    ("var m=new this.ctor");
    		    for (var i = 0; i < fields.length; ++i) {
    		        var field  = fields[i].resolve(),
    		            prop   = util.safeProp(field.name);

    		        // Map fields
    		        if (field.map) { gen
    		    ("if(d%s){", prop)
    		        ("if(typeof d%s!==\"object\")", prop)
    		            ("throw TypeError(%j)", field.fullName + ": object expected")
    		        ("m%s={}", prop)
    		        ("for(var ks=Object.keys(d%s),i=0;i<ks.length;++i){", prop);
    		            genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[ks[i]]")
    		        ("}")
    		    ("}");

    		        // Repeated fields
    		        } else if (field.repeated) { gen
    		    ("if(d%s){", prop)
    		        ("if(!Array.isArray(d%s))", prop)
    		            ("throw TypeError(%j)", field.fullName + ": array expected")
    		        ("m%s=[]", prop)
    		        ("for(var i=0;i<d%s.length;++i){", prop);
    		            genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[i]")
    		        ("}")
    		    ("}");

    		        // Non-repeated fields
    		        } else {
    		            if (!(field.resolvedType instanceof Enum)) gen // no need to test for null/undefined if an enum (uses switch)
    		    ("if(d%s!=null){", prop); // !== undefined && !== null
    		        genValuePartial_fromObject(gen, field, /* not sorted */ i, prop);
    		            if (!(field.resolvedType instanceof Enum)) gen
    		    ("}");
    		        }
    		    } return gen
    		    ("return m");
    		    /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		};

    		/**
    		 * Generates a partial value toObject converter.
    		 * @param {Codegen} gen Codegen instance
    		 * @param {Field} field Reflected field
    		 * @param {number} fieldIndex Field index
    		 * @param {string} prop Property reference
    		 * @returns {Codegen} Codegen instance
    		 * @ignore
    		 */
    		function genValuePartial_toObject(gen, field, fieldIndex, prop) {
    		    /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		    if (field.resolvedType) {
    		        if (field.resolvedType instanceof Enum) gen
    		            ("d%s=o.enums===String?(types[%i].values[m%s]===undefined?m%s:types[%i].values[m%s]):m%s", prop, fieldIndex, prop, prop, fieldIndex, prop, prop);
    		        else gen
    		            ("d%s=types[%i].toObject(m%s,o)", prop, fieldIndex, prop);
    		    } else {
    		        var isUnsigned = false;
    		        switch (field.type) {
    		            case "double":
    		            case "float": gen
    		            ("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s", prop, prop, prop, prop);
    		                break;
    		            case "uint64":
    		                isUnsigned = true;
    		                // eslint-disable-line no-fallthrough
    		            case "int64":
    		            case "sint64":
    		            case "fixed64":
    		            case "sfixed64": gen
    		            ("if(typeof m%s===\"number\")", prop)
    		                ("d%s=o.longs===String?String(m%s):m%s", prop, prop, prop)
    		            ("else") // Long-like
    		                ("d%s=o.longs===String?util.Long.prototype.toString.call(m%s):o.longs===Number?new util.LongBits(m%s.low>>>0,m%s.high>>>0).toNumber(%s):m%s", prop, prop, prop, prop, isUnsigned ? "true": "", prop);
    		                break;
    		            case "bytes": gen
    		            ("d%s=o.bytes===String?util.base64.encode(m%s,0,m%s.length):o.bytes===Array?Array.prototype.slice.call(m%s):m%s", prop, prop, prop, prop, prop);
    		                break;
    		            default: gen
    		            ("d%s=m%s", prop, prop);
    		                break;
    		        }
    		    }
    		    return gen;
    		    /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		}

    		/**
    		 * Generates a runtime message to plain object converter specific to the specified message type.
    		 * @param {Type} mtype Message type
    		 * @returns {Codegen} Codegen instance
    		 */
    		converter.toObject = function toObject(mtype) {
    		    /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		    var fields = mtype.fieldsArray.slice().sort(util.compareFieldsById);
    		    if (!fields.length)
    		        return util.codegen()("return {}");
    		    var gen = util.codegen(["m", "o"], mtype.name + "$toObject")
    		    ("if(!o)")
    		        ("o={}")
    		    ("var d={}");

    		    var repeatedFields = [],
    		        mapFields = [],
    		        normalFields = [],
    		        i = 0;
    		    for (; i < fields.length; ++i)
    		        if (!fields[i].partOf)
    		            ( fields[i].resolve().repeated ? repeatedFields
    		            : fields[i].map ? mapFields
    		            : normalFields).push(fields[i]);

    		    if (repeatedFields.length) { gen
    		    ("if(o.arrays||o.defaults){");
    		        for (i = 0; i < repeatedFields.length; ++i) gen
    		        ("d%s=[]", util.safeProp(repeatedFields[i].name));
    		        gen
    		    ("}");
    		    }

    		    if (mapFields.length) { gen
    		    ("if(o.objects||o.defaults){");
    		        for (i = 0; i < mapFields.length; ++i) gen
    		        ("d%s={}", util.safeProp(mapFields[i].name));
    		        gen
    		    ("}");
    		    }

    		    if (normalFields.length) { gen
    		    ("if(o.defaults){");
    		        for (i = 0; i < normalFields.length; ++i) {
    		            var field = normalFields[i],
    		                prop  = util.safeProp(field.name);
    		            if (field.resolvedType instanceof Enum) gen
    		        ("d%s=o.enums===String?%j:%j", prop, field.resolvedType.valuesById[field.typeDefault], field.typeDefault);
    		            else if (field.long) gen
    		        ("if(util.Long){")
    		            ("var n=new util.Long(%i,%i,%j)", field.typeDefault.low, field.typeDefault.high, field.typeDefault.unsigned)
    		            ("d%s=o.longs===String?n.toString():o.longs===Number?n.toNumber():n", prop)
    		        ("}else")
    		            ("d%s=o.longs===String?%j:%i", prop, field.typeDefault.toString(), field.typeDefault.toNumber());
    		            else if (field.bytes) {
    		                var arrayDefault = "[" + Array.prototype.slice.call(field.typeDefault).join(",") + "]";
    		                gen
    		        ("if(o.bytes===String)d%s=%j", prop, String.fromCharCode.apply(String, field.typeDefault))
    		        ("else{")
    		            ("d%s=%s", prop, arrayDefault)
    		            ("if(o.bytes!==Array)d%s=util.newBuffer(d%s)", prop, prop)
    		        ("}");
    		            } else gen
    		        ("d%s=%j", prop, field.typeDefault); // also messages (=null)
    		        } gen
    		    ("}");
    		    }
    		    var hasKs2 = false;
    		    for (i = 0; i < fields.length; ++i) {
    		        var field = fields[i],
    		            index = mtype._fieldsArray.indexOf(field),
    		            prop  = util.safeProp(field.name);
    		        if (field.map) {
    		            if (!hasKs2) { hasKs2 = true; gen
    		    ("var ks2");
    		            } gen
    		    ("if(m%s&&(ks2=Object.keys(m%s)).length){", prop, prop)
    		        ("d%s={}", prop)
    		        ("for(var j=0;j<ks2.length;++j){");
    		            genValuePartial_toObject(gen, field, /* sorted */ index, prop + "[ks2[j]]")
    		        ("}");
    		        } else if (field.repeated) { gen
    		    ("if(m%s&&m%s.length){", prop, prop)
    		        ("d%s=[]", prop)
    		        ("for(var j=0;j<m%s.length;++j){", prop);
    		            genValuePartial_toObject(gen, field, /* sorted */ index, prop + "[j]")
    		        ("}");
    		        } else { gen
    		    ("if(m%s!=null&&m.hasOwnProperty(%j)){", prop, field.name); // !== undefined && !== null
    		        genValuePartial_toObject(gen, field, /* sorted */ index, prop);
    		        if (field.partOf) gen
    		        ("if(o.oneofs)")
    		            ("d%s=%j", util.safeProp(field.partOf.name), field.name);
    		        }
    		        gen
    		    ("}");
    		    }
    		    return gen
    		    ("return d");
    		    /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
    		}; 
    	} (converter));
    	return converter;
    }

    var wrappers$1 = {};

    (function (exports) {
    	"use strict";

    	/**
    	 * Wrappers for common types.
    	 * @type {Object.<string,IWrapper>}
    	 * @const
    	 */
    	var wrappers = exports;

    	var Message = message$1;

    	/**
    	 * From object converter part of an {@link IWrapper}.
    	 * @typedef WrapperFromObjectConverter
    	 * @type {function}
    	 * @param {Object.<string,*>} object Plain object
    	 * @returns {Message<{}>} Message instance
    	 * @this Type
    	 */

    	/**
    	 * To object converter part of an {@link IWrapper}.
    	 * @typedef WrapperToObjectConverter
    	 * @type {function}
    	 * @param {Message<{}>} message Message instance
    	 * @param {IConversionOptions} [options] Conversion options
    	 * @returns {Object.<string,*>} Plain object
    	 * @this Type
    	 */

    	/**
    	 * Common type wrapper part of {@link wrappers}.
    	 * @interface IWrapper
    	 * @property {WrapperFromObjectConverter} [fromObject] From object converter
    	 * @property {WrapperToObjectConverter} [toObject] To object converter
    	 */

    	// Custom wrapper for Any
    	wrappers[".google.protobuf.Any"] = {

    	    fromObject: function(object) {

    	        // unwrap value type if mapped
    	        if (object && object["@type"]) {
    	             // Only use fully qualified type name after the last '/'
    	            var name = object["@type"].substring(object["@type"].lastIndexOf("/") + 1);
    	            var type = this.lookup(name);
    	            /* istanbul ignore else */
    	            if (type) {
    	                // type_url does not accept leading "."
    	                var type_url = object["@type"].charAt(0) === "." ?
    	                    object["@type"].slice(1) : object["@type"];
    	                // type_url prefix is optional, but path seperator is required
    	                if (type_url.indexOf("/") === -1) {
    	                    type_url = "/" + type_url;
    	                }
    	                return this.create({
    	                    type_url: type_url,
    	                    value: type.encode(type.fromObject(object)).finish()
    	                });
    	            }
    	        }

    	        return this.fromObject(object);
    	    },

    	    toObject: function(message, options) {

    	        // Default prefix
    	        var googleApi = "type.googleapis.com/";
    	        var prefix = "";
    	        var name = "";

    	        // decode value if requested and unmapped
    	        if (options && options.json && message.type_url && message.value) {
    	            // Only use fully qualified type name after the last '/'
    	            name = message.type_url.substring(message.type_url.lastIndexOf("/") + 1);
    	            // Separate the prefix used
    	            prefix = message.type_url.substring(0, message.type_url.lastIndexOf("/") + 1);
    	            var type = this.lookup(name);
    	            /* istanbul ignore else */
    	            if (type)
    	                message = type.decode(message.value);
    	        }

    	        // wrap value if unmapped
    	        if (!(message instanceof this.ctor) && message instanceof Message) {
    	            var object = message.$type.toObject(message, options);
    	            var messageName = message.$type.fullName[0] === "." ?
    	                message.$type.fullName.slice(1) : message.$type.fullName;
    	            // Default to type.googleapis.com prefix if no prefix is used
    	            if (prefix === "") {
    	                prefix = googleApi;
    	            }
    	            name = prefix + messageName;
    	            object["@type"] = name;
    	            return object;
    	        }

    	        return this.toObject(message, options);
    	    }
    	}; 
    } (wrappers$1));

    const wrappers = /*@__PURE__*/getDefaultExportFromCjs(wrappers$1);

    var type;
    var hasRequiredType;

    function requireType () {
    	if (hasRequiredType) return type;
    	hasRequiredType = 1;
    	"use strict";
    	type = Type;

    	// extends Namespace
    	var Namespace = requireNamespace();
    	((Type.prototype = Object.create(Namespace.prototype)).constructor = Type).className = "Type";

    	var Enum      = require_enum(),
    	    OneOf     = requireOneof(),
    	    Field     = requireField(),
    	    MapField  = requireMapfield(),
    	    Service   = requireService(),
    	    Message   = message$1,
    	    Reader    = reader,
    	    Writer    = writer,
    	    util      = requireUtil(),
    	    encoder   = requireEncoder(),
    	    decoder   = requireDecoder(),
    	    verifier  = requireVerifier(),
    	    converter = requireConverter(),
    	    wrappers  = wrappers$1;

    	/**
    	 * Constructs a new reflected message type instance.
    	 * @classdesc Reflected message type.
    	 * @extends NamespaceBase
    	 * @constructor
    	 * @param {string} name Message name
    	 * @param {Object.<string,*>} [options] Declared options
    	 */
    	function Type(name, options) {
    	    Namespace.call(this, name, options);

    	    /**
    	     * Message fields.
    	     * @type {Object.<string,Field>}
    	     */
    	    this.fields = {};  // toJSON, marker

    	    /**
    	     * Oneofs declared within this namespace, if any.
    	     * @type {Object.<string,OneOf>}
    	     */
    	    this.oneofs = undefined; // toJSON

    	    /**
    	     * Extension ranges, if any.
    	     * @type {number[][]}
    	     */
    	    this.extensions = undefined; // toJSON

    	    /**
    	     * Reserved ranges, if any.
    	     * @type {Array.<number[]|string>}
    	     */
    	    this.reserved = undefined; // toJSON

    	    /*?
    	     * Whether this type is a legacy group.
    	     * @type {boolean|undefined}
    	     */
    	    this.group = undefined; // toJSON

    	    /**
    	     * Cached fields by id.
    	     * @type {Object.<number,Field>|null}
    	     * @private
    	     */
    	    this._fieldsById = null;

    	    /**
    	     * Cached fields as an array.
    	     * @type {Field[]|null}
    	     * @private
    	     */
    	    this._fieldsArray = null;

    	    /**
    	     * Cached oneofs as an array.
    	     * @type {OneOf[]|null}
    	     * @private
    	     */
    	    this._oneofsArray = null;

    	    /**
    	     * Cached constructor.
    	     * @type {Constructor<{}>}
    	     * @private
    	     */
    	    this._ctor = null;
    	}

    	Object.defineProperties(Type.prototype, {

    	    /**
    	     * Message fields by id.
    	     * @name Type#fieldsById
    	     * @type {Object.<number,Field>}
    	     * @readonly
    	     */
    	    fieldsById: {
    	        get: function() {

    	            /* istanbul ignore if */
    	            if (this._fieldsById)
    	                return this._fieldsById;

    	            this._fieldsById = {};
    	            for (var names = Object.keys(this.fields), i = 0; i < names.length; ++i) {
    	                var field = this.fields[names[i]],
    	                    id = field.id;

    	                /* istanbul ignore if */
    	                if (this._fieldsById[id])
    	                    throw Error("duplicate id " + id + " in " + this);

    	                this._fieldsById[id] = field;
    	            }
    	            return this._fieldsById;
    	        }
    	    },

    	    /**
    	     * Fields of this message as an array for iteration.
    	     * @name Type#fieldsArray
    	     * @type {Field[]}
    	     * @readonly
    	     */
    	    fieldsArray: {
    	        get: function() {
    	            return this._fieldsArray || (this._fieldsArray = util.toArray(this.fields));
    	        }
    	    },

    	    /**
    	     * Oneofs of this message as an array for iteration.
    	     * @name Type#oneofsArray
    	     * @type {OneOf[]}
    	     * @readonly
    	     */
    	    oneofsArray: {
    	        get: function() {
    	            return this._oneofsArray || (this._oneofsArray = util.toArray(this.oneofs));
    	        }
    	    },

    	    /**
    	     * The registered constructor, if any registered, otherwise a generic constructor.
    	     * Assigning a function replaces the internal constructor. If the function does not extend {@link Message} yet, its prototype will be setup accordingly and static methods will be populated. If it already extends {@link Message}, it will just replace the internal constructor.
    	     * @name Type#ctor
    	     * @type {Constructor<{}>}
    	     */
    	    ctor: {
    	        get: function() {
    	            return this._ctor || (this.ctor = Type.generateConstructor(this)());
    	        },
    	        set: function(ctor) {

    	            // Ensure proper prototype
    	            var prototype = ctor.prototype;
    	            if (!(prototype instanceof Message)) {
    	                (ctor.prototype = new Message()).constructor = ctor;
    	                util.merge(ctor.prototype, prototype);
    	            }

    	            // Classes and messages reference their reflected type
    	            ctor.$type = ctor.prototype.$type = this;

    	            // Mix in static methods
    	            util.merge(ctor, Message, true);

    	            this._ctor = ctor;

    	            // Messages have non-enumerable default values on their prototype
    	            var i = 0;
    	            for (; i < /* initializes */ this.fieldsArray.length; ++i)
    	                this._fieldsArray[i].resolve(); // ensures a proper value

    	            // Messages have non-enumerable getters and setters for each virtual oneof field
    	            var ctorProperties = {};
    	            for (i = 0; i < /* initializes */ this.oneofsArray.length; ++i)
    	                ctorProperties[this._oneofsArray[i].resolve().name] = {
    	                    get: util.oneOfGetter(this._oneofsArray[i].oneof),
    	                    set: util.oneOfSetter(this._oneofsArray[i].oneof)
    	                };
    	            if (i)
    	                Object.defineProperties(ctor.prototype, ctorProperties);
    	        }
    	    }
    	});

    	/**
    	 * Generates a constructor function for the specified type.
    	 * @param {Type} mtype Message type
    	 * @returns {Codegen} Codegen instance
    	 */
    	Type.generateConstructor = function generateConstructor(mtype) {
    	    /* eslint-disable no-unexpected-multiline */
    	    var gen = util.codegen(["p"], mtype.name);
    	    // explicitly initialize mutable object/array fields so that these aren't just inherited from the prototype
    	    for (var i = 0, field; i < mtype.fieldsArray.length; ++i)
    	        if ((field = mtype._fieldsArray[i]).map) gen
    	            ("this%s={}", util.safeProp(field.name));
    	        else if (field.repeated) gen
    	            ("this%s=[]", util.safeProp(field.name));
    	    return gen
    	    ("if(p)for(var ks=Object.keys(p),i=0;i<ks.length;++i)if(p[ks[i]]!=null)") // omit undefined or null
    	        ("this[ks[i]]=p[ks[i]]");
    	    /* eslint-enable no-unexpected-multiline */
    	};

    	function clearCache(type) {
    	    type._fieldsById = type._fieldsArray = type._oneofsArray = null;
    	    delete type.encode;
    	    delete type.decode;
    	    delete type.verify;
    	    return type;
    	}

    	/**
    	 * Message type descriptor.
    	 * @interface IType
    	 * @extends INamespace
    	 * @property {Object.<string,IOneOf>} [oneofs] Oneof descriptors
    	 * @property {Object.<string,IField>} fields Field descriptors
    	 * @property {number[][]} [extensions] Extension ranges
    	 * @property {number[][]} [reserved] Reserved ranges
    	 * @property {boolean} [group=false] Whether a legacy group or not
    	 */

    	/**
    	 * Creates a message type from a message type descriptor.
    	 * @param {string} name Message name
    	 * @param {IType} json Message type descriptor
    	 * @returns {Type} Created message type
    	 */
    	Type.fromJSON = function fromJSON(name, json) {
    	    var type = new Type(name, json.options);
    	    type.extensions = json.extensions;
    	    type.reserved = json.reserved;
    	    var names = Object.keys(json.fields),
    	        i = 0;
    	    for (; i < names.length; ++i)
    	        type.add(
    	            ( typeof json.fields[names[i]].keyType !== "undefined"
    	            ? MapField.fromJSON
    	            : Field.fromJSON )(names[i], json.fields[names[i]])
    	        );
    	    if (json.oneofs)
    	        for (names = Object.keys(json.oneofs), i = 0; i < names.length; ++i)
    	            type.add(OneOf.fromJSON(names[i], json.oneofs[names[i]]));
    	    if (json.nested)
    	        for (names = Object.keys(json.nested), i = 0; i < names.length; ++i) {
    	            var nested = json.nested[names[i]];
    	            type.add( // most to least likely
    	                ( nested.id !== undefined
    	                ? Field.fromJSON
    	                : nested.fields !== undefined
    	                ? Type.fromJSON
    	                : nested.values !== undefined
    	                ? Enum.fromJSON
    	                : nested.methods !== undefined
    	                ? Service.fromJSON
    	                : Namespace.fromJSON )(names[i], nested)
    	            );
    	        }
    	    if (json.extensions && json.extensions.length)
    	        type.extensions = json.extensions;
    	    if (json.reserved && json.reserved.length)
    	        type.reserved = json.reserved;
    	    if (json.group)
    	        type.group = true;
    	    if (json.comment)
    	        type.comment = json.comment;
    	    return type;
    	};

    	/**
    	 * Converts this message type to a message type descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IType} Message type descriptor
    	 */
    	Type.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "options"    , inherited && inherited.options || undefined,
    	        "oneofs"     , Namespace.arrayToJSON(this.oneofsArray, toJSONOptions),
    	        "fields"     , Namespace.arrayToJSON(this.fieldsArray.filter(function(obj) { return !obj.declaringField; }), toJSONOptions) || {},
    	        "extensions" , this.extensions && this.extensions.length ? this.extensions : undefined,
    	        "reserved"   , this.reserved && this.reserved.length ? this.reserved : undefined,
    	        "group"      , this.group || undefined,
    	        "nested"     , inherited && inherited.nested || undefined,
    	        "comment"    , keepComments ? this.comment : undefined
    	    ]);
    	};

    	/**
    	 * @override
    	 */
    	Type.prototype.resolveAll = function resolveAll() {
    	    var fields = this.fieldsArray, i = 0;
    	    while (i < fields.length)
    	        fields[i++].resolve();
    	    var oneofs = this.oneofsArray; i = 0;
    	    while (i < oneofs.length)
    	        oneofs[i++].resolve();
    	    return Namespace.prototype.resolveAll.call(this);
    	};

    	/**
    	 * @override
    	 */
    	Type.prototype.get = function get(name) {
    	    return this.fields[name]
    	        || this.oneofs && this.oneofs[name]
    	        || this.nested && this.nested[name]
    	        || null;
    	};

    	/**
    	 * Adds a nested object to this type.
    	 * @param {ReflectionObject} object Nested object to add
    	 * @returns {Type} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If there is already a nested object with this name or, if a field, when there is already a field with this id
    	 */
    	Type.prototype.add = function add(object) {

    	    if (this.get(object.name))
    	        throw Error("duplicate name '" + object.name + "' in " + this);

    	    if (object instanceof Field && object.extend === undefined) {
    	        // NOTE: Extension fields aren't actual fields on the declaring type, but nested objects.
    	        // The root object takes care of adding distinct sister-fields to the respective extended
    	        // type instead.

    	        // avoids calling the getter if not absolutely necessary because it's called quite frequently
    	        if (this._fieldsById ? /* istanbul ignore next */ this._fieldsById[object.id] : this.fieldsById[object.id])
    	            throw Error("duplicate id " + object.id + " in " + this);
    	        if (this.isReservedId(object.id))
    	            throw Error("id " + object.id + " is reserved in " + this);
    	        if (this.isReservedName(object.name))
    	            throw Error("name '" + object.name + "' is reserved in " + this);

    	        if (object.parent)
    	            object.parent.remove(object);
    	        this.fields[object.name] = object;
    	        object.message = this;
    	        object.onAdd(this);
    	        return clearCache(this);
    	    }
    	    if (object instanceof OneOf) {
    	        if (!this.oneofs)
    	            this.oneofs = {};
    	        this.oneofs[object.name] = object;
    	        object.onAdd(this);
    	        return clearCache(this);
    	    }
    	    return Namespace.prototype.add.call(this, object);
    	};

    	/**
    	 * Removes a nested object from this type.
    	 * @param {ReflectionObject} object Nested object to remove
    	 * @returns {Type} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If `object` is not a member of this type
    	 */
    	Type.prototype.remove = function remove(object) {
    	    if (object instanceof Field && object.extend === undefined) {
    	        // See Type#add for the reason why extension fields are excluded here.

    	        /* istanbul ignore if */
    	        if (!this.fields || this.fields[object.name] !== object)
    	            throw Error(object + " is not a member of " + this);

    	        delete this.fields[object.name];
    	        object.parent = null;
    	        object.onRemove(this);
    	        return clearCache(this);
    	    }
    	    if (object instanceof OneOf) {

    	        /* istanbul ignore if */
    	        if (!this.oneofs || this.oneofs[object.name] !== object)
    	            throw Error(object + " is not a member of " + this);

    	        delete this.oneofs[object.name];
    	        object.parent = null;
    	        object.onRemove(this);
    	        return clearCache(this);
    	    }
    	    return Namespace.prototype.remove.call(this, object);
    	};

    	/**
    	 * Tests if the specified id is reserved.
    	 * @param {number} id Id to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Type.prototype.isReservedId = function isReservedId(id) {
    	    return Namespace.isReservedId(this.reserved, id);
    	};

    	/**
    	 * Tests if the specified name is reserved.
    	 * @param {string} name Name to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Type.prototype.isReservedName = function isReservedName(name) {
    	    return Namespace.isReservedName(this.reserved, name);
    	};

    	/**
    	 * Creates a new message of this type using the specified properties.
    	 * @param {Object.<string,*>} [properties] Properties to set
    	 * @returns {Message<{}>} Message instance
    	 */
    	Type.prototype.create = function create(properties) {
    	    return new this.ctor(properties);
    	};

    	/**
    	 * Sets up {@link Type#encode|encode}, {@link Type#decode|decode} and {@link Type#verify|verify}.
    	 * @returns {Type} `this`
    	 */
    	Type.prototype.setup = function setup() {
    	    // Sets up everything at once so that the prototype chain does not have to be re-evaluated
    	    // multiple times (V8, soft-deopt prototype-check).

    	    var fullName = this.fullName,
    	        types    = [];
    	    for (var i = 0; i < /* initializes */ this.fieldsArray.length; ++i)
    	        types.push(this._fieldsArray[i].resolve().resolvedType);

    	    // Replace setup methods with type-specific generated functions
    	    this.encode = encoder(this)({
    	        Writer : Writer,
    	        types  : types,
    	        util   : util
    	    });
    	    this.decode = decoder(this)({
    	        Reader : Reader,
    	        types  : types,
    	        util   : util
    	    });
    	    this.verify = verifier(this)({
    	        types : types,
    	        util  : util
    	    });
    	    this.fromObject = converter.fromObject(this)({
    	        types : types,
    	        util  : util
    	    });
    	    this.toObject = converter.toObject(this)({
    	        types : types,
    	        util  : util
    	    });

    	    // Inject custom wrappers for common types
    	    var wrapper = wrappers[fullName];
    	    if (wrapper) {
    	        var originalThis = Object.create(this);
    	        // if (wrapper.fromObject) {
    	            originalThis.fromObject = this.fromObject;
    	            this.fromObject = wrapper.fromObject.bind(originalThis);
    	        // }
    	        // if (wrapper.toObject) {
    	            originalThis.toObject = this.toObject;
    	            this.toObject = wrapper.toObject.bind(originalThis);
    	        // }
    	    }

    	    return this;
    	};

    	/**
    	 * Encodes a message of this type. Does not implicitly {@link Type#verify|verify} messages.
    	 * @param {Message<{}>|Object.<string,*>} message Message instance or plain object
    	 * @param {Writer} [writer] Writer to encode to
    	 * @returns {Writer} writer
    	 */
    	Type.prototype.encode = function encode_setup(message, writer) {
    	    return this.setup().encode(message, writer); // overrides this method
    	};

    	/**
    	 * Encodes a message of this type preceeded by its byte length as a varint. Does not implicitly {@link Type#verify|verify} messages.
    	 * @param {Message<{}>|Object.<string,*>} message Message instance or plain object
    	 * @param {Writer} [writer] Writer to encode to
    	 * @returns {Writer} writer
    	 */
    	Type.prototype.encodeDelimited = function encodeDelimited(message, writer) {
    	    return this.encode(message, writer && writer.len ? writer.fork() : writer).ldelim();
    	};

    	/**
    	 * Decodes a message of this type.
    	 * @param {Reader|Uint8Array} reader Reader or buffer to decode from
    	 * @param {number} [length] Length of the message, if known beforehand
    	 * @returns {Message<{}>} Decoded message
    	 * @throws {Error} If the payload is not a reader or valid buffer
    	 * @throws {util.ProtocolError<{}>} If required fields are missing
    	 */
    	Type.prototype.decode = function decode_setup(reader, length) {
    	    return this.setup().decode(reader, length); // overrides this method
    	};

    	/**
    	 * Decodes a message of this type preceeded by its byte length as a varint.
    	 * @param {Reader|Uint8Array} reader Reader or buffer to decode from
    	 * @returns {Message<{}>} Decoded message
    	 * @throws {Error} If the payload is not a reader or valid buffer
    	 * @throws {util.ProtocolError} If required fields are missing
    	 */
    	Type.prototype.decodeDelimited = function decodeDelimited(reader) {
    	    if (!(reader instanceof Reader))
    	        reader = Reader.create(reader);
    	    return this.decode(reader, reader.uint32());
    	};

    	/**
    	 * Verifies that field values are valid and that required fields are present.
    	 * @param {Object.<string,*>} message Plain object to verify
    	 * @returns {null|string} `null` if valid, otherwise the reason why it is not
    	 */
    	Type.prototype.verify = function verify_setup(message) {
    	    return this.setup().verify(message); // overrides this method
    	};

    	/**
    	 * Creates a new message of this type from a plain object. Also converts values to their respective internal types.
    	 * @param {Object.<string,*>} object Plain object to convert
    	 * @returns {Message<{}>} Message instance
    	 */
    	Type.prototype.fromObject = function fromObject(object) {
    	    return this.setup().fromObject(object);
    	};

    	/**
    	 * Conversion options as used by {@link Type#toObject} and {@link Message.toObject}.
    	 * @interface IConversionOptions
    	 * @property {Function} [longs] Long conversion type.
    	 * Valid values are `String` and `Number` (the global types).
    	 * Defaults to copy the present value, which is a possibly unsafe number without and a {@link Long} with a long library.
    	 * @property {Function} [enums] Enum value conversion type.
    	 * Only valid value is `String` (the global type).
    	 * Defaults to copy the present value, which is the numeric id.
    	 * @property {Function} [bytes] Bytes value conversion type.
    	 * Valid values are `Array` and (a base64 encoded) `String` (the global types).
    	 * Defaults to copy the present value, which usually is a Buffer under node and an Uint8Array in the browser.
    	 * @property {boolean} [defaults=false] Also sets default values on the resulting object
    	 * @property {boolean} [arrays=false] Sets empty arrays for missing repeated fields even if `defaults=false`
    	 * @property {boolean} [objects=false] Sets empty objects for missing map fields even if `defaults=false`
    	 * @property {boolean} [oneofs=false] Includes virtual oneof properties set to the present field's name, if any
    	 * @property {boolean} [json=false] Performs additional JSON compatibility conversions, i.e. NaN and Infinity to strings
    	 */

    	/**
    	 * Creates a plain object from a message of this type. Also converts values to other types if specified.
    	 * @param {Message<{}>} message Message instance
    	 * @param {IConversionOptions} [options] Conversion options
    	 * @returns {Object.<string,*>} Plain object
    	 */
    	Type.prototype.toObject = function toObject(message, options) {
    	    return this.setup().toObject(message, options);
    	};

    	/**
    	 * Decorator function as returned by {@link Type.d} (TypeScript).
    	 * @typedef TypeDecorator
    	 * @type {function}
    	 * @param {Constructor<T>} target Target constructor
    	 * @returns {undefined}
    	 * @template T extends Message<T>
    	 */

    	/**
    	 * Type decorator (TypeScript).
    	 * @param {string} [typeName] Type name, defaults to the constructor's name
    	 * @returns {TypeDecorator<T>} Decorator function
    	 * @template T extends Message<T>
    	 */
    	Type.d = function decorateType(typeName) {
    	    return function typeDecorator(target) {
    	        util.decorateType(target, typeName);
    	    };
    	};
    	return type;
    }

    var root;
    var hasRequiredRoot;

    function requireRoot () {
    	if (hasRequiredRoot) return root;
    	hasRequiredRoot = 1;
    	"use strict";
    	root = Root;

    	// extends Namespace
    	var Namespace = requireNamespace();
    	((Root.prototype = Object.create(Namespace.prototype)).constructor = Root).className = "Root";

    	var Field   = requireField(),
    	    Enum    = require_enum(),
    	    OneOf   = requireOneof(),
    	    util    = requireUtil();

    	var Type,   // cyclic
    	    parse,  // might be excluded
    	    common; // "

    	/**
    	 * Constructs a new root namespace instance.
    	 * @classdesc Root namespace wrapping all types, enums, services, sub-namespaces etc. that belong together.
    	 * @extends NamespaceBase
    	 * @constructor
    	 * @param {Object.<string,*>} [options] Top level options
    	 */
    	function Root(options) {
    	    Namespace.call(this, "", options);

    	    /**
    	     * Deferred extension fields.
    	     * @type {Field[]}
    	     */
    	    this.deferred = [];

    	    /**
    	     * Resolved file names of loaded files.
    	     * @type {string[]}
    	     */
    	    this.files = [];
    	}

    	/**
    	 * Loads a namespace descriptor into a root namespace.
    	 * @param {INamespace} json Nameespace descriptor
    	 * @param {Root} [root] Root namespace, defaults to create a new one if omitted
    	 * @returns {Root} Root namespace
    	 */
    	Root.fromJSON = function fromJSON(json, root) {
    	    if (!root)
    	        root = new Root();
    	    if (json.options)
    	        root.setOptions(json.options);
    	    return root.addJSON(json.nested);
    	};

    	/**
    	 * Resolves the path of an imported file, relative to the importing origin.
    	 * This method exists so you can override it with your own logic in case your imports are scattered over multiple directories.
    	 * @function
    	 * @param {string} origin The file name of the importing file
    	 * @param {string} target The file name being imported
    	 * @returns {string|null} Resolved path to `target` or `null` to skip the file
    	 */
    	Root.prototype.resolvePath = util.path.resolve;

    	/**
    	 * Fetch content from file path or url
    	 * This method exists so you can override it with your own logic.
    	 * @function
    	 * @param {string} path File path or url
    	 * @param {FetchCallback} callback Callback function
    	 * @returns {undefined}
    	 */
    	Root.prototype.fetch = util.fetch;

    	// A symbol-like function to safely signal synchronous loading
    	/* istanbul ignore next */
    	function SYNC() {} // eslint-disable-line no-empty-function

    	/**
    	 * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
    	 * @param {string|string[]} filename Names of one or multiple files to load
    	 * @param {IParseOptions} options Parse options
    	 * @param {LoadCallback} callback Callback function
    	 * @returns {undefined}
    	 */
    	Root.prototype.load = function load(filename, options, callback) {
    	    if (typeof options === "function") {
    	        callback = options;
    	        options = undefined;
    	    }
    	    var self = this;
    	    if (!callback)
    	        return util.asPromise(load, self, filename, options);

    	    var sync = callback === SYNC; // undocumented

    	    // Finishes loading by calling the callback (exactly once)
    	    function finish(err, root) {
    	        /* istanbul ignore if */
    	        if (!callback)
    	            return;
    	        var cb = callback;
    	        callback = null;
    	        if (sync)
    	            throw err;
    	        cb(err, root);
    	    }

    	    // Bundled definition existence checking
    	    function getBundledFileName(filename) {
    	        var idx = filename.lastIndexOf("google/protobuf/");
    	        if (idx > -1) {
    	            var altname = filename.substring(idx);
    	            if (altname in common) return altname;
    	        }
    	        return null;
    	    }

    	    // Processes a single file
    	    function process(filename, source) {
    	        try {
    	            if (util.isString(source) && source.charAt(0) === "{")
    	                source = JSON.parse(source);
    	            if (!util.isString(source))
    	                self.setOptions(source.options).addJSON(source.nested);
    	            else {
    	                parse.filename = filename;
    	                var parsed = parse(source, self, options),
    	                    resolved,
    	                    i = 0;
    	                if (parsed.imports)
    	                    for (; i < parsed.imports.length; ++i)
    	                        if (resolved = getBundledFileName(parsed.imports[i]) || self.resolvePath(filename, parsed.imports[i]))
    	                            fetch(resolved);
    	                if (parsed.weakImports)
    	                    for (i = 0; i < parsed.weakImports.length; ++i)
    	                        if (resolved = getBundledFileName(parsed.weakImports[i]) || self.resolvePath(filename, parsed.weakImports[i]))
    	                            fetch(resolved, true);
    	            }
    	        } catch (err) {
    	            finish(err);
    	        }
    	        if (!sync && !queued)
    	            finish(null, self); // only once anyway
    	    }

    	    // Fetches a single file
    	    function fetch(filename, weak) {
    	        filename = getBundledFileName(filename) || filename;

    	        // Skip if already loaded / attempted
    	        if (self.files.indexOf(filename) > -1)
    	            return;
    	        self.files.push(filename);

    	        // Shortcut bundled definitions
    	        if (filename in common) {
    	            if (sync)
    	                process(filename, common[filename]);
    	            else {
    	                ++queued;
    	                setTimeout(function() {
    	                    --queued;
    	                    process(filename, common[filename]);
    	                });
    	            }
    	            return;
    	        }

    	        // Otherwise fetch from disk or network
    	        if (sync) {
    	            var source;
    	            try {
    	                source = util.fs.readFileSync(filename).toString("utf8");
    	            } catch (err) {
    	                if (!weak)
    	                    finish(err);
    	                return;
    	            }
    	            process(filename, source);
    	        } else {
    	            ++queued;
    	            self.fetch(filename, function(err, source) {
    	                --queued;
    	                /* istanbul ignore if */
    	                if (!callback)
    	                    return; // terminated meanwhile
    	                if (err) {
    	                    /* istanbul ignore else */
    	                    if (!weak)
    	                        finish(err);
    	                    else if (!queued) // can't be covered reliably
    	                        finish(null, self);
    	                    return;
    	                }
    	                process(filename, source);
    	            });
    	        }
    	    }
    	    var queued = 0;

    	    // Assembling the root namespace doesn't require working type
    	    // references anymore, so we can load everything in parallel
    	    if (util.isString(filename))
    	        filename = [ filename ];
    	    for (var i = 0, resolved; i < filename.length; ++i)
    	        if (resolved = self.resolvePath("", filename[i]))
    	            fetch(resolved);

    	    if (sync)
    	        return self;
    	    if (!queued)
    	        finish(null, self);
    	    return undefined;
    	};
    	// function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined

    	/**
    	 * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
    	 * @function Root#load
    	 * @param {string|string[]} filename Names of one or multiple files to load
    	 * @param {LoadCallback} callback Callback function
    	 * @returns {undefined}
    	 * @variation 2
    	 */
    	// function load(filename:string, callback:LoadCallback):undefined

    	/**
    	 * Loads one or multiple .proto or preprocessed .json files into this root namespace and returns a promise.
    	 * @function Root#load
    	 * @param {string|string[]} filename Names of one or multiple files to load
    	 * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
    	 * @returns {Promise<Root>} Promise
    	 * @variation 3
    	 */
    	// function load(filename:string, [options:IParseOptions]):Promise<Root>

    	/**
    	 * Synchronously loads one or multiple .proto or preprocessed .json files into this root namespace (node only).
    	 * @function Root#loadSync
    	 * @param {string|string[]} filename Names of one or multiple files to load
    	 * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
    	 * @returns {Root} Root namespace
    	 * @throws {Error} If synchronous fetching is not supported (i.e. in browsers) or if a file's syntax is invalid
    	 */
    	Root.prototype.loadSync = function loadSync(filename, options) {
    	    if (!util.isNode)
    	        throw Error("not supported");
    	    return this.load(filename, options, SYNC);
    	};

    	/**
    	 * @override
    	 */
    	Root.prototype.resolveAll = function resolveAll() {
    	    if (this.deferred.length)
    	        throw Error("unresolvable extensions: " + this.deferred.map(function(field) {
    	            return "'extend " + field.extend + "' in " + field.parent.fullName;
    	        }).join(", "));
    	    return Namespace.prototype.resolveAll.call(this);
    	};

    	// only uppercased (and thus conflict-free) children are exposed, see below
    	var exposeRe = /^[A-Z]/;

    	/**
    	 * Handles a deferred declaring extension field by creating a sister field to represent it within its extended type.
    	 * @param {Root} root Root instance
    	 * @param {Field} field Declaring extension field witin the declaring type
    	 * @returns {boolean} `true` if successfully added to the extended type, `false` otherwise
    	 * @inner
    	 * @ignore
    	 */
    	function tryHandleExtension(root, field) {
    	    var extendedType = field.parent.lookup(field.extend);
    	    if (extendedType) {
    	        var sisterField = new Field(field.fullName, field.id, field.type, field.rule, undefined, field.options);
    	        //do not allow to extend same field twice to prevent the error
    	        if (extendedType.get(sisterField.name)) {
    	            return true;
    	        }
    	        sisterField.declaringField = field;
    	        field.extensionField = sisterField;
    	        extendedType.add(sisterField);
    	        return true;
    	    }
    	    return false;
    	}

    	/**
    	 * Called when any object is added to this root or its sub-namespaces.
    	 * @param {ReflectionObject} object Object added
    	 * @returns {undefined}
    	 * @private
    	 */
    	Root.prototype._handleAdd = function _handleAdd(object) {
    	    if (object instanceof Field) {

    	        if (/* an extension field (implies not part of a oneof) */ object.extend !== undefined && /* not already handled */ !object.extensionField)
    	            if (!tryHandleExtension(this, object))
    	                this.deferred.push(object);

    	    } else if (object instanceof Enum) {

    	        if (exposeRe.test(object.name))
    	            object.parent[object.name] = object.values; // expose enum values as property of its parent

    	    } else if (!(object instanceof OneOf)) /* everything else is a namespace */ {

    	        if (object instanceof Type) // Try to handle any deferred extensions
    	            for (var i = 0; i < this.deferred.length;)
    	                if (tryHandleExtension(this, this.deferred[i]))
    	                    this.deferred.splice(i, 1);
    	                else
    	                    ++i;
    	        for (var j = 0; j < /* initializes */ object.nestedArray.length; ++j) // recurse into the namespace
    	            this._handleAdd(object._nestedArray[j]);
    	        if (exposeRe.test(object.name))
    	            object.parent[object.name] = object; // expose namespace as property of its parent
    	    }

    	    // The above also adds uppercased (and thus conflict-free) nested types, services and enums as
    	    // properties of namespaces just like static code does. This allows using a .d.ts generated for
    	    // a static module with reflection-based solutions where the condition is met.
    	};

    	/**
    	 * Called when any object is removed from this root or its sub-namespaces.
    	 * @param {ReflectionObject} object Object removed
    	 * @returns {undefined}
    	 * @private
    	 */
    	Root.prototype._handleRemove = function _handleRemove(object) {
    	    if (object instanceof Field) {

    	        if (/* an extension field */ object.extend !== undefined) {
    	            if (/* already handled */ object.extensionField) { // remove its sister field
    	                object.extensionField.parent.remove(object.extensionField);
    	                object.extensionField = null;
    	            } else { // cancel the extension
    	                var index = this.deferred.indexOf(object);
    	                /* istanbul ignore else */
    	                if (index > -1)
    	                    this.deferred.splice(index, 1);
    	            }
    	        }

    	    } else if (object instanceof Enum) {

    	        if (exposeRe.test(object.name))
    	            delete object.parent[object.name]; // unexpose enum values

    	    } else if (object instanceof Namespace) {

    	        for (var i = 0; i < /* initializes */ object.nestedArray.length; ++i) // recurse into the namespace
    	            this._handleRemove(object._nestedArray[i]);

    	        if (exposeRe.test(object.name))
    	            delete object.parent[object.name]; // unexpose namespaces

    	    }
    	};

    	// Sets up cyclic dependencies (called in index-light)
    	Root._configure = function(Type_, parse_, common_) {
    	    Type   = Type_;
    	    parse  = parse_;
    	    common = common_;
    	};
    	return root;
    }

    var util_1 = util$2.exports;

    var hasRequiredUtil;

    function requireUtil () {
    	if (hasRequiredUtil) return util$2.exports;
    	hasRequiredUtil = 1;
    	"use strict";

    	/**
    	 * Various utility functions.
    	 * @namespace
    	 */
    	var util = util$2.exports = requireMinimal();

    	var roots$1 = roots;

    	var Type, // cyclic
    	    Enum;

    	util.codegen = requireCodegen();
    	util.fetch   = requireFetch();
    	util.path    = requirePath();

    	/**
    	 * Node's fs module if available.
    	 * @type {Object.<string,*>}
    	 */
    	util.fs = util.inquire("fs");

    	/**
    	 * Converts an object's values to an array.
    	 * @param {Object.<string,*>} object Object to convert
    	 * @returns {Array.<*>} Converted array
    	 */
    	util.toArray = function toArray(object) {
    	    if (object) {
    	        var keys  = Object.keys(object),
    	            array = new Array(keys.length),
    	            index = 0;
    	        while (index < keys.length)
    	            array[index] = object[keys[index++]];
    	        return array;
    	    }
    	    return [];
    	};

    	/**
    	 * Converts an array of keys immediately followed by their respective value to an object, omitting undefined values.
    	 * @param {Array.<*>} array Array to convert
    	 * @returns {Object.<string,*>} Converted object
    	 */
    	util.toObject = function toObject(array) {
    	    var object = {},
    	        index  = 0;
    	    while (index < array.length) {
    	        var key = array[index++],
    	            val = array[index++];
    	        if (val !== undefined)
    	            object[key] = val;
    	    }
    	    return object;
    	};

    	var safePropBackslashRe = /\\/g,
    	    safePropQuoteRe     = /"/g;

    	/**
    	 * Tests whether the specified name is a reserved word in JS.
    	 * @param {string} name Name to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	util.isReserved = function isReserved(name) {
    	    return /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/.test(name);
    	};

    	/**
    	 * Returns a safe property accessor for the specified property name.
    	 * @param {string} prop Property name
    	 * @returns {string} Safe accessor
    	 */
    	util.safeProp = function safeProp(prop) {
    	    if (!/^[$\w_]+$/.test(prop) || util.isReserved(prop))
    	        return "[\"" + prop.replace(safePropBackslashRe, "\\\\").replace(safePropQuoteRe, "\\\"") + "\"]";
    	    return "." + prop;
    	};

    	/**
    	 * Converts the first character of a string to upper case.
    	 * @param {string} str String to convert
    	 * @returns {string} Converted string
    	 */
    	util.ucFirst = function ucFirst(str) {
    	    return str.charAt(0).toUpperCase() + str.substring(1);
    	};

    	var camelCaseRe = /_([a-z])/g;

    	/**
    	 * Converts a string to camel case.
    	 * @param {string} str String to convert
    	 * @returns {string} Converted string
    	 */
    	util.camelCase = function camelCase(str) {
    	    return str.substring(0, 1)
    	         + str.substring(1)
    	               .replace(camelCaseRe, function($0, $1) { return $1.toUpperCase(); });
    	};

    	/**
    	 * Compares reflected fields by id.
    	 * @param {Field} a First field
    	 * @param {Field} b Second field
    	 * @returns {number} Comparison value
    	 */
    	util.compareFieldsById = function compareFieldsById(a, b) {
    	    return a.id - b.id;
    	};

    	/**
    	 * Decorator helper for types (TypeScript).
    	 * @param {Constructor<T>} ctor Constructor function
    	 * @param {string} [typeName] Type name, defaults to the constructor's name
    	 * @returns {Type} Reflected type
    	 * @template T extends Message<T>
    	 * @property {Root} root Decorators root
    	 */
    	util.decorateType = function decorateType(ctor, typeName) {

    	    /* istanbul ignore if */
    	    if (ctor.$type) {
    	        if (typeName && ctor.$type.name !== typeName) {
    	            util.decorateRoot.remove(ctor.$type);
    	            ctor.$type.name = typeName;
    	            util.decorateRoot.add(ctor.$type);
    	        }
    	        return ctor.$type;
    	    }

    	    /* istanbul ignore next */
    	    if (!Type)
    	        Type = requireType();

    	    var type = new Type(typeName || ctor.name);
    	    util.decorateRoot.add(type);
    	    type.ctor = ctor; // sets up .encode, .decode etc.
    	    Object.defineProperty(ctor, "$type", { value: type, enumerable: false });
    	    Object.defineProperty(ctor.prototype, "$type", { value: type, enumerable: false });
    	    return type;
    	};

    	var decorateEnumIndex = 0;

    	/**
    	 * Decorator helper for enums (TypeScript).
    	 * @param {Object} object Enum object
    	 * @returns {Enum} Reflected enum
    	 */
    	util.decorateEnum = function decorateEnum(object) {

    	    /* istanbul ignore if */
    	    if (object.$type)
    	        return object.$type;

    	    /* istanbul ignore next */
    	    if (!Enum)
    	        Enum = require_enum();

    	    var enm = new Enum("Enum" + decorateEnumIndex++, object);
    	    util.decorateRoot.add(enm);
    	    Object.defineProperty(object, "$type", { value: enm, enumerable: false });
    	    return enm;
    	};


    	/**
    	 * Sets the value of a property by property path. If a value already exists, it is turned to an array
    	 * @param {Object.<string,*>} dst Destination object
    	 * @param {string} path dot '.' delimited path of the property to set
    	 * @param {Object} value the value to set
    	 * @returns {Object.<string,*>} Destination object
    	 */
    	util.setProperty = function setProperty(dst, path, value) {
    	    function setProp(dst, path, value) {
    	        var part = path.shift();
    	        if (part === "__proto__") {
    	          return dst;
    	        }
    	        if (path.length > 0) {
    	            dst[part] = setProp(dst[part] || {}, path, value);
    	        } else {
    	            var prevValue = dst[part];
    	            if (prevValue)
    	                value = [].concat(prevValue).concat(value);
    	            dst[part] = value;
    	        }
    	        return dst;
    	    }

    	    if (typeof dst !== "object")
    	        throw TypeError("dst must be an object");
    	    if (!path)
    	        throw TypeError("path must be specified");

    	    path = path.split(".");
    	    return setProp(dst, path, value);
    	};

    	/**
    	 * Decorator root (TypeScript).
    	 * @name util.decorateRoot
    	 * @type {Root}
    	 * @readonly
    	 */
    	Object.defineProperty(util, "decorateRoot", {
    	    get: function() {
    	        return roots$1["decorated"] || (roots$1["decorated"] = new (requireRoot())());
    	    }
    	});
    	return util$2.exports;
    }

    var object;
    var hasRequiredObject;

    function requireObject () {
    	if (hasRequiredObject) return object;
    	hasRequiredObject = 1;
    	"use strict";
    	object = ReflectionObject;

    	ReflectionObject.className = "ReflectionObject";

    	var util = requireUtil();

    	var Root; // cyclic

    	/**
    	 * Constructs a new reflection object instance.
    	 * @classdesc Base class of all reflection objects.
    	 * @constructor
    	 * @param {string} name Object name
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @abstract
    	 */
    	function ReflectionObject(name, options) {

    	    if (!util.isString(name))
    	        throw TypeError("name must be a string");

    	    if (options && !util.isObject(options))
    	        throw TypeError("options must be an object");

    	    /**
    	     * Options.
    	     * @type {Object.<string,*>|undefined}
    	     */
    	    this.options = options; // toJSON

    	    /**
    	     * Parsed Options.
    	     * @type {Array.<Object.<string,*>>|undefined}
    	     */
    	    this.parsedOptions = null;

    	    /**
    	     * Unique name within its namespace.
    	     * @type {string}
    	     */
    	    this.name = name;

    	    /**
    	     * Parent namespace.
    	     * @type {Namespace|null}
    	     */
    	    this.parent = null;

    	    /**
    	     * Whether already resolved or not.
    	     * @type {boolean}
    	     */
    	    this.resolved = false;

    	    /**
    	     * Comment text, if any.
    	     * @type {string|null}
    	     */
    	    this.comment = null;

    	    /**
    	     * Defining file name.
    	     * @type {string|null}
    	     */
    	    this.filename = null;
    	}

    	Object.defineProperties(ReflectionObject.prototype, {

    	    /**
    	     * Reference to the root namespace.
    	     * @name ReflectionObject#root
    	     * @type {Root}
    	     * @readonly
    	     */
    	    root: {
    	        get: function() {
    	            var ptr = this;
    	            while (ptr.parent !== null)
    	                ptr = ptr.parent;
    	            return ptr;
    	        }
    	    },

    	    /**
    	     * Full name including leading dot.
    	     * @name ReflectionObject#fullName
    	     * @type {string}
    	     * @readonly
    	     */
    	    fullName: {
    	        get: function() {
    	            var path = [ this.name ],
    	                ptr = this.parent;
    	            while (ptr) {
    	                path.unshift(ptr.name);
    	                ptr = ptr.parent;
    	            }
    	            return path.join(".");
    	        }
    	    }
    	});

    	/**
    	 * Converts this reflection object to its descriptor representation.
    	 * @returns {Object.<string,*>} Descriptor
    	 * @abstract
    	 */
    	ReflectionObject.prototype.toJSON = /* istanbul ignore next */ function toJSON() {
    	    throw Error(); // not implemented, shouldn't happen
    	};

    	/**
    	 * Called when this object is added to a parent.
    	 * @param {ReflectionObject} parent Parent added to
    	 * @returns {undefined}
    	 */
    	ReflectionObject.prototype.onAdd = function onAdd(parent) {
    	    if (this.parent && this.parent !== parent)
    	        this.parent.remove(this);
    	    this.parent = parent;
    	    this.resolved = false;
    	    var root = parent.root;
    	    if (root instanceof Root)
    	        root._handleAdd(this);
    	};

    	/**
    	 * Called when this object is removed from a parent.
    	 * @param {ReflectionObject} parent Parent removed from
    	 * @returns {undefined}
    	 */
    	ReflectionObject.prototype.onRemove = function onRemove(parent) {
    	    var root = parent.root;
    	    if (root instanceof Root)
    	        root._handleRemove(this);
    	    this.parent = null;
    	    this.resolved = false;
    	};

    	/**
    	 * Resolves this objects type references.
    	 * @returns {ReflectionObject} `this`
    	 */
    	ReflectionObject.prototype.resolve = function resolve() {
    	    if (this.resolved)
    	        return this;
    	    if (this.root instanceof Root)
    	        this.resolved = true; // only if part of a root
    	    return this;
    	};

    	/**
    	 * Gets an option value.
    	 * @param {string} name Option name
    	 * @returns {*} Option value or `undefined` if not set
    	 */
    	ReflectionObject.prototype.getOption = function getOption(name) {
    	    if (this.options)
    	        return this.options[name];
    	    return undefined;
    	};

    	/**
    	 * Sets an option.
    	 * @param {string} name Option name
    	 * @param {*} value Option value
    	 * @param {boolean} [ifNotSet] Sets the option only if it isn't currently set
    	 * @returns {ReflectionObject} `this`
    	 */
    	ReflectionObject.prototype.setOption = function setOption(name, value, ifNotSet) {
    	    if (!ifNotSet || !this.options || this.options[name] === undefined)
    	        (this.options || (this.options = {}))[name] = value;
    	    return this;
    	};

    	/**
    	 * Sets a parsed option.
    	 * @param {string} name parsed Option name
    	 * @param {*} value Option value
    	 * @param {string} propName dot '.' delimited full path of property within the option to set. if undefined\empty, will add a new option with that value
    	 * @returns {ReflectionObject} `this`
    	 */
    	ReflectionObject.prototype.setParsedOption = function setParsedOption(name, value, propName) {
    	    if (!this.parsedOptions) {
    	        this.parsedOptions = [];
    	    }
    	    var parsedOptions = this.parsedOptions;
    	    if (propName) {
    	        // If setting a sub property of an option then try to merge it
    	        // with an existing option
    	        var opt = parsedOptions.find(function (opt) {
    	            return Object.prototype.hasOwnProperty.call(opt, name);
    	        });
    	        if (opt) {
    	            // If we found an existing option - just merge the property value
    	            var newValue = opt[name];
    	            util.setProperty(newValue, propName, value);
    	        } else {
    	            // otherwise, create a new option, set it's property and add it to the list
    	            opt = {};
    	            opt[name] = util.setProperty({}, propName, value);
    	            parsedOptions.push(opt);
    	        }
    	    } else {
    	        // Always create a new option when setting the value of the option itself
    	        var newOpt = {};
    	        newOpt[name] = value;
    	        parsedOptions.push(newOpt);
    	    }
    	    return this;
    	};

    	/**
    	 * Sets multiple options.
    	 * @param {Object.<string,*>} options Options to set
    	 * @param {boolean} [ifNotSet] Sets an option only if it isn't currently set
    	 * @returns {ReflectionObject} `this`
    	 */
    	ReflectionObject.prototype.setOptions = function setOptions(options, ifNotSet) {
    	    if (options)
    	        for (var keys = Object.keys(options), i = 0; i < keys.length; ++i)
    	            this.setOption(keys[i], options[keys[i]], ifNotSet);
    	    return this;
    	};

    	/**
    	 * Converts this instance to its string representation.
    	 * @returns {string} Class name[, space, full name]
    	 */
    	ReflectionObject.prototype.toString = function toString() {
    	    var className = this.constructor.className,
    	        fullName  = this.fullName;
    	    if (fullName.length)
    	        return className + " " + fullName;
    	    return className;
    	};

    	// Sets up cyclic dependencies (called in index-light)
    	ReflectionObject._configure = function(Root_) {
    	    Root = Root_;
    	};
    	return object;
    }

    var _enum;
    var hasRequired_enum;

    function require_enum () {
    	if (hasRequired_enum) return _enum;
    	hasRequired_enum = 1;
    	"use strict";
    	_enum = Enum;

    	// extends ReflectionObject
    	var ReflectionObject = requireObject();
    	((Enum.prototype = Object.create(ReflectionObject.prototype)).constructor = Enum).className = "Enum";

    	var Namespace = requireNamespace(),
    	    util = requireUtil();

    	/**
    	 * Constructs a new enum instance.
    	 * @classdesc Reflected enum.
    	 * @extends ReflectionObject
    	 * @constructor
    	 * @param {string} name Unique name within its namespace
    	 * @param {Object.<string,number>} [values] Enum values as an object, by name
    	 * @param {Object.<string,*>} [options] Declared options
    	 * @param {string} [comment] The comment for this enum
    	 * @param {Object.<string,string>} [comments] The value comments for this enum
    	 * @param {Object.<string,Object<string,*>>|undefined} [valuesOptions] The value options for this enum
    	 */
    	function Enum(name, values, options, comment, comments, valuesOptions) {
    	    ReflectionObject.call(this, name, options);

    	    if (values && typeof values !== "object")
    	        throw TypeError("values must be an object");

    	    /**
    	     * Enum values by id.
    	     * @type {Object.<number,string>}
    	     */
    	    this.valuesById = {};

    	    /**
    	     * Enum values by name.
    	     * @type {Object.<string,number>}
    	     */
    	    this.values = Object.create(this.valuesById); // toJSON, marker

    	    /**
    	     * Enum comment text.
    	     * @type {string|null}
    	     */
    	    this.comment = comment;

    	    /**
    	     * Value comment texts, if any.
    	     * @type {Object.<string,string>}
    	     */
    	    this.comments = comments || {};

    	    /**
    	     * Values options, if any
    	     * @type {Object<string, Object<string, *>>|undefined}
    	     */
    	    this.valuesOptions = valuesOptions;

    	    /**
    	     * Reserved ranges, if any.
    	     * @type {Array.<number[]|string>}
    	     */
    	    this.reserved = undefined; // toJSON

    	    // Note that values inherit valuesById on their prototype which makes them a TypeScript-
    	    // compatible enum. This is used by pbts to write actual enum definitions that work for
    	    // static and reflection code alike instead of emitting generic object definitions.

    	    if (values)
    	        for (var keys = Object.keys(values), i = 0; i < keys.length; ++i)
    	            if (typeof values[keys[i]] === "number") // use forward entries only
    	                this.valuesById[ this.values[keys[i]] = values[keys[i]] ] = keys[i];
    	}

    	/**
    	 * Enum descriptor.
    	 * @interface IEnum
    	 * @property {Object.<string,number>} values Enum values
    	 * @property {Object.<string,*>} [options] Enum options
    	 */

    	/**
    	 * Constructs an enum from an enum descriptor.
    	 * @param {string} name Enum name
    	 * @param {IEnum} json Enum descriptor
    	 * @returns {Enum} Created enum
    	 * @throws {TypeError} If arguments are invalid
    	 */
    	Enum.fromJSON = function fromJSON(name, json) {
    	    var enm = new Enum(name, json.values, json.options, json.comment, json.comments);
    	    enm.reserved = json.reserved;
    	    return enm;
    	};

    	/**
    	 * Converts this enum to an enum descriptor.
    	 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
    	 * @returns {IEnum} Enum descriptor
    	 */
    	Enum.prototype.toJSON = function toJSON(toJSONOptions) {
    	    var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
    	    return util.toObject([
    	        "options"       , this.options,
    	        "valuesOptions" , this.valuesOptions,
    	        "values"        , this.values,
    	        "reserved"      , this.reserved && this.reserved.length ? this.reserved : undefined,
    	        "comment"       , keepComments ? this.comment : undefined,
    	        "comments"      , keepComments ? this.comments : undefined
    	    ]);
    	};

    	/**
    	 * Adds a value to this enum.
    	 * @param {string} name Value name
    	 * @param {number} id Value id
    	 * @param {string} [comment] Comment, if any
    	 * @param {Object.<string, *>|undefined} [options] Options, if any
    	 * @returns {Enum} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If there is already a value with this name or id
    	 */
    	Enum.prototype.add = function add(name, id, comment, options) {
    	    // utilized by the parser but not by .fromJSON

    	    if (!util.isString(name))
    	        throw TypeError("name must be a string");

    	    if (!util.isInteger(id))
    	        throw TypeError("id must be an integer");

    	    if (this.values[name] !== undefined)
    	        throw Error("duplicate name '" + name + "' in " + this);

    	    if (this.isReservedId(id))
    	        throw Error("id " + id + " is reserved in " + this);

    	    if (this.isReservedName(name))
    	        throw Error("name '" + name + "' is reserved in " + this);

    	    if (this.valuesById[id] !== undefined) {
    	        if (!(this.options && this.options.allow_alias))
    	            throw Error("duplicate id " + id + " in " + this);
    	        this.values[name] = id;
    	    } else
    	        this.valuesById[this.values[name] = id] = name;

    	    if (options) {
    	        if (this.valuesOptions === undefined)
    	            this.valuesOptions = {};
    	        this.valuesOptions[name] = options || null;
    	    }

    	    this.comments[name] = comment || null;
    	    return this;
    	};

    	/**
    	 * Removes a value from this enum
    	 * @param {string} name Value name
    	 * @returns {Enum} `this`
    	 * @throws {TypeError} If arguments are invalid
    	 * @throws {Error} If `name` is not a name of this enum
    	 */
    	Enum.prototype.remove = function remove(name) {

    	    if (!util.isString(name))
    	        throw TypeError("name must be a string");

    	    var val = this.values[name];
    	    if (val == null)
    	        throw Error("name '" + name + "' does not exist in " + this);

    	    delete this.valuesById[val];
    	    delete this.values[name];
    	    delete this.comments[name];
    	    if (this.valuesOptions)
    	        delete this.valuesOptions[name];

    	    return this;
    	};

    	/**
    	 * Tests if the specified id is reserved.
    	 * @param {number} id Id to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Enum.prototype.isReservedId = function isReservedId(id) {
    	    return Namespace.isReservedId(this.reserved, id);
    	};

    	/**
    	 * Tests if the specified name is reserved.
    	 * @param {string} name Name to test
    	 * @returns {boolean} `true` if reserved, otherwise `false`
    	 */
    	Enum.prototype.isReservedName = function isReservedName(name) {
    	    return Namespace.isReservedName(this.reserved, name);
    	};
    	return _enum;
    }

    var encoder_1;
    var hasRequiredEncoder;

    function requireEncoder () {
    	if (hasRequiredEncoder) return encoder_1;
    	hasRequiredEncoder = 1;
    	"use strict";
    	encoder_1 = encoder;

    	var Enum     = require_enum(),
    	    types    = requireTypes(),
    	    util     = requireUtil();

    	/**
    	 * Generates a partial message type encoder.
    	 * @param {Codegen} gen Codegen instance
    	 * @param {Field} field Reflected field
    	 * @param {number} fieldIndex Field index
    	 * @param {string} ref Variable reference
    	 * @returns {Codegen} Codegen instance
    	 * @ignore
    	 */
    	function genTypePartial(gen, field, fieldIndex, ref) {
    	    return field.resolvedType.group
    	        ? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
    	        : gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
    	}

    	/**
    	 * Generates an encoder specific to the specified message type.
    	 * @param {Type} mtype Message type
    	 * @returns {Codegen} Codegen instance
    	 */
    	function encoder(mtype) {
    	    /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
    	    var gen = util.codegen(["m", "w"], mtype.name + "$encode")
    	    ("if(!w)")
    	        ("w=Writer.create()");

    	    var i, ref;

    	    // "when a message is serialized its known fields should be written sequentially by field number"
    	    var fields = /* initializes */ mtype.fieldsArray.slice().sort(util.compareFieldsById);

    	    for (var i = 0; i < fields.length; ++i) {
    	        var field    = fields[i].resolve(),
    	            index    = mtype._fieldsArray.indexOf(field),
    	            type     = field.resolvedType instanceof Enum ? "int32" : field.type,
    	            wireType = types.basic[type];
    	            ref      = "m" + util.safeProp(field.name);

    	        // Map fields
    	        if (field.map) {
    	            gen
    	    ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)){", ref, field.name) // !== undefined && !== null
    	        ("for(var ks=Object.keys(%s),i=0;i<ks.length;++i){", ref)
    	            ("w.uint32(%i).fork().uint32(%i).%s(ks[i])", (field.id << 3 | 2) >>> 0, 8 | types.mapKey[field.keyType], field.keyType);
    	            if (wireType === undefined) gen
    	            ("types[%i].encode(%s[ks[i]],w.uint32(18).fork()).ldelim().ldelim()", index, ref); // can't be groups
    	            else gen
    	            (".uint32(%i).%s(%s[ks[i]]).ldelim()", 16 | wireType, type, ref);
    	            gen
    	        ("}")
    	    ("}");

    	            // Repeated fields
    	        } else if (field.repeated) { gen
    	    ("if(%s!=null&&%s.length){", ref, ref); // !== undefined && !== null

    	            // Packed repeated
    	            if (field.packed && types.packed[type] !== undefined) { gen

    	        ("w.uint32(%i).fork()", (field.id << 3 | 2) >>> 0)
    	        ("for(var i=0;i<%s.length;++i)", ref)
    	            ("w.%s(%s[i])", type, ref)
    	        ("w.ldelim()");

    	            // Non-packed
    	            } else { gen

    	        ("for(var i=0;i<%s.length;++i)", ref);
    	                if (wireType === undefined)
    	            genTypePartial(gen, field, index, ref + "[i]");
    	                else gen
    	            ("w.uint32(%i).%s(%s[i])", (field.id << 3 | wireType) >>> 0, type, ref);

    	            } gen
    	    ("}");

    	        // Non-repeated
    	        } else {
    	            if (field.optional) gen
    	    ("if(%s!=null&&Object.hasOwnProperty.call(m,%j))", ref, field.name); // !== undefined && !== null

    	            if (wireType === undefined)
    	        genTypePartial(gen, field, index, ref);
    	            else gen
    	        ("w.uint32(%i).%s(%s)", (field.id << 3 | wireType) >>> 0, type, ref);

    	        }
    	    }

    	    return gen
    	    ("return w");
    	    /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
    	}
    	return encoder_1;
    }

    var indexLight = indexLight$2.exports;

    "use strict";
    var protobuf$1 = indexLight$2.exports = indexMinimal$1;

    protobuf$1.build = "light";

    /**
     * A node-style callback as used by {@link load} and {@link Root#load}.
     * @typedef LoadCallback
     * @type {function}
     * @param {Error|null} error Error, if any, otherwise `null`
     * @param {Root} [root] Root, if there hasn't been an error
     * @returns {undefined}
     */

    /**
     * Loads one or multiple .proto or preprocessed .json files into a common root namespace and calls the callback.
     * @param {string|string[]} filename One or multiple files to load
     * @param {Root} root Root namespace, defaults to create a new one if omitted.
     * @param {LoadCallback} callback Callback function
     * @returns {undefined}
     * @see {@link Root#load}
     */
    function load(filename, root, callback) {
        if (typeof root === "function") {
            callback = root;
            root = new protobuf$1.Root();
        } else if (!root)
            root = new protobuf$1.Root();
        return root.load(filename, callback);
    }

    /**
     * Loads one or multiple .proto or preprocessed .json files into a common root namespace and calls the callback.
     * @name load
     * @function
     * @param {string|string[]} filename One or multiple files to load
     * @param {LoadCallback} callback Callback function
     * @returns {undefined}
     * @see {@link Root#load}
     * @variation 2
     */
    // function load(filename:string, callback:LoadCallback):undefined

    /**
     * Loads one or multiple .proto or preprocessed .json files into a common root namespace and returns a promise.
     * @name load
     * @function
     * @param {string|string[]} filename One or multiple files to load
     * @param {Root} [root] Root namespace, defaults to create a new one if omitted.
     * @returns {Promise<Root>} Promise
     * @see {@link Root#load}
     * @variation 3
     */
    // function load(filename:string, [root:Root]):Promise<Root>

    protobuf$1.load = load;

    /**
     * Synchronously loads one or multiple .proto or preprocessed .json files into a common root namespace (node only).
     * @param {string|string[]} filename One or multiple files to load
     * @param {Root} [root] Root namespace, defaults to create a new one if omitted.
     * @returns {Root} Root namespace
     * @throws {Error} If synchronous fetching is not supported (i.e. in browsers) or if a file's syntax is invalid
     * @see {@link Root#loadSync}
     */
    function loadSync(filename, root) {
        if (!root)
            root = new protobuf$1.Root();
        return root.loadSync(filename);
    }

    protobuf$1.loadSync = loadSync;

    // Serialization
    protobuf$1.encoder          = requireEncoder();
    protobuf$1.decoder          = requireDecoder();
    protobuf$1.verifier         = requireVerifier();
    protobuf$1.converter        = requireConverter();

    // Reflection
    protobuf$1.ReflectionObject = requireObject();
    protobuf$1.Namespace        = requireNamespace();
    protobuf$1.Root             = requireRoot();
    protobuf$1.Enum             = require_enum();
    protobuf$1.Type             = requireType();
    protobuf$1.Field            = requireField();
    protobuf$1.OneOf            = requireOneof();
    protobuf$1.MapField         = requireMapfield();
    protobuf$1.Service          = requireService();
    protobuf$1.Method           = requireMethod();

    // Runtime
    protobuf$1.Message          = message$1;
    protobuf$1.wrappers         = wrappers$1;

    // Utility
    protobuf$1.types            = requireTypes();
    protobuf$1.util             = requireUtil();

    // Set up possibly cyclic reflection dependencies
    protobuf$1.ReflectionObject._configure(protobuf$1.Root);
    protobuf$1.Namespace._configure(protobuf$1.Type, protobuf$1.Service, protobuf$1.Enum);
    protobuf$1.Root._configure(protobuf$1.Type);
    protobuf$1.Field._configure(protobuf$1.Type);

    var indexLightExports = indexLight$2.exports;
    const indexLight$1 = /*@__PURE__*/getDefaultExportFromCjs(indexLightExports);

    "use strict";
    var tokenize_1 = tokenize$1;

    var delimRe        = /[\s{}=;:[\],'"()<>]/g,
        stringDoubleRe = /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
        stringSingleRe = /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g;

    var setCommentRe = /^ *[*/]+ */,
        setCommentAltRe = /^\s*\*?\/*/,
        setCommentSplitRe = /\n/g,
        whitespaceRe = /\s/,
        unescapeRe = /\\(.?)/g;

    var unescapeMap = {
        "0": "\0",
        "r": "\r",
        "n": "\n",
        "t": "\t"
    };

    /**
     * Unescapes a string.
     * @param {string} str String to unescape
     * @returns {string} Unescaped string
     * @property {Object.<string,string>} map Special characters map
     * @memberof tokenize
     */
    function unescape(str) {
        return str.replace(unescapeRe, function($0, $1) {
            switch ($1) {
                case "\\":
                case "":
                    return $1;
                default:
                    return unescapeMap[$1] || "";
            }
        });
    }

    tokenize$1.unescape = unescape;

    /**
     * Gets the next token and advances.
     * @typedef TokenizerHandleNext
     * @type {function}
     * @returns {string|null} Next token or `null` on eof
     */

    /**
     * Peeks for the next token.
     * @typedef TokenizerHandlePeek
     * @type {function}
     * @returns {string|null} Next token or `null` on eof
     */

    /**
     * Pushes a token back to the stack.
     * @typedef TokenizerHandlePush
     * @type {function}
     * @param {string} token Token
     * @returns {undefined}
     */

    /**
     * Skips the next token.
     * @typedef TokenizerHandleSkip
     * @type {function}
     * @param {string} expected Expected token
     * @param {boolean} [optional=false] If optional
     * @returns {boolean} Whether the token matched
     * @throws {Error} If the token didn't match and is not optional
     */

    /**
     * Gets the comment on the previous line or, alternatively, the line comment on the specified line.
     * @typedef TokenizerHandleCmnt
     * @type {function}
     * @param {number} [line] Line number
     * @returns {string|null} Comment text or `null` if none
     */

    /**
     * Handle object returned from {@link tokenize}.
     * @interface ITokenizerHandle
     * @property {TokenizerHandleNext} next Gets the next token and advances (`null` on eof)
     * @property {TokenizerHandlePeek} peek Peeks for the next token (`null` on eof)
     * @property {TokenizerHandlePush} push Pushes a token back to the stack
     * @property {TokenizerHandleSkip} skip Skips a token, returns its presence and advances or, if non-optional and not present, throws
     * @property {TokenizerHandleCmnt} cmnt Gets the comment on the previous line or the line comment on the specified line, if any
     * @property {number} line Current line number
     */

    /**
     * Tokenizes the given .proto source and returns an object with useful utility functions.
     * @param {string} source Source contents
     * @param {boolean} alternateCommentMode Whether we should activate alternate comment parsing mode.
     * @returns {ITokenizerHandle} Tokenizer handle
     */
    function tokenize$1(source, alternateCommentMode) {
        /* eslint-disable callback-return */
        source = source.toString();

        var offset = 0,
            length = source.length,
            line = 1,
            lastCommentLine = 0,
            comments = {};

        var stack = [];

        var stringDelim = null;

        /* istanbul ignore next */
        /**
         * Creates an error for illegal syntax.
         * @param {string} subject Subject
         * @returns {Error} Error created
         * @inner
         */
        function illegal(subject) {
            return Error("illegal " + subject + " (line " + line + ")");
        }

        /**
         * Reads a string till its end.
         * @returns {string} String read
         * @inner
         */
        function readString() {
            var re = stringDelim === "'" ? stringSingleRe : stringDoubleRe;
            re.lastIndex = offset - 1;
            var match = re.exec(source);
            if (!match)
                throw illegal("string");
            offset = re.lastIndex;
            push(stringDelim);
            stringDelim = null;
            return unescape(match[1]);
        }

        /**
         * Gets the character at `pos` within the source.
         * @param {number} pos Position
         * @returns {string} Character
         * @inner
         */
        function charAt(pos) {
            return source.charAt(pos);
        }

        /**
         * Sets the current comment text.
         * @param {number} start Start offset
         * @param {number} end End offset
         * @param {boolean} isLeading set if a leading comment
         * @returns {undefined}
         * @inner
         */
        function setComment(start, end, isLeading) {
            var comment = {
                type: source.charAt(start++),
                lineEmpty: false,
                leading: isLeading,
            };
            var lookback;
            if (alternateCommentMode) {
                lookback = 2;  // alternate comment parsing: "//" or "/*"
            } else {
                lookback = 3;  // "///" or "/**"
            }
            var commentOffset = start - lookback,
                c;
            do {
                if (--commentOffset < 0 ||
                        (c = source.charAt(commentOffset)) === "\n") {
                    comment.lineEmpty = true;
                    break;
                }
            } while (c === " " || c === "\t");
            var lines = source
                .substring(start, end)
                .split(setCommentSplitRe);
            for (var i = 0; i < lines.length; ++i)
                lines[i] = lines[i]
                    .replace(alternateCommentMode ? setCommentAltRe : setCommentRe, "")
                    .trim();
            comment.text = lines
                .join("\n")
                .trim();

            comments[line] = comment;
            lastCommentLine = line;
        }

        function isDoubleSlashCommentLine(startOffset) {
            var endOffset = findEndOfLine(startOffset);

            // see if remaining line matches comment pattern
            var lineText = source.substring(startOffset, endOffset);
            // look for 1 or 2 slashes since startOffset would already point past
            // the first slash that started the comment.
            var isComment = /^\s*\/{1,2}/.test(lineText);
            return isComment;
        }

        function findEndOfLine(cursor) {
            // find end of cursor's line
            var endOffset = cursor;
            while (endOffset < length && charAt(endOffset) !== "\n") {
                endOffset++;
            }
            return endOffset;
        }

        /**
         * Obtains the next token.
         * @returns {string|null} Next token or `null` on eof
         * @inner
         */
        function next() {
            if (stack.length > 0)
                return stack.shift();
            if (stringDelim)
                return readString();
            var repeat,
                prev,
                curr,
                start,
                isDoc,
                isLeadingComment = offset === 0;
            do {
                if (offset === length)
                    return null;
                repeat = false;
                while (whitespaceRe.test(curr = charAt(offset))) {
                    if (curr === "\n") {
                        isLeadingComment = true;
                        ++line;
                    }
                    if (++offset === length)
                        return null;
                }

                if (charAt(offset) === "/") {
                    if (++offset === length) {
                        throw illegal("comment");
                    }
                    if (charAt(offset) === "/") { // Line
                        if (!alternateCommentMode) {
                            // check for triple-slash comment
                            isDoc = charAt(start = offset + 1) === "/";

                            while (charAt(++offset) !== "\n") {
                                if (offset === length) {
                                    return null;
                                }
                            }
                            ++offset;
                            if (isDoc) {
                                setComment(start, offset - 1, isLeadingComment);
                                // Trailing comment cannot not be multi-line,
                                // so leading comment state should be reset to handle potential next comments
                                isLeadingComment = true;
                            }
                            ++line;
                            repeat = true;
                        } else {
                            // check for double-slash comments, consolidating consecutive lines
                            start = offset;
                            isDoc = false;
                            if (isDoubleSlashCommentLine(offset)) {
                                isDoc = true;
                                do {
                                    offset = findEndOfLine(offset);
                                    if (offset === length) {
                                        break;
                                    }
                                    offset++;
                                    if (!isLeadingComment) {
                                        // Trailing comment cannot not be multi-line
                                        break;
                                    }
                                } while (isDoubleSlashCommentLine(offset));
                            } else {
                                offset = Math.min(length, findEndOfLine(offset) + 1);
                            }
                            if (isDoc) {
                                setComment(start, offset, isLeadingComment);
                                isLeadingComment = true;
                            }
                            line++;
                            repeat = true;
                        }
                    } else if ((curr = charAt(offset)) === "*") { /* Block */
                        // check for /** (regular comment mode) or /* (alternate comment mode)
                        start = offset + 1;
                        isDoc = alternateCommentMode || charAt(start) === "*";
                        do {
                            if (curr === "\n") {
                                ++line;
                            }
                            if (++offset === length) {
                                throw illegal("comment");
                            }
                            prev = curr;
                            curr = charAt(offset);
                        } while (prev !== "*" || curr !== "/");
                        ++offset;
                        if (isDoc) {
                            setComment(start, offset - 2, isLeadingComment);
                            isLeadingComment = true;
                        }
                        repeat = true;
                    } else {
                        return "/";
                    }
                }
            } while (repeat);

            // offset !== length if we got here

            var end = offset;
            delimRe.lastIndex = 0;
            var delim = delimRe.test(charAt(end++));
            if (!delim)
                while (end < length && !delimRe.test(charAt(end)))
                    ++end;
            var token = source.substring(offset, offset = end);
            if (token === "\"" || token === "'")
                stringDelim = token;
            return token;
        }

        /**
         * Pushes a token back to the stack.
         * @param {string} token Token
         * @returns {undefined}
         * @inner
         */
        function push(token) {
            stack.push(token);
        }

        /**
         * Peeks for the next token.
         * @returns {string|null} Token or `null` on eof
         * @inner
         */
        function peek() {
            if (!stack.length) {
                var token = next();
                if (token === null)
                    return null;
                push(token);
            }
            return stack[0];
        }

        /**
         * Skips a token.
         * @param {string} expected Expected token
         * @param {boolean} [optional=false] Whether the token is optional
         * @returns {boolean} `true` when skipped, `false` if not
         * @throws {Error} When a required token is not present
         * @inner
         */
        function skip(expected, optional) {
            var actual = peek(),
                equals = actual === expected;
            if (equals) {
                next();
                return true;
            }
            if (!optional)
                throw illegal("token '" + actual + "', '" + expected + "' expected");
            return false;
        }

        /**
         * Gets a comment.
         * @param {number} [trailingLine] Line number if looking for a trailing comment
         * @returns {string|null} Comment text
         * @inner
         */
        function cmnt(trailingLine) {
            var ret = null;
            var comment;
            if (trailingLine === undefined) {
                comment = comments[line - 1];
                delete comments[line - 1];
                if (comment && (alternateCommentMode || comment.type === "*" || comment.lineEmpty)) {
                    ret = comment.leading ? comment.text : null;
                }
            } else {
                /* istanbul ignore else */
                if (lastCommentLine < trailingLine) {
                    peek();
                }
                comment = comments[trailingLine];
                delete comments[trailingLine];
                if (comment && !comment.lineEmpty && (alternateCommentMode || comment.type === "/")) {
                    ret = comment.leading ? null : comment.text;
                }
            }
            return ret;
        }

        return Object.defineProperty({
            next: next,
            peek: peek,
            push: push,
            skip: skip,
            cmnt: cmnt
        }, "line", {
            get: function() { return line; }
        });
        /* eslint-enable callback-return */
    }

    const tokenize$2 = /*@__PURE__*/getDefaultExportFromCjs(tokenize_1);

    "use strict";
    var parse_1 = parse;

    parse.filename = null;
    parse.defaults = { keepCase: false };

    var tokenize  = tokenize_1,
        Root      = requireRoot(),
        Type      = requireType(),
        Field     = requireField(),
        MapField  = requireMapfield(),
        OneOf     = requireOneof(),
        Enum      = require_enum(),
        Service   = requireService(),
        Method    = requireMethod(),
        types     = requireTypes(),
        util      = requireUtil();

    var base10Re    = /^[1-9][0-9]*$/,
        base10NegRe = /^-?[1-9][0-9]*$/,
        base16Re    = /^0[x][0-9a-fA-F]+$/,
        base16NegRe = /^-?0[x][0-9a-fA-F]+$/,
        base8Re     = /^0[0-7]+$/,
        base8NegRe  = /^-?0[0-7]+$/,
        numberRe    = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,
        nameRe      = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
        typeRefRe   = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
        fqTypeRefRe = /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/;

    /**
     * Result object returned from {@link parse}.
     * @interface IParserResult
     * @property {string|undefined} package Package name, if declared
     * @property {string[]|undefined} imports Imports, if any
     * @property {string[]|undefined} weakImports Weak imports, if any
     * @property {string|undefined} syntax Syntax, if specified (either `"proto2"` or `"proto3"`)
     * @property {Root} root Populated root instance
     */

    /**
     * Options modifying the behavior of {@link parse}.
     * @interface IParseOptions
     * @property {boolean} [keepCase=false] Keeps field casing instead of converting to camel case
     * @property {boolean} [alternateCommentMode=false] Recognize double-slash comments in addition to doc-block comments.
     * @property {boolean} [preferTrailingComment=false] Use trailing comment when both leading comment and trailing comment exist.
     */

    /**
     * Options modifying the behavior of JSON serialization.
     * @interface IToJSONOptions
     * @property {boolean} [keepComments=false] Serializes comments.
     */

    /**
     * Parses the given .proto source and returns an object with the parsed contents.
     * @param {string} source Source contents
     * @param {Root} root Root to populate
     * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
     * @returns {IParserResult} Parser result
     * @property {string} filename=null Currently processing file name for error reporting, if known
     * @property {IParseOptions} defaults Default {@link IParseOptions}
     */
    function parse(source, root, options) {
        /* eslint-disable callback-return */
        if (!(root instanceof Root)) {
            options = root;
            root = new Root();
        }
        if (!options)
            options = parse.defaults;

        var preferTrailingComment = options.preferTrailingComment || false;
        var tn = tokenize(source, options.alternateCommentMode || false),
            next = tn.next,
            push = tn.push,
            peek = tn.peek,
            skip = tn.skip,
            cmnt = tn.cmnt;

        var head = true,
            pkg,
            imports,
            weakImports,
            syntax,
            isProto3 = false;

        var ptr = root;

        var applyCase = options.keepCase ? function(name) { return name; } : util.camelCase;

        /* istanbul ignore next */
        function illegal(token, name, insideTryCatch) {
            var filename = parse.filename;
            if (!insideTryCatch)
                parse.filename = null;
            return Error("illegal " + (name || "token") + " '" + token + "' (" + (filename ? filename + ", " : "") + "line " + tn.line + ")");
        }

        function readString() {
            var values = [],
                token;
            do {
                /* istanbul ignore if */
                if ((token = next()) !== "\"" && token !== "'")
                    throw illegal(token);

                values.push(next());
                skip(token);
                token = peek();
            } while (token === "\"" || token === "'");
            return values.join("");
        }

        function readValue(acceptTypeRef) {
            var token = next();
            switch (token) {
                case "'":
                case "\"":
                    push(token);
                    return readString();
                case "true": case "TRUE":
                    return true;
                case "false": case "FALSE":
                    return false;
            }
            try {
                return parseNumber(token, /* insideTryCatch */ true);
            } catch (e) {

                /* istanbul ignore else */
                if (acceptTypeRef && typeRefRe.test(token))
                    return token;

                /* istanbul ignore next */
                throw illegal(token, "value");
            }
        }

        function readRanges(target, acceptStrings) {
            var token, start;
            do {
                if (acceptStrings && ((token = peek()) === "\"" || token === "'"))
                    target.push(readString());
                else
                    target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
            } while (skip(",", true));
            skip(";");
        }

        function parseNumber(token, insideTryCatch) {
            var sign = 1;
            if (token.charAt(0) === "-") {
                sign = -1;
                token = token.substring(1);
            }
            switch (token) {
                case "inf": case "INF": case "Inf":
                    return sign * Infinity;
                case "nan": case "NAN": case "Nan": case "NaN":
                    return NaN;
                case "0":
                    return 0;
            }
            if (base10Re.test(token))
                return sign * parseInt(token, 10);
            if (base16Re.test(token))
                return sign * parseInt(token, 16);
            if (base8Re.test(token))
                return sign * parseInt(token, 8);

            /* istanbul ignore else */
            if (numberRe.test(token))
                return sign * parseFloat(token);

            /* istanbul ignore next */
            throw illegal(token, "number", insideTryCatch);
        }

        function parseId(token, acceptNegative) {
            switch (token) {
                case "max": case "MAX": case "Max":
                    return 536870911;
                case "0":
                    return 0;
            }

            /* istanbul ignore if */
            if (!acceptNegative && token.charAt(0) === "-")
                throw illegal(token, "id");

            if (base10NegRe.test(token))
                return parseInt(token, 10);
            if (base16NegRe.test(token))
                return parseInt(token, 16);

            /* istanbul ignore else */
            if (base8NegRe.test(token))
                return parseInt(token, 8);

            /* istanbul ignore next */
            throw illegal(token, "id");
        }

        function parsePackage() {

            /* istanbul ignore if */
            if (pkg !== undefined)
                throw illegal("package");

            pkg = next();

            /* istanbul ignore if */
            if (!typeRefRe.test(pkg))
                throw illegal(pkg, "name");

            ptr = ptr.define(pkg);
            skip(";");
        }

        function parseImport() {
            var token = peek();
            var whichImports;
            switch (token) {
                case "weak":
                    whichImports = weakImports || (weakImports = []);
                    next();
                    break;
                case "public":
                    next();
                    // eslint-disable-line no-fallthrough
                default:
                    whichImports = imports || (imports = []);
                    break;
            }
            token = readString();
            skip(";");
            whichImports.push(token);
        }

        function parseSyntax() {
            skip("=");
            syntax = readString();
            isProto3 = syntax === "proto3";

            /* istanbul ignore if */
            if (!isProto3 && syntax !== "proto2")
                throw illegal(syntax, "syntax");

            skip(";");
        }

        function parseCommon(parent, token) {
            switch (token) {

                case "option":
                    parseOption(parent, token);
                    skip(";");
                    return true;

                case "message":
                    parseType(parent, token);
                    return true;

                case "enum":
                    parseEnum(parent, token);
                    return true;

                case "service":
                    parseService(parent, token);
                    return true;

                case "extend":
                    parseExtension(parent, token);
                    return true;
            }
            return false;
        }

        function ifBlock(obj, fnIf, fnElse) {
            var trailingLine = tn.line;
            if (obj) {
                if(typeof obj.comment !== "string") {
                  obj.comment = cmnt(); // try block-type comment
                }
                obj.filename = parse.filename;
            }
            if (skip("{", true)) {
                var token;
                while ((token = next()) !== "}")
                    fnIf(token);
                skip(";", true);
            } else {
                if (fnElse)
                    fnElse();
                skip(";");
                if (obj && (typeof obj.comment !== "string" || preferTrailingComment))
                    obj.comment = cmnt(trailingLine) || obj.comment; // try line-type comment
            }
        }

        function parseType(parent, token) {

            /* istanbul ignore if */
            if (!nameRe.test(token = next()))
                throw illegal(token, "type name");

            var type = new Type(token);
            ifBlock(type, function parseType_block(token) {
                if (parseCommon(type, token))
                    return;

                switch (token) {

                    case "map":
                        parseMapField(type, token);
                        break;

                    case "required":
                    case "repeated":
                        parseField(type, token);
                        break;

                    case "optional":
                        /* istanbul ignore if */
                        if (isProto3) {
                            parseField(type, "proto3_optional");
                        } else {
                            parseField(type, "optional");
                        }
                        break;

                    case "oneof":
                        parseOneOf(type, token);
                        break;

                    case "extensions":
                        readRanges(type.extensions || (type.extensions = []));
                        break;

                    case "reserved":
                        readRanges(type.reserved || (type.reserved = []), true);
                        break;

                    default:
                        /* istanbul ignore if */
                        if (!isProto3 || !typeRefRe.test(token))
                            throw illegal(token);

                        push(token);
                        parseField(type, "optional");
                        break;
                }
            });
            parent.add(type);
        }

        function parseField(parent, rule, extend) {
            var type = next();
            if (type === "group") {
                parseGroup(parent, rule);
                return;
            }
            // Type names can consume multiple tokens, in multiple variants:
            //    package.subpackage   field       tokens: "package.subpackage" [TYPE NAME ENDS HERE] "field"
            //    package . subpackage field       tokens: "package" "." "subpackage" [TYPE NAME ENDS HERE] "field"
            //    package.  subpackage field       tokens: "package." "subpackage" [TYPE NAME ENDS HERE] "field"
            //    package  .subpackage field       tokens: "package" ".subpackage" [TYPE NAME ENDS HERE] "field"
            // Keep reading tokens until we get a type name with no period at the end,
            // and the next token does not start with a period.
            while (type.endsWith(".") || peek().startsWith(".")) {
                type += next();
            }

            /* istanbul ignore if */
            if (!typeRefRe.test(type))
                throw illegal(type, "type");

            var name = next();

            /* istanbul ignore if */
            if (!nameRe.test(name))
                throw illegal(name, "name");

            name = applyCase(name);
            skip("=");

            var field = new Field(name, parseId(next()), type, rule, extend);
            ifBlock(field, function parseField_block(token) {

                /* istanbul ignore else */
                if (token === "option") {
                    parseOption(field, token);
                    skip(";");
                } else
                    throw illegal(token);

            }, function parseField_line() {
                parseInlineOptions(field);
            });

            if (rule === "proto3_optional") {
                // for proto3 optional fields, we create a single-member Oneof to mimic "optional" behavior
                var oneof = new OneOf("_" + name);
                field.setOption("proto3_optional", true);
                oneof.add(field);
                parent.add(oneof);
            } else {
                parent.add(field);
            }

            // JSON defaults to packed=true if not set so we have to set packed=false explicity when
            // parsing proto2 descriptors without the option, where applicable. This must be done for
            // all known packable types and anything that could be an enum (= is not a basic type).
            if (!isProto3 && field.repeated && (types.packed[type] !== undefined || types.basic[type] === undefined))
                field.setOption("packed", false, /* ifNotSet */ true);
        }

        function parseGroup(parent, rule) {
            var name = next();

            /* istanbul ignore if */
            if (!nameRe.test(name))
                throw illegal(name, "name");

            var fieldName = util.lcFirst(name);
            if (name === fieldName)
                name = util.ucFirst(name);
            skip("=");
            var id = parseId(next());
            var type = new Type(name);
            type.group = true;
            var field = new Field(fieldName, id, name, rule);
            field.filename = parse.filename;
            ifBlock(type, function parseGroup_block(token) {
                switch (token) {

                    case "option":
                        parseOption(type, token);
                        skip(";");
                        break;

                    case "required":
                    case "repeated":
                        parseField(type, token);
                        break;

                    case "optional":
                        /* istanbul ignore if */
                        if (isProto3) {
                            parseField(type, "proto3_optional");
                        } else {
                            parseField(type, "optional");
                        }
                        break;

                    case "message":
                        parseType(type, token);
                        break;

                    case "enum":
                        parseEnum(type, token);
                        break;

                    /* istanbul ignore next */
                    default:
                        throw illegal(token); // there are no groups with proto3 semantics
                }
            });
            parent.add(type)
                  .add(field);
        }

        function parseMapField(parent) {
            skip("<");
            var keyType = next();

            /* istanbul ignore if */
            if (types.mapKey[keyType] === undefined)
                throw illegal(keyType, "type");

            skip(",");
            var valueType = next();

            /* istanbul ignore if */
            if (!typeRefRe.test(valueType))
                throw illegal(valueType, "type");

            skip(">");
            var name = next();

            /* istanbul ignore if */
            if (!nameRe.test(name))
                throw illegal(name, "name");

            skip("=");
            var field = new MapField(applyCase(name), parseId(next()), keyType, valueType);
            ifBlock(field, function parseMapField_block(token) {

                /* istanbul ignore else */
                if (token === "option") {
                    parseOption(field, token);
                    skip(";");
                } else
                    throw illegal(token);

            }, function parseMapField_line() {
                parseInlineOptions(field);
            });
            parent.add(field);
        }

        function parseOneOf(parent, token) {

            /* istanbul ignore if */
            if (!nameRe.test(token = next()))
                throw illegal(token, "name");

            var oneof = new OneOf(applyCase(token));
            ifBlock(oneof, function parseOneOf_block(token) {
                if (token === "option") {
                    parseOption(oneof, token);
                    skip(";");
                } else {
                    push(token);
                    parseField(oneof, "optional");
                }
            });
            parent.add(oneof);
        }

        function parseEnum(parent, token) {

            /* istanbul ignore if */
            if (!nameRe.test(token = next()))
                throw illegal(token, "name");

            var enm = new Enum(token);
            ifBlock(enm, function parseEnum_block(token) {
              switch(token) {
                case "option":
                  parseOption(enm, token);
                  skip(";");
                  break;

                case "reserved":
                  readRanges(enm.reserved || (enm.reserved = []), true);
                  break;

                default:
                  parseEnumValue(enm, token);
              }
            });
            parent.add(enm);
        }

        function parseEnumValue(parent, token) {

            /* istanbul ignore if */
            if (!nameRe.test(token))
                throw illegal(token, "name");

            skip("=");
            var value = parseId(next(), true),
                dummy = {
                    options: undefined
                };
            dummy.setOption = function(name, value) {
                if (this.options === undefined)
                    this.options = {};
                this.options[name] = value;
            };
            ifBlock(dummy, function parseEnumValue_block(token) {

                /* istanbul ignore else */
                if (token === "option") {
                    parseOption(dummy, token); // skip
                    skip(";");
                } else
                    throw illegal(token);

            }, function parseEnumValue_line() {
                parseInlineOptions(dummy); // skip
            });
            parent.add(token, value, dummy.comment, dummy.options);
        }

        function parseOption(parent, token) {
            var isCustom = skip("(", true);

            /* istanbul ignore if */
            if (!typeRefRe.test(token = next()))
                throw illegal(token, "name");

            var name = token;
            var option = name;
            var propName;

            if (isCustom) {
                skip(")");
                name = "(" + name + ")";
                option = name;
                token = peek();
                if (fqTypeRefRe.test(token)) {
                    propName = token.slice(1); //remove '.' before property name
                    name += token;
                    next();
                }
            }
            skip("=");
            var optionValue = parseOptionValue(parent, name);
            setParsedOption(parent, option, optionValue, propName);
        }

        function parseOptionValue(parent, name) {
            // { a: "foo" b { c: "bar" } }
            if (skip("{", true)) {
                var objectResult = {};

                while (!skip("}", true)) {
                    /* istanbul ignore if */
                    if (!nameRe.test(token = next())) {
                        throw illegal(token, "name");
                    }

                    var value;
                    var propName = token;

                    skip(":", true);

                    if (peek() === "{")
                        value = parseOptionValue(parent, name + "." + token);
                    else if (peek() === "[") {
                        // option (my_option) = {
                        //     repeated_value: [ "foo", "bar" ]
                        // };
                        value = [];
                        var lastValue;
                        if (skip("[", true)) {
                            do {
                                lastValue = readValue(true);
                                value.push(lastValue);
                            } while (skip(",", true));
                            skip("]");
                            if (typeof lastValue !== "undefined") {
                                setOption(parent, name + "." + token, lastValue);
                            }
                        }
                    } else {
                        value = readValue(true);
                        setOption(parent, name + "." + token, value);
                    }

                    var prevValue = objectResult[propName];

                    if (prevValue)
                        value = [].concat(prevValue).concat(value);

                    objectResult[propName] = value;

                    // Semicolons and commas can be optional
                    skip(",", true);
                    skip(";", true);
                }

                return objectResult;
            }

            var simpleValue = readValue(true);
            setOption(parent, name, simpleValue);
            return simpleValue;
            // Does not enforce a delimiter to be universal
        }

        function setOption(parent, name, value) {
            if (parent.setOption)
                parent.setOption(name, value);
        }

        function setParsedOption(parent, name, value, propName) {
            if (parent.setParsedOption)
                parent.setParsedOption(name, value, propName);
        }

        function parseInlineOptions(parent) {
            if (skip("[", true)) {
                do {
                    parseOption(parent, "option");
                } while (skip(",", true));
                skip("]");
            }
            return parent;
        }

        function parseService(parent, token) {

            /* istanbul ignore if */
            if (!nameRe.test(token = next()))
                throw illegal(token, "service name");

            var service = new Service(token);
            ifBlock(service, function parseService_block(token) {
                if (parseCommon(service, token))
                    return;

                /* istanbul ignore else */
                if (token === "rpc")
                    parseMethod(service, token);
                else
                    throw illegal(token);
            });
            parent.add(service);
        }

        function parseMethod(parent, token) {
            // Get the comment of the preceding line now (if one exists) in case the
            // method is defined across multiple lines.
            var commentText = cmnt();

            var type = token;

            /* istanbul ignore if */
            if (!nameRe.test(token = next()))
                throw illegal(token, "name");

            var name = token,
                requestType, requestStream,
                responseType, responseStream;

            skip("(");
            if (skip("stream", true))
                requestStream = true;

            /* istanbul ignore if */
            if (!typeRefRe.test(token = next()))
                throw illegal(token);

            requestType = token;
            skip(")"); skip("returns"); skip("(");
            if (skip("stream", true))
                responseStream = true;

            /* istanbul ignore if */
            if (!typeRefRe.test(token = next()))
                throw illegal(token);

            responseType = token;
            skip(")");

            var method = new Method(name, type, requestType, responseType, requestStream, responseStream);
            method.comment = commentText;
            ifBlock(method, function parseMethod_block(token) {

                /* istanbul ignore else */
                if (token === "option") {
                    parseOption(method, token);
                    skip(";");
                } else
                    throw illegal(token);

            });
            parent.add(method);
        }

        function parseExtension(parent, token) {

            /* istanbul ignore if */
            if (!typeRefRe.test(token = next()))
                throw illegal(token, "reference");

            var reference = token;
            ifBlock(null, function parseExtension_block(token) {
                switch (token) {

                    case "required":
                    case "repeated":
                        parseField(parent, token, reference);
                        break;

                    case "optional":
                        /* istanbul ignore if */
                        if (isProto3) {
                            parseField(parent, "proto3_optional", reference);
                        } else {
                            parseField(parent, "optional", reference);
                        }
                        break;

                    default:
                        /* istanbul ignore if */
                        if (!isProto3 || !typeRefRe.test(token))
                            throw illegal(token);
                        push(token);
                        parseField(parent, "optional", reference);
                        break;
                }
            });
        }

        var token;
        while ((token = next()) !== null) {
            switch (token) {

                case "package":

                    /* istanbul ignore if */
                    if (!head)
                        throw illegal(token);

                    parsePackage();
                    break;

                case "import":

                    /* istanbul ignore if */
                    if (!head)
                        throw illegal(token);

                    parseImport();
                    break;

                case "syntax":

                    /* istanbul ignore if */
                    if (!head)
                        throw illegal(token);

                    parseSyntax();
                    break;

                case "option":

                    parseOption(ptr, token);
                    skip(";");
                    break;

                default:

                    /* istanbul ignore else */
                    if (parseCommon(ptr, token)) {
                        head = false;
                        continue;
                    }

                    /* istanbul ignore next */
                    throw illegal(token);
            }
        }

        parse.filename = null;
        return {
            "package"     : pkg,
            "imports"     : imports,
             weakImports  : weakImports,
             syntax       : syntax,
             root         : root
        };
    }

    /**
     * Parses the given .proto source and returns an object with the parsed contents.
     * @name parse
     * @function
     * @param {string} source Source contents
     * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
     * @returns {IParserResult} Parser result
     * @property {string} filename=null Currently processing file name for error reporting, if known
     * @property {IParseOptions} defaults Default {@link IParseOptions}
     * @variation 2
     */

    const parse$1 = /*@__PURE__*/getDefaultExportFromCjs(parse_1);

    "use strict";
    var common_1 = common;

    var commonRe = /\/|\./;

    /**
     * Provides common type definitions.
     * Can also be used to provide additional google types or your own custom types.
     * @param {string} name Short name as in `google/protobuf/[name].proto` or full file name
     * @param {Object.<string,*>} json JSON definition within `google.protobuf` if a short name, otherwise the file's root definition
     * @returns {undefined}
     * @property {INamespace} google/protobuf/any.proto Any
     * @property {INamespace} google/protobuf/duration.proto Duration
     * @property {INamespace} google/protobuf/empty.proto Empty
     * @property {INamespace} google/protobuf/field_mask.proto FieldMask
     * @property {INamespace} google/protobuf/struct.proto Struct, Value, NullValue and ListValue
     * @property {INamespace} google/protobuf/timestamp.proto Timestamp
     * @property {INamespace} google/protobuf/wrappers.proto Wrappers
     * @example
     * // manually provides descriptor.proto (assumes google/protobuf/ namespace and .proto extension)
     * protobuf.common("descriptor", descriptorJson);
     *
     * // manually provides a custom definition (uses my.foo namespace)
     * protobuf.common("my/foo/bar.proto", myFooBarJson);
     */
    function common(name, json) {
        if (!commonRe.test(name)) {
            name = "google/protobuf/" + name + ".proto";
            json = { nested: { google: { nested: { protobuf: { nested: json } } } } };
        }
        common[name] = json;
    }

    // Not provided because of limited use (feel free to discuss or to provide yourself):
    //
    // google/protobuf/descriptor.proto
    // google/protobuf/source_context.proto
    // google/protobuf/type.proto
    //
    // Stripped and pre-parsed versions of these non-bundled files are instead available as part of
    // the repository or package within the google/protobuf directory.

    common("any", {

        /**
         * Properties of a google.protobuf.Any message.
         * @interface IAny
         * @type {Object}
         * @property {string} [typeUrl]
         * @property {Uint8Array} [bytes]
         * @memberof common
         */
        Any: {
            fields: {
                type_url: {
                    type: "string",
                    id: 1
                },
                value: {
                    type: "bytes",
                    id: 2
                }
            }
        }
    });

    var timeType;

    common("duration", {

        /**
         * Properties of a google.protobuf.Duration message.
         * @interface IDuration
         * @type {Object}
         * @property {number|Long} [seconds]
         * @property {number} [nanos]
         * @memberof common
         */
        Duration: timeType = {
            fields: {
                seconds: {
                    type: "int64",
                    id: 1
                },
                nanos: {
                    type: "int32",
                    id: 2
                }
            }
        }
    });

    common("timestamp", {

        /**
         * Properties of a google.protobuf.Timestamp message.
         * @interface ITimestamp
         * @type {Object}
         * @property {number|Long} [seconds]
         * @property {number} [nanos]
         * @memberof common
         */
        Timestamp: timeType
    });

    common("empty", {

        /**
         * Properties of a google.protobuf.Empty message.
         * @interface IEmpty
         * @memberof common
         */
        Empty: {
            fields: {}
        }
    });

    common("struct", {

        /**
         * Properties of a google.protobuf.Struct message.
         * @interface IStruct
         * @type {Object}
         * @property {Object.<string,IValue>} [fields]
         * @memberof common
         */
        Struct: {
            fields: {
                fields: {
                    keyType: "string",
                    type: "Value",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.Value message.
         * @interface IValue
         * @type {Object}
         * @property {string} [kind]
         * @property {0} [nullValue]
         * @property {number} [numberValue]
         * @property {string} [stringValue]
         * @property {boolean} [boolValue]
         * @property {IStruct} [structValue]
         * @property {IListValue} [listValue]
         * @memberof common
         */
        Value: {
            oneofs: {
                kind: {
                    oneof: [
                        "nullValue",
                        "numberValue",
                        "stringValue",
                        "boolValue",
                        "structValue",
                        "listValue"
                    ]
                }
            },
            fields: {
                nullValue: {
                    type: "NullValue",
                    id: 1
                },
                numberValue: {
                    type: "double",
                    id: 2
                },
                stringValue: {
                    type: "string",
                    id: 3
                },
                boolValue: {
                    type: "bool",
                    id: 4
                },
                structValue: {
                    type: "Struct",
                    id: 5
                },
                listValue: {
                    type: "ListValue",
                    id: 6
                }
            }
        },

        NullValue: {
            values: {
                NULL_VALUE: 0
            }
        },

        /**
         * Properties of a google.protobuf.ListValue message.
         * @interface IListValue
         * @type {Object}
         * @property {Array.<IValue>} [values]
         * @memberof common
         */
        ListValue: {
            fields: {
                values: {
                    rule: "repeated",
                    type: "Value",
                    id: 1
                }
            }
        }
    });

    common("wrappers", {

        /**
         * Properties of a google.protobuf.DoubleValue message.
         * @interface IDoubleValue
         * @type {Object}
         * @property {number} [value]
         * @memberof common
         */
        DoubleValue: {
            fields: {
                value: {
                    type: "double",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.FloatValue message.
         * @interface IFloatValue
         * @type {Object}
         * @property {number} [value]
         * @memberof common
         */
        FloatValue: {
            fields: {
                value: {
                    type: "float",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.Int64Value message.
         * @interface IInt64Value
         * @type {Object}
         * @property {number|Long} [value]
         * @memberof common
         */
        Int64Value: {
            fields: {
                value: {
                    type: "int64",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.UInt64Value message.
         * @interface IUInt64Value
         * @type {Object}
         * @property {number|Long} [value]
         * @memberof common
         */
        UInt64Value: {
            fields: {
                value: {
                    type: "uint64",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.Int32Value message.
         * @interface IInt32Value
         * @type {Object}
         * @property {number} [value]
         * @memberof common
         */
        Int32Value: {
            fields: {
                value: {
                    type: "int32",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.UInt32Value message.
         * @interface IUInt32Value
         * @type {Object}
         * @property {number} [value]
         * @memberof common
         */
        UInt32Value: {
            fields: {
                value: {
                    type: "uint32",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.BoolValue message.
         * @interface IBoolValue
         * @type {Object}
         * @property {boolean} [value]
         * @memberof common
         */
        BoolValue: {
            fields: {
                value: {
                    type: "bool",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.StringValue message.
         * @interface IStringValue
         * @type {Object}
         * @property {string} [value]
         * @memberof common
         */
        StringValue: {
            fields: {
                value: {
                    type: "string",
                    id: 1
                }
            }
        },

        /**
         * Properties of a google.protobuf.BytesValue message.
         * @interface IBytesValue
         * @type {Object}
         * @property {Uint8Array} [value]
         * @memberof common
         */
        BytesValue: {
            fields: {
                value: {
                    type: "bytes",
                    id: 1
                }
            }
        }
    });

    common("field_mask", {

        /**
         * Properties of a google.protobuf.FieldMask message.
         * @interface IDoubleValue
         * @type {Object}
         * @property {number} [value]
         * @memberof common
         */
        FieldMask: {
            fields: {
                paths: {
                    rule: "repeated",
                    type: "string",
                    id: 1
                }
            }
        }
    });

    /**
     * Gets the root definition of the specified common proto file.
     *
     * Bundled definitions are:
     * - google/protobuf/any.proto
     * - google/protobuf/duration.proto
     * - google/protobuf/empty.proto
     * - google/protobuf/field_mask.proto
     * - google/protobuf/struct.proto
     * - google/protobuf/timestamp.proto
     * - google/protobuf/wrappers.proto
     *
     * @param {string} file Proto file name
     * @returns {INamespace|null} Root definition or `null` if not defined
     */
    common.get = function get(file) {
        return common[file] || null;
    };

    const common$1 = /*@__PURE__*/getDefaultExportFromCjs(common_1);

    var src = src$1.exports;

    "use strict";
    var protobuf = src$1.exports = indexLightExports;

    protobuf.build = "full";

    // Parser
    protobuf.tokenize         = tokenize_1;
    protobuf.parse            = parse_1;
    protobuf.common           = common_1;

    // Configure parser
    protobuf.Root._configure(protobuf.Type, protobuf.parse, protobuf.common);

    var srcExports = src$1.exports;
    const index$1 = /*@__PURE__*/getDefaultExportFromCjs(srcExports);

    // full library entry point.

    "use strict";
    var protobufjs = srcExports;

    const index = /*@__PURE__*/getDefaultExportFromCjs(protobufjs);

    /**
     * 针对 dmzj v4api 的解密
     *
     * 代码来源于 https://greasyfork.org/zh-CN/scripts/466729-动漫之家解除屏蔽
     * 仅因为不想修改 jsencrypt 库的代码,加上希望打包出来的代码尽量小点所以调整了下结构
     */

    const V4_PRIVATE_KEY = 'MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK8nNR1lTnIfIes6oRWJNj3mB6OssDGx0uGMpgpbVCpf6+VwnuI2stmhZNoQcM417Iz7WqlPzbUmu9R4dEKmLGEEqOhOdVaeh9Xk2IPPjqIu5TbkLZRxkY3dJM1htbz57d/roesJLkZXqssfG5EJauNc+RcABTfLb4IiFjSMlTsnAgMBAAECgYEAiz/pi2hKOJKlvcTL4jpHJGjn8+lL3wZX+LeAHkXDoTjHa47g0knYYQteCbv+YwMeAGupBWiLy5RyyhXFoGNKbbnvftMYK56hH+iqxjtDLnjSDKWnhcB7089sNKaEM9Ilil6uxWMrMMBH9v2PLdYsqMBHqPutKu/SigeGPeiB7VECQQDizVlNv67go99QAIv2n/ga4e0wLizVuaNBXE88AdOnaZ0LOTeniVEqvPtgUk63zbjl0P/pzQzyjitwe6HoCAIpAkEAxbOtnCm1uKEp5HsNaXEJTwE7WQf7PrLD4+BpGtNKkgja6f6F4ld4QZ2TQ6qvsCizSGJrjOpNdjVGJ7bgYMcczwJBALvJWPLmDi7ToFfGTB0EsNHZVKE66kZ/8Stx+ezueke4S556XplqOflQBjbnj2PigwBN/0afT+QZUOBOjWzoDJkCQClzo+oDQMvGVs9GEajS/32mJ3hiWQZrWvEzgzYRqSf3XVcEe7PaXSd8z3y3lACeeACsShqQoc8wGlaHXIJOHTcCQQCZw5127ZGs8ZDTSrogrH73Kw/HvX55wGAeirKYcv28eauveCG7iyFR0PFB/P/EDZnyb+ifvyEFlucPUI0+Y87F';
    const dmzjProto = {
      nested: {
        proto: {
          fields: {
            comicInfo: {
              type: 'ComicInfo',
              id: 3
            }
          }
        },
        ComicInfo: {
          fields: {
            id: {
              type: 'int64',
              id: 1
            },
            title: {
              type: 'string',
              id: 2
            },
            direction: {
              type: 'int64',
              id: 3
            },
            islong: {
              type: 'int64',
              id: 4
            },
            cover: {
              type: 'string',
              id: 6
            },
            description: {
              type: 'string',
              id: 7
            },
            last_updatetime: {
              type: 'int64',
              id: 8
            },
            last_update_chapter_name: {
              type: 'string',
              id: 9
            },
            first_letter: {
              type: 'string',
              id: 11
            },
            comic_py: {
              type: 'string',
              id: 12
            },
            hidden: {
              type: 'int64',
              id: 13
            },
            hot_num: {
              type: 'int64',
              id: 14
            },
            hit_num: {
              type: 'int64',
              id: 15
            },
            last_update_chapter_id: {
              type: 'int64',
              id: 18
            },
            types: {
              type: 'Types',
              id: 19,
              rule: 'repeated'
            },
            status: {
              type: 'Status',
              id: 20
            },
            authors: {
              type: 'Authors',
              id: 21,
              rule: 'repeated'
            },
            subscribe_num: {
              type: 'int64',
              id: 22
            },
            chapters: {
              type: 'Chapters',
              id: 23,
              rule: 'repeated'
            },
            is_need_login: {
              type: 'int64',
              id: 24
            },
            dh_url_links: {
              type: 'DhUrlLink',
              id: 27,
              rule: 'repeated'
            }
          }
        },
        Types: {
          fields: {
            tag_id: {
              type: 'int64',
              id: 1
            },
            tag_name: {
              type: 'string',
              id: 2
            }
          }
        },
        Status: {
          fields: {
            tag_id: {
              type: 'int64',
              id: 1
            },
            tag_name: {
              type: 'string',
              id: 2
            }
          }
        },
        Authors: {
          fields: {
            tag_id: {
              type: 'int64',
              id: 1
            },
            tag_name: {
              type: 'string',
              id: 2
            }
          }
        },
        Data: {
          fields: {
            chapter_id: {
              type: 'int64',
              id: 1
            },
            chapter_title: {
              type: 'string',
              id: 2
            },
            updatetime: {
              type: 'int64',
              id: 3
            },
            filesize: {
              type: 'int64',
              id: 4
            },
            chapter_order: {
              type: 'int64',
              id: 5
            }
          }
        },
        Chapters: {
          fields: {
            title: {
              type: 'string',
              id: 1
            },
            data: {
              type: 'Data',
              id: 2,
              rule: 'repeated'
            }
          }
        },
        DhUrlLink: {
          fields: {
            title: {
              type: 'string',
              id: 1
            }
          }
        }
      }
    };
    const key = new JSEncryptRSAKey(V4_PRIVATE_KEY);
    const message = protobufjs.Root.fromJSON(dmzjProto).lookupType('proto');
    const base64ToArrayBuffer = str => {
      const binaryString = window.atob(str);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
      return bytes;
    };
    const arrayBufferToBase64 = buffer => {
      let binary = '';
      const bytes = new Uint8Array(buffer);
      const len = bytes.byteLength;
      for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]);
      return window.btoa(binary);
    };
    const pkcs1unpad2 = (d, n) => {
      const b = d.toByteArray();
      let i = 0;
      while (i < b.length && b[i] === 0) ++i;
      if (b.length - i !== n - 1 || b[i] !== 2) return null;
      ++i;
      while (b[i] !== 0) if (++i >= b.length) return null;
      const bytes = [];
      while (++i < b.length) bytes.push(b[i]);
      return bytes;
    };
    const customDecrypt = t => {
      const e = parseBigInt(t, 16);
      const i = key.doPrivate(e);
      if (i == null) return null;
      // eslint-disable-next-line no-bitwise
      return pkcs1unpad2(i, key.n.bitLength() + 7 >> 3);
    };
    const utilsDmzjDecrypt = str => {
      const decode = base64ToArrayBuffer(str);
      const {
        length
      } = decode;
      let i10 = 0;
      let i11 = 0;
      let bytes = [];
      while (length - i10 > 0) {
        bytes = bytes.concat(customDecrypt(b64tohex(arrayBufferToBase64(decode.slice(i10, i10 + 128)))));
        i11++;
        i10 = i11 * 128;
      }
      return Uint8Array.from(bytes);
    };
    const dmzjDecrypt = (str => {
      const bytes = utilsDmzjDecrypt(str);
      return message.decode(bytes);
    });

    return dmzjDecrypt;

}));