PageRenderTime 371ms CodeModel.GetById 31ms app.highlight 281ms RepoModel.GetById 1ms app.codeStats 2ms

/platforms/ios/www/js/socket.io.js

https://github.com/svlsummerjam/Arduino-angular-socketio-phonegap-app
JavaScript | 6065 lines | 3324 code | 957 blank | 1784 comment | 921 complexity | 8c821c2b1818c013e88dbd2ea16bbf87 MD5 | raw file
Possible License(s): Apache-2.0, MIT

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

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

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