PageRenderTime 96ms CodeModel.GetById 7ms app.highlight 65ms RepoModel.GetById 1ms app.codeStats 2ms

/htdocs/assets/js/socket.io.js

https://github.com/FreePBX/ucp
JavaScript | 6193 lines | 3499 code | 956 blank | 1738 comment | 992 complexity | a561e9cf505224b56d5495169cbd33ed MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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.io=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
   7/**
   8 * Module dependencies.
   9 */
  10
  11var url = _dereq_('./url');
  12var parser = _dereq_('socket.io-parser');
  13var Manager = _dereq_('./manager');
  14var debug = _dereq_('debug')('socket.io-client');
  15
  16/**
  17 * Module exports.
  18 */
  19
  20module.exports = exports = lookup;
  21
  22/**
  23 * Managers cache.
  24 */
  25
  26var cache = exports.managers = {};
  27
  28/**
  29 * Looks up an existing `Manager` for multiplexing.
  30 * If the user summons:
  31 *
  32 *   `io('http://localhost/a');`
  33 *   `io('http://localhost/b');`
  34 *
  35 * We reuse the existing instance based on same scheme/port/host,
  36 * and we initialize sockets for each namespace.
  37 *
  38 * @api public
  39 */
  40
  41function lookup(uri, opts) {
  42  if (typeof uri == 'object') {
  43    opts = uri;
  44    uri = undefined;
  45  }
  46
  47  opts = opts || {};
  48
  49  var parsed = url(uri);
  50  var source = parsed.source;
  51  var id = parsed.id;
  52  var io;
  53
  54  if (opts.forceNew || opts['force new connection'] || false === opts.multiplex) {
  55    debug('ignoring socket cache for %s', source);
  56    io = Manager(source, opts);
  57  } else {
  58    if (!cache[id]) {
  59      debug('new io instance for %s', source);
  60      cache[id] = Manager(source, opts);
  61    }
  62    io = cache[id];
  63  }
  64
  65  return io.socket(parsed.path);
  66}
  67
  68/**
  69 * Protocol version.
  70 *
  71 * @api public
  72 */
  73
  74exports.protocol = parser.protocol;
  75
  76/**
  77 * `connect`.
  78 *
  79 * @param {String} uri
  80 * @api public
  81 */
  82
  83exports.connect = lookup;
  84
  85/**
  86 * Expose constructors for standalone build.
  87 *
  88 * @api public
  89 */
  90
  91exports.Manager = _dereq_('./manager');
  92exports.Socket = _dereq_('./socket');
  93
  94},{"./manager":3,"./socket":5,"./url":6,"debug":9,"socket.io-parser":40}],3:[function(_dereq_,module,exports){
  95
  96/**
  97 * Module dependencies.
  98 */
  99
 100var url = _dereq_('./url');
 101var eio = _dereq_('engine.io-client');
 102var Socket = _dereq_('./socket');
 103var Emitter = _dereq_('component-emitter');
 104var parser = _dereq_('socket.io-parser');
 105var on = _dereq_('./on');
 106var bind = _dereq_('component-bind');
 107var object = _dereq_('object-component');
 108var debug = _dereq_('debug')('socket.io-client:manager');
 109
 110/**
 111 * Module exports
 112 */
 113
 114module.exports = Manager;
 115
 116/**
 117 * `Manager` constructor.
 118 *
 119 * @param {String} engine instance or engine uri/opts
 120 * @param {Object} options
 121 * @api public
 122 */
 123
 124function Manager(uri, opts){
 125  if (!(this instanceof Manager)) return new Manager(uri, opts);
 126  if (uri && ('object' == typeof uri)) {
 127    opts = uri;
 128    uri = undefined;
 129  }
 130  opts = opts || {};
 131
 132  opts.path = opts.path || '/socket.io';
 133  this.nsps = {};
 134  this.subs = [];
 135  this.opts = opts;
 136  this.reconnection(opts.reconnection !== false);
 137  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
 138  this.reconnectionDelay(opts.reconnectionDelay || 1000);
 139  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
 140  this.timeout(null == opts.timeout ? 20000 : opts.timeout);
 141  this.readyState = 'closed';
 142  this.uri = uri;
 143  this.connected = 0;
 144  this.attempts = 0;
 145  this.encoding = false;
 146  this.packetBuffer = [];
 147  this.encoder = new parser.Encoder();
 148  this.decoder = new parser.Decoder();
 149  this.autoConnect = opts.autoConnect !== false;
 150  if (this.autoConnect) this.open();
 151}
 152
 153/**
 154 * Propagate given event to sockets and emit on `this`
 155 *
 156 * @api private
 157 */
 158
 159Manager.prototype.emitAll = function() {
 160  this.emit.apply(this, arguments);
 161  for (var nsp in this.nsps) {
 162    this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
 163  }
 164};
 165
 166/**
 167 * Mix in `Emitter`.
 168 */
 169
 170Emitter(Manager.prototype);
 171
 172/**
 173 * Sets the `reconnection` config.
 174 *
 175 * @param {Boolean} true/false if it should automatically reconnect
 176 * @return {Manager} self or value
 177 * @api public
 178 */
 179
 180Manager.prototype.reconnection = function(v){
 181  if (!arguments.length) return this._reconnection;
 182  this._reconnection = !!v;
 183  return this;
 184};
 185
 186/**
 187 * Sets the reconnection attempts config.
 188 *
 189 * @param {Number} max reconnection attempts before giving up
 190 * @return {Manager} self or value
 191 * @api public
 192 */
 193
 194Manager.prototype.reconnectionAttempts = function(v){
 195  if (!arguments.length) return this._reconnectionAttempts;
 196  this._reconnectionAttempts = v;
 197  return this;
 198};
 199
 200/**
 201 * Sets the delay between reconnections.
 202 *
 203 * @param {Number} delay
 204 * @return {Manager} self or value
 205 * @api public
 206 */
 207
 208Manager.prototype.reconnectionDelay = function(v){
 209  if (!arguments.length) return this._reconnectionDelay;
 210  this._reconnectionDelay = v;
 211  return this;
 212};
 213
 214/**
 215 * Sets the maximum delay between reconnections.
 216 *
 217 * @param {Number} delay
 218 * @return {Manager} self or value
 219 * @api public
 220 */
 221
 222Manager.prototype.reconnectionDelayMax = function(v){
 223  if (!arguments.length) return this._reconnectionDelayMax;
 224  this._reconnectionDelayMax = v;
 225  return this;
 226};
 227
 228/**
 229 * Sets the connection timeout. `false` to disable
 230 *
 231 * @return {Manager} self or value
 232 * @api public
 233 */
 234
 235Manager.prototype.timeout = function(v){
 236  if (!arguments.length) return this._timeout;
 237  this._timeout = v;
 238  return this;
 239};
 240
 241/**
 242 * Starts trying to reconnect if reconnection is enabled and we have not
 243 * started reconnecting yet
 244 *
 245 * @api private
 246 */
 247
 248Manager.prototype.maybeReconnectOnOpen = function() {
 249  // Only try to reconnect if it's the first time we're connecting
 250  if (!this.openReconnect && !this.reconnecting && this._reconnection && this.attempts === 0) {
 251    // keeps reconnection from firing twice for the same reconnection loop
 252    this.openReconnect = true;
 253    this.reconnect();
 254  }
 255};
 256
 257
 258/**
 259 * Sets the current transport `socket`.
 260 *
 261 * @param {Function} optional, callback
 262 * @return {Manager} self
 263 * @api public
 264 */
 265
 266Manager.prototype.open =
 267Manager.prototype.connect = function(fn){
 268  debug('readyState %s', this.readyState);
 269  if (~this.readyState.indexOf('open')) return this;
 270
 271  debug('opening %s', this.uri);
 272  this.engine = eio(this.uri, this.opts);
 273  var socket = this.engine;
 274  var self = this;
 275  this.readyState = 'opening';
 276
 277  // emit `open`
 278  var openSub = on(socket, 'open', function() {
 279    self.onopen();
 280    fn && fn();
 281  });
 282
 283  // emit `connect_error`
 284  var errorSub = on(socket, 'error', function(data){
 285    debug('connect_error');
 286    self.cleanup();
 287    self.readyState = 'closed';
 288    self.emitAll('connect_error', data);
 289    if (fn) {
 290      var err = new Error('Connection error');
 291      err.data = data;
 292      fn(err);
 293    }
 294
 295    self.maybeReconnectOnOpen();
 296  });
 297
 298  // emit `connect_timeout`
 299  if (false !== this._timeout) {
 300    var timeout = this._timeout;
 301    debug('connect attempt will timeout after %d', timeout);
 302
 303    // set timer
 304    var timer = setTimeout(function(){
 305      debug('connect attempt timed out after %d', timeout);
 306      openSub.destroy();
 307      socket.close();
 308      socket.emit('error', 'timeout');
 309      self.emitAll('connect_timeout', timeout);
 310    }, timeout);
 311
 312    this.subs.push({
 313      destroy: function(){
 314        clearTimeout(timer);
 315      }
 316    });
 317  }
 318
 319  this.subs.push(openSub);
 320  this.subs.push(errorSub);
 321
 322  return this;
 323};
 324
 325/**
 326 * Called upon transport open.
 327 *
 328 * @api private
 329 */
 330
 331Manager.prototype.onopen = function(){
 332  debug('open');
 333
 334  // clear old subs
 335  this.cleanup();
 336
 337  // mark as open
 338  this.readyState = 'open';
 339  this.emit('open');
 340
 341  // add new subs
 342  var socket = this.engine;
 343  this.subs.push(on(socket, 'data', bind(this, 'ondata')));
 344  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
 345  this.subs.push(on(socket, 'error', bind(this, 'onerror')));
 346  this.subs.push(on(socket, 'close', bind(this, 'onclose')));
 347};
 348
 349/**
 350 * Called with data.
 351 *
 352 * @api private
 353 */
 354
 355Manager.prototype.ondata = function(data){
 356  this.decoder.add(data);
 357};
 358
 359/**
 360 * Called when parser fully decodes a packet.
 361 *
 362 * @api private
 363 */
 364
 365Manager.prototype.ondecoded = function(packet) {
 366  this.emit('packet', packet);
 367};
 368
 369/**
 370 * Called upon socket error.
 371 *
 372 * @api private
 373 */
 374
 375Manager.prototype.onerror = function(err){
 376  debug('error', err);
 377  this.emitAll('error', err);
 378};
 379
 380/**
 381 * Creates a new socket for the given `nsp`.
 382 *
 383 * @return {Socket}
 384 * @api public
 385 */
 386
 387Manager.prototype.socket = function(nsp){
 388  var socket = this.nsps[nsp];
 389  if (!socket) {
 390    socket = new Socket(this, nsp);
 391    this.nsps[nsp] = socket;
 392    var self = this;
 393    socket.on('connect', function(){
 394      self.connected++;
 395    });
 396  }
 397  return socket;
 398};
 399
 400/**
 401 * Called upon a socket close.
 402 *
 403 * @param {Socket} socket
 404 */
 405
 406Manager.prototype.destroy = function(socket){
 407  --this.connected || this.close();
 408};
 409
 410/**
 411 * Writes a packet.
 412 *
 413 * @param {Object} packet
 414 * @api private
 415 */
 416
 417Manager.prototype.packet = function(packet){
 418  debug('writing packet %j', packet);
 419  var self = this;
 420
 421  if (!self.encoding) {
 422    // encode, then write to engine with result
 423    self.encoding = true;
 424    this.encoder.encode(packet, function(encodedPackets) {
 425      for (var i = 0; i < encodedPackets.length; i++) {
 426        self.engine.write(encodedPackets[i]);
 427      }
 428      self.encoding = false;
 429      self.processPacketQueue();
 430    });
 431  } else { // add packet to the queue
 432    self.packetBuffer.push(packet);
 433  }
 434};
 435
 436/**
 437 * If packet buffer is non-empty, begins encoding the
 438 * next packet in line.
 439 *
 440 * @api private
 441 */
 442
 443Manager.prototype.processPacketQueue = function() {
 444  if (this.packetBuffer.length > 0 && !this.encoding) {
 445    var pack = this.packetBuffer.shift();
 446    this.packet(pack);
 447  }
 448};
 449
 450/**
 451 * Clean up transport subscriptions and packet buffer.
 452 *
 453 * @api private
 454 */
 455
 456Manager.prototype.cleanup = function(){
 457  var sub;
 458  while (sub = this.subs.shift()) sub.destroy();
 459
 460  this.packetBuffer = [];
 461  this.encoding = false;
 462
 463  this.decoder.destroy();
 464};
 465
 466/**
 467 * Close the current socket.
 468 *
 469 * @api private
 470 */
 471
 472Manager.prototype.close =
 473Manager.prototype.disconnect = function(){
 474  this.skipReconnect = true;
 475  this.engine.close();
 476};
 477
 478/**
 479 * Called upon engine close.
 480 *
 481 * @api private
 482 */
 483
 484Manager.prototype.onclose = function(reason){
 485  debug('close');
 486  this.cleanup();
 487  this.readyState = 'closed';
 488  this.emit('close', reason);
 489  if (this._reconnection && !this.skipReconnect) {
 490    this.reconnect();
 491  }
 492};
 493
 494/**
 495 * Attempt a reconnection.
 496 *
 497 * @api private
 498 */
 499
 500Manager.prototype.reconnect = function(){
 501  if (this.reconnecting) return this;
 502
 503  var self = this;
 504  this.attempts++;
 505
 506  if (this.attempts > this._reconnectionAttempts) {
 507    debug('reconnect failed');
 508    this.emitAll('reconnect_failed');
 509    this.reconnecting = false;
 510  } else {
 511    var delay = this.attempts * this.reconnectionDelay();
 512    delay = Math.min(delay, this.reconnectionDelayMax());
 513    debug('will wait %dms before reconnect attempt', delay);
 514
 515    this.reconnecting = true;
 516    var timer = setTimeout(function(){
 517      debug('attempting reconnect');
 518      self.emitAll('reconnect_attempt', self.attempts);
 519      self.emitAll('reconnecting', self.attempts);
 520      self.open(function(err){
 521        if (err) {
 522          debug('reconnect attempt error');
 523          self.reconnecting = false;
 524          self.reconnect();
 525          self.emitAll('reconnect_error', err.data);
 526        } else {
 527          debug('reconnect success');
 528          self.onreconnect();
 529        }
 530      });
 531    }, delay);
 532
 533    this.subs.push({
 534      destroy: function(){
 535        clearTimeout(timer);
 536      }
 537    });
 538  }
 539};
 540
 541/**
 542 * Called upon successful reconnect.
 543 *
 544 * @api private
 545 */
 546
 547Manager.prototype.onreconnect = function(){
 548  var attempt = this.attempts;
 549  this.attempts = 0;
 550  this.reconnecting = false;
 551  this.emitAll('reconnect', attempt);
 552};
 553
 554},{"./on":4,"./socket":5,"./url":6,"component-bind":7,"component-emitter":8,"debug":9,"engine.io-client":10,"object-component":37,"socket.io-parser":40}],4:[function(_dereq_,module,exports){
 555
 556/**
 557 * Module exports.
 558 */
 559
 560module.exports = on;
 561
 562/**
 563 * Helper for subscriptions.
 564 *
 565 * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
 566 * @param {String} event name
 567 * @param {Function} callback
 568 * @api public
 569 */
 570
 571function on(obj, ev, fn) {
 572  obj.on(ev, fn);
 573  return {
 574    destroy: function(){
 575      obj.removeListener(ev, fn);
 576    }
 577  };
 578}
 579
 580},{}],5:[function(_dereq_,module,exports){
 581
 582/**
 583 * Module dependencies.
 584 */
 585
 586var parser = _dereq_('socket.io-parser');
 587var Emitter = _dereq_('component-emitter');
 588var toArray = _dereq_('to-array');
 589var on = _dereq_('./on');
 590var bind = _dereq_('component-bind');
 591var debug = _dereq_('debug')('socket.io-client:socket');
 592var hasBin = _dereq_('has-binary');
 593var indexOf = _dereq_('indexof');
 594
 595/**
 596 * Module exports.
 597 */
 598
 599module.exports = exports = Socket;
 600
 601/**
 602 * Internal events (blacklisted).
 603 * These events can't be emitted by the user.
 604 *
 605 * @api private
 606 */
 607
 608var events = {
 609  connect: 1,
 610  connect_error: 1,
 611  connect_timeout: 1,
 612  disconnect: 1,
 613  error: 1,
 614  reconnect: 1,
 615  reconnect_attempt: 1,
 616  reconnect_failed: 1,
 617  reconnect_error: 1,
 618  reconnecting: 1
 619};
 620
 621/**
 622 * Shortcut to `Emitter#emit`.
 623 */
 624
 625var emit = Emitter.prototype.emit;
 626
 627/**
 628 * `Socket` constructor.
 629 *
 630 * @api public
 631 */
 632
 633function Socket(io, nsp){
 634  this.io = io;
 635  this.nsp = nsp;
 636  this.json = this; // compat
 637  this.ids = 0;
 638  this.acks = {};
 639  if (this.io.autoConnect) this.open();
 640  this.receiveBuffer = [];
 641  this.sendBuffer = [];
 642  this.connected = false;
 643  this.disconnected = true;
 644  this.subEvents();
 645}
 646
 647/**
 648 * Mix in `Emitter`.
 649 */
 650
 651Emitter(Socket.prototype);
 652
 653/**
 654 * Subscribe to open, close and packet events
 655 *
 656 * @api private
 657 */
 658
 659Socket.prototype.subEvents = function() {
 660  var io = this.io;
 661  this.subs = [
 662    on(io, 'open', bind(this, 'onopen')),
 663    on(io, 'packet', bind(this, 'onpacket')),
 664    on(io, 'close', bind(this, 'onclose'))
 665  ];
 666};
 667
 668/**
 669 * Called upon engine `open`.
 670 *
 671 * @api private
 672 */
 673
 674Socket.prototype.open =
 675Socket.prototype.connect = function(){
 676  if (this.connected) return this;
 677
 678  this.io.open(); // ensure open
 679  if ('open' == this.io.readyState) this.onopen();
 680  return this;
 681};
 682
 683/**
 684 * Sends a `message` event.
 685 *
 686 * @return {Socket} self
 687 * @api public
 688 */
 689
 690Socket.prototype.send = function(){
 691  var args = toArray(arguments);
 692  args.unshift('message');
 693  this.emit.apply(this, args);
 694  return this;
 695};
 696
 697/**
 698 * Override `emit`.
 699 * If the event is in `events`, it's emitted normally.
 700 *
 701 * @param {String} event name
 702 * @return {Socket} self
 703 * @api public
 704 */
 705
 706Socket.prototype.emit = function(ev){
 707  if (events.hasOwnProperty(ev)) {
 708    emit.apply(this, arguments);
 709    return this;
 710  }
 711
 712  var args = toArray(arguments);
 713  var parserType = parser.EVENT; // default
 714  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
 715  var packet = { type: parserType, data: args };
 716
 717  // event ack callback
 718  if ('function' == typeof args[args.length - 1]) {
 719    debug('emitting packet with ack id %d', this.ids);
 720    this.acks[this.ids] = args.pop();
 721    packet.id = this.ids++;
 722  }
 723
 724  if (this.connected) {
 725    this.packet(packet);
 726  } else {
 727    this.sendBuffer.push(packet);
 728  }
 729
 730  return this;
 731};
 732
 733/**
 734 * Sends a packet.
 735 *
 736 * @param {Object} packet
 737 * @api private
 738 */
 739
 740Socket.prototype.packet = function(packet){
 741  packet.nsp = this.nsp;
 742  this.io.packet(packet);
 743};
 744
 745/**
 746 * "Opens" the socket.
 747 *
 748 * @api private
 749 */
 750
 751Socket.prototype.onopen = function(){
 752  debug('transport is open - connecting');
 753
 754  // write connect packet if necessary
 755  if ('/' != this.nsp) {
 756    this.packet({ type: parser.CONNECT });
 757  }
 758};
 759
 760/**
 761 * Called upon engine `close`.
 762 *
 763 * @param {String} reason
 764 * @api private
 765 */
 766
 767Socket.prototype.onclose = function(reason){
 768  debug('close (%s)', reason);
 769  this.connected = false;
 770  this.disconnected = true;
 771  this.emit('disconnect', reason);
 772};
 773
 774/**
 775 * Called with socket packet.
 776 *
 777 * @param {Object} packet
 778 * @api private
 779 */
 780
 781Socket.prototype.onpacket = function(packet){
 782  if (packet.nsp != this.nsp) return;
 783
 784  switch (packet.type) {
 785    case parser.CONNECT:
 786      this.onconnect();
 787      break;
 788
 789    case parser.EVENT:
 790      this.onevent(packet);
 791      break;
 792
 793    case parser.BINARY_EVENT:
 794      this.onevent(packet);
 795      break;
 796
 797    case parser.ACK:
 798      this.onack(packet);
 799      break;
 800
 801    case parser.BINARY_ACK:
 802      this.onack(packet);
 803      break;
 804
 805    case parser.DISCONNECT:
 806      this.ondisconnect();
 807      break;
 808
 809    case parser.ERROR:
 810      this.emit('error', packet.data);
 811      break;
 812  }
 813};
 814
 815/**
 816 * Called upon a server event.
 817 *
 818 * @param {Object} packet
 819 * @api private
 820 */
 821
 822Socket.prototype.onevent = function(packet){
 823  var args = packet.data || [];
 824  debug('emitting event %j', args);
 825
 826  if (null != packet.id) {
 827    debug('attaching ack callback to event');
 828    args.push(this.ack(packet.id));
 829  }
 830
 831  if (this.connected) {
 832    emit.apply(this, args);
 833  } else {
 834    this.receiveBuffer.push(args);
 835  }
 836};
 837
 838/**
 839 * Produces an ack callback to emit with an event.
 840 *
 841 * @api private
 842 */
 843
 844Socket.prototype.ack = function(id){
 845  var self = this;
 846  var sent = false;
 847  return function(){
 848    // prevent double callbacks
 849    if (sent) return;
 850    sent = true;
 851    var args = toArray(arguments);
 852    debug('sending ack %j', args);
 853
 854    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
 855    self.packet({
 856      type: type,
 857      id: id,
 858      data: args
 859    });
 860  };
 861};
 862
 863/**
 864 * Called upon a server acknowlegement.
 865 *
 866 * @param {Object} packet
 867 * @api private
 868 */
 869
 870Socket.prototype.onack = function(packet){
 871  debug('calling ack %s with %j', packet.id, packet.data);
 872  var fn = this.acks[packet.id];
 873  fn.apply(this, packet.data);
 874  delete this.acks[packet.id];
 875};
 876
 877/**
 878 * Called upon server connect.
 879 *
 880 * @api private
 881 */
 882
 883Socket.prototype.onconnect = function(){
 884  this.connected = true;
 885  this.disconnected = false;
 886  this.emit('connect');
 887  this.emitBuffered();
 888};
 889
 890/**
 891 * Emit buffered events (received and emitted).
 892 *
 893 * @api private
 894 */
 895
 896Socket.prototype.emitBuffered = function(){
 897  var i;
 898  for (i = 0; i < this.receiveBuffer.length; i++) {
 899    emit.apply(this, this.receiveBuffer[i]);
 900  }
 901  this.receiveBuffer = [];
 902
 903  for (i = 0; i < this.sendBuffer.length; i++) {
 904    this.packet(this.sendBuffer[i]);
 905  }
 906  this.sendBuffer = [];
 907};
 908
 909/**
 910 * Called upon server disconnect.
 911 *
 912 * @api private
 913 */
 914
 915Socket.prototype.ondisconnect = function(){
 916  debug('server disconnect (%s)', this.nsp);
 917  this.destroy();
 918  this.onclose('io server disconnect');
 919};
 920
 921/**
 922 * Called upon forced client/server side disconnections,
 923 * this method ensures the manager stops tracking us and
 924 * that reconnections don't get triggered for this.
 925 *
 926 * @api private.
 927 */
 928
 929Socket.prototype.destroy = function(){
 930  // clean subscriptions to avoid reconnections
 931  for (var i = 0; i < this.subs.length; i++) {
 932    this.subs[i].destroy();
 933  }
 934
 935  this.io.destroy(this);
 936};
 937
 938/**
 939 * Disconnects the socket manually.
 940 *
 941 * @return {Socket} self
 942 * @api public
 943 */
 944
 945Socket.prototype.close =
 946Socket.prototype.disconnect = function(){
 947  if (!this.connected) return this;
 948
 949  debug('performing disconnect (%s)', this.nsp);
 950  this.packet({ type: parser.DISCONNECT });
 951
 952  // remove socket from pool
 953  this.destroy();
 954
 955  // fire events
 956  this.onclose('io client disconnect');
 957  return this;
 958};
 959
 960},{"./on":4,"component-bind":7,"component-emitter":8,"debug":9,"has-binary":32,"indexof":36,"socket.io-parser":40,"to-array":44}],6:[function(_dereq_,module,exports){
 961(function (global){
 962
 963/**
 964 * Module dependencies.
 965 */
 966
 967var parseuri = _dereq_('parseuri');
 968var debug = _dereq_('debug')('socket.io-client:url');
 969
 970/**
 971 * Module exports.
 972 */
 973
 974module.exports = url;
 975
 976/**
 977 * URL parser.
 978 *
 979 * @param {String} url
 980 * @param {Object} An object meant to mimic window.location.
 981 *                 Defaults to window.location.
 982 * @api public
 983 */
 984
 985function url(uri, loc){
 986  var obj = uri;
 987
 988  // default to window.location
 989  var loc = loc || global.location;
 990  if (null == uri) uri = loc.protocol + '//' + loc.hostname;
 991
 992  // relative path support
 993  if ('string' == typeof uri) {
 994    if ('/' == uri.charAt(0)) {
 995      if ('undefined' != typeof loc) {
 996        uri = loc.hostname + uri;
 997      }
 998    }
 999
1000    if (!/^(https?|wss?):\/\//.test(uri)) {
1001      debug('protocol-less url %s', uri);
1002      if ('undefined' != typeof loc) {
1003        uri = loc.protocol + '//' + uri;
1004      } else {
1005        uri = 'https://' + uri;
1006      }
1007    }
1008
1009    // parse
1010    debug('parse %s', uri);
1011    obj = parseuri(uri);
1012  }
1013
1014  // make sure we treat `localhost:80` and `localhost` equally
1015  if (!obj.port) {
1016    if (/^(http|ws)$/.test(obj.protocol)) {
1017      obj.port = '80';
1018    }
1019    else if (/^(http|ws)s$/.test(obj.protocol)) {
1020      obj.port = '443';
1021    }
1022  }
1023
1024  obj.path = obj.path || '/';
1025
1026  // define unique id
1027  obj.id = obj.protocol + '://' + obj.host + ':' + obj.port;
1028  // define href
1029  obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port));
1030
1031  return obj;
1032}
1033
1034}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1035},{"debug":9,"parseuri":38}],7:[function(_dereq_,module,exports){
1036/**
1037 * Slice reference.
1038 */
1039
1040var slice = [].slice;
1041
1042/**
1043 * Bind `obj` to `fn`.
1044 *
1045 * @param {Object} obj
1046 * @param {Function|String} fn or string
1047 * @return {Function}
1048 * @api public
1049 */
1050
1051module.exports = function(obj, fn){
1052  if ('string' == typeof fn) fn = obj[fn];
1053  if ('function' != typeof fn) throw new Error('bind() requires a function');
1054  var args = slice.call(arguments, 2);
1055  return function(){
1056    return fn.apply(obj, args.concat(slice.call(arguments)));
1057  }
1058};
1059
1060},{}],8:[function(_dereq_,module,exports){
1061
1062/**
1063 * Expose `Emitter`.
1064 */
1065
1066module.exports = Emitter;
1067
1068/**
1069 * Initialize a new `Emitter`.
1070 *
1071 * @api public
1072 */
1073
1074function Emitter(obj) {
1075  if (obj) return mixin(obj);
1076};
1077
1078/**
1079 * Mixin the emitter properties.
1080 *
1081 * @param {Object} obj
1082 * @return {Object}
1083 * @api private
1084 */
1085
1086function mixin(obj) {
1087  for (var key in Emitter.prototype) {
1088    obj[key] = Emitter.prototype[key];
1089  }
1090  return obj;
1091}
1092
1093/**
1094 * Listen on the given `event` with `fn`.
1095 *
1096 * @param {String} event
1097 * @param {Function} fn
1098 * @return {Emitter}
1099 * @api public
1100 */
1101
1102Emitter.prototype.on =
1103Emitter.prototype.addEventListener = function(event, fn){
1104  this._callbacks = this._callbacks || {};
1105  (this._callbacks[event] = this._callbacks[event] || [])
1106    .push(fn);
1107  return this;
1108};
1109
1110/**
1111 * Adds an `event` listener that will be invoked a single
1112 * time then automatically removed.
1113 *
1114 * @param {String} event
1115 * @param {Function} fn
1116 * @return {Emitter}
1117 * @api public
1118 */
1119
1120Emitter.prototype.once = function(event, fn){
1121  var self = this;
1122  this._callbacks = this._callbacks || {};
1123
1124  function on() {
1125    self.off(event, on);
1126    fn.apply(this, arguments);
1127  }
1128
1129  on.fn = fn;
1130  this.on(event, on);
1131  return this;
1132};
1133
1134/**
1135 * Remove the given callback for `event` or all
1136 * registered callbacks.
1137 *
1138 * @param {String} event
1139 * @param {Function} fn
1140 * @return {Emitter}
1141 * @api public
1142 */
1143
1144Emitter.prototype.off =
1145Emitter.prototype.removeListener =
1146Emitter.prototype.removeAllListeners =
1147Emitter.prototype.removeEventListener = function(event, fn){
1148  this._callbacks = this._callbacks || {};
1149
1150  // all
1151  if (0 == arguments.length) {
1152    this._callbacks = {};
1153    return this;
1154  }
1155
1156  // specific event
1157  var callbacks = this._callbacks[event];
1158  if (!callbacks) return this;
1159
1160  // remove all handlers
1161  if (1 == arguments.length) {
1162    delete this._callbacks[event];
1163    return this;
1164  }
1165
1166  // remove specific handler
1167  var cb;
1168  for (var i = 0; i < callbacks.length; i++) {
1169    cb = callbacks[i];
1170    if (cb === fn || cb.fn === fn) {
1171      callbacks.splice(i, 1);
1172      break;
1173    }
1174  }
1175  return this;
1176};
1177
1178/**
1179 * Emit `event` with the given args.
1180 *
1181 * @param {String} event
1182 * @param {Mixed} ...
1183 * @return {Emitter}
1184 */
1185
1186Emitter.prototype.emit = function(event){
1187  this._callbacks = this._callbacks || {};
1188  var args = [].slice.call(arguments, 1)
1189    , callbacks = this._callbacks[event];
1190
1191  if (callbacks) {
1192    callbacks = callbacks.slice(0);
1193    for (var i = 0, len = callbacks.length; i < len; ++i) {
1194      callbacks[i].apply(this, args);
1195    }
1196  }
1197
1198  return this;
1199};
1200
1201/**
1202 * Return array of callbacks for `event`.
1203 *
1204 * @param {String} event
1205 * @return {Array}
1206 * @api public
1207 */
1208
1209Emitter.prototype.listeners = function(event){
1210  this._callbacks = this._callbacks || {};
1211  return this._callbacks[event] || [];
1212};
1213
1214/**
1215 * Check if this emitter has `event` handlers.
1216 *
1217 * @param {String} event
1218 * @return {Boolean}
1219 * @api public
1220 */
1221
1222Emitter.prototype.hasListeners = function(event){
1223  return !! this.listeners(event).length;
1224};
1225
1226},{}],9:[function(_dereq_,module,exports){
1227
1228/**
1229 * Expose `debug()` as the module.
1230 */
1231
1232module.exports = debug;
1233
1234/**
1235 * Create a debugger with the given `name`.
1236 *
1237 * @param {String} name
1238 * @return {Type}
1239 * @api public
1240 */
1241
1242function debug(name) {
1243  if (!debug.enabled(name)) return function(){};
1244
1245  return function(fmt){
1246    fmt = coerce(fmt);
1247
1248    var curr = new Date;
1249    var ms = curr - (debug[name] || curr);
1250    debug[name] = curr;
1251
1252    fmt = name
1253      + ' '
1254      + fmt
1255      + ' +' + debug.humanize(ms);
1256
1257    // This hackery is required for IE8
1258    // where `console.log` doesn't have 'apply'
1259    window.console
1260      && console.log
1261      && Function.prototype.apply.call(console.log, console, arguments);
1262  }
1263}
1264
1265/**
1266 * The currently active debug mode names.
1267 */
1268
1269debug.names = [];
1270debug.skips = [];
1271
1272/**
1273 * Enables a debug mode by name. This can include modes
1274 * separated by a colon and wildcards.
1275 *
1276 * @param {String} name
1277 * @api public
1278 */
1279
1280debug.enable = function(name) {
1281  try {
1282    localStorage.debug = name;
1283  } catch(e){}
1284
1285  var split = (name || '').split(/[\s,]+/)
1286    , len = split.length;
1287
1288  for (var i = 0; i < len; i++) {
1289    name = split[i].replace('*', '.*?');
1290    if (name[0] === '-') {
1291      debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
1292    }
1293    else {
1294      debug.names.push(new RegExp('^' + name + '$'));
1295    }
1296  }
1297};
1298
1299/**
1300 * Disable debug output.
1301 *
1302 * @api public
1303 */
1304
1305debug.disable = function(){
1306  debug.enable('');
1307};
1308
1309/**
1310 * Humanize the given `ms`.
1311 *
1312 * @param {Number} m
1313 * @return {String}
1314 * @api private
1315 */
1316
1317debug.humanize = function(ms) {
1318  var sec = 1000
1319    , min = 60 * 1000
1320    , hour = 60 * min;
1321
1322  if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
1323  if (ms >= min) return (ms / min).toFixed(1) + 'm';
1324  if (ms >= sec) return (ms / sec | 0) + 's';
1325  return ms + 'ms';
1326};
1327
1328/**
1329 * Returns true if the given mode name is enabled, false otherwise.
1330 *
1331 * @param {String} name
1332 * @return {Boolean}
1333 * @api public
1334 */
1335
1336debug.enabled = function(name) {
1337  for (var i = 0, len = debug.skips.length; i < len; i++) {
1338    if (debug.skips[i].test(name)) {
1339      return false;
1340    }
1341  }
1342  for (var i = 0, len = debug.names.length; i < len; i++) {
1343    if (debug.names[i].test(name)) {
1344      return true;
1345    }
1346  }
1347  return false;
1348};
1349
1350/**
1351 * Coerce `val`.
1352 */
1353
1354function coerce(val) {
1355  if (val instanceof Error) return val.stack || val.message;
1356  return val;
1357}
1358
1359// persist
1360
1361try {
1362  if (window.localStorage) debug.enable(localStorage.debug);
1363} catch(e){}
1364
1365},{}],10:[function(_dereq_,module,exports){
1366
1367module.exports =  _dereq_('./lib/');
1368
1369},{"./lib/":11}],11:[function(_dereq_,module,exports){
1370
1371module.exports = _dereq_('./socket');
1372
1373/**
1374 * Exports parser
1375 *
1376 * @api public
1377 *
1378 */
1379module.exports.parser = _dereq_('engine.io-parser');
1380
1381},{"./socket":12,"engine.io-parser":21}],12:[function(_dereq_,module,exports){
1382(function (global){
1383/**
1384 * Module dependencies.
1385 */
1386
1387var transports = _dereq_('./transports');
1388var Emitter = _dereq_('component-emitter');
1389var debug = _dereq_('debug')('engine.io-client:socket');
1390var index = _dereq_('indexof');
1391var parser = _dereq_('engine.io-parser');
1392var parseuri = _dereq_('parseuri');
1393var parsejson = _dereq_('parsejson');
1394var parseqs = _dereq_('parseqs');
1395
1396/**
1397 * Module exports.
1398 */
1399
1400module.exports = Socket;
1401
1402/**
1403 * Noop function.
1404 *
1405 * @api private
1406 */
1407
1408function noop(){}
1409
1410/**
1411 * Socket constructor.
1412 *
1413 * @param {String|Object} uri or options
1414 * @param {Object} options
1415 * @api public
1416 */
1417
1418function Socket(uri, opts){
1419  if (!(this instanceof Socket)) return new Socket(uri, opts);
1420
1421  opts = opts || {};
1422
1423  if (uri && 'object' == typeof uri) {
1424    opts = uri;
1425    uri = null;
1426  }
1427
1428  if (uri) {
1429    uri = parseuri(uri);
1430    opts.host = uri.host;
1431    opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
1432    opts.port = uri.port;
1433    if (uri.query) opts.query = uri.query;
1434  }
1435
1436  this.secure = null != opts.secure ? opts.secure :
1437    (global.location && 'https:' == location.protocol);
1438
1439  if (opts.host) {
1440    var pieces = opts.host.split(':');
1441    opts.hostname = pieces.shift();
1442    if (pieces.length) opts.port = pieces.pop();
1443  }
1444
1445  this.agent = opts.agent || false;
1446  this.hostname = opts.hostname ||
1447    (global.location ? location.hostname : 'localhost');
1448  this.port = opts.port || (global.location && location.port ?
1449       location.port :
1450       (this.secure ? 443 : 80));
1451  this.query = opts.query || {};
1452  if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
1453  this.upgrade = false !== opts.upgrade;
1454  this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
1455  this.forceJSONP = !!opts.forceJSONP;
1456  this.jsonp = false !== opts.jsonp;
1457  this.forceBase64 = !!opts.forceBase64;
1458  this.enablesXDR = !!opts.enablesXDR;
1459  this.timestampParam = opts.timestampParam || 't';
1460  this.timestampRequests = opts.timestampRequests;
1461  this.transports = opts.transports || ['polling', 'websocket'];
1462  this.readyState = '';
1463  this.writeBuffer = [];
1464  this.callbackBuffer = [];
1465  this.policyPort = opts.policyPort || 843;
1466  this.rememberUpgrade = opts.rememberUpgrade || false;
1467  this.open();
1468  this.binaryType = null;
1469  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
1470}
1471
1472Socket.priorWebsocketSuccess = false;
1473
1474/**
1475 * Mix in `Emitter`.
1476 */
1477
1478Emitter(Socket.prototype);
1479
1480/**
1481 * Protocol version.
1482 *
1483 * @api public
1484 */
1485
1486Socket.protocol = parser.protocol; // this is an int
1487
1488/**
1489 * Expose deps for legacy compatibility
1490 * and standalone browser access.
1491 */
1492
1493Socket.Socket = Socket;
1494Socket.Transport = _dereq_('./transport');
1495Socket.transports = _dereq_('./transports');
1496Socket.parser = _dereq_('engine.io-parser');
1497
1498/**
1499 * Creates transport of the given type.
1500 *
1501 * @param {String} transport name
1502 * @return {Transport}
1503 * @api private
1504 */
1505
1506Socket.prototype.createTransport = function (name) {
1507  debug('creating transport "%s"', name);
1508  var query = clone(this.query);
1509
1510  // append engine.io protocol identifier
1511  query.EIO = parser.protocol;
1512
1513  // transport name
1514  query.transport = name;
1515
1516  // session id if we already have one
1517  if (this.id) query.sid = this.id;
1518
1519  var transport = new transports[name]({
1520    agent: this.agent,
1521    hostname: this.hostname,
1522    port: this.port,
1523    secure: this.secure,
1524    path: this.path,
1525    query: query,
1526    forceJSONP: this.forceJSONP,
1527    jsonp: this.jsonp,
1528    forceBase64: this.forceBase64,
1529    enablesXDR: this.enablesXDR,
1530    timestampRequests: this.timestampRequests,
1531    timestampParam: this.timestampParam,
1532    policyPort: this.policyPort,
1533    socket: this
1534  });
1535
1536  return transport;
1537};
1538
1539function clone (obj) {
1540  var o = {};
1541  for (var i in obj) {
1542    if (obj.hasOwnProperty(i)) {
1543      o[i] = obj[i];
1544    }
1545  }
1546  return o;
1547}
1548
1549/**
1550 * Initializes transport to use and starts probe.
1551 *
1552 * @api private
1553 */
1554Socket.prototype.open = function () {
1555  var transport;
1556  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
1557    transport = 'websocket';
1558  } else if (0 == this.transports.length) {
1559    // Emit error on next tick so it can be listened to
1560    var self = this;
1561    setTimeout(function() {
1562      self.emit('error', 'No transports available');
1563    }, 0);
1564    return;
1565  } else {
1566    transport = this.transports[0];
1567  }
1568  this.readyState = 'opening';
1569
1570  // Retry with the next transport if the transport is disabled (jsonp: false)
1571  var transport;
1572  try {
1573    transport = this.createTransport(transport);
1574  } catch (e) {
1575    this.transports.shift();
1576    this.open();
1577    return;
1578  }
1579
1580  transport.open();
1581  this.setTransport(transport);
1582};
1583
1584/**
1585 * Sets the current transport. Disables the existing one (if any).
1586 *
1587 * @api private
1588 */
1589
1590Socket.prototype.setTransport = function(transport){
1591  debug('setting transport %s', transport.name);
1592  var self = this;
1593
1594  if (this.transport) {
1595    debug('clearing existing transport %s', this.transport.name);
1596    this.transport.removeAllListeners();
1597  }
1598
1599  // set up transport
1600  this.transport = transport;
1601
1602  // set up transport listeners
1603  transport
1604  .on('drain', function(){
1605    self.onDrain();
1606  })
1607  .on('packet', function(packet){
1608    self.onPacket(packet);
1609  })
1610  .on('error', function(e){
1611    self.onError(e);
1612  })
1613  .on('close', function(){
1614    self.onClose('transport close');
1615  });
1616};
1617
1618/**
1619 * Probes a transport.
1620 *
1621 * @param {String} transport name
1622 * @api private
1623 */
1624
1625Socket.prototype.probe = function (name) {
1626  debug('probing transport "%s"', name);
1627  var transport = this.createTransport(name, { probe: 1 })
1628    , failed = false
1629    , self = this;
1630
1631  Socket.priorWebsocketSuccess = false;
1632
1633  function onTransportOpen(){
1634    if (self.onlyBinaryUpgrades) {
1635      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
1636      failed = failed || upgradeLosesBinary;
1637    }
1638    if (failed) return;
1639
1640    debug('probe transport "%s" opened', name);
1641    transport.send([{ type: 'ping', data: 'probe' }]);
1642    transport.once('packet', function (msg) {
1643      if (failed) return;
1644      if ('pong' == msg.type && 'probe' == msg.data) {
1645        debug('probe transport "%s" pong', name);
1646        self.upgrading = true;
1647        self.emit('upgrading', transport);
1648        Socket.priorWebsocketSuccess = 'websocket' == transport.name;
1649
1650        debug('pausing current transport "%s"', self.transport.name);
1651        self.transport.pause(function () {
1652          if (failed) return;
1653          if ('closed' == self.readyState || 'closing' == self.readyState) {
1654            return;
1655          }
1656          debug('changing transport and sending upgrade packet');
1657
1658          cleanup();
1659
1660          self.setTransport(transport);
1661          transport.send([{ type: 'upgrade' }]);
1662          self.emit('upgrade', transport);
1663          transport = null;
1664          self.upgrading = false;
1665          self.flush();
1666        });
1667      } else {
1668        debug('probe transport "%s" failed', name);
1669        var err = new Error('probe error');
1670        err.transport = transport.name;
1671        self.emit('upgradeError', err);
1672      }
1673    });
1674  }
1675
1676  function freezeTransport() {
1677    if (failed) return;
1678
1679    // Any callback called by transport should be ignored since now
1680    failed = true;
1681
1682    cleanup();
1683
1684    transport.close();
1685    transport = null;
1686  }
1687
1688  //Handle any error that happens while probing
1689  function onerror(err) {
1690    var error = new Error('probe error: ' + err);
1691    error.transport = transport.name;
1692
1693    freezeTransport();
1694
1695    debug('probe transport "%s" failed because of error: %s', name, err);
1696
1697    self.emit('upgradeError', error);
1698  }
1699
1700  function onTransportClose(){
1701    onerror("transport closed");
1702  }
1703
1704  //When the socket is closed while we're probing
1705  function onclose(){
1706    onerror("socket closed");
1707  }
1708
1709  //When the socket is upgraded while we're probing
1710  function onupgrade(to){
1711    if (transport && to.name != transport.name) {
1712      debug('"%s" works - aborting "%s"', to.name, transport.name);
1713      freezeTransport();
1714    }
1715  }
1716
1717  //Remove all listeners on the transport and on self
1718  function cleanup(){
1719    transport.removeListener('open', onTransportOpen);
1720    transport.removeListener('error', onerror);
1721    transport.removeListener('close', onTransportClose);
1722    self.removeListener('close', onclose);
1723    self.removeListener('upgrading', onupgrade);
1724  }
1725
1726  transport.once('open', onTransportOpen);
1727  transport.once('error', onerror);
1728  transport.once('close', onTransportClose);
1729
1730  this.once('close', onclose);
1731  this.once('upgrading', onupgrade);
1732
1733  transport.open();
1734
1735};
1736
1737/**
1738 * Called when connection is deemed open.
1739 *
1740 * @api public
1741 */
1742
1743Socket.prototype.onOpen = function () {
1744  debug('socket open');
1745  this.readyState = 'open';
1746  Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
1747  this.emit('open');
1748  this.flush();
1749
1750  // we check for `readyState` in case an `open`
1751  // listener already closed the socket
1752  if ('open' == this.readyState && this.upgrade && this.transport.pause) {
1753    debug('starting upgrade probes');
1754    for (var i = 0, l = this.upgrades.length; i < l; i++) {
1755      this.probe(this.upgrades[i]);
1756    }
1757  }
1758};
1759
1760/**
1761 * Handles a packet.
1762 *
1763 * @api private
1764 */
1765
1766Socket.prototype.onPacket = function (packet) {
1767  if ('opening' == this.readyState || 'open' == this.readyState) {
1768    debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
1769
1770    this.emit('packet', packet);
1771
1772    // Socket is live - any packet counts
1773    this.emit('heartbeat');
1774
1775    switch (packet.type) {
1776      case 'open':
1777        this.onHandshake(parsejson(packet.data));
1778        break;
1779
1780      case 'pong':
1781        this.setPing();
1782        break;
1783
1784      case 'error':
1785        var err = new Error('server error');
1786        err.code = packet.data;
1787        this.emit('error', err);
1788        break;
1789
1790      case 'message':
1791        this.emit('data', packet.data);
1792        this.emit('message', packet.data);
1793        break;
1794    }
1795  } else {
1796    debug('packet received with socket readyState "%s"', this.readyState);
1797  }
1798};
1799
1800/**
1801 * Called upon handshake completion.
1802 *
1803 * @param {Object} handshake obj
1804 * @api private
1805 */
1806
1807Socket.prototype.onHandshake = function (data) {
1808  this.emit('handshake', data);
1809  this.id = data.sid;
1810  this.transport.query.sid = data.sid;
1811  this.upgrades = this.filterUpgrades(data.upgrades);
1812  this.pingInterval = data.pingInterval;
1813  this.pingTimeout = data.pingTimeout;
1814  this.onOpen();
1815  // In case open handler closes socket
1816  if  ('closed' == this.readyState) return;
1817  this.setPing();
1818
1819  // Prolong liveness of socket on heartbeat
1820  this.removeListener('heartbeat', this.onHeartbeat);
1821  this.on('heartbeat', this.onHeartbeat);
1822};
1823
1824/**
1825 * Resets ping timeout.
1826 *
1827 * @api private
1828 */
1829
1830Socket.prototype.onHeartbeat = function (timeout) {
1831  clearTimeout(this.pingTimeoutTimer);
1832  var self = this;
1833  self.pingTimeoutTimer = setTimeout(function () {
1834    if ('closed' == self.readyState) return;
1835    self.onClose('ping timeout');
1836  }, timeout || (self.pingInterval + self.pingTimeout));
1837};
1838
1839/**
1840 * Pings server every `this.pingInterval` and expects response
1841 * within `this.pingTimeout` or closes connection.
1842 *
1843 * @api private
1844 */
1845
1846Socket.prototype.setPing = function () {
1847  var self = this;
1848  clearTimeout(self.pingIntervalTimer);
1849  self.pingIntervalTimer = setTimeout(function () {
1850    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
1851    self.ping();
1852    self.onHeartbeat(self.pingTimeout);
1853  }, self.pingInterval);
1854};
1855
1856/**
1857* Sends a ping packet.
1858*
1859* @api public
1860*/
1861
1862Socket.prototype.ping = function () {
1863  this.sendPacket('ping');
1864};
1865
1866/**
1867 * Called on `drain` event
1868 *
1869 * @api private
1870 */
1871
1872Socket.prototype.onDrain = function() {
1873  for (var i = 0; i < this.prevBufferLen; i++) {
1874    if (this.callbackBuffer[i]) {
1875      this.callbackBuffer[i]();
1876    }
1877  }
1878
1879  this.writeBuffer.splice(0, this.prevBufferLen);
1880  this.callbackBuffer.splice(0, this.prevBufferLen);
1881
1882  // setting prevBufferLen = 0 is very important
1883  // for example, when upgrading, upgrade packet is sent over,
1884  // and a nonzero prevBufferLen could cause problems on `drain`
1885  this.prevBufferLen = 0;
1886
1887  if (this.writeBuffer.length == 0) {
1888    this.emit('drain');
1889  } else {
1890    this.flush();
1891  }
1892};
1893
1894/**
1895 * Flush write buffers.
1896 *
1897 * @api private
1898 */
1899
1900Socket.prototype.flush = function () {
1901  if ('closed' != this.readyState && this.transport.writable &&
1902    !this.upgrading && this.writeBuffer.length) {
1903    debug('flushing %d packets in socket', this.writeBuffer.length);
1904    this.transport.send(this.writeBuffer);
1905    // keep track of current length of writeBuffer
1906    // splice writeBuffer and callbackBuffer on `drain`
1907    this.prevBufferLen = this.writeBuffer.length;
1908    this.emit('flush');
1909  }
1910};
1911
1912/**
1913 * Sends a message.
1914 *
1915 * @param {String} message.
1916 * @param {Function} callback function.
1917 * @return {Socket} for chaining.
1918 * @api public
1919 */
1920
1921Socket.prototype.write =
1922Socket.prototype.send = function (msg, fn) {
1923  this.sendPacket('message', msg, fn);
1924  return this;
1925};
1926
1927/**
1928 * Sends a packet.
1929 *
1930 * @param {String} packet type.
1931 * @param {String} data.
1932 * @param {Function} callback function.
1933 * @api private
1934 */
1935
1936Socket.prototype.sendPacket = function (type, data, fn) {
1937  var packet = { type: type, data: data };
1938  this.emit('packetCreate', packet);
1939  this.writeBuffer.push(packet);
1940  this.callbackBuffer.push(fn);
1941  this.flush();
1942};
1943
1944/**
1945 * Closes the connection.
1946 *
1947 * @api private
1948 */
1949
1950Socket.prototype.close = function () {
1951  if ('opening' == this.readyState || 'open' == this.readyState) {
1952    this.onClose('forced close');
1953    debug('socket closing - telling transport to close');
1954    this.transport.close();
1955  }
1956
1957  return this;
1958};
1959
1960/**
1961 * Called upon transport error
1962 *
1963 * @api private
1964 */
1965
1966Socket.prototype.onError = function (err) {
1967  debug('socket error %j', err);
1968  Socket.priorWebsocketSuccess = false;
1969  this.emit('error', err);
1970  this.onClose('transport error', err);
1971};
1972
1973/**
1974 * Called upon transport close.
1975 *
1976 * @api private
1977 */
1978
1979Socket.prototype.onClose = function (reason, desc) {
1980  if ('opening' == this.readyState || 'open' == this.readyState) {
1981    debug('socket close with reason: "%s"', reason);
1982    var self = this;
1983
1984    // clear timers
1985    clearTimeout(this.pingIntervalTimer);
1986    clearTimeout(this.pingTimeoutTimer);
1987
1988    // clean buffers in next tick, so developers can still
1989    // grab the buffers on `close` event
1990    setTimeout(function() {
1991      self.writeBuffer = [];
1992      self.callbackBuffer = [];
1993      self.prevBufferLen = 0;
1994    }, 0);
1995
1996    // stop event from firing again for transport
1997    this.transport.removeAllListeners('close');
1998
1999    // ensure transport won't stay open
2000    this.transport.close();
2001
2002    // ignore further transport communication
2003    this.transport.removeAllListeners();
2004
2005    // set ready state
2006    this.readyState = 'closed';
2007
2008    // clear session id
2009    this.id = null;
2010
2011    // emit close event
2012    this.emit('close', reason, desc);
2013  }
2014};
2015
2016/**
2017 * Filters upgrades, returning only those matching client transports.
2018 *
2019 * @param {Array} server upgrades
2020 * @api private
2021 *
2022 */
2023
2024Socket.prototype.filterUpgrades = function (upgrades) {
2025  var filteredUpgrades = [];
2026  for (var i = 0, j = upgrades.length; i<j; i++) {
2027    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
2028  }
2029  return filteredUpgrades;
2030};
2031
2032}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2033},{"./transport":13,"./transports":14,"component-emitter":8,"debug":9,"engine.io-parser":21,"indexof":36,"parsejson":28,"parseqs":29,"parseuri":30}],13:[function(_dereq_,module,exports){
2034/**
2035 * Module dependencies.
2036 */
2037
2038var parser = _dereq_('engine.io-parser');
2039var Emitter = _dereq_('component-emitter');
2040
2041/**
2042 * Module exports.
2043 */
2044
2045module.exports = Transport;
2046
2047/**
2048 * Transport abstract constructor.
2049 *
2050 * @param {Object} options.
2051 * @api private
2052 */
2053
2054function Transport (opts) {
2055  this.path = opts.path;
2056  this.hostname = opts.hostname;
2057  this.port = opts.port;
2058  this.secure = opts.secure;
2059  this.query = opts.query;
2060  this.timestampParam = opts.timestampParam;
2061  this.timestampRequests = opts.timestampRequests;
2062  this.readyState = '';
2063  this.agent = opts.agent || false;
2064  this.socket = opts.socket;
2065  this.enablesXDR = opts.enablesXDR;
2066}
2067
2068/**
2069 * Mix in `Emitter`.
2070 */
2071
2072Emitter(Transport.prototype);
2073
2074/**
2075 * A counter used to prevent collisions in the timestamps used
2076 * for cache busting.
2077 */
2078
2079Transport.timestamps = 0;
2080
2081/**
2082 * Emits an error.
2083 *
2084 * @param {String} str
2085 * @return {Transport} for chaining
2086 * @api public
2087 */
2088
2089Transport.prototype.onError = function (msg, desc) {
2090  var err = new Error(msg);
2091  err.type = 'TransportError';
2092  err.description = desc;
2093  this.emit('error', err);
2094  return this;
2095};
2096
2097/**
2098 * Opens the transport.
2099 *
2100 * @api public
2101 */
2102
2103Transport.prototype.open = function () {
2104  if ('closed' == this.readyState || '' == this.readyState) {
2105    this.readyState = 'opening';
2106    this.doOpen();
2107  }
2108
2109  return this;
2110};
2111
2112/**
2113 * Closes the transport.
2114 *
2115 * @api private
2116 */
2117
2118Transport.prototype.close = function () {
2119  if ('opening' == this.readyState || 'open' == this.readyState) {
2120    this.doClose();
2121    this.onClose();
2122  }
2123
2124  return this;
2125};
2126
2127/**
2128 * Sends multiple packets.
2129 *
2130 * @param {Array} packets
2131 * @api private
2132 */
2133
2134Transport.prototype.send = function(packets){
2135  if ('open' == this.readyState) {
2136    this.write(packets);
2137  } else {
2138    throw new Error('Transport not open');
2139  }
2140};
2141
2142/**
2143 * Called upon open
2144 *
2145 * @api private
2146 */
2147
2148Transport.prototype.onOpen = function () {
2149  this.readyState = 'open';
2150  this.writable = true;
2151  this.emit('open');
2152};
2153
2154/**
2155 * Called with data.
2156 *
2157 * @param {String} data
2158 * @api private
2159 */
2160
2161Transport.prototype.onData = function(data){
2162  var packet = parser.decodePacket(data, this.socket.binaryType);
2163  this.onPacket(packet);
2164};
2165
2166/**
2167 * Called with a decoded packet.
2168 */
2169
2170Transport.prototype.onPacket = function (packet) {
2171  this.emit('packet', packet);
2172};
2173
2174/**
2175 * Called upon close.
2176 *
2177 * @api private
2178 */
2179
2180Transport.prototype.onClose = function () {
2181  this.readyState = 'closed';
2182  this.emit('close');
2183};
2184
2185},{"component-emitter":8,"engine.io-parser":21}],14:[function(_dereq_,module,exports){
2186(function (global){
2187/**
2188 * Module dependencies
2189 */
2190
2191var XMLHttpRequest = _dereq_('xmlhttprequest');
2192var XHR = _dereq_('./polling-xhr');
2193var JSONP = _dereq_('./polling-jsonp');
2194var websocket = _dereq_('./websocket');
2195
2196/**
2197 * Export transports.
2198 */
2199
2200exports.polling = polling;
2201exports.websocket = websocket;
2202
2203/**
2204 * Polling transport polymorphic constructor.
2205 * Decides on xhr vs jsonp based on feature detection.
2206 *
2207 * @api private
2208 */
2209
2210function polling(opts){
2211  var xhr;
2212  var xd = false;
2213  var xs = false;
2214  var jsonp = false !== opts.jsonp;
2215
2216  if (global.location) {
2217    var isSSL = 'https:' == location.protocol;
2218    var port = location.port;
2219
2220    // some user agents have empty `location.port`
2221    if (!port) {
2222      port = isSSL ? 443 : 80;
2223    }
2224
2225    xd = opts.hostname != location.hostname || port != opts.port;
2226    xs = opts.secure != isSSL;
2227  }
2228
2229  opts.xdomain = xd;
2230  opts.xscheme = xs;
2231  xhr = new XMLHttpRequest(opts);
2232
2233  if ('open' in xhr && !opts.forceJSONP) {
2234    return new XHR(opts);
2235  } else {
2236    if (!jsonp) throw new Error('JSONP disabled');
2237    return new JSONP(opts);
2238  }
2239}
2240
2241}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2242},{"./polling-jsonp":15,"./polling-xhr":16,"./websocket":18,"xmlhttprequest":19}],15:[function(_dereq_,module,exports){
2243(function (global){
2244
2245/**
2246 * Module requirements.
2247 */
2248
2249var Polling = _dereq_('./polling');
2250var inherit = _dereq_('component-inherit');
2251
2252/**
2253 * Module exports.
2254 */
2255
2256module.exports = JSONPPolling;
2257
2258/**
2259 * Cached regular expressions.
2260 */
2261
2262var rNewline = /\n/g;
2263var rEscapedNewline = /\\n/g;
2264
2265/**
2266 * Global JSONP callbacks.
2267 */
2268
2269var callbacks;
2270
2271/**
2272 * Callbacks count.
2273 */
2274
2275var index = 0;
2276
2277/**
2278 * Noop.
2279 */
2280
2281function empty () { }
2282
2283/**
2284 * JSONP Polling constructor.
2285 *
2286 * @param {Object} opts.
2287 * @api public
2288 */
2289
2290function JSONPPolling (opts) {
2291  Polling.call(this, opts);
2292
2293  this.query = this.query || {};
2294
2295  // define global callbacks array if not present
2296  // we do this here (lazily) to avoid unneeded global pollution
2297  if (!callbacks) {
2298    // we need to consider multiple engines in the same page
2299    if (!global.___eio) global.___eio = [];
2300    callbacks = global.___eio;
2301  }
2302
2303  // callback identifier
2304  this.index = callbacks.length;
2305
2306  // add callback to jsonp global
2307  var self = this;
2308  callbacks.push(function (msg) {
2309    self.onData(msg);
2310  });
2311
2312  // append to query string
2313  this.query.j = this.index;
2314
2315  // prevent spurious errors from being emitted when the window is unloaded
2316  if (global.document && global.addEventListener) {
2317    global.addEventListener('beforeunload', function () {
2318      if (self.script) self.script.onerror = empty;
2319    });
2320  }
2321}
2322
2323/**
2324 * Inherits from Polling.
2325 */
2326
2327inherit(JSONPPolling, Polling);
2328
2329/*
2330 * JSONP only supports binary as base64 encoded strings
2331 */
2332
2333JSONPPolling.prototype.supportsBinary = false;
2334
2335/**
2336 * Closes the socket.
2337 *
2338 * @api private
2339 */
2340
2341JSONPPolling.prototype.doClose = function () {
2342  if (this.script) {
2343    this.script.parentNode.removeChild(this.script);
2344    this.script = null;
2345  }
2346
2347  if (this.form) {
2348    this.form.parentNode.removeChild(this.form);
2349    this.form = null;
2350  }
2351
2352  Polling.prototype.doClose.call(this);
2353};
2354
2355/**
2356 * Starts a poll cycle.
2357 *
2358 * @api private
2359 */
2360
2361JSONPPolling.prototype.doPoll = function () {
2362  var self = this;
2363  var script = document.createElement('script');
2364
2365  if (this.script) {
2366    this.script.parentNode.removeChild(this.script);
2367    this.script = null;
2368  }
2369
2370  script.async = true;
2371  script.src = this.uri();
2372  script.onerror = function(e){
2373    self.onError('jsonp poll error',e);
2374  };
2375
2376  var insertAt = document.getElementsByTagName('script')[0];
2377  insertAt.parentNode.insertBefore(script, insertAt);
2378  this.script = script;
2379
2380  var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navi

Large files files are truncated, but you can click here to view the full file