PageRenderTime 251ms CodeModel.GetById 14ms app.highlight 198ms RepoModel.GetById 2ms app.codeStats 1ms

/node_modules/socket.io/node_modules/socket.io-client/socket.io.js

https://github.com/kirillKey/questSearchTrain
JavaScript | 6252 lines | 3546 code | 966 blank | 1740 comment | 1013 complexity | 44d1b2a6025c12a3af3c0d9586ca0608 MD5 | raw 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');
 109var indexOf = _dereq_('indexof');
 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 (uri && ('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 = [];
 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.autoConnect = opts.autoConnect !== false;
 151  if (this.autoConnect) this.open();
 152}
 153
 154/**
 155 * Propagate given event to sockets and emit on `this`
 156 *
 157 * @api private
 158 */
 159
 160Manager.prototype.emitAll = function() {
 161  this.emit.apply(this, arguments);
 162  for (var nsp in this.nsps) {
 163    this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
 164  }
 165};
 166
 167/**
 168 * Mix in `Emitter`.
 169 */
 170
 171Emitter(Manager.prototype);
 172
 173/**
 174 * Sets the `reconnection` config.
 175 *
 176 * @param {Boolean} true/false if it should automatically reconnect
 177 * @return {Manager} self or value
 178 * @api public
 179 */
 180
 181Manager.prototype.reconnection = function(v){
 182  if (!arguments.length) return this._reconnection;
 183  this._reconnection = !!v;
 184  return this;
 185};
 186
 187/**
 188 * Sets the reconnection attempts config.
 189 *
 190 * @param {Number} max reconnection attempts before giving up
 191 * @return {Manager} self or value
 192 * @api public
 193 */
 194
 195Manager.prototype.reconnectionAttempts = function(v){
 196  if (!arguments.length) return this._reconnectionAttempts;
 197  this._reconnectionAttempts = v;
 198  return this;
 199};
 200
 201/**
 202 * Sets the delay between reconnections.
 203 *
 204 * @param {Number} delay
 205 * @return {Manager} self or value
 206 * @api public
 207 */
 208
 209Manager.prototype.reconnectionDelay = function(v){
 210  if (!arguments.length) return this._reconnectionDelay;
 211  this._reconnectionDelay = v;
 212  return this;
 213};
 214
 215/**
 216 * Sets the maximum delay between reconnections.
 217 *
 218 * @param {Number} delay
 219 * @return {Manager} self or value
 220 * @api public
 221 */
 222
 223Manager.prototype.reconnectionDelayMax = function(v){
 224  if (!arguments.length) return this._reconnectionDelayMax;
 225  this._reconnectionDelayMax = v;
 226  return this;
 227};
 228
 229/**
 230 * Sets the connection timeout. `false` to disable
 231 *
 232 * @return {Manager} self or value
 233 * @api public
 234 */
 235
 236Manager.prototype.timeout = function(v){
 237  if (!arguments.length) return this._timeout;
 238  this._timeout = v;
 239  return this;
 240};
 241
 242/**
 243 * Starts trying to reconnect if reconnection is enabled and we have not
 244 * started reconnecting yet
 245 *
 246 * @api private
 247 */
 248
 249Manager.prototype.maybeReconnectOnOpen = function() {
 250  // Only try to reconnect if it's the first time we're connecting
 251  if (!this.openReconnect && !this.reconnecting && this._reconnection && this.attempts === 0) {
 252    // keeps reconnection from firing twice for the same reconnection loop
 253    this.openReconnect = true;
 254    this.reconnect();
 255  }
 256};
 257
 258
 259/**
 260 * Sets the current transport `socket`.
 261 *
 262 * @param {Function} optional, callback
 263 * @return {Manager} self
 264 * @api public
 265 */
 266
 267Manager.prototype.open =
 268Manager.prototype.connect = function(fn){
 269  debug('readyState %s', this.readyState);
 270  if (~this.readyState.indexOf('open')) return this;
 271
 272  debug('opening %s', this.uri);
 273  this.engine = eio(this.uri, this.opts);
 274  var socket = this.engine;
 275  var self = this;
 276  this.readyState = 'opening';
 277  this.skipReconnect = false;
 278
 279  // emit `open`
 280  var openSub = on(socket, 'open', function() {
 281    self.onopen();
 282    fn && fn();
 283  });
 284
 285  // emit `connect_error`
 286  var errorSub = on(socket, 'error', function(data){
 287    debug('connect_error');
 288    self.cleanup();
 289    self.readyState = 'closed';
 290    self.emitAll('connect_error', data);
 291    if (fn) {
 292      var err = new Error('Connection error');
 293      err.data = data;
 294      fn(err);
 295    }
 296
 297    self.maybeReconnectOnOpen();
 298  });
 299
 300  // emit `connect_timeout`
 301  if (false !== this._timeout) {
 302    var timeout = this._timeout;
 303    debug('connect attempt will timeout after %d', timeout);
 304
 305    // set timer
 306    var timer = setTimeout(function(){
 307      debug('connect attempt timed out after %d', timeout);
 308      openSub.destroy();
 309      socket.close();
 310      socket.emit('error', 'timeout');
 311      self.emitAll('connect_timeout', timeout);
 312    }, timeout);
 313
 314    this.subs.push({
 315      destroy: function(){
 316        clearTimeout(timer);
 317      }
 318    });
 319  }
 320
 321  this.subs.push(openSub);
 322  this.subs.push(errorSub);
 323
 324  return this;
 325};
 326
 327/**
 328 * Called upon transport open.
 329 *
 330 * @api private
 331 */
 332
 333Manager.prototype.onopen = function(){
 334  debug('open');
 335
 336  // clear old subs
 337  this.cleanup();
 338
 339  // mark as open
 340  this.readyState = 'open';
 341  this.emit('open');
 342
 343  // add new subs
 344  var socket = this.engine;
 345  this.subs.push(on(socket, 'data', bind(this, 'ondata')));
 346  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
 347  this.subs.push(on(socket, 'error', bind(this, 'onerror')));
 348  this.subs.push(on(socket, 'close', bind(this, 'onclose')));
 349};
 350
 351/**
 352 * Called with data.
 353 *
 354 * @api private
 355 */
 356
 357Manager.prototype.ondata = function(data){
 358  this.decoder.add(data);
 359};
 360
 361/**
 362 * Called when parser fully decodes a packet.
 363 *
 364 * @api private
 365 */
 366
 367Manager.prototype.ondecoded = function(packet) {
 368  this.emit('packet', packet);
 369};
 370
 371/**
 372 * Called upon socket error.
 373 *
 374 * @api private
 375 */
 376
 377Manager.prototype.onerror = function(err){
 378  debug('error', err);
 379  this.emitAll('error', err);
 380};
 381
 382/**
 383 * Creates a new socket for the given `nsp`.
 384 *
 385 * @return {Socket}
 386 * @api public
 387 */
 388
 389Manager.prototype.socket = function(nsp){
 390  var socket = this.nsps[nsp];
 391  if (!socket) {
 392    socket = new Socket(this, nsp);
 393    this.nsps[nsp] = socket;
 394    var self = this;
 395    socket.on('connect', function(){
 396      if (!~indexOf(self.connected, socket)) {
 397        self.connected.push(socket);
 398      }
 399    });
 400  }
 401  return socket;
 402};
 403
 404/**
 405 * Called upon a socket close.
 406 *
 407 * @param {Socket} socket
 408 */
 409
 410Manager.prototype.destroy = function(socket){
 411  var index = indexOf(this.connected, socket);
 412  if (~index) this.connected.splice(index, 1);
 413  if (this.connected.length) return;
 414
 415  this.close();
 416};
 417
 418/**
 419 * Writes a packet.
 420 *
 421 * @param {Object} packet
 422 * @api private
 423 */
 424
 425Manager.prototype.packet = function(packet){
 426  debug('writing packet %j', packet);
 427  var self = this;
 428
 429  if (!self.encoding) {
 430    // encode, then write to engine with result
 431    self.encoding = true;
 432    this.encoder.encode(packet, function(encodedPackets) {
 433      for (var i = 0; i < encodedPackets.length; i++) {
 434        self.engine.write(encodedPackets[i]);
 435      }
 436      self.encoding = false;
 437      self.processPacketQueue();
 438    });
 439  } else { // add packet to the queue
 440    self.packetBuffer.push(packet);
 441  }
 442};
 443
 444/**
 445 * If packet buffer is non-empty, begins encoding the
 446 * next packet in line.
 447 *
 448 * @api private
 449 */
 450
 451Manager.prototype.processPacketQueue = function() {
 452  if (this.packetBuffer.length > 0 && !this.encoding) {
 453    var pack = this.packetBuffer.shift();
 454    this.packet(pack);
 455  }
 456};
 457
 458/**
 459 * Clean up transport subscriptions and packet buffer.
 460 *
 461 * @api private
 462 */
 463
 464Manager.prototype.cleanup = function(){
 465  var sub;
 466  while (sub = this.subs.shift()) sub.destroy();
 467
 468  this.packetBuffer = [];
 469  this.encoding = false;
 470
 471  this.decoder.destroy();
 472};
 473
 474/**
 475 * Close the current socket.
 476 *
 477 * @api private
 478 */
 479
 480Manager.prototype.close =
 481Manager.prototype.disconnect = function(){
 482  this.skipReconnect = true;
 483  this.readyState = 'closed';
 484  this.engine && this.engine.close();
 485};
 486
 487/**
 488 * Called upon engine close.
 489 *
 490 * @api private
 491 */
 492
 493Manager.prototype.onclose = function(reason){
 494  debug('close');
 495  this.cleanup();
 496  this.readyState = 'closed';
 497  this.emit('close', reason);
 498  if (this._reconnection && !this.skipReconnect) {
 499    this.reconnect();
 500  }
 501};
 502
 503/**
 504 * Attempt a reconnection.
 505 *
 506 * @api private
 507 */
 508
 509Manager.prototype.reconnect = function(){
 510  if (this.reconnecting || this.skipReconnect) return this;
 511
 512  var self = this;
 513  this.attempts++;
 514
 515  if (this.attempts > this._reconnectionAttempts) {
 516    debug('reconnect failed');
 517    this.emitAll('reconnect_failed');
 518    this.reconnecting = false;
 519  } else {
 520    var delay = this.attempts * this.reconnectionDelay();
 521    delay = Math.min(delay, this.reconnectionDelayMax());
 522    debug('will wait %dms before reconnect attempt', delay);
 523
 524    this.reconnecting = true;
 525    var timer = setTimeout(function(){
 526      if (self.skipReconnect) return;
 527
 528      debug('attempting reconnect');
 529      self.emitAll('reconnect_attempt', self.attempts);
 530      self.emitAll('reconnecting', self.attempts);
 531
 532      // check again for the case socket closed in above events
 533      if (self.skipReconnect) return;
 534
 535      self.open(function(err){
 536        if (err) {
 537          debug('reconnect attempt error');
 538          self.reconnecting = false;
 539          self.reconnect();
 540          self.emitAll('reconnect_error', err.data);
 541        } else {
 542          debug('reconnect success');
 543          self.onreconnect();
 544        }
 545      });
 546    }, delay);
 547
 548    this.subs.push({
 549      destroy: function(){
 550        clearTimeout(timer);
 551      }
 552    });
 553  }
 554};
 555
 556/**
 557 * Called upon successful reconnect.
 558 *
 559 * @api private
 560 */
 561
 562Manager.prototype.onreconnect = function(){
 563  var attempt = this.attempts;
 564  this.attempts = 0;
 565  this.reconnecting = false;
 566  this.emitAll('reconnect', attempt);
 567};
 568
 569},{"./on":4,"./socket":5,"./url":6,"component-bind":7,"component-emitter":8,"debug":9,"engine.io-client":10,"indexof":36,"object-component":37,"socket.io-parser":40}],4:[function(_dereq_,module,exports){
 570
 571/**
 572 * Module exports.
 573 */
 574
 575module.exports = on;
 576
 577/**
 578 * Helper for subscriptions.
 579 *
 580 * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
 581 * @param {String} event name
 582 * @param {Function} callback
 583 * @api public
 584 */
 585
 586function on(obj, ev, fn) {
 587  obj.on(ev, fn);
 588  return {
 589    destroy: function(){
 590      obj.removeListener(ev, fn);
 591    }
 592  };
 593}
 594
 595},{}],5:[function(_dereq_,module,exports){
 596
 597/**
 598 * Module dependencies.
 599 */
 600
 601var parser = _dereq_('socket.io-parser');
 602var Emitter = _dereq_('component-emitter');
 603var toArray = _dereq_('to-array');
 604var on = _dereq_('./on');
 605var bind = _dereq_('component-bind');
 606var debug = _dereq_('debug')('socket.io-client:socket');
 607var hasBin = _dereq_('has-binary');
 608
 609/**
 610 * Module exports.
 611 */
 612
 613module.exports = exports = Socket;
 614
 615/**
 616 * Internal events (blacklisted).
 617 * These events can't be emitted by the user.
 618 *
 619 * @api private
 620 */
 621
 622var events = {
 623  connect: 1,
 624  connect_error: 1,
 625  connect_timeout: 1,
 626  disconnect: 1,
 627  error: 1,
 628  reconnect: 1,
 629  reconnect_attempt: 1,
 630  reconnect_failed: 1,
 631  reconnect_error: 1,
 632  reconnecting: 1
 633};
 634
 635/**
 636 * Shortcut to `Emitter#emit`.
 637 */
 638
 639var emit = Emitter.prototype.emit;
 640
 641/**
 642 * `Socket` constructor.
 643 *
 644 * @api public
 645 */
 646
 647function Socket(io, nsp){
 648  this.io = io;
 649  this.nsp = nsp;
 650  this.json = this; // compat
 651  this.ids = 0;
 652  this.acks = {};
 653  if (this.io.autoConnect) this.open();
 654  this.receiveBuffer = [];
 655  this.sendBuffer = [];
 656  this.connected = false;
 657  this.disconnected = true;
 658}
 659
 660/**
 661 * Mix in `Emitter`.
 662 */
 663
 664Emitter(Socket.prototype);
 665
 666/**
 667 * Subscribe to open, close and packet events
 668 *
 669 * @api private
 670 */
 671
 672Socket.prototype.subEvents = function() {
 673  if (this.subs) return;
 674
 675  var io = this.io;
 676  this.subs = [
 677    on(io, 'open', bind(this, 'onopen')),
 678    on(io, 'packet', bind(this, 'onpacket')),
 679    on(io, 'close', bind(this, 'onclose'))
 680  ];
 681};
 682
 683/**
 684 * "Opens" the socket.
 685 *
 686 * @api public
 687 */
 688
 689Socket.prototype.open =
 690Socket.prototype.connect = function(){
 691  if (this.connected) return this;
 692
 693  this.subEvents();
 694  this.io.open(); // ensure open
 695  if ('open' == this.io.readyState) this.onopen();
 696  return this;
 697};
 698
 699/**
 700 * Sends a `message` event.
 701 *
 702 * @return {Socket} self
 703 * @api public
 704 */
 705
 706Socket.prototype.send = function(){
 707  var args = toArray(arguments);
 708  args.unshift('message');
 709  this.emit.apply(this, args);
 710  return this;
 711};
 712
 713/**
 714 * Override `emit`.
 715 * If the event is in `events`, it's emitted normally.
 716 *
 717 * @param {String} event name
 718 * @return {Socket} self
 719 * @api public
 720 */
 721
 722Socket.prototype.emit = function(ev){
 723  if (events.hasOwnProperty(ev)) {
 724    emit.apply(this, arguments);
 725    return this;
 726  }
 727
 728  var args = toArray(arguments);
 729  var parserType = parser.EVENT; // default
 730  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
 731  var packet = { type: parserType, data: args };
 732
 733  // event ack callback
 734  if ('function' == typeof args[args.length - 1]) {
 735    debug('emitting packet with ack id %d', this.ids);
 736    this.acks[this.ids] = args.pop();
 737    packet.id = this.ids++;
 738  }
 739
 740  if (this.connected) {
 741    this.packet(packet);
 742  } else {
 743    this.sendBuffer.push(packet);
 744  }
 745
 746  return this;
 747};
 748
 749/**
 750 * Sends a packet.
 751 *
 752 * @param {Object} packet
 753 * @api private
 754 */
 755
 756Socket.prototype.packet = function(packet){
 757  packet.nsp = this.nsp;
 758  this.io.packet(packet);
 759};
 760
 761/**
 762 * Called upon engine `open`.
 763 *
 764 * @api private
 765 */
 766
 767Socket.prototype.onopen = function(){
 768  debug('transport is open - connecting');
 769
 770  // write connect packet if necessary
 771  if ('/' != this.nsp) {
 772    this.packet({ type: parser.CONNECT });
 773  }
 774};
 775
 776/**
 777 * Called upon engine `close`.
 778 *
 779 * @param {String} reason
 780 * @api private
 781 */
 782
 783Socket.prototype.onclose = function(reason){
 784  debug('close (%s)', reason);
 785  this.connected = false;
 786  this.disconnected = true;
 787  this.emit('disconnect', reason);
 788};
 789
 790/**
 791 * Called with socket packet.
 792 *
 793 * @param {Object} packet
 794 * @api private
 795 */
 796
 797Socket.prototype.onpacket = function(packet){
 798  if (packet.nsp != this.nsp) return;
 799
 800  switch (packet.type) {
 801    case parser.CONNECT:
 802      this.onconnect();
 803      break;
 804
 805    case parser.EVENT:
 806      this.onevent(packet);
 807      break;
 808
 809    case parser.BINARY_EVENT:
 810      this.onevent(packet);
 811      break;
 812
 813    case parser.ACK:
 814      this.onack(packet);
 815      break;
 816
 817    case parser.BINARY_ACK:
 818      this.onack(packet);
 819      break;
 820
 821    case parser.DISCONNECT:
 822      this.ondisconnect();
 823      break;
 824
 825    case parser.ERROR:
 826      this.emit('error', packet.data);
 827      break;
 828  }
 829};
 830
 831/**
 832 * Called upon a server event.
 833 *
 834 * @param {Object} packet
 835 * @api private
 836 */
 837
 838Socket.prototype.onevent = function(packet){
 839  var args = packet.data || [];
 840  debug('emitting event %j', args);
 841
 842  if (null != packet.id) {
 843    debug('attaching ack callback to event');
 844    args.push(this.ack(packet.id));
 845  }
 846
 847  if (this.connected) {
 848    emit.apply(this, args);
 849  } else {
 850    this.receiveBuffer.push(args);
 851  }
 852};
 853
 854/**
 855 * Produces an ack callback to emit with an event.
 856 *
 857 * @api private
 858 */
 859
 860Socket.prototype.ack = function(id){
 861  var self = this;
 862  var sent = false;
 863  return function(){
 864    // prevent double callbacks
 865    if (sent) return;
 866    sent = true;
 867    var args = toArray(arguments);
 868    debug('sending ack %j', args);
 869
 870    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
 871    self.packet({
 872      type: type,
 873      id: id,
 874      data: args
 875    });
 876  };
 877};
 878
 879/**
 880 * Called upon a server acknowlegement.
 881 *
 882 * @param {Object} packet
 883 * @api private
 884 */
 885
 886Socket.prototype.onack = function(packet){
 887  debug('calling ack %s with %j', packet.id, packet.data);
 888  var fn = this.acks[packet.id];
 889  fn.apply(this, packet.data);
 890  delete this.acks[packet.id];
 891};
 892
 893/**
 894 * Called upon server connect.
 895 *
 896 * @api private
 897 */
 898
 899Socket.prototype.onconnect = function(){
 900  this.connected = true;
 901  this.disconnected = false;
 902  this.emit('connect');
 903  this.emitBuffered();
 904};
 905
 906/**
 907 * Emit buffered events (received and emitted).
 908 *
 909 * @api private
 910 */
 911
 912Socket.prototype.emitBuffered = function(){
 913  var i;
 914  for (i = 0; i < this.receiveBuffer.length; i++) {
 915    emit.apply(this, this.receiveBuffer[i]);
 916  }
 917  this.receiveBuffer = [];
 918
 919  for (i = 0; i < this.sendBuffer.length; i++) {
 920    this.packet(this.sendBuffer[i]);
 921  }
 922  this.sendBuffer = [];
 923};
 924
 925/**
 926 * Called upon server disconnect.
 927 *
 928 * @api private
 929 */
 930
 931Socket.prototype.ondisconnect = function(){
 932  debug('server disconnect (%s)', this.nsp);
 933  this.destroy();
 934  this.onclose('io server disconnect');
 935};
 936
 937/**
 938 * Called upon forced client/server side disconnections,
 939 * this method ensures the manager stops tracking us and
 940 * that reconnections don't get triggered for this.
 941 *
 942 * @api private.
 943 */
 944
 945Socket.prototype.destroy = function(){
 946  if (this.subs) {
 947    // clean subscriptions to avoid reconnections
 948    for (var i = 0; i < this.subs.length; i++) {
 949      this.subs[i].destroy();
 950    }
 951    this.subs = null;
 952  }
 953
 954  this.io.destroy(this);
 955};
 956
 957/**
 958 * Disconnects the socket manually.
 959 *
 960 * @return {Socket} self
 961 * @api public
 962 */
 963
 964Socket.prototype.close =
 965Socket.prototype.disconnect = function(){
 966  if (this.connected) {
 967    debug('performing disconnect (%s)', this.nsp);
 968    this.packet({ type: parser.DISCONNECT });
 969  }
 970
 971  // remove socket from pool
 972  this.destroy();
 973
 974  if (this.connected) {
 975    // fire events
 976    this.onclose('io client disconnect');
 977  }
 978  return this;
 979};
 980
 981},{"./on":4,"component-bind":7,"component-emitter":8,"debug":9,"has-binary":32,"socket.io-parser":40,"to-array":44}],6:[function(_dereq_,module,exports){
 982(function (global){
 983
 984/**
 985 * Module dependencies.
 986 */
 987
 988var parseuri = _dereq_('parseuri');
 989var debug = _dereq_('debug')('socket.io-client:url');
 990
 991/**
 992 * Module exports.
 993 */
 994
 995module.exports = url;
 996
 997/**
 998 * URL parser.
 999 *
1000 * @param {String} url
1001 * @param {Object} An object meant to mimic window.location.
1002 *                 Defaults to window.location.
1003 * @api public
1004 */
1005
1006function url(uri, loc){
1007  var obj = uri;
1008
1009  // default to window.location
1010  var loc = loc || global.location;
1011  if (null == uri) uri = loc.protocol + '//' + loc.hostname;
1012
1013  // relative path support
1014  if ('string' == typeof uri) {
1015    if ('/' == uri.charAt(0)) {
1016      if ('/' == uri.charAt(1)) {
1017        uri = loc.protocol + uri;
1018      } else {
1019        uri = loc.hostname + uri;
1020      }
1021    }
1022
1023    if (!/^(https?|wss?):\/\//.test(uri)) {
1024      debug('protocol-less url %s', uri);
1025      if ('undefined' != typeof loc) {
1026        uri = loc.protocol + '//' + uri;
1027      } else {
1028        uri = 'https://' + uri;
1029      }
1030    }
1031
1032    // parse
1033    debug('parse %s', uri);
1034    obj = parseuri(uri);
1035  }
1036
1037  // make sure we treat `localhost:80` and `localhost` equally
1038  if (!obj.port) {
1039    if (/^(http|ws)$/.test(obj.protocol)) {
1040      obj.port = '80';
1041    }
1042    else if (/^(http|ws)s$/.test(obj.protocol)) {
1043      obj.port = '443';
1044    }
1045  }
1046
1047  obj.path = obj.path || '/';
1048
1049  // define unique id
1050  obj.id = obj.protocol + '://' + obj.host + ':' + obj.port;
1051  // define href
1052  obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port));
1053
1054  return obj;
1055}
1056
1057}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1058},{"debug":9,"parseuri":38}],7:[function(_dereq_,module,exports){
1059/**
1060 * Slice reference.
1061 */
1062
1063var slice = [].slice;
1064
1065/**
1066 * Bind `obj` to `fn`.
1067 *
1068 * @param {Object} obj
1069 * @param {Function|String} fn or string
1070 * @return {Function}
1071 * @api public
1072 */
1073
1074module.exports = function(obj, fn){
1075  if ('string' == typeof fn) fn = obj[fn];
1076  if ('function' != typeof fn) throw new Error('bind() requires a function');
1077  var args = slice.call(arguments, 2);
1078  return function(){
1079    return fn.apply(obj, args.concat(slice.call(arguments)));
1080  }
1081};
1082
1083},{}],8:[function(_dereq_,module,exports){
1084
1085/**
1086 * Expose `Emitter`.
1087 */
1088
1089module.exports = Emitter;
1090
1091/**
1092 * Initialize a new `Emitter`.
1093 *
1094 * @api public
1095 */
1096
1097function Emitter(obj) {
1098  if (obj) return mixin(obj);
1099};
1100
1101/**
1102 * Mixin the emitter properties.
1103 *
1104 * @param {Object} obj
1105 * @return {Object}
1106 * @api private
1107 */
1108
1109function mixin(obj) {
1110  for (var key in Emitter.prototype) {
1111    obj[key] = Emitter.prototype[key];
1112  }
1113  return obj;
1114}
1115
1116/**
1117 * Listen on the given `event` with `fn`.
1118 *
1119 * @param {String} event
1120 * @param {Function} fn
1121 * @return {Emitter}
1122 * @api public
1123 */
1124
1125Emitter.prototype.on =
1126Emitter.prototype.addEventListener = function(event, fn){
1127  this._callbacks = this._callbacks || {};
1128  (this._callbacks[event] = this._callbacks[event] || [])
1129    .push(fn);
1130  return this;
1131};
1132
1133/**
1134 * Adds an `event` listener that will be invoked a single
1135 * time then automatically removed.
1136 *
1137 * @param {String} event
1138 * @param {Function} fn
1139 * @return {Emitter}
1140 * @api public
1141 */
1142
1143Emitter.prototype.once = function(event, fn){
1144  var self = this;
1145  this._callbacks = this._callbacks || {};
1146
1147  function on() {
1148    self.off(event, on);
1149    fn.apply(this, arguments);
1150  }
1151
1152  on.fn = fn;
1153  this.on(event, on);
1154  return this;
1155};
1156
1157/**
1158 * Remove the given callback for `event` or all
1159 * registered callbacks.
1160 *
1161 * @param {String} event
1162 * @param {Function} fn
1163 * @return {Emitter}
1164 * @api public
1165 */
1166
1167Emitter.prototype.off =
1168Emitter.prototype.removeListener =
1169Emitter.prototype.removeAllListeners =
1170Emitter.prototype.removeEventListener = function(event, fn){
1171  this._callbacks = this._callbacks || {};
1172
1173  // all
1174  if (0 == arguments.length) {
1175    this._callbacks = {};
1176    return this;
1177  }
1178
1179  // specific event
1180  var callbacks = this._callbacks[event];
1181  if (!callbacks) return this;
1182
1183  // remove all handlers
1184  if (1 == arguments.length) {
1185    delete this._callbacks[event];
1186    return this;
1187  }
1188
1189  // remove specific handler
1190  var cb;
1191  for (var i = 0; i < callbacks.length; i++) {
1192    cb = callbacks[i];
1193    if (cb === fn || cb.fn === fn) {
1194      callbacks.splice(i, 1);
1195      break;
1196    }
1197  }
1198  return this;
1199};
1200
1201/**
1202 * Emit `event` with the given args.
1203 *
1204 * @param {String} event
1205 * @param {Mixed} ...
1206 * @return {Emitter}
1207 */
1208
1209Emitter.prototype.emit = function(event){
1210  this._callbacks = this._callbacks || {};
1211  var args = [].slice.call(arguments, 1)
1212    , callbacks = this._callbacks[event];
1213
1214  if (callbacks) {
1215    callbacks = callbacks.slice(0);
1216    for (var i = 0, len = callbacks.length; i < len; ++i) {
1217      callbacks[i].apply(this, args);
1218    }
1219  }
1220
1221  return this;
1222};
1223
1224/**
1225 * Return array of callbacks for `event`.
1226 *
1227 * @param {String} event
1228 * @return {Array}
1229 * @api public
1230 */
1231
1232Emitter.prototype.listeners = function(event){
1233  this._callbacks = this._callbacks || {};
1234  return this._callbacks[event] || [];
1235};
1236
1237/**
1238 * Check if this emitter has `event` handlers.
1239 *
1240 * @param {String} event
1241 * @return {Boolean}
1242 * @api public
1243 */
1244
1245Emitter.prototype.hasListeners = function(event){
1246  return !! this.listeners(event).length;
1247};
1248
1249},{}],9:[function(_dereq_,module,exports){
1250
1251/**
1252 * Expose `debug()` as the module.
1253 */
1254
1255module.exports = debug;
1256
1257/**
1258 * Create a debugger with the given `name`.
1259 *
1260 * @param {String} name
1261 * @return {Type}
1262 * @api public
1263 */
1264
1265function debug(name) {
1266  if (!debug.enabled(name)) return function(){};
1267
1268  return function(fmt){
1269    fmt = coerce(fmt);
1270
1271    var curr = new Date;
1272    var ms = curr - (debug[name] || curr);
1273    debug[name] = curr;
1274
1275    fmt = name
1276      + ' '
1277      + fmt
1278      + ' +' + debug.humanize(ms);
1279
1280    // This hackery is required for IE8
1281    // where `console.log` doesn't have 'apply'
1282    window.console
1283      && console.log
1284      && Function.prototype.apply.call(console.log, console, arguments);
1285  }
1286}
1287
1288/**
1289 * The currently active debug mode names.
1290 */
1291
1292debug.names = [];
1293debug.skips = [];
1294
1295/**
1296 * Enables a debug mode by name. This can include modes
1297 * separated by a colon and wildcards.
1298 *
1299 * @param {String} name
1300 * @api public
1301 */
1302
1303debug.enable = function(name) {
1304  try {
1305    localStorage.debug = name;
1306  } catch(e){}
1307
1308  var split = (name || '').split(/[\s,]+/)
1309    , len = split.length;
1310
1311  for (var i = 0; i < len; i++) {
1312    name = split[i].replace('*', '.*?');
1313    if (name[0] === '-') {
1314      debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
1315    }
1316    else {
1317      debug.names.push(new RegExp('^' + name + '$'));
1318    }
1319  }
1320};
1321
1322/**
1323 * Disable debug output.
1324 *
1325 * @api public
1326 */
1327
1328debug.disable = function(){
1329  debug.enable('');
1330};
1331
1332/**
1333 * Humanize the given `ms`.
1334 *
1335 * @param {Number} m
1336 * @return {String}
1337 * @api private
1338 */
1339
1340debug.humanize = function(ms) {
1341  var sec = 1000
1342    , min = 60 * 1000
1343    , hour = 60 * min;
1344
1345  if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
1346  if (ms >= min) return (ms / min).toFixed(1) + 'm';
1347  if (ms >= sec) return (ms / sec | 0) + 's';
1348  return ms + 'ms';
1349};
1350
1351/**
1352 * Returns true if the given mode name is enabled, false otherwise.
1353 *
1354 * @param {String} name
1355 * @return {Boolean}
1356 * @api public
1357 */
1358
1359debug.enabled = function(name) {
1360  for (var i = 0, len = debug.skips.length; i < len; i++) {
1361    if (debug.skips[i].test(name)) {
1362      return false;
1363    }
1364  }
1365  for (var i = 0, len = debug.names.length; i < len; i++) {
1366    if (debug.names[i].test(name)) {
1367      return true;
1368    }
1369  }
1370  return false;
1371};
1372
1373/**
1374 * Coerce `val`.
1375 */
1376
1377function coerce(val) {
1378  if (val instanceof Error) return val.stack || val.message;
1379  return val;
1380}
1381
1382// persist
1383
1384try {
1385  if (window.localStorage) debug.enable(localStorage.debug);
1386} catch(e){}
1387
1388},{}],10:[function(_dereq_,module,exports){
1389
1390module.exports =  _dereq_('./lib/');
1391
1392},{"./lib/":11}],11:[function(_dereq_,module,exports){
1393
1394module.exports = _dereq_('./socket');
1395
1396/**
1397 * Exports parser
1398 *
1399 * @api public
1400 *
1401 */
1402module.exports.parser = _dereq_('engine.io-parser');
1403
1404},{"./socket":12,"engine.io-parser":21}],12:[function(_dereq_,module,exports){
1405(function (global){
1406/**
1407 * Module dependencies.
1408 */
1409
1410var transports = _dereq_('./transports');
1411var Emitter = _dereq_('component-emitter');
1412var debug = _dereq_('debug')('engine.io-client:socket');
1413var index = _dereq_('indexof');
1414var parser = _dereq_('engine.io-parser');
1415var parseuri = _dereq_('parseuri');
1416var parsejson = _dereq_('parsejson');
1417var parseqs = _dereq_('parseqs');
1418
1419/**
1420 * Module exports.
1421 */
1422
1423module.exports = Socket;
1424
1425/**
1426 * Noop function.
1427 *
1428 * @api private
1429 */
1430
1431function noop(){}
1432
1433/**
1434 * Socket constructor.
1435 *
1436 * @param {String|Object} uri or options
1437 * @param {Object} options
1438 * @api public
1439 */
1440
1441function Socket(uri, opts){
1442  if (!(this instanceof Socket)) return new Socket(uri, opts);
1443
1444  opts = opts || {};
1445
1446  if (uri && 'object' == typeof uri) {
1447    opts = uri;
1448    uri = null;
1449  }
1450
1451  if (uri) {
1452    uri = parseuri(uri);
1453    opts.host = uri.host;
1454    opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
1455    opts.port = uri.port;
1456    if (uri.query) opts.query = uri.query;
1457  }
1458
1459  this.secure = null != opts.secure ? opts.secure :
1460    (global.location && 'https:' == location.protocol);
1461
1462  if (opts.host) {
1463    var pieces = opts.host.split(':');
1464    opts.hostname = pieces.shift();
1465    if (pieces.length) opts.port = pieces.pop();
1466  }
1467
1468  this.agent = opts.agent || false;
1469  this.hostname = opts.hostname ||
1470    (global.location ? location.hostname : 'localhost');
1471  this.port = opts.port || (global.location && location.port ?
1472       location.port :
1473       (this.secure ? 443 : 80));
1474  this.query = opts.query || {};
1475  if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
1476  this.upgrade = false !== opts.upgrade;
1477  this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
1478  this.forceJSONP = !!opts.forceJSONP;
1479  this.jsonp = false !== opts.jsonp;
1480  this.forceBase64 = !!opts.forceBase64;
1481  this.enablesXDR = !!opts.enablesXDR;
1482  this.timestampParam = opts.timestampParam || 't';
1483  this.timestampRequests = opts.timestampRequests;
1484  this.transports = opts.transports || ['polling', 'websocket'];
1485  this.readyState = '';
1486  this.writeBuffer = [];
1487  this.callbackBuffer = [];
1488  this.policyPort = opts.policyPort || 843;
1489  this.rememberUpgrade = opts.rememberUpgrade || false;
1490  this.open();
1491  this.binaryType = null;
1492  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
1493}
1494
1495Socket.priorWebsocketSuccess = false;
1496
1497/**
1498 * Mix in `Emitter`.
1499 */
1500
1501Emitter(Socket.prototype);
1502
1503/**
1504 * Protocol version.
1505 *
1506 * @api public
1507 */
1508
1509Socket.protocol = parser.protocol; // this is an int
1510
1511/**
1512 * Expose deps for legacy compatibility
1513 * and standalone browser access.
1514 */
1515
1516Socket.Socket = Socket;
1517Socket.Transport = _dereq_('./transport');
1518Socket.transports = _dereq_('./transports');
1519Socket.parser = _dereq_('engine.io-parser');
1520
1521/**
1522 * Creates transport of the given type.
1523 *
1524 * @param {String} transport name
1525 * @return {Transport}
1526 * @api private
1527 */
1528
1529Socket.prototype.createTransport = function (name) {
1530  debug('creating transport "%s"', name);
1531  var query = clone(this.query);
1532
1533  // append engine.io protocol identifier
1534  query.EIO = parser.protocol;
1535
1536  // transport name
1537  query.transport = name;
1538
1539  // session id if we already have one
1540  if (this.id) query.sid = this.id;
1541
1542  var transport = new transports[name]({
1543    agent: this.agent,
1544    hostname: this.hostname,
1545    port: this.port,
1546    secure: this.secure,
1547    path: this.path,
1548    query: query,
1549    forceJSONP: this.forceJSONP,
1550    jsonp: this.jsonp,
1551    forceBase64: this.forceBase64,
1552    enablesXDR: this.enablesXDR,
1553    timestampRequests: this.timestampRequests,
1554    timestampParam: this.timestampParam,
1555    policyPort: this.policyPort,
1556    socket: this
1557  });
1558
1559  return transport;
1560};
1561
1562function clone (obj) {
1563  var o = {};
1564  for (var i in obj) {
1565    if (obj.hasOwnProperty(i)) {
1566      o[i] = obj[i];
1567    }
1568  }
1569  return o;
1570}
1571
1572/**
1573 * Initializes transport to use and starts probe.
1574 *
1575 * @api private
1576 */
1577Socket.prototype.open = function () {
1578  var transport;
1579  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
1580    transport = 'websocket';
1581  } else if (0 == this.transports.length) {
1582    // Emit error on next tick so it can be listened to
1583    var self = this;
1584    setTimeout(function() {
1585      self.emit('error', 'No transports available');
1586    }, 0);
1587    return;
1588  } else {
1589    transport = this.transports[0];
1590  }
1591  this.readyState = 'opening';
1592
1593  // Retry with the next transport if the transport is disabled (jsonp: false)
1594  var transport;
1595  try {
1596    transport = this.createTransport(transport);
1597  } catch (e) {
1598    this.transports.shift();
1599    this.open();
1600    return;
1601  }
1602
1603  transport.open();
1604  this.setTransport(transport);
1605};
1606
1607/**
1608 * Sets the current transport. Disables the existing one (if any).
1609 *
1610 * @api private
1611 */
1612
1613Socket.prototype.setTransport = function(transport){
1614  debug('setting transport %s', transport.name);
1615  var self = this;
1616
1617  if (this.transport) {
1618    debug('clearing existing transport %s', this.transport.name);
1619    this.transport.removeAllListeners();
1620  }
1621
1622  // set up transport
1623  this.transport = transport;
1624
1625  // set up transport listeners
1626  transport
1627  .on('drain', function(){
1628    self.onDrain();
1629  })
1630  .on('packet', function(packet){
1631    self.onPacket(packet);
1632  })
1633  .on('error', function(e){
1634    self.onError(e);
1635  })
1636  .on('close', function(){
1637    self.onClose('transport close');
1638  });
1639};
1640
1641/**
1642 * Probes a transport.
1643 *
1644 * @param {String} transport name
1645 * @api private
1646 */
1647
1648Socket.prototype.probe = function (name) {
1649  debug('probing transport "%s"', name);
1650  var transport = this.createTransport(name, { probe: 1 })
1651    , failed = false
1652    , self = this;
1653
1654  Socket.priorWebsocketSuccess = false;
1655
1656  function onTransportOpen(){
1657    if (self.onlyBinaryUpgrades) {
1658      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
1659      failed = failed || upgradeLosesBinary;
1660    }
1661    if (failed) return;
1662
1663    debug('probe transport "%s" opened', name);
1664    transport.send([{ type: 'ping', data: 'probe' }]);
1665    transport.once('packet', function (msg) {
1666      if (failed) return;
1667      if ('pong' == msg.type && 'probe' == msg.data) {
1668        debug('probe transport "%s" pong', name);
1669        self.upgrading = true;
1670        self.emit('upgrading', transport);
1671        if (!transport) return;
1672        Socket.priorWebsocketSuccess = 'websocket' == transport.name;
1673
1674        debug('pausing current transport "%s"', self.transport.name);
1675        self.transport.pause(function () {
1676          if (failed) return;
1677          if ('closed' == self.readyState) return;
1678          debug('changing transport and sending upgrade packet');
1679
1680          cleanup();
1681
1682          self.setTransport(transport);
1683          transport.send([{ type: 'upgrade' }]);
1684          self.emit('upgrade', transport);
1685          transport = null;
1686          self.upgrading = false;
1687          self.flush();
1688        });
1689      } else {
1690        debug('probe transport "%s" failed', name);
1691        var err = new Error('probe error');
1692        err.transport = transport.name;
1693        self.emit('upgradeError', err);
1694      }
1695    });
1696  }
1697
1698  function freezeTransport() {
1699    if (failed) return;
1700
1701    // Any callback called by transport should be ignored since now
1702    failed = true;
1703
1704    cleanup();
1705
1706    transport.close();
1707    transport = null;
1708  }
1709
1710  //Handle any error that happens while probing
1711  function onerror(err) {
1712    var error = new Error('probe error: ' + err);
1713    error.transport = transport.name;
1714
1715    freezeTransport();
1716
1717    debug('probe transport "%s" failed because of error: %s', name, err);
1718
1719    self.emit('upgradeError', error);
1720  }
1721
1722  function onTransportClose(){
1723    onerror("transport closed");
1724  }
1725
1726  //When the socket is closed while we're probing
1727  function onclose(){
1728    onerror("socket closed");
1729  }
1730
1731  //When the socket is upgraded while we're probing
1732  function onupgrade(to){
1733    if (transport && to.name != transport.name) {
1734      debug('"%s" works - aborting "%s"', to.name, transport.name);
1735      freezeTransport();
1736    }
1737  }
1738
1739  //Remove all listeners on the transport and on self
1740  function cleanup(){
1741    transport.removeListener('open', onTransportOpen);
1742    transport.removeListener('error', onerror);
1743    transport.removeListener('close', onTransportClose);
1744    self.removeListener('close', onclose);
1745    self.removeListener('upgrading', onupgrade);
1746  }
1747
1748  transport.once('open', onTransportOpen);
1749  transport.once('error', onerror);
1750  transport.once('close', onTransportClose);
1751
1752  this.once('close', onclose);
1753  this.once('upgrading', onupgrade);
1754
1755  transport.open();
1756
1757};
1758
1759/**
1760 * Called when connection is deemed open.
1761 *
1762 * @api public
1763 */
1764
1765Socket.prototype.onOpen = function () {
1766  debug('socket open');
1767  this.readyState = 'open';
1768  Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
1769  this.emit('open');
1770  this.flush();
1771
1772  // we check for `readyState` in case an `open`
1773  // listener already closed the socket
1774  if ('open' == this.readyState && this.upgrade && this.transport.pause) {
1775    debug('starting upgrade probes');
1776    for (var i = 0, l = this.upgrades.length; i < l; i++) {
1777      this.probe(this.upgrades[i]);
1778    }
1779  }
1780};
1781
1782/**
1783 * Handles a packet.
1784 *
1785 * @api private
1786 */
1787
1788Socket.prototype.onPacket = function (packet) {
1789  if ('opening' == this.readyState || 'open' == this.readyState) {
1790    debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
1791
1792    this.emit('packet', packet);
1793
1794    // Socket is live - any packet counts
1795    this.emit('heartbeat');
1796
1797    switch (packet.type) {
1798      case 'open':
1799        this.onHandshake(parsejson(packet.data));
1800        break;
1801
1802      case 'pong':
1803        this.setPing();
1804        break;
1805
1806      case 'error':
1807        var err = new Error('server error');
1808        err.code = packet.data;
1809        this.emit('error', err);
1810        break;
1811
1812      case 'message':
1813        this.emit('data', packet.data);
1814        this.emit('message', packet.data);
1815        break;
1816    }
1817  } else {
1818    debug('packet received with socket readyState "%s"', this.readyState);
1819  }
1820};
1821
1822/**
1823 * Called upon handshake completion.
1824 *
1825 * @param {Object} handshake obj
1826 * @api private
1827 */
1828
1829Socket.prototype.onHandshake = function (data) {
1830  this.emit('handshake', data);
1831  this.id = data.sid;
1832  this.transport.query.sid = data.sid;
1833  this.upgrades = this.filterUpgrades(data.upgrades);
1834  this.pingInterval = data.pingInterval;
1835  this.pingTimeout = data.pingTimeout;
1836  this.onOpen();
1837  // In case open handler closes socket
1838  if  ('closed' == this.readyState) return;
1839  this.setPing();
1840
1841  // Prolong liveness of socket on heartbeat
1842  this.removeListener('heartbeat', this.onHeartbeat);
1843  this.on('heartbeat', this.onHeartbeat);
1844};
1845
1846/**
1847 * Resets ping timeout.
1848 *
1849 * @api private
1850 */
1851
1852Socket.prototype.onHeartbeat = function (timeout) {
1853  clearTimeout(this.pingTimeoutTimer);
1854  var self = this;
1855  self.pingTimeoutTimer = setTimeout(function () {
1856    if ('closed' == self.readyState) return;
1857    self.onClose('ping timeout');
1858  }, timeout || (self.pingInterval + self.pingTimeout));
1859};
1860
1861/**
1862 * Pings server every `this.pingInterval` and expects response
1863 * within `this.pingTimeout` or closes connection.
1864 *
1865 * @api private
1866 */
1867
1868Socket.prototype.setPing = function () {
1869  var self = this;
1870  clearTimeout(self.pingIntervalTimer);
1871  self.pingIntervalTimer = setTimeout(function () {
1872    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
1873    self.ping();
1874    self.onHeartbeat(self.pingTimeout);
1875  }, self.pingInterval);
1876};
1877
1878/**
1879* Sends a ping packet.
1880*
1881* @api public
1882*/
1883
1884Socket.prototype.ping = function () {
1885  this.sendPacket('ping');
1886};
1887
1888/**
1889 * Called on `drain` event
1890 *
1891 * @api private
1892 */
1893
1894Socket.prototype.onDrain = function() {
1895  for (var i = 0; i < this.prevBufferLen; i++) {
1896    if (this.callbackBuffer[i]) {
1897      this.callbackBuffer[i]();
1898    }
1899  }
1900
1901  this.writeBuffer.splice(0, this.prevBufferLen);
1902  this.callbackBuffer.splice(0, this.prevBufferLen);
1903
1904  // setting prevBufferLen = 0 is very important
1905  // for example, when upgrading, upgrade packet is sent over,
1906  // and a nonzero prevBufferLen could cause problems on `drain`
1907  this.prevBufferLen = 0;
1908
1909  if (this.writeBuffer.length == 0) {
1910    this.emit('drain');
1911  } else {
1912    this.flush();
1913  }
1914};
1915
1916/**
1917 * Flush write buffers.
1918 *
1919 * @api private
1920 */
1921
1922Socket.prototype.flush = function () {
1923  if ('closed' != this.readyState && this.transport.writable &&
1924    !this.upgrading && this.writeBuffer.length) {
1925    debug('flushing %d packets in socket', this.writeBuffer.length);
1926    this.transport.send(this.writeBuffer);
1927    // keep track of current length of writeBuffer
1928    // splice writeBuffer and callbackBuffer on `drain`
1929    this.prevBufferLen = this.writeBuffer.length;
1930    this.emit('flush');
1931  }
1932};
1933
1934/**
1935 * Sends a message.
1936 *
1937 * @param {String} message.
1938 * @param {Function} callback function.
1939 * @return {Socket} for chaining.
1940 * @api public
1941 */
1942
1943Socket.prototype.write =
1944Socket.prototype.send = function (msg, fn) {
1945  this.sendPacket('message', msg, fn);
1946  return this;
1947};
1948
1949/**
1950 * Sends a packet.
1951 *
1952 * @param {String} packet type.
1953 * @param {String} data.
1954 * @param {Function} callback function.
1955 * @api private
1956 */
1957
1958Socket.prototype.sendPacket = function (type, data, fn) {
1959  if ('closing' == this.readyState || 'closed' == this.readyState) {
1960    return;
1961  }
1962
1963  var packet = { type: type, data: data };
1964  this.emit('packetCreate', packet);
1965  this.writeBuffer.push(packet);
1966  this.callbackBuffer.push(fn);
1967  this.flush();
1968};
1969
1970/**
1971 * Closes the connection.
1972 *
1973 * @api private
1974 */
1975
1976Socket.prototype.close = function () {
1977  if ('opening' == this.readyState || 'open' == this.readyState) {
1978    this.readyState = 'closing';
1979
1980    var self = this;
1981
1982    function close() {
1983      self.onClose('forced close');
1984      debug('socket closing - telling transport to close');
1985      self.transport.close();
1986    }
1987
1988    function cleanupAndClose() {
1989      self.removeListener('upgrade', cleanupAndClose);
1990      self.removeListener('upgradeError', cleanupAndClose);
1991      close();
1992    }
1993
1994    function waitForUpgrade() {
1995      // wait for upgrade to finish since we can't send packets while pausing a transport
1996      self.once('upgrade', cleanupAndClose);
1997      self.once('upgradeError', cleanupAndClose);
1998    }
1999
2000    if (this.writeBuffer.length) {
2001      this.once('drain', function() {
2002        if (this.upgrading) {
2003          waitForUpgrade();
2004        } else {
2005          close();
2006        }
2007      });
2008    } else if (this.upgrading) {
2009      waitForUpgrade();
2010    } else {
2011      close();
2012    }
2013  }
2014
2015  return this;
2016};
2017
2018/**
2019 * Called upon transport error
2020 *
2021 * @api private
2022 */
2023
2024Socket.prototype.onError = function (err) {
2025  debug('socket error %j', err);
2026  Socket.priorWebsocketSuccess = false;
2027  this.emit('error', err);
2028  this.onClose('transport error', err);
2029};
2030
2031/**
2032 * Called upon transport close.
2033 *
2034 * @api private
2035 */
2036
2037Socket.prototype.onClose = function (reason, desc) {
2038  if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
2039    debug('socket close with reason: "%s"', reason);
2040    var self = this;
2041
2042    // clear timers
2043    clearTimeout(this.pingIntervalTimer);
2044    clearTimeout(this.pingTimeoutTimer);
2045
2046    // clean buffers in next tick, so developers can still
2047    // grab the buffers on `close` event
2048    setTimeout(function() {
2049      self.writeBuffer = [];
2050      self.callbackBuffer = [];
2051      self.prevBufferLen = 0;
2052    }, 0);
2053
2054    // stop event from firing again for transport
2055    this.transport.removeAllListeners('close');
2056
2057    // ensure transport won't stay open
2058    this.transport.close();
2059
2060    // ignore further transport communication
2061    this.transport.removeAllListeners();
2062
2063    // set ready state
2064    this.readyState = 'closed';
2065
2066    // clear session id
2067    this.id = null;
2068
2069    // emit close event
2070    this.emit('close', reason, desc);
2071  }
2072};
2073
2074/**
2075 * Filters upgrades, returning only those matching client transports.
2076 *
2077 * @param {Array} server upgrades
2078 * @api private
2079 *
2080 */
2081
2082Socket.prototype.filterUpgrades = function (upgrades) {
2083  var filteredUpgrades = [];
2084  for (var i = 0, j = upgrades.length; i<j; i++) {
2085    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
2086  }
2087  return filteredUpgrades;
2088};
2089
2090}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2091},{"./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){
2092/**
2093 * Module dependencies.
2094 */
2095
2096var parser = _dereq_('engine.io-parser');
2097var Emitter = _dereq_('component-emitter');
2098
2099/**
2100 * Module exports.
2101 */
2102
2103module.exports = Transport;
2104
2105/**
2106 * Transport abstract constructor.
2107 *
2108 * @param {Object} options.
2109 * @api private
2110 */
2111
2112function Transport (opts) {
2113  this.path = opts.path;
2114  this.hostname = opts.hostname;
2115  this.port = opts.port;
2116  this.secure = opts.secure;
2117  this.query = opts.query;
2118  this.timestampParam = opts.timestampParam;
2119  this.timestampRequests = opts.timestampRequests;
2120  this.readyState = '';
2121  this.agent = opts.agent || false;
2122  this.socket = opts.socket;
2123  this.enablesXDR = opts.enablesXDR;
2124}
2125
2126/**
2127 * Mix in `Emitter`.
2128 */
2129
2130Emitter(Transport.prototype);
2131
2132/**
2133 * A counter used to prevent collisions in the timestamps used
2134 * for cache busting.
2135 */
2136
2137Transport.timestamps = 0;
2138
2139/**
2140 * Emits an error.
2141 *
2142 * @param {String} str
2143 * @return {Transport} for chaining
2144 * @api public
2145 */
2146
2147Transport.prototype.onError = function (msg, desc) {
2148  var err = new Error(msg);
2149  err.type = 'TransportError';
2150  err.description = desc;
2151  this.emit('error', err);
2152  return this;
2153};
2154
2155/**
2156 * Opens the transport.
2157 *
2158 * @api public
2159 */
2160
2161Transport.prototype.open = function () {
2162  if ('closed' == this.readyState || '' == this.readyState) {
2163    this.readyState = 'opening';
2164    this.doOpen();
2165  }
2166
2167  return this;
2168};
2169
2170/**
2171 * Closes the transport.
2172 *
2173 * @api private
2174 */
2175
2176Transport.prototype.close = function () {
2177  if ('opening' == this.readyState || 'open' == this.readyState) {
2178    this.doClose();
2179    this.onClose();
2180  }
2181
2182  return this;
2183};
2184
2185/**
2186 * Sends multiple packets.
2187 *
2188 * @param {Array} packets
2189 * @api private
2190 */
2191
2192Transport.prototype.send = function(packets){
2193  if ('open' == this.readyState) {
2194    this.write(packets);
2195  } else {
2196    throw new Error('Transport not open');
2197  }
2198};
2199
2200/**
2201 * Called upon open
2202 *
2203 * @api private
2204 */
2205
2206Transport.prototype.onOpen = function () {
2207  this.readyState = 'open';
2208  this.writable = true;
2209  this.emit('open');
2210};
2211
2212/**
2213 * Called with data.
2214 *
2215 * @param {String} data
2216 * @api private
2217 */
2218
2219Transport.prototype.onData = function(data){
2220  var packet = parser.decodePacket(data, this.socket.binaryType);
2221  this.onPacket(packet);
2222};
2223
2224/**
2225 * Called with a decoded packet.
2226 */
2227
2228Transport.prototype.onPacket = function (packet) {
2229  this.emit('packet', packet);
2230};
2231
2232/**
2233 * Called upon close.
2234 *
2235 * @api private
2236 */
2237
2238Transport.prototype.onClose = function () {
2239  this.readyState = 'closed';
2240  this.emit('close');
2241};
2242
2243},{"component-emitter":8,"engine.io-parser":21}],14:[function(_dereq_,module,exports){
2244(function (global){
2245/**
2246 * Module dependencies
2247 */
2248
2249var XMLHttpRequest = _dereq_('xmlhttprequest');
2250var XHR = _dereq_('./polling-xhr');
2251var JSONP = _dereq_('./polling-jsonp');
2252var websocket = _dereq_('./websocket');
2253
2254/**
2255 * Export transports.
2256 */
2257
2258exports.polling = polling;
2259exports.websocket = websocket;
2260
2261/**
2262 * Polling transport polymorphic constructor.
2263 * Decides on xhr vs jsonp based on feature detection.
2264 *
2265 * @api private
2266 */
2267
2268function polling(opts){
2269  var xhr;
2270  var xd = false;
2271  var xs = false;
2272  var jsonp = false !== opts.jsonp;
2273
2274  if (global.location) {
2275    var isSSL = 'https:' == location.protocol;
2276    var port = location.port;
2277
2278    // some user agents have empty `location.port`
2279    if (!port) {
2280      port = isSSL ? 443 : 80;
2281    }
2282
2283    xd = opts.hostname != location.hostname || port != opts.port;
2284    xs = opts.secure != isSSL;
2285  }
2286
2287  opts.xdomain = xd;
2288  opts.xscheme = xs;
2289  xhr = new XMLHttpRequest(opts);
2290
2291  if ('open' in xhr && !opts.forceJSONP) {
2292    return new XHR(opts);
2293  } else {
2294    if (!jsonp) throw new Error('JSONP disabled');
2295    return new JSONP(opts);
2296  }
2297}
2298
2299}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2300},{"./polling-jsonp":15,"./polling-xhr":16,"./websocket":18,"xmlhttprequest":19}],15:[function(_dereq_,module,exports){
2301(function (global){
2302
2303/**
2304 * Module requirements.
2305 */
2306
2307var Polling = _dereq_('./polling');
2308var inherit = _dereq_('component-inherit');
2309
2310/**
2311 * Module exports.
2312 */
2313
2314module.exports = JSONPPolling;
2315
2316/**
2317 * Cached regular expressions.
2318 */
2319
2320var rNewline = /\n/g;
2321var rEscapedNewline = /\\n/g;
2322
2323/**
2324 * Global JSONP callbacks.
2325 */
2326
2327var callbacks;
2328
2329/**
2330 * Callbacks count.
2331 */
2332
2333var index = 0;
2334
2335/**
2336 * Noop.
2337 */
2338
2339function empty () { }
2340
2341/**
2342 * JSONP Polling constructor.
2343 *
2344 * @param {Object} opts.
2345 * @api public
2346 */
2347
2348function JSONPPolling (opts) {
2349  Polling.call(this, opts);
2350
2351  this.query = this.query || {};
2352
2353  // define global callbacks array if not present
2354  // we do this here (lazily) to avoid unneeded global pollution
2355  if (!callbacks) {
2356    // we need to consider multiple engines in the same page
2357    if (!global.___eio) global.___eio = [];
2358    callbacks = global.___eio;
2359  }
2360
2361  // callback identifier
2362  this.index = callbacks.length;
2363
2364  // add callback to jsonp global
2365  var self = this;
2366  callbacks.push(function (msg) {
2367    self.onData(msg);
2368  });
2369
2370  // append to query string
2371  this.query.j = this.index;
2372
2373  // prevent spurious errors from being emitted when the window is unloaded
2374  if (global.document && global.addEventListener) {
2375    global.addEventListener('beforeunload', function () {
2376      if (self.script) self.script.onerror = empty;
2377    });
2378  }
2379}
2380
2381/**
2382 * Inherits from Polling.
2383 */
2384
2385inherit(JSONPPolling, Polling);
2386
2387/*
2388 * JSONP only supports binary as base64 encoded strings
2389 */
2390
2391JSONPPolling.prototype.supportsBinary = false;
2392
2393/**
2394 * Closes the socket.
2395 *
2396 * @api private
2397 */
2398
2399JSONPPolling.prototype.doClose = function () {
2400  if (this.script) {
2401    this.script.parentNode.removeChild(this.script);
2402    this.script = null;
2403  }
2404
2405  if (this.form) {
2406    this.form.parentNode.removeChild(this.form);
2407    this.form = null;
2408    this.iframe = null;
2409  }
2410
2411  Polling.prototype.doClose.call(this);
2412};
2413
2414/**
2415 * Starts a poll cycle.
2416 *
2417 * @api private
2418 */
2419
2420JSONPPolling.prototype.doPoll = function () {
2421  var self = this;
2422  var script = document.createElement('script');
2423
2424  if (this.script) {
2425    this.script.parentNode.removeChild(this.script);
2426    this.script = null;
2427  }
2428
2429  script.async = true;
2430  script.src = this.uri();
2431  script.onerror = function(e){
2432    self.onError('jsonp poll error',e);
2433  };
2434
2435  var insertAt = document.getElementsByTagName('script')[0];
2436  insertAt.parentNode.insertBefore(script, insertAt);
2437  this.script = script;
2438
2439  var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);
2440  
2441  if (isUAgecko) {
2442    setTimeout(function () {
2443      var iframe = document.createElement('iframe');
2444      document.body.appendChild(iframe);
2445      document.body.removeChild(iframe);
2446    }, 100);
2447  }
2448};
2449
2450/**
2451 * Writes with a hidden iframe.
2452 *
2453 * @param {String} data to send
2454 * @param {Function} called upon flush.
2455 * @api private
2456 */
2457
2458JSONPPolling.prototype.doWrite = function (data, fn) {
2459  var self = this;
2460
2461  if (!this.form) {
2462    var form = document.createElement('form');
2463    var area = document.createElement('textarea');
2464    var id = this.iframeId = 'eio_iframe_' + this.index;
2465    var iframe;
2466
2467    form.className = 'socketio';
2468    form.style.position = 'absolute';
2469    form.style.top = '-1000px';
2470    form.style.left = '-1000px';
2471    form.target = id;
2472    form.method = 'POST';
2473    form.setAttribute('accept-charset', 'utf-8');
2474    area.name = 'd';
2475    form.appendChild(area);
2476    document.body.appendChild(form);
2477
2478    this.form = form;
2479    this.area = area;
2480  }
2481
2482  this.form.action = this.uri();
2483
2484  function complete () {
2485    initIframe();
2486    fn();
2487  }
2488
2489  function initIframe () {
2490    if (self.iframe) {
2491      try {
2492        self.form.removeChild(self.iframe);
2493      } catch (e) {
2494        self.onError('jsonp polling iframe removal error', e);
2495      }
2496    }
2497
2498    try {
2499      // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
2500      var html = '<iframe src="javascript:0" name="'+ self.iframeId +'">';
2501      iframe = document.createElement(html);
2502    } catch (e) {
2503      iframe = document.createElement('iframe');
2504      iframe.name = self.iframeId;
2505      iframe.src = 'javascript:0';
2506    }
2507
2508    iframe.id = self.iframeId;
2509
2510    self.form.appendChild(iframe);
2511    self.iframe = iframe;
2512  }
2513
2514  initIframe();
2515
2516  // escape \n to prevent it from being converted into \r\n by some UAs
2517  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
2518  data = data.replace(rEscapedNewline, '\\\n');
2519  this.area.value = data.replace(rNewline, '\\n');
2520
2521  try {
2522    this.form.submit();
2523  } catch(e) {}
2524
2525  if (this.iframe.attachEvent) {
2526    this.iframe.onreadystatechange = function(){
2527      if (self.iframe.readyState == 'complete') {
2528        complete();
2529      }
2530    };
2531  } else {
2532    this.iframe.onload = complete;
2533  }
2534};
2535
2536}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2537},{"./polling":17,"component-inherit":20}],16:[function(_dereq_,module,exports){
2538(function (global){
2539/**
2540 * Module requirements.
2541 */
2542
2543var XMLHttpRequest = _dereq_('xmlhttprequest');
2544var Polling = _dereq_('./polling');
2545var Emitter = _dereq_('component-emitter');
2546var inherit = _dereq_('component-inherit');
2547var debug = _dereq_('debug')('engine.io-client:polling-xhr');
2548
2549/**
2550 * Module exports.
2551 */
2552
2553module.exports = XHR;
2554module.exports.Request = Request;
2555
2556/**
2557 * Empty function
2558 */
2559
2560function empty(){}
2561
2562/**
2563 * XHR Polling constructor.
2564 *
2565 * @param {Object} opts
2566 * @api public
2567 */
2568
2569function XHR(opts){
2570  Polling.call(this, opts);
2571
2572  if (global.location) {
2573    var isSSL = 'https:' == location.protocol;
2574    var port = location.port;
2575
2576    // some user agents have empty `location.port`
2577    if (!port) {
2578      port = isSSL ? 443 : 80;
2579    }
2580
2581    this.xd = opts.hostname != global.location.hostname ||
2582      port != opts.port;
2583    this.xs = opts.secure != isSSL;
2584  }
2585}
2586
2587/**
2588 * Inherits from Polling.
2589 */
2590
2591inherit(XHR, Polling);
2592
2593/**
2594 * XHR supports binary
2595 */
2596
2597XHR.prototype.supportsBinary = true;
2598
2599/**
2600 * Creates a request.
2601 *
2602 * @param {String} method
2603 * @api private
2604 */
2605
2606XHR.prototype.request = function(opts){
2607  opts = opts || {};
2608  opts.uri = this.uri();
2609  opts.xd = this.xd;
2610  opts.xs = this.xs;
2611  opts.agent = this.agent || false;
2612  opts.supportsBinary = this.supportsBinary;
2613  opts.enablesXDR = this.enablesXDR;
2614  return new Request(opts);
2615};
2616
2617/**
2618 * Sends data.
2619 *
2620 * @param {String} data to send.
2621 * @param {Function} called upon flush.
2622 * @api private
2623 */
2624
2625XHR.prototype.doWrite = function(data, fn){
2626  var isBinary = typeof data !== 'string' && data !== undefined;
2627  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
2628  var self = this;
2629  req.on('success', fn);
2630  req.on('error', function(err){
2631    self.onError('xhr post error', err);
2632  });
2633  this.sendXhr = req;
2634};
2635
2636/**
2637 * Starts a poll cycle.
2638 *
2639 * @api private
2640 */
2641
2642XHR.prototype.doPoll = function(){
2643  debug('xhr poll');
2644  var req = this.request();
2645  var self = this;
2646  req.on('data', function(data){
2647    self.onData(data);
2648  });
2649  req.on('error', function(err){
2650    self.onError('xhr poll error', err);
2651  });
2652  this.pollXhr = req;
2653};
2654
2655/**
2656 * Request constructor
2657 *
2658 * @param {Object} options
2659 * @api public
2660 */
2661
2662function Request(opts){
2663  this.method = opts.method || 'GET';
2664  this.uri = opts.uri;
2665  this.xd = !!opts.xd;
2666  this.xs = !!opts.xs;
2667  this.async = false !== opts.async;
2668  this.data = undefined != opts.data ? opts.data : null;
2669  this.agent = opts.agent;
2670  this.isBinary = opts.isBinary;
2671  this.supportsBinary = opts.supportsBinary;
2672  this.enablesXDR = opts.enablesXDR;
2673  this.create();
2674}
2675
2676/**
2677 * Mix in `Emitter`.
2678 */
2679
2680Emitter(Request.prototype);
2681
2682/**
2683 * Creates the XHR object and sends the request.
2684 *
2685 * @api private
2686 */
2687
2688Request.prototype.create = function(){
2689  var xhr = this.xhr = new XMLHttpRequest({ agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR });
2690  var self = this;
2691
2692  try {
2693    debug('xhr open %s: %s', this.method, this.uri);
2694    xhr.open(this.method, this.uri, this.async);
2695    if (this.supportsBinary) {
2696      // This has to be done after open because Firefox is stupid
2697      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
2698      xhr.responseType = 'arraybuffer';
2699    }
2700
2701    if ('POST' == this.method) {
2702      try {
2703        if (this.isBinary) {
2704          xhr.setRequestHeader('Content-type', 'application/octet-stream');
2705        } else {
2706          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
2707        }
2708      } catch (e) {}
2709    }
2710
2711    // ie6 check
2712    if ('withCredentials' in xhr) {
2713      xhr.withCredentials = true;
2714    }
2715
2716    if (this.hasXDR()) {
2717      xhr.onload = function(){
2718        self.onLoad();
2719      };
2720      xhr.onerror = function(){
2721        self.onError(xhr.responseText);
2722      };
2723    } else {
2724      xhr.onreadystatechange = function(){
2725        if (4 != xhr.readyState) return;
2726        if (200 == xhr.status || 1223 == xhr.status) {
2727          self.onLoad();
2728        } else {
2729          // make sure the `error` event handler that's user-set
2730          // does not throw in the same tick and gets caught here
2731          setTimeout(function(){
2732            self.onError(xhr.status);
2733          }, 0);
2734        }
2735      };
2736    }
2737
2738    debug('xhr data %s', this.data);
2739    xhr.send(this.data);
2740  } catch (e) {
2741    // Need to defer since .create() is called directly fhrom the constructor
2742    // and thus the 'error' event can only be only bound *after* this exception
2743    // occurs.  Therefore, also, we cannot throw here at all.
2744    setTimeout(function() {
2745      self.onError(e);
2746    }, 0);
2747    return;
2748  }
2749
2750  if (global.document) {
2751    this.index = Request.requestsCount++;
2752    Request.requests[this.index] = this;
2753  }
2754};
2755
2756/**
2757 * Called upon successful response.
2758 *
2759 * @api private
2760 */
2761
2762Request.prototype.onSuccess = function(){
2763  this.emit('success');
2764  this.cleanup();
2765};
2766
2767/**
2768 * Called if we have data.
2769 *
2770 * @api private
2771 */
2772
2773Request.prototype.onData = function(data){
2774  this.emit('data', data);
2775  this.onSuccess();
2776};
2777
2778/**
2779 * Called upon error.
2780 *
2781 * @api private
2782 */
2783
2784Request.prototype.onError = function(err){
2785  this.emit('error', err);
2786  this.cleanup();
2787};
2788
2789/**
2790 * Cleans up house.
2791 *
2792 * @api private
2793 */
2794
2795Request.prototype.cleanup = function(){
2796  if ('undefined' == typeof this.xhr || null === this.xhr) {
2797    return;
2798  }
2799  // xmlhttprequest
2800  if (this.hasXDR()) {
2801    this.xhr.onload = this.xhr.onerror = empty;
2802  } else {
2803    this.xhr.onreadystatechange = empty;
2804  }
2805
2806  try {
2807    this.xhr.abort();
2808  } catch(e) {}
2809
2810  if (global.document) {
2811    delete Request.requests[this.index];
2812  }
2813
2814  this.xhr = null;
2815};
2816
2817/**
2818 * Called upon load.
2819 *
2820 * @api private
2821 */
2822
2823Request.prototype.onLoad = function(){
2824  var data;
2825  try {
2826    var contentType;
2827    try {
2828      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];
2829    } catch (e) {}
2830    if (contentType === 'application/octet-stream') {
2831      data = this.xhr.response;
2832    } else {
2833      if (!this.supportsBinary) {
2834        data = this.xhr.responseText;
2835      } else {
2836        data = 'ok';
2837      }
2838    }
2839  } catch (e) {
2840    this.onError(e);
2841  }
2842  if (null != data) {
2843    this.onData(data);
2844  }
2845};
2846
2847/**
2848 * Check if it has XDomainRequest.
2849 *
2850 * @api private
2851 */
2852
2853Request.prototype.hasXDR = function(){
2854  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;
2855};
2856
2857/**
2858 * Aborts the request.
2859 *
2860 * @api public
2861 */
2862
2863Request.prototype.abort = function(){
2864  this.cleanup();
2865};
2866
2867/**
2868 * Aborts pending requests when unloading the window. This is needed to prevent
2869 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
2870 * emitted.
2871 */
2872
2873if (global.document) {
2874  Request.requestsCount = 0;
2875  Request.requests = {};
2876  if (global.attachEvent) {
2877    global.attachEvent('onunload', unloadHandler);
2878  } else if (global.addEventListener) {
2879    global.addEventListener('beforeunload', unloadHandler);
2880  }
2881}
2882
2883function unloadHandler() {
2884  for (var i in Request.requests) {
2885    if (Request.requests.hasOwnProperty(i)) {
2886      Request.requests[i].abort();
2887    }
2888  }
2889}
2890
2891}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2892},{"./polling":17,"component-emitter":8,"component-inherit":20,"debug":9,"xmlhttprequest":19}],17:[function(_dereq_,module,exports){
2893/**
2894 * Module dependencies.
2895 */
2896
2897var Transport = _dereq_('../transport');
2898var parseqs = _dereq_('parseqs');
2899var parser = _dereq_('engine.io-parser');
2900var inherit = _dereq_('component-inherit');
2901var debug = _dereq_('debug')('engine.io-client:polling');
2902
2903/**
2904 * Module exports.
2905 */
2906
2907module.exports = Polling;
2908
2909/**
2910 * Is XHR2 supported?
2911 */
2912
2913var hasXHR2 = (function() {
2914  var XMLHttpRequest = _dereq_('xmlhttprequest');
2915  var xhr = new XMLHttpRequest({ xdomain: false });
2916  return null != xhr.responseType;
2917})();
2918
2919/**
2920 * Polling interface.
2921 *
2922 * @param {Object} opts
2923 * @api private
2924 */
2925
2926function Polling(opts){
2927  var forceBase64 = (opts && opts.forceBase64);
2928  if (!hasXHR2 || forceBase64) {
2929    this.supportsBinary = false;
2930  }
2931  Transport.call(this, opts);
2932}
2933
2934/**
2935 * Inherits from Transport.
2936 */
2937
2938inherit(Polling, Transport);
2939
2940/**
2941 * Transport name.
2942 */
2943
2944Polling.prototype.name = 'polling';
2945
2946/**
2947 * Opens the socket (triggers polling). We write a PING message to determine
2948 * when the transport is open.
2949 *
2950 * @api private
2951 */
2952
2953Polling.prototype.doOpen = function(){
2954  this.poll();
2955};
2956
2957/**
2958 * Pauses polling.
2959 *
2960 * @param {Function} callback upon buffers are flushed and transport is paused
2961 * @api private
2962 */
2963
2964Polling.prototype.pause = function(onPause){
2965  var pending = 0;
2966  var self = this;
2967
2968  this.readyState = 'pausing';
2969
2970  function pause(){
2971    debug('paused');
2972    self.readyState = 'paused';
2973    onPause();
2974  }
2975
2976  if (this.polling || !this.writable) {
2977    var total = 0;
2978
2979    if (this.polling) {
2980      debug('we are currently polling - waiting to pause');
2981      total++;
2982      this.once('pollComplete', function(){
2983        debug('pre-pause polling complete');
2984        --total || pause();
2985      });
2986    }
2987
2988    if (!this.writable) {
2989      debug('we are currently writing - waiting to pause');
2990      total++;
2991      this.once('drain', function(){
2992        debug('pre-pause writing complete');
2993        --total || pause();
2994      });
2995    }
2996  } else {
2997    pause();
2998  }
2999};
3000
3001/**
3002 * Starts polling cycle.
3003 *
3004 * @api public
3005 */
3006
3007Polling.prototype.poll = function(){
3008  debug('polling');
3009  this.polling = true;
3010  this.doPoll();
3011  this.emit('poll');
3012};
3013
3014/**
3015 * Overloads onData to detect payloads.
3016 *
3017 * @api private
3018 */
3019
3020Polling.prototype.onData = function(data){
3021  var self = this;
3022  debug('polling got data %s', data);
3023  var callback = function(packet, index, total) {
3024    // if its the first message we consider the transport open
3025    if ('opening' == self.readyState) {
3026      self.onOpen();
3027    }
3028
3029    // if its a close packet, we close the ongoing requests
3030    if ('close' == packet.type) {
3031      self.onClose();
3032      return false;
3033    }
3034
3035    // otherwise bypass onData and handle the message
3036    self.onPacket(packet);
3037  };
3038
3039  // decode payload
3040  parser.decodePayload(data, this.socket.binaryType, callback);
3041
3042  // if an event did not trigger closing
3043  if ('closed' != this.readyState) {
3044    // if we got data we're not polling
3045    this.polling = false;
3046    this.emit('pollComplete');
3047
3048    if ('open' == this.readyState) {
3049      this.poll();
3050    } else {
3051      debug('ignoring poll - transport state "%s"', this.readyState);
3052    }
3053  }
3054};
3055
3056/**
3057 * For polling, send a close packet.
3058 *
3059 * @api private
3060 */
3061
3062Polling.prototype.doClose = function(){
3063  var self = this;
3064
3065  function close(){
3066    debug('writing close packet');
3067    self.write([{ type: 'close' }]);
3068  }
3069
3070  if ('open' == this.readyState) {
3071    debug('transport open - closing');
3072    close();
3073  } else {
3074    // in case we're trying to close while
3075    // handshaking is in progress (GH-164)
3076    debug('transport not open - deferring close');
3077    this.once('open', close);
3078  }
3079};
3080
3081/**
3082 * Writes a packets payload.
3083 *
3084 * @param {Array} data packets
3085 * @param {Function} drain callback
3086 * @api private
3087 */
3088
3089Polling.prototype.write = function(packets){
3090  var self = this;
3091  this.writable = false;
3092  var callbackfn = function() {
3093    self.writable = true;
3094    self.emit('drain');
3095  };
3096
3097  var self = this;
3098  parser.encodePayload(packets, this.supportsBinary, function(data) {
3099    self.doWrite(data, callbackfn);
3100  });
3101};
3102
3103/**
3104 * Generates uri for connection.
3105 *
3106 * @api private
3107 */
3108
3109Polling.prototype.uri = function(){
3110  var query = this.query || {};
3111  var schema = this.secure ? 'https' : 'http';
3112  var port = '';
3113
3114  // cache busting is forced
3115  if (false !== this.timestampRequests) {
3116    query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;
3117  }
3118
3119  if (!this.supportsBinary && !query.sid) {
3120    query.b64 = 1;
3121  }
3122
3123  query = parseqs.encode(query);
3124
3125  // avoid port if default for schema
3126  if (this.port && (('https' == schema && this.port != 443) ||
3127     ('http' == schema && this.port != 80))) {
3128    port = ':' + this.port;
3129  }
3130
3131  // prepend ? to query
3132  if (query.length) {
3133    query = '?' + query;
3134  }
3135
3136  return schema + '://' + this.hostname + port + this.path + query;
3137};
3138
3139},{"../transport":13,"component-inherit":20,"debug":9,"engine.io-parser":21,"parseqs":29,"xmlhttprequest":19}],18:[function(_dereq_,module,exports){
3140/**
3141 * Module dependencies.
3142 */
3143
3144var Transport = _dereq_('../transport');
3145var parser = _dereq_('engine.io-parser');
3146var parseqs = _dereq_('parseqs');
3147var inherit = _dereq_('component-inherit');
3148var debug = _dereq_('debug')('engine.io-client:websocket');
3149
3150/**
3151 * `ws` exposes a WebSocket-compatible interface in
3152 * Node, or the `WebSocket` or `MozWebSocket` globals
3153 * in the browser.
3154 */
3155
3156var WebSocket = _dereq_('ws');
3157
3158/**
3159 * Module exports.
3160 */
3161
3162module.exports = WS;
3163
3164/**
3165 * WebSocket transport constructor.
3166 *
3167 * @api {Object} connection options
3168 * @api public
3169 */
3170
3171function WS(opts){
3172  var forceBase64 = (opts && opts.forceBase64);
3173  if (forceBase64) {
3174    this.supportsBinary = false;
3175  }
3176  Transport.call(this, opts);
3177}
3178
3179/**
3180 * Inherits from Transport.
3181 */
3182
3183inherit(WS, Transport);
3184
3185/**
3186 * Transport name.
3187 *
3188 * @api public
3189 */
3190
3191WS.prototype.name = 'websocket';
3192
3193/*
3194 * WebSockets support binary
3195 */
3196
3197WS.prototype.supportsBinary = true;
3198
3199/**
3200 * Opens socket.
3201 *
3202 * @api private
3203 */
3204
3205WS.prototype.doOpen = function(){
3206  if (!this.check()) {
3207    // let probe timeout
3208    return;
3209  }
3210
3211  var self = this;
3212  var uri = this.uri();
3213  var protocols = void(0);
3214  var opts = { agent: this.agent };
3215
3216  this.ws = new WebSocket(uri, protocols, opts);
3217
3218  if (this.ws.binaryType === undefined) {
3219    this.supportsBinary = false;
3220  }
3221
3222  this.ws.binaryType = 'arraybuffer';
3223  this.addEventListeners();
3224};
3225
3226/**
3227 * Adds event listeners to the socket
3228 *
3229 * @api private
3230 */
3231
3232WS.prototype.addEventListeners = function(){
3233  var self = this;
3234
3235  this.ws.onopen = function(){
3236    self.onOpen();
3237  };
3238  this.ws.onclose = function(){
3239    self.onClose();
3240  };
3241  this.ws.onmessage = function(ev){
3242    self.onData(ev.data);
3243  };
3244  this.ws.onerror = function(e){
3245    self.onError('websocket error', e);
3246  };
3247};
3248
3249/**
3250 * Override `onData` to use a timer on iOS.
3251 * See: https://gist.github.com/mloughran/2052006
3252 *
3253 * @api private
3254 */
3255
3256if ('undefined' != typeof navigator
3257  && /iPad|iPhone|iPod/i.test(navigator.userAgent)) {
3258  WS.prototype.onData = function(data){
3259    var self = this;
3260    setTimeout(function(){
3261      Transport.prototype.onData.call(self, data);
3262    }, 0);
3263  };
3264}
3265
3266/**
3267 * Writes data to socket.
3268 *
3269 * @param {Array} array of packets.
3270 * @api private
3271 */
3272
3273WS.prototype.write = function(packets){
3274  var self = this;
3275  this.writable = false;
3276  // encodePacket efficient as it uses WS framing
3277  // no need for encodePayload
3278  for (var i = 0, l = packets.length; i < l; i++) {
3279    parser.encodePacket(packets[i], this.supportsBinary, function(data) {
3280      //Sometimes the websocket has already been closed but the browser didn't
3281      //have a chance of informing us about it yet, in that case send will
3282      //throw an error
3283      try {
3284        self.ws.send(data);
3285      } catch (e){
3286        debug('websocket closed before onclose event');
3287      }
3288    });
3289  }
3290
3291  function ondrain() {
3292    self.writable = true;
3293    self.emit('drain');
3294  }
3295  // fake drain
3296  // defer to next tick to allow Socket to clear writeBuffer
3297  setTimeout(ondrain, 0);
3298};
3299
3300/**
3301 * Called upon close
3302 *
3303 * @api private
3304 */
3305
3306WS.prototype.onClose = function(){
3307  Transport.prototype.onClose.call(this);
3308};
3309
3310/**
3311 * Closes socket.
3312 *
3313 * @api private
3314 */
3315
3316WS.prototype.doClose = function(){
3317  if (typeof this.ws !== 'undefined') {
3318    this.ws.close();
3319  }
3320};
3321
3322/**
3323 * Generates uri for connection.
3324 *
3325 * @api private
3326 */
3327
3328WS.prototype.uri = function(){
3329  var query = this.query || {};
3330  var schema = this.secure ? 'wss' : 'ws';
3331  var port = '';
3332
3333  // avoid port if default for schema
3334  if (this.port && (('wss' == schema && this.port != 443)
3335    || ('ws' == schema && this.port != 80))) {
3336    port = ':' + this.port;
3337  }
3338
3339  // append timestamp to URI
3340  if (this.timestampRequests) {
3341    query[this.timestampParam] = +new Date;
3342  }
3343
3344  // communicate binary support capabilities
3345  if (!this.supportsBinary) {
3346    query.b64 = 1;
3347  }
3348
3349  query = parseqs.encode(query);
3350
3351  // prepend ? to query
3352  if (query.length) {
3353    query = '?' + query;
3354  }
3355
3356  return schema + '://' + this.hostname + port + this.path + query;
3357};
3358
3359/**
3360 * Feature detection for WebSocket.
3361 *
3362 * @return {Boolean} whether this transport is available.
3363 * @api public
3364 */
3365
3366WS.prototype.check = function(){
3367  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
3368};
3369
3370},{"../transport":13,"component-inherit":20,"debug":9,"engine.io-parser":21,"parseqs":29,"ws":31}],19:[function(_dereq_,module,exports){
3371// browser shim for xmlhttprequest module
3372var hasCORS = _dereq_('has-cors');
3373
3374module.exports = function(opts) {
3375  var xdomain = opts.xdomain;
3376
3377  // scheme must be same when usign XDomainRequest
3378  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
3379  var xscheme = opts.xscheme;
3380
3381  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
3382  // https://github.com/Automattic/engine.io-client/pull/217
3383  var enablesXDR = opts.enablesXDR;
3384
3385  // XMLHttpRequest can be disabled on IE
3386  try {
3387    if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {
3388      return new XMLHttpRequest();
3389    }
3390  } catch (e) { }
3391
3392  // Use XDomainRequest for IE8 if enablesXDR is true
3393  // because loading bar keeps flashing when using jsonp-polling
3394  // https://github.com/yujiosaka/socke.io-ie8-loading-example
3395  try {
3396    if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {
3397      return new XDomainRequest();
3398    }
3399  } catch (e) { }
3400
3401  if (!xdomain) {
3402    try {
3403      return new ActiveXObject('Microsoft.XMLHTTP');
3404    } catch(e) { }
3405  }
3406}
3407
3408},{"has-cors":34}],20:[function(_dereq_,module,exports){
3409
3410module.exports = function(a, b){
3411  var fn = function(){};
3412  fn.prototype = b.prototype;
3413  a.prototype = new fn;
3414  a.prototype.constructor = a;
3415};
3416},{}],21:[function(_dereq_,module,exports){
3417(function (global){
3418/**
3419 * Module dependencies.
3420 */
3421
3422var keys = _dereq_('./keys');
3423var sliceBuffer = _dereq_('arraybuffer.slice');
3424var base64encoder = _dereq_('base64-arraybuffer');
3425var after = _dereq_('after');
3426var utf8 = _dereq_('utf8');
3427
3428/**
3429 * Check if we are running an android browser. That requires us to use
3430 * ArrayBuffer with polling transports...
3431 *
3432 * http://ghinda.net/jpeg-blob-ajax-android/
3433 */
3434
3435var isAndroid = navigator.userAgent.match(/Android/i);
3436
3437/**
3438 * Current protocol version.
3439 */
3440
3441exports.protocol = 3;
3442
3443/**
3444 * Packet types.
3445 */
3446
3447var packets = exports.packets = {
3448    open:     0    // non-ws
3449  , close:    1    // non-ws
3450  , ping:     2
3451  , pong:     3
3452  , message:  4
3453  , upgrade:  5
3454  , noop:     6
3455};
3456
3457var packetslist = keys(packets);
3458
3459/**
3460 * Premade error packet.
3461 */
3462
3463var err = { type: 'error', data: 'parser error' };
3464
3465/**
3466 * Create a blob api even for blob builder when vendor prefixes exist
3467 */
3468
3469var Blob = _dereq_('blob');
3470
3471/**
3472 * Encodes a packet.
3473 *
3474 *     <packet type id> [ <data> ]
3475 *
3476 * Example:
3477 *
3478 *     5hello world
3479 *     3
3480 *     4
3481 *
3482 * Binary is encoded in an identical principle
3483 *
3484 * @api private
3485 */
3486
3487exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
3488  if ('function' == typeof supportsBinary) {
3489    callback = supportsBinary;
3490    supportsBinary = false;
3491  }
3492
3493  if ('function' == typeof utf8encode) {
3494    callback = utf8encode;
3495    utf8encode = null;
3496  }
3497
3498  var data = (packet.data === undefined)
3499    ? undefined
3500    : packet.data.buffer || packet.data;
3501
3502  if (global.ArrayBuffer && data instanceof ArrayBuffer) {
3503    return encodeArrayBuffer(packet, supportsBinary, callback);
3504  } else if (Blob && data instanceof global.Blob) {
3505    return encodeBlob(packet, supportsBinary, callback);
3506  }
3507
3508  // Sending data as a utf-8 string
3509  var encoded = packets[packet.type];
3510
3511  // data fragment is optional
3512  if (undefined !== packet.data) {
3513    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);
3514  }
3515
3516  return callback('' + encoded);
3517
3518};
3519
3520/**
3521 * Encode packet helpers for binary types
3522 */
3523
3524function encodeArrayBuffer(packet, supportsBinary, callback) {
3525  if (!supportsBinary) {
3526    return exports.encodeBase64Packet(packet, callback);
3527  }
3528
3529  var data = packet.data;
3530  var contentArray = new Uint8Array(data);
3531  var resultBuffer = new Uint8Array(1 + data.byteLength);
3532
3533  resultBuffer[0] = packets[packet.type];
3534  for (var i = 0; i < contentArray.length; i++) {
3535    resultBuffer[i+1] = contentArray[i];
3536  }
3537
3538  return callback(resultBuffer.buffer);
3539}
3540
3541function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
3542  if (!supportsBinary) {
3543    return exports.encodeBase64Packet(packet, callback);
3544  }
3545
3546  var fr = new FileReader();
3547  fr.onload = function() {
3548    packet.data = fr.result;
3549    exports.encodePacket(packet, supportsBinary, true, callback);
3550  };
3551  return fr.readAsArrayBuffer(packet.data);
3552}
3553
3554function encodeBlob(packet, supportsBinary, callback) {
3555  if (!supportsBinary) {
3556    return exports.encodeBase64Packet(packet, callback);
3557  }
3558
3559  if (isAndroid) {
3560    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
3561  }
3562
3563  var length = new Uint8Array(1);
3564  length[0] = packets[packet.type];
3565  var blob = new Blob([length.buffer, packet.data]);
3566
3567  return callback(blob);
3568}
3569
3570/**
3571 * Encodes a packet with binary data in a base64 string
3572 *
3573 * @param {Object} packet, has `type` and `data`
3574 * @return {String} base64 encoded message
3575 */
3576
3577exports.encodeBase64Packet = function(packet, callback) {
3578  var message = 'b' + exports.packets[packet.type];
3579  if (Blob && packet.data instanceof Blob) {
3580    var fr = new FileReader();
3581    fr.onload = function() {
3582      var b64 = fr.result.split(',')[1];
3583      callback(message + b64);
3584    };
3585    return fr.readAsDataURL(packet.data);
3586  }
3587
3588  var b64data;
3589  try {
3590    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
3591  } catch (e) {
3592    // iPhone Safari doesn't let you apply with typed arrays
3593    var typed = new Uint8Array(packet.data);
3594    var basic = new Array(typed.length);
3595    for (var i = 0; i < typed.length; i++) {
3596      basic[i] = typed[i];
3597    }
3598    b64data = String.fromCharCode.apply(null, basic);
3599  }
3600  message += global.btoa(b64data);
3601  return callback(message);
3602};
3603
3604/**
3605 * Decodes a packet. Changes format to Blob if requested.
3606 *
3607 * @return {Object} with `type` and `data` (if any)
3608 * @api private
3609 */
3610
3611exports.decodePacket = function (data, binaryType, utf8decode) {
3612  // String data
3613  if (typeof data == 'string' || data === undefined) {
3614    if (data.charAt(0) == 'b') {
3615      return exports.decodeBase64Packet(data.substr(1), binaryType);
3616    }
3617
3618    if (utf8decode) {
3619      try {
3620        data = utf8.decode(data);
3621      } catch (e) {
3622        return err;
3623      }
3624    }
3625    var type = data.charAt(0);
3626
3627    if (Number(type) != type || !packetslist[type]) {
3628      return err;
3629    }
3630
3631    if (data.length > 1) {
3632      return { type: packetslist[type], data: data.substring(1) };
3633    } else {
3634      return { type: packetslist[type] };
3635    }
3636  }
3637
3638  var asArray = new Uint8Array(data);
3639  var type = asArray[0];
3640  var rest = sliceBuffer(data, 1);
3641  if (Blob && binaryType === 'blob') {
3642    rest = new Blob([rest]);
3643  }
3644  return { type: packetslist[type], data: rest };
3645};
3646
3647/**
3648 * Decodes a packet encoded in a base64 string
3649 *
3650 * @param {String} base64 encoded message
3651 * @return {Object} with `type` and `data` (if any)
3652 */
3653
3654exports.decodeBase64Packet = function(msg, binaryType) {
3655  var type = packetslist[msg.charAt(0)];
3656  if (!global.ArrayBuffer) {
3657    return { type: type, data: { base64: true, data: msg.substr(1) } };
3658  }
3659
3660  var data = base64encoder.decode(msg.substr(1));
3661
3662  if (binaryType === 'blob' && Blob) {
3663    data = new Blob([data]);
3664  }
3665
3666  return { type: type, data: data };
3667};
3668
3669/**
3670 * Encodes multiple messages (payload).
3671 *
3672 *     <length>:data
3673 *
3674 * Example:
3675 *
3676 *     11:hello world2:hi
3677 *
3678 * If any contents are binary, they will be encoded as base64 strings. Base64
3679 * encoded strings are marked with a b before the length specifier
3680 *
3681 * @param {Array} packets
3682 * @api private
3683 */
3684
3685exports.encodePayload = function (packets, supportsBinary, callback) {
3686  if (typeof supportsBinary == 'function') {
3687    callback = supportsBinary;
3688    supportsBinary = null;
3689  }
3690
3691  if (supportsBinary) {
3692    if (Blob && !isAndroid) {
3693      return exports.encodePayloadAsBlob(packets, callback);
3694    }
3695
3696    return exports.encodePayloadAsArrayBuffer(packets, callback);
3697  }
3698
3699  if (!packets.length) {
3700    return callback('0:');
3701  }
3702
3703  function setLengthHeader(message) {
3704    return message.length + ':' + message;
3705  }
3706
3707  function encodeOne(packet, doneCallback) {
3708    exports.encodePacket(packet, supportsBinary, true, function(message) {
3709      doneCallback(null, setLengthHeader(message));
3710    });
3711  }
3712
3713  map(packets, encodeOne, function(err, results) {
3714    return callback(results.join(''));
3715  });
3716};
3717
3718/**
3719 * Async array map using after
3720 */
3721
3722function map(ary, each, done) {
3723  var result = new Array(ary.length);
3724  var next = after(ary.length, done);
3725
3726  var eachWithIndex = function(i, el, cb) {
3727    each(el, function(error, msg) {
3728      result[i] = msg;
3729      cb(error, result);
3730    });
3731  };
3732
3733  for (var i = 0; i < ary.length; i++) {
3734    eachWithIndex(i, ary[i], next);
3735  }
3736}
3737
3738/*
3739 * Decodes data when a payload is maybe expected. Possible binary contents are
3740 * decoded from their base64 representation
3741 *
3742 * @param {String} data, callback method
3743 * @api public
3744 */
3745
3746exports.decodePayload = function (data, binaryType, callback) {
3747  if (typeof data != 'string') {
3748    return exports.decodePayloadAsBinary(data, binaryType, callback);
3749  }
3750
3751  if (typeof binaryType === 'function') {
3752    callback = binaryType;
3753    binaryType = null;
3754  }
3755
3756  var packet;
3757  if (data == '') {
3758    // parser error - ignoring payload
3759    return callback(err, 0, 1);
3760  }
3761
3762  var length = ''
3763    , n, msg;
3764
3765  for (var i = 0, l = data.length; i < l; i++) {
3766    var chr = data.charAt(i);
3767
3768    if (':' != chr) {
3769      length += chr;
3770    } else {
3771      if ('' == length || (length != (n = Number(length)))) {
3772        // parser error - ignoring payload
3773        return callback(err, 0, 1);
3774      }
3775
3776      msg = data.substr(i + 1, n);
3777
3778      if (length != msg.length) {
3779        // parser error - ignoring payload
3780        return callback(err, 0, 1);
3781      }
3782
3783      if (msg.length) {
3784        packet = exports.decodePacket(msg, binaryType, true);
3785
3786        if (err.type == packet.type && err.data == packet.data) {
3787          // parser error in individual packet - ignoring payload
3788          return callback(err, 0, 1);
3789        }
3790
3791        var ret = callback(packet, i + n, l);
3792        if (false === ret) return;
3793      }
3794
3795      // advance cursor
3796      i += n;
3797      length = '';
3798    }
3799  }
3800
3801  if (length != '') {
3802    // parser error - ignoring payload
3803    return callback(err, 0, 1);
3804  }
3805
3806};
3807
3808/**
3809 * Encodes multiple messages (payload) as binary.
3810 *
3811 * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
3812 * 255><data>
3813 *
3814 * Example:
3815 * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
3816 *
3817 * @param {Array} packets
3818 * @return {ArrayBuffer} encoded payload
3819 * @api private
3820 */
3821
3822exports.encodePayloadAsArrayBuffer = function(packets, callback) {
3823  if (!packets.length) {
3824    return callback(new ArrayBuffer(0));
3825  }
3826
3827  function encodeOne(packet, doneCallback) {
3828    exports.encodePacket(packet, true, true, function(data) {
3829      return doneCallback(null, data);
3830    });
3831  }
3832
3833  map(packets, encodeOne, function(err, encodedPackets) {
3834    var totalLength = encodedPackets.reduce(function(acc, p) {
3835      var len;
3836      if (typeof p === 'string'){
3837        len = p.length;
3838      } else {
3839        len = p.byteLength;
3840      }
3841      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
3842    }, 0);
3843
3844    var resultArray = new Uint8Array(totalLength);
3845
3846    var bufferIndex = 0;
3847    encodedPackets.forEach(function(p) {
3848      var isString = typeof p === 'string';
3849      var ab = p;
3850      if (isString) {
3851        var view = new Uint8Array(p.length);
3852        for (var i = 0; i < p.length; i++) {
3853          view[i] = p.charCodeAt(i);
3854        }
3855        ab = view.buffer;
3856      }
3857
3858      if (isString) { // not true binary
3859        resultArray[bufferIndex++] = 0;
3860      } else { // true binary
3861        resultArray[bufferIndex++] = 1;
3862      }
3863
3864      var lenStr = ab.byteLength.toString();
3865      for (var i = 0; i < lenStr.length; i++) {
3866        resultArray[bufferIndex++] = parseInt(lenStr[i]);
3867      }
3868      resultArray[bufferIndex++] = 255;
3869
3870      var view = new Uint8Array(ab);
3871      for (var i = 0; i < view.length; i++) {
3872        resultArray[bufferIndex++] = view[i];
3873      }
3874    });
3875
3876    return callback(resultArray.buffer);
3877  });
3878};
3879
3880/**
3881 * Encode as Blob
3882 */
3883
3884exports.encodePayloadAsBlob = function(packets, callback) {
3885  function encodeOne(packet, doneCallback) {
3886    exports.encodePacket(packet, true, true, function(encoded) {
3887      var binaryIdentifier = new Uint8Array(1);
3888      binaryIdentifier[0] = 1;
3889      if (typeof encoded === 'string') {
3890        var view = new Uint8Array(encoded.length);
3891        for (var i = 0; i < encoded.length; i++) {
3892          view[i] = encoded.charCodeAt(i);
3893        }
3894        encoded = view.buffer;
3895        binaryIdentifier[0] = 0;
3896      }
3897
3898      var len = (encoded instanceof ArrayBuffer)
3899        ? encoded.byteLength
3900        : encoded.size;
3901
3902      var lenStr = len.toString();
3903      var lengthAry = new Uint8Array(lenStr.length + 1);
3904      for (var i = 0; i < lenStr.length; i++) {
3905        lengthAry[i] = parseInt(lenStr[i]);
3906      }
3907      lengthAry[lenStr.length] = 255;
3908
3909      if (Blob) {
3910        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
3911        doneCallback(null, blob);
3912      }
3913    });
3914  }
3915
3916  map(packets, encodeOne, function(err, results) {
3917    return callback(new Blob(results));
3918  });
3919};
3920
3921/*
3922 * Decodes data when a payload is maybe expected. Strings are decoded by
3923 * interpreting each byte as a key code for entries marked to start with 0. See
3924 * description of encodePayloadAsBinary
3925 *
3926 * @param {ArrayBuffer} data, callback method
3927 * @api public
3928 */
3929
3930exports.decodePayloadAsBinary = function (data, binaryType, callback) {
3931  if (typeof binaryType === 'function') {
3932    callback = binaryType;
3933    binaryType = null;
3934  }
3935
3936  var bufferTail = data;
3937  var buffers = [];
3938
3939  var numberTooLong = false;
3940  while (bufferTail.byteLength > 0) {
3941    var tailArray = new Uint8Array(bufferTail);
3942    var isString = tailArray[0] === 0;
3943    var msgLength = '';
3944
3945    for (var i = 1; ; i++) {
3946      if (tailArray[i] == 255) break;
3947
3948      if (msgLength.length > 310) {
3949        numberTooLong = true;
3950        break;
3951      }
3952
3953      msgLength += tailArray[i];
3954    }
3955
3956    if(numberTooLong) return callback(err, 0, 1);
3957
3958    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
3959    msgLength = parseInt(msgLength);
3960
3961    var msg = sliceBuffer(bufferTail, 0, msgLength);
3962    if (isString) {
3963      try {
3964        msg = String.fromCharCode.apply(null, new Uint8Array(msg));
3965      } catch (e) {
3966        // iPhone Safari doesn't let you apply to typed arrays
3967        var typed = new Uint8Array(msg);
3968        msg = '';
3969        for (var i = 0; i < typed.length; i++) {
3970          msg += String.fromCharCode(typed[i]);
3971        }
3972      }
3973    }
3974
3975    buffers.push(msg);
3976    bufferTail = sliceBuffer(bufferTail, msgLength);
3977  }
3978
3979  var total = buffers.length;
3980  buffers.forEach(function(buffer, i) {
3981    callback(exports.decodePacket(buffer, binaryType, true), i, total);
3982  });
3983};
3984
3985}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3986},{"./keys":22,"after":23,"arraybuffer.slice":24,"base64-arraybuffer":25,"blob":26,"utf8":27}],22:[function(_dereq_,module,exports){
3987
3988/**
3989 * Gets the keys for an object.
3990 *
3991 * @return {Array} keys
3992 * @api private
3993 */
3994
3995module.exports = Object.keys || function keys (obj){
3996  var arr = [];
3997  var has = Object.prototype.hasOwnProperty;
3998
3999  for (var i in obj) {
4000    if (has.call(obj, i)) {
4001      arr.push(i);
4002    }
4003  }
4004  return arr;
4005};
4006
4007},{}],23:[function(_dereq_,module,exports){
4008module.exports = after
4009
4010function after(count, callback, err_cb) {
4011    var bail = false
4012    err_cb = err_cb || noop
4013    proxy.count = count
4014
4015    return (count === 0) ? callback() : proxy
4016
4017    function proxy(err, result) {
4018        if (proxy.count <= 0) {
4019            throw new Error('after called too many times')
4020        }
4021        --proxy.count
4022
4023        // after first error, rest are passed to err_cb
4024        if (err) {
4025            bail = true
4026            callback(err)
4027            // future error callbacks will go to error handler
4028            callback = err_cb
4029        } else if (proxy.count === 0 && !bail) {
4030            callback(null, result)
4031        }
4032    }
4033}
4034
4035function noop() {}
4036
4037},{}],24:[function(_dereq_,module,exports){
4038/**
4039 * An abstraction for slicing an arraybuffer even when
4040 * ArrayBuffer.prototype.slice is not supported
4041 *
4042 * @api public
4043 */
4044
4045module.exports = function(arraybuffer, start, end) {
4046  var bytes = arraybuffer.byteLength;
4047  start = start || 0;
4048  end = end || bytes;
4049
4050  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
4051
4052  if (start < 0) { start += bytes; }
4053  if (end < 0) { end += bytes; }
4054  if (end > bytes) { end = bytes; }
4055
4056  if (start >= bytes || start >= end || bytes === 0) {
4057    return new ArrayBuffer(0);
4058  }
4059
4060  var abv = new Uint8Array(arraybuffer);
4061  var result = new Uint8Array(end - start);
4062  for (var i = start, ii = 0; i < end; i++, ii++) {
4063    result[ii] = abv[i];
4064  }
4065  return result.buffer;
4066};
4067
4068},{}],25:[function(_dereq_,module,exports){
4069/*
4070 * base64-arraybuffer
4071 * https://github.com/niklasvh/base64-arraybuffer
4072 *
4073 * Copyright (c) 2012 Niklas von Hertzen
4074 * Licensed under the MIT license.
4075 */
4076(function(chars){
4077  "use strict";
4078
4079  exports.encode = function(arraybuffer) {
4080    var bytes = new Uint8Array(arraybuffer),
4081    i, len = bytes.length, base64 = "";
4082
4083    for (i = 0; i < len; i+=3) {
4084      base64 += chars[bytes[i] >> 2];
4085      base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
4086      base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
4087      base64 += chars[bytes[i + 2] & 63];
4088    }
4089
4090    if ((len % 3) === 2) {
4091      base64 = base64.substring(0, base64.length - 1) + "=";
4092    } else if (len % 3 === 1) {
4093      base64 = base64.substring(0, base64.length - 2) + "==";
4094    }
4095
4096    return base64;
4097  };
4098
4099  exports.decode =  function(base64) {
4100    var bufferLength = base64.length * 0.75,
4101    len = base64.length, i, p = 0,
4102    encoded1, encoded2, encoded3, encoded4;
4103
4104    if (base64[base64.length - 1] === "=") {
4105      bufferLength--;
4106      if (base64[base64.length - 2] === "=") {
4107        bufferLength--;
4108      }
4109    }
4110
4111    var arraybuffer = new ArrayBuffer(bufferLength),
4112    bytes = new Uint8Array(arraybuffer);
4113
4114    for (i = 0; i < len; i+=4) {
4115      encoded1 = chars.indexOf(base64[i]);
4116      encoded2 = chars.indexOf(base64[i+1]);
4117      encoded3 = chars.indexOf(base64[i+2]);
4118      encoded4 = chars.indexOf(base64[i+3]);
4119
4120      bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
4121      bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
4122      bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
4123    }
4124
4125    return arraybuffer;
4126  };
4127})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
4128
4129},{}],26:[function(_dereq_,module,exports){
4130(function (global){
4131/**
4132 * Create a blob builder even when vendor prefixes exist
4133 */
4134
4135var BlobBuilder = global.BlobBuilder
4136  || global.WebKitBlobBuilder
4137  || global.MSBlobBuilder
4138  || global.MozBlobBuilder;
4139
4140/**
4141 * Check if Blob constructor is supported
4142 */
4143
4144var blobSupported = (function() {
4145  try {
4146    var b = new Blob(['hi']);
4147    return b.size == 2;
4148  } catch(e) {
4149    return false;
4150  }
4151})();
4152
4153/**
4154 * Check if BlobBuilder is supported
4155 */
4156
4157var blobBuilderSupported = BlobBuilder
4158  && BlobBuilder.prototype.append
4159  && BlobBuilder.prototype.getBlob;
4160
4161function BlobBuilderConstructor(ary, options) {
4162  options = options || {};
4163
4164  var bb = new BlobBuilder();
4165  for (var i = 0; i < ary.length; i++) {
4166    bb.append(ary[i]);
4167  }
4168  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
4169};
4170
4171module.exports = (function() {
4172  if (blobSupported) {
4173    return global.Blob;
4174  } else if (blobBuilderSupported) {
4175    return BlobBuilderConstructor;
4176  } else {
4177    return undefined;
4178  }
4179})();
4180
4181}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4182},{}],27:[function(_dereq_,module,exports){
4183(function (global){
4184/*! http://mths.be/utf8js v2.0.0 by @mathias */
4185;(function(root) {
4186
4187	// Detect free variables `exports`
4188	var freeExports = typeof exports == 'object' && exports;
4189
4190	// Detect free variable `module`
4191	var freeModule = typeof module == 'object' && module &&
4192		module.exports == freeExports && module;
4193
4194	// Detect free variable `global`, from Node.js or Browserified code,
4195	// and use it as `root`
4196	var freeGlobal = typeof global == 'object' && global;
4197	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
4198		root = freeGlobal;
4199	}
4200
4201	/*--------------------------------------------------------------------------*/
4202
4203	var stringFromCharCode = String.fromCharCode;
4204
4205	// Taken from http://mths.be/punycode
4206	function ucs2decode(string) {
4207		var output = [];
4208		var counter = 0;
4209		var length = string.length;
4210		var value;
4211		var extra;
4212		while (counter < length) {
4213			value = string.charCodeAt(counter++);
4214			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
4215				// high surrogate, and there is a next character
4216				extra = string.charCodeAt(counter++);
4217				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
4218					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
4219				} else {
4220					// unmatched surrogate; only append this code unit, in case the next
4221					// code unit is the high surrogate of a surrogate pair
4222					output.push(value);
4223					counter--;
4224				}
4225			} else {
4226				output.push(value);
4227			}
4228		}
4229		return output;
4230	}
4231
4232	// Taken from http://mths.be/punycode
4233	function ucs2encode(array) {
4234		var length = array.length;
4235		var index = -1;
4236		var value;
4237		var output = '';
4238		while (++index < length) {
4239			value = array[index];
4240			if (value > 0xFFFF) {
4241				value -= 0x10000;
4242				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
4243				value = 0xDC00 | value & 0x3FF;
4244			}
4245			output += stringFromCharCode(value);
4246		}
4247		return output;
4248	}
4249
4250	/*--------------------------------------------------------------------------*/
4251
4252	function createByte(codePoint, shift) {
4253		return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
4254	}
4255
4256	function encodeCodePoint(codePoint) {
4257		if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
4258			return stringFromCharCode(codePoint);
4259		}
4260		var symbol = '';
4261		if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
4262			symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
4263		}
4264		else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
4265			symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
4266			symbol += createByte(codePoint, 6);
4267		}
4268		else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
4269			symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
4270			symbol += createByte(codePoint, 12);
4271			symbol += createByte(codePoint, 6);
4272		}
4273		symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
4274		return symbol;
4275	}
4276
4277	function utf8encode(string) {
4278		var codePoints = ucs2decode(string);
4279
4280		// console.log(JSON.stringify(codePoints.map(function(x) {
4281		// 	return 'U+' + x.toString(16).toUpperCase();
4282		// })));
4283
4284		var length = codePoints.length;
4285		var index = -1;
4286		var codePoint;
4287		var byteString = '';
4288		while (++index < length) {
4289			codePoint = codePoints[index];
4290			byteString += encodeCodePoint(codePoint);
4291		}
4292		return byteString;
4293	}
4294
4295	/*--------------------------------------------------------------------------*/
4296
4297	function readContinuationByte() {
4298		if (byteIndex >= byteCount) {
4299			throw Error('Invalid byte index');
4300		}
4301
4302		var continuationByte = byteArray[byteIndex] & 0xFF;
4303		byteIndex++;
4304
4305		if ((continuationByte & 0xC0) == 0x80) {
4306			return continuationByte & 0x3F;
4307		}
4308
4309		// If we end up here, it’s not a continuation byte
4310		throw Error('Invalid continuation byte');
4311	}
4312
4313	function decodeSymbol() {
4314		var byte1;
4315		var byte2;
4316		var byte3;
4317		var byte4;
4318		var codePoint;
4319
4320		if (byteIndex > byteCount) {
4321			throw Error('Invalid byte index');
4322		}
4323
4324		if (byteIndex == byteCount) {
4325			return false;
4326		}
4327
4328		// Read first byte
4329		byte1 = byteArray[byteIndex] & 0xFF;
4330		byteIndex++;
4331
4332		// 1-byte sequence (no continuation bytes)
4333		if ((byte1 & 0x80) == 0) {
4334			return byte1;
4335		}
4336
4337		// 2-byte sequence
4338		if ((byte1 & 0xE0) == 0xC0) {
4339			var byte2 = readContinuationByte();
4340			codePoint = ((byte1 & 0x1F) << 6) | byte2;
4341			if (codePoint >= 0x80) {
4342				return codePoint;
4343			} else {
4344				throw Error('Invalid continuation byte');
4345			}
4346		}
4347
4348		// 3-byte sequence (may include unpaired surrogates)
4349		if ((byte1 & 0xF0) == 0xE0) {
4350			byte2 = readContinuationByte();
4351			byte3 = readContinuationByte();
4352			codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
4353			if (codePoint >= 0x0800) {
4354				return codePoint;
4355			} else {
4356				throw Error('Invalid continuation byte');
4357			}
4358		}
4359
4360		// 4-byte sequence
4361		if ((byte1 & 0xF8) == 0xF0) {
4362			byte2 = readContinuationByte();
4363			byte3 = readContinuationByte();
4364			byte4 = readContinuationByte();
4365			codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
4366				(byte3 << 0x06) | byte4;
4367			if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
4368				return codePoint;
4369			}
4370		}
4371
4372		throw Error('Invalid UTF-8 detected');
4373	}
4374
4375	var byteArray;
4376	var byteCount;
4377	var byteIndex;
4378	function utf8decode(byteString) {
4379		byteArray = ucs2decode(byteString);
4380		byteCount = byteArray.length;
4381		byteIndex = 0;
4382		var codePoints = [];
4383		var tmp;
4384		while ((tmp = decodeSymbol()) !== false) {
4385			codePoints.push(tmp);
4386		}
4387		return ucs2encode(codePoints);
4388	}
4389
4390	/*--------------------------------------------------------------------------*/
4391
4392	var utf8 = {
4393		'version': '2.0.0',
4394		'encode': utf8encode,
4395		'decode': utf8decode
4396	};
4397
4398	// Some AMD build optimizers, like r.js, check for specific condition patterns
4399	// like the following:
4400	if (
4401		typeof define == 'function' &&
4402		typeof define.amd == 'object' &&
4403		define.amd
4404	) {
4405		define(function() {
4406			return utf8;
4407		});
4408	}	else if (freeExports && !freeExports.nodeType) {
4409		if (freeModule) { // in Node.js or RingoJS v0.8.0+
4410			freeModule.exports = utf8;
4411		} else { // in Narwhal or RingoJS v0.7.0-
4412			var object = {};
4413			var hasOwnProperty = object.hasOwnProperty;
4414			for (var key in utf8) {
4415				hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
4416			}
4417		}
4418	} else { // in Rhino or a web browser
4419		root.utf8 = utf8;
4420	}
4421
4422}(this));
4423
4424}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4425},{}],28:[function(_dereq_,module,exports){
4426(function (global){
4427/**
4428 * JSON parse.
4429 *
4430 * @see Based on jQuery#parseJSON (MIT) and JSON2
4431 * @api private
4432 */
4433
4434var rvalidchars = /^[\],:{}\s]*$/;
4435var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
4436var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
4437var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
4438var rtrimLeft = /^\s+/;
4439var rtrimRight = /\s+$/;
4440
4441module.exports = function parsejson(data) {
4442  if ('string' != typeof data || !data) {
4443    return null;
4444  }
4445
4446  data = data.replace(rtrimLeft, '').replace(rtrimRight, '');
4447
4448  // Attempt to parse using the native JSON parser first
4449  if (global.JSON && JSON.parse) {
4450    return JSON.parse(data);
4451  }
4452
4453  if (rvalidchars.test(data.replace(rvalidescape, '@')
4454      .replace(rvalidtokens, ']')
4455      .replace(rvalidbraces, ''))) {
4456    return (new Function('return ' + data))();
4457  }
4458};
4459}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4460},{}],29:[function(_dereq_,module,exports){
4461/**
4462 * Compiles a querystring
4463 * Returns string representation of the object
4464 *
4465 * @param {Object}
4466 * @api private
4467 */
4468
4469exports.encode = function (obj) {
4470  var str = '';
4471
4472  for (var i in obj) {
4473    if (obj.hasOwnProperty(i)) {
4474      if (str.length) str += '&';
4475      str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
4476    }
4477  }
4478
4479  return str;
4480};
4481
4482/**
4483 * Parses a simple querystring into an object
4484 *
4485 * @param {String} qs
4486 * @api private
4487 */
4488
4489exports.decode = function(qs){
4490  var qry = {};
4491  var pairs = qs.split('&');
4492  for (var i = 0, l = pairs.length; i < l; i++) {
4493    var pair = pairs[i].split('=');
4494    qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
4495  }
4496  return qry;
4497};
4498
4499},{}],30:[function(_dereq_,module,exports){
4500/**
4501 * Parses an URI
4502 *
4503 * @author Steven Levithan <stevenlevithan.com> (MIT license)
4504 * @api private
4505 */
4506
4507var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
4508
4509var parts = [
4510    'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
4511];
4512
4513module.exports = function parseuri(str) {
4514    var src = str,
4515        b = str.indexOf('['),
4516        e = str.indexOf(']');
4517
4518    if (b != -1 && e != -1) {
4519        str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
4520    }
4521
4522    var m = re.exec(str || ''),
4523        uri = {},
4524        i = 14;
4525
4526    while (i--) {
4527        uri[parts[i]] = m[i] || '';
4528    }
4529
4530    if (b != -1 && e != -1) {
4531        uri.source = src;
4532        uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
4533        uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
4534        uri.ipv6uri = true;
4535    }
4536
4537    return uri;
4538};
4539
4540},{}],31:[function(_dereq_,module,exports){
4541
4542/**
4543 * Module dependencies.
4544 */
4545
4546var global = (function() { return this; })();
4547
4548/**
4549 * WebSocket constructor.
4550 */
4551
4552var WebSocket = global.WebSocket || global.MozWebSocket;
4553
4554/**
4555 * Module exports.
4556 */
4557
4558module.exports = WebSocket ? ws : null;
4559
4560/**
4561 * WebSocket constructor.
4562 *
4563 * The third `opts` options object gets ignored in web browsers, since it's
4564 * non-standard, and throws a TypeError if passed to the constructor.
4565 * See: https://github.com/einaros/ws/issues/227
4566 *
4567 * @param {String} uri
4568 * @param {Array} protocols (optional)
4569 * @param {Object) opts (optional)
4570 * @api public
4571 */
4572
4573function ws(uri, protocols, opts) {
4574  var instance;
4575  if (protocols) {
4576    instance = new WebSocket(uri, protocols);
4577  } else {
4578    instance = new WebSocket(uri);
4579  }
4580  return instance;
4581}
4582
4583if (WebSocket) ws.prototype = WebSocket.prototype;
4584
4585},{}],32:[function(_dereq_,module,exports){
4586(function (global){
4587
4588/*
4589 * Module requirements.
4590 */
4591
4592var isArray = _dereq_('isarray');
4593
4594/**
4595 * Module exports.
4596 */
4597
4598module.exports = hasBinary;
4599
4600/**
4601 * Checks for binary data.
4602 *
4603 * Right now only Buffer and ArrayBuffer are supported..
4604 *
4605 * @param {Object} anything
4606 * @api public
4607 */
4608
4609function hasBinary(data) {
4610
4611  function _hasBinary(obj) {
4612    if (!obj) return false;
4613
4614    if ( (global.Buffer && global.Buffer.isBuffer(obj)) ||
4615         (global.ArrayBuffer && obj instanceof ArrayBuffer) ||
4616         (global.Blob && obj instanceof Blob) ||
4617         (global.File && obj instanceof File)
4618        ) {
4619      return true;
4620    }
4621
4622    if (isArray(obj)) {
4623      for (var i = 0; i < obj.length; i++) {
4624          if (_hasBinary(obj[i])) {
4625              return true;
4626          }
4627      }
4628    } else if (obj && 'object' == typeof obj) {
4629      if (obj.toJSON) {
4630        obj = obj.toJSON();
4631      }
4632
4633      for (var key in obj) {
4634        if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) {
4635          return true;
4636        }
4637      }
4638    }
4639
4640    return false;
4641  }
4642
4643  return _hasBinary(data);
4644}
4645
4646}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4647},{"isarray":33}],33:[function(_dereq_,module,exports){
4648module.exports = Array.isArray || function (arr) {
4649  return Object.prototype.toString.call(arr) == '[object Array]';
4650};
4651
4652},{}],34:[function(_dereq_,module,exports){
4653
4654/**
4655 * Module dependencies.
4656 */
4657
4658var global = _dereq_('global');
4659
4660/**
4661 * Module exports.
4662 *
4663 * Logic borrowed from Modernizr:
4664 *
4665 *   - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
4666 */
4667
4668try {
4669  module.exports = 'XMLHttpRequest' in global &&
4670    'withCredentials' in new global.XMLHttpRequest();
4671} catch (err) {
4672  // if XMLHttp support is disabled in IE then it will throw
4673  // when trying to create
4674  module.exports = false;
4675}
4676
4677},{"global":35}],35:[function(_dereq_,module,exports){
4678
4679/**
4680 * Returns `this`. Execute this without a "context" (i.e. without it being
4681 * attached to an object of the left-hand side), and `this` points to the
4682 * "global" scope of the current JS execution.
4683 */
4684
4685module.exports = (function () { return this; })();
4686
4687},{}],36:[function(_dereq_,module,exports){
4688
4689var indexOf = [].indexOf;
4690
4691module.exports = function(arr, obj){
4692  if (indexOf) return arr.indexOf(obj);
4693  for (var i = 0; i < arr.length; ++i) {
4694    if (arr[i] === obj) return i;
4695  }
4696  return -1;
4697};
4698},{}],37:[function(_dereq_,module,exports){
4699
4700/**
4701 * HOP ref.
4702 */
4703
4704var has = Object.prototype.hasOwnProperty;
4705
4706/**
4707 * Return own keys in `obj`.
4708 *
4709 * @param {Object} obj
4710 * @return {Array}
4711 * @api public
4712 */
4713
4714exports.keys = Object.keys || function(obj){
4715  var keys = [];
4716  for (var key in obj) {
4717    if (has.call(obj, key)) {
4718      keys.push(key);
4719    }
4720  }
4721  return keys;
4722};
4723
4724/**
4725 * Return own values in `obj`.
4726 *
4727 * @param {Object} obj
4728 * @return {Array}
4729 * @api public
4730 */
4731
4732exports.values = function(obj){
4733  var vals = [];
4734  for (var key in obj) {
4735    if (has.call(obj, key)) {
4736      vals.push(obj[key]);
4737    }
4738  }
4739  return vals;
4740};
4741
4742/**
4743 * Merge `b` into `a`.
4744 *
4745 * @param {Object} a
4746 * @param {Object} b
4747 * @return {Object} a
4748 * @api public
4749 */
4750
4751exports.merge = function(a, b){
4752  for (var key in b) {
4753    if (has.call(b, key)) {
4754      a[key] = b[key];
4755    }
4756  }
4757  return a;
4758};
4759
4760/**
4761 * Return length of `obj`.
4762 *
4763 * @param {Object} obj
4764 * @return {Number}
4765 * @api public
4766 */
4767
4768exports.length = function(obj){
4769  return exports.keys(obj).length;
4770};
4771
4772/**
4773 * Check if `obj` is empty.
4774 *
4775 * @param {Object} obj
4776 * @return {Boolean}
4777 * @api public
4778 */
4779
4780exports.isEmpty = function(obj){
4781  return 0 == exports.length(obj);
4782};
4783},{}],38:[function(_dereq_,module,exports){
4784/**
4785 * Parses an URI
4786 *
4787 * @author Steven Levithan <stevenlevithan.com> (MIT license)
4788 * @api private
4789 */
4790
4791var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
4792
4793var parts = [
4794    'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host'
4795  , 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
4796];
4797
4798module.exports = function parseuri(str) {
4799  var m = re.exec(str || '')
4800    , uri = {}
4801    , i = 14;
4802
4803  while (i--) {
4804    uri[parts[i]] = m[i] || '';
4805  }
4806
4807  return uri;
4808};
4809
4810},{}],39:[function(_dereq_,module,exports){
4811(function (global){
4812/*global Blob,File*/
4813
4814/**
4815 * Module requirements
4816 */
4817
4818var isArray = _dereq_('isarray');
4819var isBuf = _dereq_('./is-buffer');
4820
4821/**
4822 * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
4823 * Anything with blobs or files should be fed through removeBlobs before coming
4824 * here.
4825 *
4826 * @param {Object} packet - socket.io event packet
4827 * @return {Object} with deconstructed packet and list of buffers
4828 * @api public
4829 */
4830
4831exports.deconstructPacket = function(packet){
4832  var buffers = [];
4833  var packetData = packet.data;
4834
4835  function _deconstructPacket(data) {
4836    if (!data) return data;
4837
4838    if (isBuf(data)) {
4839      var placeholder = { _placeholder: true, num: buffers.length };
4840      buffers.push(data);
4841      return placeholder;
4842    } else if (isArray(data)) {
4843      var newData = new Array(data.length);
4844      for (var i = 0; i < data.length; i++) {
4845        newData[i] = _deconstructPacket(data[i]);
4846      }
4847      return newData;
4848    } else if ('object' == typeof data && !(data instanceof Date)) {
4849      var newData = {};
4850      for (var key in data) {
4851        newData[key] = _deconstructPacket(data[key]);
4852      }
4853      return newData;
4854    }
4855    return data;
4856  }
4857
4858  var pack = packet;
4859  pack.data = _deconstructPacket(packetData);
4860  pack.attachments = buffers.length; // number of binary 'attachments'
4861  return {packet: pack, buffers: buffers};
4862};
4863
4864/**
4865 * Reconstructs a binary packet from its placeholder packet and buffers
4866 *
4867 * @param {Object} packet - event packet with placeholders
4868 * @param {Array} buffers - binary buffers to put in placeholder positions
4869 * @return {Object} reconstructed packet
4870 * @api public
4871 */
4872
4873exports.reconstructPacket = function(packet, buffers) {
4874  var curPlaceHolder = 0;
4875
4876  function _reconstructPacket(data) {
4877    if (data && data._placeholder) {
4878      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)
4879      return buf;
4880    } else if (isArray(data)) {
4881      for (var i = 0; i < data.length; i++) {
4882        data[i] = _reconstructPacket(data[i]);
4883      }
4884      return data;
4885    } else if (data && 'object' == typeof data) {
4886      for (var key in data) {
4887        data[key] = _reconstructPacket(data[key]);
4888      }
4889      return data;
4890    }
4891    return data;
4892  }
4893
4894  packet.data = _reconstructPacket(packet.data);
4895  packet.attachments = undefined; // no longer useful
4896  return packet;
4897};
4898
4899/**
4900 * Asynchronously removes Blobs or Files from data via
4901 * FileReader's readAsArrayBuffer method. Used before encoding
4902 * data as msgpack. Calls callback with the blobless data.
4903 *
4904 * @param {Object} data
4905 * @param {Function} callback
4906 * @api private
4907 */
4908
4909exports.removeBlobs = function(data, callback) {
4910  function _removeBlobs(obj, curKey, containingObject) {
4911    if (!obj) return obj;
4912
4913    // convert any blob
4914    if ((global.Blob && obj instanceof Blob) ||
4915        (global.File && obj instanceof File)) {
4916      pendingBlobs++;
4917
4918      // async filereader
4919      var fileReader = new FileReader();
4920      fileReader.onload = function() { // this.result == arraybuffer
4921        if (containingObject) {
4922          containingObject[curKey] = this.result;
4923        }
4924        else {
4925          bloblessData = this.result;
4926        }
4927
4928        // if nothing pending its callback time
4929        if(! --pendingBlobs) {
4930          callback(bloblessData);
4931        }
4932      };
4933
4934      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
4935    } else if (isArray(obj)) { // handle array
4936      for (var i = 0; i < obj.length; i++) {
4937        _removeBlobs(obj[i], i, obj);
4938      }
4939    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object
4940      for (var key in obj) {
4941        _removeBlobs(obj[key], key, obj);
4942      }
4943    }
4944  }
4945
4946  var pendingBlobs = 0;
4947  var bloblessData = data;
4948  _removeBlobs(bloblessData);
4949  if (!pendingBlobs) {
4950    callback(bloblessData);
4951  }
4952};
4953
4954}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4955},{"./is-buffer":41,"isarray":42}],40:[function(_dereq_,module,exports){
4956
4957/**
4958 * Module dependencies.
4959 */
4960
4961var debug = _dereq_('debug')('socket.io-parser');
4962var json = _dereq_('json3');
4963var isArray = _dereq_('isarray');
4964var Emitter = _dereq_('component-emitter');
4965var binary = _dereq_('./binary');
4966var isBuf = _dereq_('./is-buffer');
4967
4968/**
4969 * Protocol version.
4970 *
4971 * @api public
4972 */
4973
4974exports.protocol = 4;
4975
4976/**
4977 * Packet types.
4978 *
4979 * @api public
4980 */
4981
4982exports.types = [
4983  'CONNECT',
4984  'DISCONNECT',
4985  'EVENT',
4986  'BINARY_EVENT',
4987  'ACK',
4988  'BINARY_ACK',
4989  'ERROR'
4990];
4991
4992/**
4993 * Packet type `connect`.
4994 *
4995 * @api public
4996 */
4997
4998exports.CONNECT = 0;
4999
5000/**
5001 * Packet type `disconnect`.
5002 *
5003 * @api public
5004 */
5005
5006exports.DISCONNECT = 1;
5007
5008/**
5009 * Packet type `event`.
5010 *
5011 * @api public
5012 */
5013
5014exports.EVENT = 2;
5015
5016/**
5017 * Packet type `ack`.
5018 *
5019 * @api public
5020 */
5021
5022exports.ACK = 3;
5023
5024/**
5025 * Packet type `error`.
5026 *
5027 * @api public
5028 */
5029
5030exports.ERROR = 4;
5031
5032/**
5033 * Packet type 'binary event'
5034 *
5035 * @api public
5036 */
5037
5038exports.BINARY_EVENT = 5;
5039
5040/**
5041 * Packet type `binary ack`. For acks with binary arguments.
5042 *
5043 * @api public
5044 */
5045
5046exports.BINARY_ACK = 6;
5047
5048/**
5049 * Encoder constructor.
5050 *
5051 * @api public
5052 */
5053
5054exports.Encoder = Encoder;
5055
5056/**
5057 * Decoder constructor.
5058 *
5059 * @api public
5060 */
5061
5062exports.Decoder = Decoder;
5063
5064/**
5065 * A socket.io Encoder instance
5066 *
5067 * @api public
5068 */
5069
5070function Encoder() {}
5071
5072/**
5073 * Encode a packet as a single string if non-binary, or as a
5074 * buffer sequence, depending on packet type.
5075 *
5076 * @param {Object} obj - packet object
5077 * @param {Function} callback - function to handle encodings (likely engine.write)
5078 * @return Calls callback with Array of encodings
5079 * @api public
5080 */
5081
5082Encoder.prototype.encode = function(obj, callback){
5083  debug('encoding packet %j', obj);
5084
5085  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
5086    encodeAsBinary(obj, callback);
5087  }
5088  else {
5089    var encoding = encodeAsString(obj);
5090    callback([encoding]);
5091  }
5092};
5093
5094/**
5095 * Encode packet as string.
5096 *
5097 * @param {Object} packet
5098 * @return {String} encoded
5099 * @api private
5100 */
5101
5102function encodeAsString(obj) {
5103  var str = '';
5104  var nsp = false;
5105
5106  // first is type
5107  str += obj.type;
5108
5109  // attachments if we have them
5110  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
5111    str += obj.attachments;
5112    str += '-';
5113  }
5114
5115  // if we have a namespace other than `/`
5116  // we append it followed by a comma `,`
5117  if (obj.nsp && '/' != obj.nsp) {
5118    nsp = true;
5119    str += obj.nsp;
5120  }
5121
5122  // immediately followed by the id
5123  if (null != obj.id) {
5124    if (nsp) {
5125      str += ',';
5126      nsp = false;
5127    }
5128    str += obj.id;
5129  }
5130
5131  // json data
5132  if (null != obj.data) {
5133    if (nsp) str += ',';
5134    str += json.stringify(obj.data);
5135  }
5136
5137  debug('encoded %j as %s', obj, str);
5138  return str;
5139}
5140
5141/**
5142 * Encode packet as 'buffer sequence' by removing blobs, and
5143 * deconstructing packet into object with placeholders and
5144 * a list of buffers.
5145 *
5146 * @param {Object} packet
5147 * @return {Buffer} encoded
5148 * @api private
5149 */
5150
5151function encodeAsBinary(obj, callback) {
5152
5153  function writeEncoding(bloblessData) {
5154    var deconstruction = binary.deconstructPacket(bloblessData);
5155    var pack = encodeAsString(deconstruction.packet);
5156    var buffers = deconstruction.buffers;
5157
5158    buffers.unshift(pack); // add packet info to beginning of data list
5159    callback(buffers); // write all the buffers
5160  }
5161
5162  binary.removeBlobs(obj, writeEncoding);
5163}
5164
5165/**
5166 * A socket.io Decoder instance
5167 *
5168 * @return {Object} decoder
5169 * @api public
5170 */
5171
5172function Decoder() {
5173  this.reconstructor = null;
5174}
5175
5176/**
5177 * Mix in `Emitter` with Decoder.
5178 */
5179
5180Emitter(Decoder.prototype);
5181
5182/**
5183 * Decodes an ecoded packet string into packet JSON.
5184 *
5185 * @param {String} obj - encoded packet
5186 * @return {Object} packet
5187 * @api public
5188 */
5189
5190Decoder.prototype.add = function(obj) {
5191  var packet;
5192  if ('string' == typeof obj) {
5193    packet = decodeString(obj);
5194    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json
5195      this.reconstructor = new BinaryReconstructor(packet);
5196
5197      // no attachments, labeled binary but no binary data to follow
5198      if (this.reconstructor.reconPack.attachments == 0) {
5199        this.emit('decoded', packet);
5200      }
5201    } else { // non-binary full packet
5202      this.emit('decoded', packet);
5203    }
5204  }
5205  else if (isBuf(obj) || obj.base64) { // raw binary data
5206    if (!this.reconstructor) {
5207      throw new Error('got binary data when not reconstructing a packet');
5208    } else {
5209      packet = this.reconstructor.takeBinaryData(obj);
5210      if (packet) { // received final buffer
5211        this.reconstructor = null;
5212        this.emit('decoded', packet);
5213      }
5214    }
5215  }
5216  else {
5217    throw new Error('Unknown type: ' + obj);
5218  }
5219};
5220
5221/**
5222 * Decode a packet String (JSON data)
5223 *
5224 * @param {String} str
5225 * @return {Object} packet
5226 * @api private
5227 */
5228
5229function decodeString(str) {
5230  var p = {};
5231  var i = 0;
5232
5233  // look up type
5234  p.type = Number(str.charAt(0));
5235  if (null == exports.types[p.type]) return error();
5236
5237  // look up attachments if type binary
5238  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {
5239    p.attachments = '';
5240    while (str.charAt(++i) != '-') {
5241      p.attachments += str.charAt(i);
5242    }
5243    p.attachments = Number(p.attachments);
5244  }
5245
5246  // look up namespace (if any)
5247  if ('/' == str.charAt(i + 1)) {
5248    p.nsp = '';
5249    while (++i) {
5250      var c = str.charAt(i);
5251      if (',' == c) break;
5252      p.nsp += c;
5253      if (i + 1 == str.length) break;
5254    }
5255  } else {
5256    p.nsp = '/';
5257  }
5258
5259  // look up id
5260  var next = str.charAt(i + 1);
5261  if ('' != next && Number(next) == next) {
5262    p.id = '';
5263    while (++i) {
5264      var c = str.charAt(i);
5265      if (null == c || Number(c) != c) {
5266        --i;
5267        break;
5268      }
5269      p.id += str.charAt(i);
5270      if (i + 1 == str.length) break;
5271    }
5272    p.id = Number(p.id);
5273  }
5274
5275  // look up json data
5276  if (str.charAt(++i)) {
5277    try {
5278      p.data = json.parse(str.substr(i));
5279    } catch(e){
5280      return error();
5281    }
5282  }
5283
5284  debug('decoded %s as %j', str, p);
5285  return p;
5286}
5287
5288/**
5289 * Deallocates a parser's resources
5290 *
5291 * @api public
5292 */
5293
5294Decoder.prototype.destroy = function() {
5295  if (this.reconstructor) {
5296    this.reconstructor.finishedReconstruction();
5297  }
5298};
5299
5300/**
5301 * A manager of a binary event's 'buffer sequence'. Should
5302 * be constructed whenever a packet of type BINARY_EVENT is
5303 * decoded.
5304 *
5305 * @param {Object} packet
5306 * @return {BinaryReconstructor} initialized reconstructor
5307 * @api private
5308 */
5309
5310function BinaryReconstructor(packet) {
5311  this.reconPack = packet;
5312  this.buffers = [];
5313}
5314
5315/**
5316 * Method to be called when binary data received from connection
5317 * after a BINARY_EVENT packet.
5318 *
5319 * @param {Buffer | ArrayBuffer} binData - the raw binary data received
5320 * @return {null | Object} returns null if more binary data is expected or
5321 *   a reconstructed packet object if all buffers have been received.
5322 * @api private
5323 */
5324
5325BinaryReconstructor.prototype.takeBinaryData = function(binData) {
5326  this.buffers.push(binData);
5327  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list
5328    var packet = binary.reconstructPacket(this.reconPack, this.buffers);
5329    this.finishedReconstruction();
5330    return packet;
5331  }
5332  return null;
5333};
5334
5335/**
5336 * Cleans up binary packet reconstruction variables.
5337 *
5338 * @api private
5339 */
5340
5341BinaryReconstructor.prototype.finishedReconstruction = function() {
5342  this.reconPack = null;
5343  this.buffers = [];
5344};
5345
5346function error(data){
5347  return {
5348    type: exports.ERROR,
5349    data: 'parser error'
5350  };
5351}
5352
5353},{"./binary":39,"./is-buffer":41,"component-emitter":8,"debug":9,"isarray":42,"json3":43}],41:[function(_dereq_,module,exports){
5354(function (global){
5355
5356module.exports = isBuf;
5357
5358/**
5359 * Returns true if obj is a buffer or an arraybuffer.
5360 *
5361 * @api private
5362 */
5363
5364function isBuf(obj) {
5365  return (global.Buffer && global.Buffer.isBuffer(obj)) ||
5366         (global.ArrayBuffer && obj instanceof ArrayBuffer);
5367}
5368
5369}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
5370},{}],42:[function(_dereq_,module,exports){
5371module.exports=_dereq_(33)
5372},{}],43:[function(_dereq_,module,exports){
5373/*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */
5374;(function (window) {
5375  // Convenience aliases.
5376  var getClass = {}.toString, isProperty, forEach, undef;
5377
5378  // Detect the `define` function exposed by asynchronous module loaders. The
5379  // strict `define` check is necessary for compatibility with `r.js`.
5380  var isLoader = typeof define === "function" && define.amd;
5381
5382  // Detect native implementations.
5383  var nativeJSON = typeof JSON == "object" && JSON;
5384
5385  // Set up the JSON 3 namespace, preferring the CommonJS `exports` object if
5386  // available.
5387  var JSON3 = typeof exports == "object" && exports && !exports.nodeType && exports;
5388
5389  if (JSON3 && nativeJSON) {
5390    // Explicitly delegate to the native `stringify` and `parse`
5391    // implementations in CommonJS environments.
5392    JSON3.stringify = nativeJSON.stringify;
5393    JSON3.parse = nativeJSON.parse;
5394  } else {
5395    // Export for web browsers, JavaScript engines, and asynchronous module
5396    // loaders, using the global `JSON` object if available.
5397    JSON3 = window.JSON = nativeJSON || {};
5398  }
5399
5400  // Test the `Date#getUTC*` methods. Based on work by @Yaffle.
5401  var isExtended = new Date(-3509827334573292);
5402  try {
5403    // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
5404    // results for certain dates in Opera >= 10.53.
5405    isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
5406      // Safari < 2.0.2 stores the internal millisecond time value correctly,
5407      // but clips the values returned by the date methods to the range of
5408      // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
5409      isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
5410  } catch (exception) {}
5411
5412  // Internal: Determines whether the native `JSON.stringify` and `parse`
5413  // implementations are spec-compliant. Based on work by Ken Snyder.
5414  function has(name) {
5415    if (has[name] !== undef) {
5416      // Return cached feature test result.
5417      return has[name];
5418    }
5419
5420    var isSupported;
5421    if (name == "bug-string-char-index") {
5422      // IE <= 7 doesn't support accessing string characters using square
5423      // bracket notation. IE 8 only supports this for primitives.
5424      isSupported = "a"[0] != "a";
5425    } else if (name == "json") {
5426      // Indicates whether both `JSON.stringify` and `JSON.parse` are
5427      // supported.
5428      isSupported = has("json-stringify") && has("json-parse");
5429    } else {
5430      var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
5431      // Test `JSON.stringify`.
5432      if (name == "json-stringify") {
5433        var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended;
5434        if (stringifySupported) {
5435          // A test function object with a custom `toJSON` method.
5436          (value = function () {
5437            return 1;
5438          }).toJSON = value;
5439          try {
5440            stringifySupported =
5441              // Firefox 3.1b1 and b2 serialize string, number, and boolean
5442              // primitives as object literals.
5443              stringify(0) === "0" &&
5444              // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
5445              // literals.
5446              stringify(new Number()) === "0" &&
5447              stringify(new String()) == '""' &&
5448              // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
5449              // does not define a canonical JSON representation (this applies to
5450              // objects with `toJSON` properties as well, *unless* they are nested
5451              // within an object or array).
5452              stringify(getClass) === undef &&
5453              // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
5454              // FF 3.1b3 pass this test.
5455              stringify(undef) === undef &&
5456              // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
5457              // respectively, if the value is omitted entirely.
5458              stringify() === undef &&
5459              // FF 3.1b1, 2 throw an error if the given value is not a number,
5460              // string, array, object, Boolean, or `null` literal. This applies to
5461              // objects with custom `toJSON` methods as well, unless they are nested
5462              // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
5463              // methods entirely.
5464              stringify(value) === "1" &&
5465              stringify([value]) == "[1]" &&
5466              // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
5467              // `"[null]"`.
5468              stringify([undef]) == "[null]" &&
5469              // YUI 3.0.0b1 fails to serialize `null` literals.
5470              stringify(null) == "null" &&
5471              // FF 3.1b1, 2 halts serialization if an array contains a function:
5472              // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
5473              // elides non-JSON values from objects and arrays, unless they
5474              // define custom `toJSON` methods.
5475              stringify([undef, getClass, null]) == "[null,null,null]" &&
5476              // Simple serialization test. FF 3.1b1 uses Unicode escape sequences
5477              // where character escape codes are expected (e.g., `\b` => `\u0008`).
5478              stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
5479              // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
5480              stringify(null, value) === "1" &&
5481              stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
5482              // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
5483              // serialize extended years.
5484              stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
5485              // The milliseconds are optional in ES 5, but required in 5.1.
5486              stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
5487              // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
5488              // four-digit years instead of six-digit years. Credits: @Yaffle.
5489              stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
5490              // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
5491              // values less than 1000. Credits: @Yaffle.
5492              stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
5493          } catch (exception) {
5494            stringifySupported = false;
5495          }
5496        }
5497        isSupported = stringifySupported;
5498      }
5499      // Test `JSON.parse`.
5500      if (name == "json-parse") {
5501        var parse = JSON3.parse;
5502        if (typeof parse == "function") {
5503          try {
5504            // FF 3.1b1, b2 will throw an exception if a bare literal is provided.
5505            // Conforming implementations should also coerce the initial argument to
5506            // a string prior to parsing.
5507            if (parse("0") === 0 && !parse(false)) {
5508              // Simple parsing test.
5509              value = parse(serialized);
5510              var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
5511              if (parseSupported) {
5512                try {
5513                  // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
5514                  parseSupported = !parse('"\t"');
5515                } catch (exception) {}
5516                if (parseSupported) {
5517                  try {
5518                    // FF 4.0 and 4.0.1 allow leading `+` signs and leading
5519                    // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
5520                    // certain octal literals.
5521                    parseSupported = parse("01") !== 1;
5522                  } catch (exception) {}
5523                }
5524                if (parseSupported) {
5525                  try {
5526                    // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
5527                    // points. These environments, along with FF 3.1b1 and 2,
5528                    // also allow trailing commas in JSON objects and arrays.
5529                    parseSupported = parse("1.") !== 1;
5530                  } catch (exception) {}
5531                }
5532              }
5533            }
5534          } catch (exception) {
5535            parseSupported = false;
5536          }
5537        }
5538        isSupported = parseSupported;
5539      }
5540    }
5541    return has[name] = !!isSupported;
5542  }
5543
5544  if (!has("json")) {
5545    // Common `[[Class]]` name aliases.
5546    var functionClass = "[object Function]";
5547    var dateClass = "[object Date]";
5548    var numberClass = "[object Number]";
5549    var stringClass = "[object String]";
5550    var arrayClass = "[object Array]";
5551    var booleanClass = "[object Boolean]";
5552
5553    // Detect incomplete support for accessing string characters by index.
5554    var charIndexBuggy = has("bug-string-char-index");
5555
5556    // Define additional utility methods if the `Date` methods are buggy.
5557    if (!isExtended) {
5558      var floor = Math.floor;
5559      // A mapping between the months of the year and the number of days between
5560      // January 1st and the first of the respective month.
5561      var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
5562      // Internal: Calculates the number of days between the Unix epoch and the
5563      // first day of the given month.
5564      var getDay = function (year, month) {
5565        return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
5566      };
5567    }
5568
5569    // Internal: Determines if a property is a direct property of the given
5570    // object. Delegates to the native `Object#hasOwnProperty` method.
5571    if (!(isProperty = {}.hasOwnProperty)) {
5572      isProperty = function (property) {
5573        var members = {}, constructor;
5574        if ((members.__proto__ = null, members.__proto__ = {
5575          // The *proto* property cannot be set multiple times in recent
5576          // versions of Firefox and SeaMonkey.
5577          "toString": 1
5578        }, members).toString != getClass) {
5579          // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
5580          // supports the mutable *proto* property.
5581          isProperty = function (property) {
5582            // Capture and break the object's prototype chain (see section 8.6.2
5583            // of the ES 5.1 spec). The parenthesized expression prevents an
5584            // unsafe transformation by the Closure Compiler.
5585            var original = this.__proto__, result = property in (this.__proto__ = null, this);
5586            // Restore the original prototype chain.
5587            this.__proto__ = original;
5588            return result;
5589          };
5590        } else {
5591          // Capture a reference to the top-level `Object` constructor.
5592          constructor = members.constructor;
5593          // Use the `constructor` property to simulate `Object#hasOwnProperty` in
5594          // other environments.
5595          isProperty = function (property) {
5596            var parent = (this.constructor || constructor).prototype;
5597            return property in this && !(property in parent && this[property] === parent[property]);
5598          };
5599        }
5600        members = null;
5601        return isProperty.call(this, property);
5602      };
5603    }
5604
5605    // Internal: A set of primitive types used by `isHostType`.
5606    var PrimitiveTypes = {
5607      'boolean': 1,
5608      'number': 1,
5609      'string': 1,
5610      'undefined': 1
5611    };
5612
5613    // Internal: Determines if the given object `property` value is a
5614    // non-primitive.
5615    var isHostType = function (object, property) {
5616      var type = typeof object[property];
5617      return type == 'object' ? !!object[property] : !PrimitiveTypes[type];
5618    };
5619
5620    // Internal: Normalizes the `for...in` iteration algorithm across
5621    // environments. Each enumerated key is yielded to a `callback` function.
5622    forEach = function (object, callback) {
5623      var size = 0, Properties, members, property;
5624
5625      // Tests for bugs in the current environment's `for...in` algorithm. The
5626      // `valueOf` property inherits the non-enumerable flag from
5627      // `Object.prototype` in older versions of IE, Netscape, and Mozilla.
5628      (Properties = function () {
5629        this.valueOf = 0;
5630      }).prototype.valueOf = 0;
5631
5632      // Iterate over a new instance of the `Properties` class.
5633      members = new Properties();
5634      for (property in members) {
5635        // Ignore all properties inherited from `Object.prototype`.
5636        if (isProperty.call(members, property)) {
5637          size++;
5638        }
5639      }
5640      Properties = members = null;
5641
5642      // Normalize the iteration algorithm.
5643      if (!size) {
5644        // A list of non-enumerable properties inherited from `Object.prototype`.
5645        members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
5646        // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
5647        // properties.
5648        forEach = function (object, callback) {
5649          var isFunction = getClass.call(object) == functionClass, property, length;
5650          var hasProperty = !isFunction && typeof object.constructor != 'function' && isHostType(object, 'hasOwnProperty') ? object.hasOwnProperty : isProperty;
5651          for (property in object) {
5652            // Gecko <= 1.0 enumerates the `prototype` property of functions under
5653            // certain conditions; IE does not.
5654            if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
5655              callback(property);
5656            }
5657          }
5658          // Manually invoke the callback for each non-enumerable property.
5659          for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));
5660        };
5661      } else if (size == 2) {
5662        // Safari <= 2.0.4 enumerates shadowed properties twice.
5663        forEach = function (object, callback) {
5664          // Create a set of iterated properties.
5665          var members = {}, isFunction = getClass.call(object) == functionClass, property;
5666          for (property in object) {
5667            // Store each property name to prevent double enumeration. The
5668            // `prototype` property of functions is not enumerated due to cross-
5669            // environment inconsistencies.
5670            if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
5671              callback(property);
5672            }
5673          }
5674        };
5675      } else {
5676        // No bugs detected; use the standard `for...in` algorithm.
5677        forEach = function (object, callback) {
5678          var isFunction = getClass.call(object) == functionClass, property, isConstructor;
5679          for (property in object) {
5680            if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
5681              callback(property);
5682            }
5683          }
5684          // Manually invoke the callback for the `constructor` property due to
5685          // cross-environment inconsistencies.
5686          if (isConstructor || isProperty.call(object, (property = "constructor"))) {
5687            callback(property);
5688          }
5689        };
5690      }
5691      return forEach(object, callback);
5692    };
5693
5694    // Public: Serializes a JavaScript `value` as a JSON string. The optional
5695    // `filter` argument may specify either a function that alters how object and
5696    // array members are serialized, or an array of strings and numbers that
5697    // indicates which properties should be serialized. The optional `width`
5698    // argument may be either a string or number that specifies the indentation
5699    // level of the output.
5700    if (!has("json-stringify")) {
5701      // Internal: A map of control characters and their escaped equivalents.
5702      var Escapes = {
5703        92: "\\\\",
5704        34: '\\"',
5705        8: "\\b",
5706        12: "\\f",
5707        10: "\\n",
5708        13: "\\r",
5709        9: "\\t"
5710      };
5711
5712      // Internal: Converts `value` into a zero-padded string such that its
5713      // length is at least equal to `width`. The `width` must be <= 6.
5714      var leadingZeroes = "000000";
5715      var toPaddedString = function (width, value) {
5716        // The `|| 0` expression is necessary to work around a bug in
5717        // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
5718        return (leadingZeroes + (value || 0)).slice(-width);
5719      };
5720
5721      // Internal: Double-quotes a string `value`, replacing all ASCII control
5722      // characters (characters with code unit values between 0 and 31) with
5723      // their escaped equivalents. This is an implementation of the
5724      // `Quote(value)` operation defined in ES 5.1 section 15.12.3.
5725      var unicodePrefix = "\\u00";
5726      var quote = function (value) {
5727        var result = '"', index = 0, length = value.length, isLarge = length > 10 && charIndexBuggy, symbols;
5728        if (isLarge) {
5729          symbols = value.split("");
5730        }
5731        for (; index < length; index++) {
5732          var charCode = value.charCodeAt(index);
5733          // If the character is a control character, append its Unicode or
5734          // shorthand escape sequence; otherwise, append the character as-is.
5735          switch (charCode) {
5736            case 8: case 9: case 10: case 12: case 13: case 34: case 92:
5737              result += Escapes[charCode];
5738              break;
5739            default:
5740              if (charCode < 32) {
5741                result += unicodePrefix + toPaddedString(2, charCode.toString(16));
5742                break;
5743              }
5744              result += isLarge ? symbols[index] : charIndexBuggy ? value.charAt(index) : value[index];
5745          }
5746        }
5747        return result + '"';
5748      };
5749
5750      // Internal: Recursively serializes an object. Implements the
5751      // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
5752      var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
5753        var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;
5754        try {
5755          // Necessary for host object support.
5756          value = object[property];
5757        } catch (exception) {}
5758        if (typeof value == "object" && value) {
5759          className = getClass.call(value);
5760          if (className == dateClass && !isProperty.call(value, "toJSON")) {
5761            if (value > -1 / 0 && value < 1 / 0) {
5762              // Dates are serialized according to the `Date#toJSON` method
5763              // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
5764              // for the ISO 8601 date time string format.
5765              if (getDay) {
5766                // Manually compute the year, month, date, hours, minutes,
5767                // seconds, and milliseconds if the `getUTC*` methods are
5768                // buggy. Adapted from @Yaffle's `date-shim` project.
5769                date = floor(value / 864e5);
5770                for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
5771                for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
5772                date = 1 + date - getDay(year, month);
5773                // The `time` value specifies the time within the day (see ES
5774                // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
5775                // to compute `A modulo B`, as the `%` operator does not
5776                // correspond to the `modulo` operation for negative numbers.
5777                time = (value % 864e5 + 864e5) % 864e5;
5778                // The hours, minutes, seconds, and milliseconds are obtained by
5779                // decomposing the time within the day. See section 15.9.1.10.
5780                hours = floor(time / 36e5) % 24;
5781                minutes = floor(time / 6e4) % 60;
5782                seconds = floor(time / 1e3) % 60;
5783                milliseconds = time % 1e3;
5784              } else {
5785                year = value.getUTCFullYear();
5786                month = value.getUTCMonth();
5787                date = value.getUTCDate();
5788                hours = value.getUTCHours();
5789                minutes = value.getUTCMinutes();
5790                seconds = value.getUTCSeconds();
5791                milliseconds = value.getUTCMilliseconds();
5792              }
5793              // Serialize extended years correctly.
5794              value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
5795                "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
5796                // Months, dates, hours, minutes, and seconds should have two
5797                // digits; milliseconds should have three.
5798                "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
5799                // Milliseconds are optional in ES 5.0, but required in 5.1.
5800                "." + toPaddedString(3, milliseconds) + "Z";
5801            } else {
5802              value = null;
5803            }
5804          } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
5805            // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
5806            // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
5807            // ignores all `toJSON` methods on these objects unless they are
5808            // defined directly on an instance.
5809            value = value.toJSON(property);
5810          }
5811        }
5812        if (callback) {
5813          // If a replacement function was provided, call it to obtain the value
5814          // for serialization.
5815          value = callback.call(object, property, value);
5816        }
5817        if (value === null) {
5818          return "null";
5819        }
5820        className = getClass.call(value);
5821        if (className == booleanClass) {
5822          // Booleans are represented literally.
5823          return "" + value;
5824        } else if (className == numberClass) {
5825          // JSON numbers must be finite. `Infinity` and `NaN` are serialized as
5826          // `"null"`.
5827          return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
5828        } else if (className == stringClass) {
5829          // Strings are double-quoted and escaped.
5830          return quote("" + value);
5831        }
5832        // Recursively serialize objects and arrays.
5833        if (typeof value == "object") {
5834          // Check for cyclic structures. This is a linear search; performance
5835          // is inversely proportional to the number of unique nested objects.
5836          for (length = stack.length; length--;) {
5837            if (stack[length] === value) {
5838              // Cyclic structures cannot be serialized by `JSON.stringify`.
5839              throw TypeError();
5840            }
5841          }
5842          // Add the object to the stack of traversed objects.
5843          stack.push(value);
5844          results = [];
5845          // Save the current indentation level and indent one additional level.
5846          prefix = indentation;
5847          indentation += whitespace;
5848          if (className == arrayClass) {
5849            // Recursively serialize array elements.
5850            for (index = 0, length = value.length; index < length; index++) {
5851              element = serialize(index, value, callback, properties, whitespace, indentation, stack);
5852              results.push(element === undef ? "null" : element);
5853            }
5854            result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
5855          } else {
5856            // Recursively serialize object members. Members are selected from
5857            // either a user-specified list of property names, or the object
5858            // itself.
5859            forEach(properties || value, function (property) {
5860              var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
5861              if (element !== undef) {
5862                // According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
5863                // is not the empty string, let `member` {quote(property) + ":"}
5864                // be the concatenation of `member` and the `space` character."
5865                // The "`space` character" refers to the literal space
5866                // character, not the `space` {width} argument provided to
5867                // `JSON.stringify`.
5868                results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
5869              }
5870            });
5871            result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
5872          }
5873          // Remove the object from the traversed object stack.
5874          stack.pop();
5875          return result;
5876        }
5877      };
5878
5879      // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
5880      JSON3.stringify = function (source, filter, width) {
5881        var whitespace, callback, properties, className;
5882        if (typeof filter == "function" || typeof filter == "object" && filter) {
5883          if ((className = getClass.call(filter)) == functionClass) {
5884            callback = filter;
5885          } else if (className == arrayClass) {
5886            // Convert the property names array into a makeshift set.
5887            properties = {};
5888            for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));
5889          }
5890        }
5891        if (width) {
5892          if ((className = getClass.call(width)) == numberClass) {
5893            // Convert the `width` to an integer and create a string containing
5894            // `width` number of space characters.
5895            if ((width -= width % 1) > 0) {
5896              for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
5897            }
5898          } else if (className == stringClass) {
5899            whitespace = width.length <= 10 ? width : width.slice(0, 10);
5900          }
5901        }
5902        // Opera <= 7.54u2 discards the values associated with empty string keys
5903        // (`""`) only if they are used directly within an object member list
5904        // (e.g., `!("" in { "": 1})`).
5905        return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
5906      };
5907    }
5908
5909    // Public: Parses a JSON source string.
5910    if (!has("json-parse")) {
5911      var fromCharCode = String.fromCharCode;
5912
5913      // Internal: A map of escaped control characters and their unescaped
5914      // equivalents.
5915      var Unescapes = {
5916        92: "\\",
5917        34: '"',
5918        47: "/",
5919        98: "\b",
5920        116: "\t",
5921        110: "\n",
5922        102: "\f",
5923        114: "\r"
5924      };
5925
5926      // Internal: Stores the parser state.
5927      var Index, Source;
5928
5929      // Internal: Resets the parser state and throws a `SyntaxError`.
5930      var abort = function() {
5931        Index = Source = null;
5932        throw SyntaxError();
5933      };
5934
5935      // Internal: Returns the next token, or `"$"` if the parser has reached
5936      // the end of the source string. A token may be a string, number, `null`
5937      // literal, or Boolean literal.
5938      var lex = function () {
5939        var source = Source, length = source.length, value, begin, position, isSigned, charCode;
5940        while (Index < length) {
5941          charCode = source.charCodeAt(Index);
5942          switch (charCode) {
5943            case 9: case 10: case 13: case 32:
5944              // Skip whitespace tokens, including tabs, carriage returns, line
5945              // feeds, and space characters.
5946              Index++;
5947              break;
5948            case 123: case 125: case 91: case 93: case 58: case 44:
5949              // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
5950              // the current position.
5951              value = charIndexBuggy ? source.charAt(Index) : source[Index];
5952              Index++;
5953              return value;
5954            case 34:
5955              // `"` delimits a JSON string; advance to the next character and
5956              // begin parsing the string. String tokens are prefixed with the
5957              // sentinel `@` character to distinguish them from punctuators and
5958              // end-of-string tokens.
5959              for (value = "@", Index++; Index < length;) {
5960                charCode = source.charCodeAt(Index);
5961                if (charCode < 32) {
5962                  // Unescaped ASCII control characters (those with a code unit
5963                  // less than the space character) are not permitted.
5964                  abort();
5965                } else if (charCode == 92) {
5966                  // A reverse solidus (`\`) marks the beginning of an escaped
5967                  // control character (including `"`, `\`, and `/`) or Unicode
5968                  // escape sequence.
5969                  charCode = source.charCodeAt(++Index);
5970                  switch (charCode) {
5971                    case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:
5972                      // Revive escaped control characters.
5973                      value += Unescapes[charCode];
5974                      Index++;
5975                      break;
5976                    case 117:
5977                      // `\u` marks the beginning of a Unicode escape sequence.
5978                      // Advance to the first character and validate the
5979                      // four-digit code point.
5980                      begin = ++Index;
5981                      for (position = Index + 4; Index < position; Index++) {
5982                        charCode = source.charCodeAt(Index);
5983                        // A valid sequence comprises four hexdigits (case-
5984                        // insensitive) that form a single hexadecimal value.
5985                        if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
5986                          // Invalid Unicode escape sequence.
5987                          abort();
5988                        }
5989                      }
5990                      // Revive the escaped character.
5991                      value += fromCharCode("0x" + source.slice(begin, Index));
5992                      break;
5993                    default:
5994                      // Invalid escape sequence.
5995                      abort();
5996                  }
5997                } else {
5998                  if (charCode == 34) {
5999                    // An unescaped double-quote character marks the end of the
6000                    // string.
6001                    break;
6002                  }
6003                  charCode = source.charCodeAt(Index);
6004                  begin = Index;
6005                  // Optimize for the common case where a string is valid.
6006                  while (charCode >= 32 && charCode != 92 && charCode != 34) {
6007                    charCode = source.charCodeAt(++Index);
6008                  }
6009                  // Append the string as-is.
6010                  value += source.slice(begin, Index);
6011                }
6012              }
6013              if (source.charCodeAt(Index) == 34) {
6014                // Advance to the next character and return the revived string.
6015                Index++;
6016                return value;
6017              }
6018              // Unterminated string.
6019              abort();
6020            default:
6021              // Parse numbers and literals.
6022              begin = Index;
6023              // Advance past the negative sign, if one is specified.
6024              if (charCode == 45) {
6025                isSigned = true;
6026                charCode = source.charCodeAt(++Index);
6027              }
6028              // Parse an integer or floating-point value.
6029              if (charCode >= 48 && charCode <= 57) {
6030                // Leading zeroes are interpreted as octal literals.
6031                if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
6032                  // Illegal octal literal.
6033                  abort();
6034                }
6035                isSigned = false;
6036                // Parse the integer component.
6037                for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);
6038                // Floats cannot contain a leading decimal point; however, this
6039                // case is already accounted for by the parser.
6040                if (source.charCodeAt(Index) == 46) {
6041                  position = ++Index;
6042                  // Parse the decimal component.
6043                  for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
6044                  if (position == Index) {
6045                    // Illegal trailing decimal.
6046                    abort();
6047                  }
6048                  Index = position;
6049                }
6050                // Parse exponents. The `e` denoting the exponent is
6051                // case-insensitive.
6052                charCode = source.charCodeAt(Index);
6053                if (charCode == 101 || charCode == 69) {
6054                  charCode = source.charCodeAt(++Index);
6055                  // Skip past the sign following the exponent, if one is
6056                  // specified.
6057                  if (charCode == 43 || charCode == 45) {
6058                    Index++;
6059                  }
6060                  // Parse the exponential component.
6061                  for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
6062                  if (position == Index) {
6063                    // Illegal empty exponent.
6064                    abort();
6065                  }
6066                  Index = position;
6067                }
6068                // Coerce the parsed value to a JavaScript number.
6069                return +source.slice(begin, Index);
6070              }
6071              // A negative sign may only precede numbers.
6072              if (isSigned) {
6073                abort();
6074              }
6075              // `true`, `false`, and `null` literals.
6076              if (source.slice(Index, Index + 4) == "true") {
6077                Index += 4;
6078                return true;
6079              } else if (source.slice(Index, Index + 5) == "false") {
6080                Index += 5;
6081                return false;
6082              } else if (source.slice(Index, Index + 4) == "null") {
6083                Index += 4;
6084                return null;
6085              }
6086              // Unrecognized token.
6087              abort();
6088          }
6089        }
6090        // Return the sentinel `$` character if the parser has reached the end
6091        // of the source string.
6092        return "$";
6093      };
6094
6095      // Internal: Parses a JSON `value` token.
6096      var get = function (value) {
6097        var results, hasMembers;
6098        if (value == "$") {
6099          // Unexpected end of input.
6100          abort();
6101        }
6102        if (typeof value == "string") {
6103          if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
6104            // Remove the sentinel `@` character.
6105            return value.slice(1);
6106          }
6107          // Parse object and array literals.
6108          if (value == "[") {
6109            // Parses a JSON array, returning a new JavaScript array.
6110            results = [];
6111            for (;; hasMembers || (hasMembers = true)) {
6112              value = lex();
6113              // A closing square bracket marks the end of the array literal.
6114              if (value == "]") {
6115                break;
6116              }
6117              // If the array literal contains elements, the current token
6118              // should be a comma separating the previous element from the
6119              // next.
6120              if (hasMembers) {
6121                if (value == ",") {
6122                  value = lex();
6123                  if (value == "]") {
6124                    // Unexpected trailing `,` in array literal.
6125                    abort();
6126                  }
6127                } else {
6128                  // A `,` must separate each array element.
6129                  abort();
6130                }
6131              }
6132              // Elisions and leading commas are not permitted.
6133              if (value == ",") {
6134                abort();
6135              }
6136              results.push(get(value));
6137            }
6138            return results;
6139          } else if (value == "{") {
6140            // Parses a JSON object, returning a new JavaScript object.
6141            results = {};
6142            for (;; hasMembers || (hasMembers = true)) {
6143              value = lex();
6144              // A closing curly brace marks the end of the object literal.
6145              if (value == "}") {
6146                break;
6147              }
6148              // If the object literal contains members, the current token
6149              // should be a comma separator.
6150              if (hasMembers) {
6151                if (value == ",") {
6152                  value = lex();
6153                  if (value == "}") {
6154                    // Unexpected trailing `,` in object literal.
6155                    abort();
6156                  }
6157                } else {
6158                  // A `,` must separate each object member.
6159                  abort();
6160                }
6161              }
6162              // Leading commas are not permitted, object property names must be
6163              // double-quoted strings, and a `:` must separate each property
6164              // name and value.
6165              if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
6166                abort();
6167              }
6168              results[value.slice(1)] = get(lex());
6169            }
6170            return results;
6171          }
6172          // Unexpected token encountered.
6173          abort();
6174        }
6175        return value;
6176      };
6177
6178      // Internal: Updates a traversed object member.
6179      var update = function(source, property, callback) {
6180        var element = walk(source, property, callback);
6181        if (element === undef) {
6182          delete source[property];
6183        } else {
6184          source[property] = element;
6185        }
6186      };
6187
6188      // Internal: Recursively traverses a parsed JSON object, invoking the
6189      // `callback` function for each value. This is an implementation of the
6190      // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
6191      var walk = function (source, property, callback) {
6192        var value = source[property], length;
6193        if (typeof value == "object" && value) {
6194          // `forEach` can't be used to traverse an array in Opera <= 8.54
6195          // because its `Object#hasOwnProperty` implementation returns `false`
6196          // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
6197          if (getClass.call(value) == arrayClass) {
6198            for (length = value.length; length--;) {
6199              update(value, length, callback);
6200            }
6201          } else {
6202            forEach(value, function (property) {
6203              update(value, property, callback);
6204            });
6205          }
6206        }
6207        return callback.call(source, property, value);
6208      };
6209
6210      // Public: `JSON.parse`. See ES 5.1 section 15.12.2.
6211      JSON3.parse = function (source, callback) {
6212        var result, value;
6213        Index = 0;
6214        Source = "" + source;
6215        result = get(lex());
6216        // If a JSON string contains multiple tokens, it is invalid.
6217        if (lex() != "$") {
6218          abort();
6219        }
6220        // Reset the parser state.
6221        Index = Source = null;
6222        return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
6223      };
6224    }
6225  }
6226
6227  // Export for asynchronous module loaders.
6228  if (isLoader) {
6229    define(function () {
6230      return JSON3;
6231    });
6232  }
6233}(this));
6234
6235},{}],44:[function(_dereq_,module,exports){
6236module.exports = toArray
6237
6238function toArray(list, index) {
6239    var array = []
6240
6241    index = index || 0
6242
6243    for (var i = index || 0; i < list.length; i++) {
6244        array[i - index] = list[i]
6245    }
6246
6247    return array
6248}
6249
6250},{}]},{},[1])
6251(1)
6252});