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