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