Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / socket.io-client / dist / socket.io.js
1 /*! Socket.IO.js build:0.9.16, development. Copyright(c) 2011 LearnBoost <dev@learnboost.com> MIT Licensed */
2
3 var io = ('undefined' === typeof module ? {} : module.exports);
4 (function() {
5
6 /**
7  * socket.io
8  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
9  * MIT Licensed
10  */
11
12 (function (exports, global) {
13
14   /**
15    * IO namespace.
16    *
17    * @namespace
18    */
19
20   var io = exports;
21
22   /**
23    * Socket.IO version
24    *
25    * @api public
26    */
27
28   io.version = '0.9.16';
29
30   /**
31    * Protocol implemented.
32    *
33    * @api public
34    */
35
36   io.protocol = 1;
37
38   /**
39    * Available transports, these will be populated with the available transports
40    *
41    * @api public
42    */
43
44   io.transports = [];
45
46   /**
47    * Keep track of jsonp callbacks.
48    *
49    * @api private
50    */
51
52   io.j = [];
53
54   /**
55    * Keep track of our io.Sockets
56    *
57    * @api private
58    */
59   io.sockets = {};
60
61
62   /**
63    * Manages connections to hosts.
64    *
65    * @param {String} uri
66    * @Param {Boolean} force creation of new socket (defaults to false)
67    * @api public
68    */
69
70   io.connect = function (host, details) {
71     var uri = io.util.parseUri(host)
72       , uuri
73       , socket;
74
75     if (global && global.location) {
76       uri.protocol = uri.protocol || global.location.protocol.slice(0, -1);
77       uri.host = uri.host || (global.document
78         ? global.document.domain : global.location.hostname);
79       uri.port = uri.port || global.location.port;
80     }
81
82     uuri = io.util.uniqueUri(uri);
83
84     var options = {
85         host: uri.host
86       , secure: 'https' == uri.protocol
87       , port: uri.port || ('https' == uri.protocol ? 443 : 80)
88       , query: uri.query || ''
89     };
90
91     io.util.merge(options, details);
92
93     if (options['force new connection'] || !io.sockets[uuri]) {
94       socket = new io.Socket(options);
95     }
96
97     if (!options['force new connection'] && socket) {
98       io.sockets[uuri] = socket;
99     }
100
101     socket = socket || io.sockets[uuri];
102
103     // if path is different from '' or /
104     return socket.of(uri.path.length > 1 ? uri.path : '');
105   };
106
107 })('object' === typeof module ? module.exports : (this.io = {}), this);
108 /**
109  * socket.io
110  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
111  * MIT Licensed
112  */
113
114 (function (exports, global) {
115
116   /**
117    * Utilities namespace.
118    *
119    * @namespace
120    */
121
122   var util = exports.util = {};
123
124   /**
125    * Parses an URI
126    *
127    * @author Steven Levithan <stevenlevithan.com> (MIT license)
128    * @api public
129    */
130
131   var re = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
132
133   var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password',
134                'host', 'port', 'relative', 'path', 'directory', 'file', 'query',
135                'anchor'];
136
137   util.parseUri = function (str) {
138     var m = re.exec(str || '')
139       , uri = {}
140       , i = 14;
141
142     while (i--) {
143       uri[parts[i]] = m[i] || '';
144     }
145
146     return uri;
147   };
148
149   /**
150    * Produces a unique url that identifies a Socket.IO connection.
151    *
152    * @param {Object} uri
153    * @api public
154    */
155
156   util.uniqueUri = function (uri) {
157     var protocol = uri.protocol
158       , host = uri.host
159       , port = uri.port;
160
161     if ('document' in global) {
162       host = host || document.domain;
163       port = port || (protocol == 'https'
164         && document.location.protocol !== 'https:' ? 443 : document.location.port);
165     } else {
166       host = host || 'localhost';
167
168       if (!port && protocol == 'https') {
169         port = 443;
170       }
171     }
172
173     return (protocol || 'http') + '://' + host + ':' + (port || 80);
174   };
175
176   /**
177    * Mergest 2 query strings in to once unique query string
178    *
179    * @param {String} base
180    * @param {String} addition
181    * @api public
182    */
183
184   util.query = function (base, addition) {
185     var query = util.chunkQuery(base || '')
186       , components = [];
187
188     util.merge(query, util.chunkQuery(addition || ''));
189     for (var part in query) {
190       if (query.hasOwnProperty(part)) {
191         components.push(part + '=' + query[part]);
192       }
193     }
194
195     return components.length ? '?' + components.join('&') : '';
196   };
197
198   /**
199    * Transforms a querystring in to an object
200    *
201    * @param {String} qs
202    * @api public
203    */
204
205   util.chunkQuery = function (qs) {
206     var query = {}
207       , params = qs.split('&')
208       , i = 0
209       , l = params.length
210       , kv;
211
212     for (; i < l; ++i) {
213       kv = params[i].split('=');
214       if (kv[0]) {
215         query[kv[0]] = kv[1];
216       }
217     }
218
219     return query;
220   };
221
222   /**
223    * Executes the given function when the page is loaded.
224    *
225    *     io.util.load(function () { console.log('page loaded'); });
226    *
227    * @param {Function} fn
228    * @api public
229    */
230
231   var pageLoaded = false;
232
233   util.load = function (fn) {
234     if ('document' in global && document.readyState === 'complete' || pageLoaded) {
235       return fn();
236     }
237
238     util.on(global, 'load', fn, false);
239   };
240
241   /**
242    * Adds an event.
243    *
244    * @api private
245    */
246
247   util.on = function (element, event, fn, capture) {
248     if (element.attachEvent) {
249       element.attachEvent('on' + event, fn);
250     } else if (element.addEventListener) {
251       element.addEventListener(event, fn, capture);
252     }
253   };
254
255   /**
256    * Generates the correct `XMLHttpRequest` for regular and cross domain requests.
257    *
258    * @param {Boolean} [xdomain] Create a request that can be used cross domain.
259    * @returns {XMLHttpRequest|false} If we can create a XMLHttpRequest.
260    * @api private
261    */
262
263   util.request = function (xdomain) {
264
265     if (xdomain && 'undefined' != typeof XDomainRequest && !util.ua.hasCORS) {
266       return new XDomainRequest();
267     }
268
269     if ('undefined' != typeof XMLHttpRequest && (!xdomain || util.ua.hasCORS)) {
270       return new XMLHttpRequest();
271     }
272
273     if (!xdomain) {
274       try {
275         return new window[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP');
276       } catch(e) { }
277     }
278
279     return null;
280   };
281
282   /**
283    * XHR based transport constructor.
284    *
285    * @constructor
286    * @api public
287    */
288
289   /**
290    * Change the internal pageLoaded value.
291    */
292
293   if ('undefined' != typeof window) {
294     util.load(function () {
295       pageLoaded = true;
296     });
297   }
298
299   /**
300    * Defers a function to ensure a spinner is not displayed by the browser
301    *
302    * @param {Function} fn
303    * @api public
304    */
305
306   util.defer = function (fn) {
307     if (!util.ua.webkit || 'undefined' != typeof importScripts) {
308       return fn();
309     }
310
311     util.load(function () {
312       setTimeout(fn, 100);
313     });
314   };
315
316   /**
317    * Merges two objects.
318    *
319    * @api public
320    */
321
322   util.merge = function merge (target, additional, deep, lastseen) {
323     var seen = lastseen || []
324       , depth = typeof deep == 'undefined' ? 2 : deep
325       , prop;
326
327     for (prop in additional) {
328       if (additional.hasOwnProperty(prop) && util.indexOf(seen, prop) < 0) {
329         if (typeof target[prop] !== 'object' || !depth) {
330           target[prop] = additional[prop];
331           seen.push(additional[prop]);
332         } else {
333           util.merge(target[prop], additional[prop], depth - 1, seen);
334         }
335       }
336     }
337
338     return target;
339   };
340
341   /**
342    * Merges prototypes from objects
343    *
344    * @api public
345    */
346
347   util.mixin = function (ctor, ctor2) {
348     util.merge(ctor.prototype, ctor2.prototype);
349   };
350
351   /**
352    * Shortcut for prototypical and static inheritance.
353    *
354    * @api private
355    */
356
357   util.inherit = function (ctor, ctor2) {
358     function f() {};
359     f.prototype = ctor2.prototype;
360     ctor.prototype = new f;
361   };
362
363   /**
364    * Checks if the given object is an Array.
365    *
366    *     io.util.isArray([]); // true
367    *     io.util.isArray({}); // false
368    *
369    * @param Object obj
370    * @api public
371    */
372
373   util.isArray = Array.isArray || function (obj) {
374     return Object.prototype.toString.call(obj) === '[object Array]';
375   };
376
377   /**
378    * Intersects values of two arrays into a third
379    *
380    * @api public
381    */
382
383   util.intersect = function (arr, arr2) {
384     var ret = []
385       , longest = arr.length > arr2.length ? arr : arr2
386       , shortest = arr.length > arr2.length ? arr2 : arr;
387
388     for (var i = 0, l = shortest.length; i < l; i++) {
389       if (~util.indexOf(longest, shortest[i]))
390         ret.push(shortest[i]);
391     }
392
393     return ret;
394   };
395
396   /**
397    * Array indexOf compatibility.
398    *
399    * @see bit.ly/a5Dxa2
400    * @api public
401    */
402
403   util.indexOf = function (arr, o, i) {
404
405     for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0;
406          i < j && arr[i] !== o; i++) {}
407
408     return j <= i ? -1 : i;
409   };
410
411   /**
412    * Converts enumerables to array.
413    *
414    * @api public
415    */
416
417   util.toArray = function (enu) {
418     var arr = [];
419
420     for (var i = 0, l = enu.length; i < l; i++)
421       arr.push(enu[i]);
422
423     return arr;
424   };
425
426   /**
427    * UA / engines detection namespace.
428    *
429    * @namespace
430    */
431
432   util.ua = {};
433
434   /**
435    * Whether the UA supports CORS for XHR.
436    *
437    * @api public
438    */
439
440   util.ua.hasCORS = 'undefined' != typeof XMLHttpRequest && (function () {
441     try {
442       var a = new XMLHttpRequest();
443     } catch (e) {
444       return false;
445     }
446
447     return a.withCredentials != undefined;
448   })();
449
450   /**
451    * Detect webkit.
452    *
453    * @api public
454    */
455
456   util.ua.webkit = 'undefined' != typeof navigator
457     && /webkit/i.test(navigator.userAgent);
458
459    /**
460    * Detect iPad/iPhone/iPod.
461    *
462    * @api public
463    */
464
465   util.ua.iDevice = 'undefined' != typeof navigator
466       && /iPad|iPhone|iPod/i.test(navigator.userAgent);
467
468 })('undefined' != typeof io ? io : module.exports, this);
469 /**
470  * socket.io
471  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
472  * MIT Licensed
473  */
474
475 (function (exports, io) {
476
477   /**
478    * Expose constructor.
479    */
480
481   exports.EventEmitter = EventEmitter;
482
483   /**
484    * Event emitter constructor.
485    *
486    * @api public.
487    */
488
489   function EventEmitter () {};
490
491   /**
492    * Adds a listener
493    *
494    * @api public
495    */
496
497   EventEmitter.prototype.on = function (name, fn) {
498     if (!this.$events) {
499       this.$events = {};
500     }
501
502     if (!this.$events[name]) {
503       this.$events[name] = fn;
504     } else if (io.util.isArray(this.$events[name])) {
505       this.$events[name].push(fn);
506     } else {
507       this.$events[name] = [this.$events[name], fn];
508     }
509
510     return this;
511   };
512
513   EventEmitter.prototype.addListener = EventEmitter.prototype.on;
514
515   /**
516    * Adds a volatile listener.
517    *
518    * @api public
519    */
520
521   EventEmitter.prototype.once = function (name, fn) {
522     var self = this;
523
524     function on () {
525       self.removeListener(name, on);
526       fn.apply(this, arguments);
527     };
528
529     on.listener = fn;
530     this.on(name, on);
531
532     return this;
533   };
534
535   /**
536    * Removes a listener.
537    *
538    * @api public
539    */
540
541   EventEmitter.prototype.removeListener = function (name, fn) {
542     if (this.$events && this.$events[name]) {
543       var list = this.$events[name];
544
545       if (io.util.isArray(list)) {
546         var pos = -1;
547
548         for (var i = 0, l = list.length; i < l; i++) {
549           if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
550             pos = i;
551             break;
552           }
553         }
554
555         if (pos < 0) {
556           return this;
557         }
558
559         list.splice(pos, 1);
560
561         if (!list.length) {
562           delete this.$events[name];
563         }
564       } else if (list === fn || (list.listener && list.listener === fn)) {
565         delete this.$events[name];
566       }
567     }
568
569     return this;
570   };
571
572   /**
573    * Removes all listeners for an event.
574    *
575    * @api public
576    */
577
578   EventEmitter.prototype.removeAllListeners = function (name) {
579     if (name === undefined) {
580       this.$events = {};
581       return this;
582     }
583
584     if (this.$events && this.$events[name]) {
585       this.$events[name] = null;
586     }
587
588     return this;
589   };
590
591   /**
592    * Gets all listeners for a certain event.
593    *
594    * @api publci
595    */
596
597   EventEmitter.prototype.listeners = function (name) {
598     if (!this.$events) {
599       this.$events = {};
600     }
601
602     if (!this.$events[name]) {
603       this.$events[name] = [];
604     }
605
606     if (!io.util.isArray(this.$events[name])) {
607       this.$events[name] = [this.$events[name]];
608     }
609
610     return this.$events[name];
611   };
612
613   /**
614    * Emits an event.
615    *
616    * @api public
617    */
618
619   EventEmitter.prototype.emit = function (name) {
620     if (!this.$events) {
621       return false;
622     }
623
624     var handler = this.$events[name];
625
626     if (!handler) {
627       return false;
628     }
629
630     var args = Array.prototype.slice.call(arguments, 1);
631
632     if ('function' == typeof handler) {
633       handler.apply(this, args);
634     } else if (io.util.isArray(handler)) {
635       var listeners = handler.slice();
636
637       for (var i = 0, l = listeners.length; i < l; i++) {
638         listeners[i].apply(this, args);
639       }
640     } else {
641       return false;
642     }
643
644     return true;
645   };
646
647 })(
648     'undefined' != typeof io ? io : module.exports
649   , 'undefined' != typeof io ? io : module.parent.exports
650 );
651
652 /**
653  * socket.io
654  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
655  * MIT Licensed
656  */
657
658 /**
659  * Based on JSON2 (http://www.JSON.org/js.html).
660  */
661
662 (function (exports, nativeJSON) {
663   "use strict";
664
665   // use native JSON if it's available
666   if (nativeJSON && nativeJSON.parse){
667     return exports.JSON = {
668       parse: nativeJSON.parse
669     , stringify: nativeJSON.stringify
670     };
671   }
672
673   var JSON = exports.JSON = {};
674
675   function f(n) {
676       // Format integers to have at least two digits.
677       return n < 10 ? '0' + n : n;
678   }
679
680   function date(d, key) {
681     return isFinite(d.valueOf()) ?
682         d.getUTCFullYear()     + '-' +
683         f(d.getUTCMonth() + 1) + '-' +
684         f(d.getUTCDate())      + 'T' +
685         f(d.getUTCHours())     + ':' +
686         f(d.getUTCMinutes())   + ':' +
687         f(d.getUTCSeconds())   + 'Z' : null;
688   };
689
690   var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
691       escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
692       gap,
693       indent,
694       meta = {    // table of character substitutions
695           '\b': '\\b',
696           '\t': '\\t',
697           '\n': '\\n',
698           '\f': '\\f',
699           '\r': '\\r',
700           '"' : '\\"',
701           '\\': '\\\\'
702       },
703       rep;
704
705
706   function quote(string) {
707
708 // If the string contains no control characters, no quote characters, and no
709 // backslash characters, then we can safely slap some quotes around it.
710 // Otherwise we must also replace the offending characters with safe escape
711 // sequences.
712
713       escapable.lastIndex = 0;
714       return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
715           var c = meta[a];
716           return typeof c === 'string' ? c :
717               '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
718       }) + '"' : '"' + string + '"';
719   }
720
721
722   function str(key, holder) {
723
724 // Produce a string from holder[key].
725
726       var i,          // The loop counter.
727           k,          // The member key.
728           v,          // The member value.
729           length,
730           mind = gap,
731           partial,
732           value = holder[key];
733
734 // If the value has a toJSON method, call it to obtain a replacement value.
735
736       if (value instanceof Date) {
737           value = date(key);
738       }
739
740 // If we were called with a replacer function, then call the replacer to
741 // obtain a replacement value.
742
743       if (typeof rep === 'function') {
744           value = rep.call(holder, key, value);
745       }
746
747 // What happens next depends on the value's type.
748
749       switch (typeof value) {
750       case 'string':
751           return quote(value);
752
753       case 'number':
754
755 // JSON numbers must be finite. Encode non-finite numbers as null.
756
757           return isFinite(value) ? String(value) : 'null';
758
759       case 'boolean':
760       case 'null':
761
762 // If the value is a boolean or null, convert it to a string. Note:
763 // typeof null does not produce 'null'. The case is included here in
764 // the remote chance that this gets fixed someday.
765
766           return String(value);
767
768 // If the type is 'object', we might be dealing with an object or an array or
769 // null.
770
771       case 'object':
772
773 // Due to a specification blunder in ECMAScript, typeof null is 'object',
774 // so watch out for that case.
775
776           if (!value) {
777               return 'null';
778           }
779
780 // Make an array to hold the partial results of stringifying this object value.
781
782           gap += indent;
783           partial = [];
784
785 // Is the value an array?
786
787           if (Object.prototype.toString.apply(value) === '[object Array]') {
788
789 // The value is an array. Stringify every element. Use null as a placeholder
790 // for non-JSON values.
791
792               length = value.length;
793               for (i = 0; i < length; i += 1) {
794                   partial[i] = str(i, value) || 'null';
795               }
796
797 // Join all of the elements together, separated with commas, and wrap them in
798 // brackets.
799
800               v = partial.length === 0 ? '[]' : gap ?
801                   '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
802                   '[' + partial.join(',') + ']';
803               gap = mind;
804               return v;
805           }
806
807 // If the replacer is an array, use it to select the members to be stringified.
808
809           if (rep && typeof rep === 'object') {
810               length = rep.length;
811               for (i = 0; i < length; i += 1) {
812                   if (typeof rep[i] === 'string') {
813                       k = rep[i];
814                       v = str(k, value);
815                       if (v) {
816                           partial.push(quote(k) + (gap ? ': ' : ':') + v);
817                       }
818                   }
819               }
820           } else {
821
822 // Otherwise, iterate through all of the keys in the object.
823
824               for (k in value) {
825                   if (Object.prototype.hasOwnProperty.call(value, k)) {
826                       v = str(k, value);
827                       if (v) {
828                           partial.push(quote(k) + (gap ? ': ' : ':') + v);
829                       }
830                   }
831               }
832           }
833
834 // Join all of the member texts together, separated with commas,
835 // and wrap them in braces.
836
837           v = partial.length === 0 ? '{}' : gap ?
838               '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
839               '{' + partial.join(',') + '}';
840           gap = mind;
841           return v;
842       }
843   }
844
845 // If the JSON object does not yet have a stringify method, give it one.
846
847   JSON.stringify = function (value, replacer, space) {
848
849 // The stringify method takes a value and an optional replacer, and an optional
850 // space parameter, and returns a JSON text. The replacer can be a function
851 // that can replace values, or an array of strings that will select the keys.
852 // A default replacer method can be provided. Use of the space parameter can
853 // produce text that is more easily readable.
854
855       var i;
856       gap = '';
857       indent = '';
858
859 // If the space parameter is a number, make an indent string containing that
860 // many spaces.
861
862       if (typeof space === 'number') {
863           for (i = 0; i < space; i += 1) {
864               indent += ' ';
865           }
866
867 // If the space parameter is a string, it will be used as the indent string.
868
869       } else if (typeof space === 'string') {
870           indent = space;
871       }
872
873 // If there is a replacer, it must be a function or an array.
874 // Otherwise, throw an error.
875
876       rep = replacer;
877       if (replacer && typeof replacer !== 'function' &&
878               (typeof replacer !== 'object' ||
879               typeof replacer.length !== 'number')) {
880           throw new Error('JSON.stringify');
881       }
882
883 // Make a fake root object containing our value under the key of ''.
884 // Return the result of stringifying the value.
885
886       return str('', {'': value});
887   };
888
889 // If the JSON object does not yet have a parse method, give it one.
890
891   JSON.parse = function (text, reviver) {
892   // The parse method takes a text and an optional reviver function, and returns
893   // a JavaScript value if the text is a valid JSON text.
894
895       var j;
896
897       function walk(holder, key) {
898
899   // The walk method is used to recursively walk the resulting structure so
900   // that modifications can be made.
901
902           var k, v, value = holder[key];
903           if (value && typeof value === 'object') {
904               for (k in value) {
905                   if (Object.prototype.hasOwnProperty.call(value, k)) {
906                       v = walk(value, k);
907                       if (v !== undefined) {
908                           value[k] = v;
909                       } else {
910                           delete value[k];
911                       }
912                   }
913               }
914           }
915           return reviver.call(holder, key, value);
916       }
917
918
919   // Parsing happens in four stages. In the first stage, we replace certain
920   // Unicode characters with escape sequences. JavaScript handles many characters
921   // incorrectly, either silently deleting them, or treating them as line endings.
922
923       text = String(text);
924       cx.lastIndex = 0;
925       if (cx.test(text)) {
926           text = text.replace(cx, function (a) {
927               return '\\u' +
928                   ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
929           });
930       }
931
932   // In the second stage, we run the text against regular expressions that look
933   // for non-JSON patterns. We are especially concerned with '()' and 'new'
934   // because they can cause invocation, and '=' because it can cause mutation.
935   // But just to be safe, we want to reject all unexpected forms.
936
937   // We split the second stage into 4 regexp operations in order to work around
938   // crippling inefficiencies in IE's and Safari's regexp engines. First we
939   // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
940   // replace all simple value tokens with ']' characters. Third, we delete all
941   // open brackets that follow a colon or comma or that begin the text. Finally,
942   // we look to see that the remaining characters are only whitespace or ']' or
943   // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
944
945       if (/^[\],:{}\s]*$/
946               .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
947                   .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
948                   .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
949
950   // In the third stage we use the eval function to compile the text into a
951   // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
952   // in JavaScript: it can begin a block or an object literal. We wrap the text
953   // in parens to eliminate the ambiguity.
954
955           j = eval('(' + text + ')');
956
957   // In the optional fourth stage, we recursively walk the new structure, passing
958   // each name/value pair to a reviver function for possible transformation.
959
960           return typeof reviver === 'function' ?
961               walk({'': j}, '') : j;
962       }
963
964   // If the text is not JSON parseable, then a SyntaxError is thrown.
965
966       throw new SyntaxError('JSON.parse');
967   };
968
969 })(
970     'undefined' != typeof io ? io : module.exports
971   , typeof JSON !== 'undefined' ? JSON : undefined
972 );
973
974 /**
975  * socket.io
976  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
977  * MIT Licensed
978  */
979
980 (function (exports, io) {
981
982   /**
983    * Parser namespace.
984    *
985    * @namespace
986    */
987
988   var parser = exports.parser = {};
989
990   /**
991    * Packet types.
992    */
993
994   var packets = parser.packets = [
995       'disconnect'
996     , 'connect'
997     , 'heartbeat'
998     , 'message'
999     , 'json'
1000     , 'event'
1001     , 'ack'
1002     , 'error'
1003     , 'noop'
1004   ];
1005
1006   /**
1007    * Errors reasons.
1008    */
1009
1010   var reasons = parser.reasons = [
1011       'transport not supported'
1012     , 'client not handshaken'
1013     , 'unauthorized'
1014   ];
1015
1016   /**
1017    * Errors advice.
1018    */
1019
1020   var advice = parser.advice = [
1021       'reconnect'
1022   ];
1023
1024   /**
1025    * Shortcuts.
1026    */
1027
1028   var JSON = io.JSON
1029     , indexOf = io.util.indexOf;
1030
1031   /**
1032    * Encodes a packet.
1033    *
1034    * @api private
1035    */
1036
1037   parser.encodePacket = function (packet) {
1038     var type = indexOf(packets, packet.type)
1039       , id = packet.id || ''
1040       , endpoint = packet.endpoint || ''
1041       , ack = packet.ack
1042       , data = null;
1043
1044     switch (packet.type) {
1045       case 'error':
1046         var reason = packet.reason ? indexOf(reasons, packet.reason) : ''
1047           , adv = packet.advice ? indexOf(advice, packet.advice) : '';
1048
1049         if (reason !== '' || adv !== '')
1050           data = reason + (adv !== '' ? ('+' + adv) : '');
1051
1052         break;
1053
1054       case 'message':
1055         if (packet.data !== '')
1056           data = packet.data;
1057         break;
1058
1059       case 'event':
1060         var ev = { name: packet.name };
1061
1062         if (packet.args && packet.args.length) {
1063           ev.args = packet.args;
1064         }
1065
1066         data = JSON.stringify(ev);
1067         break;
1068
1069       case 'json':
1070         data = JSON.stringify(packet.data);
1071         break;
1072
1073       case 'connect':
1074         if (packet.qs)
1075           data = packet.qs;
1076         break;
1077
1078       case 'ack':
1079         data = packet.ackId
1080           + (packet.args && packet.args.length
1081               ? '+' + JSON.stringify(packet.args) : '');
1082         break;
1083     }
1084
1085     // construct packet with required fragments
1086     var encoded = [
1087         type
1088       , id + (ack == 'data' ? '+' : '')
1089       , endpoint
1090     ];
1091
1092     // data fragment is optional
1093     if (data !== null && data !== undefined)
1094       encoded.push(data);
1095
1096     return encoded.join(':');
1097   };
1098
1099   /**
1100    * Encodes multiple messages (payload).
1101    *
1102    * @param {Array} messages
1103    * @api private
1104    */
1105
1106   parser.encodePayload = function (packets) {
1107     var decoded = '';
1108
1109     if (packets.length == 1)
1110       return packets[0];
1111
1112     for (var i = 0, l = packets.length; i < l; i++) {
1113       var packet = packets[i];
1114       decoded += '\ufffd' + packet.length + '\ufffd' + packets[i];
1115     }
1116
1117     return decoded;
1118   };
1119
1120   /**
1121    * Decodes a packet
1122    *
1123    * @api private
1124    */
1125
1126   var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/;
1127
1128   parser.decodePacket = function (data) {
1129     var pieces = data.match(regexp);
1130
1131     if (!pieces) return {};
1132
1133     var id = pieces[2] || ''
1134       , data = pieces[5] || ''
1135       , packet = {
1136             type: packets[pieces[1]]
1137           , endpoint: pieces[4] || ''
1138         };
1139
1140     // whether we need to acknowledge the packet
1141     if (id) {
1142       packet.id = id;
1143       if (pieces[3])
1144         packet.ack = 'data';
1145       else
1146         packet.ack = true;
1147     }
1148
1149     // handle different packet types
1150     switch (packet.type) {
1151       case 'error':
1152         var pieces = data.split('+');
1153         packet.reason = reasons[pieces[0]] || '';
1154         packet.advice = advice[pieces[1]] || '';
1155         break;
1156
1157       case 'message':
1158         packet.data = data || '';
1159         break;
1160
1161       case 'event':
1162         try {
1163           var opts = JSON.parse(data);
1164           packet.name = opts.name;
1165           packet.args = opts.args;
1166         } catch (e) { }
1167
1168         packet.args = packet.args || [];
1169         break;
1170
1171       case 'json':
1172         try {
1173           packet.data = JSON.parse(data);
1174         } catch (e) { }
1175         break;
1176
1177       case 'connect':
1178         packet.qs = data || '';
1179         break;
1180
1181       case 'ack':
1182         var pieces = data.match(/^([0-9]+)(\+)?(.*)/);
1183         if (pieces) {
1184           packet.ackId = pieces[1];
1185           packet.args = [];
1186
1187           if (pieces[3]) {
1188             try {
1189               packet.args = pieces[3] ? JSON.parse(pieces[3]) : [];
1190             } catch (e) { }
1191           }
1192         }
1193         break;
1194
1195       case 'disconnect':
1196       case 'heartbeat':
1197         break;
1198     };
1199
1200     return packet;
1201   };
1202
1203   /**
1204    * Decodes data payload. Detects multiple messages
1205    *
1206    * @return {Array} messages
1207    * @api public
1208    */
1209
1210   parser.decodePayload = function (data) {
1211     // IE doesn't like data[i] for unicode chars, charAt works fine
1212     if (data.charAt(0) == '\ufffd') {
1213       var ret = [];
1214
1215       for (var i = 1, length = ''; i < data.length; i++) {
1216         if (data.charAt(i) == '\ufffd') {
1217           ret.push(parser.decodePacket(data.substr(i + 1).substr(0, length)));
1218           i += Number(length) + 1;
1219           length = '';
1220         } else {
1221           length += data.charAt(i);
1222         }
1223       }
1224
1225       return ret;
1226     } else {
1227       return [parser.decodePacket(data)];
1228     }
1229   };
1230
1231 })(
1232     'undefined' != typeof io ? io : module.exports
1233   , 'undefined' != typeof io ? io : module.parent.exports
1234 );
1235 /**
1236  * socket.io
1237  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
1238  * MIT Licensed
1239  */
1240
1241 (function (exports, io) {
1242
1243   /**
1244    * Expose constructor.
1245    */
1246
1247   exports.Transport = Transport;
1248
1249   /**
1250    * This is the transport template for all supported transport methods.
1251    *
1252    * @constructor
1253    * @api public
1254    */
1255
1256   function Transport (socket, sessid) {
1257     this.socket = socket;
1258     this.sessid = sessid;
1259   };
1260
1261   /**
1262    * Apply EventEmitter mixin.
1263    */
1264
1265   io.util.mixin(Transport, io.EventEmitter);
1266
1267
1268   /**
1269    * Indicates whether heartbeats is enabled for this transport
1270    *
1271    * @api private
1272    */
1273
1274   Transport.prototype.heartbeats = function () {
1275     return true;
1276   };
1277
1278   /**
1279    * Handles the response from the server. When a new response is received
1280    * it will automatically update the timeout, decode the message and
1281    * forwards the response to the onMessage function for further processing.
1282    *
1283    * @param {String} data Response from the server.
1284    * @api private
1285    */
1286
1287   Transport.prototype.onData = function (data) {
1288     this.clearCloseTimeout();
1289
1290     // If the connection in currently open (or in a reopening state) reset the close
1291     // timeout since we have just received data. This check is necessary so
1292     // that we don't reset the timeout on an explicitly disconnected connection.
1293     if (this.socket.connected || this.socket.connecting || this.socket.reconnecting) {
1294       this.setCloseTimeout();
1295     }
1296
1297     if (data !== '') {
1298       // todo: we should only do decodePayload for xhr transports
1299       var msgs = io.parser.decodePayload(data);
1300
1301       if (msgs && msgs.length) {
1302         for (var i = 0, l = msgs.length; i < l; i++) {
1303           this.onPacket(msgs[i]);
1304         }
1305       }
1306     }
1307
1308     return this;
1309   };
1310
1311   /**
1312    * Handles packets.
1313    *
1314    * @api private
1315    */
1316
1317   Transport.prototype.onPacket = function (packet) {
1318     this.socket.setHeartbeatTimeout();
1319
1320     if (packet.type == 'heartbeat') {
1321       return this.onHeartbeat();
1322     }
1323
1324     if (packet.type == 'connect' && packet.endpoint == '') {
1325       this.onConnect();
1326     }
1327
1328     if (packet.type == 'error' && packet.advice == 'reconnect') {
1329       this.isOpen = false;
1330     }
1331
1332     this.socket.onPacket(packet);
1333
1334     return this;
1335   };
1336
1337   /**
1338    * Sets close timeout
1339    *
1340    * @api private
1341    */
1342
1343   Transport.prototype.setCloseTimeout = function () {
1344     if (!this.closeTimeout) {
1345       var self = this;
1346
1347       this.closeTimeout = setTimeout(function () {
1348         self.onDisconnect();
1349       }, this.socket.closeTimeout);
1350     }
1351   };
1352
1353   /**
1354    * Called when transport disconnects.
1355    *
1356    * @api private
1357    */
1358
1359   Transport.prototype.onDisconnect = function () {
1360     if (this.isOpen) this.close();
1361     this.clearTimeouts();
1362     this.socket.onDisconnect();
1363     return this;
1364   };
1365
1366   /**
1367    * Called when transport connects
1368    *
1369    * @api private
1370    */
1371
1372   Transport.prototype.onConnect = function () {
1373     this.socket.onConnect();
1374     return this;
1375   };
1376
1377   /**
1378    * Clears close timeout
1379    *
1380    * @api private
1381    */
1382
1383   Transport.prototype.clearCloseTimeout = function () {
1384     if (this.closeTimeout) {
1385       clearTimeout(this.closeTimeout);
1386       this.closeTimeout = null;
1387     }
1388   };
1389
1390   /**
1391    * Clear timeouts
1392    *
1393    * @api private
1394    */
1395
1396   Transport.prototype.clearTimeouts = function () {
1397     this.clearCloseTimeout();
1398
1399     if (this.reopenTimeout) {
1400       clearTimeout(this.reopenTimeout);
1401     }
1402   };
1403
1404   /**
1405    * Sends a packet
1406    *
1407    * @param {Object} packet object.
1408    * @api private
1409    */
1410
1411   Transport.prototype.packet = function (packet) {
1412     this.send(io.parser.encodePacket(packet));
1413   };
1414
1415   /**
1416    * Send the received heartbeat message back to server. So the server
1417    * knows we are still connected.
1418    *
1419    * @param {String} heartbeat Heartbeat response from the server.
1420    * @api private
1421    */
1422
1423   Transport.prototype.onHeartbeat = function (heartbeat) {
1424     this.packet({ type: 'heartbeat' });
1425   };
1426
1427   /**
1428    * Called when the transport opens.
1429    *
1430    * @api private
1431    */
1432
1433   Transport.prototype.onOpen = function () {
1434     this.isOpen = true;
1435     this.clearCloseTimeout();
1436     this.socket.onOpen();
1437   };
1438
1439   /**
1440    * Notifies the base when the connection with the Socket.IO server
1441    * has been disconnected.
1442    *
1443    * @api private
1444    */
1445
1446   Transport.prototype.onClose = function () {
1447     var self = this;
1448
1449     /* FIXME: reopen delay causing a infinit loop
1450     this.reopenTimeout = setTimeout(function () {
1451       self.open();
1452     }, this.socket.options['reopen delay']);*/
1453
1454     this.isOpen = false;
1455     this.socket.onClose();
1456     this.onDisconnect();
1457   };
1458
1459   /**
1460    * Generates a connection url based on the Socket.IO URL Protocol.
1461    * See <https://github.com/learnboost/socket.io-node/> for more details.
1462    *
1463    * @returns {String} Connection url
1464    * @api private
1465    */
1466
1467   Transport.prototype.prepareUrl = function () {
1468     var options = this.socket.options;
1469
1470     return this.scheme() + '://'
1471       + options.host + ':' + options.port + '/'
1472       + options.resource + '/' + io.protocol
1473       + '/' + this.name + '/' + this.sessid;
1474   };
1475
1476   /**
1477    * Checks if the transport is ready to start a connection.
1478    *
1479    * @param {Socket} socket The socket instance that needs a transport
1480    * @param {Function} fn The callback
1481    * @api private
1482    */
1483
1484   Transport.prototype.ready = function (socket, fn) {
1485     fn.call(this);
1486   };
1487 })(
1488     'undefined' != typeof io ? io : module.exports
1489   , 'undefined' != typeof io ? io : module.parent.exports
1490 );
1491 /**
1492  * socket.io
1493  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
1494  * MIT Licensed
1495  */
1496
1497 (function (exports, io, global) {
1498
1499   /**
1500    * Expose constructor.
1501    */
1502
1503   exports.Socket = Socket;
1504
1505   /**
1506    * Create a new `Socket.IO client` which can establish a persistent
1507    * connection with a Socket.IO enabled server.
1508    *
1509    * @api public
1510    */
1511
1512   function Socket (options) {
1513     this.options = {
1514         port: 80
1515       , secure: false
1516       , document: 'document' in global ? document : false
1517       , resource: 'socket.io'
1518       , transports: io.transports
1519       , 'connect timeout': 10000
1520       , 'try multiple transports': true
1521       , 'reconnect': true
1522       , 'reconnection delay': 500
1523       , 'reconnection limit': Infinity
1524       , 'reopen delay': 3000
1525       , 'max reconnection attempts': 10
1526       , 'sync disconnect on unload': false
1527       , 'auto connect': true
1528       , 'flash policy port': 10843
1529       , 'manualFlush': false
1530     };
1531
1532     io.util.merge(this.options, options);
1533
1534     this.connected = false;
1535     this.open = false;
1536     this.connecting = false;
1537     this.reconnecting = false;
1538     this.namespaces = {};
1539     this.buffer = [];
1540     this.doBuffer = false;
1541
1542     if (this.options['sync disconnect on unload'] &&
1543         (!this.isXDomain() || io.util.ua.hasCORS)) {
1544       var self = this;
1545       io.util.on(global, 'beforeunload', function () {
1546         self.disconnectSync();
1547       }, false);
1548     }
1549
1550     if (this.options['auto connect']) {
1551       this.connect();
1552     }
1553 };
1554
1555   /**
1556    * Apply EventEmitter mixin.
1557    */
1558
1559   io.util.mixin(Socket, io.EventEmitter);
1560
1561   /**
1562    * Returns a namespace listener/emitter for this socket
1563    *
1564    * @api public
1565    */
1566
1567   Socket.prototype.of = function (name) {
1568     if (!this.namespaces[name]) {
1569       this.namespaces[name] = new io.SocketNamespace(this, name);
1570
1571       if (name !== '') {
1572         this.namespaces[name].packet({ type: 'connect' });
1573       }
1574     }
1575
1576     return this.namespaces[name];
1577   };
1578
1579   /**
1580    * Emits the given event to the Socket and all namespaces
1581    *
1582    * @api private
1583    */
1584
1585   Socket.prototype.publish = function () {
1586     this.emit.apply(this, arguments);
1587
1588     var nsp;
1589
1590     for (var i in this.namespaces) {
1591       if (this.namespaces.hasOwnProperty(i)) {
1592         nsp = this.of(i);
1593         nsp.$emit.apply(nsp, arguments);
1594       }
1595     }
1596   };
1597
1598   /**
1599    * Performs the handshake
1600    *
1601    * @api private
1602    */
1603
1604   function empty () { };
1605
1606   Socket.prototype.handshake = function (fn) {
1607     var self = this
1608       , options = this.options;
1609
1610     function complete (data) {
1611       if (data instanceof Error) {
1612         self.connecting = false;
1613         self.onError(data.message);
1614       } else {
1615         fn.apply(null, data.split(':'));
1616       }
1617     };
1618
1619     var url = [
1620           'http' + (options.secure ? 's' : '') + ':/'
1621         , options.host + ':' + options.port
1622         , options.resource
1623         , io.protocol
1624         , io.util.query(this.options.query, 't=' + +new Date)
1625       ].join('/');
1626
1627     if (this.isXDomain() && !io.util.ua.hasCORS) {
1628       var insertAt = document.getElementsByTagName('script')[0]
1629         , script = document.createElement('script');
1630
1631       script.src = url + '&jsonp=' + io.j.length;
1632       insertAt.parentNode.insertBefore(script, insertAt);
1633
1634       io.j.push(function (data) {
1635         complete(data);
1636         script.parentNode.removeChild(script);
1637       });
1638     } else {
1639       var xhr = io.util.request();
1640
1641       xhr.open('GET', url, true);
1642       if (this.isXDomain()) {
1643         xhr.withCredentials = true;
1644       }
1645       xhr.onreadystatechange = function () {
1646         if (xhr.readyState == 4) {
1647           xhr.onreadystatechange = empty;
1648
1649           if (xhr.status == 200) {
1650             complete(xhr.responseText);
1651           } else if (xhr.status == 403) {
1652             self.onError(xhr.responseText);
1653           } else {
1654             self.connecting = false;            
1655             !self.reconnecting && self.onError(xhr.responseText);
1656           }
1657         }
1658       };
1659       xhr.send(null);
1660     }
1661   };
1662
1663   /**
1664    * Find an available transport based on the options supplied in the constructor.
1665    *
1666    * @api private
1667    */
1668
1669   Socket.prototype.getTransport = function (override) {
1670     var transports = override || this.transports, match;
1671
1672     for (var i = 0, transport; transport = transports[i]; i++) {
1673       if (io.Transport[transport]
1674         && io.Transport[transport].check(this)
1675         && (!this.isXDomain() || io.Transport[transport].xdomainCheck(this))) {
1676         return new io.Transport[transport](this, this.sessionid);
1677       }
1678     }
1679
1680     return null;
1681   };
1682
1683   /**
1684    * Connects to the server.
1685    *
1686    * @param {Function} [fn] Callback.
1687    * @returns {io.Socket}
1688    * @api public
1689    */
1690
1691   Socket.prototype.connect = function (fn) {
1692     if (this.connecting) {
1693       return this;
1694     }
1695
1696     var self = this;
1697     self.connecting = true;
1698     
1699     this.handshake(function (sid, heartbeat, close, transports) {
1700       self.sessionid = sid;
1701       self.closeTimeout = close * 1000;
1702       self.heartbeatTimeout = heartbeat * 1000;
1703       if(!self.transports)
1704           self.transports = self.origTransports = (transports ? io.util.intersect(
1705               transports.split(',')
1706             , self.options.transports
1707           ) : self.options.transports);
1708
1709       self.setHeartbeatTimeout();
1710
1711       function connect (transports){
1712         if (self.transport) self.transport.clearTimeouts();
1713
1714         self.transport = self.getTransport(transports);
1715         if (!self.transport) return self.publish('connect_failed');
1716
1717         // once the transport is ready
1718         self.transport.ready(self, function () {
1719           self.connecting = true;
1720           self.publish('connecting', self.transport.name);
1721           self.transport.open();
1722
1723           if (self.options['connect timeout']) {
1724             self.connectTimeoutTimer = setTimeout(function () {
1725               if (!self.connected) {
1726                 self.connecting = false;
1727
1728                 if (self.options['try multiple transports']) {
1729                   var remaining = self.transports;
1730
1731                   while (remaining.length > 0 && remaining.splice(0,1)[0] !=
1732                          self.transport.name) {}
1733
1734                     if (remaining.length){
1735                       connect(remaining);
1736                     } else {
1737                       self.publish('connect_failed');
1738                     }
1739                 }
1740               }
1741             }, self.options['connect timeout']);
1742           }
1743         });
1744       }
1745
1746       connect(self.transports);
1747
1748       self.once('connect', function (){
1749         clearTimeout(self.connectTimeoutTimer);
1750
1751         fn && typeof fn == 'function' && fn();
1752       });
1753     });
1754
1755     return this;
1756   };
1757
1758   /**
1759    * Clears and sets a new heartbeat timeout using the value given by the
1760    * server during the handshake.
1761    *
1762    * @api private
1763    */
1764
1765   Socket.prototype.setHeartbeatTimeout = function () {
1766     clearTimeout(this.heartbeatTimeoutTimer);
1767     if(this.transport && !this.transport.heartbeats()) return;
1768
1769     var self = this;
1770     this.heartbeatTimeoutTimer = setTimeout(function () {
1771       self.transport.onClose();
1772     }, this.heartbeatTimeout);
1773   };
1774
1775   /**
1776    * Sends a message.
1777    *
1778    * @param {Object} data packet.
1779    * @returns {io.Socket}
1780    * @api public
1781    */
1782
1783   Socket.prototype.packet = function (data) {
1784     if (this.connected && !this.doBuffer) {
1785       this.transport.packet(data);
1786     } else {
1787       this.buffer.push(data);
1788     }
1789
1790     return this;
1791   };
1792
1793   /**
1794    * Sets buffer state
1795    *
1796    * @api private
1797    */
1798
1799   Socket.prototype.setBuffer = function (v) {
1800     this.doBuffer = v;
1801
1802     if (!v && this.connected && this.buffer.length) {
1803       if (!this.options['manualFlush']) {
1804         this.flushBuffer();
1805       }
1806     }
1807   };
1808
1809   /**
1810    * Flushes the buffer data over the wire.
1811    * To be invoked manually when 'manualFlush' is set to true.
1812    *
1813    * @api public
1814    */
1815
1816   Socket.prototype.flushBuffer = function() {
1817     this.transport.payload(this.buffer);
1818     this.buffer = [];
1819   };
1820   
1821
1822   /**
1823    * Disconnect the established connect.
1824    *
1825    * @returns {io.Socket}
1826    * @api public
1827    */
1828
1829   Socket.prototype.disconnect = function () {
1830     if (this.connected || this.connecting) {
1831       if (this.open) {
1832         this.of('').packet({ type: 'disconnect' });
1833       }
1834
1835       // handle disconnection immediately
1836       this.onDisconnect('booted');
1837     }
1838
1839     return this;
1840   };
1841
1842   /**
1843    * Disconnects the socket with a sync XHR.
1844    *
1845    * @api private
1846    */
1847
1848   Socket.prototype.disconnectSync = function () {
1849     // ensure disconnection
1850     var xhr = io.util.request();
1851     var uri = [
1852         'http' + (this.options.secure ? 's' : '') + ':/'
1853       , this.options.host + ':' + this.options.port
1854       , this.options.resource
1855       , io.protocol
1856       , ''
1857       , this.sessionid
1858     ].join('/') + '/?disconnect=1';
1859
1860     xhr.open('GET', uri, false);
1861     xhr.send(null);
1862
1863     // handle disconnection immediately
1864     this.onDisconnect('booted');
1865   };
1866
1867   /**
1868    * Check if we need to use cross domain enabled transports. Cross domain would
1869    * be a different port or different domain name.
1870    *
1871    * @returns {Boolean}
1872    * @api private
1873    */
1874
1875   Socket.prototype.isXDomain = function () {
1876
1877     var port = global.location.port ||
1878       ('https:' == global.location.protocol ? 443 : 80);
1879
1880     return this.options.host !== global.location.hostname 
1881       || this.options.port != port;
1882   };
1883
1884   /**
1885    * Called upon handshake.
1886    *
1887    * @api private
1888    */
1889
1890   Socket.prototype.onConnect = function () {
1891     if (!this.connected) {
1892       this.connected = true;
1893       this.connecting = false;
1894       if (!this.doBuffer) {
1895         // make sure to flush the buffer
1896         this.setBuffer(false);
1897       }
1898       this.emit('connect');
1899     }
1900   };
1901
1902   /**
1903    * Called when the transport opens
1904    *
1905    * @api private
1906    */
1907
1908   Socket.prototype.onOpen = function () {
1909     this.open = true;
1910   };
1911
1912   /**
1913    * Called when the transport closes.
1914    *
1915    * @api private
1916    */
1917
1918   Socket.prototype.onClose = function () {
1919     this.open = false;
1920     clearTimeout(this.heartbeatTimeoutTimer);
1921   };
1922
1923   /**
1924    * Called when the transport first opens a connection
1925    *
1926    * @param text
1927    */
1928
1929   Socket.prototype.onPacket = function (packet) {
1930     this.of(packet.endpoint).onPacket(packet);
1931   };
1932
1933   /**
1934    * Handles an error.
1935    *
1936    * @api private
1937    */
1938
1939   Socket.prototype.onError = function (err) {
1940     if (err && err.advice) {
1941       if (err.advice === 'reconnect' && (this.connected || this.connecting)) {
1942         this.disconnect();
1943         if (this.options.reconnect) {
1944           this.reconnect();
1945         }
1946       }
1947     }
1948
1949     this.publish('error', err && err.reason ? err.reason : err);
1950   };
1951
1952   /**
1953    * Called when the transport disconnects.
1954    *
1955    * @api private
1956    */
1957
1958   Socket.prototype.onDisconnect = function (reason) {
1959     var wasConnected = this.connected
1960       , wasConnecting = this.connecting;
1961
1962     this.connected = false;
1963     this.connecting = false;
1964     this.open = false;
1965
1966     if (wasConnected || wasConnecting) {
1967       this.transport.close();
1968       this.transport.clearTimeouts();
1969       if (wasConnected) {
1970         this.publish('disconnect', reason);
1971
1972         if ('booted' != reason && this.options.reconnect && !this.reconnecting) {
1973           this.reconnect();
1974         }
1975       }
1976     }
1977   };
1978
1979   /**
1980    * Called upon reconnection.
1981    *
1982    * @api private
1983    */
1984
1985   Socket.prototype.reconnect = function () {
1986     this.reconnecting = true;
1987     this.reconnectionAttempts = 0;
1988     this.reconnectionDelay = this.options['reconnection delay'];
1989
1990     var self = this
1991       , maxAttempts = this.options['max reconnection attempts']
1992       , tryMultiple = this.options['try multiple transports']
1993       , limit = this.options['reconnection limit'];
1994
1995     function reset () {
1996       if (self.connected) {
1997         for (var i in self.namespaces) {
1998           if (self.namespaces.hasOwnProperty(i) && '' !== i) {
1999               self.namespaces[i].packet({ type: 'connect' });
2000           }
2001         }
2002         self.publish('reconnect', self.transport.name, self.reconnectionAttempts);
2003       }
2004
2005       clearTimeout(self.reconnectionTimer);
2006
2007       self.removeListener('connect_failed', maybeReconnect);
2008       self.removeListener('connect', maybeReconnect);
2009
2010       self.reconnecting = false;
2011
2012       delete self.reconnectionAttempts;
2013       delete self.reconnectionDelay;
2014       delete self.reconnectionTimer;
2015       delete self.redoTransports;
2016
2017       self.options['try multiple transports'] = tryMultiple;
2018     };
2019
2020     function maybeReconnect () {
2021       if (!self.reconnecting) {
2022         return;
2023       }
2024
2025       if (self.connected) {
2026         return reset();
2027       };
2028
2029       if (self.connecting && self.reconnecting) {
2030         return self.reconnectionTimer = setTimeout(maybeReconnect, 1000);
2031       }
2032
2033       if (self.reconnectionAttempts++ >= maxAttempts) {
2034         if (!self.redoTransports) {
2035           self.on('connect_failed', maybeReconnect);
2036           self.options['try multiple transports'] = true;
2037           self.transports = self.origTransports;
2038           self.transport = self.getTransport();
2039           self.redoTransports = true;
2040           self.connect();
2041         } else {
2042           self.publish('reconnect_failed');
2043           reset();
2044         }
2045       } else {
2046         if (self.reconnectionDelay < limit) {
2047           self.reconnectionDelay *= 2; // exponential back off
2048         }
2049
2050         self.connect();
2051         self.publish('reconnecting', self.reconnectionDelay, self.reconnectionAttempts);
2052         self.reconnectionTimer = setTimeout(maybeReconnect, self.reconnectionDelay);
2053       }
2054     };
2055
2056     this.options['try multiple transports'] = false;
2057     this.reconnectionTimer = setTimeout(maybeReconnect, this.reconnectionDelay);
2058
2059     this.on('connect', maybeReconnect);
2060   };
2061
2062 })(
2063     'undefined' != typeof io ? io : module.exports
2064   , 'undefined' != typeof io ? io : module.parent.exports
2065   , this
2066 );
2067 /**
2068  * socket.io
2069  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
2070  * MIT Licensed
2071  */
2072
2073 (function (exports, io) {
2074
2075   /**
2076    * Expose constructor.
2077    */
2078
2079   exports.SocketNamespace = SocketNamespace;
2080
2081   /**
2082    * Socket namespace constructor.
2083    *
2084    * @constructor
2085    * @api public
2086    */
2087
2088   function SocketNamespace (socket, name) {
2089     this.socket = socket;
2090     this.name = name || '';
2091     this.flags = {};
2092     this.json = new Flag(this, 'json');
2093     this.ackPackets = 0;
2094     this.acks = {};
2095   };
2096
2097   /**
2098    * Apply EventEmitter mixin.
2099    */
2100
2101   io.util.mixin(SocketNamespace, io.EventEmitter);
2102
2103   /**
2104    * Copies emit since we override it
2105    *
2106    * @api private
2107    */
2108
2109   SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit;
2110
2111   /**
2112    * Creates a new namespace, by proxying the request to the socket. This
2113    * allows us to use the synax as we do on the server.
2114    *
2115    * @api public
2116    */
2117
2118   SocketNamespace.prototype.of = function () {
2119     return this.socket.of.apply(this.socket, arguments);
2120   };
2121
2122   /**
2123    * Sends a packet.
2124    *
2125    * @api private
2126    */
2127
2128   SocketNamespace.prototype.packet = function (packet) {
2129     packet.endpoint = this.name;
2130     this.socket.packet(packet);
2131     this.flags = {};
2132     return this;
2133   };
2134
2135   /**
2136    * Sends a message
2137    *
2138    * @api public
2139    */
2140
2141   SocketNamespace.prototype.send = function (data, fn) {
2142     var packet = {
2143         type: this.flags.json ? 'json' : 'message'
2144       , data: data
2145     };
2146
2147     if ('function' == typeof fn) {
2148       packet.id = ++this.ackPackets;
2149       packet.ack = true;
2150       this.acks[packet.id] = fn;
2151     }
2152
2153     return this.packet(packet);
2154   };
2155
2156   /**
2157    * Emits an event
2158    *
2159    * @api public
2160    */
2161   
2162   SocketNamespace.prototype.emit = function (name) {
2163     var args = Array.prototype.slice.call(arguments, 1)
2164       , lastArg = args[args.length - 1]
2165       , packet = {
2166             type: 'event'
2167           , name: name
2168         };
2169
2170     if ('function' == typeof lastArg) {
2171       packet.id = ++this.ackPackets;
2172       packet.ack = 'data';
2173       this.acks[packet.id] = lastArg;
2174       args = args.slice(0, args.length - 1);
2175     }
2176
2177     packet.args = args;
2178
2179     return this.packet(packet);
2180   };
2181
2182   /**
2183    * Disconnects the namespace
2184    *
2185    * @api private
2186    */
2187
2188   SocketNamespace.prototype.disconnect = function () {
2189     if (this.name === '') {
2190       this.socket.disconnect();
2191     } else {
2192       this.packet({ type: 'disconnect' });
2193       this.$emit('disconnect');
2194     }
2195
2196     return this;
2197   };
2198
2199   /**
2200    * Handles a packet
2201    *
2202    * @api private
2203    */
2204
2205   SocketNamespace.prototype.onPacket = function (packet) {
2206     var self = this;
2207
2208     function ack () {
2209       self.packet({
2210           type: 'ack'
2211         , args: io.util.toArray(arguments)
2212         , ackId: packet.id
2213       });
2214     };
2215
2216     switch (packet.type) {
2217       case 'connect':
2218         this.$emit('connect');
2219         break;
2220
2221       case 'disconnect':
2222         if (this.name === '') {
2223           this.socket.onDisconnect(packet.reason || 'booted');
2224         } else {
2225           this.$emit('disconnect', packet.reason);
2226         }
2227         break;
2228
2229       case 'message':
2230       case 'json':
2231         var params = ['message', packet.data];
2232
2233         if (packet.ack == 'data') {
2234           params.push(ack);
2235         } else if (packet.ack) {
2236           this.packet({ type: 'ack', ackId: packet.id });
2237         }
2238
2239         this.$emit.apply(this, params);
2240         break;
2241
2242       case 'event':
2243         var params = [packet.name].concat(packet.args);
2244
2245         if (packet.ack == 'data')
2246           params.push(ack);
2247
2248         this.$emit.apply(this, params);
2249         break;
2250
2251       case 'ack':
2252         if (this.acks[packet.ackId]) {
2253           this.acks[packet.ackId].apply(this, packet.args);
2254           delete this.acks[packet.ackId];
2255         }
2256         break;
2257
2258       case 'error':
2259         if (packet.advice){
2260           this.socket.onError(packet);
2261         } else {
2262           if (packet.reason == 'unauthorized') {
2263             this.$emit('connect_failed', packet.reason);
2264           } else {
2265             this.$emit('error', packet.reason);
2266           }
2267         }
2268         break;
2269     }
2270   };
2271
2272   /**
2273    * Flag interface.
2274    *
2275    * @api private
2276    */
2277
2278   function Flag (nsp, name) {
2279     this.namespace = nsp;
2280     this.name = name;
2281   };
2282
2283   /**
2284    * Send a message
2285    *
2286    * @api public
2287    */
2288
2289   Flag.prototype.send = function () {
2290     this.namespace.flags[this.name] = true;
2291     this.namespace.send.apply(this.namespace, arguments);
2292   };
2293
2294   /**
2295    * Emit an event
2296    *
2297    * @api public
2298    */
2299
2300   Flag.prototype.emit = function () {
2301     this.namespace.flags[this.name] = true;
2302     this.namespace.emit.apply(this.namespace, arguments);
2303   };
2304
2305 })(
2306     'undefined' != typeof io ? io : module.exports
2307   , 'undefined' != typeof io ? io : module.parent.exports
2308 );
2309
2310 /**
2311  * socket.io
2312  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
2313  * MIT Licensed
2314  */
2315
2316 (function (exports, io, global) {
2317
2318   /**
2319    * Expose constructor.
2320    */
2321
2322   exports.websocket = WS;
2323
2324   /**
2325    * The WebSocket transport uses the HTML5 WebSocket API to establish an
2326    * persistent connection with the Socket.IO server. This transport will also
2327    * be inherited by the FlashSocket fallback as it provides a API compatible
2328    * polyfill for the WebSockets.
2329    *
2330    * @constructor
2331    * @extends {io.Transport}
2332    * @api public
2333    */
2334
2335   function WS (socket) {
2336     io.Transport.apply(this, arguments);
2337   };
2338
2339   /**
2340    * Inherits from Transport.
2341    */
2342
2343   io.util.inherit(WS, io.Transport);
2344
2345   /**
2346    * Transport name
2347    *
2348    * @api public
2349    */
2350
2351   WS.prototype.name = 'websocket';
2352
2353   /**
2354    * Initializes a new `WebSocket` connection with the Socket.IO server. We attach
2355    * all the appropriate listeners to handle the responses from the server.
2356    *
2357    * @returns {Transport}
2358    * @api public
2359    */
2360
2361   WS.prototype.open = function () {
2362     var query = io.util.query(this.socket.options.query)
2363       , self = this
2364       , Socket
2365
2366
2367     if (!Socket) {
2368       Socket = global.MozWebSocket || global.WebSocket;
2369     }
2370
2371     this.websocket = new Socket(this.prepareUrl() + query);
2372
2373     this.websocket.onopen = function () {
2374       self.onOpen();
2375       self.socket.setBuffer(false);
2376     };
2377     this.websocket.onmessage = function (ev) {
2378       self.onData(ev.data);
2379     };
2380     this.websocket.onclose = function () {
2381       self.onClose();
2382       self.socket.setBuffer(true);
2383     };
2384     this.websocket.onerror = function (e) {
2385       self.onError(e);
2386     };
2387
2388     return this;
2389   };
2390
2391   /**
2392    * Send a message to the Socket.IO server. The message will automatically be
2393    * encoded in the correct message format.
2394    *
2395    * @returns {Transport}
2396    * @api public
2397    */
2398
2399   // Do to a bug in the current IDevices browser, we need to wrap the send in a 
2400   // setTimeout, when they resume from sleeping the browser will crash if 
2401   // we don't allow the browser time to detect the socket has been closed
2402   if (io.util.ua.iDevice) {
2403     WS.prototype.send = function (data) {
2404       var self = this;
2405       setTimeout(function() {
2406          self.websocket.send(data);
2407       },0);
2408       return this;
2409     };
2410   } else {
2411     WS.prototype.send = function (data) {
2412       this.websocket.send(data);
2413       return this;
2414     };
2415   }
2416
2417   /**
2418    * Payload
2419    *
2420    * @api private
2421    */
2422
2423   WS.prototype.payload = function (arr) {
2424     for (var i = 0, l = arr.length; i < l; i++) {
2425       this.packet(arr[i]);
2426     }
2427     return this;
2428   };
2429
2430   /**
2431    * Disconnect the established `WebSocket` connection.
2432    *
2433    * @returns {Transport}
2434    * @api public
2435    */
2436
2437   WS.prototype.close = function () {
2438     this.websocket.close();
2439     return this;
2440   };
2441
2442   /**
2443    * Handle the errors that `WebSocket` might be giving when we
2444    * are attempting to connect or send messages.
2445    *
2446    * @param {Error} e The error.
2447    * @api private
2448    */
2449
2450   WS.prototype.onError = function (e) {
2451     this.socket.onError(e);
2452   };
2453
2454   /**
2455    * Returns the appropriate scheme for the URI generation.
2456    *
2457    * @api private
2458    */
2459   WS.prototype.scheme = function () {
2460     return this.socket.options.secure ? 'wss' : 'ws';
2461   };
2462
2463   /**
2464    * Checks if the browser has support for native `WebSockets` and that
2465    * it's not the polyfill created for the FlashSocket transport.
2466    *
2467    * @return {Boolean}
2468    * @api public
2469    */
2470
2471   WS.check = function () {
2472     return ('WebSocket' in global && !('__addTask' in WebSocket))
2473           || 'MozWebSocket' in global;
2474   };
2475
2476   /**
2477    * Check if the `WebSocket` transport support cross domain communications.
2478    *
2479    * @returns {Boolean}
2480    * @api public
2481    */
2482
2483   WS.xdomainCheck = function () {
2484     return true;
2485   };
2486
2487   /**
2488    * Add the transport to your public io.transports array.
2489    *
2490    * @api private
2491    */
2492
2493   io.transports.push('websocket');
2494
2495 })(
2496     'undefined' != typeof io ? io.Transport : module.exports
2497   , 'undefined' != typeof io ? io : module.parent.exports
2498   , this
2499 );
2500
2501 /**
2502  * socket.io
2503  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
2504  * MIT Licensed
2505  */
2506
2507 (function (exports, io) {
2508
2509   /**
2510    * Expose constructor.
2511    */
2512
2513   exports.flashsocket = Flashsocket;
2514
2515   /**
2516    * The FlashSocket transport. This is a API wrapper for the HTML5 WebSocket
2517    * specification. It uses a .swf file to communicate with the server. If you want
2518    * to serve the .swf file from a other server than where the Socket.IO script is
2519    * coming from you need to use the insecure version of the .swf. More information
2520    * about this can be found on the github page.
2521    *
2522    * @constructor
2523    * @extends {io.Transport.websocket}
2524    * @api public
2525    */
2526
2527   function Flashsocket () {
2528     io.Transport.websocket.apply(this, arguments);
2529   };
2530
2531   /**
2532    * Inherits from Transport.
2533    */
2534
2535   io.util.inherit(Flashsocket, io.Transport.websocket);
2536
2537   /**
2538    * Transport name
2539    *
2540    * @api public
2541    */
2542
2543   Flashsocket.prototype.name = 'flashsocket';
2544
2545   /**
2546    * Disconnect the established `FlashSocket` connection. This is done by adding a 
2547    * new task to the FlashSocket. The rest will be handled off by the `WebSocket` 
2548    * transport.
2549    *
2550    * @returns {Transport}
2551    * @api public
2552    */
2553
2554   Flashsocket.prototype.open = function () {
2555     var self = this
2556       , args = arguments;
2557
2558     WebSocket.__addTask(function () {
2559       io.Transport.websocket.prototype.open.apply(self, args);
2560     });
2561     return this;
2562   };
2563   
2564   /**
2565    * Sends a message to the Socket.IO server. This is done by adding a new
2566    * task to the FlashSocket. The rest will be handled off by the `WebSocket` 
2567    * transport.
2568    *
2569    * @returns {Transport}
2570    * @api public
2571    */
2572
2573   Flashsocket.prototype.send = function () {
2574     var self = this, args = arguments;
2575     WebSocket.__addTask(function () {
2576       io.Transport.websocket.prototype.send.apply(self, args);
2577     });
2578     return this;
2579   };
2580
2581   /**
2582    * Disconnects the established `FlashSocket` connection.
2583    *
2584    * @returns {Transport}
2585    * @api public
2586    */
2587
2588   Flashsocket.prototype.close = function () {
2589     WebSocket.__tasks.length = 0;
2590     io.Transport.websocket.prototype.close.call(this);
2591     return this;
2592   };
2593
2594   /**
2595    * The WebSocket fall back needs to append the flash container to the body
2596    * element, so we need to make sure we have access to it. Or defer the call
2597    * until we are sure there is a body element.
2598    *
2599    * @param {Socket} socket The socket instance that needs a transport
2600    * @param {Function} fn The callback
2601    * @api private
2602    */
2603
2604   Flashsocket.prototype.ready = function (socket, fn) {
2605     function init () {
2606       var options = socket.options
2607         , port = options['flash policy port']
2608         , path = [
2609               'http' + (options.secure ? 's' : '') + ':/'
2610             , options.host + ':' + options.port
2611             , options.resource
2612             , 'static/flashsocket'
2613             , 'WebSocketMain' + (socket.isXDomain() ? 'Insecure' : '') + '.swf'
2614           ];
2615
2616       // Only start downloading the swf file when the checked that this browser
2617       // actually supports it
2618       if (!Flashsocket.loaded) {
2619         if (typeof WEB_SOCKET_SWF_LOCATION === 'undefined') {
2620           // Set the correct file based on the XDomain settings
2621           WEB_SOCKET_SWF_LOCATION = path.join('/');
2622         }
2623
2624         if (port !== 843) {
2625           WebSocket.loadFlashPolicyFile('xmlsocket://' + options.host + ':' + port);
2626         }
2627
2628         WebSocket.__initialize();
2629         Flashsocket.loaded = true;
2630       }
2631
2632       fn.call(self);
2633     }
2634
2635     var self = this;
2636     if (document.body) return init();
2637
2638     io.util.load(init);
2639   };
2640
2641   /**
2642    * Check if the FlashSocket transport is supported as it requires that the Adobe
2643    * Flash Player plug-in version `10.0.0` or greater is installed. And also check if
2644    * the polyfill is correctly loaded.
2645    *
2646    * @returns {Boolean}
2647    * @api public
2648    */
2649
2650   Flashsocket.check = function () {
2651     if (
2652         typeof WebSocket == 'undefined'
2653       || !('__initialize' in WebSocket) || !swfobject
2654     ) return false;
2655
2656     return swfobject.getFlashPlayerVersion().major >= 10;
2657   };
2658
2659   /**
2660    * Check if the FlashSocket transport can be used as cross domain / cross origin 
2661    * transport. Because we can't see which type (secure or insecure) of .swf is used
2662    * we will just return true.
2663    *
2664    * @returns {Boolean}
2665    * @api public
2666    */
2667
2668   Flashsocket.xdomainCheck = function () {
2669     return true;
2670   };
2671
2672   /**
2673    * Disable AUTO_INITIALIZATION
2674    */
2675
2676   if (typeof window != 'undefined') {
2677     WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true;
2678   }
2679
2680   /**
2681    * Add the transport to your public io.transports array.
2682    *
2683    * @api private
2684    */
2685
2686   io.transports.push('flashsocket');
2687 })(
2688     'undefined' != typeof io ? io.Transport : module.exports
2689   , 'undefined' != typeof io ? io : module.parent.exports
2690 );
2691 /*      SWFObject v2.2 <http://code.google.com/p/swfobject/> 
2692         is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
2693 */
2694 if ('undefined' != typeof window) {
2695 var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O[(['Active'].concat('Object').join('X'))]!=D){try{var ad=new window[(['Active'].concat('Object').join('X'))](W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?(['Active'].concat('').join('X')):"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
2696 }
2697 // Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
2698 // License: New BSD License
2699 // Reference: http://dev.w3.org/html5/websockets/
2700 // Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
2701
2702 (function() {
2703   
2704   if ('undefined' == typeof window || window.WebSocket) return;
2705
2706   var console = window.console;
2707   if (!console || !console.log || !console.error) {
2708     console = {log: function(){ }, error: function(){ }};
2709   }
2710   
2711   if (!swfobject.hasFlashPlayerVersion("10.0.0")) {
2712     console.error("Flash Player >= 10.0.0 is required.");
2713     return;
2714   }
2715   if (location.protocol == "file:") {
2716     console.error(
2717       "WARNING: web-socket-js doesn't work in file:///... URL " +
2718       "unless you set Flash Security Settings properly. " +
2719       "Open the page via Web server i.e. http://...");
2720   }
2721
2722   /**
2723    * This class represents a faux web socket.
2724    * @param {string} url
2725    * @param {array or string} protocols
2726    * @param {string} proxyHost
2727    * @param {int} proxyPort
2728    * @param {string} headers
2729    */
2730   WebSocket = function(url, protocols, proxyHost, proxyPort, headers) {
2731     var self = this;
2732     self.__id = WebSocket.__nextId++;
2733     WebSocket.__instances[self.__id] = self;
2734     self.readyState = WebSocket.CONNECTING;
2735     self.bufferedAmount = 0;
2736     self.__events = {};
2737     if (!protocols) {
2738       protocols = [];
2739     } else if (typeof protocols == "string") {
2740       protocols = [protocols];
2741     }
2742     // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc.
2743     // Otherwise, when onopen fires immediately, onopen is called before it is set.
2744     setTimeout(function() {
2745       WebSocket.__addTask(function() {
2746         WebSocket.__flash.create(
2747             self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null);
2748       });
2749     }, 0);
2750   };
2751
2752   /**
2753    * Send data to the web socket.
2754    * @param {string} data  The data to send to the socket.
2755    * @return {boolean}  True for success, false for failure.
2756    */
2757   WebSocket.prototype.send = function(data) {
2758     if (this.readyState == WebSocket.CONNECTING) {
2759       throw "INVALID_STATE_ERR: Web Socket connection has not been established";
2760     }
2761     // We use encodeURIComponent() here, because FABridge doesn't work if
2762     // the argument includes some characters. We don't use escape() here
2763     // because of this:
2764     // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions
2765     // But it looks decodeURIComponent(encodeURIComponent(s)) doesn't
2766     // preserve all Unicode characters either e.g. "\uffff" in Firefox.
2767     // Note by wtritch: Hopefully this will not be necessary using ExternalInterface.  Will require
2768     // additional testing.
2769     var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data));
2770     if (result < 0) { // success
2771       return true;
2772     } else {
2773       this.bufferedAmount += result;
2774       return false;
2775     }
2776   };
2777
2778   /**
2779    * Close this web socket gracefully.
2780    */
2781   WebSocket.prototype.close = function() {
2782     if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) {
2783       return;
2784     }
2785     this.readyState = WebSocket.CLOSING;
2786     WebSocket.__flash.close(this.__id);
2787   };
2788
2789   /**
2790    * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
2791    *
2792    * @param {string} type
2793    * @param {function} listener
2794    * @param {boolean} useCapture
2795    * @return void
2796    */
2797   WebSocket.prototype.addEventListener = function(type, listener, useCapture) {
2798     if (!(type in this.__events)) {
2799       this.__events[type] = [];
2800     }
2801     this.__events[type].push(listener);
2802   };
2803
2804   /**
2805    * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
2806    *
2807    * @param {string} type
2808    * @param {function} listener
2809    * @param {boolean} useCapture
2810    * @return void
2811    */
2812   WebSocket.prototype.removeEventListener = function(type, listener, useCapture) {
2813     if (!(type in this.__events)) return;
2814     var events = this.__events[type];
2815     for (var i = events.length - 1; i >= 0; --i) {
2816       if (events[i] === listener) {
2817         events.splice(i, 1);
2818         break;
2819       }
2820     }
2821   };
2822
2823   /**
2824    * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
2825    *
2826    * @param {Event} event
2827    * @return void
2828    */
2829   WebSocket.prototype.dispatchEvent = function(event) {
2830     var events = this.__events[event.type] || [];
2831     for (var i = 0; i < events.length; ++i) {
2832       events[i](event);
2833     }
2834     var handler = this["on" + event.type];
2835     if (handler) handler(event);
2836   };
2837
2838   /**
2839    * Handles an event from Flash.
2840    * @param {Object} flashEvent
2841    */
2842   WebSocket.prototype.__handleEvent = function(flashEvent) {
2843     if ("readyState" in flashEvent) {
2844       this.readyState = flashEvent.readyState;
2845     }
2846     if ("protocol" in flashEvent) {
2847       this.protocol = flashEvent.protocol;
2848     }
2849     
2850     var jsEvent;
2851     if (flashEvent.type == "open" || flashEvent.type == "error") {
2852       jsEvent = this.__createSimpleEvent(flashEvent.type);
2853     } else if (flashEvent.type == "close") {
2854       // TODO implement jsEvent.wasClean
2855       jsEvent = this.__createSimpleEvent("close");
2856     } else if (flashEvent.type == "message") {
2857       var data = decodeURIComponent(flashEvent.message);
2858       jsEvent = this.__createMessageEvent("message", data);
2859     } else {
2860       throw "unknown event type: " + flashEvent.type;
2861     }
2862     
2863     this.dispatchEvent(jsEvent);
2864   };
2865   
2866   WebSocket.prototype.__createSimpleEvent = function(type) {
2867     if (document.createEvent && window.Event) {
2868       var event = document.createEvent("Event");
2869       event.initEvent(type, false, false);
2870       return event;
2871     } else {
2872       return {type: type, bubbles: false, cancelable: false};
2873     }
2874   };
2875   
2876   WebSocket.prototype.__createMessageEvent = function(type, data) {
2877     if (document.createEvent && window.MessageEvent && !window.opera) {
2878       var event = document.createEvent("MessageEvent");
2879       event.initMessageEvent("message", false, false, data, null, null, window, null);
2880       return event;
2881     } else {
2882       // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes.
2883       return {type: type, data: data, bubbles: false, cancelable: false};
2884     }
2885   };
2886   
2887   /**
2888    * Define the WebSocket readyState enumeration.
2889    */
2890   WebSocket.CONNECTING = 0;
2891   WebSocket.OPEN = 1;
2892   WebSocket.CLOSING = 2;
2893   WebSocket.CLOSED = 3;
2894
2895   WebSocket.__flash = null;
2896   WebSocket.__instances = {};
2897   WebSocket.__tasks = [];
2898   WebSocket.__nextId = 0;
2899   
2900   /**
2901    * Load a new flash security policy file.
2902    * @param {string} url
2903    */
2904   WebSocket.loadFlashPolicyFile = function(url){
2905     WebSocket.__addTask(function() {
2906       WebSocket.__flash.loadManualPolicyFile(url);
2907     });
2908   };
2909
2910   /**
2911    * Loads WebSocketMain.swf and creates WebSocketMain object in Flash.
2912    */
2913   WebSocket.__initialize = function() {
2914     if (WebSocket.__flash) return;
2915     
2916     if (WebSocket.__swfLocation) {
2917       // For backword compatibility.
2918       window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
2919     }
2920     if (!window.WEB_SOCKET_SWF_LOCATION) {
2921       console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
2922       return;
2923     }
2924     var container = document.createElement("div");
2925     container.id = "webSocketContainer";
2926     // Hides Flash box. We cannot use display: none or visibility: hidden because it prevents
2927     // Flash from loading at least in IE. So we move it out of the screen at (-100, -100).
2928     // But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash
2929     // Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is
2930     // the best we can do as far as we know now.
2931     container.style.position = "absolute";
2932     if (WebSocket.__isFlashLite()) {
2933       container.style.left = "0px";
2934       container.style.top = "0px";
2935     } else {
2936       container.style.left = "-100px";
2937       container.style.top = "-100px";
2938     }
2939     var holder = document.createElement("div");
2940     holder.id = "webSocketFlash";
2941     container.appendChild(holder);
2942     document.body.appendChild(container);
2943     // See this article for hasPriority:
2944     // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html
2945     swfobject.embedSWF(
2946       WEB_SOCKET_SWF_LOCATION,
2947       "webSocketFlash",
2948       "1" /* width */,
2949       "1" /* height */,
2950       "10.0.0" /* SWF version */,
2951       null,
2952       null,
2953       {hasPriority: true, swliveconnect : true, allowScriptAccess: "always"},
2954       null,
2955       function(e) {
2956         if (!e.success) {
2957           console.error("[WebSocket] swfobject.embedSWF failed");
2958         }
2959       });
2960   };
2961   
2962   /**
2963    * Called by Flash to notify JS that it's fully loaded and ready
2964    * for communication.
2965    */
2966   WebSocket.__onFlashInitialized = function() {
2967     // We need to set a timeout here to avoid round-trip calls
2968     // to flash during the initialization process.
2969     setTimeout(function() {
2970       WebSocket.__flash = document.getElementById("webSocketFlash");
2971       WebSocket.__flash.setCallerUrl(location.href);
2972       WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
2973       for (var i = 0; i < WebSocket.__tasks.length; ++i) {
2974         WebSocket.__tasks[i]();
2975       }
2976       WebSocket.__tasks = [];
2977     }, 0);
2978   };
2979   
2980   /**
2981    * Called by Flash to notify WebSockets events are fired.
2982    */
2983   WebSocket.__onFlashEvent = function() {
2984     setTimeout(function() {
2985       try {
2986         // Gets events using receiveEvents() instead of getting it from event object
2987         // of Flash event. This is to make sure to keep message order.
2988         // It seems sometimes Flash events don't arrive in the same order as they are sent.
2989         var events = WebSocket.__flash.receiveEvents();
2990         for (var i = 0; i < events.length; ++i) {
2991           WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
2992         }
2993       } catch (e) {
2994         console.error(e);
2995       }
2996     }, 0);
2997     return true;
2998   };
2999   
3000   // Called by Flash.
3001   WebSocket.__log = function(message) {
3002     console.log(decodeURIComponent(message));
3003   };
3004   
3005   // Called by Flash.
3006   WebSocket.__error = function(message) {
3007     console.error(decodeURIComponent(message));
3008   };
3009   
3010   WebSocket.__addTask = function(task) {
3011     if (WebSocket.__flash) {
3012       task();
3013     } else {
3014       WebSocket.__tasks.push(task);
3015     }
3016   };
3017   
3018   /**
3019    * Test if the browser is running flash lite.
3020    * @return {boolean} True if flash lite is running, false otherwise.
3021    */
3022   WebSocket.__isFlashLite = function() {
3023     if (!window.navigator || !window.navigator.mimeTypes) {
3024       return false;
3025     }
3026     var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"];
3027     if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) {
3028       return false;
3029     }
3030     return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false;
3031   };
3032   
3033   if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
3034     if (window.addEventListener) {
3035       window.addEventListener("load", function(){
3036         WebSocket.__initialize();
3037       }, false);
3038     } else {
3039       window.attachEvent("onload", function(){
3040         WebSocket.__initialize();
3041       });
3042     }
3043   }
3044   
3045 })();
3046
3047 /**
3048  * socket.io
3049  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
3050  * MIT Licensed
3051  */
3052
3053 (function (exports, io, global) {
3054
3055   /**
3056    * Expose constructor.
3057    *
3058    * @api public
3059    */
3060
3061   exports.XHR = XHR;
3062
3063   /**
3064    * XHR constructor
3065    *
3066    * @costructor
3067    * @api public
3068    */
3069
3070   function XHR (socket) {
3071     if (!socket) return;
3072
3073     io.Transport.apply(this, arguments);
3074     this.sendBuffer = [];
3075   };
3076
3077   /**
3078    * Inherits from Transport.
3079    */
3080
3081   io.util.inherit(XHR, io.Transport);
3082
3083   /**
3084    * Establish a connection
3085    *
3086    * @returns {Transport}
3087    * @api public
3088    */
3089
3090   XHR.prototype.open = function () {
3091     this.socket.setBuffer(false);
3092     this.onOpen();
3093     this.get();
3094
3095     // we need to make sure the request succeeds since we have no indication
3096     // whether the request opened or not until it succeeded.
3097     this.setCloseTimeout();
3098
3099     return this;
3100   };
3101
3102   /**
3103    * Check if we need to send data to the Socket.IO server, if we have data in our
3104    * buffer we encode it and forward it to the `post` method.
3105    *
3106    * @api private
3107    */
3108
3109   XHR.prototype.payload = function (payload) {
3110     var msgs = [];
3111
3112     for (var i = 0, l = payload.length; i < l; i++) {
3113       msgs.push(io.parser.encodePacket(payload[i]));
3114     }
3115
3116     this.send(io.parser.encodePayload(msgs));
3117   };
3118
3119   /**
3120    * Send data to the Socket.IO server.
3121    *
3122    * @param data The message
3123    * @returns {Transport}
3124    * @api public
3125    */
3126
3127   XHR.prototype.send = function (data) {
3128     this.post(data);
3129     return this;
3130   };
3131
3132   /**
3133    * Posts a encoded message to the Socket.IO server.
3134    *
3135    * @param {String} data A encoded message.
3136    * @api private
3137    */
3138
3139   function empty () { };
3140
3141   XHR.prototype.post = function (data) {
3142     var self = this;
3143     this.socket.setBuffer(true);
3144
3145     function stateChange () {
3146       if (this.readyState == 4) {
3147         this.onreadystatechange = empty;
3148         self.posting = false;
3149
3150         if (this.status == 200){
3151           self.socket.setBuffer(false);
3152         } else {
3153           self.onClose();
3154         }
3155       }
3156     }
3157
3158     function onload () {
3159       this.onload = empty;
3160       self.socket.setBuffer(false);
3161     };
3162
3163     this.sendXHR = this.request('POST');
3164
3165     if (global.XDomainRequest && this.sendXHR instanceof XDomainRequest) {
3166       this.sendXHR.onload = this.sendXHR.onerror = onload;
3167     } else {
3168       this.sendXHR.onreadystatechange = stateChange;
3169     }
3170
3171     this.sendXHR.send(data);
3172   };
3173
3174   /**
3175    * Disconnects the established `XHR` connection.
3176    *
3177    * @returns {Transport}
3178    * @api public
3179    */
3180
3181   XHR.prototype.close = function () {
3182     this.onClose();
3183     return this;
3184   };
3185
3186   /**
3187    * Generates a configured XHR request
3188    *
3189    * @param {String} url The url that needs to be requested.
3190    * @param {String} method The method the request should use.
3191    * @returns {XMLHttpRequest}
3192    * @api private
3193    */
3194
3195   XHR.prototype.request = function (method) {
3196     var req = io.util.request(this.socket.isXDomain())
3197       , query = io.util.query(this.socket.options.query, 't=' + +new Date);
3198
3199     req.open(method || 'GET', this.prepareUrl() + query, true);
3200
3201     if (method == 'POST') {
3202       try {
3203         if (req.setRequestHeader) {
3204           req.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
3205         } else {
3206           // XDomainRequest
3207           req.contentType = 'text/plain';
3208         }
3209       } catch (e) {}
3210     }
3211
3212     return req;
3213   };
3214
3215   /**
3216    * Returns the scheme to use for the transport URLs.
3217    *
3218    * @api private
3219    */
3220
3221   XHR.prototype.scheme = function () {
3222     return this.socket.options.secure ? 'https' : 'http';
3223   };
3224
3225   /**
3226    * Check if the XHR transports are supported
3227    *
3228    * @param {Boolean} xdomain Check if we support cross domain requests.
3229    * @returns {Boolean}
3230    * @api public
3231    */
3232
3233   XHR.check = function (socket, xdomain) {
3234     try {
3235       var request = io.util.request(xdomain),
3236           usesXDomReq = (global.XDomainRequest && request instanceof XDomainRequest),
3237           socketProtocol = (socket && socket.options && socket.options.secure ? 'https:' : 'http:'),
3238           isXProtocol = (global.location && socketProtocol != global.location.protocol);
3239       if (request && !(usesXDomReq && isXProtocol)) {
3240         return true;
3241       }
3242     } catch(e) {}
3243
3244     return false;
3245   };
3246
3247   /**
3248    * Check if the XHR transport supports cross domain requests.
3249    *
3250    * @returns {Boolean}
3251    * @api public
3252    */
3253
3254   XHR.xdomainCheck = function (socket) {
3255     return XHR.check(socket, true);
3256   };
3257
3258 })(
3259     'undefined' != typeof io ? io.Transport : module.exports
3260   , 'undefined' != typeof io ? io : module.parent.exports
3261   , this
3262 );
3263 /**
3264  * socket.io
3265  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
3266  * MIT Licensed
3267  */
3268
3269 (function (exports, io) {
3270
3271   /**
3272    * Expose constructor.
3273    */
3274
3275   exports.htmlfile = HTMLFile;
3276
3277   /**
3278    * The HTMLFile transport creates a `forever iframe` based transport
3279    * for Internet Explorer. Regular forever iframe implementations will 
3280    * continuously trigger the browsers buzy indicators. If the forever iframe
3281    * is created inside a `htmlfile` these indicators will not be trigged.
3282    *
3283    * @constructor
3284    * @extends {io.Transport.XHR}
3285    * @api public
3286    */
3287
3288   function HTMLFile (socket) {
3289     io.Transport.XHR.apply(this, arguments);
3290   };
3291
3292   /**
3293    * Inherits from XHR transport.
3294    */
3295
3296   io.util.inherit(HTMLFile, io.Transport.XHR);
3297
3298   /**
3299    * Transport name
3300    *
3301    * @api public
3302    */
3303
3304   HTMLFile.prototype.name = 'htmlfile';
3305
3306   /**
3307    * Creates a new Ac...eX `htmlfile` with a forever loading iframe
3308    * that can be used to listen to messages. Inside the generated
3309    * `htmlfile` a reference will be made to the HTMLFile transport.
3310    *
3311    * @api private
3312    */
3313
3314   HTMLFile.prototype.get = function () {
3315     this.doc = new window[(['Active'].concat('Object').join('X'))]('htmlfile');
3316     this.doc.open();
3317     this.doc.write('<html></html>');
3318     this.doc.close();
3319     this.doc.parentWindow.s = this;
3320
3321     var iframeC = this.doc.createElement('div');
3322     iframeC.className = 'socketio';
3323
3324     this.doc.body.appendChild(iframeC);
3325     this.iframe = this.doc.createElement('iframe');
3326
3327     iframeC.appendChild(this.iframe);
3328
3329     var self = this
3330       , query = io.util.query(this.socket.options.query, 't='+ +new Date);
3331
3332     this.iframe.src = this.prepareUrl() + query;
3333
3334     io.util.on(window, 'unload', function () {
3335       self.destroy();
3336     });
3337   };
3338
3339   /**
3340    * The Socket.IO server will write script tags inside the forever
3341    * iframe, this function will be used as callback for the incoming
3342    * information.
3343    *
3344    * @param {String} data The message
3345    * @param {document} doc Reference to the context
3346    * @api private
3347    */
3348
3349   HTMLFile.prototype._ = function (data, doc) {
3350     // unescape all forward slashes. see GH-1251
3351     data = data.replace(/\\\//g, '/');
3352     this.onData(data);
3353     try {
3354       var script = doc.getElementsByTagName('script')[0];
3355       script.parentNode.removeChild(script);
3356     } catch (e) { }
3357   };
3358
3359   /**
3360    * Destroy the established connection, iframe and `htmlfile`.
3361    * And calls the `CollectGarbage` function of Internet Explorer
3362    * to release the memory.
3363    *
3364    * @api private
3365    */
3366
3367   HTMLFile.prototype.destroy = function () {
3368     if (this.iframe){
3369       try {
3370         this.iframe.src = 'about:blank';
3371       } catch(e){}
3372
3373       this.doc = null;
3374       this.iframe.parentNode.removeChild(this.iframe);
3375       this.iframe = null;
3376
3377       CollectGarbage();
3378     }
3379   };
3380
3381   /**
3382    * Disconnects the established connection.
3383    *
3384    * @returns {Transport} Chaining.
3385    * @api public
3386    */
3387
3388   HTMLFile.prototype.close = function () {
3389     this.destroy();
3390     return io.Transport.XHR.prototype.close.call(this);
3391   };
3392
3393   /**
3394    * Checks if the browser supports this transport. The browser
3395    * must have an `Ac...eXObject` implementation.
3396    *
3397    * @return {Boolean}
3398    * @api public
3399    */
3400
3401   HTMLFile.check = function (socket) {
3402     if (typeof window != "undefined" && (['Active'].concat('Object').join('X')) in window){
3403       try {
3404         var a = new window[(['Active'].concat('Object').join('X'))]('htmlfile');
3405         return a && io.Transport.XHR.check(socket);
3406       } catch(e){}
3407     }
3408     return false;
3409   };
3410
3411   /**
3412    * Check if cross domain requests are supported.
3413    *
3414    * @returns {Boolean}
3415    * @api public
3416    */
3417
3418   HTMLFile.xdomainCheck = function () {
3419     // we can probably do handling for sub-domains, we should
3420     // test that it's cross domain but a subdomain here
3421     return false;
3422   };
3423
3424   /**
3425    * Add the transport to your public io.transports array.
3426    *
3427    * @api private
3428    */
3429
3430   io.transports.push('htmlfile');
3431
3432 })(
3433     'undefined' != typeof io ? io.Transport : module.exports
3434   , 'undefined' != typeof io ? io : module.parent.exports
3435 );
3436
3437 /**
3438  * socket.io
3439  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
3440  * MIT Licensed
3441  */
3442
3443 (function (exports, io, global) {
3444
3445   /**
3446    * Expose constructor.
3447    */
3448
3449   exports['xhr-polling'] = XHRPolling;
3450
3451   /**
3452    * The XHR-polling transport uses long polling XHR requests to create a
3453    * "persistent" connection with the server.
3454    *
3455    * @constructor
3456    * @api public
3457    */
3458
3459   function XHRPolling () {
3460     io.Transport.XHR.apply(this, arguments);
3461   };
3462
3463   /**
3464    * Inherits from XHR transport.
3465    */
3466
3467   io.util.inherit(XHRPolling, io.Transport.XHR);
3468
3469   /**
3470    * Merge the properties from XHR transport
3471    */
3472
3473   io.util.merge(XHRPolling, io.Transport.XHR);
3474
3475   /**
3476    * Transport name
3477    *
3478    * @api public
3479    */
3480
3481   XHRPolling.prototype.name = 'xhr-polling';
3482
3483   /**
3484    * Indicates whether heartbeats is enabled for this transport
3485    *
3486    * @api private
3487    */
3488
3489   XHRPolling.prototype.heartbeats = function () {
3490     return false;
3491   };
3492
3493   /** 
3494    * Establish a connection, for iPhone and Android this will be done once the page
3495    * is loaded.
3496    *
3497    * @returns {Transport} Chaining.
3498    * @api public
3499    */
3500
3501   XHRPolling.prototype.open = function () {
3502     var self = this;
3503
3504     io.Transport.XHR.prototype.open.call(self);
3505     return false;
3506   };
3507
3508   /**
3509    * Starts a XHR request to wait for incoming messages.
3510    *
3511    * @api private
3512    */
3513
3514   function empty () {};
3515
3516   XHRPolling.prototype.get = function () {
3517     if (!this.isOpen) return;
3518
3519     var self = this;
3520
3521     function stateChange () {
3522       if (this.readyState == 4) {
3523         this.onreadystatechange = empty;
3524
3525         if (this.status == 200) {
3526           self.onData(this.responseText);
3527           self.get();
3528         } else {
3529           self.onClose();
3530         }
3531       }
3532     };
3533
3534     function onload () {
3535       this.onload = empty;
3536       this.onerror = empty;
3537       self.retryCounter = 1;
3538       self.onData(this.responseText);
3539       self.get();
3540     };
3541
3542     function onerror () {
3543       self.retryCounter ++;
3544       if(!self.retryCounter || self.retryCounter > 3) {
3545         self.onClose();  
3546       } else {
3547         self.get();
3548       }
3549     };
3550
3551     this.xhr = this.request();
3552
3553     if (global.XDomainRequest && this.xhr instanceof XDomainRequest) {
3554       this.xhr.onload = onload;
3555       this.xhr.onerror = onerror;
3556     } else {
3557       this.xhr.onreadystatechange = stateChange;
3558     }
3559
3560     this.xhr.send(null);
3561   };
3562
3563   /**
3564    * Handle the unclean close behavior.
3565    *
3566    * @api private
3567    */
3568
3569   XHRPolling.prototype.onClose = function () {
3570     io.Transport.XHR.prototype.onClose.call(this);
3571
3572     if (this.xhr) {
3573       this.xhr.onreadystatechange = this.xhr.onload = this.xhr.onerror = empty;
3574       try {
3575         this.xhr.abort();
3576       } catch(e){}
3577       this.xhr = null;
3578     }
3579   };
3580
3581   /**
3582    * Webkit based browsers show a infinit spinner when you start a XHR request
3583    * before the browsers onload event is called so we need to defer opening of
3584    * the transport until the onload event is called. Wrapping the cb in our
3585    * defer method solve this.
3586    *
3587    * @param {Socket} socket The socket instance that needs a transport
3588    * @param {Function} fn The callback
3589    * @api private
3590    */
3591
3592   XHRPolling.prototype.ready = function (socket, fn) {
3593     var self = this;
3594
3595     io.util.defer(function () {
3596       fn.call(self);
3597     });
3598   };
3599
3600   /**
3601    * Add the transport to your public io.transports array.
3602    *
3603    * @api private
3604    */
3605
3606   io.transports.push('xhr-polling');
3607
3608 })(
3609     'undefined' != typeof io ? io.Transport : module.exports
3610   , 'undefined' != typeof io ? io : module.parent.exports
3611   , this
3612 );
3613
3614 /**
3615  * socket.io
3616  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
3617  * MIT Licensed
3618  */
3619
3620 (function (exports, io, global) {
3621   /**
3622    * There is a way to hide the loading indicator in Firefox. If you create and
3623    * remove a iframe it will stop showing the current loading indicator.
3624    * Unfortunately we can't feature detect that and UA sniffing is evil.
3625    *
3626    * @api private
3627    */
3628
3629   var indicator = global.document && "MozAppearance" in
3630     global.document.documentElement.style;
3631
3632   /**
3633    * Expose constructor.
3634    */
3635
3636   exports['jsonp-polling'] = JSONPPolling;
3637
3638   /**
3639    * The JSONP transport creates an persistent connection by dynamically
3640    * inserting a script tag in the page. This script tag will receive the
3641    * information of the Socket.IO server. When new information is received
3642    * it creates a new script tag for the new data stream.
3643    *
3644    * @constructor
3645    * @extends {io.Transport.xhr-polling}
3646    * @api public
3647    */
3648
3649   function JSONPPolling (socket) {
3650     io.Transport['xhr-polling'].apply(this, arguments);
3651
3652     this.index = io.j.length;
3653
3654     var self = this;
3655
3656     io.j.push(function (msg) {
3657       self._(msg);
3658     });
3659   };
3660
3661   /**
3662    * Inherits from XHR polling transport.
3663    */
3664
3665   io.util.inherit(JSONPPolling, io.Transport['xhr-polling']);
3666
3667   /**
3668    * Transport name
3669    *
3670    * @api public
3671    */
3672
3673   JSONPPolling.prototype.name = 'jsonp-polling';
3674
3675   /**
3676    * Posts a encoded message to the Socket.IO server using an iframe.
3677    * The iframe is used because script tags can create POST based requests.
3678    * The iframe is positioned outside of the view so the user does not
3679    * notice it's existence.
3680    *
3681    * @param {String} data A encoded message.
3682    * @api private
3683    */
3684
3685   JSONPPolling.prototype.post = function (data) {
3686     var self = this
3687       , query = io.util.query(
3688              this.socket.options.query
3689           , 't='+ (+new Date) + '&i=' + this.index
3690         );
3691
3692     if (!this.form) {
3693       var form = document.createElement('form')
3694         , area = document.createElement('textarea')
3695         , id = this.iframeId = 'socketio_iframe_' + this.index
3696         , iframe;
3697
3698       form.className = 'socketio';
3699       form.style.position = 'absolute';
3700       form.style.top = '0px';
3701       form.style.left = '0px';
3702       form.style.display = 'none';
3703       form.target = id;
3704       form.method = 'POST';
3705       form.setAttribute('accept-charset', 'utf-8');
3706       area.name = 'd';
3707       form.appendChild(area);
3708       document.body.appendChild(form);
3709
3710       this.form = form;
3711       this.area = area;
3712     }
3713
3714     this.form.action = this.prepareUrl() + query;
3715
3716     function complete () {
3717       initIframe();
3718       self.socket.setBuffer(false);
3719     };
3720
3721     function initIframe () {
3722       if (self.iframe) {
3723         self.form.removeChild(self.iframe);
3724       }
3725
3726       try {
3727         // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
3728         iframe = document.createElement('<iframe name="'+ self.iframeId +'">');
3729       } catch (e) {
3730         iframe = document.createElement('iframe');
3731         iframe.name = self.iframeId;
3732       }
3733
3734       iframe.id = self.iframeId;
3735
3736       self.form.appendChild(iframe);
3737       self.iframe = iframe;
3738     };
3739
3740     initIframe();
3741
3742     // we temporarily stringify until we figure out how to prevent
3743     // browsers from turning `\n` into `\r\n` in form inputs
3744     this.area.value = io.JSON.stringify(data);
3745
3746     try {
3747       this.form.submit();
3748     } catch(e) {}
3749
3750     if (this.iframe.attachEvent) {
3751       iframe.onreadystatechange = function () {
3752         if (self.iframe.readyState == 'complete') {
3753           complete();
3754         }
3755       };
3756     } else {
3757       this.iframe.onload = complete;
3758     }
3759
3760     this.socket.setBuffer(true);
3761   };
3762
3763   /**
3764    * Creates a new JSONP poll that can be used to listen
3765    * for messages from the Socket.IO server.
3766    *
3767    * @api private
3768    */
3769
3770   JSONPPolling.prototype.get = function () {
3771     var self = this
3772       , script = document.createElement('script')
3773       , query = io.util.query(
3774              this.socket.options.query
3775           , 't='+ (+new Date) + '&i=' + this.index
3776         );
3777
3778     if (this.script) {
3779       this.script.parentNode.removeChild(this.script);
3780       this.script = null;
3781     }
3782
3783     script.async = true;
3784     script.src = this.prepareUrl() + query;
3785     script.onerror = function () {
3786       self.onClose();
3787     };
3788
3789     var insertAt = document.getElementsByTagName('script')[0];
3790     insertAt.parentNode.insertBefore(script, insertAt);
3791     this.script = script;
3792
3793     if (indicator) {
3794       setTimeout(function () {
3795         var iframe = document.createElement('iframe');
3796         document.body.appendChild(iframe);
3797         document.body.removeChild(iframe);
3798       }, 100);
3799     }
3800   };
3801
3802   /**
3803    * Callback function for the incoming message stream from the Socket.IO server.
3804    *
3805    * @param {String} data The message
3806    * @api private
3807    */
3808
3809   JSONPPolling.prototype._ = function (msg) {
3810     this.onData(msg);
3811     if (this.isOpen) {
3812       this.get();
3813     }
3814     return this;
3815   };
3816
3817   /**
3818    * The indicator hack only works after onload
3819    *
3820    * @param {Socket} socket The socket instance that needs a transport
3821    * @param {Function} fn The callback
3822    * @api private
3823    */
3824
3825   JSONPPolling.prototype.ready = function (socket, fn) {
3826     var self = this;
3827     if (!indicator) return fn.call(this);
3828
3829     io.util.load(function () {
3830       fn.call(self);
3831     });
3832   };
3833
3834   /**
3835    * Checks if browser supports this transport.
3836    *
3837    * @return {Boolean}
3838    * @api public
3839    */
3840
3841   JSONPPolling.check = function () {
3842     return 'document' in global;
3843   };
3844
3845   /**
3846    * Check if cross domain requests are supported
3847    *
3848    * @returns {Boolean}
3849    * @api public
3850    */
3851
3852   JSONPPolling.xdomainCheck = function () {
3853     return true;
3854   };
3855
3856   /**
3857    * Add the transport to your public io.transports array.
3858    *
3859    * @api private
3860    */
3861
3862   io.transports.push('jsonp-polling');
3863
3864 })(
3865     'undefined' != typeof io ? io.Transport : module.exports
3866   , 'undefined' != typeof io ? io : module.parent.exports
3867   , this
3868 );
3869
3870 if (typeof define === "function" && define.amd) {
3871   define([], function () { return io; });
3872 }
3873 })();