arnaucube
arnaucube/raspberryGPIOhtmlserverPublic Self-hosted repository
raspberryGPIOhtmlserver/node_modules/engine.io-client/engine.io.js
node_modules/engine.io-client/engine.io.jsRaw
   1!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.eio=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
   2
   3module.exports =  _dereq_('./lib/');
   4
   5},{"./lib/":2}],2:[function(_dereq_,module,exports){
   6
   7module.exports = _dereq_('./socket');
   8
   9/**
  10 * Exports parser
  11 *
  12 * @api public
  13 *
  14 */
  15module.exports.parser = _dereq_('engine.io-parser');
  16
  17},{"./socket":3,"engine.io-parser":15}],3:[function(_dereq_,module,exports){
  18(function (global){
  19/**
  20 * Module dependencies.
  21 */
  22
  23var transports = _dereq_('./transports');
  24var Emitter = _dereq_('component-emitter');
  25var debug = _dereq_('debug')('engine.io-client:socket');
  26var index = _dereq_('indexof');
  27var parser = _dereq_('engine.io-parser');
  28var parseuri = _dereq_('parseuri');
  29var parsejson = _dereq_('parsejson');
  30var parseqs = _dereq_('parseqs');
  31
  32/**
  33 * Module exports.
  34 */
  35
  36module.exports = Socket;
  37
  38/**
  39 * Noop function.
  40 *
  41 * @api private
  42 */
  43
  44function noop(){}
  45
  46/**
  47 * Socket constructor.
  48 *
  49 * @param {String|Object} uri or options
  50 * @param {Object} options
  51 * @api public
  52 */
  53
  54function Socket(uri, opts){
  55  if (!(this instanceof Socket)) return new Socket(uri, opts);
  56
  57  opts = opts || {};
  58
  59  if (uri && 'object' == typeof uri) {
  60    opts = uri;
  61    uri = null;
  62  }
  63
  64  if (uri) {
  65    uri = parseuri(uri);
  66    opts.host = uri.host;
  67    opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
  68    opts.port = uri.port;
  69    if (uri.query) opts.query = uri.query;
  70  }
  71
  72  this.secure = null != opts.secure ? opts.secure :
  73    (global.location && 'https:' == location.protocol);
  74
  75  if (opts.host) {
  76    var pieces = opts.host.split(':');
  77    opts.hostname = pieces.shift();
  78    if (pieces.length) opts.port = pieces.pop();
  79  }
  80
  81  this.agent = opts.agent || false;
  82  this.hostname = opts.hostname ||
  83    (global.location ? location.hostname : 'localhost');
  84  this.port = opts.port || (global.location && location.port ?
  85       location.port :
  86       (this.secure ? 443 : 80));
  87  this.query = opts.query || {};
  88  if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
  89  this.upgrade = false !== opts.upgrade;
  90  this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
  91  this.forceJSONP = !!opts.forceJSONP;
  92  this.jsonp = false !== opts.jsonp;
  93  this.forceBase64 = !!opts.forceBase64;
  94  this.enablesXDR = !!opts.enablesXDR;
  95  this.timestampParam = opts.timestampParam || 't';
  96  this.timestampRequests = opts.timestampRequests;
  97  this.transports = opts.transports || ['polling', 'websocket'];
  98  this.readyState = '';
  99  this.writeBuffer = [];
 100  this.callbackBuffer = [];
 101  this.policyPort = opts.policyPort || 843;
 102  this.rememberUpgrade = opts.rememberUpgrade || false;
 103  this.open();
 104  this.binaryType = null;
 105  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
 106}
 107
 108Socket.priorWebsocketSuccess = false;
 109
 110/**
 111 * Mix in `Emitter`.
 112 */
 113
 114Emitter(Socket.prototype);
 115
 116/**
 117 * Protocol version.
 118 *
 119 * @api public
 120 */
 121
 122Socket.protocol = parser.protocol; // this is an int
 123
 124/**
 125 * Expose deps for legacy compatibility
 126 * and standalone browser access.
 127 */
 128
 129Socket.Socket = Socket;
 130Socket.Transport = _dereq_('./transport');
 131Socket.transports = _dereq_('./transports');
 132Socket.parser = _dereq_('engine.io-parser');
 133
 134/**
 135 * Creates transport of the given type.
 136 *
 137 * @param {String} transport name
 138 * @return {Transport}
 139 * @api private
 140 */
 141
 142Socket.prototype.createTransport = function (name) {
 143  debug('creating transport "%s"', name);
 144  var query = clone(this.query);
 145
 146  // append engine.io protocol identifier
 147  query.EIO = parser.protocol;
 148
 149  // transport name
 150  query.transport = name;
 151
 152  // session id if we already have one
 153  if (this.id) query.sid = this.id;
 154
 155  var transport = new transports[name]({
 156    agent: this.agent,
 157    hostname: this.hostname,
 158    port: this.port,
 159    secure: this.secure,
 160    path: this.path,
 161    query: query,
 162    forceJSONP: this.forceJSONP,
 163    jsonp: this.jsonp,
 164    forceBase64: this.forceBase64,
 165    enablesXDR: this.enablesXDR,
 166    timestampRequests: this.timestampRequests,
 167    timestampParam: this.timestampParam,
 168    policyPort: this.policyPort,
 169    socket: this
 170  });
 171
 172  return transport;
 173};
 174
 175function clone (obj) {
 176  var o = {};
 177  for (var i in obj) {
 178    if (obj.hasOwnProperty(i)) {
 179      o[i] = obj[i];
 180    }
 181  }
 182  return o;
 183}
 184
 185/**
 186 * Initializes transport to use and starts probe.
 187 *
 188 * @api private
 189 */
 190Socket.prototype.open = function () {
 191  var transport;
 192  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
 193    transport = 'websocket';
 194  } else if (0 == this.transports.length) {
 195    // Emit error on next tick so it can be listened to
 196    var self = this;
 197    setTimeout(function() {
 198      self.emit('error', 'No transports available');
 199    }, 0);
 200    return;
 201  } else {
 202    transport = this.transports[0];
 203  }
 204  this.readyState = 'opening';
 205
 206  // Retry with the next transport if the transport is disabled (jsonp: false)
 207  var transport;
 208  try {
 209    transport = this.createTransport(transport);
 210  } catch (e) {
 211    this.transports.shift();
 212    this.open();
 213    return;
 214  }
 215
 216  transport.open();
 217  this.setTransport(transport);
 218};
 219
 220/**
 221 * Sets the current transport. Disables the existing one (if any).
 222 *
 223 * @api private
 224 */
 225
 226Socket.prototype.setTransport = function(transport){
 227  debug('setting transport %s', transport.name);
 228  var self = this;
 229
 230  if (this.transport) {
 231    debug('clearing existing transport %s', this.transport.name);
 232    this.transport.removeAllListeners();
 233  }
 234
 235  // set up transport
 236  this.transport = transport;
 237
 238  // set up transport listeners
 239  transport
 240  .on('drain', function(){
 241    self.onDrain();
 242  })
 243  .on('packet', function(packet){
 244    self.onPacket(packet);
 245  })
 246  .on('error', function(e){
 247    self.onError(e);
 248  })
 249  .on('close', function(){
 250    self.onClose('transport close');
 251  });
 252};
 253
 254/**
 255 * Probes a transport.
 256 *
 257 * @param {String} transport name
 258 * @api private
 259 */
 260
 261Socket.prototype.probe = function (name) {
 262  debug('probing transport "%s"', name);
 263  var transport = this.createTransport(name, { probe: 1 })
 264    , failed = false
 265    , self = this;
 266
 267  Socket.priorWebsocketSuccess = false;
 268
 269  function onTransportOpen(){
 270    if (self.onlyBinaryUpgrades) {
 271      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
 272      failed = failed || upgradeLosesBinary;
 273    }
 274    if (failed) return;
 275
 276    debug('probe transport "%s" opened', name);
 277    transport.send([{ type: 'ping', data: 'probe' }]);
 278    transport.once('packet', function (msg) {
 279      if (failed) return;
 280      if ('pong' == msg.type && 'probe' == msg.data) {
 281        debug('probe transport "%s" pong', name);
 282        self.upgrading = true;
 283        self.emit('upgrading', transport);
 284        if (!transport) return;
 285        Socket.priorWebsocketSuccess = 'websocket' == transport.name;
 286
 287        debug('pausing current transport "%s"', self.transport.name);
 288        self.transport.pause(function () {
 289          if (failed) return;
 290          if ('closed' == self.readyState) return;
 291          debug('changing transport and sending upgrade packet');
 292
 293          cleanup();
 294
 295          self.setTransport(transport);
 296          transport.send([{ type: 'upgrade' }]);
 297          self.emit('upgrade', transport);
 298          transport = null;
 299          self.upgrading = false;
 300          self.flush();
 301        });
 302      } else {
 303        debug('probe transport "%s" failed', name);
 304        var err = new Error('probe error');
 305        err.transport = transport.name;
 306        self.emit('upgradeError', err);
 307      }
 308    });
 309  }
 310
 311  function freezeTransport() {
 312    if (failed) return;
 313
 314    // Any callback called by transport should be ignored since now
 315    failed = true;
 316
 317    cleanup();
 318
 319    transport.close();
 320    transport = null;
 321  }
 322
 323  //Handle any error that happens while probing
 324  function onerror(err) {
 325    var error = new Error('probe error: ' + err);
 326    error.transport = transport.name;
 327
 328    freezeTransport();
 329
 330    debug('probe transport "%s" failed because of error: %s', name, err);
 331
 332    self.emit('upgradeError', error);
 333  }
 334
 335  function onTransportClose(){
 336    onerror("transport closed");
 337  }
 338
 339  //When the socket is closed while we're probing
 340  function onclose(){
 341    onerror("socket closed");
 342  }
 343
 344  //When the socket is upgraded while we're probing
 345  function onupgrade(to){
 346    if (transport && to.name != transport.name) {
 347      debug('"%s" works - aborting "%s"', to.name, transport.name);
 348      freezeTransport();
 349    }
 350  }
 351
 352  //Remove all listeners on the transport and on self
 353  function cleanup(){
 354    transport.removeListener('open', onTransportOpen);
 355    transport.removeListener('error', onerror);
 356    transport.removeListener('close', onTransportClose);
 357    self.removeListener('close', onclose);
 358    self.removeListener('upgrading', onupgrade);
 359  }
 360
 361  transport.once('open', onTransportOpen);
 362  transport.once('error', onerror);
 363  transport.once('close', onTransportClose);
 364
 365  this.once('close', onclose);
 366  this.once('upgrading', onupgrade);
 367
 368  transport.open();
 369
 370};
 371
 372/**
 373 * Called when connection is deemed open.
 374 *
 375 * @api public
 376 */
 377
 378Socket.prototype.onOpen = function () {
 379  debug('socket open');
 380  this.readyState = 'open';
 381  Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
 382  this.emit('open');
 383  this.flush();
 384
 385  // we check for `readyState` in case an `open`
 386  // listener already closed the socket
 387  if ('open' == this.readyState && this.upgrade && this.transport.pause) {
 388    debug('starting upgrade probes');
 389    for (var i = 0, l = this.upgrades.length; i < l; i++) {
 390      this.probe(this.upgrades[i]);
 391    }
 392  }
 393};
 394
 395/**
 396 * Handles a packet.
 397 *
 398 * @api private
 399 */
 400
 401Socket.prototype.onPacket = function (packet) {
 402  if ('opening' == this.readyState || 'open' == this.readyState) {
 403    debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
 404
 405    this.emit('packet', packet);
 406
 407    // Socket is live - any packet counts
 408    this.emit('heartbeat');
 409
 410    switch (packet.type) {
 411      case 'open':
 412        this.onHandshake(parsejson(packet.data));
 413        break;
 414
 415      case 'pong':
 416        this.setPing();
 417        break;
 418
 419      case 'error':
 420        var err = new Error('server error');
 421        err.code = packet.data;
 422        this.emit('error', err);
 423        break;
 424
 425      case 'message':
 426        this.emit('data', packet.data);
 427        this.emit('message', packet.data);
 428        break;
 429    }
 430  } else {
 431    debug('packet received with socket readyState "%s"', this.readyState);
 432  }
 433};
 434
 435/**
 436 * Called upon handshake completion.
 437 *
 438 * @param {Object} handshake obj
 439 * @api private
 440 */
 441
 442Socket.prototype.onHandshake = function (data) {
 443  this.emit('handshake', data);
 444  this.id = data.sid;
 445  this.transport.query.sid = data.sid;
 446  this.upgrades = this.filterUpgrades(data.upgrades);
 447  this.pingInterval = data.pingInterval;
 448  this.pingTimeout = data.pingTimeout;
 449  this.onOpen();
 450  // In case open handler closes socket
 451  if  ('closed' == this.readyState) return;
 452  this.setPing();
 453
 454  // Prolong liveness of socket on heartbeat
 455  this.removeListener('heartbeat', this.onHeartbeat);
 456  this.on('heartbeat', this.onHeartbeat);
 457};
 458
 459/**
 460 * Resets ping timeout.
 461 *
 462 * @api private
 463 */
 464
 465Socket.prototype.onHeartbeat = function (timeout) {
 466  clearTimeout(this.pingTimeoutTimer);
 467  var self = this;
 468  self.pingTimeoutTimer = setTimeout(function () {
 469    if ('closed' == self.readyState) return;
 470    self.onClose('ping timeout');
 471  }, timeout || (self.pingInterval + self.pingTimeout));
 472};
 473
 474/**
 475 * Pings server every `this.pingInterval` and expects response
 476 * within `this.pingTimeout` or closes connection.
 477 *
 478 * @api private
 479 */
 480
 481Socket.prototype.setPing = function () {
 482  var self = this;
 483  clearTimeout(self.pingIntervalTimer);
 484  self.pingIntervalTimer = setTimeout(function () {
 485    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
 486    self.ping();
 487    self.onHeartbeat(self.pingTimeout);
 488  }, self.pingInterval);
 489};
 490
 491/**
 492* Sends a ping packet.
 493*
 494* @api public
 495*/
 496
 497Socket.prototype.ping = function () {
 498  this.sendPacket('ping');
 499};
 500
 501/**
 502 * Called on `drain` event
 503 *
 504 * @api private
 505 */
 506
 507Socket.prototype.onDrain = function() {
 508  for (var i = 0; i < this.prevBufferLen; i++) {
 509    if (this.callbackBuffer[i]) {
 510      this.callbackBuffer[i]();
 511    }
 512  }
 513
 514  this.writeBuffer.splice(0, this.prevBufferLen);
 515  this.callbackBuffer.splice(0, this.prevBufferLen);
 516
 517  // setting prevBufferLen = 0 is very important
 518  // for example, when upgrading, upgrade packet is sent over,
 519  // and a nonzero prevBufferLen could cause problems on `drain`
 520  this.prevBufferLen = 0;
 521
 522  if (this.writeBuffer.length == 0) {
 523    this.emit('drain');
 524  } else {
 525    this.flush();
 526  }
 527};
 528
 529/**
 530 * Flush write buffers.
 531 *
 532 * @api private
 533 */
 534
 535Socket.prototype.flush = function () {
 536  if ('closed' != this.readyState && this.transport.writable &&
 537    !this.upgrading && this.writeBuffer.length) {
 538    debug('flushing %d packets in socket', this.writeBuffer.length);
 539    this.transport.send(this.writeBuffer);
 540    // keep track of current length of writeBuffer
 541    // splice writeBuffer and callbackBuffer on `drain`
 542    this.prevBufferLen = this.writeBuffer.length;
 543    this.emit('flush');
 544  }
 545};
 546
 547/**
 548 * Sends a message.
 549 *
 550 * @param {String} message.
 551 * @param {Function} callback function.
 552 * @return {Socket} for chaining.
 553 * @api public
 554 */
 555
 556Socket.prototype.write =
 557Socket.prototype.send = function (msg, fn) {
 558  this.sendPacket('message', msg, fn);
 559  return this;
 560};
 561
 562/**
 563 * Sends a packet.
 564 *
 565 * @param {String} packet type.
 566 * @param {String} data.
 567 * @param {Function} callback function.
 568 * @api private
 569 */
 570
 571Socket.prototype.sendPacket = function (type, data, fn) {
 572  if ('closing' == this.readyState || 'closed' == this.readyState) {
 573    return;
 574  }
 575
 576  var packet = { type: type, data: data };
 577  this.emit('packetCreate', packet);
 578  this.writeBuffer.push(packet);
 579  this.callbackBuffer.push(fn);
 580  this.flush();
 581};
 582
 583/**
 584 * Closes the connection.
 585 *
 586 * @api private
 587 */
 588
 589Socket.prototype.close = function () {
 590  if ('opening' == this.readyState || 'open' == this.readyState) {
 591    this.readyState = 'closing';
 592
 593    var self = this;
 594
 595    function close() {
 596      self.onClose('forced close');
 597      debug('socket closing - telling transport to close');
 598      self.transport.close();
 599    }
 600
 601    function cleanupAndClose() {
 602      self.removeListener('upgrade', cleanupAndClose);
 603      self.removeListener('upgradeError', cleanupAndClose);
 604      close();
 605    }
 606
 607    function waitForUpgrade() {
 608      // wait for upgrade to finish since we can't send packets while pausing a transport
 609      self.once('upgrade', cleanupAndClose);
 610      self.once('upgradeError', cleanupAndClose);
 611    }
 612
 613    if (this.writeBuffer.length) {
 614      this.once('drain', function() {
 615        if (this.upgrading) {
 616          waitForUpgrade();
 617        } else {
 618          close();
 619        }
 620      });
 621    } else if (this.upgrading) {
 622      waitForUpgrade();
 623    } else {
 624      close();
 625    }
 626  }
 627
 628  return this;
 629};
 630
 631/**
 632 * Called upon transport error
 633 *
 634 * @api private
 635 */
 636
 637Socket.prototype.onError = function (err) {
 638  debug('socket error %j', err);
 639  Socket.priorWebsocketSuccess = false;
 640  this.emit('error', err);
 641  this.onClose('transport error', err);
 642};
 643
 644/**
 645 * Called upon transport close.
 646 *
 647 * @api private
 648 */
 649
 650Socket.prototype.onClose = function (reason, desc) {
 651  if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
 652    debug('socket close with reason: "%s"', reason);
 653    var self = this;
 654
 655    // clear timers
 656    clearTimeout(this.pingIntervalTimer);
 657    clearTimeout(this.pingTimeoutTimer);
 658
 659    // clean buffers in next tick, so developers can still
 660    // grab the buffers on `close` event
 661    setTimeout(function() {
 662      self.writeBuffer = [];
 663      self.callbackBuffer = [];
 664      self.prevBufferLen = 0;
 665    }, 0);
 666
 667    // stop event from firing again for transport
 668    this.transport.removeAllListeners('close');
 669
 670    // ensure transport won't stay open
 671    this.transport.close();
 672
 673    // ignore further transport communication
 674    this.transport.removeAllListeners();
 675
 676    // set ready state
 677    this.readyState = 'closed';
 678
 679    // clear session id
 680    this.id = null;
 681
 682    // emit close event
 683    this.emit('close', reason, desc);
 684  }
 685};
 686
 687/**
 688 * Filters upgrades, returning only those matching client transports.
 689 *
 690 * @param {Array} server upgrades
 691 * @api private
 692 *
 693 */
 694
 695Socket.prototype.filterUpgrades = function (upgrades) {
 696  var filteredUpgrades = [];
 697  for (var i = 0, j = upgrades.length; i<j; i++) {
 698    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
 699  }
 700  return filteredUpgrades;
 701};
 702
 703}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 704},{"./transport":4,"./transports":5,"component-emitter":12,"debug":14,"engine.io-parser":15,"indexof":23,"parsejson":24,"parseqs":25,"parseuri":26}],4:[function(_dereq_,module,exports){
 705/**
 706 * Module dependencies.
 707 */
 708
 709var parser = _dereq_('engine.io-parser');
 710var Emitter = _dereq_('component-emitter');
 711
 712/**
 713 * Module exports.
 714 */
 715
 716module.exports = Transport;
 717
 718/**
 719 * Transport abstract constructor.
 720 *
 721 * @param {Object} options.
 722 * @api private
 723 */
 724
 725function Transport (opts) {
 726  this.path = opts.path;
 727  this.hostname = opts.hostname;
 728  this.port = opts.port;
 729  this.secure = opts.secure;
 730  this.query = opts.query;
 731  this.timestampParam = opts.timestampParam;
 732  this.timestampRequests = opts.timestampRequests;
 733  this.readyState = '';
 734  this.agent = opts.agent || false;
 735  this.socket = opts.socket;
 736  this.enablesXDR = opts.enablesXDR;
 737}
 738
 739/**
 740 * Mix in `Emitter`.
 741 */
 742
 743Emitter(Transport.prototype);
 744
 745/**
 746 * A counter used to prevent collisions in the timestamps used
 747 * for cache busting.
 748 */
 749
 750Transport.timestamps = 0;
 751
 752/**
 753 * Emits an error.
 754 *
 755 * @param {String} str
 756 * @return {Transport} for chaining
 757 * @api public
 758 */
 759
 760Transport.prototype.onError = function (msg, desc) {
 761  var err = new Error(msg);
 762  err.type = 'TransportError';
 763  err.description = desc;
 764  this.emit('error', err);
 765  return this;
 766};
 767
 768/**
 769 * Opens the transport.
 770 *
 771 * @api public
 772 */
 773
 774Transport.prototype.open = function () {
 775  if ('closed' == this.readyState || '' == this.readyState) {
 776    this.readyState = 'opening';
 777    this.doOpen();
 778  }
 779
 780  return this;
 781};
 782
 783/**
 784 * Closes the transport.
 785 *
 786 * @api private
 787 */
 788
 789Transport.prototype.close = function () {
 790  if ('opening' == this.readyState || 'open' == this.readyState) {
 791    this.doClose();
 792    this.onClose();
 793  }
 794
 795  return this;
 796};
 797
 798/**
 799 * Sends multiple packets.
 800 *
 801 * @param {Array} packets
 802 * @api private
 803 */
 804
 805Transport.prototype.send = function(packets){
 806  if ('open' == this.readyState) {
 807    this.write(packets);
 808  } else {
 809    throw new Error('Transport not open');
 810  }
 811};
 812
 813/**
 814 * Called upon open
 815 *
 816 * @api private
 817 */
 818
 819Transport.prototype.onOpen = function () {
 820  this.readyState = 'open';
 821  this.writable = true;
 822  this.emit('open');
 823};
 824
 825/**
 826 * Called with data.
 827 *
 828 * @param {String} data
 829 * @api private
 830 */
 831
 832Transport.prototype.onData = function(data){
 833  var packet = parser.decodePacket(data, this.socket.binaryType);
 834  this.onPacket(packet);
 835};
 836
 837/**
 838 * Called with a decoded packet.
 839 */
 840
 841Transport.prototype.onPacket = function (packet) {
 842  this.emit('packet', packet);
 843};
 844
 845/**
 846 * Called upon close.
 847 *
 848 * @api private
 849 */
 850
 851Transport.prototype.onClose = function () {
 852  this.readyState = 'closed';
 853  this.emit('close');
 854};
 855
 856},{"component-emitter":12,"engine.io-parser":15}],5:[function(_dereq_,module,exports){
 857(function (global){
 858/**
 859 * Module dependencies
 860 */
 861
 862var XMLHttpRequest = _dereq_('xmlhttprequest');
 863var XHR = _dereq_('./polling-xhr');
 864var JSONP = _dereq_('./polling-jsonp');
 865var websocket = _dereq_('./websocket');
 866
 867/**
 868 * Export transports.
 869 */
 870
 871exports.polling = polling;
 872exports.websocket = websocket;
 873
 874/**
 875 * Polling transport polymorphic constructor.
 876 * Decides on xhr vs jsonp based on feature detection.
 877 *
 878 * @api private
 879 */
 880
 881function polling(opts){
 882  var xhr;
 883  var xd = false;
 884  var xs = false;
 885  var jsonp = false !== opts.jsonp;
 886
 887  if (global.location) {
 888    var isSSL = 'https:' == location.protocol;
 889    var port = location.port;
 890
 891    // some user agents have empty `location.port`
 892    if (!port) {
 893      port = isSSL ? 443 : 80;
 894    }
 895
 896    xd = opts.hostname != location.hostname || port != opts.port;
 897    xs = opts.secure != isSSL;
 898  }
 899
 900  opts.xdomain = xd;
 901  opts.xscheme = xs;
 902  xhr = new XMLHttpRequest(opts);
 903
 904  if ('open' in xhr && !opts.forceJSONP) {
 905    return new XHR(opts);
 906  } else {
 907    if (!jsonp) throw new Error('JSONP disabled');
 908    return new JSONP(opts);
 909  }
 910}
 911
 912}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 913},{"./polling-jsonp":6,"./polling-xhr":7,"./websocket":9,"xmlhttprequest":10}],6:[function(_dereq_,module,exports){
 914(function (global){
 915
 916/**
 917 * Module requirements.
 918 */
 919
 920var Polling = _dereq_('./polling');
 921var inherit = _dereq_('component-inherit');
 922
 923/**
 924 * Module exports.
 925 */
 926
 927module.exports = JSONPPolling;
 928
 929/**
 930 * Cached regular expressions.
 931 */
 932
 933var rNewline = /\n/g;
 934var rEscapedNewline = /\\n/g;
 935
 936/**
 937 * Global JSONP callbacks.
 938 */
 939
 940var callbacks;
 941
 942/**
 943 * Callbacks count.
 944 */
 945
 946var index = 0;
 947
 948/**
 949 * Noop.
 950 */
 951
 952function empty () { }
 953
 954/**
 955 * JSONP Polling constructor.
 956 *
 957 * @param {Object} opts.
 958 * @api public
 959 */
 960
 961function JSONPPolling (opts) {
 962  Polling.call(this, opts);
 963
 964  this.query = this.query || {};
 965
 966  // define global callbacks array if not present
 967  // we do this here (lazily) to avoid unneeded global pollution
 968  if (!callbacks) {
 969    // we need to consider multiple engines in the same page
 970    if (!global.___eio) global.___eio = [];
 971    callbacks = global.___eio;
 972  }
 973
 974  // callback identifier
 975  this.index = callbacks.length;
 976
 977  // add callback to jsonp global
 978  var self = this;
 979  callbacks.push(function (msg) {
 980    self.onData(msg);
 981  });
 982
 983  // append to query string
 984  this.query.j = this.index;
 985
 986  // prevent spurious errors from being emitted when the window is unloaded
 987  if (global.document && global.addEventListener) {
 988    global.addEventListener('beforeunload', function () {
 989      if (self.script) self.script.onerror = empty;
 990    });
 991  }
 992}
 993
 994/**
 995 * Inherits from Polling.
 996 */
 997
 998inherit(JSONPPolling, Polling);
 999
1000/*
1001 * JSONP only supports binary as base64 encoded strings
1002 */
1003
1004JSONPPolling.prototype.supportsBinary = false;
1005
1006/**
1007 * Closes the socket.
1008 *
1009 * @api private
1010 */
1011
1012JSONPPolling.prototype.doClose = function () {
1013  if (this.script) {
1014    this.script.parentNode.removeChild(this.script);
1015    this.script = null;
1016  }
1017
1018  if (this.form) {
1019    this.form.parentNode.removeChild(this.form);
1020    this.form = null;
1021    this.iframe = null;
1022  }
1023
1024  Polling.prototype.doClose.call(this);
1025};
1026
1027/**
1028 * Starts a poll cycle.
1029 *
1030 * @api private
1031 */
1032
1033JSONPPolling.prototype.doPoll = function () {
1034  var self = this;
1035  var script = document.createElement('script');
1036
1037  if (this.script) {
1038    this.script.parentNode.removeChild(this.script);
1039    this.script = null;
1040  }
1041
1042  script.async = true;
1043  script.src = this.uri();
1044  script.onerror = function(e){
1045    self.onError('jsonp poll error',e);
1046  };
1047
1048  var insertAt = document.getElementsByTagName('script')[0];
1049  insertAt.parentNode.insertBefore(script, insertAt);
1050  this.script = script;
1051
1052  var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);
1053  
1054  if (isUAgecko) {
1055    setTimeout(function () {
1056      var iframe = document.createElement('iframe');
1057      document.body.appendChild(iframe);
1058      document.body.removeChild(iframe);
1059    }, 100);
1060  }
1061};
1062
1063/**
1064 * Writes with a hidden iframe.
1065 *
1066 * @param {String} data to send
1067 * @param {Function} called upon flush.
1068 * @api private
1069 */
1070
1071JSONPPolling.prototype.doWrite = function (data, fn) {
1072  var self = this;
1073
1074  if (!this.form) {
1075    var form = document.createElement('form');
1076    var area = document.createElement('textarea');
1077    var id = this.iframeId = 'eio_iframe_' + this.index;
1078    var iframe;
1079
1080    form.className = 'socketio';
1081    form.style.position = 'absolute';
1082    form.style.top = '-1000px';
1083    form.style.left = '-1000px';
1084    form.target = id;
1085    form.method = 'POST';
1086    form.setAttribute('accept-charset', 'utf-8');
1087    area.name = 'd';
1088    form.appendChild(area);
1089    document.body.appendChild(form);
1090
1091    this.form = form;
1092    this.area = area;
1093  }
1094
1095  this.form.action = this.uri();
1096
1097  function complete () {
1098    initIframe();
1099    fn();
1100  }
1101
1102  function initIframe () {
1103    if (self.iframe) {
1104      try {
1105        self.form.removeChild(self.iframe);
1106      } catch (e) {
1107        self.onError('jsonp polling iframe removal error', e);
1108      }
1109    }
1110
1111    try {
1112      // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
1113      var html = '<iframe src="javascript:0" name="'+ self.iframeId +'">';
1114      iframe = document.createElement(html);
1115    } catch (e) {
1116      iframe = document.createElement('iframe');
1117      iframe.name = self.iframeId;
1118      iframe.src = 'javascript:0';
1119    }
1120
1121    iframe.id = self.iframeId;
1122
1123    self.form.appendChild(iframe);
1124    self.iframe = iframe;
1125  }
1126
1127  initIframe();
1128
1129  // escape \n to prevent it from being converted into \r\n by some UAs
1130  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
1131  data = data.replace(rEscapedNewline, '\\\n');
1132  this.area.value = data.replace(rNewline, '\\n');
1133
1134  try {
1135    this.form.submit();
1136  } catch(e) {}
1137
1138  if (this.iframe.attachEvent) {
1139    this.iframe.onreadystatechange = function(){
1140      if (self.iframe.readyState == 'complete') {
1141        complete();
1142      }
1143    };
1144  } else {
1145    this.iframe.onload = complete;
1146  }
1147};
1148
1149}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1150},{"./polling":8,"component-inherit":13}],7:[function(_dereq_,module,exports){
1151(function (global){
1152/**
1153 * Module requirements.
1154 */
1155
1156var XMLHttpRequest = _dereq_('xmlhttprequest');
1157var Polling = _dereq_('./polling');
1158var Emitter = _dereq_('component-emitter');
1159var inherit = _dereq_('component-inherit');
1160var debug = _dereq_('debug')('engine.io-client:polling-xhr');
1161
1162/**
1163 * Module exports.
1164 */
1165
1166module.exports = XHR;
1167module.exports.Request = Request;
1168
1169/**
1170 * Empty function
1171 */
1172
1173function empty(){}
1174
1175/**
1176 * XHR Polling constructor.
1177 *
1178 * @param {Object} opts
1179 * @api public
1180 */
1181
1182function XHR(opts){
1183  Polling.call(this, opts);
1184
1185  if (global.location) {
1186    var isSSL = 'https:' == location.protocol;
1187    var port = location.port;
1188
1189    // some user agents have empty `location.port`
1190    if (!port) {
1191      port = isSSL ? 443 : 80;
1192    }
1193
1194    this.xd = opts.hostname != global.location.hostname ||
1195      port != opts.port;
1196    this.xs = opts.secure != isSSL;
1197  }
1198}
1199
1200/**
1201 * Inherits from Polling.
1202 */
1203
1204inherit(XHR, Polling);
1205
1206/**
1207 * XHR supports binary
1208 */
1209
1210XHR.prototype.supportsBinary = true;
1211
1212/**
1213 * Creates a request.
1214 *
1215 * @param {String} method
1216 * @api private
1217 */
1218
1219XHR.prototype.request = function(opts){
1220  opts = opts || {};
1221  opts.uri = this.uri();
1222  opts.xd = this.xd;
1223  opts.xs = this.xs;
1224  opts.agent = this.agent || false;
1225  opts.supportsBinary = this.supportsBinary;
1226  opts.enablesXDR = this.enablesXDR;
1227  return new Request(opts);
1228};
1229
1230/**
1231 * Sends data.
1232 *
1233 * @param {String} data to send.
1234 * @param {Function} called upon flush.
1235 * @api private
1236 */
1237
1238XHR.prototype.doWrite = function(data, fn){
1239  var isBinary = typeof data !== 'string' && data !== undefined;
1240  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
1241  var self = this;
1242  req.on('success', fn);
1243  req.on('error', function(err){
1244    self.onError('xhr post error', err);
1245  });
1246  this.sendXhr = req;
1247};
1248
1249/**
1250 * Starts a poll cycle.
1251 *
1252 * @api private
1253 */
1254
1255XHR.prototype.doPoll = function(){
1256  debug('xhr poll');
1257  var req = this.request();
1258  var self = this;
1259  req.on('data', function(data){
1260    self.onData(data);
1261  });
1262  req.on('error', function(err){
1263    self.onError('xhr poll error', err);
1264  });
1265  this.pollXhr = req;
1266};
1267
1268/**
1269 * Request constructor
1270 *
1271 * @param {Object} options
1272 * @api public
1273 */
1274
1275function Request(opts){
1276  this.method = opts.method || 'GET';
1277  this.uri = opts.uri;
1278  this.xd = !!opts.xd;
1279  this.xs = !!opts.xs;
1280  this.async = false !== opts.async;
1281  this.data = undefined != opts.data ? opts.data : null;
1282  this.agent = opts.agent;
1283  this.isBinary = opts.isBinary;
1284  this.supportsBinary = opts.supportsBinary;
1285  this.enablesXDR = opts.enablesXDR;
1286  this.create();
1287}
1288
1289/**
1290 * Mix in `Emitter`.
1291 */
1292
1293Emitter(Request.prototype);
1294
1295/**
1296 * Creates the XHR object and sends the request.
1297 *
1298 * @api private
1299 */
1300
1301Request.prototype.create = function(){
1302  var xhr = this.xhr = new XMLHttpRequest({ agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR });
1303  var self = this;
1304
1305  try {
1306    debug('xhr open %s: %s', this.method, this.uri);
1307    xhr.open(this.method, this.uri, this.async);
1308    if (this.supportsBinary) {
1309      // This has to be done after open because Firefox is stupid
1310      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
1311      xhr.responseType = 'arraybuffer';
1312    }
1313
1314    if ('POST' == this.method) {
1315      try {
1316        if (this.isBinary) {
1317          xhr.setRequestHeader('Content-type', 'application/octet-stream');
1318        } else {
1319          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
1320        }
1321      } catch (e) {}
1322    }
1323
1324    // ie6 check
1325    if ('withCredentials' in xhr) {
1326      xhr.withCredentials = true;
1327    }
1328
1329    if (this.hasXDR()) {
1330      xhr.onload = function(){
1331        self.onLoad();
1332      };
1333      xhr.onerror = function(){
1334        self.onError(xhr.responseText);
1335      };
1336    } else {
1337      xhr.onreadystatechange = function(){
1338        if (4 != xhr.readyState) return;
1339        if (200 == xhr.status || 1223 == xhr.status) {
1340          self.onLoad();
1341        } else {
1342          // make sure the `error` event handler that's user-set
1343          // does not throw in the same tick and gets caught here
1344          setTimeout(function(){
1345            self.onError(xhr.status);
1346          }, 0);
1347        }
1348      };
1349    }
1350
1351    debug('xhr data %s', this.data);
1352    xhr.send(this.data);
1353  } catch (e) {
1354    // Need to defer since .create() is called directly fhrom the constructor
1355    // and thus the 'error' event can only be only bound *after* this exception
1356    // occurs.  Therefore, also, we cannot throw here at all.
1357    setTimeout(function() {
1358      self.onError(e);
1359    }, 0);
1360    return;
1361  }
1362
1363  if (global.document) {
1364    this.index = Request.requestsCount++;
1365    Request.requests[this.index] = this;
1366  }
1367};
1368
1369/**
1370 * Called upon successful response.
1371 *
1372 * @api private
1373 */
1374
1375Request.prototype.onSuccess = function(){
1376  this.emit('success');
1377  this.cleanup();
1378};
1379
1380/**
1381 * Called if we have data.
1382 *
1383 * @api private
1384 */
1385
1386Request.prototype.onData = function(data){
1387  this.emit('data', data);
1388  this.onSuccess();
1389};
1390
1391/**
1392 * Called upon error.
1393 *
1394 * @api private
1395 */
1396
1397Request.prototype.onError = function(err){
1398  this.emit('error', err);
1399  this.cleanup();
1400};
1401
1402/**
1403 * Cleans up house.
1404 *
1405 * @api private
1406 */
1407
1408Request.prototype.cleanup = function(){
1409  if ('undefined' == typeof this.xhr || null === this.xhr) {
1410    return;
1411  }
1412  // xmlhttprequest
1413  if (this.hasXDR()) {
1414    this.xhr.onload = this.xhr.onerror = empty;
1415  } else {
1416    this.xhr.onreadystatechange = empty;
1417  }
1418
1419  try {
1420    this.xhr.abort();
1421  } catch(e) {}
1422
1423  if (global.document) {
1424    delete Request.requests[this.index];
1425  }
1426
1427  this.xhr = null;
1428};
1429
1430/**
1431 * Called upon load.
1432 *
1433 * @api private
1434 */
1435
1436Request.prototype.onLoad = function(){
1437  var data;
1438  try {
1439    var contentType;
1440    try {
1441      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];
1442    } catch (e) {}
1443    if (contentType === 'application/octet-stream') {
1444      data = this.xhr.response;
1445    } else {
1446      if (!this.supportsBinary) {
1447        data = this.xhr.responseText;
1448      } else {
1449        data = 'ok';
1450      }
1451    }
1452  } catch (e) {
1453    this.onError(e);
1454  }
1455  if (null != data) {
1456    this.onData(data);
1457  }
1458};
1459
1460/**
1461 * Check if it has XDomainRequest.
1462 *
1463 * @api private
1464 */
1465
1466Request.prototype.hasXDR = function(){
1467  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;
1468};
1469
1470/**
1471 * Aborts the request.
1472 *
1473 * @api public
1474 */
1475
1476Request.prototype.abort = function(){
1477  this.cleanup();
1478};
1479
1480/**
1481 * Aborts pending requests when unloading the window. This is needed to prevent
1482 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
1483 * emitted.
1484 */
1485
1486if (global.document) {
1487  Request.requestsCount = 0;
1488  Request.requests = {};
1489  if (global.attachEvent) {
1490    global.attachEvent('onunload', unloadHandler);
1491  } else if (global.addEventListener) {
1492    global.addEventListener('beforeunload', unloadHandler);
1493  }
1494}
1495
1496function unloadHandler() {
1497  for (var i in Request.requests) {
1498    if (Request.requests.hasOwnProperty(i)) {
1499      Request.requests[i].abort();
1500    }
1501  }
1502}
1503
1504}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1505},{"./polling":8,"component-emitter":12,"component-inherit":13,"debug":14,"xmlhttprequest":10}],8:[function(_dereq_,module,exports){
1506/**
1507 * Module dependencies.
1508 */
1509
1510var Transport = _dereq_('../transport');
1511var parseqs = _dereq_('parseqs');
1512var parser = _dereq_('engine.io-parser');
1513var inherit = _dereq_('component-inherit');
1514var debug = _dereq_('debug')('engine.io-client:polling');
1515
1516/**
1517 * Module exports.
1518 */
1519
1520module.exports = Polling;
1521
1522/**
1523 * Is XHR2 supported?
1524 */
1525
1526var hasXHR2 = (function() {
1527  var XMLHttpRequest = _dereq_('xmlhttprequest');
1528  var xhr = new XMLHttpRequest({ xdomain: false });
1529  return null != xhr.responseType;
1530})();
1531
1532/**
1533 * Polling interface.
1534 *
1535 * @param {Object} opts
1536 * @api private
1537 */
1538
1539function Polling(opts){
1540  var forceBase64 = (opts && opts.forceBase64);
1541  if (!hasXHR2 || forceBase64) {
1542    this.supportsBinary = false;
1543  }
1544  Transport.call(this, opts);
1545}
1546
1547/**
1548 * Inherits from Transport.
1549 */
1550
1551inherit(Polling, Transport);
1552
1553/**
1554 * Transport name.
1555 */
1556
1557Polling.prototype.name = 'polling';
1558
1559/**
1560 * Opens the socket (triggers polling). We write a PING message to determine
1561 * when the transport is open.
1562 *
1563 * @api private
1564 */
1565
1566Polling.prototype.doOpen = function(){
1567  this.poll();
1568};
1569
1570/**
1571 * Pauses polling.
1572 *
1573 * @param {Function} callback upon buffers are flushed and transport is paused
1574 * @api private
1575 */
1576
1577Polling.prototype.pause = function(onPause){
1578  var pending = 0;
1579  var self = this;
1580
1581  this.readyState = 'pausing';
1582
1583  function pause(){
1584    debug('paused');
1585    self.readyState = 'paused';
1586    onPause();
1587  }
1588
1589  if (this.polling || !this.writable) {
1590    var total = 0;
1591
1592    if (this.polling) {
1593      debug('we are currently polling - waiting to pause');
1594      total++;
1595      this.once('pollComplete', function(){
1596        debug('pre-pause polling complete');
1597        --total || pause();
1598      });
1599    }
1600
1601    if (!this.writable) {
1602      debug('we are currently writing - waiting to pause');
1603      total++;
1604      this.once('drain', function(){
1605        debug('pre-pause writing complete');
1606        --total || pause();
1607      });
1608    }
1609  } else {
1610    pause();
1611  }
1612};
1613
1614/**
1615 * Starts polling cycle.
1616 *
1617 * @api public
1618 */
1619
1620Polling.prototype.poll = function(){
1621  debug('polling');
1622  this.polling = true;
1623  this.doPoll();
1624  this.emit('poll');
1625};
1626
1627/**
1628 * Overloads onData to detect payloads.
1629 *
1630 * @api private
1631 */
1632
1633Polling.prototype.onData = function(data){
1634  var self = this;
1635  debug('polling got data %s', data);
1636  var callback = function(packet, index, total) {
1637    // if its the first message we consider the transport open
1638    if ('opening' == self.readyState) {
1639      self.onOpen();
1640    }
1641
1642    // if its a close packet, we close the ongoing requests
1643    if ('close' == packet.type) {
1644      self.onClose();
1645      return false;
1646    }
1647
1648    // otherwise bypass onData and handle the message
1649    self.onPacket(packet);
1650  };
1651
1652  // decode payload
1653  parser.decodePayload(data, this.socket.binaryType, callback);
1654
1655  // if an event did not trigger closing
1656  if ('closed' != this.readyState) {
1657    // if we got data we're not polling
1658    this.polling = false;
1659    this.emit('pollComplete');
1660
1661    if ('open' == this.readyState) {
1662      this.poll();
1663    } else {
1664      debug('ignoring poll - transport state "%s"', this.readyState);
1665    }
1666  }
1667};
1668
1669/**
1670 * For polling, send a close packet.
1671 *
1672 * @api private
1673 */
1674
1675Polling.prototype.doClose = function(){
1676  var self = this;
1677
1678  function close(){
1679    debug('writing close packet');
1680    self.write([{ type: 'close' }]);
1681  }
1682
1683  if ('open' == this.readyState) {
1684    debug('transport open - closing');
1685    close();
1686  } else {
1687    // in case we're trying to close while
1688    // handshaking is in progress (GH-164)
1689    debug('transport not open - deferring close');
1690    this.once('open', close);
1691  }
1692};
1693
1694/**
1695 * Writes a packets payload.
1696 *
1697 * @param {Array} data packets
1698 * @param {Function} drain callback
1699 * @api private
1700 */
1701
1702Polling.prototype.write = function(packets){
1703  var self = this;
1704  this.writable = false;
1705  var callbackfn = function() {
1706    self.writable = true;
1707    self.emit('drain');
1708  };
1709
1710  var self = this;
1711  parser.encodePayload(packets, this.supportsBinary, function(data) {
1712    self.doWrite(data, callbackfn);
1713  });
1714};
1715
1716/**
1717 * Generates uri for connection.
1718 *
1719 * @api private
1720 */
1721
1722Polling.prototype.uri = function(){
1723  var query = this.query || {};
1724  var schema = this.secure ? 'https' : 'http';
1725  var port = '';
1726
1727  // cache busting is forced
1728  if (false !== this.timestampRequests) {
1729    query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;
1730  }
1731
1732  if (!this.supportsBinary && !query.sid) {
1733    query.b64 = 1;
1734  }
1735
1736  query = parseqs.encode(query);
1737
1738  // avoid port if default for schema
1739  if (this.port && (('https' == schema && this.port != 443) ||
1740     ('http' == schema && this.port != 80))) {
1741    port = ':' + this.port;
1742  }
1743
1744  // prepend ? to query
1745  if (query.length) {
1746    query = '?' + query;
1747  }
1748
1749  return schema + '://' + this.hostname + port + this.path + query;
1750};
1751
1752},{"../transport":4,"component-inherit":13,"debug":14,"engine.io-parser":15,"parseqs":25,"xmlhttprequest":10}],9:[function(_dereq_,module,exports){
1753/**
1754 * Module dependencies.
1755 */
1756
1757var Transport = _dereq_('../transport');
1758var parser = _dereq_('engine.io-parser');
1759var parseqs = _dereq_('parseqs');
1760var inherit = _dereq_('component-inherit');
1761var debug = _dereq_('debug')('engine.io-client:websocket');
1762
1763/**
1764 * `ws` exposes a WebSocket-compatible interface in
1765 * Node, or the `WebSocket` or `MozWebSocket` globals
1766 * in the browser.
1767 */
1768
1769var WebSocket = _dereq_('ws');
1770
1771/**
1772 * Module exports.
1773 */
1774
1775module.exports = WS;
1776
1777/**
1778 * WebSocket transport constructor.
1779 *
1780 * @api {Object} connection options
1781 * @api public
1782 */
1783
1784function WS(opts){
1785  var forceBase64 = (opts && opts.forceBase64);
1786  if (forceBase64) {
1787    this.supportsBinary = false;
1788  }
1789  Transport.call(this, opts);
1790}
1791
1792/**
1793 * Inherits from Transport.
1794 */
1795
1796inherit(WS, Transport);
1797
1798/**
1799 * Transport name.
1800 *
1801 * @api public
1802 */
1803
1804WS.prototype.name = 'websocket';
1805
1806/*
1807 * WebSockets support binary
1808 */
1809
1810WS.prototype.supportsBinary = true;
1811
1812/**
1813 * Opens socket.
1814 *
1815 * @api private
1816 */
1817
1818WS.prototype.doOpen = function(){
1819  if (!this.check()) {
1820    // let probe timeout
1821    return;
1822  }
1823
1824  var self = this;
1825  var uri = this.uri();
1826  var protocols = void(0);
1827  var opts = { agent: this.agent };
1828
1829  this.ws = new WebSocket(uri, protocols, opts);
1830
1831  if (this.ws.binaryType === undefined) {
1832    this.supportsBinary = false;
1833  }
1834
1835  this.ws.binaryType = 'arraybuffer';
1836  this.addEventListeners();
1837};
1838
1839/**
1840 * Adds event listeners to the socket
1841 *
1842 * @api private
1843 */
1844
1845WS.prototype.addEventListeners = function(){
1846  var self = this;
1847
1848  this.ws.onopen = function(){
1849    self.onOpen();
1850  };
1851  this.ws.onclose = function(){
1852    self.onClose();
1853  };
1854  this.ws.onmessage = function(ev){
1855    self.onData(ev.data);
1856  };
1857  this.ws.onerror = function(e){
1858    self.onError('websocket error', e);
1859  };
1860};
1861
1862/**
1863 * Override `onData` to use a timer on iOS.
1864 * See: https://gist.github.com/mloughran/2052006
1865 *
1866 * @api private
1867 */
1868
1869if ('undefined' != typeof navigator
1870  && /iPad|iPhone|iPod/i.test(navigator.userAgent)) {
1871  WS.prototype.onData = function(data){
1872    var self = this;
1873    setTimeout(function(){
1874      Transport.prototype.onData.call(self, data);
1875    }, 0);
1876  };
1877}
1878
1879/**
1880 * Writes data to socket.
1881 *
1882 * @param {Array} array of packets.
1883 * @api private
1884 */
1885
1886WS.prototype.write = function(packets){
1887  var self = this;
1888  this.writable = false;
1889  // encodePacket efficient as it uses WS framing
1890  // no need for encodePayload
1891  for (var i = 0, l = packets.length; i < l; i++) {
1892    parser.encodePacket(packets[i], this.supportsBinary, function(data) {
1893      //Sometimes the websocket has already been closed but the browser didn't
1894      //have a chance of informing us about it yet, in that case send will
1895      //throw an error
1896      try {
1897        self.ws.send(data);
1898      } catch (e){
1899        debug('websocket closed before onclose event');
1900      }
1901    });
1902  }
1903
1904  function ondrain() {
1905    self.writable = true;
1906    self.emit('drain');
1907  }
1908  // fake drain
1909  // defer to next tick to allow Socket to clear writeBuffer
1910  setTimeout(ondrain, 0);
1911};
1912
1913/**
1914 * Called upon close
1915 *
1916 * @api private
1917 */
1918
1919WS.prototype.onClose = function(){
1920  Transport.prototype.onClose.call(this);
1921};
1922
1923/**
1924 * Closes socket.
1925 *
1926 * @api private
1927 */
1928
1929WS.prototype.doClose = function(){
1930  if (typeof this.ws !== 'undefined') {
1931    this.ws.close();
1932  }
1933};
1934
1935/**
1936 * Generates uri for connection.
1937 *
1938 * @api private
1939 */
1940
1941WS.prototype.uri = function(){
1942  var query = this.query || {};
1943  var schema = this.secure ? 'wss' : 'ws';
1944  var port = '';
1945
1946  // avoid port if default for schema
1947  if (this.port && (('wss' == schema && this.port != 443)
1948    || ('ws' == schema && this.port != 80))) {
1949    port = ':' + this.port;
1950  }
1951
1952  // append timestamp to URI
1953  if (this.timestampRequests) {
1954    query[this.timestampParam] = +new Date;
1955  }
1956
1957  // communicate binary support capabilities
1958  if (!this.supportsBinary) {
1959    query.b64 = 1;
1960  }
1961
1962  query = parseqs.encode(query);
1963
1964  // prepend ? to query
1965  if (query.length) {
1966    query = '?' + query;
1967  }
1968
1969  return schema + '://' + this.hostname + port + this.path + query;
1970};
1971
1972/**
1973 * Feature detection for WebSocket.
1974 *
1975 * @return {Boolean} whether this transport is available.
1976 * @api public
1977 */
1978
1979WS.prototype.check = function(){
1980  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
1981};
1982
1983},{"../transport":4,"component-inherit":13,"debug":14,"engine.io-parser":15,"parseqs":25,"ws":27}],10:[function(_dereq_,module,exports){
1984// browser shim for xmlhttprequest module
1985var hasCORS = _dereq_('has-cors');
1986
1987module.exports = function(opts) {
1988  var xdomain = opts.xdomain;
1989
1990  // scheme must be same when usign XDomainRequest
1991  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
1992  var xscheme = opts.xscheme;
1993
1994  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
1995  // https://github.com/Automattic/engine.io-client/pull/217
1996  var enablesXDR = opts.enablesXDR;
1997
1998  // XMLHttpRequest can be disabled on IE
1999  try {
2000    if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {
2001      return new XMLHttpRequest();
2002    }
2003  } catch (e) { }
2004
2005  // Use XDomainRequest for IE8 if enablesXDR is true
2006  // because loading bar keeps flashing when using jsonp-polling
2007  // https://github.com/yujiosaka/socke.io-ie8-loading-example
2008  try {
2009    if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {
2010      return new XDomainRequest();
2011    }
2012  } catch (e) { }
2013
2014  if (!xdomain) {
2015    try {
2016      return new ActiveXObject('Microsoft.XMLHTTP');
2017    } catch(e) { }
2018  }
2019}
2020
2021},{"has-cors":21}],11:[function(_dereq_,module,exports){
2022(function (global){
2023/**
2024 * Create a blob builder even when vendor prefixes exist
2025 */
2026
2027var BlobBuilder = global.BlobBuilder
2028  || global.WebKitBlobBuilder
2029  || global.MSBlobBuilder
2030  || global.MozBlobBuilder;
2031
2032/**
2033 * Check if Blob constructor is supported
2034 */
2035
2036var blobSupported = (function() {
2037  try {
2038    var b = new Blob(['hi']);
2039    return b.size == 2;
2040  } catch(e) {
2041    return false;
2042  }
2043})();
2044
2045/**
2046 * Check if BlobBuilder is supported
2047 */
2048
2049var blobBuilderSupported = BlobBuilder
2050  && BlobBuilder.prototype.append
2051  && BlobBuilder.prototype.getBlob;
2052
2053function BlobBuilderConstructor(ary, options) {
2054  options = options || {};
2055
2056  var bb = new BlobBuilder();
2057  for (var i = 0; i < ary.length; i++) {
2058    bb.append(ary[i]);
2059  }
2060  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
2061};
2062
2063module.exports = (function() {
2064  if (blobSupported) {
2065    return global.Blob;
2066  } else if (blobBuilderSupported) {
2067    return BlobBuilderConstructor;
2068  } else {
2069    return undefined;
2070  }
2071})();
2072
2073}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2074},{}],12:[function(_dereq_,module,exports){
2075
2076/**
2077 * Expose `Emitter`.
2078 */
2079
2080module.exports = Emitter;
2081
2082/**
2083 * Initialize a new `Emitter`.
2084 *
2085 * @api public
2086 */
2087
2088function Emitter(obj) {
2089  if (obj) return mixin(obj);
2090};
2091
2092/**
2093 * Mixin the emitter properties.
2094 *
2095 * @param {Object} obj
2096 * @return {Object}
2097 * @api private
2098 */
2099
2100function mixin(obj) {
2101  for (var key in Emitter.prototype) {
2102    obj[key] = Emitter.prototype[key];
2103  }
2104  return obj;
2105}
2106
2107/**
2108 * Listen on the given `event` with `fn`.
2109 *
2110 * @param {String} event
2111 * @param {Function} fn
2112 * @return {Emitter}
2113 * @api public
2114 */
2115
2116Emitter.prototype.on =
2117Emitter.prototype.addEventListener = function(event, fn){
2118  this._callbacks = this._callbacks || {};
2119  (this._callbacks[event] = this._callbacks[event] || [])
2120    .push(fn);
2121  return this;
2122};
2123
2124/**
2125 * Adds an `event` listener that will be invoked a single
2126 * time then automatically removed.
2127 *
2128 * @param {String} event
2129 * @param {Function} fn
2130 * @return {Emitter}
2131 * @api public
2132 */
2133
2134Emitter.prototype.once = function(event, fn){
2135  var self = this;
2136  this._callbacks = this._callbacks || {};
2137
2138  function on() {
2139    self.off(event, on);
2140    fn.apply(this, arguments);
2141  }
2142
2143  on.fn = fn;
2144  this.on(event, on);
2145  return this;
2146};
2147
2148/**
2149 * Remove the given callback for `event` or all
2150 * registered callbacks.
2151 *
2152 * @param {String} event
2153 * @param {Function} fn
2154 * @return {Emitter}
2155 * @api public
2156 */
2157
2158Emitter.prototype.off =
2159Emitter.prototype.removeListener =
2160Emitter.prototype.removeAllListeners =
2161Emitter.prototype.removeEventListener = function(event, fn){
2162  this._callbacks = this._callbacks || {};
2163
2164  // all
2165  if (0 == arguments.length) {
2166    this._callbacks = {};
2167    return this;
2168  }
2169
2170  // specific event
2171  var callbacks = this._callbacks[event];
2172  if (!callbacks) return this;
2173
2174  // remove all handlers
2175  if (1 == arguments.length) {
2176    delete this._callbacks[event];
2177    return this;
2178  }
2179
2180  // remove specific handler
2181  var cb;
2182  for (var i = 0; i < callbacks.length; i++) {
2183    cb = callbacks[i];
2184    if (cb === fn || cb.fn === fn) {
2185      callbacks.splice(i, 1);
2186      break;
2187    }
2188  }
2189  return this;
2190};
2191
2192/**
2193 * Emit `event` with the given args.
2194 *
2195 * @param {String} event
2196 * @param {Mixed} ...
2197 * @return {Emitter}
2198 */
2199
2200Emitter.prototype.emit = function(event){
2201  this._callbacks = this._callbacks || {};
2202  var args = [].slice.call(arguments, 1)
2203    , callbacks = this._callbacks[event];
2204
2205  if (callbacks) {
2206    callbacks = callbacks.slice(0);
2207    for (var i = 0, len = callbacks.length; i < len; ++i) {
2208      callbacks[i].apply(this, args);
2209    }
2210  }
2211
2212  return this;
2213};
2214
2215/**
2216 * Return array of callbacks for `event`.
2217 *
2218 * @param {String} event
2219 * @return {Array}
2220 * @api public
2221 */
2222
2223Emitter.prototype.listeners = function(event){
2224  this._callbacks = this._callbacks || {};
2225  return this._callbacks[event] || [];
2226};
2227
2228/**
2229 * Check if this emitter has `event` handlers.
2230 *
2231 * @param {String} event
2232 * @return {Boolean}
2233 * @api public
2234 */
2235
2236Emitter.prototype.hasListeners = function(event){
2237  return !! this.listeners(event).length;
2238};
2239
2240},{}],13:[function(_dereq_,module,exports){
2241
2242module.exports = function(a, b){
2243  var fn = function(){};
2244  fn.prototype = b.prototype;
2245  a.prototype = new fn;
2246  a.prototype.constructor = a;
2247};
2248},{}],14:[function(_dereq_,module,exports){
2249
2250/**
2251 * Expose `debug()` as the module.
2252 */
2253
2254module.exports = debug;
2255
2256/**
2257 * Create a debugger with the given `name`.
2258 *
2259 * @param {String} name
2260 * @return {Type}
2261 * @api public
2262 */
2263
2264function debug(name) {
2265  if (!debug.enabled(name)) return function(){};
2266
2267  return function(fmt){
2268    fmt = coerce(fmt);
2269
2270    var curr = new Date;
2271    var ms = curr - (debug[name] || curr);
2272    debug[name] = curr;
2273
2274    fmt = name
2275      + ' '
2276      + fmt
2277      + ' +' + debug.humanize(ms);
2278
2279    // This hackery is required for IE8
2280    // where `console.log` doesn't have 'apply'
2281    window.console
2282      && console.log
2283      && Function.prototype.apply.call(console.log, console, arguments);
2284  }
2285}
2286
2287/**
2288 * The currently active debug mode names.
2289 */
2290
2291debug.names = [];
2292debug.skips = [];
2293
2294/**
2295 * Enables a debug mode by name. This can include modes
2296 * separated by a colon and wildcards.
2297 *
2298 * @param {String} name
2299 * @api public
2300 */
2301
2302debug.enable = function(name) {
2303  try {
2304    localStorage.debug = name;
2305  } catch(e){}
2306
2307  var split = (name || '').split(/[\s,]+/)
2308    , len = split.length;
2309
2310  for (var i = 0; i < len; i++) {
2311    name = split[i].replace('*', '.*?');
2312    if (name[0] === '-') {
2313      debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
2314    }
2315    else {
2316      debug.names.push(new RegExp('^' + name + '$'));
2317    }
2318  }
2319};
2320
2321/**
2322 * Disable debug output.
2323 *
2324 * @api public
2325 */
2326
2327debug.disable = function(){
2328  debug.enable('');
2329};
2330
2331/**
2332 * Humanize the given `ms`.
2333 *
2334 * @param {Number} m
2335 * @return {String}
2336 * @api private
2337 */
2338
2339debug.humanize = function(ms) {
2340  var sec = 1000
2341    , min = 60 * 1000
2342    , hour = 60 * min;
2343
2344  if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
2345  if (ms >= min) return (ms / min).toFixed(1) + 'm';
2346  if (ms >= sec) return (ms / sec | 0) + 's';
2347  return ms + 'ms';
2348};
2349
2350/**
2351 * Returns true if the given mode name is enabled, false otherwise.
2352 *
2353 * @param {String} name
2354 * @return {Boolean}
2355 * @api public
2356 */
2357
2358debug.enabled = function(name) {
2359  for (var i = 0, len = debug.skips.length; i < len; i++) {
2360    if (debug.skips[i].test(name)) {
2361      return false;
2362    }
2363  }
2364  for (var i = 0, len = debug.names.length; i < len; i++) {
2365    if (debug.names[i].test(name)) {
2366      return true;
2367    }
2368  }
2369  return false;
2370};
2371
2372/**
2373 * Coerce `val`.
2374 */
2375
2376function coerce(val) {
2377  if (val instanceof Error) return val.stack || val.message;
2378  return val;
2379}
2380
2381// persist
2382
2383try {
2384  if (window.localStorage) debug.enable(localStorage.debug);
2385} catch(e){}
2386
2387},{}],15:[function(_dereq_,module,exports){
2388(function (global){
2389/**
2390 * Module dependencies.
2391 */
2392
2393var keys = _dereq_('./keys');
2394var sliceBuffer = _dereq_('arraybuffer.slice');
2395var base64encoder = _dereq_('base64-arraybuffer');
2396var after = _dereq_('after');
2397var utf8 = _dereq_('utf8');
2398
2399/**
2400 * Check if we are running an android browser. That requires us to use
2401 * ArrayBuffer with polling transports...
2402 *
2403 * http://ghinda.net/jpeg-blob-ajax-android/
2404 */
2405
2406var isAndroid = navigator.userAgent.match(/Android/i);
2407
2408/**
2409 * Current protocol version.
2410 */
2411
2412exports.protocol = 3;
2413
2414/**
2415 * Packet types.
2416 */
2417
2418var packets = exports.packets = {
2419    open:     0    // non-ws
2420  , close:    1    // non-ws
2421  , ping:     2
2422  , pong:     3
2423  , message:  4
2424  , upgrade:  5
2425  , noop:     6
2426};
2427
2428var packetslist = keys(packets);
2429
2430/**
2431 * Premade error packet.
2432 */
2433
2434var err = { type: 'error', data: 'parser error' };
2435
2436/**
2437 * Create a blob api even for blob builder when vendor prefixes exist
2438 */
2439
2440var Blob = _dereq_('blob');
2441
2442/**
2443 * Encodes a packet.
2444 *
2445 *     <packet type id> [ <data> ]
2446 *
2447 * Example:
2448 *
2449 *     5hello world
2450 *     3
2451 *     4
2452 *
2453 * Binary is encoded in an identical principle
2454 *
2455 * @api private
2456 */
2457
2458exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
2459  if ('function' == typeof supportsBinary) {
2460    callback = supportsBinary;
2461    supportsBinary = false;
2462  }
2463
2464  if ('function' == typeof utf8encode) {
2465    callback = utf8encode;
2466    utf8encode = null;
2467  }
2468
2469  var data = (packet.data === undefined)
2470    ? undefined
2471    : packet.data.buffer || packet.data;
2472
2473  if (global.ArrayBuffer && data instanceof ArrayBuffer) {
2474    return encodeArrayBuffer(packet, supportsBinary, callback);
2475  } else if (Blob && data instanceof global.Blob) {
2476    return encodeBlob(packet, supportsBinary, callback);
2477  }
2478
2479  // Sending data as a utf-8 string
2480  var encoded = packets[packet.type];
2481
2482  // data fragment is optional
2483  if (undefined !== packet.data) {
2484    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);
2485  }
2486
2487  return callback('' + encoded);
2488
2489};
2490
2491/**
2492 * Encode packet helpers for binary types
2493 */
2494
2495function encodeArrayBuffer(packet, supportsBinary, callback) {
2496  if (!supportsBinary) {
2497    return exports.encodeBase64Packet(packet, callback);
2498  }
2499
2500  var data = packet.data;
2501  var contentArray = new Uint8Array(data);
2502  var resultBuffer = new Uint8Array(1 + data.byteLength);
2503
2504  resultBuffer[0] = packets[packet.type];
2505  for (var i = 0; i < contentArray.length; i++) {
2506    resultBuffer[i+1] = contentArray[i];
2507  }
2508
2509  return callback(resultBuffer.buffer);
2510}
2511
2512function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
2513  if (!supportsBinary) {
2514    return exports.encodeBase64Packet(packet, callback);
2515  }
2516
2517  var fr = new FileReader();
2518  fr.onload = function() {
2519    packet.data = fr.result;
2520    exports.encodePacket(packet, supportsBinary, true, callback);
2521  };
2522  return fr.readAsArrayBuffer(packet.data);
2523}
2524
2525function encodeBlob(packet, supportsBinary, callback) {
2526  if (!supportsBinary) {
2527    return exports.encodeBase64Packet(packet, callback);
2528  }
2529
2530  if (isAndroid) {
2531    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
2532  }
2533
2534  var length = new Uint8Array(1);
2535  length[0] = packets[packet.type];
2536  var blob = new Blob([length.buffer, packet.data]);
2537
2538  return callback(blob);
2539}
2540
2541/**
2542 * Encodes a packet with binary data in a base64 string
2543 *
2544 * @param {Object} packet, has `type` and `data`
2545 * @return {String} base64 encoded message
2546 */
2547
2548exports.encodeBase64Packet = function(packet, callback) {
2549  var message = 'b' + exports.packets[packet.type];
2550  if (Blob && packet.data instanceof Blob) {
2551    var fr = new FileReader();
2552    fr.onload = function() {
2553      var b64 = fr.result.split(',')[1];
2554      callback(message + b64);
2555    };
2556    return fr.readAsDataURL(packet.data);
2557  }
2558
2559  var b64data;
2560  try {
2561    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
2562  } catch (e) {
2563    // iPhone Safari doesn't let you apply with typed arrays
2564    var typed = new Uint8Array(packet.data);
2565    var basic = new Array(typed.length);
2566    for (var i = 0; i < typed.length; i++) {
2567      basic[i] = typed[i];
2568    }
2569    b64data = String.fromCharCode.apply(null, basic);
2570  }
2571  message += global.btoa(b64data);
2572  return callback(message);
2573};
2574
2575/**
2576 * Decodes a packet. Changes format to Blob if requested.
2577 *
2578 * @return {Object} with `type` and `data` (if any)
2579 * @api private
2580 */
2581
2582exports.decodePacket = function (data, binaryType, utf8decode) {
2583  // String data
2584  if (typeof data == 'string' || data === undefined) {
2585    if (data.charAt(0) == 'b') {
2586      return exports.decodeBase64Packet(data.substr(1), binaryType);
2587    }
2588
2589    if (utf8decode) {
2590      try {
2591        data = utf8.decode(data);
2592      } catch (e) {
2593        return err;
2594      }
2595    }
2596    var type = data.charAt(0);
2597
2598    if (Number(type) != type || !packetslist[type]) {
2599      return err;
2600    }
2601
2602    if (data.length > 1) {
2603      return { type: packetslist[type], data: data.substring(1) };
2604    } else {
2605      return { type: packetslist[type] };
2606    }
2607  }
2608
2609  var asArray = new Uint8Array(data);
2610  var type = asArray[0];
2611  var rest = sliceBuffer(data, 1);
2612  if (Blob && binaryType === 'blob') {
2613    rest = new Blob([rest]);
2614  }
2615  return { type: packetslist[type], data: rest };
2616};
2617
2618/**
2619 * Decodes a packet encoded in a base64 string
2620 *
2621 * @param {String} base64 encoded message
2622 * @return {Object} with `type` and `data` (if any)
2623 */
2624
2625exports.decodeBase64Packet = function(msg, binaryType) {
2626  var type = packetslist[msg.charAt(0)];
2627  if (!global.ArrayBuffer) {
2628    return { type: type, data: { base64: true, data: msg.substr(1) } };
2629  }
2630
2631  var data = base64encoder.decode(msg.substr(1));
2632
2633  if (binaryType === 'blob' && Blob) {
2634    data = new Blob([data]);
2635  }
2636
2637  return { type: type, data: data };
2638};
2639
2640/**
2641 * Encodes multiple messages (payload).
2642 *
2643 *     <length>:data
2644 *
2645 * Example:
2646 *
2647 *     11:hello world2:hi
2648 *
2649 * If any contents are binary, they will be encoded as base64 strings. Base64
2650 * encoded strings are marked with a b before the length specifier
2651 *
2652 * @param {Array} packets
2653 * @api private
2654 */
2655
2656exports.encodePayload = function (packets, supportsBinary, callback) {
2657  if (typeof supportsBinary == 'function') {
2658    callback = supportsBinary;
2659    supportsBinary = null;
2660  }
2661
2662  if (supportsBinary) {
2663    if (Blob && !isAndroid) {
2664      return exports.encodePayloadAsBlob(packets, callback);
2665    }
2666
2667    return exports.encodePayloadAsArrayBuffer(packets, callback);
2668  }
2669
2670  if (!packets.length) {
2671    return callback('0:');
2672  }
2673
2674  function setLengthHeader(message) {
2675    return message.length + ':' + message;
2676  }
2677
2678  function encodeOne(packet, doneCallback) {
2679    exports.encodePacket(packet, supportsBinary, true, function(message) {
2680      doneCallback(null, setLengthHeader(message));
2681    });
2682  }
2683
2684  map(packets, encodeOne, function(err, results) {
2685    return callback(results.join(''));
2686  });
2687};
2688
2689/**
2690 * Async array map using after
2691 */
2692
2693function map(ary, each, done) {
2694  var result = new Array(ary.length);
2695  var next = after(ary.length, done);
2696
2697  var eachWithIndex = function(i, el, cb) {
2698    each(el, function(error, msg) {
2699      result[i] = msg;
2700      cb(error, result);
2701    });
2702  };
2703
2704  for (var i = 0; i < ary.length; i++) {
2705    eachWithIndex(i, ary[i], next);
2706  }
2707}
2708
2709/*
2710 * Decodes data when a payload is maybe expected. Possible binary contents are
2711 * decoded from their base64 representation
2712 *
2713 * @param {String} data, callback method
2714 * @api public
2715 */
2716
2717exports.decodePayload = function (data, binaryType, callback) {
2718  if (typeof data != 'string') {
2719    return exports.decodePayloadAsBinary(data, binaryType, callback);
2720  }
2721
2722  if (typeof binaryType === 'function') {
2723    callback = binaryType;
2724    binaryType = null;
2725  }
2726
2727  var packet;
2728  if (data == '') {
2729    // parser error - ignoring payload
2730    return callback(err, 0, 1);
2731  }
2732
2733  var length = ''
2734    , n, msg;
2735
2736  for (var i = 0, l = data.length; i < l; i++) {
2737    var chr = data.charAt(i);
2738
2739    if (':' != chr) {
2740      length += chr;
2741    } else {
2742      if ('' == length || (length != (n = Number(length)))) {
2743        // parser error - ignoring payload
2744        return callback(err, 0, 1);
2745      }
2746
2747      msg = data.substr(i + 1, n);
2748
2749      if (length != msg.length) {
2750        // parser error - ignoring payload
2751        return callback(err, 0, 1);
2752      }
2753
2754      if (msg.length) {
2755        packet = exports.decodePacket(msg, binaryType, true);
2756
2757        if (err.type == packet.type && err.data == packet.data) {
2758          // parser error in individual packet - ignoring payload
2759          return callback(err, 0, 1);
2760        }
2761
2762        var ret = callback(packet, i + n, l);
2763        if (false === ret) return;
2764      }
2765
2766      // advance cursor
2767      i += n;
2768      length = '';
2769    }
2770  }
2771
2772  if (length != '') {
2773    // parser error - ignoring payload
2774    return callback(err, 0, 1);
2775  }
2776
2777};
2778
2779/**
2780 * Encodes multiple messages (payload) as binary.
2781 *
2782 * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
2783 * 255><data>
2784 *
2785 * Example:
2786 * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
2787 *
2788 * @param {Array} packets
2789 * @return {ArrayBuffer} encoded payload
2790 * @api private
2791 */
2792
2793exports.encodePayloadAsArrayBuffer = function(packets, callback) {
2794  if (!packets.length) {
2795    return callback(new ArrayBuffer(0));
2796  }
2797
2798  function encodeOne(packet, doneCallback) {
2799    exports.encodePacket(packet, true, true, function(data) {
2800      return doneCallback(null, data);
2801    });
2802  }
2803
2804  map(packets, encodeOne, function(err, encodedPackets) {
2805    var totalLength = encodedPackets.reduce(function(acc, p) {
2806      var len;
2807      if (typeof p === 'string'){
2808        len = p.length;
2809      } else {
2810        len = p.byteLength;
2811      }
2812      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
2813    }, 0);
2814
2815    var resultArray = new Uint8Array(totalLength);
2816
2817    var bufferIndex = 0;
2818    encodedPackets.forEach(function(p) {
2819      var isString = typeof p === 'string';
2820      var ab = p;
2821      if (isString) {
2822        var view = new Uint8Array(p.length);
2823        for (var i = 0; i < p.length; i++) {
2824          view[i] = p.charCodeAt(i);
2825        }
2826        ab = view.buffer;
2827      }
2828
2829      if (isString) { // not true binary
2830        resultArray[bufferIndex++] = 0;
2831      } else { // true binary
2832        resultArray[bufferIndex++] = 1;
2833      }
2834
2835      var lenStr = ab.byteLength.toString();
2836      for (var i = 0; i < lenStr.length; i++) {
2837        resultArray[bufferIndex++] = parseInt(lenStr[i]);
2838      }
2839      resultArray[bufferIndex++] = 255;
2840
2841      var view = new Uint8Array(ab);
2842      for (var i = 0; i < view.length; i++) {
2843        resultArray[bufferIndex++] = view[i];
2844      }
2845    });
2846
2847    return callback(resultArray.buffer);
2848  });
2849};
2850
2851/**
2852 * Encode as Blob
2853 */
2854
2855exports.encodePayloadAsBlob = function(packets, callback) {
2856  function encodeOne(packet, doneCallback) {
2857    exports.encodePacket(packet, true, true, function(encoded) {
2858      var binaryIdentifier = new Uint8Array(1);
2859      binaryIdentifier[0] = 1;
2860      if (typeof encoded === 'string') {
2861        var view = new Uint8Array(encoded.length);
2862        for (var i = 0; i < encoded.length; i++) {
2863          view[i] = encoded.charCodeAt(i);
2864        }
2865        encoded = view.buffer;
2866        binaryIdentifier[0] = 0;
2867      }
2868
2869      var len = (encoded instanceof ArrayBuffer)
2870        ? encoded.byteLength
2871        : encoded.size;
2872
2873      var lenStr = len.toString();
2874      var lengthAry = new Uint8Array(lenStr.length + 1);
2875      for (var i = 0; i < lenStr.length; i++) {
2876        lengthAry[i] = parseInt(lenStr[i]);
2877      }
2878      lengthAry[lenStr.length] = 255;
2879
2880      if (Blob) {
2881        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
2882        doneCallback(null, blob);
2883      }
2884    });
2885  }
2886
2887  map(packets, encodeOne, function(err, results) {
2888    return callback(new Blob(results));
2889  });
2890};
2891
2892/*
2893 * Decodes data when a payload is maybe expected. Strings are decoded by
2894 * interpreting each byte as a key code for entries marked to start with 0. See
2895 * description of encodePayloadAsBinary
2896 *
2897 * @param {ArrayBuffer} data, callback method
2898 * @api public
2899 */
2900
2901exports.decodePayloadAsBinary = function (data, binaryType, callback) {
2902  if (typeof binaryType === 'function') {
2903    callback = binaryType;
2904    binaryType = null;
2905  }
2906
2907  var bufferTail = data;
2908  var buffers = [];
2909
2910  var numberTooLong = false;
2911  while (bufferTail.byteLength > 0) {
2912    var tailArray = new Uint8Array(bufferTail);
2913    var isString = tailArray[0] === 0;
2914    var msgLength = '';
2915
2916    for (var i = 1; ; i++) {
2917      if (tailArray[i] == 255) break;
2918
2919      if (msgLength.length > 310) {
2920        numberTooLong = true;
2921        break;
2922      }
2923
2924      msgLength += tailArray[i];
2925    }
2926
2927    if(numberTooLong) return callback(err, 0, 1);
2928
2929    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
2930    msgLength = parseInt(msgLength);
2931
2932    var msg = sliceBuffer(bufferTail, 0, msgLength);
2933    if (isString) {
2934      try {
2935        msg = String.fromCharCode.apply(null, new Uint8Array(msg));
2936      } catch (e) {
2937        // iPhone Safari doesn't let you apply to typed arrays
2938        var typed = new Uint8Array(msg);
2939        msg = '';
2940        for (var i = 0; i < typed.length; i++) {
2941          msg += String.fromCharCode(typed[i]);
2942        }
2943      }
2944    }
2945
2946    buffers.push(msg);
2947    bufferTail = sliceBuffer(bufferTail, msgLength);
2948  }
2949
2950  var total = buffers.length;
2951  buffers.forEach(function(buffer, i) {
2952    callback(exports.decodePacket(buffer, binaryType, true), i, total);
2953  });
2954};
2955
2956}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2957},{"./keys":16,"after":17,"arraybuffer.slice":18,"base64-arraybuffer":19,"blob":11,"utf8":20}],16:[function(_dereq_,module,exports){
2958
2959/**
2960 * Gets the keys for an object.
2961 *
2962 * @return {Array} keys
2963 * @api private
2964 */
2965
2966module.exports = Object.keys || function keys (obj){
2967  var arr = [];
2968  var has = Object.prototype.hasOwnProperty;
2969
2970  for (var i in obj) {
2971    if (has.call(obj, i)) {
2972      arr.push(i);
2973    }
2974  }
2975  return arr;
2976};
2977
2978},{}],17:[function(_dereq_,module,exports){
2979module.exports = after
2980
2981function after(count, callback, err_cb) {
2982    var bail = false
2983    err_cb = err_cb || noop
2984    proxy.count = count
2985
2986    return (count === 0) ? callback() : proxy
2987
2988    function proxy(err, result) {
2989        if (proxy.count <= 0) {
2990            throw new Error('after called too many times')
2991        }
2992        --proxy.count
2993
2994        // after first error, rest are passed to err_cb
2995        if (err) {
2996            bail = true
2997            callback(err)
2998            // future error callbacks will go to error handler
2999            callback = err_cb
3000        } else if (proxy.count === 0 && !bail) {
3001            callback(null, result)
3002        }
3003    }
3004}
3005
3006function noop() {}
3007
3008},{}],18:[function(_dereq_,module,exports){
3009/**
3010 * An abstraction for slicing an arraybuffer even when
3011 * ArrayBuffer.prototype.slice is not supported
3012 *
3013 * @api public
3014 */
3015
3016module.exports = function(arraybuffer, start, end) {
3017  var bytes = arraybuffer.byteLength;
3018  start = start || 0;
3019  end = end || bytes;
3020
3021  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
3022
3023  if (start < 0) { start += bytes; }
3024  if (end < 0) { end += bytes; }
3025  if (end > bytes) { end = bytes; }
3026
3027  if (start >= bytes || start >= end || bytes === 0) {
3028    return new ArrayBuffer(0);
3029  }
3030
3031  var abv = new Uint8Array(arraybuffer);
3032  var result = new Uint8Array(end - start);
3033  for (var i = start, ii = 0; i < end; i++, ii++) {
3034    result[ii] = abv[i];
3035  }
3036  return result.buffer;
3037};
3038
3039},{}],19:[function(_dereq_,module,exports){
3040/*
3041 * base64-arraybuffer
3042 * https://github.com/niklasvh/base64-arraybuffer
3043 *
3044 * Copyright (c) 2012 Niklas von Hertzen
3045 * Licensed under the MIT license.
3046 */
3047(function(chars){
3048  "use strict";
3049
3050  exports.encode = function(arraybuffer) {
3051    var bytes = new Uint8Array(arraybuffer),
3052    i, len = bytes.length, base64 = "";
3053
3054    for (i = 0; i < len; i+=3) {
3055      base64 += chars[bytes[i] >> 2];
3056      base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
3057      base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
3058      base64 += chars[bytes[i + 2] & 63];
3059    }
3060
3061    if ((len % 3) === 2) {
3062      base64 = base64.substring(0, base64.length - 1) + "=";
3063    } else if (len % 3 === 1) {
3064      base64 = base64.substring(0, base64.length - 2) + "==";
3065    }
3066
3067    return base64;
3068  };
3069
3070  exports.decode =  function(base64) {
3071    var bufferLength = base64.length * 0.75,
3072    len = base64.length, i, p = 0,
3073    encoded1, encoded2, encoded3, encoded4;
3074
3075    if (base64[base64.length - 1] === "=") {
3076      bufferLength--;
3077      if (base64[base64.length - 2] === "=") {
3078        bufferLength--;
3079      }
3080    }
3081
3082    var arraybuffer = new ArrayBuffer(bufferLength),
3083    bytes = new Uint8Array(arraybuffer);
3084
3085    for (i = 0; i < len; i+=4) {
3086      encoded1 = chars.indexOf(base64[i]);
3087      encoded2 = chars.indexOf(base64[i+1]);
3088      encoded3 = chars.indexOf(base64[i+2]);
3089      encoded4 = chars.indexOf(base64[i+3]);
3090
3091      bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
3092      bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
3093      bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
3094    }
3095
3096    return arraybuffer;
3097  };
3098})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
3099
3100},{}],20:[function(_dereq_,module,exports){
3101(function (global){
3102/*! http://mths.be/utf8js v2.0.0 by @mathias */
3103;(function(root) {
3104
3105	// Detect free variables `exports`
3106	var freeExports = typeof exports == 'object' && exports;
3107
3108	// Detect free variable `module`
3109	var freeModule = typeof module == 'object' && module &&
3110		module.exports == freeExports && module;
3111
3112	// Detect free variable `global`, from Node.js or Browserified code,
3113	// and use it as `root`
3114	var freeGlobal = typeof global == 'object' && global;
3115	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
3116		root = freeGlobal;
3117	}
3118
3119	/*--------------------------------------------------------------------------*/
3120
3121	var stringFromCharCode = String.fromCharCode;
3122
3123	// Taken from http://mths.be/punycode
3124	function ucs2decode(string) {
3125		var output = [];
3126		var counter = 0;
3127		var length = string.length;
3128		var value;
3129		var extra;
3130		while (counter < length) {
3131			value = string.charCodeAt(counter++);
3132			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
3133				// high surrogate, and there is a next character
3134				extra = string.charCodeAt(counter++);
3135				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
3136					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
3137				} else {
3138					// unmatched surrogate; only append this code unit, in case the next
3139					// code unit is the high surrogate of a surrogate pair
3140					output.push(value);
3141					counter--;
3142				}
3143			} else {
3144				output.push(value);
3145			}
3146		}
3147		return output;
3148	}
3149
3150	// Taken from http://mths.be/punycode
3151	function ucs2encode(array) {
3152		var length = array.length;
3153		var index = -1;
3154		var value;
3155		var output = '';
3156		while (++index < length) {
3157			value = array[index];
3158			if (value > 0xFFFF) {
3159				value -= 0x10000;
3160				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
3161				value = 0xDC00 | value & 0x3FF;
3162			}
3163			output += stringFromCharCode(value);
3164		}
3165		return output;
3166	}
3167
3168	/*--------------------------------------------------------------------------*/
3169
3170	function createByte(codePoint, shift) {
3171		return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
3172	}
3173
3174	function encodeCodePoint(codePoint) {
3175		if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
3176			return stringFromCharCode(codePoint);
3177		}
3178		var symbol = '';
3179		if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
3180			symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
3181		}
3182		else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
3183			symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
3184			symbol += createByte(codePoint, 6);
3185		}
3186		else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
3187			symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
3188			symbol += createByte(codePoint, 12);
3189			symbol += createByte(codePoint, 6);
3190		}
3191		symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
3192		return symbol;
3193	}
3194
3195	function utf8encode(string) {
3196		var codePoints = ucs2decode(string);
3197
3198		// console.log(JSON.stringify(codePoints.map(function(x) {
3199		// 	return 'U+' + x.toString(16).toUpperCase();
3200		// })));
3201
3202		var length = codePoints.length;
3203		var index = -1;
3204		var codePoint;
3205		var byteString = '';
3206		while (++index < length) {
3207			codePoint = codePoints[index];
3208			byteString += encodeCodePoint(codePoint);
3209		}
3210		return byteString;
3211	}
3212
3213	/*--------------------------------------------------------------------------*/
3214
3215	function readContinuationByte() {
3216		if (byteIndex >= byteCount) {
3217			throw Error('Invalid byte index');
3218		}
3219
3220		var continuationByte = byteArray[byteIndex] & 0xFF;
3221		byteIndex++;
3222
3223		if ((continuationByte & 0xC0) == 0x80) {
3224			return continuationByte & 0x3F;
3225		}
3226
3227		// If we end up here, it’s not a continuation byte
3228		throw Error('Invalid continuation byte');
3229	}
3230
3231	function decodeSymbol() {
3232		var byte1;
3233		var byte2;
3234		var byte3;
3235		var byte4;
3236		var codePoint;
3237
3238		if (byteIndex > byteCount) {
3239			throw Error('Invalid byte index');
3240		}
3241
3242		if (byteIndex == byteCount) {
3243			return false;
3244		}
3245
3246		// Read first byte
3247		byte1 = byteArray[byteIndex] & 0xFF;
3248		byteIndex++;
3249
3250		// 1-byte sequence (no continuation bytes)
3251		if ((byte1 & 0x80) == 0) {
3252			return byte1;
3253		}
3254
3255		// 2-byte sequence
3256		if ((byte1 & 0xE0) == 0xC0) {
3257			var byte2 = readContinuationByte();
3258			codePoint = ((byte1 & 0x1F) << 6) | byte2;
3259			if (codePoint >= 0x80) {
3260				return codePoint;
3261			} else {
3262				throw Error('Invalid continuation byte');
3263			}
3264		}
3265
3266		// 3-byte sequence (may include unpaired surrogates)
3267		if ((byte1 & 0xF0) == 0xE0) {
3268			byte2 = readContinuationByte();
3269			byte3 = readContinuationByte();
3270			codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
3271			if (codePoint >= 0x0800) {
3272				return codePoint;
3273			} else {
3274				throw Error('Invalid continuation byte');
3275			}
3276		}
3277
3278		// 4-byte sequence
3279		if ((byte1 & 0xF8) == 0xF0) {
3280			byte2 = readContinuationByte();
3281			byte3 = readContinuationByte();
3282			byte4 = readContinuationByte();
3283			codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
3284				(byte3 << 0x06) | byte4;
3285			if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
3286				return codePoint;
3287			}
3288		}
3289
3290		throw Error('Invalid UTF-8 detected');
3291	}
3292
3293	var byteArray;
3294	var byteCount;
3295	var byteIndex;
3296	function utf8decode(byteString) {
3297		byteArray = ucs2decode(byteString);
3298		byteCount = byteArray.length;
3299		byteIndex = 0;
3300		var codePoints = [];
3301		var tmp;
3302		while ((tmp = decodeSymbol()) !== false) {
3303			codePoints.push(tmp);
3304		}
3305		return ucs2encode(codePoints);
3306	}
3307
3308	/*--------------------------------------------------------------------------*/
3309
3310	var utf8 = {
3311		'version': '2.0.0',
3312		'encode': utf8encode,
3313		'decode': utf8decode
3314	};
3315
3316	// Some AMD build optimizers, like r.js, check for specific condition patterns
3317	// like the following:
3318	if (
3319		typeof define == 'function' &&
3320		typeof define.amd == 'object' &&
3321		define.amd
3322	) {
3323		define(function() {
3324			return utf8;
3325		});
3326	}	else if (freeExports && !freeExports.nodeType) {
3327		if (freeModule) { // in Node.js or RingoJS v0.8.0+
3328			freeModule.exports = utf8;
3329		} else { // in Narwhal or RingoJS v0.7.0-
3330			var object = {};
3331			var hasOwnProperty = object.hasOwnProperty;
3332			for (var key in utf8) {
3333				hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
3334			}
3335		}
3336	} else { // in Rhino or a web browser
3337		root.utf8 = utf8;
3338	}
3339
3340}(this));
3341
3342}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3343},{}],21:[function(_dereq_,module,exports){
3344
3345/**
3346 * Module dependencies.
3347 */
3348
3349var global = _dereq_('global');
3350
3351/**
3352 * Module exports.
3353 *
3354 * Logic borrowed from Modernizr:
3355 *
3356 *   - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
3357 */
3358
3359try {
3360  module.exports = 'XMLHttpRequest' in global &&
3361    'withCredentials' in new global.XMLHttpRequest();
3362} catch (err) {
3363  // if XMLHttp support is disabled in IE then it will throw
3364  // when trying to create
3365  module.exports = false;
3366}
3367
3368},{"global":22}],22:[function(_dereq_,module,exports){
3369
3370/**
3371 * Returns `this`. Execute this without a "context" (i.e. without it being
3372 * attached to an object of the left-hand side), and `this` points to the
3373 * "global" scope of the current JS execution.
3374 */
3375
3376module.exports = (function () { return this; })();
3377
3378},{}],23:[function(_dereq_,module,exports){
3379
3380var indexOf = [].indexOf;
3381
3382module.exports = function(arr, obj){
3383  if (indexOf) return arr.indexOf(obj);
3384  for (var i = 0; i < arr.length; ++i) {
3385    if (arr[i] === obj) return i;
3386  }
3387  return -1;
3388};
3389},{}],24:[function(_dereq_,module,exports){
3390(function (global){
3391/**
3392 * JSON parse.
3393 *
3394 * @see Based on jQuery#parseJSON (MIT) and JSON2
3395 * @api private
3396 */
3397
3398var rvalidchars = /^[\],:{}\s]*$/;
3399var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
3400var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
3401var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
3402var rtrimLeft = /^\s+/;
3403var rtrimRight = /\s+$/;
3404
3405module.exports = function parsejson(data) {
3406  if ('string' != typeof data || !data) {
3407    return null;
3408  }
3409
3410  data = data.replace(rtrimLeft, '').replace(rtrimRight, '');
3411
3412  // Attempt to parse using the native JSON parser first
3413  if (global.JSON && JSON.parse) {
3414    return JSON.parse(data);
3415  }
3416
3417  if (rvalidchars.test(data.replace(rvalidescape, '@')
3418      .replace(rvalidtokens, ']')
3419      .replace(rvalidbraces, ''))) {
3420    return (new Function('return ' + data))();
3421  }
3422};
3423}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3424},{}],25:[function(_dereq_,module,exports){
3425/**
3426 * Compiles a querystring
3427 * Returns string representation of the object
3428 *
3429 * @param {Object}
3430 * @api private
3431 */
3432
3433exports.encode = function (obj) {
3434  var str = '';
3435
3436  for (var i in obj) {
3437    if (obj.hasOwnProperty(i)) {
3438      if (str.length) str += '&';
3439      str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
3440    }
3441  }
3442
3443  return str;
3444};
3445
3446/**
3447 * Parses a simple querystring into an object
3448 *
3449 * @param {String} qs
3450 * @api private
3451 */
3452
3453exports.decode = function(qs){
3454  var qry = {};
3455  var pairs = qs.split('&');
3456  for (var i = 0, l = pairs.length; i < l; i++) {
3457    var pair = pairs[i].split('=');
3458    qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
3459  }
3460  return qry;
3461};
3462
3463},{}],26:[function(_dereq_,module,exports){
3464/**
3465 * Parses an URI
3466 *
3467 * @author Steven Levithan <stevenlevithan.com> (MIT license)
3468 * @api private
3469 */
3470
3471var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
3472
3473var parts = [
3474    'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
3475];
3476
3477module.exports = function parseuri(str) {
3478    var src = str,
3479        b = str.indexOf('['),
3480        e = str.indexOf(']');
3481
3482    if (b != -1 && e != -1) {
3483        str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
3484    }
3485
3486    var m = re.exec(str || ''),
3487        uri = {},
3488        i = 14;
3489
3490    while (i--) {
3491        uri[parts[i]] = m[i] || '';
3492    }
3493
3494    if (b != -1 && e != -1) {
3495        uri.source = src;
3496        uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
3497        uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
3498        uri.ipv6uri = true;
3499    }
3500
3501    return uri;
3502};
3503
3504},{}],27:[function(_dereq_,module,exports){
3505
3506/**
3507 * Module dependencies.
3508 */
3509
3510var global = (function() { return this; })();
3511
3512/**
3513 * WebSocket constructor.
3514 */
3515
3516var WebSocket = global.WebSocket || global.MozWebSocket;
3517
3518/**
3519 * Module exports.
3520 */
3521
3522module.exports = WebSocket ? ws : null;
3523
3524/**
3525 * WebSocket constructor.
3526 *
3527 * The third `opts` options object gets ignored in web browsers, since it's
3528 * non-standard, and throws a TypeError if passed to the constructor.
3529 * See: https://github.com/einaros/ws/issues/227
3530 *
3531 * @param {String} uri
3532 * @param {Array} protocols (optional)
3533 * @param {Object) opts (optional)
3534 * @api public
3535 */
3536
3537function ws(uri, protocols, opts) {
3538  var instance;
3539  if (protocols) {
3540    instance = new WebSocket(uri, protocols);
3541  } else {
3542    instance = new WebSocket(uri);
3543  }
3544  return instance;
3545}
3546
3547if (WebSocket) ws.prototype = WebSocket.prototype;
3548
3549},{}]},{},[1])
3550(1)
3551});