mqtt.js源码1

6 篇文章 8 订阅
6 篇文章 0 订阅

mqtt.js源码1

由于代码过长博客不支持,故分为几个部分

(function (f) {
  if (typeof exports === "object" && typeof module !== "undefined") {
    module.exports = f()
  } else if (typeof define === "function" && define.amd) {
    define([], f)
  } else {
    var g;
    if (typeof window !== "undefined") {
      g = window
    } else if (typeof global !== "undefined") {
      g = global
    } else if (typeof self !== "undefined") {
      g = self
    } else {
      g = this
    }
    g.mqtt = f()
  }
})(function () {
  var define, module, exports;
  return (function () {
    function r(e, n, t) {
      function o(i, f) {
        if (!n[i]) {
          if (!e[i]) {
            var c = "function" == typeof require && require;
            if (!f && c) return c(i, !0);
            if (u) return u(i, !0);
            var a = new Error("Cannot find module '" + i + "'");
            throw a.code = "MODULE_NOT_FOUND", a
          }
          var p = n[i] = {
            exports: {}
          };
          e[i][0].call(p.exports, function (r) {
            var n = e[i][1][r];
            return o(n || r)
          }, p, p.exports, r, e, n, t)
        }
        return n[i].exports
      }
      for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) o(t[i]);
      return o
    }
    return r
  })()({
    1: [function (require, module, exports) {
      (function (process, global) {
        'use strict'

        /**
         * Module dependencies
         */
        var events = require('events')
        var Store = require('./store')
        var mqttPacket = require('mqtt-packet')
        var Writable = require('readable-stream').Writable
        var inherits = require('inherits')
        var reInterval = require('reinterval')
        var validations = require('./validations')
        var xtend = require('xtend')
        var setImmediate = global.setImmediate || function (callback) {
          // works in node v0.8
          process.nextTick(callback)
        }
        var defaultConnectOptions = {
          keepalive: 60,
          reschedulePings: true,
          protocolId: 'MQTT',
          protocolVersion: 4,
          reconnectPeriod: 1000,
          connectTimeout: 30 * 1000,
          clean: true,
          resubscribe: true
        }
        var errors = {
          0: '',
          1: 'Unacceptable protocol version',
          2: 'Identifier rejected',
          3: 'Server unavailable',
          4: 'Bad username or password',
          5: 'Not authorized',
          16: 'No matching subscribers',
          17: 'No subscription existed',
          128: 'Unspecified error',
          129: 'Malformed Packet',
          130: 'Protocol Error',
          131: 'Implementation specific error',
          132: 'Unsupported Protocol Version',
          133: 'Client Identifier not valid',
          134: 'Bad User Name or Password',
          135: 'Not authorized',
          136: 'Server unavailable',
          137: 'Server busy',
          138: 'Banned',
          139: 'Server shutting down',
          140: 'Bad authentication method',
          141: 'Keep Alive timeout',
          142: 'Session taken over',
          143: 'Topic Filter invalid',
          144: 'Topic Name invalid',
          145: 'Packet identifier in use',
          146: 'Packet Identifier not found',
          147: 'Receive Maximum exceeded',
          148: 'Topic Alias invalid',
          149: 'Packet too large',
          150: 'Message rate too high',
          151: 'Quota exceeded',
          152: 'Administrative action',
          153: 'Payload format invalid',
          154: 'Retain not supported',
          155: 'QoS not supported',
          156: 'Use another server',
          157: 'Server moved',
          158: 'Shared Subscriptions not supported',
          159: 'Connection rate exceeded',
          160: 'Maximum connect time',
          161: 'Subscription Identifiers not supported',
          162: 'Wildcard Subscriptions not supported'
        }

        function defaultId() {
          return 'mqttjs_' + Math.random().toString(16).substr(2, 8)
        }

        function sendPacket(client, packet, cb) {
          client.emit('packetsend', packet)

          var result = mqttPacket.writeToStream(packet, client.stream, client.options)

          if (!result && cb) {
            client.stream.once('drain', cb)
          } else if (cb) {
            cb()
          }
        }

        function flush(queue) {
          if (queue) {
            Object.keys(queue).forEach(function (messageId) {
              if (typeof queue[messageId].cb === 'function') {
                queue[messageId].cb(new Error('Connection closed'))
                delete queue[messageId]
              }
            })
          }
        }

        function flushVolatile(queue) {
          if (queue) {
            Object.keys(queue).forEach(function (messageId) {
              if (queue[messageId].volatile && typeof queue[messageId].cb === 'function') {
                queue[messageId].cb(new Error('Connection closed'))
                delete queue[messageId]
              }
            })
          }
        }

        function storeAndSend(client, packet, cb, cbStorePut) {
          client.outgoingStore.put(packet, function storedPacket(err) {
            if (err) {
              return cb && cb(err)
            }
            cbStorePut()
            sendPacket(client, packet, cb)
          })
        }

        function nop() {}

        /**
         * MqttClient constructor
         *
         * @param {Stream} stream - stream
         * @param {Object} [options] - connection options
         * (see Connection#connect)
         */
        function MqttClient(streamBuilder, options) {
          var k
          var that = this

          if (!(this instanceof MqttClient)) {
            return new MqttClient(streamBuilder, options)
          }

          this.options = options || {}

          // Defaults
          for (k in defaultConnectOptions) {
            if (typeof this.options[k] === 'undefined') {
              this.options[k] = defaultConnectOptions[k]
            } else {
              this.options[k] = options[k]
            }
          }

          this.options.clientId = (typeof options.clientId === 'string') ? options.clientId : defaultId()

          this.options.customHandleAcks = (options.protocolVersion === 5 && options.customHandleAcks) ? options.customHandleAcks : function () {
            arguments[3](0)
          }

          this.streamBuilder = streamBuilder

          // Inflight message storages
          this.outgoingStore = options.outgoingStore || new Store()
          this.incomingStore = options.incomingStore || new Store()

          // Should QoS zero messages be queued when the connection is broken?
          this.queueQoSZero = options.queueQoSZero === undefined ? true : options.queueQoSZero

          // map of subscribed topics to support reconnection
          this._resubscribeTopics = {}

          // map of a subscribe messageId and a topic
          this.messageIdToTopic = {}

          // Ping timer, setup in _setupPingTimer
          this.pingTimer = null
          // Is the client connected?
          this.connected = false
          // Are we disconnecting?
          this.disconnecting = false
          // Packet queue
          this.queue = []
          // connack timer
          this.connackTimer = null
          // Reconnect timer
          this.reconnectTimer = null
          // Is processing store?
          this._storeProcessing = false
          // Packet Ids are put into the store during store processing
          this._packetIdsDuringStoreProcessing = {}
          /**
           * MessageIDs starting with 1
           * ensure that nextId is min. 1, see https://github.com/mqttjs/MQTT.js/issues/810
           */
          this.nextId = Math.max(1, Math.floor(Math.random() * 65535))

          // Inflight callbacks
          this.outgoing = {}

          // True if connection is first time.
          this._firstConnection = true

          // Mark disconnected on stream close
          this.on('close', function () {
            this.connected = false
            clearTimeout(this.connackTimer)
          })

          // Send queued packets
          this.on('connect', function () {
            var queue = this.queue

            function deliver() {
              var entry = queue.shift()
              var packet = null

              if (!entry) {
                return
              }

              packet = entry.packet

              that._sendPacket(
                packet,
                function (err) {
                  if (entry.cb) {
                    entry.cb(err)
                  }
                  deliver()
                }
              )
            }

            deliver()
          })

          // Clear ping timer
          this.on('close', function () {
            if (that.pingTimer !== null) {
              that.pingTimer.clear()
              that.pingTimer = null
            }
          })

          // Setup reconnect timer on disconnect
          this.on('close', this._setupReconnect)

          events.EventEmitter.call(this)

          this._setupStream()
        }
        inherits(MqttClient, events.EventEmitter)

        /**
         * setup the event handlers in the inner stream.
         *
         * @api private
         */
        MqttClient.prototype._setupStream = function () {
          var connectPacket
          var that = this
          var writable = new Writable()
          var parser = mqttPacket.parser(this.options)
          var completeParse = null
          var packets = []

          this._clearReconnect()

          this.stream = this.streamBuilder(this)

          parser.on('packet', function (packet) {
            packets.push(packet)
          })

          function nextTickWork() {
            if (packets.length) {
              process.nextTick(work)
            } else {
              var done = completeParse
              completeParse = null
              done()
            }
          }

          function work() {
            var packet = packets.shift()

            if (packet) {
              that._handlePacket(packet, nextTickWork)
            } else {
              var done = completeParse
              completeParse = null
              if (done) done()
            }
          }

          writable._write = function (buf, enc, done) {
            completeParse = done
            parser.parse(buf)
            work()
          }

          this.stream.pipe(writable)

          // Suppress connection errors
          this.stream.on('error', nop)

          // Echo stream close
          this.stream.on('close', function () {
            flushVolatile(that.outgoing)
            that.emit('close')
          })

          // Send a connect packet
          connectPacket = Object.create(this.options)
          connectPacket.cmd = 'connect'
          // avoid message queue
          sendPacket(this, connectPacket)

          // Echo connection errors
          parser.on('error', this.emit.bind(this, 'error'))

          // auth
          if (this.options.properties) {
            if (!this.options.properties.authenticationMethod && this.options.properties.authenticationData) {
              this.emit('error', new Error('Packet has no Authentication Method'))
              return this
            }
            if (this.options.properties.authenticationMethod && this.options.authPacket && typeof this.options.authPacket === 'object') {
              var authPacket = xtend({
                cmd: 'auth',
                reasonCode: 0
              }, this.options.authPacket)
              sendPacket(this, authPacket)
            }
          }

          // many drain listeners are needed for qos 1 callbacks if the connection is intermittent
          this.stream.setMaxListeners(1000)

          clearTimeout(this.connackTimer)
          this.connackTimer = setTimeout(function () {
            that._cleanUp(true)
          }, this.options.connectTimeout)
        }

        MqttClient.prototype._handlePacket = function (packet, done) {
          var options = this.options

          if (options.protocolVersion === 5 && options.properties && options.properties.maximumPacketSize && options.properties.maximumPacketSize < packet.length) {
            this.emit('error', new Error('exceeding packets size ' + packet.cmd))
            this.end({
              reasonCode: 149,
              properties: {
                reasonString: 'Maximum packet size was exceeded'
              }
            })
            return this
          }

          this.emit('packetreceive', packet)

          switch (packet.cmd) {
            case 'publish':
              this._handlePublish(packet, done)
              break
            case 'puback':
            case 'pubrec':
            case 'pubcomp':
            case 'suback':
            case 'unsuback':
              this._handleAck(packet)
              done()
              break
            case 'pubrel':
              this._handlePubrel(packet, done)
              break
            case 'connack':
              this._handleConnack(packet)
              done()
              break
            case 'pingresp':
              this._handlePingresp(packet)
              done()
              break
            case 'disconnect':
              this._handleDisconnect(packet)
              done()
              break
            default:
              // do nothing
              // maybe we should do an error handling
              // or just log it
              break
          }
        }

        MqttClient.prototype._checkDisconnecting = function (callback) {
          if (this.disconnecting) {
            if (callback) {
              callback(new Error('client disconnecting'))
            } else {
              this.emit('error', new Error('client disconnecting'))
            }
          }
          return this.disconnecting
        }

        /**
         * publish - publish <message> to <topic>
         *
         * @param {String} topic - topic to publish to
         * @param {String, Buffer} message - message to publish
         * @param {Object} [opts] - publish options, includes:
         *    {Number} qos - qos level to publish on
         *    {Boolean} retain - whether or not to retain the message
         *    {Boolean} dup - whether or not mark a message as duplicate
         *    {Function} cbStorePut - function(){} called when message is put into `outgoingStore`
         * @param {Function} [callback] - function(err){}
         *    called when publish succeeds or fails
         * @returns {MqttClient} this - for chaining
         * @api public
         *
         * @example client.publish('topic', 'message');
         * @example
         *     client.publish('topic', 'message', {qos: 1, retain: true, dup: true});
         * @example client.publish('topic', 'message', console.log);
         */
        MqttClient.prototype.publish = function (topic, message, opts, callback) {
          var packet
          var options = this.options

          // .publish(topic, payload, cb);
          if (typeof opts === 'function') {
            callback = opts
            opts = null
          }

          // default opts
          var defaultOpts = {
            qos: 0,
            retain: false,
            dup: false
          }
          opts = xtend(defaultOpts, opts)

          if (this._checkDisconnecting(callback)) {
            return this
          }

          packet = {
            cmd: 'publish',
            topic: topic,
            payload: message,
            qos: opts.qos,
            retain: opts.retain,
            messageId: this._nextId(),
            dup: opts.dup
          }

          if (options.protocolVersion === 5) {
            packet.properties = opts.properties
            if ((!options.properties && packet.properties && packet.properties.topicAlias) || ((opts.properties && options.properties) &&
                ((opts.properties.topicAlias && options.properties.topicAliasMaximum && opts.properties.topicAlias > options.properties.topicAliasMaximum) ||
                  (!options.properties.topicAliasMaximum && opts.properties.topicAlias)))) {
              /*
              if we are don`t setup topic alias or
              topic alias maximum less than topic alias or
              server don`t give topic alias maximum,
              we are removing topic alias from packet
              */
              delete packet.properties.topicAlias
            }
          }

          switch (opts.qos) {
            case 1:
            case 2:
              // Add to callbacks
              this.outgoing[packet.messageId] = {
                volatile: false,
                cb: callback || nop
              }
              if (this._storeProcessing) {
                this._packetIdsDuringStoreProcessing[packet.messageId] = false
                this._storePacket(packet, undefined, opts.cbStorePut)
              } else {
                this._sendPacket(packet, undefined, opts.cbStorePut)
              }
              break
            default:
              if (this._storeProcessing) {
                this._storePacket(packet, callback, opts.cbStorePut)
              } else {
                this._sendPacket(packet, callback, opts.cbStorePut)
              }
              break
          }

          return this
        }

        /**
         * subscribe - subscribe to <topic>
         *
         * @param {String, Array, Object} topic - topic(s) to subscribe to, supports objects in the form {'topic': qos}
         * @param {Object} [opts] - optional subscription options, includes:
         *    {Number} qos - subscribe qos level
         * @param {Function} [callback] - function(err, granted){} where:
         *    {Error} err - subscription error (none at the moment!)
         *    {Array} granted - array of {topic: 't', qos: 0}
         * @returns {MqttClient} this - for chaining
         * @api public
         * @example client.subscribe('topic');
         * @example client.subscribe('topic', {qos: 1});
         * @example client.subscribe({'topic': {qos: 0}, 'topic2': {qos: 1}}, console.log);
         * @example client.subscribe('topic', console.log);
         */
        MqttClient.prototype.subscribe = function () {
          var packet
          var args = new Array(arguments.length)
          for (var i = 0; i < arguments.length; i++) {
            args[i] = arguments[i]
          }
          var subs = []
          var obj = args.shift()
          var resubscribe = obj.resubscribe
          var callback = args.pop() || nop
          var opts = args.pop()
          var invalidTopic
          var that = this
          var version = this.options.protocolVersion

          delete obj.resubscribe

          if (typeof obj === 'string') {
            obj = [obj]
          }

          if (typeof callback !== 'function') {
            opts = callback
            callback = nop
          }

          invalidTopic = validations.validateTopics(obj)
          if (invalidTopic !== null) {
            setImmediate(callback, new Error('Invalid topic ' + invalidTopic))
            return this
          }

          if (this._checkDisconnecting(callback)) {
            return this
          }

          var defaultOpts = {
            qos: 0
          }
          if (version === 5) {
            defaultOpts.nl = false
            defaultOpts.rap = false
            defaultOpts.rh = 0
          }
          opts = xtend(defaultOpts, opts)

          if (Array.isArray(obj)) {
            obj.forEach(function (topic) {
              if (!that._resubscribeTopics.hasOwnProperty(topic) ||
                that._resubscribeTopics[topic].qos < opts.qos ||
                resubscribe) {
                var currentOpts = {
                  topic: topic,
                  qos: opts.qos
                }
                if (version === 5) {
                  currentOpts.nl = opts.nl
                  currentOpts.rap = opts.rap
                  currentOpts.rh = opts.rh
                  currentOpts.properties = opts.properties
                }
                subs.push(currentOpts)
              }
            })
          } else {
            Object
              .keys(obj)
              .forEach(function (k) {
                if (!that._resubscribeTopics.hasOwnProperty(k) ||
                  that._resubscribeTopics[k].qos < obj[k].qos ||
                  resubscribe) {
                  var currentOpts = {
                    topic: k,
                    qos: obj[k].qos
                  }
                  if (version === 5) {
                    currentOpts.nl = obj[k].nl
                    currentOpts.rap = obj[k].rap
                    currentOpts.rh = obj[k].rh
                    currentOpts.properties = opts.properties
                  }
                  subs.push(currentOpts)
                }
              })
          }

          packet = {
            cmd: 'subscribe',
            subscriptions: subs,
            qos: 1,
            retain: false,
            dup: false,
            messageId: this._nextId()
          }

          if (opts.properties) {
            packet.properties = opts.properties
          }

          if (!subs.length) {
            callback(null, [])
            return
          }

          // subscriptions to resubscribe to in case of disconnect
          if (this.options.resubscribe) {
            var topics = []
            subs.forEach(function (sub) {
              if (that.options.reconnectPeriod > 0) {
                var topic = {
                  qos: sub.qos
                }
                if (version === 5) {
                  topic.nl = sub.nl || false
                  topic.rap = sub.rap || false
                  topic.rh = sub.rh || 0
                  topic.properties = sub.properties
                }
                that._resubscribeTopics[sub.topic] = topic
                topics.push(sub.topic)
              }
            })
            that.messageIdToTopic[packet.messageId] = topics
          }

          this.outgoing[packet.messageId] = {
            volatile: true,
            cb: function (err, packet) {
              if (!err) {
                var granted = packet.granted
                for (var i = 0; i < granted.length; i += 1) {
                  subs[i].qos = granted[i]
                }
              }

              callback(err, subs)
            }
          }

          this._sendPacket(packet)

          return this
        }

        /**
         * unsubscribe - unsubscribe from topic(s)
         *
         * @param {String, Array} topic - topics to unsubscribe from
         * @param {Object} [opts] - optional subscription options, includes:
         *    {Object} properties - properties of unsubscribe packet
         * @param {Function} [callback] - callback fired on unsuback
         * @returns {MqttClient} this - for chaining
         * @api public
         * @example client.unsubscribe('topic');
         * @example client.unsubscribe('topic', console.log);
         */
        MqttClient.prototype.unsubscribe = function () {
          var packet = {
            cmd: 'unsubscribe',
            qos: 1,
            messageId: this._nextId()
          }
          var that = this
          var args = new Array(arguments.length)
          for (var i = 0; i < arguments.length; i++) {
            args[i] = arguments[i]
          }
          var topic = args.shift()
          var callback = args.pop() || nop
          var opts = args.pop()

          if (typeof topic === 'string') {
            topic = [topic]
          }

          if (typeof callback !== 'function') {
            opts = callback
            callback = nop
          }

          if (this._checkDisconnecting(callback)) {
            return this
          }

          if (typeof topic === 'string') {
            packet.unsubscriptions = [topic]
          } else if (typeof topic === 'object' && topic.length) {
            packet.unsubscriptions = topic
          }

          if (this.options.resubscribe) {
            packet.unsubscriptions.forEach(function (topic) {
              delete that._resubscribeTopics[topic]
            })
          }

          if (typeof opts === 'object' && opts.properties) {
            packet.properties = opts.properties
          }

          this.outgoing[packet.messageId] = {
            volatile: true,
            cb: callback
          }

          this._sendPacket(packet)

          return this
        }

        /**
         * end - close connection
         *
         * @returns {MqttClient} this - for chaining
         * @param {Boolean} force - do not wait for all in-flight messages to be acked
         * @param {Function} cb - called when the client has been closed
         *
         * @api public
         */
        MqttClient.prototype.end = function () {
          var that = this

          var force = arguments[0]
          var opts = arguments[1]
          var cb = arguments[2]

          if (force == null || typeof force !== 'boolean') {
            cb = opts || nop
            opts = force
            force = false
            if (typeof opts !== 'object') {
              cb = opts
              opts = null
              if (typeof cb !== 'function') {
                cb = nop
              }
            }
          }

          if (typeof opts !== 'object') {
            cb = opts
            opts = null
          }

          cb = cb || nop

          function closeStores() {
            that.disconnected = true
            that.incomingStore.close(function () {
              that.outgoingStore.close(function () {
                if (cb) {
                  cb.apply(null, arguments)
                }
                that.emit('end')
              })
            })
            if (that._deferredReconnect) {
              that._deferredReconnect()
            }
          }

          function finish() {
            // defer closesStores of an I/O cycle,
            // just to make sure things are
            // ok for websockets
            that._cleanUp(force, setImmediate.bind(null, closeStores), opts)
          }

          if (this.disconnecting) {
            return this
          }

          this._clearReconnect()

          this.disconnecting = true

          if (!force && Object.keys(this.outgoing).length > 0) {
            // wait 10ms, just to be sure we received all of it
            this.once('outgoingEmpty', setTimeout.bind(null, finish, 10))
          } else {
            finish()
          }

          return this
        }

        /**
         * removeOutgoingMessage - remove a message in outgoing store
         * the outgoing callback will be called withe Error('Message removed') if the message is removed
         *
         * @param {Number} mid - messageId to remove message
         * @returns {MqttClient} this - for chaining
         * @api public
         *
         * @example client.removeOutgoingMessage(client.getLastMessageId());
         */
        MqttClient.prototype.removeOutgoingMessage = function (mid) {
          var cb = this.outgoing[mid] ? this.outgoing[mid].cb : null
          delete this.outgoing[mid]
          this.outgoingStore.del({
            messageId: mid
          }, function () {
            cb(new Error('Message removed'))
          })
          return this
        }

        /**
         * reconnect - connect again using the same options as connect()
         *
         * @param {Object} [opts] - optional reconnect options, includes:
         *    {Store} incomingStore - a store for the incoming packets
         *    {Store} outgoingStore - a store for the outgoing packets
         *    if opts is not given, current stores are used
         * @returns {MqttClient} this - for chaining
         *
         * @api public
         */
        MqttClient.prototype.reconnect = function (opts) {
          var that = this
          var f = function () {
            if (opts) {
              that.options.incomingStore = opts.incomingStore
              that.options.outgoingStore = opts.outgoingStore
            } else {
              that.options.incomingStore = null
              that.options.outgoingStore = null
            }
            that.incomingStore = that.options.incomingStore || new Store()
            that.outgoingStore = that.options.outgoingStore || new Store()
            that.disconnecting = false
            that.disconnected = false
            that._deferredReconnect = null
            that._reconnect()
          }

          if (this.disconnecting && !this.disconnected) {
            this._deferredReconnect = f
          } else {
            f()
          }
          return this
        }

        /**
         * _reconnect - implement reconnection
         * @api privateish
         */
        MqttClient.prototype._reconnect = function () {
          this.emit('reconnect')
          this._setupStream()
        }

        /**
         * _setupReconnect - setup reconnect timer
         */
        MqttClient.prototype._setupReconnect = function () {
          var that = this

          if (!that.disconnecting && !that.reconnectTimer && (that.options.reconnectPeriod > 0)) {
            if (!this.reconnecting) {
              this.emit('offline')
              this.reconnecting = true
            }
            that.reconnectTimer = setInterval(function () {
              that._reconnect()
            }, that.options.reconnectPeriod)
          }
        }

        /**
         * _clearReconnect - clear the reconnect timer
         */
        MqttClient.prototype._clearReconnect = function () {
          if (this.reconnectTimer) {
            clearInterval(this.reconnectTimer)
            this.reconnectTimer = null
          }
        }

        /**
         * _cleanUp - clean up on connection end
         * @api private
         */
        MqttClient.prototype._cleanUp = function (forced, done) {
          var opts = arguments[2]
          if (done) {
            this.stream.on('close', done)
          }

          if (forced) {
            if ((this.options.reconnectPeriod === 0) && this.options.clean) {
              flush(this.outgoing)
            }
            this.stream.destroy()
          } else {
            var packet = xtend({
              cmd: 'disconnect'
            }, opts)
            this._sendPacket(
              packet,
              setImmediate.bind(
                null,
                this.stream.end.bind(this.stream)
              )
            )
          }

          if (!this.disconnecting) {
            this._clearReconnect()
            this._setupReconnect()
          }

          if (this.pingTimer !== null) {
            this.pingTimer.clear()
            this.pingTimer = null
          }

          if (done && !this.connected) {
            this.stream.removeListener('close', done)
            done()
          }
        }

        /**
         * _sendPacket - send or queue a packet
         * @param {String} type - packet type (see `protocol`)
         * @param {Object} packet - packet options
         * @param {Function} cb - callback when the packet is sent
         * @param {Function} cbStorePut - called when message is put into outgoingStore
         * @api private
         */
        MqttClient.prototype._sendPacket = function (packet, cb, cbStorePut) {
          cbStorePut = cbStorePut || nop

          if (!this.connected) {
            this._storePacket(packet, cb, cbStorePut)
            return
          }

          // When sending a packet, reschedule the ping timer
          this._shiftPingInterval()

          switch (packet.cmd) {
            case 'publish':
              break
            case 'pubrel':
              storeAndSend(this, packet, cb, cbStorePut)
              return
            default:
              sendPacket(this, packet, cb)
              return
          }

          switch (packet.qos) {
            case 2:
            case 1:
              storeAndSend(this, packet, cb, cbStorePut)
              break
              /**
               * no need of case here since it will be caught by default
               * and jshint comply that before default it must be a break
               * anyway it will result in -1 evaluation
               */
            case 0:
              /* falls through */
            default:
              sendPacket(this, packet, cb)
              break
          }
        }

        /**
         * _storePacket - queue a packet
         * @param {String} type - packet type (see `protocol`)
         * @param {Object} packet - packet options
         * @param {Function} cb - callback when the packet is sent
         * @param {Function} cbStorePut - called when message is put into outgoingStore
         * @api private
         */
        MqttClient.prototype._storePacket = function (packet, cb, cbStorePut) {
          cbStorePut = cbStorePut || nop

          if (((packet.qos || 0) === 0 && this.queueQoSZero) || packet.cmd !== 'publish') {
            this.queue.push({
              packet: packet,
              cb: cb
            })
          } else if (packet.qos > 0) {
            cb = this.outgoing[packet.messageId] ? this.outgoing[packet.messageId].cb : null
            this.outgoingStore.put(packet, function (err) {
              if (err) {
                return cb && cb(err)
              }
              cbStorePut()
            })
          } else if (cb) {
            cb(new Error('No connection to broker'))
          }
        }

        /**
         * _setupPingTimer - setup the ping timer
         *
         * @api private
         */
        MqttClient.prototype._setupPingTimer = function () {
          var that = this

          if (!this.pingTimer && this.options.keepalive) {
            this.pingResp = true
            this.pingTimer = reInterval(function () {
              that._checkPing()
            }, this.options.keepalive * 1000)
          }
        }

        /**
         * _shiftPingInterval - reschedule the ping interval
         *
         * @api private
         */
        MqttClient.prototype._shiftPingInterval = function () {
          if (this.pingTimer && this.options.keepalive && this.options.reschedulePings) {
            this.pingTimer.reschedule(this.options.keepalive * 1000)
          }
        }
        /**
         * _checkPing - check if a pingresp has come back, and ping the server again
         *
         * @api private
         */
        MqttClient.prototype._checkPing = function () {
          if (this.pingResp) {
            this.pingResp = false
            this._sendPacket({
              cmd: 'pingreq'
            })
          } else {
            // do a forced cleanup since socket will be in bad shape
            this._cleanUp(true)
          }
        }

        /**
         * _handlePingresp - handle a pingresp
         *
         * @api private
         */
        MqttClient.prototype._handlePingresp = function () {
          this.pingResp = true
        }

        /**
         * _handleConnack
         *
         * @param {Object} packet
         * @api private
         */

        MqttClient.prototype._handleConnack = function (packet) {
          var options = this.options
          var version = options.protocolVersion
          var rc = version === 5 ? packet.reasonCode : packet.returnCode

          clearTimeout(this.connackTimer)

          if (packet.properties) {
            if (packet.properties.topicAliasMaximum) {
              if (!options.properties) {
                options.properties = {}
              }
              options.properties.topicAliasMaximum = packet.properties.topicAliasMaximum
            }
            if (packet.properties.serverKeepAlive && options.keepalive) {
              options.keepalive = packet.properties.serverKeepAlive
              this._shiftPingInterval()
            }
            if (packet.properties.maximumPacketSize) {
              if (!options.properties) {
                options.properties = {}
              }
              options.properties.maximumPacketSize = packet.properties.maximumPacketSize
            }
          }

          if (rc === 0) {
            this.reconnecting = false
            this._onConnect(packet)
          } else if (rc > 0) {
            var err = new Error('Connection refused: ' + errors[rc])
            err.code = rc
            this.emit('error', err)
          }
        }

        /**
         * _handlePublish
         *
         * @param {Object} packet
         * @api private
         */
        /*
        those late 2 case should be rewrite to comply with coding style:

        case 1:
        case 0:
          // do not wait sending a puback
          // no callback passed
          if (1 === qos) {
            this._sendPacket({
              cmd: 'puback',
              messageId: mid
            });
          }
          // emit the message event for both qos 1 and 0
          this.emit('message', topic, message, packet);
          this.handleMessage(packet, done);
          break;
        default:
          // do nothing but every switch mus have a default
          // log or throw an error about unknown qos
          break;

        for now i just suppressed the warnings
        */
        MqttClient.prototype._handlePublish = function (packet, done) {
          done = typeof done !== 'undefined' ? done : nop
          var topic = packet.topic.toString()
          var message = packet.payload
          var qos = packet.qos
          var mid = packet.messageId
          var that = this
          var options = this.options
          var validReasonCodes = [0, 16, 128, 131, 135, 144, 145, 151, 153]

          switch (qos) {
            case 2: {
              options.customHandleAcks(topic, message, packet, function (error, code) {
                if (!(error instanceof Error)) {
                  code = error
                  error = null
                }
                if (error) {
                  return that.emit('error', error)
                }
                if (validReasonCodes.indexOf(code) === -1) {
                  return that.emit('error', new Error('Wrong reason code for pubrec'))
                }
                if (code) {
                  that._sendPacket({
                    cmd: 'pubrec',
                    messageId: mid,
                    reasonCode: code
                  }, done)
                } else {
                  that.incomingStore.put(packet, function () {
                    that._sendPacket({
                      cmd: 'pubrec',
                      messageId: mid
                    }, done)
                  })
                }
              })
              break
            }
            case 1: {
              // emit the message event
              options.customHandleAcks(topic, message, packet, function (error, code) {
                if (!(error instanceof Error)) {
                  code = error
                  error = null
                }
                if (error) {
                  return that.emit('error', error)
                }
                if (validReasonCodes.indexOf(code) === -1) {
                  return that.emit('error', new Error('Wrong reason code for puback'))
                }
                if (!code) {
                  that.emit('message', topic, message, packet)
                }
                that.handleMessage(packet, function (err) {
                  if (err) {
                    return done && done(err)
                  }
                  that._sendPacket({
                    cmd: 'puback',
                    messageId: mid,
                    reasonCode: code
                  }, done)
                })
              })
              break
            }
            case 0:
              // emit the message event
              this.emit('message', topic, message, packet)
              this.handleMessage(packet, done)
              break
            default:
              // do nothing
              // log or throw an error about unknown qos
              break
          }
        }

        /**
         * Handle messages with backpressure support, one at a time.
         * Override at will.
         *
         * @param Packet packet the packet
         * @param Function callback call when finished
         * @api public
         */
        MqttClient.prototype.handleMessage = function (packet, callback) {
          callback()
        }

        /**
         * _handleAck
         *
         * @param {Object} packet
         * @api private
         */

        MqttClient.prototype._handleAck = function (packet) {
          /* eslint no-fallthrough: "off" */
          var mid = packet.messageId
          var type = packet.cmd
          var response = null
          var cb = this.outgoing[mid] ? this.outgoing[mid].cb : null
          var that = this
          var err

          if (!cb) {
            // Server sent an ack in error, ignore it.
            return
          }

          // Process
          switch (type) {
            case 'pubcomp':
              // same thing as puback for QoS 2
            case 'puback':
              var pubackRC = packet.reasonCode
              // Callback - we're done
              if (pubackRC && pubackRC > 0 && pubackRC !== 16) {
                err = new Error('Publish error: ' + errors[pubackRC])
                err.code = pubackRC
                cb(err, packet)
              }
              delete this.outgoing[mid]
              this.outgoingStore.del(packet, cb)
              break
            case 'pubrec':
              response = {
                cmd: 'pubrel',
                qos: 2,
                messageId: mid
              }
              var pubrecRC = packet.reasonCode

              if (pubrecRC && pubrecRC > 0 && pubrecRC !== 16) {
                err = new Error('Publish error: ' + errors[pubrecRC])
                err.code = pubrecRC
                cb(err, packet)
              } else {
                this._sendPacket(response)
              }
              break
            case 'suback':
              delete this.outgoing[mid]
              for (var grantedI = 0; grantedI < packet.granted.length; grantedI++) {
                if ((packet.granted[grantedI] & 0x80) !== 0) {
                  // suback with Failure status
                  var topics = this.messageIdToTopic[mid]
                  if (topics) {
                    topics.forEach(function (topic) {
                      delete that._resubscribeTopics[topic]
                    })
                  }
                }
              }
              cb(null, packet)
              break
            case 'unsuback':
              delete this.outgoing[mid]
              cb(null)
              break
            default:
              that.emit('error', new Error('unrecognized packet type'))
          }

          if (this.disconnecting &&
            Object.keys(this.outgoing).length === 0) {
            this.emit('outgoingEmpty')
          }
        }

        /**
         * _handlePubrel
         *
         * @param {Object} packet
         * @api private
         */
        MqttClient.prototype._handlePubrel = function (packet, callback) {
          callback = typeof callback !== 'undefined' ? callback : nop
          var mid = packet.messageId
          var that = this

          var comp = {
            cmd: 'pubcomp',
            messageId: mid
          }

          that.incomingStore.get(packet, function (err, pub) {
            if (!err) {
              that.emit('message', pub.topic, pub.payload, pub)
              that.handleMessage(pub, function (err) {
                if (err) {
                  return callback(err)
                }
                that.incomingStore.del(pub, nop)
                that._sendPacket(comp, callback)
              })
            } else {
              that._sendPacket(comp, callback)
            }
          })
        }

        /**
         * _handleDisconnect
         *
         * @param {Object} packet
         * @api private
         */
        MqttClient.prototype._handleDisconnect = function (packet) {
          this.emit('disconnect', packet)
        }

        /**
         * _nextId
         * @return unsigned int
         */
        MqttClient.prototype._nextId = function () {
          // id becomes current state of this.nextId and increments afterwards
          var id = this.nextId++
          // Ensure 16 bit unsigned int (max 65535, nextId got one higher)
          if (this.nextId === 65536) {
            this.nextId = 1
          }
          return id
        }

        /**
         * getLastMessageId
         * @return unsigned int
         */
        MqttClient.prototype.getLastMessageId = function () {
          return (this.nextId === 1) ? 65535 : (this.nextId - 1)
        }

        /**
         * _resubscribe
         * @api private
         */
        MqttClient.prototype._resubscribe = function (connack) {
          var _resubscribeTopicsKeys = Object.keys(this._resubscribeTopics)
          if (!this._firstConnection &&
            (this.options.clean || (this.options.protocolVersion === 5 && !connack.sessionPresent)) &&
            _resubscribeTopicsKeys.length > 0) {
            if (this.options.resubscribe) {
              if (this.options.protocolVersion === 5) {
                for (var topicI = 0; topicI < _resubscribeTopicsKeys.length; topicI++) {
                  var resubscribeTopic = {}
                  resubscribeTopic[_resubscribeTopicsKeys[topicI]] = this._resubscribeTopics[_resubscribeTopicsKeys[topicI]]
                  resubscribeTopic.resubscribe = true
                  this.subscribe(resubscribeTopic, {
                    properties: resubscribeTopic[_resubscribeTopicsKeys[topicI]].properties
                  })
                }
              } else {
                this._resubscribeTopics.resubscribe = true
                this.subscribe(this._resubscribeTopics)
              }
            } else {
              this._resubscribeTopics = {}
            }
          }

          this._firstConnection = false
        }

        /**
         * _onConnect
         *
         * @api private
         */
        MqttClient.prototype._onConnect = function (packet) {
          if (this.disconnected) {
            this.emit('connect', packet)
            return
          }

          var that = this

          this._setupPingTimer()
          this._resubscribe(packet)

          this.connected = true

          function startStreamProcess() {
            var outStore = that.outgoingStore.createStream()

            function clearStoreProcessing() {
              that._storeProcessing = false
              that._packetIdsDuringStoreProcessing = {}
            }

            that.once('close', remove)
            outStore.on('error', function (err) {
              clearStoreProcessing()
              that.removeListener('close', remove)
              that.emit('error', err)
            })

            function remove() {
              outStore.destroy()
              outStore = null
              clearStoreProcessing()
            }

            function storeDeliver() {
              // edge case, we wrapped this twice
              if (!outStore) {
                return
              }
              that._storeProcessing = true

              var packet = outStore.read(1)

              var cb

              if (!packet) {
                // read when data is available in the future
                outStore.once('readable', storeDeliver)
                return
              }

              // Skip already processed store packets
              if (that._packetIdsDuringStoreProcessing[packet.messageId]) {
                storeDeliver()
                return
              }

              // Avoid unnecessary stream read operations when disconnected
              if (!that.disconnecting && !that.reconnectTimer) {
                cb = that.outgoing[packet.messageId] ? that.outgoing[packet.messageId].cb : null
                that.outgoing[packet.messageId] = {
                  volatile: false,
                  cb: function (err, status) {
                    // Ensure that the original callback passed in to publish gets invoked
                    if (cb) {
                      cb(err, status)
                    }

                    storeDeliver()
                  }
                }
                that._packetIdsDuringStoreProcessing[packet.messageId] = true
                that._sendPacket(packet)
              } else if (outStore.destroy) {
                outStore.destroy()
              }
            }

            outStore.on('end', function () {
              var allProcessed = true
              for (var id in that._packetIdsDuringStoreProcessing) {
                if (!that._packetIdsDuringStoreProcessing[id]) {
                  allProcessed = false
                  break
                }
              }
              if (allProcessed) {
                clearStoreProcessing()
                that.removeListener('close', remove)
                that.emit('connect', packet)
              } else {
                startStreamProcess()
              }
            })
            storeDeliver()
          }
          // start flowing
          startStreamProcess()
        }

        module.exports = MqttClient

      }).call(this, require('_process'), typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    }, {
      "./store": 7,
      "./validations": 8,
      "_process": 92,
      "events": 13,
      "inherits": 80,
      "mqtt-packet": 84,
      "readable-stream": 108,
      "reinterval": 109,
      "xtend": 121
    }],
    2: [function (require, module, exports) {
      (function (Buffer) {
        'use strict'

        var Transform = require('readable-stream').Transform
        var duplexify = require('duplexify')
        var base64 = require('base64-js')

        /* global FileReader */
        var my
        var proxy
        var stream
        var isInitialized = false

        function buildProxy() {
          var proxy = new Transform()
          proxy._write = function (chunk, encoding, next) {
            my.sendSocketMessage({
              data: chunk.buffer,
              success: function () {
                next()
              },
              fail: function () {
                next(new Error())
              }
            })
          }
          proxy._flush = function socketEnd(done) {
            my.closeSocket({
              success: function () {
                done()
              }
            })
          }

          return proxy
        }

        function setDefaultOpts(opts) {
          if (!opts.hostname) {
            opts.hostname = 'localhost'
          }
          if (!opts.path) {
            opts.path = '/'
          }

          if (!opts.wsOptions) {
            opts.wsOptions = {}
          }
        }

        function buildUrl(opts, client) {
          var protocol = opts.protocol === 'alis' ? 'wss' : 'ws'
          var url = protocol + '://' + opts.hostname + opts.path
          if (opts.port && opts.port !== 80 && opts.port !== 443) {
            url = protocol + '://' + opts.hostname + ':' + opts.port + opts.path
          }
          if (typeof (opts.transformWsUrl) === 'function') {
            url = opts.transformWsUrl(url, opts, client)
          }
          return url
        }

        function bindEventHandler() {
          if (isInitialized) return

          isInitialized = true

          my.onSocketOpen(function () {
            stream.setReadable(proxy)
            stream.setWritable(proxy)
            stream.emit('connect')
          })

          my.onSocketMessage(function (res) {
            if (typeof res.data === 'string') {
              var array = base64.toByteArray(res.data)
              var buffer = Buffer.from(array)
              proxy.push(buffer)
            } else {
              var reader = new FileReader()
              reader.addEventListener('load', function () {
                var data = reader.result

                if (data instanceof ArrayBuffer) data = Buffer.from(data)
                else data = Buffer.from(data, 'utf8')
                proxy.push(data)
              })
              reader.readAsArrayBuffer(res.data)
            }
          })

          my.onSocketClose(function () {
            stream.end()
            stream.destroy()
          })

          my.onSocketError(function (res) {
            stream.destroy(res)
          })
        }

        function buildStream(client, opts) {
          opts.hostname = opts.hostname || opts.host

          if (!opts.hostname) {
            throw new Error('Could not determine host. Specify host manually.')
          }

          var websocketSubProtocol =
            (opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3) ?
            'mqttv3.1' :
            'mqtt'

          setDefaultOpts(opts)

          var url = buildUrl(opts, client)
          my = opts.my
          my.connectSocket({
            url: url,
            protocols: websocketSubProtocol
          })

          proxy = buildProxy()
          stream = duplexify.obj()

          bindEventHandler()

          return stream
        }

        module.exports = buildStream

      }).call(this, require("buffer").Buffer)
    }, {
      "base64-js": 10,
      "buffer": 12,
      "duplexify": 17,
      "readable-stream": 108
    }],
    3: [function (require, module, exports) {
      'use strict'
      var net = require('net')

      /*
        variables port and host can be removed since
        you have all required information in opts object
      */
      function buildBuilder(client, opts) {
        var port, host
        opts.port = opts.port || 1883
        opts.hostname = opts.hostname || opts.host || 'localhost'

        port = opts.port
        host = opts.hostname

        return net.createConnection(port, host)
      }

      module.exports = buildBuilder

    }, {
      "net": 11
    }],
    4: [function (require, module, exports) {
      'use strict'
      var tls = require('tls')

      function buildBuilder(mqttClient, opts) {
        var connection
        opts.port = opts.port || 8883
        opts.host = opts.hostname || opts.host || 'localhost'

        opts.rejectUnauthorized = opts.rejectUnauthorized !== false

        delete opts.path

        connection = tls.connect(opts)
        /* eslint no-use-before-define: [2, "nofunc"] */
        connection.on('secureConnect', function () {
          if (opts.rejectUnauthorized && !connection.authorized) {
            connection.emit('error', new Error('TLS not authorized'))
          } else {
            connection.removeListener('error', handleTLSerrors)
          }
        })

        function handleTLSerrors(err) {
          // How can I get verify this error is a tls error?
          if (opts.rejectUnauthorized) {
            mqttClient.emit('error', err)
          }

          // close this connection to match the behaviour of net
          // otherwise all we get is an error from the connection
          // and close event doesn't fire. This is a work around
          // to enable the reconnect code to work the same as with
          // net.createConnection
          connection.end()
        }

        connection.on('error', handleTLSerrors)
        return connection
      }

      module.exports = buildBuilder

    }, {
      "tls": 11
    }],
    5: [function (require, module, exports) {
      (function (process) {
        'use strict'

        var websocket = require('websocket-stream')
        var urlModule = require('url')
        var WSS_OPTIONS = [
          'rejectUnauthorized',
          'ca',
          'cert',
          'key',
          'pfx',
          'passphrase'
        ]
        var IS_BROWSER = process.title === 'browser'

        function buildUrl(opts, client) {
          var url = opts.protocol + '://' + opts.hostname + ':' + opts.port + opts.path
          if (typeof (opts.transformWsUrl) === 'function') {
            url = opts.transformWsUrl(url, opts, client)
          }
          return url
        }

        function setDefaultOpts(opts) {
          if (!opts.hostname) {
            opts.hostname = 'localhost'
          }
          if (!opts.port) {
            if (opts.protocol === 'wss') {
              opts.port = 443
            } else {
              opts.port = 80
            }
          }
          if (!opts.path) {
            opts.path = '/'
          }

          if (!opts.wsOptions) {
            opts.wsOptions = {}
          }
          if (!IS_BROWSER && opts.protocol === 'wss') {
            // Add cert/key/ca etc options
            WSS_OPTIONS.forEach(function (prop) {
              if (opts.hasOwnProperty(prop) && !opts.wsOptions.hasOwnProperty(prop)) {
                opts.wsOptions[prop] = opts[prop]
              }
            })
          }
        }

        function createWebSocket(client, opts) {
          var websocketSubProtocol =
            (opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3) ?
            'mqttv3.1' :
            'mqtt'

          setDefaultOpts(opts)
          var url = buildUrl(opts, client)
          return websocket(url, [websocketSubProtocol], opts.wsOptions)
        }

        function buildBuilder(client, opts) {
          return createWebSocket(client, opts)
        }

        function buildBuilderBrowser(client, opts) {
          if (!opts.hostname) {
            opts.hostname = opts.host
          }

          if (!opts.hostname) {
            // Throwing an error in a Web Worker if no `hostname` is given, because we
            // can not determine the `hostname` automatically.  If connecting to
            // localhost, please supply the `hostname` as an argument.
            if (typeof (document) === 'undefined') {
              throw new Error('Could not determine host. Specify host manually.')
            }
            var parsed = urlModule.parse(document.URL)
            opts.hostname = parsed.hostname

            if (!opts.port) {
              opts.port = parsed.port
            }
          }
          return createWebSocket(client, opts)
        }

        if (IS_BROWSER) {
          module.exports = buildBuilderBrowser
        } else {
          module.exports = buildBuilder
        }

      }).call(this, require('_process'))
    }, {
      "_process": 92,
      "url": 113,
      "websocket-stream": 118
    }],
    6: [function (require, module, exports) {
      (function (process, Buffer) {
        'use strict'

        var Transform = require('readable-stream').Transform
        var duplexify = require('duplexify')

        /* global wx */
        var socketTask
        var proxy
        var stream

        function buildProxy() {
          var proxy = new Transform()
          proxy._write = function (chunk, encoding, next) {
            socketTask.send({
              data: chunk.buffer,
              success: function () {
                next()
              },
              fail: function (errMsg) {
                next(new Error(errMsg))
              }
            })
          }
          proxy._flush = function socketEnd(done) {
            socketTask.close({
              success: function () {
                done()
              }
            })
          }

          return proxy
        }

        function setDefaultOpts(opts) {
          if (!opts.hostname) {
            opts.hostname = 'localhost'
          }
          if (!opts.path) {
            opts.path = '/'
          }

          if (!opts.wsOptions) {
            opts.wsOptions = {}
          }
        }

        function buildUrl(opts, client) {
          var protocol = opts.protocol === 'wxs' ? 'wss' : 'ws'
          var url = protocol + '://' + opts.hostname + opts.path
          if (opts.port && opts.port !== 80 && opts.port !== 443) {
            url = protocol + '://' + opts.hostname + ':' + opts.port + opts.path
          }
          if (typeof (opts.transformWsUrl) === 'function') {
            url = opts.transformWsUrl(url, opts, client)
          }
          return url
        }

        function bindEventHandler() {
          socketTask.onOpen(function () {
            stream.setReadable(proxy)
            stream.setWritable(proxy)
            stream.emit('connect')
          })

          socketTask.onMessage(function (res) {
            var data = res.data

            if (data instanceof ArrayBuffer) data = Buffer.from(data)
            else data = Buffer.from(data, 'utf8')
            proxy.push(data)
          })

          socketTask.onClose(function () {
            stream.end()
            stream.destroy()
          })

          socketTask.onError(function (res) {
            stream.destroy(new Error(res.errMsg))
          })
        }

        function buildStream(client, opts) {
          opts.hostname = opts.hostname || opts.host

          if (!opts.hostname) {
            throw new Error('Could not determine host. Specify host manually.')
          }

          var websocketSubProtocol =
            (opts.protocolId === 'MQIsdp') && (opts.protocolVersion === 3) ?
            'mqttv3.1' :
            'mqtt'

          setDefaultOpts(opts)

          var url = buildUrl(opts, client)
          socketTask = wx.connectSocket({
            url: url,
            protocols: websocketSubProtocol
          })

          proxy = buildProxy()
          stream = duplexify.obj()
          stream._destroy = function (err, cb) {
            socketTask.close({
              success: function () {
                cb && cb(err)
              }
            })
          }

          var destroyRef = stream.destroy
          stream.destroy = function () {
            stream.destroy = destroyRef

            var self = this
            process.nextTick(function () {
              socketTask.close({
                fail: function () {
                  self._destroy(new Error())
                }
              })
            })
          }.bind(stream)

          bindEventHandler()

          return stream
        }

        module.exports = buildStream

      }).call(this, require('_process'), require("buffer").Buffer)
    }, {
      "_process": 92,
      "buffer": 12,
      "duplexify": 17,
      "readable-stream": 108
    }],
    7: [function (require, module, exports) {
      (function (process) {
        'use strict'

        /**
         * Module dependencies
         */
        var xtend = require('xtend')

        var Readable = require('readable-stream').Readable
        var streamsOpts = {
          objectMode: true
        }
        var defaultStoreOptions = {
          clean: true
        }

        /**
         * es6-map can preserve insertion order even if ES version is older.
         *
         * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Description
         * It should be noted that a Map which is a map of an object, especially
         * a dictionary of dictionaries, will only map to the object's insertion
         * order. In ES2015 this is ordered for objects but for older versions of
         * ES, this may be random and not ordered.
         *
         */
        var Map = require('es6-map')

        /**
         * In-memory implementation of the message store
         * This can actually be saved into files.
         *
         * @param {Object} [options] - store options
         */
        function Store(options) {
          if (!(this instanceof Store)) {
            return new Store(options)
          }

          this.options = options || {}

          // Defaults
          this.options = xtend(defaultStoreOptions, options)

          this._inflights = new Map()
        }

        /**
         * Adds a packet to the store, a packet is
         * anything that has a messageId property.
         *
         */
        Store.prototype.put = function (packet, cb) {
          this._inflights.set(packet.messageId, packet)

          if (cb) {
            cb()
          }

          return this
        }

        /**
         * Creates a stream with all the packets in the store
         *
         */
        Store.prototype.createStream = function () {
          var stream = new Readable(streamsOpts)
          var destroyed = false
          var values = []
          var i = 0

          this._inflights.forEach(function (value, key) {
            values.push(value)
          })

          stream._read = function () {
            if (!destroyed && i < values.length) {
              this.push(values[i++])
            } else {
              this.push(null)
            }
          }

          stream.destroy = function () {
            if (destroyed) {
              return
            }

            var self = this

            destroyed = true

            process.nextTick(function () {
              self.emit('close')
            })
          }

          return stream
        }

        /**
         * deletes a packet from the store.
         */
        Store.prototype.del = function (packet, cb) {
          packet = this._inflights.get(packet.messageId)
          if (packet) {
            this._inflights.delete(packet.messageId)
            cb(null, packet)
          } else if (cb) {
            cb(new Error('missing packet'))
          }

          return this
        }

        /**
         * get a packet from the store.
         */
        Store.prototype.get = function (packet, cb) {
          packet = this._inflights.get(packet.messageId)
          if (packet) {
            cb(null, packet)
          } else if (cb) {
            cb(new Error('missing packet'))
          }

          return this
        }

        /**
         * Close the store
         */
        Store.prototype.close = function (cb) {
          if (this.options.clean) {
            this._inflights = null
          }
          if (cb) {
            cb()
          }
        }

        module.exports = Store

      }).call(this, require('_process'))
    }, {
      "_process": 92,
      "es6-map": 67,
      "readable-stream": 108,
      "xtend": 121
    }],
    8: [function (require, module, exports) {
      'use strict'

      /**
       * Validate a topic to see if it's valid or not.
       * A topic is valid if it follow below rules:
       * - Rule #1: If any part of the topic is not `+` or `#`, then it must not contain `+` and '#'
       * - Rule #2: Part `#` must be located at the end of the mailbox
       *
       * @param {String} topic - A topic
       * @returns {Boolean} If the topic is valid, returns true. Otherwise, returns false.
       */
      function validateTopic(topic) {
        var parts = topic.split('/')

        for (var i = 0; i < parts.length; i++) {
          if (parts[i] === '+') {
            continue
          }

          if (parts[i] === '#') {
            // for Rule #2
            return i === parts.length - 1
          }

          if (parts[i].indexOf('+') !== -1 || parts[i].indexOf('#') !== -1) {
            return false
          }
        }

        return true
      }

      /**
       * Validate an array of topics to see if any of them is valid or not
       * @param {Array} topics - Array of topics
       * @returns {String} If the topics is valid, returns null. Otherwise, returns the invalid one
       */
      function validateTopics(topics) {
        if (topics.length === 0) {
          return 'empty_topic_list'
        }
        for (var i = 0; i < topics.length; i++) {
          if (!validateTopic(topics[i])) {
            return topics[i]
          }
        }
        return null
      }

      module.exports = {
        validateTopics: validateTopics
      }

    }, {}],
    9: [function (require, module, exports) {
      (function (process) {
        'use strict'

        var MqttClient = require('../client')
        var Store = require('../store')
        var url = require('url')
        var xtend = require('xtend')
        var protocols = {}

        if (process.title !== 'browser') {
          protocols.mqtt = require('./tcp')
          protocols.tcp = require('./tcp')
          protocols.ssl = require('./tls')
          protocols.tls = require('./tls')
          protocols.mqtts = require('./tls')
        } else {
          protocols.wx = require('./wx')
          protocols.wxs = require('./wx')

          protocols.ali = require('./ali')
          protocols.alis = require('./ali')
        }

        protocols.ws = require('./ws')
        protocols.wss = require('./ws')

        /**
         * Parse the auth attribute and merge username and password in the options object.
         *
         * @param {Object} [opts] option object
         */
        function parseAuthOptions(opts) {
          var matches
          if (opts.auth) {
            matches = opts.auth.match(/^(.+):(.+)$/)
            if (matches) {
              opts.username = matches[1]
              opts.password = matches[2]
            } else {
              opts.username = opts.auth
            }
          }
        }

        /**
         * connect - connect to an MQTT broker.
         *
         * @param {String} [brokerUrl] - url of the broker, optional
         * @param {Object} opts - see MqttClient#constructor
         */
        function connect(brokerUrl, opts) {
          if ((typeof brokerUrl === 'object') && !opts) {
            opts = brokerUrl
            brokerUrl = null
          }

          opts = opts || {}

          if (brokerUrl) {
            var parsed = url.parse(brokerUrl, true)
            if (parsed.port != null) {
              parsed.port = Number(parsed.port)
            }

            opts = xtend(parsed, opts)

            if (opts.protocol === null) {
              throw new Error('Missing protocol')
            }
            opts.protocol = opts.protocol.replace(/:$/, '')
          }

          // merge in the auth options if supplied
          parseAuthOptions(opts)

          // support clientId passed in the query string of the url
          if (opts.query && typeof opts.query.clientId === 'string') {
            opts.clientId = opts.query.clientId
          }

          if (opts.cert && opts.key) {
            if (opts.protocol) {
              if (['mqtts', 'wss', 'wxs', 'alis'].indexOf(opts.protocol) === -1) {
                switch (opts.protocol) {
                  case 'mqtt':
                    opts.protocol = 'mqtts'
                    break
                  case 'ws':
                    opts.protocol = 'wss'
                    break
                  case 'wx':
                    opts.protocol = 'wxs'
                    break
                  case 'ali':
                    opts.protocol = 'alis'
                    break
                  default:
                    throw new Error('Unknown protocol for secure connection: "' + opts.protocol + '"!')
                }
              }
            } else {
              // don't know what protocol he want to use, mqtts or wss
              throw new Error('Missing secure protocol key')
            }
          }

          if (!protocols[opts.protocol]) {
            var isSecure = ['mqtts', 'wss'].indexOf(opts.protocol) !== -1
            opts.protocol = [
              'mqtt',
              'mqtts',
              'ws',
              'wss',
              'wx',
              'wxs',
              'ali',
              'alis'
            ].filter(function (key, index) {
              if (isSecure && index % 2 === 0) {
                // Skip insecure protocols when requesting a secure one.
                return false
              }
              return (typeof protocols[key] === 'function')
            })[0]
          }

          if (opts.clean === false && !opts.clientId) {
            throw new Error('Missing clientId for unclean clients')
          }

          if (opts.protocol) {
            opts.defaultProtocol = opts.protocol
          }

          function wrapper(client) {
            if (opts.servers) {
              if (!client._reconnectCount || client._reconnectCount === opts.servers.length) {
                client._reconnectCount = 0
              }

              opts.host = opts.servers[client._reconnectCount].host
              opts.port = opts.servers[client._reconnectCount].port
              opts.protocol = (!opts.servers[client._reconnectCount].protocol ? opts.defaultProtocol : opts.servers[client._reconnectCount].protocol)
              opts.hostname = opts.host

              client._reconnectCount++
            }

            return protocols[opts.protocol](client, opts)
          }

          return new MqttClient(wrapper, opts)
        }

        module.exports = connect
        module.exports.connect = connect
        module.exports.MqttClient = MqttClient
        module.exports.Store = Store

      }).call(this, require('_process'))
    }, {
      "../client": 1,
      "../store": 7,
      "./ali": 2,
      "./tcp": 3,
      "./tls": 4,
      "./ws": 5,
      "./wx": 6,
      "_process": 92,
      "url": 113,
      "xtend": 121
    }],
    10: [function (require, module, exports) {
      'use strict'

      exports.byteLength = byteLength
      exports.toByteArray = toByteArray
      exports.fromByteArray = fromByteArray

      var lookup = []
      var revLookup = []
      var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array

      var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
      for (var i = 0, len = code.length; i < len; ++i) {
        lookup[i] = code[i]
        revLookup[code.charCodeAt(i)] = i
      }

      // Support decoding URL-safe base64 strings, as Node.js does.
      // See: https://en.wikipedia.org/wiki/Base64#URL_applications
      revLookup['-'.charCodeAt(0)] = 62
      revLookup['_'.charCodeAt(0)] = 63

      function getLens(b64) {
        var len = b64.length

        if (len % 4 > 0) {
          throw new Error('Invalid string. Length must be a multiple of 4')
        }

        // Trim off extra bytes after placeholder bytes are found
        // See: https://github.com/beatgammit/base64-js/issues/42
        var validLen = b64.indexOf('=')
        if (validLen === -1) validLen = len

        var placeHoldersLen = validLen === len ?
          0 :
          4 - (validLen % 4)

        return [validLen, placeHoldersLen]
      }

      // base64 is 4/3 + up to two characters of the original data
      function byteLength(b64) {
        var lens = getLens(b64)
        var validLen = lens[0]
        var placeHoldersLen = lens[1]
        return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
      }

      function _byteLength(b64, validLen, placeHoldersLen) {
        return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
      }

      function toByteArray(b64) {
        var tmp
        var lens = getLens(b64)
        var validLen = lens[0]
        var placeHoldersLen = lens[1]

        var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

        var curByte = 0

        // if there are placeholders, only get up to the last complete 4 chars
        var len = placeHoldersLen > 0 ?
          validLen - 4 :
          validLen

        for (var i = 0; i < len; i += 4) {
          tmp =
            (revLookup[b64.charCodeAt(i)] << 18) |
            (revLookup[b64.charCodeAt(i + 1)] << 12) |
            (revLookup[b64.charCodeAt(i + 2)] << 6) |
            revLookup[b64.charCodeAt(i + 3)]
          arr[curByte++] = (tmp >> 16) & 0xFF
          arr[curByte++] = (tmp >> 8) & 0xFF
          arr[curByte++] = tmp & 0xFF
        }

        if (placeHoldersLen === 2) {
          tmp =
            (revLookup[b64.charCodeAt(i)] << 2) |
            (revLookup[b64.charCodeAt(i + 1)] >> 4)
          arr[curByte++] = tmp & 0xFF
        }

        if (placeHoldersLen === 1) {
          tmp =
            (revLookup[b64.charCodeAt(i)] << 10) |
            (revLookup[b64.charCodeAt(i + 1)] << 4) |
            (revLookup[b64.charCodeAt(i + 2)] >> 2)
          arr[curByte++] = (tmp >> 8) & 0xFF
          arr[curByte++] = tmp & 0xFF
        }

        return arr
      }

      function tripletToBase64(num) {
        return lookup[num >> 18 & 0x3F] +
          lookup[num >> 12 & 0x3F] +
          lookup[num >> 6 & 0x3F] +
          lookup[num & 0x3F]
      }

      function encodeChunk(uint8, start, end) {
        var tmp
        var output = []
        for (var i = start; i < end; i += 3) {
          tmp =
            ((uint8[i] << 16) & 0xFF0000) +
            ((uint8[i + 1] << 8) & 0xFF00) +
            (uint8[i + 2] & 0xFF)
          output.push(tripletToBase64(tmp))
        }
        return output.join('')
      }

      function fromByteArray(uint8) {
        var tmp
        var len = uint8.length
        var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
        var parts = []
        var maxChunkLength = 16383 // must be multiple of 3

        // go through the array every three bytes, we'll deal with trailing stuff later
        for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
          parts.push(encodeChunk(
            uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
          ))
        }

        // pad the end with zeros, but make sure to not forget the extra bytes
        if (extraBytes === 1) {
          tmp = uint8[len - 1]
          parts.push(
            lookup[tmp >> 2] +
            lookup[(tmp << 4) & 0x3F] +
            '=='
          )
        } else if (extraBytes === 2) {
          tmp = (uint8[len - 2] << 8) + uint8[len - 1]
          parts.push(
            lookup[tmp >> 10] +
            lookup[(tmp >> 4) & 0x3F] +
            lookup[(tmp << 2) & 0x3F] +
            '='
          )
        }

        return parts.join('')
      }

    }, {}],
    11: [function (require, module, exports) {

    }, {}],
    12: [function (require, module, exports) {
      /*!
       * The buffer module from node.js, for the browser.
       *
       * @author   Feross Aboukhadijeh <https://feross.org>
       * @license  MIT
       */
      /* eslint-disable no-proto */

      'use strict'

      var base64 = require('base64-js')
      var ieee754 = require('ieee754')

      exports.Buffer = Buffer
      exports.SlowBuffer = SlowBuffer
      exports.INSPECT_MAX_BYTES = 50

      var K_MAX_LENGTH = 0x7fffffff
      exports.kMaxLength = K_MAX_LENGTH

      /**
       * If `Buffer.TYPED_ARRAY_SUPPORT`:
       *   === true    Use Uint8Array implementation (fastest)
       *   === false   Print warning and recommend using `buffer` v4.x which has an Object
       *               implementation (most compatible, even IE6)
       *
       * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
       * Opera 11.6+, iOS 4.2+.
       *
       * We report that the browser does not support typed arrays if the are not subclassable
       * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
       * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
       * for __proto__ and has a buggy typed array implementation.
       */
      Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()

      if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
        typeof console.error === 'function') {
        console.error(
          'This browser lacks typed array (Uint8Array) support which is required by ' +
          '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
        )
      }

      function typedArraySupport() {
        // Can typed array instances can be augmented?
        try {
          var arr = new Uint8Array(1)
          arr.__proto__ = {
            __proto__: Uint8Array.prototype,
            foo: function () {
              return 42
            }
          }
          return arr.foo() === 42
        } catch (e) {
          return false
        }
      }

      Object.defineProperty(Buffer.prototype, 'parent', {
        enumerable: true,
        get: function () {
          if (!Buffer.isBuffer(this)) return undefined
          return this.buffer
        }
      })

      Object.defineProperty(Buffer.prototype, 'offset', {
        enumerable: true,
        get: function () {
          if (!Buffer.isBuffer(this)) return undefined
          return this.byteOffset
        }
      })

      function createBuffer(length) {
        if (length > K_MAX_LENGTH) {
          throw new RangeError('The value "' + length + '" is invalid for option "size"')
        }
        // Return an augmented `Uint8Array` instance
        var buf = new Uint8Array(length)
        buf.__proto__ = Buffer.prototype
        return buf
      }

      /**
       * The Buffer constructor returns instances of `Uint8Array` that have their
       * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
       * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
       * and the `Uint8Array` methods. Square bracket notation works as expected -- it
       * returns a single octet.
       *
       * The `Uint8Array` prototype remains unmodified.
       */

      function Buffer(arg, encodingOrOffset, length) {
        // Common case.
        if (typeof arg === 'number') {
          if (typeof encodingOrOffset === 'string') {
            throw new TypeError(
              'The "string" argument must be of type string. Received type number'
            )
          }
          return allocUnsafe(arg)
        }
        return from(arg, encodingOrOffset, length)
      }

      // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
      if (typeof Symbol !== 'undefined' && Symbol.species != null &&
        Buffer[Symbol.species] === Buffer) {
        Object.defineProperty(Buffer, Symbol.species, {
          value: null,
          configurable: true,
          enumerable: false,
          writable: false
        })
      }

      Buffer.poolSize = 8192 // not used by this implementation

      function from(value, encodingOrOffset, length) {
        if (typeof value === 'string') {
          return fromString(value, encodingOrOffset)
        }

        if (ArrayBuffer.isView(value)) {
          return fromArrayLike(value)
        }

        if (value == null) {
          throw TypeError(
            'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
            'or Array-like Object. Received type ' + (typeof value)
          )
        }

        if (isInstance(value, ArrayBuffer) ||
          (value && isInstance(value.buffer, ArrayBuffer))) {
          return fromArrayBuffer(value, encodingOrOffset, length)
        }

        if (typeof value === 'number') {
          throw new TypeError(
            'The "value" argument must not be of type number. Received type number'
          )
        }

        var valueOf = value.valueOf && value.valueOf()
        if (valueOf != null && valueOf !== value) {
          return Buffer.from(valueOf, encodingOrOffset, length)
        }

        var b = fromObject(value)
        if (b) return b

        if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
          typeof value[Symbol.toPrimitive] === 'function') {
          return Buffer.from(
            value[Symbol.toPrimitive]('string'), encodingOrOffset, length
          )
        }

        throw new TypeError(
          'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
          'or Array-like Object. Received type ' + (typeof value)
        )
      }

      /**
       * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
       * if value is a number.
       * Buffer.from(str[, encoding])
       * Buffer.from(array)
       * Buffer.from(buffer)
       * Buffer.from(arrayBuffer[, byteOffset[, length]])
       **/
      Buffer.from = function (value, encodingOrOffset, length) {
        return from(value, encodingOrOffset, length)
      }

      // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
      // https://github.com/feross/buffer/pull/148
      Buffer.prototype.__proto__ = Uint8Array.prototype
      Buffer.__proto__ = Uint8Array

      function assertSize(size) {
        if (typeof size !== 'number') {
          throw new TypeError('"size" argument must be of type number')
        } else if (size < 0) {
          throw new RangeError('The value "' + size + '" is invalid for option "size"')
        }
      }

      function alloc(size, fill, encoding) {
        assertSize(size)
        if (size <= 0) {
          return createBuffer(size)
        }
        if (fill !== undefined) {
          // Only pay attention to encoding if it's a string. This
          // prevents accidentally sending in a number that would
          // be interpretted as a start offset.
          return typeof encoding === 'string' ?
            createBuffer(size).fill(fill, encoding) :
            createBuffer(size).fill(fill)
        }
        return createBuffer(size)
      }

      /**
       * Creates a new filled Buffer instance.
       * alloc(size[, fill[, encoding]])
       **/
      Buffer.alloc = function (size, fill, encoding) {
        return alloc(size, fill, encoding)
      }

      function allocUnsafe(size) {
        assertSize(size)
        return createBuffer(size < 0 ? 0 : checked(size) | 0)
      }

      /**
       * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
       * */
      Buffer.allocUnsafe = function (size) {
        return allocUnsafe(size)
      }
      /**
       * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
       */
      Buffer.allocUnsafeSlow = function (size) {
        return allocUnsafe(size)
      }

      function fromString(string, encoding) {
        if (typeof encoding !== 'string' || encoding === '') {
          encoding = 'utf8'
        }

        if (!Buffer.isEncoding(encoding)) {
          throw new TypeError('Unknown encoding: ' + encoding)
        }

        var length = byteLength(string, encoding) | 0
        var buf = createBuffer(length)

        var actual = buf.write(string, encoding)

        if (actual !== length) {
          // Writing a hex string, for example, that contains invalid characters will
          // cause everything after the first invalid character to be ignored. (e.g.
          // 'abxxcd' will be treated as 'ab')
          buf = buf.slice(0, actual)
        }

        return buf
      }

      function fromArrayLike(array) {
        var length = array.length < 0 ? 0 : checked(array.length) | 0
        var buf = createBuffer(length)
        for (var i = 0; i < length; i += 1) {
          buf[i] = array[i] & 255
        }
        return buf
      }

      function fromArrayBuffer(array, byteOffset, length) {
        if (byteOffset < 0 || array.byteLength < byteOffset) {
          throw new RangeError('"offset" is outside of buffer bounds')
        }

        if (array.byteLength < byteOffset + (length || 0)) {
          throw new RangeError('"length" is outside of buffer bounds')
        }

        var buf
        if (byteOffset === undefined && length === undefined) {
          buf = new Uint8Array(array)
        } else if (length === undefined) {
          buf = new Uint8Array(array, byteOffset)
        } else {
          buf = new Uint8Array(array, byteOffset, length)
        }

        // Return an augmented `Uint8Array` instance
        buf.__proto__ = Buffer.prototype
        return buf
      }

      function fromObject(obj) {
        if (Buffer.isBuffer(obj)) {
          var len = checked(obj.length) | 0
          var buf = createBuffer(len)

          if (buf.length === 0) {
            return buf
          }

          obj.copy(buf, 0, 0, len)
          return buf
        }

        if (obj.length !== undefined) {
          if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
            return createBuffer(0)
          }
          return fromArrayLike(obj)
        }

        if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
          return fromArrayLike(obj.data)
        }
      }

      function checked(length) {
        // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
        // length is NaN (which is otherwise coerced to zero.)
        if (length >= K_MAX_LENGTH) {
          throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
            'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
        }
        return length | 0
      }

      function SlowBuffer(length) {
        if (+length != length) { // eslint-disable-line eqeqeq
          length = 0
        }
        return Buffer.alloc(+length)
      }

      Buffer.isBuffer = function isBuffer(b) {
        return b != null && b._isBuffer === true &&
          b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
      }

      Buffer.compare = function compare(a, b) {
        if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
        if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
        if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
          throw new TypeError(
            'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
          )
        }

        if (a === b) return 0

        var x = a.length
        var y = b.length

        for (var i = 0, len = Math.min(x, y); i < len; ++i) {
          if (a[i] !== b[i]) {
            x = a[i]
            y = b[i]
            break
          }
        }

        if (x < y) return -1
        if (y < x) return 1
        return 0
      }

      Buffer.isEncoding = function isEncoding(encoding) {
        switch (String(encoding).toLowerCase()) {
          case 'hex':
          case 'utf8':
          case 'utf-8':
          case 'ascii':
          case 'latin1':
          case 'binary':
          case 'base64':
          case 'ucs2':
          case 'ucs-2':
          case 'utf16le':
          case 'utf-16le':
            return true
          default:
            return false
        }
      }

      Buffer.concat = function concat(list, length) {
        if (!Array.isArray(list)) {
          throw new TypeError('"list" argument must be an Array of Buffers')
        }

        if (list.length === 0) {
          return Buffer.alloc(0)
        }

        var i
        if (length === undefined) {
          length = 0
          for (i = 0; i < list.length; ++i) {
            length += list[i].length
          }
        }

        var buffer = Buffer.allocUnsafe(length)
        var pos = 0
        for (i = 0; i < list.length; ++i) {
          var buf = list[i]
          if (isInstance(buf, Uint8Array)) {
            buf = Buffer.from(buf)
          }
          if (!Buffer.isBuffer(buf)) {
            throw new TypeError('"list" argument must be an Array of Buffers')
          }
          buf.copy(buffer, pos)
          pos += buf.length
        }
        return buffer
      }

      function byteLength(string, encoding) {
        if (Buffer.isBuffer(string)) {
          return string.length
        }
        if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
          return string.byteLength
        }
        if (typeof string !== 'string') {
          throw new TypeError(
            'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
            'Received type ' + typeof string
          )
        }

        var len = string.length
        var mustMatch = (arguments.length > 2 && arguments[2] === true)
        if (!mustMatch && len === 0) return 0

        // Use a for loop to avoid recursion
        var loweredCase = false
        for (;;) {
          switch (encoding) {
            case 'ascii':
            case 'latin1':
            case 'binary':
              return len
            case 'utf8':
            case 'utf-8':
              return utf8ToBytes(string).length
            case 'ucs2':
            case 'ucs-2':
            case 'utf16le':
            case 'utf-16le':
              return len * 2
            case 'hex':
              return len >>> 1
            case 'base64':
              return base64ToBytes(string).length
            default:
              if (loweredCase) {
                return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
              }
              encoding = ('' + encoding).toLowerCase()
              loweredCase = true
          }
        }
      }
      Buffer.byteLength = byteLength

      function slowToString(encoding, start, end) {
        var loweredCase = false

        // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
        // property of a typed array.

        // This behaves neither like String nor Uint8Array in that we set start/end
        // to their upper/lower bounds if the value passed is out of range.
        // undefined is handled specially as per ECMA-262 6th Edition,
        // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
        if (start === undefined || start < 0) {
          start = 0
        }
        // Return early if start > this.length. Done here to prevent potential uint32
        // coercion fail below.
        if (start > this.length) {
          return ''
        }

        if (end === undefined || end > this.length) {
          end = this.length
        }

        if (end <= 0) {
          return ''
        }

        // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
        end >>>= 0
        start >>>= 0

        if (end <= start) {
          return ''
        }

        if (!encoding) encoding = 'utf8'

        while (true) {
          switch (encoding) {
            case 'hex':
              return hexSlice(this, start, end)

            case 'utf8':
            case 'utf-8':
              return utf8Slice(this, start, end)

            case 'ascii':
              return asciiSlice(this, start, end)

            case 'latin1':
            case 'binary':
              return latin1Slice(this, start, end)

            case 'base64':
              return base64Slice(this, start, end)

            case 'ucs2':
            case 'ucs-2':
            case 'utf16le':
            case 'utf-16le':
              return utf16leSlice(this, start, end)

            default:
              if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
              encoding = (encoding + '').toLowerCase()
              loweredCase = true
          }
        }
      }

      // This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
      // to detect a Buffer instance. It's not possible to use `instanceof Buffer`
      // reliably in a browserify context because there could be multiple different
      // copies of the 'buffer' package in use. This method works even for Buffer
      // instances that were created from another copy of the `buffer` package.
      // See: https://github.com/feross/buffer/issues/154
      Buffer.prototype._isBuffer = true

      function swap(b, n, m) {
        var i = b[n]
        b[n] = b[m]
        b[m] = i
      }

      Buffer.prototype.swap16 = function swap16() {
        var len = this.length
        if (len % 2 !== 0) {
          throw new RangeError('Buffer size must be a multiple of 16-bits')
        }
        for (var i = 0; i < len; i += 2) {
          swap(this, i, i + 1)
        }
        return this
      }

      Buffer.prototype.swap32 = function swap32() {
        var len = this.length
        if (len % 4 !== 0) {
          throw new RangeError('Buffer size must be a multiple of 32-bits')
        }
        for (var i = 0; i < len; i += 4) {
          swap(this, i, i + 3)
          swap(this, i + 1, i + 2)
        }
        return this
      }

      Buffer.prototype.swap64 = function swap64() {
        var len = this.length
        if (len % 8 !== 0) {
          throw new RangeError('Buffer size must be a multiple of 64-bits')
        }
        for (var i = 0; i < len; i += 8) {
          swap(this, i, i + 7)
          swap(this, i + 1, i + 6)
          swap(this, i + 2, i + 5)
          swap(this, i + 3, i + 4)
        }
        return this
      }

      Buffer.prototype.toString = function toString() {
        var length = this.length
        if (length === 0) return ''
        if (arguments.length === 0) return utf8Slice(this, 0, length)
        return slowToString.apply(this, arguments)
      }

      Buffer.prototype.toLocaleString = Buffer.prototype.toString

      Buffer.prototype.equals = function equals(b) {
        if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
        if (this === b) return true
        return Buffer.compare(this, b) === 0
      }

      Buffer.prototype.inspect = function inspect() {
        var str = ''
        var max = exports.INSPECT_MAX_BYTES
        str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
        if (this.length > max) str += ' ... '
        return '<Buffer ' + str + '>'
      }

      Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) {
        if (isInstance(target, Uint8Array)) {
          target = Buffer.from(target, target.offset, target.byteLength)
        }
        if (!Buffer.isBuffer(target)) {
          throw new TypeError(
            'The "target" argument must be one of type Buffer or Uint8Array. ' +
            'Received type ' + (typeof target)
          )
        }

        if (start === undefined) {
          start = 0
        }
        if (end === undefined) {
          end = target ? target.length : 0
        }
        if (thisStart === undefined) {
          thisStart = 0
        }
        if (thisEnd === undefined) {
          thisEnd = this.length
        }

        if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
          throw new RangeError('out of range index')
        }

        if (thisStart >= thisEnd && start >= end) {
          return 0
        }
        if (thisStart >= thisEnd) {
          return -1
        }
        if (start >= end) {
          return 1
        }

        start >>>= 0
        end >>>= 0
        thisStart >>>= 0
        thisEnd >>>= 0

        if (this === target) return 0

        var x = thisEnd - thisStart
        var y = end - start
        var len = Math.min(x, y)

        var thisCopy = this.slice(thisStart, thisEnd)
        var targetCopy = target.slice(start, end)

        for (var i = 0; i < len; ++i) {
          if (thisCopy[i] !== targetCopy[i]) {
            x = thisCopy[i]
            y = targetCopy[i]
            break
          }
        }

        if (x < y) return -1
        if (y < x) return 1
        return 0
      }

      // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
      // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
      //
      // Arguments:
      // - buffer - a Buffer to search
      // - val - a string, Buffer, or number
      // - byteOffset - an index into `buffer`; will be clamped to an int32
      // - encoding - an optional encoding, relevant is val is a string
      // - dir - true for indexOf, false for lastIndexOf
      function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
        // Empty buffer means no match
        if (buffer.length === 0) return -1

        // Normalize byteOffset
        if (typeof byteOffset === 'string') {
          encoding = byteOffset
          byteOffset = 0
        } else if (byteOffset > 0x7fffffff) {
          byteOffset = 0x7fffffff
        } else if (byteOffset < -0x80000000) {
          byteOffset = -0x80000000
        }
        byteOffset = +byteOffset // Coerce to Number.
        if (numberIsNaN(byteOffset)) {
          // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
          byteOffset = dir ? 0 : (buffer.length - 1)
        }

        // Normalize byteOffset: negative offsets start from the end of the buffer
        if (byteOffset < 0) byteOffset = buffer.length + byteOffset
        if (byteOffset >= buffer.length) {
          if (dir) return -1
          else byteOffset = buffer.length - 1
        } else if (byteOffset < 0) {
          if (dir) byteOffset = 0
          else return -1
        }

        // Normalize val
        if (typeof val === 'string') {
          val = Buffer.from(val, encoding)
        }

        // Finally, search either indexOf (if dir is true) or lastIndexOf
        if (Buffer.isBuffer(val)) {
          // Special case: looking for empty string/buffer always fails
          if (val.length === 0) {
            return -1
          }
          return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
        } else if (typeof val === 'number') {
          val = val & 0xFF // Search for a byte value [0-255]
          if (typeof Uint8Array.prototype.indexOf === 'function') {
            if (dir) {
              return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
            } else {
              return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
            }
          }
          return arrayIndexOf(buffer, [val], byteOffset, encoding, dir)
        }

        throw new TypeError('val must be string, number or Buffer')
      }

      function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
        var indexSize = 1
        var arrLength = arr.length
        var valLength = val.length

        if (encoding !== undefined) {
          encoding = String(encoding).toLowerCase()
          if (encoding === 'ucs2' || encoding === 'ucs-2' ||
            encoding === 'utf16le' || encoding === 'utf-16le') {
            if (arr.length < 2 || val.length < 2) {
              return -1
            }
            indexSize = 2
            arrLength /= 2
            valLength /= 2
            byteOffset /= 2
          }
        }

        function read(buf, i) {
          if (indexSize === 1) {
            return buf[i]
          } else {
            return buf.readUInt16BE(i * indexSize)
          }
        }

        var i
        if (dir) {
          var foundIndex = -1
          for (i = byteOffset; i < arrLength; i++) {
            if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
              if (foundIndex === -1) foundIndex = i
              if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
            } else {
              if (foundIndex !== -1) i -= i - foundIndex
              foundIndex = -1
            }
          }
        } else {
          if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
          for (i = byteOffset; i >= 0; i--) {
            var found = true
            for (var j = 0; j < valLength; j++) {
              if (read(arr, i + j) !== read(val, j)) {
                found = false
                break
              }
            }
            if (found) return i
          }
        }

        return -1
      }

      Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
        return this.indexOf(val, byteOffset, encoding) !== -1
      }

      Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
        return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
      }

      Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
        return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
      }

      function hexWrite(buf, string, offset, length) {
        offset = Number(offset) || 0
        var remaining = buf.length - offset
        if (!length) {
          length = remaining
        } else {
          length = Number(length)
          if (length > remaining) {
            length = remaining
          }
        }

        var strLen = string.length

        if (length > strLen / 2) {
          length = strLen / 2
        }
        for (var i = 0; i < length; ++i) {
          var parsed = parseInt(string.substr(i * 2, 2), 16)
          if (numberIsNaN(parsed)) return i
          buf[offset + i] = parsed
        }
        return i
      }

      function utf8Write(buf, string, offset, length) {
        return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
      }

      function asciiWrite(buf, string, offset, length) {
        return blitBuffer(asciiToBytes(string), buf, offset, length)
      }

      function latin1Write(buf, string, offset, length) {
        return asciiWrite(buf, string, offset, length)
      }

      function base64Write(buf, string, offset, length) {
        return blitBuffer(base64ToBytes(string), buf, offset, length)
      }

      function ucs2Write(buf, string, offset, length) {
        return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
      }

      Buffer.prototype.write = function write(string, offset, length, encoding) {
        // Buffer#write(string)
        if (offset === undefined) {
          encoding = 'utf8'
          length = this.length
          offset = 0
          // Buffer#write(string, encoding)
        } else if (length === undefined && typeof offset === 'string') {
          encoding = offset
          length = this.length
          offset = 0
          // Buffer#write(string, offset[, length][, encoding])
        } else if (isFinite(offset)) {
          offset = offset >>> 0
          if (isFinite(length)) {
            length = length >>> 0
            if (encoding === undefined) encoding = 'utf8'
          } else {
            encoding = length
            length = undefined
          }
        } else {
          throw new Error(
            'Buffer.write(string, encoding, offset[, length]) is no longer supported'
          )
        }

        var remaining = this.length - offset
        if (length === undefined || length > remaining) length = remaining

        if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
          throw new RangeError('Attempt to write outside buffer bounds')
        }

        if (!encoding) encoding = 'utf8'

        var loweredCase = false
        for (;;) {
          switch (encoding) {
            case 'hex':
              return hexWrite(this, string, offset, length)

            case 'utf8':
            case 'utf-8':
              return utf8Write(this, string, offset, length)

            case 'ascii':
              return asciiWrite(this, string, offset, length)

            case 'latin1':
            case 'binary':
              return latin1Write(this, string, offset, length)

            case 'base64':
              // Warning: maxLength not taken into account in base64Write
              return base64Write(this, string, offset, length)

            case 'ucs2':
            case 'ucs-2':
            case 'utf16le':
            case 'utf-16le':
              return ucs2Write(this, string, offset, length)

            default:
              if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
              encoding = ('' + encoding).toLowerCase()
              loweredCase = true
          }
        }
      }

      Buffer.prototype.toJSON = function toJSON() {
        return {
          type: 'Buffer',
          data: Array.prototype.slice.call(this._arr || this, 0)
        }
      }

      function base64Slice(buf, start, end) {
        if (start === 0 && end === buf.length) {
          return base64.fromByteArray(buf)
        } else {
          return base64.fromByteArray(buf.slice(start, end))
        }
      }

      function utf8Slice(buf, start, end) {
        end = Math.min(buf.length, end)
        var res = []

        var i = start
        while (i < end) {
          var firstByte = buf[i]
          var codePoint = null
          var bytesPerSequence = (firstByte > 0xEF) ? 4 :
            (firstByte > 0xDF) ? 3 :
            (firstByte > 0xBF) ? 2 :
            1

          if (i + bytesPerSequence <= end) {
            var secondByte, thirdByte, fourthByte, tempCodePoint

            switch (bytesPerSequence) {
              case 1:
                if (firstByte < 0x80) {
                  codePoint = firstByte
                }
                break
              case 2:
                secondByte = buf[i + 1]
                if ((secondByte & 0xC0) === 0x80) {
                  tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
                  if (tempCodePoint > 0x7F) {
                    codePoint = tempCodePoint
                  }
                }
                break
              case 3:
                secondByte = buf[i + 1]
                thirdByte = buf[i + 2]
                if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
                  tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
                  if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                    codePoint = tempCodePoint
                  }
                }
                break
              case 4:
                secondByte = buf[i + 1]
                thirdByte = buf[i + 2]
                fourthByte = buf[i + 3]
                if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
                  tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
                  if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                    codePoint = tempCodePoint
                  }
                }
            }
          }

          if (codePoint === null) {
            // we did not generate a valid codePoint so insert a
            // replacement char (U+FFFD) and advance only 1 byte
            codePoint = 0xFFFD
            bytesPerSequence = 1
          } else if (codePoint > 0xFFFF) {
            // encode to utf16 (surrogate pair dance)
            codePoint -= 0x10000
            res.push(codePoint >>> 10 & 0x3FF | 0xD800)
            codePoint = 0xDC00 | codePoint & 0x3FF
          }

          res.push(codePoint)
          i += bytesPerSequence
        }

        return decodeCodePointsArray(res)
      }

      // Based on http://stackoverflow.com/a/22747272/680742, the browser with
      // the lowest limit is Chrome, with 0x10000 args.
      // We go 1 magnitude less, for safety
      var MAX_ARGUMENTS_LENGTH = 0x1000

      function decodeCodePointsArray(codePoints) {
        var len = codePoints.length
        if (len <= MAX_ARGUMENTS_LENGTH) {
          return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
        }

        // Decode in chunks to avoid "call stack size exceeded".
        var res = ''
        var i = 0
        while (i < len) {
          res += String.fromCharCode.apply(
            String,
            codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
          )
        }
        return res
      }

      function asciiSlice(buf, start, end) {
        var ret = ''
        end = Math.min(buf.length, end)

        for (var i = start; i < end; ++i) {
          ret += String.fromCharCode(buf[i] & 0x7F)
        }
        return ret
      }

      function latin1Slice(buf, start, end) {
        var ret = ''
        end = Math.min(buf.length, end)

        for (var i = start; i < end; ++i) {
          ret += String.fromCharCode(buf[i])
        }
        return ret
      }

      function hexSlice(buf, start, end) {
        var len = buf.length

        if (!start || start < 0) start = 0
        if (!end || end < 0 || end > len) end = len

        var out = ''
        for (var i = start; i < end; ++i) {
          out += toHex(buf[i])
        }
        return out
      }

      function utf16leSlice(buf, start, end) {
        var bytes = buf.slice(start, end)
        var res = ''
        for (var i = 0; i < bytes.length; i += 2) {
          res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
        }
        return res
      }

      Buffer.prototype.slice = function slice(start, end) {
        var len = this.length
        start = ~~start
        end = end === undefined ? len : ~~end

        if (start < 0) {
          start += len
          if (start < 0) start = 0
        } else if (start > len) {
          start = len
        }

        if (end < 0) {
          end += len
          if (end < 0) end = 0
        } else if (end > len) {
          end = len
        }

        if (end < start) end = start

        var newBuf = this.subarray(start, end)
        // Return an augmented `Uint8Array` instance
        newBuf.__proto__ = Buffer.prototype
        return newBuf
      }

      /*
       * Need to make sure that buffer isn't trying to write out of bounds.
       */
      function checkOffset(offset, ext, length) {
        if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
        if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
      }

      Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) checkOffset(offset, byteLength, this.length)

        var val = this[offset]
        var mul = 1
        var i = 0
        while (++i < byteLength && (mul *= 0x100)) {
          val += this[offset + i] * mul
        }

        return val
      }

      Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) {
          checkOffset(offset, byteLength, this.length)
        }

        var val = this[offset + --byteLength]
        var mul = 1
        while (byteLength > 0 && (mul *= 0x100)) {
          val += this[offset + --byteLength] * mul
        }

        return val
      }

      Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 1, this.length)
        return this[offset]
      }

      Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 2, this.length)
        return this[offset] | (this[offset + 1] << 8)
      }

      Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 2, this.length)
        return (this[offset] << 8) | this[offset + 1]
      }

      Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)

        return ((this[offset]) |
            (this[offset + 1] << 8) |
            (this[offset + 2] << 16)) +
          (this[offset + 3] * 0x1000000)
      }

      Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)

        return (this[offset] * 0x1000000) +
          ((this[offset + 1] << 16) |
            (this[offset + 2] << 8) |
            this[offset + 3])
      }

      Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) checkOffset(offset, byteLength, this.length)

        var val = this[offset]
        var mul = 1
        var i = 0
        while (++i < byteLength && (mul *= 0x100)) {
          val += this[offset + i] * mul
        }
        mul *= 0x80

        if (val >= mul) val -= Math.pow(2, 8 * byteLength)

        return val
      }

      Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) checkOffset(offset, byteLength, this.length)

        var i = byteLength
        var mul = 1
        var val = this[offset + --i]
        while (i > 0 && (mul *= 0x100)) {
          val += this[offset + --i] * mul
        }
        mul *= 0x80

        if (val >= mul) val -= Math.pow(2, 8 * byteLength)

        return val
      }

      Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 1, this.length)
        if (!(this[offset] & 0x80)) return (this[offset])
        return ((0xff - this[offset] + 1) * -1)
      }

      Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 2, this.length)
        var val = this[offset] | (this[offset + 1] << 8)
        return (val & 0x8000) ? val | 0xFFFF0000 : val
      }

      Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 2, this.length)
        var val = this[offset + 1] | (this[offset] << 8)
        return (val & 0x8000) ? val | 0xFFFF0000 : val
      }

      Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)

        return (this[offset]) |
          (this[offset + 1] << 8) |
          (this[offset + 2] << 16) |
          (this[offset + 3] << 24)
      }

      Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)

        return (this[offset] << 24) |
          (this[offset + 1] << 16) |
          (this[offset + 2] << 8) |
          (this[offset + 3])
      }

      Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)
        return ieee754.read(this, offset, true, 23, 4)
      }

      Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 4, this.length)
        return ieee754.read(this, offset, false, 23, 4)
      }

      Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 8, this.length)
        return ieee754.read(this, offset, true, 52, 8)
      }

      Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
        offset = offset >>> 0
        if (!noAssert) checkOffset(offset, 8, this.length)
        return ieee754.read(this, offset, false, 52, 8)
      }

      function checkInt(buf, value, offset, ext, max, min) {
        if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
        if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
        if (offset + ext > buf.length) throw new RangeError('Index out of range')
      }

      Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
        value = +value
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) {
          var maxBytes = Math.pow(2, 8 * byteLength) - 1
          checkInt(this, value, offset, byteLength, maxBytes, 0)
        }

        var mul = 1
        var i = 0
        this[offset] = value & 0xFF
        while (++i < byteLength && (mul *= 0x100)) {
          this[offset + i] = (value / mul) & 0xFF
        }

        return offset + byteLength
      }

      Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
        value = +value
        offset = offset >>> 0
        byteLength = byteLength >>> 0
        if (!noAssert) {
          var maxBytes = Math.pow(2, 8 * byteLength) - 1
          checkInt(this, value, offset, byteLength, maxBytes, 0)
        }

        var i = byteLength - 1
        var mul = 1
        this[offset + i] = value & 0xFF
        while (--i >= 0 && (mul *= 0x100)) {
          this[offset + i] = (value / mul) & 0xFF
        }

        return offset + byteLength
      }

      Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
        this[offset] = (value & 0xff)
        return offset + 1
      }

      Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
        this[offset] = (value & 0xff)
        this[offset + 1] = (value >>> 8)
        return offset + 2
      }

      Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
        this[offset] = (value >>> 8)
        this[offset + 1] = (value & 0xff)
        return offset + 2
      }

      Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
        this[offset + 3] = (value >>> 24)
        this[offset + 2] = (value >>> 16)
        this[offset + 1] = (value >>> 8)
        this[offset] = (value & 0xff)
        return offset + 4
      }

      Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
        this[offset] = (value >>> 24)
        this[offset + 1] = (value >>> 16)
        this[offset + 2] = (value >>> 8)
        this[offset + 3] = (value & 0xff)
        return offset + 4
      }

      Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) {
          var limit = Math.pow(2, (8 * byteLength) - 1)

          checkInt(this, value, offset, byteLength, limit - 1, -limit)
        }

        var i = 0
        var mul = 1
        var sub = 0
        this[offset] = value & 0xFF
        while (++i < byteLength && (mul *= 0x100)) {
          if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
            sub = 1
          }
          this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
        }

        return offset + byteLength
      }

      Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) {
          var limit = Math.pow(2, (8 * byteLength) - 1)

          checkInt(this, value, offset, byteLength, limit - 1, -limit)
        }

        var i = byteLength - 1
        var mul = 1
        var sub = 0
        this[offset + i] = value & 0xFF
        while (--i >= 0 && (mul *= 0x100)) {
          if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
            sub = 1
          }
          this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
        }

        return offset + byteLength
      }

      Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
        if (value < 0) value = 0xff + value + 1
        this[offset] = (value & 0xff)
        return offset + 1
      }

      Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
        this[offset] = (value & 0xff)
        this[offset + 1] = (value >>> 8)
        return offset + 2
      }

      Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
        this[offset] = (value >>> 8)
        this[offset + 1] = (value & 0xff)
        return offset + 2
      }

      Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
        this[offset] = (value & 0xff)
        this[offset + 1] = (value >>> 8)
        this[offset + 2] = (value >>> 16)
        this[offset + 3] = (value >>> 24)
        return offset + 4
      }

      Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
        if (value < 0) value = 0xffffffff + value + 1
        this[offset] = (value >>> 24)
        this[offset + 1] = (value >>> 16)
        this[offset + 2] = (value >>> 8)
        this[offset + 3] = (value & 0xff)
        return offset + 4
      }

      function checkIEEE754(buf, value, offset, ext, max, min) {
        if (offset + ext > buf.length) throw new RangeError('Index out of range')
        if (offset < 0) throw new RangeError('Index out of range')
      }

      function writeFloat(buf, value, offset, littleEndian, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) {
          checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
        }
        ieee754.write(buf, value, offset, littleEndian, 23, 4)
        return offset + 4
      }

      Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
        return writeFloat(this, value, offset, true, noAssert)
      }

      Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
        return writeFloat(this, value, offset, false, noAssert)
      }

      function writeDouble(buf, value, offset, littleEndian, noAssert) {
        value = +value
        offset = offset >>> 0
        if (!noAssert) {
          checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
        }
        ieee754.write(buf, value, offset, littleEndian, 52, 8)
        return offset + 8
      }

      Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
        return writeDouble(this, value, offset, true, noAssert)
      }

      Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
        return writeDouble(this, value, offset, false, noAssert)
      }

      // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
      Buffer.prototype.copy = function copy(target, targetStart, start, end) {
        if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
        if (!start) start = 0
        if (!end && end !== 0) end = this.length
        if (targetStart >= target.length) targetStart = target.length
        if (!targetStart) targetStart = 0
        if (end > 0 && end < start) end = start

        // Copy 0 bytes; we're done
        if (end === start) return 0
        if (target.length === 0 || this.length === 0) return 0

        // Fatal error conditions
        if (targetStart < 0) {
          throw new RangeError('targetStart out of bounds')
        }
        if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
        if (end < 0) throw new RangeError('sourceEnd out of bounds')

        // Are we oob?
        if (end > this.length) end = this.length
        if (target.length - targetStart < end - start) {
          end = target.length - targetStart + start
        }

        var len = end - start

        if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
          // Use built-in when available, missing from IE11
          this.copyWithin(targetStart, start, end)
        } else if (this === target && start < targetStart && targetStart < end) {
          // descending copy from end
          for (var i = len - 1; i >= 0; --i) {
            target[i + targetStart] = this[i + start]
          }
        } else {
          Uint8Array.prototype.set.call(
            target,
            this.subarray(start, end),
            targetStart
          )
        }

        return len
      }

      // Usage:
      //    buffer.fill(number[, offset[, end]])
      //    buffer.fill(buffer[, offset[, end]])
      //    buffer.fill(string[, offset[, end]][, encoding])
      Buffer.prototype.fill = function fill(val, start, end, encoding) {
        // Handle string cases:
        if (typeof val === 'string') {
          if (typeof start === 'string') {
            encoding = start
            start = 0
            end = this.length
          } else if (typeof end === 'string') {
            encoding = end
            end = this.length
          }
          if (encoding !== undefined && typeof encoding !== 'string') {
            throw new TypeError('encoding must be a string')
          }
          if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
            throw new TypeError('Unknown encoding: ' + encoding)
          }
          if (val.length === 1) {
            var code = val.charCodeAt(0)
            if ((encoding === 'utf8' && code < 128) ||
              encoding === 'latin1') {
              // Fast path: If `val` fits into a single byte, use that numeric value.
              val = code
            }
          }
        } else if (typeof val === 'number') {
          val = val & 255
        }

        // Invalid ranges are not set to a default, so can range check early.
        if (start < 0 || this.length < start || this.length < end) {
          throw new RangeError('Out of range index')
        }

        if (end <= start) {
          return this
        }

        start = start >>> 0
        end = end === undefined ? this.length : end >>> 0

        if (!val) val = 0

        var i
        if (typeof val === 'number') {
          for (i = start; i < end; ++i) {
            this[i] = val
          }
        } else {
          var bytes = Buffer.isBuffer(val) ?
            val :
            Buffer.from(val, encoding)
          var len = bytes.length
          if (len === 0) {
            throw new TypeError('The value "' + val +
              '" is invalid for argument "value"')
          }
          for (i = 0; i < end - start; ++i) {
            this[i + start] = bytes[i % len]
          }
        }

        return this
      }

      // HELPER FUNCTIONS
      // ================

      var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g

      function base64clean(str) {
        // Node takes equal signs as end of the Base64 encoding
        str = str.split('=')[0]
        // Node strips out invalid characters like \n and \t from the string, base64-js does not
        str = str.trim().replace(INVALID_BASE64_RE, '')
        // Node converts strings with length < 2 to ''
        if (str.length < 2) return ''
        // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
        while (str.length % 4 !== 0) {
          str = str + '='
        }
        return str
      }

      function toHex(n) {
        if (n < 16) return '0' + n.toString(16)
        return n.toString(16)
      }

      function utf8ToBytes(string, units) {
        units = units || Infinity
        var codePoint
        var length = string.length
        var leadSurrogate = null
        var bytes = []

        for (var i = 0; i < length; ++i) {
          codePoint = string.charCodeAt(i)

          // is surrogate component
          if (codePoint > 0xD7FF && codePoint < 0xE000) {
            // last char was a lead
            if (!leadSurrogate) {
              // no lead yet
              if (codePoint > 0xDBFF) {
                // unexpected trail
                if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
                continue
              } else if (i + 1 === length) {
                // unpaired lead
                if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
                continue
              }

              // valid lead
              leadSurrogate = codePoint

              continue
            }

            // 2 leads in a row
            if (codePoint < 0xDC00) {
              if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
              leadSurrogate = codePoint
              continue
            }

            // valid surrogate pair
            codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
          } else if (leadSurrogate) {
            // valid bmp char, but last char was a lead
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          }

          leadSurrogate = null

          // encode utf8
          if (codePoint < 0x80) {
            if ((units -= 1) < 0) break
            bytes.push(codePoint)
          } else if (codePoint < 0x800) {
            if ((units -= 2) < 0) break
            bytes.push(
              codePoint >> 0x6 | 0xC0,
              codePoint & 0x3F | 0x80
            )
          } else if (codePoint < 0x10000) {
            if ((units -= 3) < 0) break
            bytes.push(
              codePoint >> 0xC | 0xE0,
              codePoint >> 0x6 & 0x3F | 0x80,
              codePoint & 0x3F | 0x80
            )
          } else if (codePoint < 0x110000) {
            if ((units -= 4) < 0) break
            bytes.push(
              codePoint >> 0x12 | 0xF0,
              codePoint >> 0xC & 0x3F | 0x80,
              codePoint >> 0x6 & 0x3F | 0x80,
              codePoint & 0x3F | 0x80
            )
          } else {
            throw new Error('Invalid code point')
          }
        }

        return bytes
      }

      function asciiToBytes(str) {
        var byteArray = []
        for (var i = 0; i < str.length; ++i) {
          // Node's code seems to be doing this and not & 0x7F..
          byteArray.push(str.charCodeAt(i) & 0xFF)
        }
        return byteArray
      }

      function utf16leToBytes(str, units) {
        var c, hi, lo
        var byteArray = []
        for (var i = 0; i < str.length; ++i) {
          if ((units -= 2) < 0) break

          c = str.charCodeAt(i)
          hi = c >> 8
          lo = c % 256
          byteArray.push(lo)
          byteArray.push(hi)
        }

        return byteArray
      }

      function base64ToBytes(str) {
        return base64.toByteArray(base64clean(str))
      }

      function blitBuffer(src, dst, offset, length) {
        for (var i = 0; i < length; ++i) {
          if ((i + offset >= dst.length) || (i >= src.length)) break
          dst[i + offset] = src[i]
        }
        return i
      }

      // ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
      // the `instanceof` check but they should be treated as of that type.
      // See: https://github.com/feross/buffer/issues/166
      function isInstance(obj, type) {
        return obj instanceof type ||
          (obj != null && obj.constructor != null && obj.constructor.name != null &&
            obj.constructor.name === type.name)
      }

      function numberIsNaN(obj) {
        // For IE11 support
        return obj !== obj // eslint-disable-line no-self-compare
      }

    }, {
      "base64-js": 10,
      "ieee754": 79
    }],
    13: [function (require, module, exports) {
      // Copyright Joyent, Inc. and other Node contributors.
      //
      // Permission is hereby granted, free of charge, to any person obtaining a
      // copy of this software and associated documentation files (the
      // "Software"), to deal in the Software without restriction, including
      // without limitation the rights to use, copy, modify, merge, publish,
      // distribute, sublicense, and/or sell copies of the Software, and to permit
      // persons to whom the Software is furnished to do so, subject to the
      // following conditions:
      //
      // The above copyright notice and this permission notice shall be included
      // in all copies or substantial portions of the Software.
      //
      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
      // USE OR OTHER DEALINGS IN THE SOFTWARE.

      var objectCreate = Object.create || objectCreatePolyfill
      var objectKeys = Object.keys || objectKeysPolyfill
      var bind = Function.prototype.bind || functionBindPolyfill

      function EventEmitter() {
        if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
          this._events = objectCreate(null);
          this._eventsCount = 0;
        }

        this._maxListeners = this._maxListeners || undefined;
      }
      module.exports = EventEmitter;

      // Backwards-compat with node 0.10.x
      EventEmitter.EventEmitter = EventEmitter;

      EventEmitter.prototype._events = undefined;
      EventEmitter.prototype._maxListeners = undefined;

      // By default EventEmitters will print a warning if more than 10 listeners are
      // added to it. This is a useful default which helps finding memory leaks.
      var defaultMaxListeners = 10;

      var hasDefineProperty;
      try {
        var o = {};
        if (Object.defineProperty) Object.defineProperty(o, 'x', {
          value: 0
        });
        hasDefineProperty = o.x === 0;
      } catch (err) {
        hasDefineProperty = false
      }
      if (hasDefineProperty) {
        Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
          enumerable: true,
          get: function () {
            return defaultMaxListeners;
          },
          set: function (arg) {
            // check whether the input is a positive number (whose value is zero or
            // greater and not a NaN).
            if (typeof arg !== 'number' || arg < 0 || arg !== arg)
              throw new TypeError('"defaultMaxListeners" must be a positive number');
            defaultMaxListeners = arg;
          }
        });
      } else {
        EventEmitter.defaultMaxListeners = defaultMaxListeners;
      }

      // Obviously not all Emitters should be limited to 10. This function allows
      // that to be increased. Set to zero for unlimited.
      EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
        if (typeof n !== 'number' || n < 0 || isNaN(n))
          throw new TypeError('"n" argument must be a positive number');
        this._maxListeners = n;
        return this;
      };

      function $getMaxListeners(that) {
        if (that._maxListeners === undefined)
          return EventEmitter.defaultMaxListeners;
        return that._maxListeners;
      }

      EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
        return $getMaxListeners(this);
      };

      // These standalone emit* functions are used to optimize calling of event
      // handlers for fast cases because emit() itself often has a variable number of
      // arguments and can be deoptimized because of that. These functions always have
      // the same number of arguments and thus do not get deoptimized, so the code
      // inside them can execute faster.
      function emitNone(handler, isFn, self) {
        if (isFn)
          handler.call(self);
        else {
          var len = handler.length;
          var listeners = arrayClone(handler, len);
          for (var i = 0; i < len; ++i)
            listeners[i].call(self);
        }
      }

      function emitOne(handler, isFn, self, arg1) {
        if (isFn)
          handler.call(self, arg1);
        else {
          var len = handler.length;
          var listeners = arrayClone(handler, len);
          for (var i = 0; i < len; ++i)
            listeners[i].call(self, arg1);
        }
      }

      function emitTwo(handler, isFn, self, arg1, arg2) {
        if (isFn)
          handler.call(self, arg1, arg2);
        else {
          var len = handler.length;
          var listeners = arrayClone(handler, len);
          for (var i = 0; i < len; ++i)
            listeners[i].call(self, arg1, arg2);
        }
      }

      function emitThree(handler, isFn, self, arg1, arg2, arg3) {
        if (isFn)
          handler.call(self, arg1, arg2, arg3);
        else {
          var len = handler.length;
          var listeners = arrayClone(handler, len);
          for (var i = 0; i < len; ++i)
            listeners[i].call(self, arg1, arg2, arg3);
        }
      }

      function emitMany(handler, isFn, self, args) {
        if (isFn)
          handler.apply(self, args);
        else {
          var len = handler.length;
          var listeners = arrayClone(handler, len);
          for (var i = 0; i < len; ++i)
            listeners[i].apply(self, args);
        }
      }

      EventEmitter.prototype.emit = function emit(type) {
        var er, handler, len, args, i, events;
        var doError = (type === 'error');

        events = this._events;
        if (events)
          doError = (doError && events.error == null);
        else if (!doError)
          return false;

        // If there is no 'error' event listener then throw.
        if (doError) {
          if (arguments.length > 1)
            er = arguments[1];
          if (er instanceof Error) {
            throw er; // Unhandled 'error' event
          } else {
            // At least give some kind of context to the user
            var err = new Error('Unhandled "error" event. (' + er + ')');
            err.context = er;
            throw err;
          }
          return false;
        }

        handler = events[type];

        if (!handler)
          return false;

        var isFn = typeof handler === 'function';
        len = arguments.length;
        switch (len) {
          // fast cases
          case 1:
            emitNone(handler, isFn, this);
            break;
          case 2:
            emitOne(handler, isFn, this, arguments[1]);
            break;
          case 3:
            emitTwo(handler, isFn, this, arguments[1], arguments[2]);
            break;
          case 4:
            emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
            break;
            // slower
          default:
            args = new Array(len - 1);
            for (i = 1; i < len; i++)
              args[i - 1] = arguments[i];
            emitMany(handler, isFn, this, args);
        }

        return true;
      };

      function _addListener(target, type, listener, prepend) {
        var m;
        var events;
        var existing;

        if (typeof listener !== 'function')
          throw new TypeError('"listener" argument must be a function');

        events = target._events;
        if (!events) {
          events = target._events = objectCreate(null);
          target._eventsCount = 0;
        } else {
          // To avoid recursion in the case that type === "newListener"! Before
          // adding it to the listeners, first emit "newListener".
          if (events.newListener) {
            target.emit('newListener', type,
              listener.listener ? listener.listener : listener);

            // Re-assign `events` because a newListener handler could have caused the
            // this._events to be assigned to a new object
            events = target._events;
          }
          existing = events[type];
        }

        if (!existing) {
          // Optimize the case of one listener. Don't need the extra array object.
          existing = events[type] = listener;
          ++target._eventsCount;
        } else {
          if (typeof existing === 'function') {
            // Adding the second element, need to change to array.
            existing = events[type] =
              prepend ? [listener, existing] : [existing, listener];
          } else {
            // If we've already got an array, just append.
            if (prepend) {
              existing.unshift(listener);
            } else {
              existing.push(listener);
            }
          }

          // Check for listener leak
          if (!existing.warned) {
            m = $getMaxListeners(target);
            if (m && m > 0 && existing.length > m) {
              existing.warned = true;
              var w = new Error('Possible EventEmitter memory leak detected. ' +
                existing.length + ' "' + String(type) + '" listeners ' +
                'added. Use emitter.setMaxListeners() to ' +
                'increase limit.');
              w.name = 'MaxListenersExceededWarning';
              w.emitter = target;
              w.type = type;
              w.count = existing.length;
              if (typeof console === 'object' && console.warn) {
                console.warn('%s: %s', w.name, w.message);
              }
            }
          }
        }

        return target;
      }

      EventEmitter.prototype.addListener = function addListener(type, listener) {
        return _addListener(this, type, listener, false);
      };

      EventEmitter.prototype.on = EventEmitter.prototype.addListener;

      EventEmitter.prototype.prependListener =
        function prependListener(type, listener) {
          return _addListener(this, type, listener, true);
        };

      function onceWrapper() {
        if (!this.fired) {
          this.target.removeListener(this.type, this.wrapFn);
          this.fired = true;
          switch (arguments.length) {
            case 0:
              return this.listener.call(this.target);
            case 1:
              return this.listener.call(this.target, arguments[0]);
            case 2:
              return this.listener.call(this.target, arguments[0], arguments[1]);
            case 3:
              return this.listener.call(this.target, arguments[0], arguments[1],
                arguments[2]);
            default:
              var args = new Array(arguments.length);
              for (var i = 0; i < args.length; ++i)
                args[i] = arguments[i];
              this.listener.apply(this.target, args);
          }
        }
      }

      function _onceWrap(target, type, listener) {
        var state = {
          fired: false,
          wrapFn: undefined,
          target: target,
          type: type,
          listener: listener
        };
        var wrapped = bind.call(onceWrapper, state);
        wrapped.listener = listener;
        state.wrapFn = wrapped;
        return wrapped;
      }

      EventEmitter.prototype.once = function once(type, listener) {
        if (typeof listener !== 'function')
          throw new TypeError('"listener" argument must be a function');
        this.on(type, _onceWrap(this, type, listener));
        return this;
      };

      EventEmitter.prototype.prependOnceListener =
        function prependOnceListener(type, listener) {
          if (typeof listener !== 'function')
            throw new TypeError('"listener" argument must be a function');
          this.prependListener(type, _onceWrap(this, type, listener));
          return this;
        };

      // Emits a 'removeListener' event if and only if the listener was removed.
      EventEmitter.prototype.removeListener =
        function removeListener(type, listener) {
          var list, events, position, i, originalListener;

          if (typeof listener !== 'function')
            throw new TypeError('"listener" argument must be a function');

          events = this._events;
          if (!events)
            return this;

          list = events[type];
          if (!list)
            return this;

          if (list === listener || list.listener === listener) {
            if (--this._eventsCount === 0)
              this._events = objectCreate(null);
            else {
              delete events[type];
              if (events.removeListener)
                this.emit('removeListener', type, list.listener || listener);
            }
          } else if (typeof list !== 'function') {
            position = -1;

            for (i = list.length - 1; i >= 0; i--) {
              if (list[i] === listener || list[i].listener === listener) {
                originalListener = list[i].listener;
                position = i;
                break;
              }
            }

            if (position < 0)
              return this;

            if (position === 0)
              list.shift();
            else
              spliceOne(list, position);

            if (list.length === 1)
              events[type] = list[0];

            if (events.removeListener)
              this.emit('removeListener', type, originalListener || listener);
          }

          return this;
        };

      EventEmitter.prototype.removeAllListeners =
        function removeAllListeners(type) {
          var listeners, events, i;

          events = this._events;
          if (!events)
            return this;

          // not listening for removeListener, no need to emit
          if (!events.removeListener) {
            if (arguments.length === 0) {
              this._events = objectCreate(null);
              this._eventsCount = 0;
            } else if (events[type]) {
              if (--this._eventsCount === 0)
                this._events = objectCreate(null);
              else
                delete events[type];
            }
            return this;
          }

          // emit removeListener for all listeners on all events
          if (arguments.length === 0) {
            var keys = objectKeys(events);
            var key;
            for (i = 0; i < keys.length; ++i) {
              key = keys[i];
              if (key === 'removeListener') continue;
              this.removeAllListeners(key);
            }
            this.removeAllListeners('removeListener');
            this._events = objectCreate(null);
            this._eventsCount = 0;
            return this;
          }

          listeners = events[type];

          if (typeof listeners === 'function') {
            this.removeListener(type, listeners);
          } else if (listeners) {
            // LIFO order
            for (i = listeners.length - 1; i >= 0; i--) {
              this.removeListener(type, listeners[i]);
            }
          }

          return this;
        };

      function _listeners(target, type, unwrap) {
        var events = target._events;

        if (!events)
          return [];

        var evlistener = events[type];
        if (!evlistener)
          return [];

        if (typeof evlistener === 'function')
          return unwrap ? [evlistener.listener || evlistener] : [evlistener];

        return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
      }

      EventEmitter.prototype.listeners = function listeners(type) {
        return _listeners(this, type, true);
      };

      EventEmitter.prototype.rawListeners = function rawListeners(type) {
        return _listeners(this, type, false);
      };

      EventEmitter.listenerCount = function (emitter, type) {
        if (typeof emitter.listenerCount === 'function') {
          return emitter.listenerCount(type);
        } else {
          return listenerCount.call(emitter, type);
        }
      };

      EventEmitter.prototype.listenerCount = listenerCount;

      function listenerCount(type) {
        var events = this._events;

        if (events) {
          var evlistener = events[type];

          if (typeof evlistener === 'function') {
            return 1;
          } else if (evlistener) {
            return evlistener.length;
          }
        }

        return 0;
      }

      EventEmitter.prototype.eventNames = function eventNames() {
        return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
      };

      // About 1.5x faster than the two-arg version of Array#splice().
      function spliceOne(list, index) {
        for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
          list[i] = list[k];
        list.pop();
      }

      function arrayClone(arr, n) {
        var copy = new Array(n);
        for (var i = 0; i < n; ++i)
          copy[i] = arr[i];
        return copy;
      }

      function unwrapListeners(arr) {
        var ret = new Array(arr.length);
        for (var i = 0; i < ret.length; ++i) {
          ret[i] = arr[i].listener || arr[i];
        }
        return ret;
      }

      function objectCreatePolyfill(proto) {
        var F = function () {};
        F.prototype = proto;
        return new F;
      }

      function objectKeysPolyfill(obj) {
        var keys = [];
        for (var k in obj)
          if (Object.prototype.hasOwnProperty.call(obj, k)) {
            keys.push(k);
          }
        return k;
      }

      function functionBindPolyfill(context) {
        var fn = this;
        return function () {
          return fn.apply(context, arguments);
        };
      }

    }, {}],
    14: [function (require, module, exports) {
      (function (Buffer) {
        // 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.

        // NOTE: These type checking functions intentionally don't use `instanceof`
        // because it is fragile and can be easily faked with `Object.create()`.

        function isArray(arg) {
          if (Array.isArray) {
            return Array.isArray(arg);
          }
          return objectToString(arg) === '[object Array]';
        }
        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 objectToString(re) === '[object RegExp]';
        }
        exports.isRegExp = isRegExp;

        function isObject(arg) {
          return typeof arg === 'object' && arg !== null;
        }
        exports.isObject = isObject;

        function isDate(d) {
          return objectToString(d) === '[object Date]';
        }
        exports.isDate = isDate;

        function isError(e) {
          return (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 = Buffer.isBuffer;

        function objectToString(o) {
          return Object.prototype.toString.call(o);
        }

      }).call(this, {
        "isBuffer": require("../../is-buffer/index.js")
      })
    }, {
      "../../is-buffer/index.js": 81
    }],
    15: [function (require, module, exports) {
      'use strict';

      var copy = require('es5-ext/object/copy'),
        normalizeOptions = require('es5-ext/object/normalize-options'),
        ensureCallable = require('es5-ext/object/valid-callable'),
        map = require('es5-ext/object/map'),
        callable = require('es5-ext/object/valid-callable'),
        validValue = require('es5-ext/object/valid-value')

        ,
        bind = Function.prototype.bind,
        defineProperty = Object.defineProperty,
        hasOwnProperty = Object.prototype.hasOwnProperty,
        define;

      define = function (name, desc, options) {
        var value = validValue(desc) && callable(desc.value),
          dgs;
        dgs = copy(desc);
        delete dgs.writable;
        delete dgs.value;
        dgs.get = function () {
          if (!options.overwriteDefinition && hasOwnProperty.call(this, name)) return value;
          desc.value = bind.call(value, options.resolveContext ? options.resolveContext(this) : this);
          defineProperty(this, name, desc);
          return this[name];
        };
        return dgs;
      };

      module.exports = function (props /*, options*/ ) {
        var options = normalizeOptions(arguments[1]);
        if (options.resolveContext != null) ensureCallable(options.resolveContext);
        return map(props, function (desc, name) {
          return define(name, desc, options);
        });
      };

    }, {
      "es5-ext/object/copy": 39,
      "es5-ext/object/map": 48,
      "es5-ext/object/normalize-options": 49,
      "es5-ext/object/valid-callable": 54,
      "es5-ext/object/valid-value": 55
    }],
    16: [function (require, module, exports) {
      'use strict';

      var assign = require('es5-ext/object/assign'),
        normalizeOpts = require('es5-ext/object/normalize-options'),
        isCallable = require('es5-ext/object/is-callable'),
        contains = require('es5-ext/string/#/contains')

        ,
        d;

      d = module.exports = function (dscr, value /*, options*/ ) {
        var c, e, w, options, desc;
        if ((arguments.length < 2) || (typeof dscr !== 'string')) {
          options = value;
          value = dscr;
          dscr = null;
        } else {
          options = arguments[2];
        }
        if (dscr == null) {
          c = w = true;
          e = false;
        } else {
          c = contains.call(dscr, 'c');
          e = contains.call(dscr, 'e');
          w = contains.call(dscr, 'w');
        }

        desc = {
          value: value,
          configurable: c,
          enumerable: e,
          writable: w
        };
        return !options ? desc : assign(normalizeOpts(options), desc);
      };
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值