Guest User

seligustestseligussssss

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