bigi vs digit-array encode

Benchmark created by Jared Deckard on


Description

Encodes a byte array using bigi or digit-array for the computational portion of base85 encoding.

Setup

var bytes = [115, 105, 109, 112, 108, 121, 32, 97, 32, 108, 111, 110, 103, 32, 115, 116, 114, 105, 110, 103];
    
    // Setup bs58_bigi
    !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.bs58_bigi=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
    (function (Buffer){
    var BigInteger = _dereq_('bigi');
    
    'use strict'
    
    module.exports.decode = decode;
    module.exports.encode = encode;
    
    var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    var ALPHABET_BUF = new Buffer(ALPHABET)
    var LOOKUP = {};
    for (var i=0 ; i < ALPHABET.length ; ++i) {
      LOOKUP[ALPHABET[i]] = i;
    }
    
    var BASE = 58;
    var base = BigInteger.valueOf(BASE);
    
    
    function encode (input) {
      var bi = BigInteger.fromBuffer(input)
      var result = new Buffer(input.length << 1)
    
      var i = result.length - 1
      while (bi.compareTo(BigInteger.ZERO) > 0) {
        var remainder = bi.mod(base)
        bi = bi.divide(base)
    
        result[i] = ALPHABET_BUF[remainder.intValue()]
        i--
      }
    
      // deal with leading zeros
      var j = 0
      while (input[j] === 0) {
        result[i] = ALPHABET_BUF[0]
        j++
        i--
      }
    
      return result.slice(i + 1, result.length).toString()
    }
    
    
    function decode (input) {
      var num = BigInteger.valueOf(0);
      var leadingZero = 0;
      var seenOther = false;
      for (var i = 0; i < input.length ; ++i) {
        var ch = input[i];
        var p = LOOKUP[ch];
    
        // if we encounter an invalid character, decoding fails
        if (p === undefined) {
          throw new Error('invalid base58 string: ' + input);
        }
    
        num = num.multiply(base).add(BigInteger.valueOf(p));
    
        if (ch == ALPHABET[0] && !seenOther) {
          ++leadingZero;
        }
        else {
          seenOther = true;
        }
      }
    
      var bytes = num.toByteArrayUnsigned();
    
      // remove leading zeros
      while (leadingZero-- > 0) {
        bytes.unshift(0);
      }
    
      return new Buffer(bytes);
    }
    
    }).call(this,_dereq_("buffer").Buffer)
    },{"bigi":4,"buffer":8}],2:[function(_dereq_,module,exports){
    var assert = _dereq_('assert')
    
    // (public) Constructor
    function BigInteger(a, b, c) {
      if (!(this instanceof BigInteger))
        return new 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)
      }
    }
    
    var proto = BigInteger.prototype
    
    // Bits per digit
    var dbits
    
    // 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.
    
    // 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)
    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
    }
    // 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)
    function am2(i, x, w, j, c, n) {
      var xl = x & 0x7fff,
        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
    }
    // Alternately, set max digit bits to 28 since some
    // browsers slow down when dealing with 32-bit numbers.
    function am3(i, x, w, j, c, n) {
      var xl = x & 0x3fff,
        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
    }
    
    // wtf?
    BigInteger.prototype.am = am1
    dbits = 26
    
    BigInteger.prototype.DB = dbits
    BigInteger.prototype.DM = ((1 << dbits) - 1)
    var DV = 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_RM = "0123456789abcdefghijklmnopqrstuvwxyz"
    var BI_RC = new Array()
    var rr, 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 int2char(n) {
      return BI_RM.charAt(n)
    }
    
    function intAt(s, i) {
      var c = BI_RC[s.charCodeAt(i)]
      return (c == null) ? -1 : c
    }
    
    // (protected) copy this to r
    function bnpCopyTo(r) {
      for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]
      r.t = this.t
      r.s = this.s
    }
    
    // (protected) set from integer value x, -DV <= x < DV
    function bnpFromInt(x) {
      this.t = 1
      this.s = (x < 0) ? -1 : 0
      if (x > 0) this[0] = x
      else if (x < -1) this[0] = x + DV
      else this.t = 0
    }
    
    // return bigint initialized to value
    function nbv(i) {
      var r = new BigInteger()
      r.fromInt(i)
      return r
    }
    
    // (protected) set from string and radix
    function bnpFromString(s, b) {
      var self = this
    
      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 {
        self.fromRadix(s, b)
        return
      }
      self.t = 0
      self.s = 0
      var i = s.length,
        mi = false,
        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)
          self[self.t++] = x
        else if (sh + k > self.DB) {
          self[self.t - 1] |= (x & ((1 << (self.DB - sh)) - 1)) << sh
          self[self.t++] = (x >> (self.DB - sh))
        } else
          self[self.t - 1] |= x << sh
        sh += k
        if (sh >= self.DB) sh -= self.DB
      }
      if (k == 8 && (s[0] & 0x80) != 0) {
        self.s = -1
        if (sh > 0) self[self.t - 1] |= ((1 << (self.DB - sh)) - 1) << sh
      }
      self.clamp()
      if (mi) BigInteger.ZERO.subTo(self, self)
    }
    
    // (protected) clamp off excess high words
    function bnpClamp() {
      var c = this.s & this.DM
      while (this.t > 0 && this[this.t - 1] == c)--this.t
    }
    
    // (public) return string representation in given radix
    function bnToString(b) {
      var self = this
      if (self.s < 0) return "-" + self.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 self.toRadix(b)
      var km = (1 << k) - 1,
        d, m = false,
        r = "",
        i = self.t
      var p = self.DB - (i * self.DB) % k
      if (i-- > 0) {
        if (p < self.DB && (d = self[i] >> p) > 0) {
          m = true
          r = int2char(d)
        }
        while (i >= 0) {
          if (p < k) {
            d = (self[i] & ((1 << p) - 1)) << (k - p)
            d |= self[--i] >> (p += self.DB - k)
          } else {
            d = (self[i] >> (p -= k)) & km
            if (p <= 0) {
              p += self.DB
              --i
            }
          }
          if (d > 0) m = true
          if (m) r += int2char(d)
        }
      }
      return m ? r : "0"
    }
    
    // (public) -this
    function bnNegate() {
      var r = new BigInteger()
      BigInteger.ZERO.subTo(this, r)
      return r
    }
    
    // (public) |this|
    function bnAbs() {
      return (this.s < 0) ? this.negate() : this
    }
    
    // (public) return + if this > a, - if this < a, 0 if equal
    function bnCompareTo(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
    }
    
    // returns bit length of the integer x
    function nbits(x) {
      var r = 1,
        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
    }
    
    // (public) return the number of bits in "this"
    function bnBitLength() {
      if (this.t <= 0) return 0
      return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM))
    }
    
    // (protected) r = this << n*DB
    function bnpDLShiftTo(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
    }
    
    // (protected) r = this >> n*DB
    function bnpDRShiftTo(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
    }
    
    // (protected) r = this << n
    function bnpLShiftTo(n, r) {
      var self = this
      var bs = n % self.DB
      var cbs = self.DB - bs
      var bm = (1 << cbs) - 1
      var ds = Math.floor(n / self.DB),
        c = (self.s << bs) & self.DM,
        i
      for (i = self.t - 1; i >= 0; --i) {
        r[i + ds + 1] = (self[i] >> cbs) | c
        c = (self[i] & bm) << bs
      }
      for (i = ds - 1; i >= 0; --i) r[i] = 0
      r[ds] = c
      r.t = self.t + ds + 1
      r.s = self.s
      r.clamp()
    }
    
    // (protected) r = this >> n
    function bnpRShiftTo(n, r) {
      var self = this
      r.s = self.s
      var ds = Math.floor(n / self.DB)
      if (ds >= self.t) {
        r.t = 0
        return
      }
      var bs = n % self.DB
      var cbs = self.DB - bs
      var bm = (1 << bs) - 1
      r[0] = self[ds] >> bs
      for (var i = ds + 1; i < self.t; ++i) {
        r[i - ds - 1] |= (self[i] & bm) << cbs
        r[i - ds] = self[i] >> bs
      }
      if (bs > 0) r[self.t - ds - 1] |= (self.s & bm) << cbs
      r.t = self.t - ds
      r.clamp()
    }
    
    // (protected) r = this - a
    function bnpSubTo(a, r) {
      var self = this
      var i = 0,
        c = 0,
        m = Math.min(a.t, self.t)
      while (i < m) {
        c += self[i] - a[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      if (a.t < self.t) {
        c -= a.s
        while (i < self.t) {
          c += self[i]
          r[i++] = c & self.DM
          c >>= self.DB
        }
        c += self.s
      } else {
        c += self.s
        while (i < a.t) {
          c -= a[i]
          r[i++] = c & self.DM
          c >>= self.DB
        }
        c -= a.s
      }
      r.s = (c < 0) ? -1 : 0
      if (c < -1) r[i++] = self.DV + c
      else if (c > 0) r[i++] = c
      r.t = i
      r.clamp()
    }
    
    // (protected) r = this * a, r != this,a (HAC 14.12)
    // "this" should be the larger one if appropriate.
    function bnpMultiplyTo(a, r) {
      var x = this.abs(),
        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)
    }
    
    // (protected) r = this^2, r != this (HAC 14.16)
    function bnpSquareTo(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()
    }
    
    // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
    // r != q, this != m.  q or r may be null.
    function bnpDivRemTo(m, q, r) {
      var self = this
      var pm = m.abs()
      if (pm.t <= 0) return
      var pt = self.abs()
      if (pt.t < pm.t) {
        if (q != null) q.fromInt(0)
        if (r != null) self.copyTo(r)
        return
      }
      if (r == null) r = new BigInteger()
      var y = new BigInteger(),
        ts = self.s,
        ms = m.s
      var nsh = self.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 << self.F1) + ((ys > 1) ? y[ys - 2] >> self.F2 : 0)
      var d1 = self.FV / yt,
        d2 = (1 << self.F1) / yt,
        e = 1 << self.F2
      var i = r.t,
        j = i - ys,
        t = (q == null) ? new BigInteger() : 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) ? self.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)
    }
    
    // (public) this mod a
    function bnMod(a) {
      var r = new BigInteger()
      this.abs()
        .divRemTo(a, null, r)
      if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r)
      return r
    }
    
    // Modular reduction using "classic" algorithm
    function Classic(m) {
      this.m = m
    }
    
    function cConvert(x) {
      if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m)
      else return x
    }
    
    function cRevert(x) {
      return x
    }
    
    function cReduce(x) {
      x.divRemTo(this.m, null, x)
    }
    
    function cMulTo(x, y, r) {
      x.multiplyTo(y, r)
      this.reduce(r)
    }
    
    function cSqrTo(x, r) {
      x.squareTo(r)
      this.reduce(r)
    }
    
    Classic.prototype.convert = cConvert
    Classic.prototype.revert = cRevert
    Classic.prototype.reduce = cReduce
    Classic.prototype.mulTo = cMulTo
    Classic.prototype.sqrTo = cSqrTo
    
    // (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.
    function bnpInvDigit() {
      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
    }
    
    // Montgomery reduction
    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
    }
    
    // xR mod m
    function montConvert(x) {
      var r = new BigInteger()
      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
    }
    
    // x/R mod m
    function montRevert(x) {
      var r = new BigInteger()
      x.copyTo(r)
      this.reduce(r)
      return r
    }
    
    // x = x/R mod m (HAC 14.32)
    function montReduce(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)
    }
    
    // r = "x^2/R mod m"; x != r
    function montSqrTo(x, r) {
      x.squareTo(r)
      this.reduce(r)
    }
    
    // r = "xy/R mod m"; x,y != r
    function montMulTo(x, y, r) {
      x.multiplyTo(y, r)
      this.reduce(r)
    }
    
    Montgomery.prototype.convert = montConvert
    Montgomery.prototype.revert = montRevert
    Montgomery.prototype.reduce = montReduce
    Montgomery.prototype.mulTo = montMulTo
    Montgomery.prototype.sqrTo = montSqrTo
    
    // (protected) true iff this is even
    function bnpIsEven() {
      return ((this.t > 0) ? (this[0] & 1) : this.s) == 0
    }
    
    // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
    function bnpExp(e, z) {
      if (e > 0xffffffff || e < 1) return BigInteger.ONE
      var r = new BigInteger(),
        r2 = new BigInteger(),
        g = z.convert(this),
        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)
    }
    
    // (public) this^e % m, 0 <= e < 2^32
    function bnModPowInt(e, m) {
      var z
      if (e < 256 || m.isEven()) z = new Classic(m)
      else z = new Montgomery(m)
      return this.exp(e, z)
    }
    
    // protected
    proto.copyTo = bnpCopyTo
    proto.fromInt = bnpFromInt
    proto.fromString = bnpFromString
    proto.clamp = bnpClamp
    proto.dlShiftTo = bnpDLShiftTo
    proto.drShiftTo = bnpDRShiftTo
    proto.lShiftTo = bnpLShiftTo
    proto.rShiftTo = bnpRShiftTo
    proto.subTo = bnpSubTo
    proto.multiplyTo = bnpMultiplyTo
    proto.squareTo = bnpSquareTo
    proto.divRemTo = bnpDivRemTo
    proto.invDigit = bnpInvDigit
    proto.isEven = bnpIsEven
    proto.exp = bnpExp
    
    // public
    proto.toString = bnToString
    proto.negate = bnNegate
    proto.abs = bnAbs
    proto.compareTo = bnCompareTo
    proto.bitLength = bnBitLength
    proto.mod = bnMod
    proto.modPowInt = bnModPowInt
    
    // (public)
    function bnClone() {
      var r = new BigInteger()
      this.copyTo(r)
      return r
    }
    
    // (public) return value as integer
    function bnIntValue() {
      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]
    }
    
    // (public) return value as byte
    function bnByteValue() {
      return (this.t == 0) ? this.s : (this[0] << 24) >> 24
    }
    
    // (public) return value as short (assumes DB>=16)
    function bnShortValue() {
      return (this.t == 0) ? this.s : (this[0] << 16) >> 16
    }
    
    // (protected) return x s.t. r^x < DV
    function bnpChunkSize(r) {
      return Math.floor(Math.LN2 * this.DB / Math.log(r))
    }
    
    // (public) 0 if this == 0, 1 if this > 0
    function bnSigNum() {
      if (this.s < 0) return -1
      else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0
      else return 1
    }
    
    // (protected) convert to radix string
    function bnpToRadix(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),
        y = new BigInteger(),
        z = new BigInteger(),
        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
    }
    
    // (protected) convert from radix string
    function bnpFromRadix(s, b) {
      var self = this
      self.fromInt(0)
      if (b == null) b = 10
      var cs = self.chunkSize(b)
      var d = Math.pow(b, cs),
        mi = false,
        j = 0,
        w = 0
      for (var i = 0; i < s.length; ++i) {
        var x = intAt(s, i)
        if (x < 0) {
          if (s.charAt(i) == "-" && self.signum() == 0) mi = true
          continue
        }
        w = b * w + x
        if (++j >= cs) {
          self.dMultiply(d)
          self.dAddOffset(w, 0)
          j = 0
          w = 0
        }
      }
      if (j > 0) {
        self.dMultiply(Math.pow(b, j))
        self.dAddOffset(w, 0)
      }
      if (mi) BigInteger.ZERO.subTo(self, self)
    }
    
    // (protected) alternate constructor
    function bnpFromNumber(a, b, c) {
      var self = this
      if ("number" == typeof b) {
        // new BigInteger(int,int,RNG)
        if (a < 2) self.fromInt(1)
        else {
          self.fromNumber(a, c)
          if (!self.testBit(a - 1)) // force MSB set
            self.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, self)
          if (self.isEven()) self.dAddOffset(1, 0); // force odd
          while (!self.isProbablePrime(b)) {
            self.dAddOffset(2, 0)
            if (self.bitLength() > a) self.subTo(BigInteger.ONE.shiftLeft(a - 1), self)
          }
        }
      } else {
        // new BigInteger(int,RNG)
        var x = new Array(),
          t = a & 7
        x.length = (a >> 3) + 1
        b.nextBytes(x)
        if (t > 0) x[0] &= ((1 << t) - 1)
        else x[0] = 0
        self.fromString(x, 256)
      }
    }
    
    // (public) convert to bigendian byte array
    function bnToByteArray() {
      var self = this
      var i = self.t,
        r = new Array()
      r[0] = self.s
      var p = self.DB - (i * self.DB) % 8,
        d, k = 0
      if (i-- > 0) {
        if (p < self.DB && (d = self[i] >> p) != (self.s & self.DM) >> p)
          r[k++] = d | (self.s << (self.DB - p))
        while (i >= 0) {
          if (p < 8) {
            d = (self[i] & ((1 << p) - 1)) << (8 - p)
            d |= self[--i] >> (p += self.DB - 8)
          } else {
            d = (self[i] >> (p -= 8)) & 0xff
            if (p <= 0) {
              p += self.DB
              --i
            }
          }
          if ((d & 0x80) != 0) d |= -256
          if (k === 0 && (self.s & 0x80) != (d & 0x80))++k
          if (k > 0 || d != self.s) r[k++] = d
        }
      }
      return r
    }
    
    function bnEquals(a) {
      return (this.compareTo(a) == 0)
    }
    
    function bnMin(a) {
      return (this.compareTo(a) < 0) ? this : a
    }
    
    function bnMax(a) {
      return (this.compareTo(a) > 0) ? this : a
    }
    
    // (protected) r = this op a (bitwise)
    function bnpBitwiseTo(a, op, r) {
      var self = this
      var i, f, m = Math.min(a.t, self.t)
      for (i = 0; i < m; ++i) r[i] = op(self[i], a[i])
      if (a.t < self.t) {
        f = a.s & self.DM
        for (i = m; i < self.t; ++i) r[i] = op(self[i], f)
        r.t = self.t
      } else {
        f = self.s & self.DM
        for (i = m; i < a.t; ++i) r[i] = op(f, a[i])
        r.t = a.t
      }
      r.s = op(self.s, a.s)
      r.clamp()
    }
    
    // (public) this & a
    function op_and(x, y) {
      return x & y
    }
    
    function bnAnd(a) {
      var r = new BigInteger()
      this.bitwiseTo(a, op_and, r)
      return r
    }
    
    // (public) this | a
    function op_or(x, y) {
      return x | y
    }
    
    function bnOr(a) {
      var r = new BigInteger()
      this.bitwiseTo(a, op_or, r)
      return r
    }
    
    // (public) this ^ a
    function op_xor(x, y) {
      return x ^ y
    }
    
    function bnXor(a) {
      var r = new BigInteger()
      this.bitwiseTo(a, op_xor, r)
      return r
    }
    
    // (public) this & ~a
    function op_andnot(x, y) {
      return x & ~y
    }
    
    function bnAndNot(a) {
      var r = new BigInteger()
      this.bitwiseTo(a, op_andnot, r)
      return r
    }
    
    // (public) ~this
    function bnNot() {
      var r = new BigInteger()
      for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]
      r.t = this.t
      r.s = ~this.s
      return r
    }
    
    // (public) this << n
    function bnShiftLeft(n) {
      var r = new BigInteger()
      if (n < 0) this.rShiftTo(-n, r)
      else this.lShiftTo(n, r)
      return r
    }
    
    // (public) this >> n
    function bnShiftRight(n) {
      var r = new BigInteger()
      if (n < 0) this.lShiftTo(-n, r)
      else this.rShiftTo(n, r)
      return r
    }
    
    // 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
    }
    
    // (public) returns index of lowest 1-bit (or -1 if none)
    function bnGetLowestSetBit() {
      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
    }
    
    // return number of 1 bits in x
    function cbit(x) {
      var r = 0
      while (x != 0) {
        x &= x - 1
        ++r
      }
      return r
    }
    
    // (public) return number of set bits
    function bnBitCount() {
      var r = 0,
        x = this.s & this.DM
      for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x)
      return r
    }
    
    // (public) true iff nth bit is set
    function bnTestBit(n) {
      var j = Math.floor(n / this.DB)
      if (j >= this.t) return (this.s != 0)
      return ((this[j] & (1 << (n % this.DB))) != 0)
    }
    
    // (protected) this op (1<<n)
    function bnpChangeBit(n, op) {
      var r = BigInteger.ONE.shiftLeft(n)
      this.bitwiseTo(r, op, r)
      return r
    }
    
    // (public) this | (1<<n)
    function bnSetBit(n) {
      return this.changeBit(n, op_or)
    }
    
    // (public) this & ~(1<<n)
    function bnClearBit(n) {
      return this.changeBit(n, op_andnot)
    }
    
    // (public) this ^ (1<<n)
    function bnFlipBit(n) {
      return this.changeBit(n, op_xor)
    }
    
    // (protected) r = this + a
    function bnpAddTo(a, r) {
      var self = this
    
      var i = 0,
        c = 0,
        m = Math.min(a.t, self.t)
      while (i < m) {
        c += self[i] + a[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      if (a.t < self.t) {
        c += a.s
        while (i < self.t) {
          c += self[i]
          r[i++] = c & self.DM
          c >>= self.DB
        }
        c += self.s
      } else {
        c += self.s
        while (i < a.t) {
          c += a[i]
          r[i++] = c & self.DM
          c >>= self.DB
        }
        c += a.s
      }
      r.s = (c < 0) ? -1 : 0
      if (c > 0) r[i++] = c
      else if (c < -1) r[i++] = self.DV + c
      r.t = i
      r.clamp()
    }
    
    // (public) this + a
    function bnAdd(a) {
      var r = new BigInteger()
      this.addTo(a, r)
      return r
    }
    
    // (public) this - a
    function bnSubtract(a) {
      var r = new BigInteger()
      this.subTo(a, r)
      return r
    }
    
    // (public) this * a
    function bnMultiply(a) {
      var r = new BigInteger()
      this.multiplyTo(a, r)
      return r
    }
    
    // (public) this^2
    function bnSquare() {
      var r = new BigInteger()
      this.squareTo(r)
      return r
    }
    
    // (public) this / a
    function bnDivide(a) {
      var r = new BigInteger()
      this.divRemTo(a, r, null)
      return r
    }
    
    // (public) this % a
    function bnRemainder(a) {
      var r = new BigInteger()
      this.divRemTo(a, null, r)
      return r
    }
    
    // (public) [this/a,this%a]
    function bnDivideAndRemainder(a) {
      var q = new BigInteger(),
        r = new BigInteger()
      this.divRemTo(a, q, r)
      return new Array(q, r)
    }
    
    // (protected) this *= n, this >= 0, 1 < n < DV
    function bnpDMultiply(n) {
      this[this.t] = this.am(0, n - 1, this, 0, 0, this.t)
      ++this.t
      this.clamp()
    }
    
    // (protected) this += n << w words, this >= 0
    function bnpDAddOffset(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]
      }
    }
    
    // A "null" reducer
    function NullExp() {}
    
    function nNop(x) {
      return x
    }
    
    function nMulTo(x, y, r) {
      x.multiplyTo(y, r)
    }
    
    function nSqrTo(x, r) {
      x.squareTo(r)
    }
    
    NullExp.prototype.convert = nNop
    NullExp.prototype.revert = nNop
    NullExp.prototype.mulTo = nMulTo
    NullExp.prototype.sqrTo = nSqrTo
    
    // (public) this^e
    function bnPow(e) {
      return this.exp(e, new NullExp())
    }
    
    // (protected) r = lower n words of "this * a", a.t <= n
    // "this" should be the larger one if appropriate.
    function bnpMultiplyLowerTo(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
      var j
      for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t)
      for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i)
      r.clamp()
    }
    
    // (protected) r = "this * a" without lower n words, n > 0
    // "this" should be the larger one if appropriate.
    function bnpMultiplyUpperTo(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)
    }
    
    // Barrett modular reduction
    function Barrett(m) {
      // setup Barrett
      this.r2 = new BigInteger()
      this.q3 = new BigInteger()
      BigInteger.ONE.dlShiftTo(2 * m.t, this.r2)
      this.mu = this.r2.divide(m)
      this.m = m
    }
    
    function barrettConvert(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 = new BigInteger()
        x.copyTo(r)
        this.reduce(r)
        return r
      }
    }
    
    function barrettRevert(x) {
      return x
    }
    
    // x = x mod m (HAC 14.42)
    function barrettReduce(x) {
      var self = this
      x.drShiftTo(self.m.t - 1, self.r2)
      if (x.t > self.m.t + 1) {
        x.t = self.m.t + 1
        x.clamp()
      }
      self.mu.multiplyUpperTo(self.r2, self.m.t + 1, self.q3)
      self.m.multiplyLowerTo(self.q3, self.m.t + 1, self.r2)
      while (x.compareTo(self.r2) < 0) x.dAddOffset(1, self.m.t + 1)
      x.subTo(self.r2, x)
      while (x.compareTo(self.m) >= 0) x.subTo(self.m, x)
    }
    
    // r = x^2 mod m; x != r
    function barrettSqrTo(x, r) {
      x.squareTo(r)
      this.reduce(r)
    }
    
    // r = x*y mod m; x,y != r
    function barrettMulTo(x, y, r) {
      x.multiplyTo(y, r)
      this.reduce(r)
    }
    
    Barrett.prototype.convert = barrettConvert
    Barrett.prototype.revert = barrettRevert
    Barrett.prototype.reduce = barrettReduce
    Barrett.prototype.mulTo = barrettMulTo
    Barrett.prototype.sqrTo = barrettSqrTo
    
    // (public) this^e % m (HAC 14.85)
    function bnModPow(e, m) {
      var i = e.bitLength(),
        k, r = nbv(1),
        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 = new Array(),
        n = 3,
        k1 = k - 1,
        km = (1 << k) - 1
      g[1] = z.convert(this)
      if (k > 1) {
        var g2 = new BigInteger()
        z.sqrTo(g[1], g2)
        while (n <= km) {
          g[n] = new BigInteger()
          z.mulTo(g2, g[n - 2], g[n])
          n += 2
        }
      }
    
      var j = e.t - 1,
        w, is1 = true,
        r2 = new BigInteger(),
        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)
    }
    
    // (public) gcd(this,a) (HAC 14.54)
    function bnGCD(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(),
        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
    }
    
    // (protected) this % n, n < 2^26
    function bnpModInt(n) {
      if (n <= 0) return 0
      var d = this.DV % n,
        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
    }
    
    // (public) 1/this % m (HAC 14.61)
    function bnModInverse(m) {
      var ac = m.isEven()
      if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO
      var u = m.clone(),
        v = this.clone()
      var a = nbv(1),
        b = nbv(0),
        c = nbv(0),
        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
    }
    
    // protected
    proto.chunkSize = bnpChunkSize
    proto.toRadix = bnpToRadix
    proto.fromRadix = bnpFromRadix
    proto.fromNumber = bnpFromNumber
    proto.bitwiseTo = bnpBitwiseTo
    proto.changeBit = bnpChangeBit
    proto.addTo = bnpAddTo
    proto.dMultiply = bnpDMultiply
    proto.dAddOffset = bnpDAddOffset
    proto.multiplyLowerTo = bnpMultiplyLowerTo
    proto.multiplyUpperTo = bnpMultiplyUpperTo
    proto.modInt = bnpModInt
    
    // public
    proto.clone = bnClone
    proto.intValue = bnIntValue
    proto.byteValue = bnByteValue
    proto.shortValue = bnShortValue
    proto.signum = bnSigNum
    proto.toByteArray = bnToByteArray
    proto.equals = bnEquals
    proto.min = bnMin
    proto.max = bnMax
    proto.and = bnAnd
    proto.or = bnOr
    proto.xor = bnXor
    proto.andNot = bnAndNot
    proto.not = bnNot
    proto.shiftLeft = bnShiftLeft
    proto.shiftRight = bnShiftRight
    proto.getLowestSetBit = bnGetLowestSetBit
    proto.bitCount = bnBitCount
    proto.testBit = bnTestBit
    proto.setBit = bnSetBit
    proto.clearBit = bnClearBit
    proto.flipBit = bnFlipBit
    proto.add = bnAdd
    proto.subtract = bnSubtract
    proto.multiply = bnMultiply
    proto.divide = bnDivide
    proto.remainder = bnRemainder
    proto.divideAndRemainder = bnDivideAndRemainder
    proto.modPow = bnModPow
    proto.modInverse = bnModInverse
    proto.pow = bnPow
    proto.gcd = bnGCD
    
    // JSBN-specific extension
    proto.square = bnSquare
    
    // constants
    BigInteger.ZERO = nbv(0)
    BigInteger.ONE = nbv(1)
    BigInteger.valueOf = nbv
    
    module.exports = BigInteger
    
    },{"assert":5}],3:[function(_dereq_,module,exports){
    (function (Buffer){
    // FIXME: Kind of a weird way to throw exceptions, consider removing
    var assert = _dereq_('assert')
    var BigInteger = _dereq_('./bigi')
    
    /**
     * Turns a byte array into a big integer.
     *
     * This function will interpret a byte array as a big integer in big
     * endian notation.
     */
    BigInteger.fromByteArrayUnsigned = function(byteArray) {
      // BigInteger expects a DER integer conformant byte array
      if (byteArray[0] & 0x80) {
        return new BigInteger([0].concat(byteArray))
      }
    
      return new BigInteger(byteArray)
    }
    
    /**
     * Returns a byte array representation of the big integer.
     *
     * This returns the absolute of the contained value in big endian
     * form. A value of zero results in an empty array.
     */
    BigInteger.prototype.toByteArrayUnsigned = function() {
      var byteArray = this.toByteArray()
      return byteArray[0] === 0 ? byteArray.slice(1) : byteArray
    }
    
    BigInteger.fromDERInteger = function(byteArray) {
      return new BigInteger(byteArray)
    }
    
    /*
     * Converts BigInteger to a DER integer representation.
     *
     * The format for this value uses the most significant bit as a sign
     * bit.  If the most significant bit is already set and the integer is
     * positive, a 0x00 is prepended.
     *
     * Examples:
     *
     *      0 =>     0x00
     *      1 =>     0x01
     *     -1 =>     0xff
     *    127 =>     0x7f
     *   -127 =>     0x81
     *    128 =>   0x0080
     *   -128 =>     0x80
     *    255 =>   0x00ff
     *   -255 =>   0xff01
     *  16300 =>   0x3fac
     * -16300 =>   0xc054
     *  62300 => 0x00f35c
     * -62300 => 0xff0ca4
    */
    BigInteger.prototype.toDERInteger = BigInteger.prototype.toByteArray
    
    BigInteger.fromBuffer = function(buffer) {
      // BigInteger expects a DER integer conformant byte array
      if (buffer[0] & 0x80) {
        var byteArray = Array.prototype.slice.call(buffer)
    
        return new BigInteger([0].concat(byteArray))
      }
    
      return new BigInteger(buffer)
    }
    
    BigInteger.fromHex = function(hex) {
      if (hex === '') return BigInteger.ZERO
    
      assert.equal(hex, hex.match(/^[A-Fa-f0-9]+/), 'Invalid hex string')
      assert.equal(hex.length % 2, 0, 'Incomplete hex')
      return new BigInteger(hex, 16)
    }
    
    BigInteger.prototype.toBuffer = function(size) {
      var byteArray = this.toByteArrayUnsigned()
      var zeros = []
    
      var padding = size - byteArray.length
      while (zeros.length < padding) zeros.push(0)
    
      return new Buffer(zeros.concat(byteArray))
    }
    
    BigInteger.prototype.toHex = function(size) {
      return this.toBuffer(size).toString('hex')
    }
    
    }).call(this,_dereq_("buffer").Buffer)
    },{"./bigi":2,"assert":5,"buffer":8}],4:[function(_dereq_,module,exports){
    var BigInteger = _dereq_('./bigi')
    
    //addons
    _dereq_('./convert')
    
    module.exports = BigInteger
    },{"./bigi":2,"./convert":3}],5:[function(_dereq_,module,exports){
    // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
    //
    // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
    //
    // Originally from narwhal.js (http://narwhaljs.org)
    // Copyright (c) 2009 Thomas Robinson <280north.com>
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the 'Software'), to
    // deal in the Software without restriction, including without limitation the
    // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    // sell copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    // when used in node, this will actually load the util module we depend on
    // versus loading the builtin util module as happens otherwise
    // this is a bug in node module loading as far as I am concerned
    var util = _dereq_('util/');
    
    var pSlice = Array.prototype.slice;
    var hasOwn = Object.prototype.hasOwnProperty;
    
    // 1. The assert module provides functions that throw
    // AssertionError's when particular conditions are not met. The
    // assert module must conform to the following interface.
    
    var assert = module.exports = ok;
    
    // 2. The AssertionError is defined in assert.
    // new assert.AssertionError({ message: message,
    //                             actual: actual,
    //                             expected: expected })
    
    assert.AssertionError = function AssertionError(options) {
      this.name = 'AssertionError';
      this.actual = options.actual;
      this.expected = options.expected;
      this.operator = options.operator;
      if (options.message) {
        this.message = options.message;
        this.generatedMessage = false;
      } else {
        this.message = getMessage(this);
        this.generatedMessage = true;
      }
      var stackStartFunction = options.stackStartFunction || fail;
    
      if (Error.captureStackTrace) {
        Error.captureStackTrace(this, stackStartFunction);
      }
      else {
        // non v8 browsers so we can have a stacktrace
        var err = new Error();
        if (err.stack) {
          var out = err.stack;
    
          // try to strip useless frames
          var fn_name = stackStartFunction.name;
          var idx = out.indexOf('\n' + fn_name);
          if (idx >= 0) {
            // once we have located the function frame
            // we need to strip out everything before it (and its line)
            var next_line = out.indexOf('\n', idx + 1);
            out = out.substring(next_line + 1);
          }
    
          this.stack = out;
        }
      }
    };
    
    // assert.AssertionError instanceof Error
    util.inherits(assert.AssertionError, Error);
    
    function replacer(key, value) {
      if (util.isUndefined(value)) {
        return '' + value;
      }
      if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) {
        return value.toString();
      }
      if (util.isFunction(value) || util.isRegExp(value)) {
        return value.toString();
      }
      return value;
    }
    
    function truncate(s, n) {
      if (util.isString(s)) {
        return s.length < n ? s : s.slice(0, n);
      } else {
        return s;
      }
    }
    
    function getMessage(self) {
      return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
             self.operator + ' ' +
             truncate(JSON.stringify(self.expected, replacer), 128);
    }
    
    // At present only the three keys mentioned above are used and
    // understood by the spec. Implementations or sub modules can pass
    // other keys to the AssertionError's constructor - they will be
    // ignored.
    
    // 3. All of the following functions must throw an AssertionError
    // when a corresponding condition is not met, with a message that
    // may be undefined if not provided.  All assertion methods provide
    // both the actual and expected values to the assertion error for
    // display purposes.
    
    function fail(actual, expected, message, operator, stackStartFunction) {
      throw new assert.AssertionError({
        message: message,
        actual: actual,
        expected: expected,
        operator: operator,
        stackStartFunction: stackStartFunction
      });
    }
    
    // EXTENSION! allows for well behaved errors defined elsewhere.
    assert.fail = fail;
    
    // 4. Pure assertion tests whether a value is truthy, as determined
    // by !!guard.
    // assert.ok(guard, message_opt);
    // This statement is equivalent to assert.equal(true, !!guard,
    // message_opt);. To test strictly for the value true, use
    // assert.strictEqual(true, guard, message_opt);.
    
    function ok(value, message) {
      if (!value) fail(value, true, message, '==', assert.ok);
    }
    assert.ok = ok;
    
    // 5. The equality assertion tests shallow, coercive equality with
    // ==.
    // assert.equal(actual, expected, message_opt);
    
    assert.equal = function equal(actual, expected, message) {
      if (actual != expected) fail(actual, expected, message, '==', assert.equal);
    };
    
    // 6. The non-equality assertion tests for whether two objects are not equal
    // with != assert.notEqual(actual, expected, message_opt);
    
    assert.notEqual = function notEqual(actual, expected, message) {
      if (actual == expected) {
        fail(actual, expected, message, '!=', assert.notEqual);
      }
    };
    
    // 7. The equivalence assertion tests a deep equality relation.
    // assert.deepEqual(actual, expected, message_opt);
    
    assert.deepEqual = function deepEqual(actual, expected, message) {
      if (!_deepEqual(actual, expected)) {
        fail(actual, expected, message, 'deepEqual', assert.deepEqual);
      }
    };
    
    function _deepEqual(actual, expected) {
      // 7.1. All identical values are equivalent, as determined by ===.
      if (actual === expected) {
        return true;
    
      } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
        if (actual.length != expected.length) return false;
    
        for (var i = 0; i < actual.length; i++) {
          if (actual[i] !== expected[i]) return false;
        }
    
        return true;
    
      // 7.2. If the expected value is a Date object, the actual value is
      // equivalent if it is also a Date object that refers to the same time.
      } else if (util.isDate(actual) && util.isDate(expected)) {
        return actual.getTime() === expected.getTime();
    
      // 7.3 If the expected value is a RegExp object, the actual value is
      // equivalent if it is also a RegExp object with the same source and
      // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
      } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
        return actual.source === expected.source &&
               actual.global === expected.global &&
               actual.multiline === expected.multiline &&
               actual.lastIndex === expected.lastIndex &&
               actual.ignoreCase === expected.ignoreCase;
    
      // 7.4. Other pairs that do not both pass typeof value == 'object',
      // equivalence is determined by ==.
      } else if (!util.isObject(actual) && !util.isObject(expected)) {
        return actual == expected;
    
      // 7.5 For all other Object pairs, including Array objects, equivalence is
      // determined by having the same number of owned properties (as verified
      // with Object.prototype.hasOwnProperty.call), the same set of keys
      // (although not necessarily the same order), equivalent values for every
      // corresponding key, and an identical 'prototype' property. Note: this
      // accounts for both named and indexed properties on Arrays.
      } else {
        return objEquiv(actual, expected);
      }
    }
    
    function isArguments(object) {
      return Object.prototype.toString.call(object) == '[object Arguments]';
    }
    
    function objEquiv(a, b) {
      if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
        return false;
      // an identical 'prototype' property.
      if (a.prototype !== b.prototype) return false;
      //~~~I've managed to break Object.keys through screwy arguments passing.
      //   Converting to array solves the problem.
      if (isArguments(a)) {
        if (!isArguments(b)) {
          return false;
        }
        a = pSlice.call(a);
        b = pSlice.call(b);
        return _deepEqual(a, b);
      }
      try {
        var ka = objectKeys(a),
            kb = objectKeys(b),
            key, i;
      } catch (e) {//happens when one is a string literal and the other isn't
        return false;
      }
      // having the same number of owned properties (keys incorporates
      // hasOwnProperty)
      if (ka.length != kb.length)
        return false;
      //the same set of keys (although not necessarily the same order),
      ka.sort();
      kb.sort();
      //~~~cheap key test
      for (i = ka.length - 1; i >= 0; i--) {
        if (ka[i] != kb[i])
          return false;
      }
      //equivalent values for every corresponding key, and
      //~~~possibly expensive deep test
      for (i = ka.length - 1; i >= 0; i--) {
        key = ka[i];
        if (!_deepEqual(a[key], b[key])) return false;
      }
      return true;
    }
    
    // 8. The non-equivalence assertion tests for any deep inequality.
    // assert.notDeepEqual(actual, expected, message_opt);
    
    assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
      if (_deepEqual(actual, expected)) {
        fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
      }
    };
    
    // 9. The strict equality assertion tests strict equality, as determined by ===.
    // assert.strictEqual(actual, expected, message_opt);
    
    assert.strictEqual = function strictEqual(actual, expected, message) {
      if (actual !== expected) {
        fail(actual, expected, message, '===', assert.strictEqual);
      }
    };
    
    // 10. The strict non-equality assertion tests for strict inequality, as
    // determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
    
    assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
      if (actual === expected) {
        fail(actual, expected, message, '!==', assert.notStrictEqual);
      }
    };
    
    function expectedException(actual, expected) {
      if (!actual || !expected) {
        return false;
      }
    
      if (Object.prototype.toString.call(expected) == '[object RegExp]') {
        return expected.test(actual);
      } else if (actual instanceof expected) {
        return true;
      } else if (expected.call({}, actual) === true) {
        return true;
      }
    
      return false;
    }
    
    function _throws(shouldThrow, block, expected, message) {
      var actual;
    
      if (util.isString(expected)) {
        message = expected;
        expected = null;
      }
    
      try {
        block();
      } catch (e) {
        actual = e;
      }
    
      message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
                (message ? ' ' + message : '.');
    
      if (shouldThrow && !actual) {
        fail(actual, expected, 'Missing expected exception' + message);
      }
    
      if (!shouldThrow && expectedException(actual, expected)) {
        fail(actual, expected, 'Got unwanted exception' + message);
      }
    
      if ((shouldThrow && actual && expected &&
          !expectedException(actual, expected)) || (!shouldThrow && actual)) {
        throw actual;
      }
    }
    
    // 11. Expected to throw an error:
    // assert.throws(block, Error_opt, message_opt);
    
    assert.throws = function(block, /*optional*/error, /*optional*/message) {
      _throws.apply(this, [true].concat(pSlice.call(arguments)));
    };
    
    // EXTENSION! This is annoying to write outside this module.
    assert.doesNotThrow = function(block, /*optional*/message) {
      _throws.apply(this, [false].concat(pSlice.call(arguments)));
    };
    
    assert.ifError = function(err) { if (err) {throw err;}};
    
    var objectKeys = Object.keys || function (obj) {
      var keys = [];
      for (var key in obj) {
        if (hasOwn.call(obj, key)) keys.push(key);
      }
      return keys;
    };
    
    },{"util/":7}],6:[function(_dereq_,module,exports){
    module.exports = function isBuffer(arg) {
      return arg && typeof arg === 'object'
        && typeof arg.copy === 'function'
        && typeof arg.fill === 'function'
        && typeof arg.readUInt8 === 'function';
    }
    },{}],7:[function(_dereq_,module,exports){
    (function (process,global){
    // Copyright Joyent, Inc. and other Node contributors.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a
    // copy of this software and associated documentation files (the
    // "Software"), to deal in the Software without restriction, including
    // without limitation the rights to use, copy, modify, merge, publish,
    // distribute, sublicense, and/or sell copies of the Software, and to permit
    // persons to whom the Software is furnished to do so, subject to the
    // following conditions:
    //
    // The above copyright notice and this permission notice shall be included
    // in all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    // USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    var formatRegExp = /%[sdj%]/g;
    exports.format = function(f) {
      if (!isString(f)) {
        var objects = [];
        for (var i = 0; i < arguments.length; i++) {
          objects.push(inspect(arguments[i]));
        }
        return objects.join(' ');
      }
    
      var i = 1;
      var args = arguments;
      var len = args.length;
      var str = String(f).replace(formatRegExp, function(x) {
        if (x === '%%') return '%';
        if (i >= len) return x;
        switch (x) {
          case '%s': return String(args[i++]);
          case '%d': return Number(args[i++]);
          case '%j':
            try {
              return JSON.stringify(args[i++]);
            } catch (_) {
              return '[Circular]';
            }
          default:
            return x;
        }
      });
      for (var x = args[i]; i < len; x = args[++i]) {
        if (isNull(x) || !isObject(x)) {
          str += ' ' + x;
        } else {
          str += ' ' + inspect(x);
        }
      }
      return str;
    };
    
    
    // Mark that a method should not be used.
    // Returns a modified function which warns once by default.
    // If --no-deprecation is set, then it is a no-op.
    exports.deprecate = function(fn, msg) {
      // Allow for deprecating things in the process of starting up.
      if (isUndefined(global.process)) {
        return function() {
          return exports.deprecate(fn, msg).apply(this, arguments);
        };
      }
    
      if (process.noDeprecation === true) {
        return fn;
      }
    
      var warned = false;
      function deprecated() {
        if (!warned) {
          if (process.throwDeprecation) {
            throw new Error(msg);
          } else if (process.traceDeprecation) {
            console.trace(msg);
          } else {
            console.error(msg);
          }
          warned = true;
        }
        return fn.apply(this, arguments);
      }
    
      return deprecated;
    };
    
    
    var debugs = {};
    var debugEnviron;
    exports.debuglog = function(set) {
      if (isUndefined(debugEnviron))
        debugEnviron = process.env.NODE_DEBUG || '';
      set = set.toUpperCase();
      if (!debugs[set]) {
        if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
          var pid = process.pid;
          debugs[set] = function() {
            var msg = exports.format.apply(exports, arguments);
            console.error('%s %d: %s', set, pid, msg);
          };
        } else {
          debugs[set] = function() {};
        }
      }
      return debugs[set];
    };
    
    
    /**
     * Echos the value of a value. Trys to print the value out
     * in the best way possible given the different types.
     *
     * @param {Object} obj The object to print out.
     * @param {Object} opts Optional options object that alters the output.
     */
    /* legacy: obj, showHidden, depth, colors*/
    function inspect(obj, opts) {
      // default options
      var ctx = {
        seen: [],
        stylize: stylizeNoColor
      };
      // legacy...
      if (arguments.length >= 3) ctx.depth = arguments[2];
      if (arguments.length >= 4) ctx.colors = arguments[3];
      if (isBoolean(opts)) {
        // legacy...
        ctx.showHidden = opts;
      } else if (opts) {
        // got an "options" object
        exports._extend(ctx, opts);
      }
      // set default options
      if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
      if (isUndefined(ctx.depth)) ctx.depth = 2;
      if (isUndefined(ctx.colors)) ctx.colors = false;
      if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
      if (ctx.colors) ctx.stylize = stylizeWithColor;
      return formatValue(ctx, obj, ctx.depth);
    }
    exports.inspect = inspect;
    
    
    // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
    inspect.colors = {
      'bold' : [1, 22],
      'italic' : [3, 23],
      'underline' : [4, 24],
      'inverse' : [7, 27],
      'white' : [37, 39],
      'grey' : [90, 39],
      'black' : [30, 39],
      'blue' : [34, 39],
      'cyan' : [36, 39],
      'green' : [32, 39],
      'magenta' : [35, 39],
      'red' : [31, 39],
      'yellow' : [33, 39]
    };
    
    // Don't use 'blue' not visible on cmd.exe
    inspect.styles = {
      'special': 'cyan',
      'number': 'yellow',
      'boolean': 'yellow',
      'undefined': 'grey',
      'null': 'bold',
      'string': 'green',
      'date': 'magenta',
      // "name": intentionally not styling
      'regexp': 'red'
    };
    
    
    function stylizeWithColor(str, styleType) {
      var style = inspect.styles[styleType];
    
      if (style) {
        return '\u001b[' + inspect.colors[style][0] + 'm' + str +
               '\u001b[' + inspect.colors[style][1] + 'm';
      } else {
        return str;
      }
    }
    
    
    function stylizeNoColor(str, styleType) {
      return str;
    }
    
    
    function arrayToHash(array) {
      var hash = {};
    
      array.forEach(function(val, idx) {
        hash[val] = true;
      });
    
      return hash;
    }
    
    
    function formatValue(ctx, value, recurseTimes) {
      // Provide a hook for user-specified inspect functions.
      // Check that value is an object with an inspect function on it
      if (ctx.customInspect &&
          value &&
          isFunction(value.inspect) &&
          // Filter out the util module, it's inspect function is special
          value.inspect !== exports.inspect &&
          // Also filter out any prototype objects using the circular check.
          !(value.constructor && value.constructor.prototype === value)) {
        var ret = value.inspect(recurseTimes, ctx);
        if (!isString(ret)) {
          ret = formatValue(ctx, ret, recurseTimes);
        }
        return ret;
      }
    
      // Primitive types cannot have properties
      var primitive = formatPrimitive(ctx, value);
      if (primitive) {
        return primitive;
      }
    
      // Look up the keys of the object.
      var keys = Object.keys(value);
      var visibleKeys = arrayToHash(keys);
    
      if (ctx.showHidden) {
        keys = Object.getOwnPropertyNames(value);
      }
    
      // IE doesn't make error fields non-enumerable
      // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
      if (isError(value)
          && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
        return formatError(value);
      }
    
      // Some type of object without properties can be shortcutted.
      if (keys.length === 0) {
        if (isFunction(value)) {
          var name = value.name ? ': ' + value.name : '';
          return ctx.stylize('[Function' + name + ']', 'special');
        }
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        }
        if (isDate(value)) {
          return ctx.stylize(Date.prototype.toString.call(value), 'date');
        }
        if (isError(value)) {
          return formatError(value);
        }
      }
    
      var base = '', array = false, braces = ['{', '}'];
    
      // Make Array say that they are Array
      if (isArray(value)) {
        array = true;
        braces = ['[', ']'];
      }
    
      // Make functions say that they are functions
      if (isFunction(value)) {
        var n = value.name ? ': ' + value.name : '';
        base = ' [Function' + n + ']';
      }
    
      // Make RegExps say that they are RegExps
      if (isRegExp(value)) {
        base = ' ' + RegExp.prototype.toString.call(value);
      }
    
      // Make dates with properties first say the date
      if (isDate(value)) {
        base = ' ' + Date.prototype.toUTCString.call(value);
      }
    
      // Make error with message first say the error
      if (isError(value)) {
        base = ' ' + formatError(value);
      }
    
      if (keys.length === 0 && (!array || value.length == 0)) {
        return braces[0] + base + braces[1];
      }
    
      if (recurseTimes < 0) {
        if (isRegExp(value)) {
          return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
        } else {
          return ctx.stylize('[Object]', 'special');
        }
      }
    
      ctx.seen.push(value);
    
      var output;
      if (array) {
        output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
      } else {
        output = keys.map(function(key) {
          return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
        });
      }
    
      ctx.seen.pop();
    
      return reduceToSingleString(output, base, braces);
    }
    
    
    function formatPrimitive(ctx, value) {
      if (isUndefined(value))
        return ctx.stylize('undefined', 'undefined');
      if (isString(value)) {
        var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                                 .replace(/'/g, "\\'")
                                                 .replace(/\\"/g, '"') + '\'';
        return ctx.stylize(simple, 'string');
      }
      if (isNumber(value))
        return ctx.stylize('' + value, 'number');
      if (isBoolean(value))
        return ctx.stylize('' + value, 'boolean');
      // For some reason typeof null is "object", so special case here.
      if (isNull(value))
        return ctx.stylize('null', 'null');
    }
    
    
    function formatError(value) {
      return '[' + Error.prototype.toString.call(value) + ']';
    }
    
    
    function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
      var output = [];
      for (var i = 0, l = value.length; i < l; ++i) {
        if (hasOwnProperty(value, String(i))) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              String(i), true));
        } else {
          output.push('');
        }
      }
      keys.forEach(function(key) {
        if (!key.match(/^\d+$/)) {
          output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
              key, true));
        }
      });
      return output;
    }
    
    
    function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
      var name, str, desc;
      desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
      if (desc.get) {
        if (desc.set) {
          str = ctx.stylize('[Getter/Setter]', 'special');
        } else {
          str = ctx.stylize('[Getter]', 'special');
        }
      } else {
        if (desc.set) {
          str = ctx.stylize('[Setter]', 'special');
        }
      }
      if (!hasOwnProperty(visibleKeys, key)) {
        name = '[' + key + ']';
      }
      if (!str) {
        if (ctx.seen.indexOf(desc.value) < 0) {
          if (isNull(recurseTimes)) {
            str = formatValue(ctx, desc.value, null);
          } else {
            str = formatValue(ctx, desc.value, recurseTimes - 1);
          }
          if (str.indexOf('\n') > -1) {
            if (array) {
              str = str.split('\n').map(function(line) {
                return '  ' + line;
              }).join('\n').substr(2);
            } else {
              str = '\n' + str.split('\n').map(function(line) {
                return '   ' + line;
              }).join('\n');
            }
          }
        } else {
          str = ctx.stylize('[Circular]', 'special');
        }
      }
      if (isUndefined(name)) {
        if (array && key.match(/^\d+$/)) {
          return str;
        }
        name = JSON.stringify('' + key);
        if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
          name = name.substr(1, name.length - 2);
          name = ctx.stylize(name, 'name');
        } else {
          name = name.replace(/'/g, "\\'")
                     .replace(/\\"/g, '"')
                     .replace(/(^"|"$)/g, "'");
          name = ctx.stylize(name, 'string');
        }
      }
    
      return name + ': ' + str;
    }
    
    
    function reduceToSingleString(output, base, braces) {
      var numLinesEst = 0;
      var length = output.reduce(function(prev, cur) {
        numLinesEst++;
        if (cur.indexOf('\n') >= 0) numLinesEst++;
        return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
      }, 0);
    
      if (length > 60) {
        return braces[0] +
               (base === '' ? '' : base + '\n ') +
               ' ' +
               output.join(',\n  ') +
               ' ' +
               braces[1];
      }
    
      return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
    }
    
    
    // NOTE: These type checking functions intentionally don't use `instanceof`
    // because it is fragile and can be easily faked with `Object.create()`.
    function isArray(ar) {
      return Array.isArray(ar);
    }
    exports.isArray = isArray;
    
    function isBoolean(arg) {
      return typeof arg === 'boolean';
    }
    exports.isBoolean = isBoolean;
    
    function isNull(arg) {
      return arg === null;
    }
    exports.isNull = isNull;
    
    function isNullOrUndefined(arg) {
      return arg == null;
    }
    exports.isNullOrUndefined = isNullOrUndefined;
    
    function isNumber(arg) {
      return typeof arg === 'number';
    }
    exports.isNumber = isNumber;
    
    function isString(arg) {
      return typeof arg === 'string';
    }
    exports.isString = isString;
    
    function isSymbol(arg) {
      return typeof arg === 'symbol';
    }
    exports.isSymbol = isSymbol;
    
    function isUndefined(arg) {
      return arg === void 0;
    }
    exports.isUndefined = isUndefined;
    
    function isRegExp(re) {
      return isObject(re) && objectToString(re) === '[object RegExp]';
    }
    exports.isRegExp = isRegExp;
    
    function isObject(arg) {
      return typeof arg === 'object' && arg !== null;
    }
    exports.isObject = isObject;
    
    function isDate(d) {
      return isObject(d) && objectToString(d) === '[object Date]';
    }
    exports.isDate = isDate;
    
    function isError(e) {
      return isObject(e) &&
          (objectToString(e) === '[object Error]' || e instanceof Error);
    }
    exports.isError = isError;
    
    function isFunction(arg) {
      return typeof arg === 'function';
    }
    exports.isFunction = isFunction;
    
    function isPrimitive(arg) {
      return arg === null ||
             typeof arg === 'boolean' ||
             typeof arg === 'number' ||
             typeof arg === 'string' ||
             typeof arg === 'symbol' ||  // ES6 symbol
             typeof arg === 'undefined';
    }
    exports.isPrimitive = isPrimitive;
    
    exports.isBuffer = _dereq_('./support/isBuffer');
    
    function objectToString(o) {
      return Object.prototype.toString.call(o);
    }
    
    
    function pad(n) {
      return n < 10 ? '0' + n.toString(10) : n.toString(10);
    }
    
    
    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
                  'Oct', 'Nov', 'Dec'];
    
    // 26 Feb 16:19:34
    function timestamp() {
      var d = new Date();
      var time = [pad(d.getHours()),
                  pad(d.getMinutes()),
                  pad(d.getSeconds())].join(':');
      return [d.getDate(), months[d.getMonth()], time].join(' ');
    }
    
    
    // log is just a thin wrapper to console.log that prepends a timestamp
    exports.log = function() {
      console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
    };
    
    
    /**
     * Inherit the prototype methods from one constructor into another.
     *
     * The Function.prototype.inherits from lang.js rewritten as a standalone
     * function (not on Function.prototype). NOTE: If this file is to be loaded
     * during bootstrapping this function needs to be rewritten using some native
     * functions as prototype setup using normal JavaScript does not work as
     * expected during bootstrapping (see mirror.js in r114903).
     *
     * @param {function} ctor Constructor function which needs to inherit the
     *     prototype.
     * @param {function} superCtor Constructor function to inherit prototype from.
     */
    exports.inherits = _dereq_('inherits');
    
    exports._extend = function(origin, add) {
      // Don't do anything if add isn't an object
      if (!add || !isObject(add)) return origin;
    
      var keys = Object.keys(add);
      var i = keys.length;
      while (i--) {
        origin[keys[i]] = add[keys[i]];
      }
      return origin;
    };
    
    function hasOwnProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }
    
    }).call(this,_dereq_("UPikzY"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    },{"./support/isBuffer":6,"UPikzY":12,"inherits":11}],8:[function(_dereq_,module,exports){
    /*!
     * The buffer module from node.js, for the browser.
     *
     * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
     * @license  MIT
     */
    
    var base64 = _dereq_('base64-js')
    var ieee754 = _dereq_('ieee754')
    
    exports.Buffer = Buffer
    exports.SlowBuffer = Buffer
    exports.INSPECT_MAX_BYTES = 50
    Buffer.poolSize = 8192
    
    /**
     * If `Buffer._useTypedArrays`:
     *   === true    Use Uint8Array implementation (fastest)
     *   === false   Use Object implementation (compatible down to IE6)
     */
    Buffer._useTypedArrays = (function () {
      // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,
      // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding
      // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support
      // because we need to be able to add all the node Buffer API methods. This is an issue
      // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438
      try {
        var buf = new ArrayBuffer(0)
        var arr = new Uint8Array(buf)
        arr.foo = function () { return 42 }
        return 42 === arr.foo() &&
            typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`
      } catch (e) {
        return false
      }
    })()
    
    /**
     * Class: Buffer
     * =============
     *
     * The Buffer constructor returns instances of `Uint8Array` that are augmented
     * with function properties for all the node `Buffer` API functions. We use
     * `Uint8Array` so that square bracket notation works as expected -- it returns
     * a single octet.
     *
     * By augmenting the instances, we can avoid modifying the `Uint8Array`
     * prototype.
     */
    function Buffer (subject, encoding, noZero) {
      if (!(this instanceof Buffer))
        return new Buffer(subject, encoding, noZero)
    
      var type = typeof subject
    
      // Workaround: node's base64 implementation allows for non-padded strings
      // while base64-js does not.
      if (encoding === 'base64' && type === 'string') {
        subject = stringtrim(subject)
        while (subject.length % 4 !== 0) {
          subject = subject + '='
        }
      }
    
      // Find the length
      var length
      if (type === 'number')
        length = coerce(subject)
      else if (type === 'string')
        length = Buffer.byteLength(subject, encoding)
      else if (type === 'object')
        length = coerce(subject.length) // assume that object is array-like
      else
        throw new Error('First argument needs to be a number, array or string.')
    
      var buf
      if (Buffer._useTypedArrays) {
        // Preferred: Return an augmented `Uint8Array` instance for best performance
        buf = Buffer._augment(new Uint8Array(length))
      } else {
        // Fallback: Return THIS instance of Buffer (created by `new`)
        buf = this
        buf.length = length
        buf._isBuffer = true
      }
    
      var i
      if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {
        // Speed optimization -- use set if we're copying from a typed array
        buf._set(subject)
      } else if (isArrayish(subject)) {
        // Treat array-ish objects as a byte array
        if (Buffer.isBuffer(subject)) {
          for (i = 0; i < length; i++)
            buf[i] = subject.readUInt8(i)
        } else {
          for (i = 0; i < length; i++)
            buf[i] = ((subject[i] % 256) + 256) % 256
        }
      } else if (type === 'string') {
        buf.write(subject, 0, encoding)
      } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {
        for (i = 0; i < length; i++) {
          buf[i] = 0
        }
      }
    
      return buf
    }
    
    // STATIC METHODS
    // ==============
    
    Buffer.isEncoding = function (encoding) {
      switch (String(encoding).toLowerCase()) {
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'binary':
        case 'base64':
        case 'raw':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return true
        default:
          return false
      }
    }
    
    Buffer.isBuffer = function (b) {
      return !!(b !== null && b !== undefined && b._isBuffer)
    }
    
    Buffer.byteLength = function (str, encoding) {
      var ret
      str = str.toString()
      switch (encoding || 'utf8') {
        case 'hex':
          ret = str.length / 2
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8ToBytes(str).length
          break
        case 'ascii':
        case 'binary':
        case 'raw':
          ret = str.length
          break
        case 'base64':
          ret = base64ToBytes(str).length
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = str.length * 2
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.concat = function (list, totalLength) {
      assert(isArray(list), 'Usage: Buffer.concat(list[, length])')
    
      if (list.length === 0) {
        return new Buffer(0)
      } else if (list.length === 1) {
        return list[0]
      }
    
      var i
      if (totalLength === undefined) {
        totalLength = 0
        for (i = 0; i < list.length; i++) {
          totalLength += list[i].length
        }
      }
    
      var buf = new Buffer(totalLength)
      var pos = 0
      for (i = 0; i < list.length; i++) {
        var item = list[i]
        item.copy(buf, pos)
        pos += item.length
      }
      return buf
    }
    
    Buffer.compare = function (a, b) {
      assert(Buffer.isBuffer(a) && Buffer.isBuffer(b), 'Arguments must be Buffers')
      var x = a.length
      var y = b.length
      for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
      if (i !== len) {
        x = a[i]
        y = b[i]
      }
      if (x < y) {
        return -1
      }
      if (y < x) {
        return 1
      }
      return 0
    }
    
    // BUFFER INSTANCE METHODS
    // =======================
    
    function hexWrite (buf, string, offset, length) {
      offset = Number(offset) || 0
      var remaining = buf.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
    
      // must be an even number of digits
      var strLen = string.length
      assert(strLen % 2 === 0, 'Invalid hex string')
    
      if (length > strLen / 2) {
        length = strLen / 2
      }
      for (var i = 0; i < length; i++) {
        var byte = parseInt(string.substr(i * 2, 2), 16)
        assert(!isNaN(byte), 'Invalid hex string')
        buf[offset + i] = byte
      }
      return i
    }
    
    function utf8Write (buf, string, offset, length) {
      var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function asciiWrite (buf, string, offset, length) {
      var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function binaryWrite (buf, string, offset, length) {
      return asciiWrite(buf, string, offset, length)
    }
    
    function base64Write (buf, string, offset, length) {
      var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function utf16leWrite (buf, string, offset, length) {
      var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    Buffer.prototype.write = function (string, offset, length, encoding) {
      // Support both (string, offset, length, encoding)
      // and the legacy (string, encoding, offset, length)
      if (isFinite(offset)) {
        if (!isFinite(length)) {
          encoding = length
          length = undefined
        }
      } else {  // legacy
        var swap = encoding
        encoding = offset
        offset = length
        length = swap
      }
    
      offset = Number(offset) || 0
      var remaining = this.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
      encoding = String(encoding || 'utf8').toLowerCase()
    
      var ret
      switch (encoding) {
        case 'hex':
          ret = hexWrite(this, string, offset, length)
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8Write(this, string, offset, length)
          break
        case 'ascii':
          ret = asciiWrite(this, string, offset, length)
          break
        case 'binary':
          ret = binaryWrite(this, string, offset, length)
          break
        case 'base64':
          ret = base64Write(this, string, offset, length)
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = utf16leWrite(this, string, offset, length)
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.prototype.toString = function (encoding, start, end) {
      var self = this
    
      encoding = String(encoding || 'utf8').toLowerCase()
      start = Number(start) || 0
      end = (end === undefined) ? self.length : Number(end)
    
      // Fastpath empty strings
      if (end === start)
        return ''
    
      var ret
      switch (encoding) {
        case 'hex':
          ret = hexSlice(self, start, end)
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8Slice(self, start, end)
          break
        case 'ascii':
          ret = asciiSlice(self, start, end)
          break
        case 'binary':
          ret = binarySlice(self, start, end)
          break
        case 'base64':
          ret = base64Slice(self, start, end)
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = utf16leSlice(self, start, end)
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.prototype.toJSON = function () {
      return {
        type: 'Buffer',
        data: Array.prototype.slice.call(this._arr || this, 0)
      }
    }
    
    Buffer.prototype.equals = function (b) {
      assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
      return Buffer.compare(this, b) === 0
    }
    
    Buffer.prototype.compare = function (b) {
      assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
      return Buffer.compare(this, b)
    }
    
    // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
    Buffer.prototype.copy = function (target, target_start, start, end) {
      var source = this
    
      if (!start) start = 0
      if (!end && end !== 0) end = this.length
      if (!target_start) target_start = 0
    
      // Copy 0 bytes; we're done
      if (end === start) return
      if (target.length === 0 || source.length === 0) return
    
      // Fatal error conditions
      assert(end >= start, 'sourceEnd < sourceStart')
      assert(target_start >= 0 && target_start < target.length,
          'targetStart out of bounds')
      assert(start >= 0 && start < source.length, 'sourceStart out of bounds')
      assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')
    
      // Are we oob?
      if (end > this.length)
        end = this.length
      if (target.length - target_start < end - start)
        end = target.length - target_start + start
    
      var len = end - start
    
      if (len < 100 || !Buffer._useTypedArrays) {
        for (var i = 0; i < len; i++) {
          target[i + target_start] = this[i + start]
        }
      } else {
        target._set(this.subarray(start, start + len), target_start)
      }
    }
    
    function base64Slice (buf, start, end) {
      if (start === 0 && end === buf.length) {
        return base64.fromByteArray(buf)
      } else {
        return base64.fromByteArray(buf.slice(start, end))
      }
    }
    
    function utf8Slice (buf, start, end) {
      var res = ''
      var tmp = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; i++) {
        if (buf[i] <= 0x7F) {
          res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
          tmp = ''
        } else {
          tmp += '%' + buf[i].toString(16)
        }
      }
    
      return res + decodeUtf8Char(tmp)
    }
    
    function asciiSlice (buf, start, end) {
      var ret = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; i++) {
        ret += String.fromCharCode(buf[i])
      }
      return ret
    }
    
    function binarySlice (buf, start, end) {
      return asciiSlice(buf, start, end)
    }
    
    function hexSlice (buf, start, end) {
      var len = buf.length
    
      if (!start || start < 0) start = 0
      if (!end || end < 0 || end > len) end = len
    
      var out = ''
      for (var i = start; i < end; i++) {
        out += toHex(buf[i])
      }
      return out
    }
    
    function utf16leSlice (buf, start, end) {
      var bytes = buf.slice(start, end)
      var res = ''
      for (var i = 0; i < bytes.length; i += 2) {
        res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
      }
      return res
    }
    
    Buffer.prototype.slice = function (start, end) {
      var len = this.length
      start = clamp(start, len, 0)
      end = clamp(end, len, len)
    
      if (Buffer._useTypedArrays) {
        return Buffer._augment(this.subarray(start, end))
      } else {
        var sliceLen = end - start
        var newBuf = new Buffer(sliceLen, undefined, true)
        for (var i = 0; i < sliceLen; i++) {
          newBuf[i] = this[i + start]
        }
        return newBuf
      }
    }
    
    // `get` will be removed in Node 0.13+
    Buffer.prototype.get = function (offset) {
      console.log('.get() is deprecated. Access using array indexes instead.')
      return this.readUInt8(offset)
    }
    
    // `set` will be removed in Node 0.13+
    Buffer.prototype.set = function (v, offset) {
      console.log('.set() is deprecated. Access using array indexes instead.')
      return this.writeUInt8(v, offset)
    }
    
    Buffer.prototype.readUInt8 = function (offset, noAssert) {
      if (!noAssert) {
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'Trying to read beyond buffer length')
      }
    
      if (offset >= this.length)
        return
    
      return this[offset]
    }
    
    function readUInt16 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val
      if (littleEndian) {
        val = buf[offset]
        if (offset + 1 < len)
          val |= buf[offset + 1] << 8
      } else {
        val = buf[offset] << 8
        if (offset + 1 < len)
          val |= buf[offset + 1]
      }
      return val
    }
    
    Buffer.prototype.readUInt16LE = function (offset, noAssert) {
      return readUInt16(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readUInt16BE = function (offset, noAssert) {
      return readUInt16(this, offset, false, noAssert)
    }
    
    function readUInt32 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val
      if (littleEndian) {
        if (offset + 2 < len)
          val = buf[offset + 2] << 16
        if (offset + 1 < len)
          val |= buf[offset + 1] << 8
        val |= buf[offset]
        if (offset + 3 < len)
          val = val + (buf[offset + 3] << 24 >>> 0)
      } else {
        if (offset + 1 < len)
          val = buf[offset + 1] << 16
        if (offset + 2 < len)
          val |= buf[offset + 2] << 8
        if (offset + 3 < len)
          val |= buf[offset + 3]
        val = val + (buf[offset] << 24 >>> 0)
      }
      return val
    }
    
    Buffer.prototype.readUInt32LE = function (offset, noAssert) {
      return readUInt32(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readUInt32BE = function (offset, noAssert) {
      return readUInt32(this, offset, false, noAssert)
    }
    
    Buffer.prototype.readInt8 = function (offset, noAssert) {
      if (!noAssert) {
        assert(offset !== undefined && offset !== null,
            'missing offset')
        assert(offset < this.length, 'Trying to read beyond buffer length')
      }
    
      if (offset >= this.length)
        return
    
      var neg = this[offset] & 0x80
      if (neg)
        return (0xff - this[offset] + 1) * -1
      else
        return this[offset]
    }
    
    function readInt16 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val = readUInt16(buf, offset, littleEndian, true)
      var neg = val & 0x8000
      if (neg)
        return (0xffff - val + 1) * -1
      else
        return val
    }
    
    Buffer.prototype.readInt16LE = function (offset, noAssert) {
      return readInt16(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readInt16BE = function (offset, noAssert) {
      return readInt16(this, offset, false, noAssert)
    }
    
    function readInt32 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val = readUInt32(buf, offset, littleEndian, true)
      var neg = val & 0x80000000
      if (neg)
        return (0xffffffff - val + 1) * -1
      else
        return val
    }
    
    Buffer.prototype.readInt32LE = function (offset, noAssert) {
      return readInt32(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readInt32BE = function (offset, noAssert) {
      return readInt32(this, offset, false, noAssert)
    }
    
    function readFloat (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      return ieee754.read(buf, offset, littleEndian, 23, 4)
    }
    
    Buffer.prototype.readFloatLE = function (offset, noAssert) {
      return readFloat(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readFloatBE = function (offset, noAssert) {
      return readFloat(this, offset, false, noAssert)
    }
    
    function readDouble (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')
      }
    
      return ieee754.read(buf, offset, littleEndian, 52, 8)
    }
    
    Buffer.prototype.readDoubleLE = function (offset, noAssert) {
      return readDouble(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readDoubleBE = function (offset, noAssert) {
      return readDouble(this, offset, false, noAssert)
    }
    
    Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'trying to write beyond buffer length')
        verifuint(value, 0xff)
      }
    
      if (offset >= this.length) return
    
      this[offset] = value
      return offset + 1
    }
    
    function writeUInt16 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'trying to write beyond buffer length')
        verifuint(value, 0xffff)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {
        buf[offset + i] =
            (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
                (littleEndian ? i : 1 - i) * 8
      }
      return offset + 2
    }
    
    Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
      return writeUInt16(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
      return writeUInt16(this, value, offset, false, noAssert)
    }
    
    function writeUInt32 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'trying to write beyond buffer length')
        verifuint(value, 0xffffffff)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {
        buf[offset + i] =
            (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
      }
      return offset + 4
    }
    
    Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
      return writeUInt32(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
      return writeUInt32(this, value, offset, false, noAssert)
    }
    
    Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7f, -0x80)
      }
    
      if (offset >= this.length)
        return
    
      if (value >= 0)
        this.writeUInt8(value, offset, noAssert)
      else
        this.writeUInt8(0xff + value + 1, offset, noAssert)
      return offset + 1
    }
    
    function writeInt16 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7fff, -0x8000)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      if (value >= 0)
        writeUInt16(buf, value, offset, littleEndian, noAssert)
      else
        writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)
      return offset + 2
    }
    
    Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
      return writeInt16(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
      return writeInt16(this, value, offset, false, noAssert)
    }
    
    function writeInt32 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7fffffff, -0x80000000)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      if (value >= 0)
        writeUInt32(buf, value, offset, littleEndian, noAssert)
      else
        writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)
      return offset + 4
    }
    
    Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
      return writeInt32(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
      return writeInt32(this, value, offset, false, noAssert)
    }
    
    function writeFloat (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
        verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      ieee754.write(buf, value, offset, littleEndian, 23, 4)
      return offset + 4
    }
    
    Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
      return writeFloat(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
      return writeFloat(this, value, offset, false, noAssert)
    }
    
    function writeDouble (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 7 < buf.length,
            'Trying to write beyond buffer length')
        verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      ieee754.write(buf, value, offset, littleEndian, 52, 8)
      return offset + 8
    }
    
    Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
      return writeDouble(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
      return writeDouble(this, value, offset, false, noAssert)
    }
    
    // fill(value, start=0, end=buffer.length)
    Buffer.prototype.fill = function (value, start, end) {
      if (!value) value = 0
      if (!start) start = 0
      if (!end) end = this.length
    
      assert(end >= start, 'end < start')
    
      // Fill 0 bytes; we're done
      if (end === start) return
      if (this.length === 0) return
    
      assert(start >= 0 && start < this.length, 'start out of bounds')
      assert(end >= 0 && end <= this.length, 'end out of bounds')
    
      var i
      if (typeof value === 'number') {
        for (i = start; i < end; i++) {
          this[i] = value
        }
      } else {
        var bytes = utf8ToBytes(value.toString())
        var len = bytes.length
        for (i = start; i < end; i++) {
          this[i] = bytes[i % len]
        }
      }
    
      return this
    }
    
    Buffer.prototype.inspect = function () {
      var out = []
      var len = this.length
      for (var i = 0; i < len; i++) {
        out[i] = toHex(this[i])
        if (i === exports.INSPECT_MAX_BYTES) {
          out[i + 1] = '...'
          break
        }
      }
      return '<Buffer ' + out.join(' ') + '>'
    }
    
    /**
     * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
     * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
     */
    Buffer.prototype.toArrayBuffer = function () {
      if (typeof Uint8Array !== 'undefined') {
        if (Buffer._useTypedArrays) {
          return (new Buffer(this)).buffer
        } else {
          var buf = new Uint8Array(this.length)
          for (var i = 0, len = buf.length; i < len; i += 1) {
            buf[i] = this[i]
          }
          return buf.buffer
        }
      } else {
        throw new Error('Buffer.toArrayBuffer not supported in this browser')
      }
    }
    
    // HELPER FUNCTIONS
    // ================
    
    var BP = Buffer.prototype
    
    /**
     * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
     */
    Buffer._augment = function (arr) {
      arr._isBuffer = true
    
      // save reference to original Uint8Array get/set methods before overwriting
      arr._get = arr.get
      arr._set = arr.set
    
      // deprecated, will be removed in node 0.13+
      arr.get = BP.get
      arr.set = BP.set
    
      arr.write = BP.write
      arr.toString = BP.toString
      arr.toLocaleString = BP.toString
      arr.toJSON = BP.toJSON
      arr.equals = BP.equals
      arr.compare = BP.compare
      arr.copy = BP.copy
      arr.slice = BP.slice
      arr.readUInt8 = BP.readUInt8
      arr.readUInt16LE = BP.readUInt16LE
      arr.readUInt16BE = BP.readUInt16BE
      arr.readUInt32LE = BP.readUInt32LE
      arr.readUInt32BE = BP.readUInt32BE
      arr.readInt8 = BP.readInt8
      arr.readInt16LE = BP.readInt16LE
      arr.readInt16BE = BP.readInt16BE
      arr.readInt32LE = BP.readInt32LE
      arr.readInt32BE = BP.readInt32BE
      arr.readFloatLE = BP.readFloatLE
      arr.readFloatBE = BP.readFloatBE
      arr.readDoubleLE = BP.readDoubleLE
      arr.readDoubleBE = BP.readDoubleBE
      arr.writeUInt8 = BP.writeUInt8
      arr.writeUInt16LE = BP.writeUInt16LE
      arr.writeUInt16BE = BP.writeUInt16BE
      arr.writeUInt32LE = BP.writeUInt32LE
      arr.writeUInt32BE = BP.writeUInt32BE
      arr.writeInt8 = BP.writeInt8
      arr.writeInt16LE = BP.writeInt16LE
      arr.writeInt16BE = BP.writeInt16BE
      arr.writeInt32LE = BP.writeInt32LE
      arr.writeInt32BE = BP.writeInt32BE
      arr.writeFloatLE = BP.writeFloatLE
      arr.writeFloatBE = BP.writeFloatBE
      arr.writeDoubleLE = BP.writeDoubleLE
      arr.writeDoubleBE = BP.writeDoubleBE
      arr.fill = BP.fill
      arr.inspect = BP.inspect
      arr.toArrayBuffer = BP.toArrayBuffer
    
      return arr
    }
    
    function stringtrim (str) {
      if (str.trim) return str.trim()
      return str.replace(/^\s+|\s+$/g, '')
    }
    
    // slice(start, end)
    function clamp (index, len, defaultValue) {
      if (typeof index !== 'number') return defaultValue
      index = ~~index;  // Coerce to integer.
      if (index >= len) return len
      if (index >= 0) return index
      index += len
      if (index >= 0) return index
      return 0
    }
    
    function coerce (length) {
      // Coerce length to a number (possibly NaN), round up
      // in case it's fractional (e.g. 123.456) then do a
      // double negate to coerce a NaN to 0. Easy, right?
      length = ~~Math.ceil(+length)
      return length < 0 ? 0 : length
    }
    
    function isArray (subject) {
      return (Array.isArray || function (subject) {
        return Object.prototype.toString.call(subject) === '[object Array]'
      })(subject)
    }
    
    function isArrayish (subject) {
      return isArray(subject) || Buffer.isBuffer(subject) ||
          subject && typeof subject === 'object' &&
          typeof subject.length === 'number'
    }
    
    function toHex (n) {
      if (n < 16) return '0' + n.toString(16)
      return n.toString(16)
    }
    
    function utf8ToBytes (str) {
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        var b = str.charCodeAt(i)
        if (b <= 0x7F) {
          byteArray.push(b)
        } else {
          var start = i
          if (b >= 0xD800 && b <= 0xDFFF) i++
          var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')
          for (var j = 0; j < h.length; j++) {
            byteArray.push(parseInt(h[j], 16))
          }
        }
      }
      return byteArray
    }
    
    function asciiToBytes (str) {
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        // Node's code seems to be doing this and not & 0x7F..
        byteArray.push(str.charCodeAt(i) & 0xFF)
      }
      return byteArray
    }
    
    function utf16leToBytes (str) {
      var c, hi, lo
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        c = str.charCodeAt(i)
        hi = c >> 8
        lo = c % 256
        byteArray.push(lo)
        byteArray.push(hi)
      }
    
      return byteArray
    }
    
    function base64ToBytes (str) {
      return base64.toByteArray(str)
    }
    
    function blitBuffer (src, dst, offset, length) {
      for (var i = 0; i < length; i++) {
        if ((i + offset >= dst.length) || (i >= src.length))
          break
        dst[i + offset] = src[i]
      }
      return i
    }
    
    function decodeUtf8Char (str) {
      try {
        return decodeURIComponent(str)
      } catch (err) {
        return String.fromCharCode(0xFFFD) // UTF 8 invalid char
      }
    }
    
    /*
     * We have to make sure that the value is a valid integer. This means that it
     * is non-negative. It has no fractional component and that it does not
     * exceed the maximum allowed value.
     */
    function verifuint (value, max) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value >= 0, 'specified a negative value for writing an unsigned value')
      assert(value <= max, 'value is larger than maximum value for type')
      assert(Math.floor(value) === value, 'value has a fractional component')
    }
    
    function verifsint (value, max, min) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value <= max, 'value larger than maximum allowed value')
      assert(value >= min, 'value smaller than minimum allowed value')
      assert(Math.floor(value) === value, 'value has a fractional component')
    }
    
    function verifIEEE754 (value, max, min) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value <= max, 'value larger than maximum allowed value')
      assert(value >= min, 'value smaller than minimum allowed value')
    }
    
    function assert (test, message) {
      if (!test) throw new Error(message || 'Failed assertion')
    }
    
    },{"base64-js":9,"ieee754":10}],9:[function(_dereq_,module,exports){
    var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    
    ;(function (exports) {
        'use strict';
    
      var Arr = (typeof Uint8Array !== 'undefined')
        ? Uint8Array
        : Array
    
        var PLUS   = '+'.charCodeAt(0)
        var SLASH  = '/'.charCodeAt(0)
        var NUMBER = '0'.charCodeAt(0)
        var LOWER  = 'a'.charCodeAt(0)
        var UPPER  = 'A'.charCodeAt(0)
    
        function decode (elt) {
                var code = elt.charCodeAt(0)
                if (code === PLUS)
                        return 62 // '+'
                if (code === SLASH)
                        return 63 // '/'
                if (code < NUMBER)
                        return -1 //no match
                if (code < NUMBER + 10)
                        return code - NUMBER + 26 + 26
                if (code < UPPER + 26)
                        return code - UPPER
                if (code < LOWER + 26)
                        return code - LOWER + 26
        }
    
        function b64ToByteArray (b64) {
                var i, j, l, tmp, placeHolders, arr
    
                if (b64.length % 4 > 0) {
                        throw new Error('Invalid string. Length must be a multiple of 4')
                }
    
                // the number of equal signs (place holders)
                // if there are two placeholders, than the two characters before it
                // represent one byte
                // if there is only one, then the three characters before it represent 2 bytes
                // this is just a cheap hack to not do indexOf twice
                var len = b64.length
                placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
    
                // base64 is 4/3 + up to two characters of the original data
                arr = new Arr(b64.length * 3 / 4 - placeHolders)
    
                // if there are placeholders, only get up to the last complete 4 chars
                l = placeHolders > 0 ? b64.length - 4 : b64.length
    
                var L = 0
    
                function push (v) {
                        arr[L++] = v
                }
    
                for (i = 0, j = 0; i < l; i += 4, j += 3) {
                        tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
                        push((tmp & 0xFF0000) >> 16)
                        push((tmp & 0xFF00) >> 8)
                        push(tmp & 0xFF)
                }
    
                if (placeHolders === 2) {
                        tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
                        push(tmp & 0xFF)
                } else if (placeHolders === 1) {
                        tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
                        push((tmp >> 8) & 0xFF)
                        push(tmp & 0xFF)
                }
    
                return arr
        }
    
        function uint8ToBase64 (uint8) {
                var i,
                        extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
                        output = "",
                        temp, length
    
                function encode (num) {
                        return lookup.charAt(num)
                }
    
                function tripletToBase64 (num) {
                        return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
                }
    
                // go through the array every three bytes, we'll deal with trailing stuff later
                for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
                        temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
                        output += tripletToBase64(temp)
                }
    
                // pad the end with zeros, but make sure to not forget the extra bytes
                switch (extraBytes) {
                        case 1:
                                temp = uint8[uint8.length - 1]
                                output += encode(temp >> 2)
                                output += encode((temp << 4) & 0x3F)
                                output += '=='
                                break
                        case 2:
                                temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
                                output += encode(temp >> 10)
                                output += encode((temp >> 4) & 0x3F)
                                output += encode((temp << 2) & 0x3F)
                                output += '='
                                break
                }
    
                return output
        }
    
        exports.toByteArray = b64ToByteArray
        exports.fromByteArray = uint8ToBase64
    }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
    
    },{}],10:[function(_dereq_,module,exports){
    exports.read = function(buffer, offset, isLE, mLen, nBytes) {
      var e, m,
          eLen = nBytes * 8 - mLen - 1,
          eMax = (1 << eLen) - 1,
          eBias = eMax >> 1,
          nBits = -7,
          i = isLE ? (nBytes - 1) : 0,
          d = isLE ? -1 : 1,
          s = buffer[offset + i];
    
      i += d;
    
      e = s & ((1 << (-nBits)) - 1);
      s >>= (-nBits);
      nBits += eLen;
      for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
    
      m = e & ((1 << (-nBits)) - 1);
      e >>= (-nBits);
      nBits += mLen;
      for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
    
      if (e === 0) {
        e = 1 - eBias;
      } else if (e === eMax) {
        return m ? NaN : ((s ? -1 : 1) * Infinity);
      } else {
        m = m + Math.pow(2, mLen);
        e = e - eBias;
      }
      return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
    };
    
    exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
      var e, m, c,
          eLen = nBytes * 8 - mLen - 1,
          eMax = (1 << eLen) - 1,
          eBias = eMax >> 1,
          rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
          i = isLE ? 0 : (nBytes - 1),
          d = isLE ? 1 : -1,
          s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
    
      value = Math.abs(value);
    
      if (isNaN(value) || value === Infinity) {
        m = isNaN(value) ? 1 : 0;
        e = eMax;
      } else {
        e = Math.floor(Math.log(value) / Math.LN2);
        if (value * (c = Math.pow(2, -e)) < 1) {
          e--;
          c *= 2;
        }
        if (e + eBias >= 1) {
          value += rt / c;
        } else {
          value += rt * Math.pow(2, 1 - eBias);
        }
        if (value * c >= 2) {
          e++;
          c /= 2;
        }
    
        if (e + eBias >= eMax) {
          m = 0;
          e = eMax;
        } else if (e + eBias >= 1) {
          m = (value * c - 1) * Math.pow(2, mLen);
          e = e + eBias;
        } else {
          m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
          e = 0;
        }
      }
    
      for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
    
      e = (e << mLen) | m;
      eLen += mLen;
      for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
    
      buffer[offset + i - d] |= s * 128;
    };
    
    },{}],11:[function(_dereq_,module,exports){
    if (typeof Object.create === 'function') {
      // implementation from standard node.js 'util' module
      module.exports = function inherits(ctor, superCtor) {
        ctor.super_ = superCtor
        ctor.prototype = Object.create(superCtor.prototype, {
          constructor: {
            value: ctor,
            enumerable: false,
            writable: true,
            configurable: true
          }
        });
      };
    } else {
      // old school shim for old browsers
      module.exports = function inherits(ctor, superCtor) {
        ctor.super_ = superCtor
        var TempCtor = function () {}
        TempCtor.prototype = superCtor.prototype
        ctor.prototype = new TempCtor()
        ctor.prototype.constructor = ctor
      }
    }
    
    },{}],12:[function(_dereq_,module,exports){
    // shim for using process in browser
    
    var process = module.exports = {};
    
    process.nextTick = (function () {
        var canSetImmediate = typeof window !== 'undefined'
        && window.setImmediate;
        var canPost = typeof window !== 'undefined'
        && window.postMessage && window.addEventListener
        ;
    
        if (canSetImmediate) {
            return function (f) { return window.setImmediate(f) };
        }
    
        if (canPost) {
            var queue = [];
            window.addEventListener('message', function (ev) {
                var source = ev.source;
                if ((source === window || source === null) && ev.data === 'process-tick') {
                    ev.stopPropagation();
                    if (queue.length > 0) {
                        var fn = queue.shift();
                        fn();
                    }
                }
            }, true);
    
            return function nextTick(fn) {
                queue.push(fn);
                window.postMessage('process-tick', '*');
            };
        }
    
        return function nextTick(fn) {
            setTimeout(fn, 0);
        };
    })();
    
    process.title = 'browser';
    process.browser = true;
    process.env = {};
    process.argv = [];
    
    function noop() {}
    
    process.on = noop;
    process.addListener = noop;
    process.once = noop;
    process.off = noop;
    process.removeListener = noop;
    process.removeAllListeners = noop;
    process.emit = noop;
    
    process.binding = function (name) {
        throw new Error('process.binding is not supported');
    }
    
    // TODO(shtylman)
    process.cwd = function () { return '/' };
    process.chdir = function (dir) {
        throw new Error('process.chdir is not supported');
    };
    
    },{}]},{},[1])
    (1)
    });
    
    // Setup bs58_digit_array
    !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.bs58_digit_array=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
    (function (Buffer){
    var DigitArray = _dereq_('digit-array');
    
    'use strict'
    
    module.exports.decode = decode;
    module.exports.encode = encode;
    
    var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    var BASE = 58;
    
    /**
     * Encodes a node Buffer as base58.
     *
     * @param {Buffer} input The buffer to encode.
     *
     * @return {string} The input encoded as base58.
     */
    function encode (input) {
      // Handle the edge case for empty input.
      if(input.length == 0) return '';
    
      // Force the Buffer into an array of bytes.
      var bytes = Array.prototype.slice.apply(input);
    
      // Create a base58 DigitArray with the Buffer's array of big endian bytes.
      var value = new DigitArray(256, bytes).toBase(BASE);
    
      // Preserve leading padding characters.
      preservePadding(bytes, value.digits);
    
      // Encode the digits with the base58 alphabet.
      return value.encode(ALPHABET);
    }
    
    /**
     * Decodes a base58 string as a Buffer.
     *
     * @param {string} input The string to decode.
     *
     * @return {Buffer} The input decoded into a Buffer.
     */
    function decode (input) {
      // Handle the edge case for empty input.
      if(input.length == 0) return new Buffer([]);
    
      // Decode a DigitArray from the base58 encoded input.
      var value = DigitArray.decode(input, BASE, ALPHABET);
    
      // Convert the base58 digits into a byte array.
      var bytes = value.toBase(256).digits;
    
      // Preserve leading padding characters.
      preservePadding(value.digits.reverse(), bytes);
    
      // Create a Buffer with the little endian byte array.
      return new Buffer(bytes.reverse());
    }
    
    /**
     * Copies leading zero values between encoded arrays.
     *
     * @param {Array.<number>} original The big endian array to copy from.
     * @param {Array.<number>} result The little endian array to copy to.
     */ 
    function preservePadding(original, result) {
      // Preserve leading 0 bytes.
      for (var i = 0; i < original.length - 1 && original[i] == 0; i++) {
        result.push(0);
      }
    }
    
    }).call(this,_dereq_("buffer").Buffer)
    },{"buffer":6,"digit-array":2}],2:[function(_dereq_,module,exports){
    var Endianess = _dereq_('./endianess');
    var Utils = _dereq_('./utils');
    
    /**
     * A number represented as an array of digits of an arbitrary base.
     * @constructor
     *
     * Math: Let n ∈ N, b ∈ N, b >= 2, D = [d | d ∈ N and d < b].
     *       n = SUM(D[i] * b^i), where i ∈ N and i < |D|
     *         = (D[0] * b^0) + (D[1] * b^1) + ... + (D[|D|-1] * b^(|D|-1))
     *
     * @param {number} base The base used to store the digits.
     * @param {Array.<number> | number} [digits=[0]] The initial set of digits or value.
     * @param {Endianess} [endianess=Endianess.big] The endianess of the given digits.
     */
    var DigitArray = function(base, digits, endianess){
      Utils.checkBase(base);
      
      this.base = base;
      endianess = endianess || Endianess.big;
    
      if(typeof digits === 'number'){
        this.digits = [digits];
        this.normalize();
      } else {
        this.digits = (digits || [0]).slice();
        if(endianess === Endianess.big) this.digits.reverse();
      }
    };
    
    /**
     * Adds a value to the number represented by the DigitArray.
     * 
     * Math: Let m ∈ N.
     *       m + n = m + (D[0] * b^0) + (D[1] * b^1) + ... 
     *             = (m + D[0] * b^0) + (D[1] * b^1) + ...
     *             = (m * b^0 + D[0] * b^0) + (D[1] * b^1) + ...
     *             = ((m + D[0]) * b^0) + (D[1] * b^1) + ...
     *
     * @param {number} value The value to add.
     *
     * @return {DigitArray} this
     */
    DigitArray.prototype.add = function(value){
      this.digits[0] += value;
      return this.normalize();
    };
    
    /**
     * Multiplies a value with the number represented by the DigitArray.
     * 
     * Math: Let m ∈ N.
     *       m * n = m * ((D[0] * b^0) + (D[1] * b^1) + ... + (D[|D|-1] * b^(|D|-1)))
     *             = m * (D[0] * b^0) + m * (D[1] * b^1) + ... + m * (D[|D|-1] * b^(|D|-1)))
     *             = (m * D[0] * b^0) + (m * D[1] * b^1) + ... + (m * D[|D|-1] * b^(|D|-1)))
     *             = ((m * D[0]) * b^0) + ((m * D[1]) * b^1) + ... + ((m * D[|D|-1]) * b^(|D|-1)))
     *
     * @param {number} value The value to multiply.
     *
     * @return {DigitArray} this
     */
    DigitArray.prototype.multiply = function(value){
      this.digits = this.digits.map(function(digit){ return value * digit; });
      return this.normalize();
    };
    
    /**
     * Normalizes any digits that are larger than the base allows.
     *
     * Math: Let D' = [d | d ∈ N] and n' = n.
     *       n' = SUM(D'[i] * b^i), where i ∈ N and i < |D'|
     *          = (D'[0] * b^0) + (D'[1] * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1))
     *          = ((D[0] + q[0] * b) * b^0) + (D'[1] * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1)), where q[0] = floor(D'[0] / b)
     *          = (D[0] * b^0) + (q[0] * b^1) + (D'[1] * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1))
     *          = (D[0] * b^0) + ((q[0] + D'[1]) * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1))
     *          = (D[0] * b^0) + ((D[1] + q[1] * b) * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1)), where q[1] = floor((q[0] + D'[1]) / b)
     *          = (D[0] * b^0) + (D[1] * b^1) + (q[1] * b^2) + ... + (D'[|D'|-1] * b^(|D'|-1))
     *          = ...
     *          = (D[0] * b^0) + (D[1] * b^1) + ... + (q[j-1] * b^(j-1)) + (D'[j-1] * b^(j-1)) + ..., where j ∈ N and 0 < j < |D|
     *          = (D[0] * b^0) + (D[1] * b^1) + ... + ((D'[j-1] + q[j-1]) * b^(j-1)) + ...
     *          = (D[0] * b^0) + (D[1] * b^1) + ... + (D[j-1] + q[j] * b) * b^(j-1) + ..., where q[j] = floor((q[j-1] + D'[j]) / b)
     *          = ...
     *          = (D[0] * b^0) + (D[1] * b^1) + ... + (D[|D|-1] * b^(|D|-1)), when j = |D| - 1
     *
     * @return {DigitArray} this
     */
    DigitArray.prototype.normalize = function(){
      var carry = 0;
    
      for(var i = 0; carry > 0 || i < this.digits.length; i++){
        var result = Utils.divide((this.digits[i] || 0) + carry, this.base);
        this.digits[i] = result.remainder;
        carry = result.quotient;
      }
    
      return this;
    };
    
    /**
     * Converts the DigitArray to another base.
     *
     * Math: Let D' = [d | d ∈ N], n' = n, b' ∈ N, and b' >= 2.
     *       n' = SUM(D'[i] * b^i), where i ∈ N and i < |D'|
     *          = (D'[0] * b^0) + (D'[1] * b^1) + ... + (D'[|D'|-1] * b^(|D'|-1))
     *          = D'[0] + b' * (D'[1] + b' * (D'[2] + ... + b' * (D'[|D'|-1]) ... ))
     *          = ...
     *          = (D[0] * b^0) + (D[1] * b^1) + ... + (D[|D|-1] * b^(|D|-1))
     * 
     * @param {number} base The base use.
     *
     * @return {DigitArray} The DigitArray in the given base.
     */
    DigitArray.prototype.toBase = function(base){
      Utils.checkBase(base);
    
      var other = new DigitArray(base);
      for(var i = this.digits.length - 1; i >= 0; i--){
        other.multiply(this.base).add(this.digits[i]);
      }
    
      return other;
    };
    
    /**
     * Encodes the digits as text using an alphabet substitution.
     *
     * @param {string} alphabet The alphabet to encode the digits in.
     * @param {Endianess} [endianess=Endianess.big] The endianess of the encoded digits.
     *
     * @return {string} The DigitArray encoded as text.
     */
    DigitArray.prototype.encode = function(alphabet, endianess){
      Utils.checkAlphabet(this.base, alphabet);
    
      var digits = this.digits.map(function(digit){ return alphabet[digit]; });
    
      endianess = endianess || Endianess.big;
      if(endianess === Endianess.big) digits.reverse();
      
      return digits.join('');
    };
    
    /**
     * Creates a DigitArray from encoded text using an alphabet substitution.
     *
     * @param {string} text The text to decode.
     * @param {number} base The base the DigitArray was encoded in.
     * @param {string} alphabet The alphabet the DigitArray was encoded in.
     * @param {Endianess} [endianess=Endianess.big] The endianess of the encoded digits.
     *
     * @return {DigitArray} The decoded DigitArray.
     */
    DigitArray.decode = function(text, base, alphabet, endianess){
      Utils.checkAlphabet(base, alphabet);
    
      var digits = Utils.textToDigits(text, alphabet);
    
      endianess = endianess || Endianess.big;
      if(endianess === Endianess.little) digits.reverse();
    
      return new DigitArray(base, digits);
    };
    
    /**
     * Converts the value that a DigitArray represents to a number.
     *
     * Warning: DigitArrays representing values greater than MAX_INT will return an
     * approximated value due to JavaScript's implementation of the number type.
     * 
     * @return {number} The value of the DigitArray.
     */
    DigitArray.prototype.toNumber = function(){
      var number = 0;
    
      for(var i = this.digits.length - 1; i >= 0; i--){
        number = (number * this.base) + this.digits[i];
      }
    
      
      return number;
    };
    
    module.exports = DigitArray;
    
    },{"./endianess":3,"./utils":5}],3:[function(_dereq_,module,exports){
    /**
     * Endianess describes the order of significance of a sequence of digits.
     * 
     * @enum {string}
     */
    module.exports = {
      big: 'big',
      little: 'little'
    };
    
    },{}],4:[function(_dereq_,module,exports){
    // The largest integer that can be uniquely represented by JavaScript's number type.
    var MAX_INT = Math.pow(2, 53) - 1;
    
    // The smallest integer base that is practical for encoding values.
    var MIN_BASE = 2;
    
    // The largest integer that will not exceed MAX_INT during multiplication with itself.
    var MAX_BASE = Math.floor(Math.sqrt(MAX_INT));
    
    module.exports = {
      MAX_INT: MAX_INT,
      MIN_BASE: MIN_BASE,
      MAX_BASE: MAX_BASE
    };
    
    },{}],5:[function(_dereq_,module,exports){
    var LIMIT = _dereq_('./limit');
    
    /**
     * Throw an error if the base is invalid.
     *
     * @param {number} base The base size to check.
     */
    var checkBase = function(base){
      if(typeof base !== 'number' || base !== Math.floor(base)) throw('Expected the base to be an integer, but got (' + base + ').');
      if(base < LIMIT.MIN_BASE) throw('Expected a base greater than ' + LIMIT.MIN_BASE + ', but got (' + base + ').');
      if(base > LIMIT.MAX_BASE) throw('Expected a base less than ' + LIMIT.MAX_BASE + ', but got (' + base + ').');
    };
    
    /**
     * Throw an error if the alphabet size is smaller than the base size.
     *
     * @param {number} base The base size to check.
     */
    var checkAlphabet = function(base, alphabet){
      if(alphabet.length < base) throw('Alphabet must contain at least ' + base + ' numerals.');
    };
    
    /**
     * Converts a string to an array of alphabet indexes.
     * Throws an error if the text contains characters not in the alphabet.
     *
     * @param {string} text The text to convert to digits.
     * @param {string} alphabet The alphabet used to decode the text.
     *
     * @return {Array.<number>} The index of each character in the alphabet.
     */
    var textToDigits = function(text, alphabet){
      var map = {};
      alphabet.split('').forEach(function(numeral, index){ map[numeral] = index; });
    
      return text.split('').map(function(numeral){
        var digit = map[numeral];
        if (typeof digit !== 'number') throw('Input contains a character (' + numeral + ') not in the alphabet.');
        return digit;
      });
    };
    
    
    /**
     * Returns the quotient and remainder produced by dividing the dividend by the divisor.
     *
     * @param {number} divident The number that is being divided.
     * @param {number} divisor The number that the dividend will be divided by.
     *
     * @return { {quotient: number, remainder: number} }
     */
    var divide = function(dividend, divisor){
      var quotient = Math.floor(dividend / divisor);
      var remainder = dividend - (quotient * divisor);
      return {
        quotient: quotient,
        remainder: remainder
      };
    };
    
    module.exports = {
      checkBase: checkBase,
      checkAlphabet: checkAlphabet,
      textToDigits: textToDigits,
      divide: divide
    };
    
    },{"./limit":4}],6:[function(_dereq_,module,exports){
    /*!
     * The buffer module from node.js, for the browser.
     *
     * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
     * @license  MIT
     */
    
    var base64 = _dereq_('base64-js')
    var ieee754 = _dereq_('ieee754')
    
    exports.Buffer = Buffer
    exports.SlowBuffer = Buffer
    exports.INSPECT_MAX_BYTES = 50
    Buffer.poolSize = 8192
    
    /**
     * If `Buffer._useTypedArrays`:
     *   === true    Use Uint8Array implementation (fastest)
     *   === false   Use Object implementation (compatible down to IE6)
     */
    Buffer._useTypedArrays = (function () {
      // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+,
      // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding
      // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support
      // because we need to be able to add all the node Buffer API methods. This is an issue
      // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438
      try {
        var buf = new ArrayBuffer(0)
        var arr = new Uint8Array(buf)
        arr.foo = function () { return 42 }
        return 42 === arr.foo() &&
            typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray`
      } catch (e) {
        return false
      }
    })()
    
    /**
     * Class: Buffer
     * =============
     *
     * The Buffer constructor returns instances of `Uint8Array` that are augmented
     * with function properties for all the node `Buffer` API functions. We use
     * `Uint8Array` so that square bracket notation works as expected -- it returns
     * a single octet.
     *
     * By augmenting the instances, we can avoid modifying the `Uint8Array`
     * prototype.
     */
    function Buffer (subject, encoding, noZero) {
      if (!(this instanceof Buffer))
        return new Buffer(subject, encoding, noZero)
    
      var type = typeof subject
    
      // Workaround: node's base64 implementation allows for non-padded strings
      // while base64-js does not.
      if (encoding === 'base64' && type === 'string') {
        subject = stringtrim(subject)
        while (subject.length % 4 !== 0) {
          subject = subject + '='
        }
      }
    
      // Find the length
      var length
      if (type === 'number')
        length = coerce(subject)
      else if (type === 'string')
        length = Buffer.byteLength(subject, encoding)
      else if (type === 'object')
        length = coerce(subject.length) // assume that object is array-like
      else
        throw new Error('First argument needs to be a number, array or string.')
    
      var buf
      if (Buffer._useTypedArrays) {
        // Preferred: Return an augmented `Uint8Array` instance for best performance
        buf = Buffer._augment(new Uint8Array(length))
      } else {
        // Fallback: Return THIS instance of Buffer (created by `new`)
        buf = this
        buf.length = length
        buf._isBuffer = true
      }
    
      var i
      if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') {
        // Speed optimization -- use set if we're copying from a typed array
        buf._set(subject)
      } else if (isArrayish(subject)) {
        // Treat array-ish objects as a byte array
        if (Buffer.isBuffer(subject)) {
          for (i = 0; i < length; i++)
            buf[i] = subject.readUInt8(i)
        } else {
          for (i = 0; i < length; i++)
            buf[i] = ((subject[i] % 256) + 256) % 256
        }
      } else if (type === 'string') {
        buf.write(subject, 0, encoding)
      } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) {
        for (i = 0; i < length; i++) {
          buf[i] = 0
        }
      }
    
      return buf
    }
    
    // STATIC METHODS
    // ==============
    
    Buffer.isEncoding = function (encoding) {
      switch (String(encoding).toLowerCase()) {
        case 'hex':
        case 'utf8':
        case 'utf-8':
        case 'ascii':
        case 'binary':
        case 'base64':
        case 'raw':
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return true
        default:
          return false
      }
    }
    
    Buffer.isBuffer = function (b) {
      return !!(b !== null && b !== undefined && b._isBuffer)
    }
    
    Buffer.byteLength = function (str, encoding) {
      var ret
      str = str.toString()
      switch (encoding || 'utf8') {
        case 'hex':
          ret = str.length / 2
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8ToBytes(str).length
          break
        case 'ascii':
        case 'binary':
        case 'raw':
          ret = str.length
          break
        case 'base64':
          ret = base64ToBytes(str).length
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = str.length * 2
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.concat = function (list, totalLength) {
      assert(isArray(list), 'Usage: Buffer.concat(list[, length])')
    
      if (list.length === 0) {
        return new Buffer(0)
      } else if (list.length === 1) {
        return list[0]
      }
    
      var i
      if (totalLength === undefined) {
        totalLength = 0
        for (i = 0; i < list.length; i++) {
          totalLength += list[i].length
        }
      }
    
      var buf = new Buffer(totalLength)
      var pos = 0
      for (i = 0; i < list.length; i++) {
        var item = list[i]
        item.copy(buf, pos)
        pos += item.length
      }
      return buf
    }
    
    Buffer.compare = function (a, b) {
      assert(Buffer.isBuffer(a) && Buffer.isBuffer(b), 'Arguments must be Buffers')
      var x = a.length
      var y = b.length
      for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {}
      if (i !== len) {
        x = a[i]
        y = b[i]
      }
      if (x < y) {
        return -1
      }
      if (y < x) {
        return 1
      }
      return 0
    }
    
    // BUFFER INSTANCE METHODS
    // =======================
    
    function hexWrite (buf, string, offset, length) {
      offset = Number(offset) || 0
      var remaining = buf.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
    
      // must be an even number of digits
      var strLen = string.length
      assert(strLen % 2 === 0, 'Invalid hex string')
    
      if (length > strLen / 2) {
        length = strLen / 2
      }
      for (var i = 0; i < length; i++) {
        var byte = parseInt(string.substr(i * 2, 2), 16)
        assert(!isNaN(byte), 'Invalid hex string')
        buf[offset + i] = byte
      }
      return i
    }
    
    function utf8Write (buf, string, offset, length) {
      var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function asciiWrite (buf, string, offset, length) {
      var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function binaryWrite (buf, string, offset, length) {
      return asciiWrite(buf, string, offset, length)
    }
    
    function base64Write (buf, string, offset, length) {
      var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    function utf16leWrite (buf, string, offset, length) {
      var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length)
      return charsWritten
    }
    
    Buffer.prototype.write = function (string, offset, length, encoding) {
      // Support both (string, offset, length, encoding)
      // and the legacy (string, encoding, offset, length)
      if (isFinite(offset)) {
        if (!isFinite(length)) {
          encoding = length
          length = undefined
        }
      } else {  // legacy
        var swap = encoding
        encoding = offset
        offset = length
        length = swap
      }
    
      offset = Number(offset) || 0
      var remaining = this.length - offset
      if (!length) {
        length = remaining
      } else {
        length = Number(length)
        if (length > remaining) {
          length = remaining
        }
      }
      encoding = String(encoding || 'utf8').toLowerCase()
    
      var ret
      switch (encoding) {
        case 'hex':
          ret = hexWrite(this, string, offset, length)
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8Write(this, string, offset, length)
          break
        case 'ascii':
          ret = asciiWrite(this, string, offset, length)
          break
        case 'binary':
          ret = binaryWrite(this, string, offset, length)
          break
        case 'base64':
          ret = base64Write(this, string, offset, length)
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = utf16leWrite(this, string, offset, length)
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.prototype.toString = function (encoding, start, end) {
      var self = this
    
      encoding = String(encoding || 'utf8').toLowerCase()
      start = Number(start) || 0
      end = (end === undefined) ? self.length : Number(end)
    
      // Fastpath empty strings
      if (end === start)
        return ''
    
      var ret
      switch (encoding) {
        case 'hex':
          ret = hexSlice(self, start, end)
          break
        case 'utf8':
        case 'utf-8':
          ret = utf8Slice(self, start, end)
          break
        case 'ascii':
          ret = asciiSlice(self, start, end)
          break
        case 'binary':
          ret = binarySlice(self, start, end)
          break
        case 'base64':
          ret = base64Slice(self, start, end)
          break
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          ret = utf16leSlice(self, start, end)
          break
        default:
          throw new Error('Unknown encoding')
      }
      return ret
    }
    
    Buffer.prototype.toJSON = function () {
      return {
        type: 'Buffer',
        data: Array.prototype.slice.call(this._arr || this, 0)
      }
    }
    
    Buffer.prototype.equals = function (b) {
      assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
      return Buffer.compare(this, b) === 0
    }
    
    Buffer.prototype.compare = function (b) {
      assert(Buffer.isBuffer(b), 'Argument must be a Buffer')
      return Buffer.compare(this, b)
    }
    
    // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
    Buffer.prototype.copy = function (target, target_start, start, end) {
      var source = this
    
      if (!start) start = 0
      if (!end && end !== 0) end = this.length
      if (!target_start) target_start = 0
    
      // Copy 0 bytes; we're done
      if (end === start) return
      if (target.length === 0 || source.length === 0) return
    
      // Fatal error conditions
      assert(end >= start, 'sourceEnd < sourceStart')
      assert(target_start >= 0 && target_start < target.length,
          'targetStart out of bounds')
      assert(start >= 0 && start < source.length, 'sourceStart out of bounds')
      assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds')
    
      // Are we oob?
      if (end > this.length)
        end = this.length
      if (target.length - target_start < end - start)
        end = target.length - target_start + start
    
      var len = end - start
    
      if (len < 100 || !Buffer._useTypedArrays) {
        for (var i = 0; i < len; i++) {
          target[i + target_start] = this[i + start]
        }
      } else {
        target._set(this.subarray(start, start + len), target_start)
      }
    }
    
    function base64Slice (buf, start, end) {
      if (start === 0 && end === buf.length) {
        return base64.fromByteArray(buf)
      } else {
        return base64.fromByteArray(buf.slice(start, end))
      }
    }
    
    function utf8Slice (buf, start, end) {
      var res = ''
      var tmp = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; i++) {
        if (buf[i] <= 0x7F) {
          res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
          tmp = ''
        } else {
          tmp += '%' + buf[i].toString(16)
        }
      }
    
      return res + decodeUtf8Char(tmp)
    }
    
    function asciiSlice (buf, start, end) {
      var ret = ''
      end = Math.min(buf.length, end)
    
      for (var i = start; i < end; i++) {
        ret += String.fromCharCode(buf[i])
      }
      return ret
    }
    
    function binarySlice (buf, start, end) {
      return asciiSlice(buf, start, end)
    }
    
    function hexSlice (buf, start, end) {
      var len = buf.length
    
      if (!start || start < 0) start = 0
      if (!end || end < 0 || end > len) end = len
    
      var out = ''
      for (var i = start; i < end; i++) {
        out += toHex(buf[i])
      }
      return out
    }
    
    function utf16leSlice (buf, start, end) {
      var bytes = buf.slice(start, end)
      var res = ''
      for (var i = 0; i < bytes.length; i += 2) {
        res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
      }
      return res
    }
    
    Buffer.prototype.slice = function (start, end) {
      var len = this.length
      start = clamp(start, len, 0)
      end = clamp(end, len, len)
    
      if (Buffer._useTypedArrays) {
        return Buffer._augment(this.subarray(start, end))
      } else {
        var sliceLen = end - start
        var newBuf = new Buffer(sliceLen, undefined, true)
        for (var i = 0; i < sliceLen; i++) {
          newBuf[i] = this[i + start]
        }
        return newBuf
      }
    }
    
    // `get` will be removed in Node 0.13+
    Buffer.prototype.get = function (offset) {
      console.log('.get() is deprecated. Access using array indexes instead.')
      return this.readUInt8(offset)
    }
    
    // `set` will be removed in Node 0.13+
    Buffer.prototype.set = function (v, offset) {
      console.log('.set() is deprecated. Access using array indexes instead.')
      return this.writeUInt8(v, offset)
    }
    
    Buffer.prototype.readUInt8 = function (offset, noAssert) {
      if (!noAssert) {
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'Trying to read beyond buffer length')
      }
    
      if (offset >= this.length)
        return
    
      return this[offset]
    }
    
    function readUInt16 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val
      if (littleEndian) {
        val = buf[offset]
        if (offset + 1 < len)
          val |= buf[offset + 1] << 8
      } else {
        val = buf[offset] << 8
        if (offset + 1 < len)
          val |= buf[offset + 1]
      }
      return val
    }
    
    Buffer.prototype.readUInt16LE = function (offset, noAssert) {
      return readUInt16(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readUInt16BE = function (offset, noAssert) {
      return readUInt16(this, offset, false, noAssert)
    }
    
    function readUInt32 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val
      if (littleEndian) {
        if (offset + 2 < len)
          val = buf[offset + 2] << 16
        if (offset + 1 < len)
          val |= buf[offset + 1] << 8
        val |= buf[offset]
        if (offset + 3 < len)
          val = val + (buf[offset + 3] << 24 >>> 0)
      } else {
        if (offset + 1 < len)
          val = buf[offset + 1] << 16
        if (offset + 2 < len)
          val |= buf[offset + 2] << 8
        if (offset + 3 < len)
          val |= buf[offset + 3]
        val = val + (buf[offset] << 24 >>> 0)
      }
      return val
    }
    
    Buffer.prototype.readUInt32LE = function (offset, noAssert) {
      return readUInt32(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readUInt32BE = function (offset, noAssert) {
      return readUInt32(this, offset, false, noAssert)
    }
    
    Buffer.prototype.readInt8 = function (offset, noAssert) {
      if (!noAssert) {
        assert(offset !== undefined && offset !== null,
            'missing offset')
        assert(offset < this.length, 'Trying to read beyond buffer length')
      }
    
      if (offset >= this.length)
        return
    
      var neg = this[offset] & 0x80
      if (neg)
        return (0xff - this[offset] + 1) * -1
      else
        return this[offset]
    }
    
    function readInt16 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val = readUInt16(buf, offset, littleEndian, true)
      var neg = val & 0x8000
      if (neg)
        return (0xffff - val + 1) * -1
      else
        return val
    }
    
    Buffer.prototype.readInt16LE = function (offset, noAssert) {
      return readInt16(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readInt16BE = function (offset, noAssert) {
      return readInt16(this, offset, false, noAssert)
    }
    
    function readInt32 (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      var val = readUInt32(buf, offset, littleEndian, true)
      var neg = val & 0x80000000
      if (neg)
        return (0xffffffff - val + 1) * -1
      else
        return val
    }
    
    Buffer.prototype.readInt32LE = function (offset, noAssert) {
      return readInt32(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readInt32BE = function (offset, noAssert) {
      return readInt32(this, offset, false, noAssert)
    }
    
    function readFloat (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset + 3 < buf.length, 'Trying to read beyond buffer length')
      }
    
      return ieee754.read(buf, offset, littleEndian, 23, 4)
    }
    
    Buffer.prototype.readFloatLE = function (offset, noAssert) {
      return readFloat(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readFloatBE = function (offset, noAssert) {
      return readFloat(this, offset, false, noAssert)
    }
    
    function readDouble (buf, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset + 7 < buf.length, 'Trying to read beyond buffer length')
      }
    
      return ieee754.read(buf, offset, littleEndian, 52, 8)
    }
    
    Buffer.prototype.readDoubleLE = function (offset, noAssert) {
      return readDouble(this, offset, true, noAssert)
    }
    
    Buffer.prototype.readDoubleBE = function (offset, noAssert) {
      return readDouble(this, offset, false, noAssert)
    }
    
    Buffer.prototype.writeUInt8 = function (value, offset, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'trying to write beyond buffer length')
        verifuint(value, 0xff)
      }
    
      if (offset >= this.length) return
    
      this[offset] = value
      return offset + 1
    }
    
    function writeUInt16 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'trying to write beyond buffer length')
        verifuint(value, 0xffff)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) {
        buf[offset + i] =
            (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
                (littleEndian ? i : 1 - i) * 8
      }
      return offset + 2
    }
    
    Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) {
      return writeUInt16(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) {
      return writeUInt16(this, value, offset, false, noAssert)
    }
    
    function writeUInt32 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'trying to write beyond buffer length')
        verifuint(value, 0xffffffff)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) {
        buf[offset + i] =
            (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
      }
      return offset + 4
    }
    
    Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) {
      return writeUInt32(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) {
      return writeUInt32(this, value, offset, false, noAssert)
    }
    
    Buffer.prototype.writeInt8 = function (value, offset, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset < this.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7f, -0x80)
      }
    
      if (offset >= this.length)
        return
    
      if (value >= 0)
        this.writeUInt8(value, offset, noAssert)
      else
        this.writeUInt8(0xff + value + 1, offset, noAssert)
      return offset + 1
    }
    
    function writeInt16 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 1 < buf.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7fff, -0x8000)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      if (value >= 0)
        writeUInt16(buf, value, offset, littleEndian, noAssert)
      else
        writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert)
      return offset + 2
    }
    
    Buffer.prototype.writeInt16LE = function (value, offset, noAssert) {
      return writeInt16(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeInt16BE = function (value, offset, noAssert) {
      return writeInt16(this, value, offset, false, noAssert)
    }
    
    function writeInt32 (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
        verifsint(value, 0x7fffffff, -0x80000000)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      if (value >= 0)
        writeUInt32(buf, value, offset, littleEndian, noAssert)
      else
        writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert)
      return offset + 4
    }
    
    Buffer.prototype.writeInt32LE = function (value, offset, noAssert) {
      return writeInt32(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeInt32BE = function (value, offset, noAssert) {
      return writeInt32(this, value, offset, false, noAssert)
    }
    
    function writeFloat (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 3 < buf.length, 'Trying to write beyond buffer length')
        verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      ieee754.write(buf, value, offset, littleEndian, 23, 4)
      return offset + 4
    }
    
    Buffer.prototype.writeFloatLE = function (value, offset, noAssert) {
      return writeFloat(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeFloatBE = function (value, offset, noAssert) {
      return writeFloat(this, value, offset, false, noAssert)
    }
    
    function writeDouble (buf, value, offset, littleEndian, noAssert) {
      if (!noAssert) {
        assert(value !== undefined && value !== null, 'missing value')
        assert(typeof littleEndian === 'boolean', 'missing or invalid endian')
        assert(offset !== undefined && offset !== null, 'missing offset')
        assert(offset + 7 < buf.length,
            'Trying to write beyond buffer length')
        verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308)
      }
    
      var len = buf.length
      if (offset >= len)
        return
    
      ieee754.write(buf, value, offset, littleEndian, 52, 8)
      return offset + 8
    }
    
    Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) {
      return writeDouble(this, value, offset, true, noAssert)
    }
    
    Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) {
      return writeDouble(this, value, offset, false, noAssert)
    }
    
    // fill(value, start=0, end=buffer.length)
    Buffer.prototype.fill = function (value, start, end) {
      if (!value) value = 0
      if (!start) start = 0
      if (!end) end = this.length
    
      assert(end >= start, 'end < start')
    
      // Fill 0 bytes; we're done
      if (end === start) return
      if (this.length === 0) return
    
      assert(start >= 0 && start < this.length, 'start out of bounds')
      assert(end >= 0 && end <= this.length, 'end out of bounds')
    
      var i
      if (typeof value === 'number') {
        for (i = start; i < end; i++) {
          this[i] = value
        }
      } else {
        var bytes = utf8ToBytes(value.toString())
        var len = bytes.length
        for (i = start; i < end; i++) {
          this[i] = bytes[i % len]
        }
      }
    
      return this
    }
    
    Buffer.prototype.inspect = function () {
      var out = []
      var len = this.length
      for (var i = 0; i < len; i++) {
        out[i] = toHex(this[i])
        if (i === exports.INSPECT_MAX_BYTES) {
          out[i + 1] = '...'
          break
        }
      }
      return '<Buffer ' + out.join(' ') + '>'
    }
    
    /**
     * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
     * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
     */
    Buffer.prototype.toArrayBuffer = function () {
      if (typeof Uint8Array !== 'undefined') {
        if (Buffer._useTypedArrays) {
          return (new Buffer(this)).buffer
        } else {
          var buf = new Uint8Array(this.length)
          for (var i = 0, len = buf.length; i < len; i += 1) {
            buf[i] = this[i]
          }
          return buf.buffer
        }
      } else {
        throw new Error('Buffer.toArrayBuffer not supported in this browser')
      }
    }
    
    // HELPER FUNCTIONS
    // ================
    
    var BP = Buffer.prototype
    
    /**
     * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
     */
    Buffer._augment = function (arr) {
      arr._isBuffer = true
    
      // save reference to original Uint8Array get/set methods before overwriting
      arr._get = arr.get
      arr._set = arr.set
    
      // deprecated, will be removed in node 0.13+
      arr.get = BP.get
      arr.set = BP.set
    
      arr.write = BP.write
      arr.toString = BP.toString
      arr.toLocaleString = BP.toString
      arr.toJSON = BP.toJSON
      arr.equals = BP.equals
      arr.compare = BP.compare
      arr.copy = BP.copy
      arr.slice = BP.slice
      arr.readUInt8 = BP.readUInt8
      arr.readUInt16LE = BP.readUInt16LE
      arr.readUInt16BE = BP.readUInt16BE
      arr.readUInt32LE = BP.readUInt32LE
      arr.readUInt32BE = BP.readUInt32BE
      arr.readInt8 = BP.readInt8
      arr.readInt16LE = BP.readInt16LE
      arr.readInt16BE = BP.readInt16BE
      arr.readInt32LE = BP.readInt32LE
      arr.readInt32BE = BP.readInt32BE
      arr.readFloatLE = BP.readFloatLE
      arr.readFloatBE = BP.readFloatBE
      arr.readDoubleLE = BP.readDoubleLE
      arr.readDoubleBE = BP.readDoubleBE
      arr.writeUInt8 = BP.writeUInt8
      arr.writeUInt16LE = BP.writeUInt16LE
      arr.writeUInt16BE = BP.writeUInt16BE
      arr.writeUInt32LE = BP.writeUInt32LE
      arr.writeUInt32BE = BP.writeUInt32BE
      arr.writeInt8 = BP.writeInt8
      arr.writeInt16LE = BP.writeInt16LE
      arr.writeInt16BE = BP.writeInt16BE
      arr.writeInt32LE = BP.writeInt32LE
      arr.writeInt32BE = BP.writeInt32BE
      arr.writeFloatLE = BP.writeFloatLE
      arr.writeFloatBE = BP.writeFloatBE
      arr.writeDoubleLE = BP.writeDoubleLE
      arr.writeDoubleBE = BP.writeDoubleBE
      arr.fill = BP.fill
      arr.inspect = BP.inspect
      arr.toArrayBuffer = BP.toArrayBuffer
    
      return arr
    }
    
    function stringtrim (str) {
      if (str.trim) return str.trim()
      return str.replace(/^\s+|\s+$/g, '')
    }
    
    // slice(start, end)
    function clamp (index, len, defaultValue) {
      if (typeof index !== 'number') return defaultValue
      index = ~~index;  // Coerce to integer.
      if (index >= len) return len
      if (index >= 0) return index
      index += len
      if (index >= 0) return index
      return 0
    }
    
    function coerce (length) {
      // Coerce length to a number (possibly NaN), round up
      // in case it's fractional (e.g. 123.456) then do a
      // double negate to coerce a NaN to 0. Easy, right?
      length = ~~Math.ceil(+length)
      return length < 0 ? 0 : length
    }
    
    function isArray (subject) {
      return (Array.isArray || function (subject) {
        return Object.prototype.toString.call(subject) === '[object Array]'
      })(subject)
    }
    
    function isArrayish (subject) {
      return isArray(subject) || Buffer.isBuffer(subject) ||
          subject && typeof subject === 'object' &&
          typeof subject.length === 'number'
    }
    
    function toHex (n) {
      if (n < 16) return '0' + n.toString(16)
      return n.toString(16)
    }
    
    function utf8ToBytes (str) {
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        var b = str.charCodeAt(i)
        if (b <= 0x7F) {
          byteArray.push(b)
        } else {
          var start = i
          if (b >= 0xD800 && b <= 0xDFFF) i++
          var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%')
          for (var j = 0; j < h.length; j++) {
            byteArray.push(parseInt(h[j], 16))
          }
        }
      }
      return byteArray
    }
    
    function asciiToBytes (str) {
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        // Node's code seems to be doing this and not & 0x7F..
        byteArray.push(str.charCodeAt(i) & 0xFF)
      }
      return byteArray
    }
    
    function utf16leToBytes (str) {
      var c, hi, lo
      var byteArray = []
      for (var i = 0; i < str.length; i++) {
        c = str.charCodeAt(i)
        hi = c >> 8
        lo = c % 256
        byteArray.push(lo)
        byteArray.push(hi)
      }
    
      return byteArray
    }
    
    function base64ToBytes (str) {
      return base64.toByteArray(str)
    }
    
    function blitBuffer (src, dst, offset, length) {
      for (var i = 0; i < length; i++) {
        if ((i + offset >= dst.length) || (i >= src.length))
          break
        dst[i + offset] = src[i]
      }
      return i
    }
    
    function decodeUtf8Char (str) {
      try {
        return decodeURIComponent(str)
      } catch (err) {
        return String.fromCharCode(0xFFFD) // UTF 8 invalid char
      }
    }
    
    /*
     * We have to make sure that the value is a valid integer. This means that it
     * is non-negative. It has no fractional component and that it does not
     * exceed the maximum allowed value.
     */
    function verifuint (value, max) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value >= 0, 'specified a negative value for writing an unsigned value')
      assert(value <= max, 'value is larger than maximum value for type')
      assert(Math.floor(value) === value, 'value has a fractional component')
    }
    
    function verifsint (value, max, min) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value <= max, 'value larger than maximum allowed value')
      assert(value >= min, 'value smaller than minimum allowed value')
      assert(Math.floor(value) === value, 'value has a fractional component')
    }
    
    function verifIEEE754 (value, max, min) {
      assert(typeof value === 'number', 'cannot write a non-number as a number')
      assert(value <= max, 'value larger than maximum allowed value')
      assert(value >= min, 'value smaller than minimum allowed value')
    }
    
    function assert (test, message) {
      if (!test) throw new Error(message || 'Failed assertion')
    }
    
    },{"base64-js":7,"ieee754":8}],7:[function(_dereq_,module,exports){
    var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    
    ;(function (exports) {
        'use strict';
    
      var Arr = (typeof Uint8Array !== 'undefined')
        ? Uint8Array
        : Array
    
        var PLUS   = '+'.charCodeAt(0)
        var SLASH  = '/'.charCodeAt(0)
        var NUMBER = '0'.charCodeAt(0)
        var LOWER  = 'a'.charCodeAt(0)
        var UPPER  = 'A'.charCodeAt(0)
    
        function decode (elt) {
                var code = elt.charCodeAt(0)
                if (code === PLUS)
                        return 62 // '+'
                if (code === SLASH)
                        return 63 // '/'
                if (code < NUMBER)
                        return -1 //no match
                if (code < NUMBER + 10)
                        return code - NUMBER + 26 + 26
                if (code < UPPER + 26)
                        return code - UPPER
                if (code < LOWER + 26)
                        return code - LOWER + 26
        }
    
        function b64ToByteArray (b64) {
                var i, j, l, tmp, placeHolders, arr
    
                if (b64.length % 4 > 0) {
                        throw new Error('Invalid string. Length must be a multiple of 4')
                }
    
                // the number of equal signs (place holders)
                // if there are two placeholders, than the two characters before it
                // represent one byte
                // if there is only one, then the three characters before it represent 2 bytes
                // this is just a cheap hack to not do indexOf twice
                var len = b64.length
                placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
    
                // base64 is 4/3 + up to two characters of the original data
                arr = new Arr(b64.length * 3 / 4 - placeHolders)
    
                // if there are placeholders, only get up to the last complete 4 chars
                l = placeHolders > 0 ? b64.length - 4 : b64.length
    
                var L = 0
    
                function push (v) {
                        arr[L++] = v
                }
    
                for (i = 0, j = 0; i < l; i += 4, j += 3) {
                        tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
                        push((tmp & 0xFF0000) >> 16)
                        push((tmp & 0xFF00) >> 8)
                        push(tmp & 0xFF)
                }
    
                if (placeHolders === 2) {
                        tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
                        push(tmp & 0xFF)
                } else if (placeHolders === 1) {
                        tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
                        push((tmp >> 8) & 0xFF)
                        push(tmp & 0xFF)
                }
    
                return arr
        }
    
        function uint8ToBase64 (uint8) {
                var i,
                        extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
                        output = "",
                        temp, length
    
                function encode (num) {
                        return lookup.charAt(num)
                }
    
                function tripletToBase64 (num) {
                        return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
                }
    
                // go through the array every three bytes, we'll deal with trailing stuff later
                for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
                        temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
                        output += tripletToBase64(temp)
                }
    
                // pad the end with zeros, but make sure to not forget the extra bytes
                switch (extraBytes) {
                        case 1:
                                temp = uint8[uint8.length - 1]
                                output += encode(temp >> 2)
                                output += encode((temp << 4) & 0x3F)
                                output += '=='
                                break
                        case 2:
                                temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
                                output += encode(temp >> 10)
                                output += encode((temp >> 4) & 0x3F)
                                output += encode((temp << 2) & 0x3F)
                                output += '='
                                break
                }
    
                return output
        }
    
        exports.toByteArray = b64ToByteArray
        exports.fromByteArray = uint8ToBase64
    }(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
    
    },{}],8:[function(_dereq_,module,exports){
    exports.read = function(buffer, offset, isLE, mLen, nBytes) {
      var e, m,
          eLen = nBytes * 8 - mLen - 1,
          eMax = (1 << eLen) - 1,
          eBias = eMax >> 1,
          nBits = -7,
          i = isLE ? (nBytes - 1) : 0,
          d = isLE ? -1 : 1,
          s = buffer[offset + i];
    
      i += d;
    
      e = s & ((1 << (-nBits)) - 1);
      s >>= (-nBits);
      nBits += eLen;
      for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);
    
      m = e & ((1 << (-nBits)) - 1);
      e >>= (-nBits);
      nBits += mLen;
      for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);
    
      if (e === 0) {
        e = 1 - eBias;
      } else if (e === eMax) {
        return m ? NaN : ((s ? -1 : 1) * Infinity);
      } else {
        m = m + Math.pow(2, mLen);
        e = e - eBias;
      }
      return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
    };
    
    exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
      var e, m, c,
          eLen = nBytes * 8 - mLen - 1,
          eMax = (1 << eLen) - 1,
          eBias = eMax >> 1,
          rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
          i = isLE ? 0 : (nBytes - 1),
          d = isLE ? 1 : -1,
          s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
    
      value = Math.abs(value);
    
      if (isNaN(value) || value === Infinity) {
        m = isNaN(value) ? 1 : 0;
        e = eMax;
      } else {
        e = Math.floor(Math.log(value) / Math.LN2);
        if (value * (c = Math.pow(2, -e)) < 1) {
          e--;
          c *= 2;
        }
        if (e + eBias >= 1) {
          value += rt / c;
        } else {
          value += rt * Math.pow(2, 1 - eBias);
        }
        if (value * c >= 2) {
          e++;
          c /= 2;
        }
    
        if (e + eBias >= eMax) {
          m = 0;
          e = eMax;
        } else if (e + eBias >= 1) {
          m = (value * c - 1) * Math.pow(2, mLen);
          e = e + eBias;
        } else {
          m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
          e = 0;
        }
      }
    
      for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);
    
      e = (e << mLen) | m;
      eLen += mLen;
      for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);
    
      buffer[offset + i - d] |= s * 128;
    };
    
    },{}]},{},[1])
    (1)
    });

Test runner

Ready to run.

Testing in
TestOps/sec
bs58 using bigi
bs58_bigi.encode(bytes);
ready
bs58 using digit-array
bs58_digit_array.encode(bytes);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by Jared Deckard on