3 * (c) 2014-2019 Guillermo Rauch
4 * Released under the MIT License.
6 (function webpackUniversalModuleDefinition(root, factory) {
7 if(typeof exports === 'object' && typeof module === 'object')
8 module.exports = factory();
9 else if(typeof define === 'function' && define.amd)
11 else if(typeof exports === 'object')
12 exports["io"] = factory();
14 root["io"] = factory();
16 return /******/ (function(modules) { // webpackBootstrap
17 /******/ // The module cache
18 /******/ var installedModules = {};
20 /******/ // The require function
21 /******/ function __webpack_require__(moduleId) {
23 /******/ // Check if module is in cache
24 /******/ if(installedModules[moduleId])
25 /******/ return installedModules[moduleId].exports;
27 /******/ // Create a new module (and put it into the cache)
28 /******/ var module = installedModules[moduleId] = {
30 /******/ id: moduleId,
31 /******/ loaded: false
34 /******/ // Execute the module function
35 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
37 /******/ // Flag the module as loaded
38 /******/ module.loaded = true;
40 /******/ // Return the exports of the module
41 /******/ return module.exports;
45 /******/ // expose the modules object (__webpack_modules__)
46 /******/ __webpack_require__.m = modules;
48 /******/ // expose the module cache
49 /******/ __webpack_require__.c = installedModules;
51 /******/ // __webpack_public_path__
52 /******/ __webpack_require__.p = "";
54 /******/ // Load entry module and return exports
55 /******/ return __webpack_require__(0);
57 /************************************************************************/
60 /***/ (function(module, exports, __webpack_require__) {
64 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
67 * Module dependencies.
70 var url = __webpack_require__(1);
71 var parser = __webpack_require__(4);
72 var Manager = __webpack_require__(9);
73 var debug = __webpack_require__(3)('socket.io-client');
79 module.exports = exports = lookup;
85 var cache = exports.managers = {};
88 * Looks up an existing `Manager` for multiplexing.
89 * If the user summons:
91 * `io('http://localhost/a');`
92 * `io('http://localhost/b');`
94 * We reuse the existing instance based on same scheme/port/host,
95 * and we initialize sockets for each namespace.
100 function lookup(uri, opts) {
101 if ((typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) === 'object') {
108 var parsed = url(uri);
109 var source = parsed.source;
111 var path = parsed.path;
112 var sameNamespace = cache[id] && path in cache[id].nsps;
113 var newConnection = opts.forceNew || opts['force new connection'] || false === opts.multiplex || sameNamespace;
119 io = Manager(source, opts);
123 cache[id] = Manager(source, opts);
127 if (parsed.query && !opts.query) {
128 opts.query = parsed.query;
130 return io.socket(parsed.path, opts);
139 exports.protocol = parser.protocol;
144 * @param {String} uri
148 exports.connect = lookup;
151 * Expose constructors for standalone build.
156 exports.Manager = __webpack_require__(9);
157 exports.Socket = __webpack_require__(33);
161 /***/ (function(module, exports, __webpack_require__) {
166 * Module dependencies.
169 var parseuri = __webpack_require__(2);
170 var debug = __webpack_require__(3)('socket.io-client:url');
176 module.exports = url;
181 * @param {String} url
182 * @param {Object} An object meant to mimic window.location.
183 * Defaults to window.location.
187 function url(uri, loc) {
190 // default to window.location
191 loc = loc || typeof location !== 'undefined' && location;
192 if (null == uri) uri = loc.protocol + '//' + loc.host;
194 // relative path support
195 if ('string' === typeof uri) {
196 if ('/' === uri.charAt(0)) {
197 if ('/' === uri.charAt(1)) {
198 uri = loc.protocol + uri;
200 uri = loc.host + uri;
204 if (!/^(https?|wss?):\/\//.test(uri)) {
206 if ('undefined' !== typeof loc) {
207 uri = loc.protocol + '//' + uri;
209 uri = 'https://' + uri;
218 // make sure we treat `localhost:80` and `localhost` equally
220 if (/^(http|ws)$/.test(obj.protocol)) {
222 } else if (/^(http|ws)s$/.test(obj.protocol)) {
227 obj.path = obj.path || '/';
229 var ipv6 = obj.host.indexOf(':') !== -1;
230 var host = ipv6 ? '[' + obj.host + ']' : obj.host;
233 obj.id = obj.protocol + '://' + host + ':' + obj.port;
235 obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : ':' + obj.port);
242 /***/ (function(module, exports) {
247 * @author Steven Levithan <stevenlevithan.com> (MIT license)
251 var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
254 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
257 module.exports = function parseuri(str) {
259 b = str.indexOf('['),
260 e = str.indexOf(']');
262 if (b != -1 && e != -1) {
263 str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
266 var m = re.exec(str || ''),
271 uri[parts[i]] = m[i] || '';
274 if (b != -1 && e != -1) {
276 uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
277 uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
287 /***/ (function(module, exports) {
291 module.exports = function () {
292 return function () {};
297 /***/ (function(module, exports, __webpack_require__) {
301 * Module dependencies.
304 var debug = __webpack_require__(3)('socket.io-parser');
305 var Emitter = __webpack_require__(5);
306 var binary = __webpack_require__(6);
307 var isArray = __webpack_require__(7);
308 var isBuf = __webpack_require__(8);
316 exports.protocol = 4;
335 * Packet type `connect`.
343 * Packet type `disconnect`.
348 exports.DISCONNECT = 1;
351 * Packet type `event`.
367 * Packet type `error`.
375 * Packet type 'binary event'
380 exports.BINARY_EVENT = 5;
383 * Packet type `binary ack`. For acks with binary arguments.
388 exports.BINARY_ACK = 6;
391 * Encoder constructor.
396 exports.Encoder = Encoder;
399 * Decoder constructor.
404 exports.Decoder = Decoder;
407 * A socket.io Encoder instance
412 function Encoder() {}
414 var ERROR_PACKET = exports.ERROR + '"encode error"';
417 * Encode a packet as a single string if non-binary, or as a
418 * buffer sequence, depending on packet type.
420 * @param {Object} obj - packet object
421 * @param {Function} callback - function to handle encodings (likely engine.write)
422 * @return Calls callback with Array of encodings
426 Encoder.prototype.encode = function(obj, callback){
429 if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
430 encodeAsBinary(obj, callback);
432 var encoding = encodeAsString(obj);
433 callback([encoding]);
438 * Encode packet as string.
440 * @param {Object} packet
441 * @return {String} encoded
445 function encodeAsString(obj) {
448 var str = '' + obj.type;
450 // attachments if we have them
451 if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
452 str += obj.attachments + '-';
455 // if we have a namespace other than `/`
456 // we append it followed by a comma `,`
457 if (obj.nsp && '/' !== obj.nsp) {
458 str += obj.nsp + ',';
461 // immediately followed by the id
462 if (null != obj.id) {
467 if (null != obj.data) {
468 var payload = tryStringify(obj.data);
469 if (payload !== false) {
480 function tryStringify(str) {
482 return JSON.stringify(str);
489 * Encode packet as 'buffer sequence' by removing blobs, and
490 * deconstructing packet into object with placeholders and
493 * @param {Object} packet
494 * @return {Buffer} encoded
498 function encodeAsBinary(obj, callback) {
500 function writeEncoding(bloblessData) {
501 var deconstruction = binary.deconstructPacket(bloblessData);
502 var pack = encodeAsString(deconstruction.packet);
503 var buffers = deconstruction.buffers;
505 buffers.unshift(pack); // add packet info to beginning of data list
506 callback(buffers); // write all the buffers
509 binary.removeBlobs(obj, writeEncoding);
513 * A socket.io Decoder instance
515 * @return {Object} decoder
520 this.reconstructor = null;
524 * Mix in `Emitter` with Decoder.
527 Emitter(Decoder.prototype);
530 * Decodes an encoded packet string into packet JSON.
532 * @param {String} obj - encoded packet
533 * @return {Object} packet
537 Decoder.prototype.add = function(obj) {
539 if (typeof obj === 'string') {
540 packet = decodeString(obj);
541 if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json
542 this.reconstructor = new BinaryReconstructor(packet);
544 // no attachments, labeled binary but no binary data to follow
545 if (this.reconstructor.reconPack.attachments === 0) {
546 this.emit('decoded', packet);
548 } else { // non-binary full packet
549 this.emit('decoded', packet);
551 } else if (isBuf(obj) || obj.base64) { // raw binary data
552 if (!this.reconstructor) {
553 throw new Error('got binary data when not reconstructing a packet');
555 packet = this.reconstructor.takeBinaryData(obj);
556 if (packet) { // received final buffer
557 this.reconstructor = null;
558 this.emit('decoded', packet);
562 throw new Error('Unknown type: ' + obj);
567 * Decode a packet String (JSON data)
569 * @param {String} str
570 * @return {Object} packet
574 function decodeString(str) {
578 type: Number(str.charAt(0))
581 if (null == exports.types[p.type]) {
582 return error('unknown packet type ' + p.type);
585 // look up attachments if type binary
586 if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) {
588 while (str.charAt(++i) !== '-') {
589 buf += str.charAt(i);
590 if (i == str.length) break;
592 if (buf != Number(buf) || str.charAt(i) !== '-') {
593 throw new Error('Illegal attachments');
595 p.attachments = Number(buf);
598 // look up namespace (if any)
599 if ('/' === str.charAt(i + 1)) {
602 var c = str.charAt(i);
603 if (',' === c) break;
605 if (i === str.length) break;
612 var next = str.charAt(i + 1);
613 if ('' !== next && Number(next) == next) {
616 var c = str.charAt(i);
617 if (null == c || Number(c) != c) {
621 p.id += str.charAt(i);
622 if (i === str.length) break;
628 if (str.charAt(++i)) {
629 var payload = tryParse(str.substr(i));
630 var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload));
631 if (isPayloadValid) {
634 return error('invalid payload');
642 function tryParse(str) {
644 return JSON.parse(str);
651 * Deallocates a parser's resources
656 Decoder.prototype.destroy = function() {
657 if (this.reconstructor) {
658 this.reconstructor.finishedReconstruction();
663 * A manager of a binary event's 'buffer sequence'. Should
664 * be constructed whenever a packet of type BINARY_EVENT is
667 * @param {Object} packet
668 * @return {BinaryReconstructor} initialized reconstructor
672 function BinaryReconstructor(packet) {
673 this.reconPack = packet;
678 * Method to be called when binary data received from connection
679 * after a BINARY_EVENT packet.
681 * @param {Buffer | ArrayBuffer} binData - the raw binary data received
682 * @return {null | Object} returns null if more binary data is expected or
683 * a reconstructed packet object if all buffers have been received.
687 BinaryReconstructor.prototype.takeBinaryData = function(binData) {
688 this.buffers.push(binData);
689 if (this.buffers.length === this.reconPack.attachments) { // done with buffer list
690 var packet = binary.reconstructPacket(this.reconPack, this.buffers);
691 this.finishedReconstruction();
698 * Cleans up binary packet reconstruction variables.
703 BinaryReconstructor.prototype.finishedReconstruction = function() {
704 this.reconPack = null;
708 function error(msg) {
711 data: 'parser error: ' + msg
718 /***/ (function(module, exports, __webpack_require__) {
726 module.exports = Emitter;
730 * Initialize a new `Emitter`.
735 function Emitter(obj) {
736 if (obj) return mixin(obj);
740 * Mixin the emitter properties.
742 * @param {Object} obj
747 function mixin(obj) {
748 for (var key in Emitter.prototype) {
749 obj[key] = Emitter.prototype[key];
755 * Listen on the given `event` with `fn`.
757 * @param {String} event
758 * @param {Function} fn
763 Emitter.prototype.on =
764 Emitter.prototype.addEventListener = function(event, fn){
765 this._callbacks = this._callbacks || {};
766 (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
772 * Adds an `event` listener that will be invoked a single
773 * time then automatically removed.
775 * @param {String} event
776 * @param {Function} fn
781 Emitter.prototype.once = function(event, fn){
784 fn.apply(this, arguments);
793 * Remove the given callback for `event` or all
794 * registered callbacks.
796 * @param {String} event
797 * @param {Function} fn
802 Emitter.prototype.off =
803 Emitter.prototype.removeListener =
804 Emitter.prototype.removeAllListeners =
805 Emitter.prototype.removeEventListener = function(event, fn){
806 this._callbacks = this._callbacks || {};
809 if (0 == arguments.length) {
810 this._callbacks = {};
815 var callbacks = this._callbacks['$' + event];
816 if (!callbacks) return this;
818 // remove all handlers
819 if (1 == arguments.length) {
820 delete this._callbacks['$' + event];
824 // remove specific handler
826 for (var i = 0; i < callbacks.length; i++) {
828 if (cb === fn || cb.fn === fn) {
829 callbacks.splice(i, 1);
837 * Emit `event` with the given args.
839 * @param {String} event
844 Emitter.prototype.emit = function(event){
845 this._callbacks = this._callbacks || {};
846 var args = [].slice.call(arguments, 1)
847 , callbacks = this._callbacks['$' + event];
850 callbacks = callbacks.slice(0);
851 for (var i = 0, len = callbacks.length; i < len; ++i) {
852 callbacks[i].apply(this, args);
860 * Return array of callbacks for `event`.
862 * @param {String} event
867 Emitter.prototype.listeners = function(event){
868 this._callbacks = this._callbacks || {};
869 return this._callbacks['$' + event] || [];
873 * Check if this emitter has `event` handlers.
875 * @param {String} event
880 Emitter.prototype.hasListeners = function(event){
881 return !! this.listeners(event).length;
887 /***/ (function(module, exports, __webpack_require__) {
892 * Module requirements
895 var isArray = __webpack_require__(7);
896 var isBuf = __webpack_require__(8);
897 var toString = Object.prototype.toString;
898 var withNativeBlob = typeof Blob === 'function' || (typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]');
899 var withNativeFile = typeof File === 'function' || (typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]');
902 * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
903 * Anything with blobs or files should be fed through removeBlobs before coming
906 * @param {Object} packet - socket.io event packet
907 * @return {Object} with deconstructed packet and list of buffers
911 exports.deconstructPacket = function(packet) {
913 var packetData = packet.data;
915 pack.data = _deconstructPacket(packetData, buffers);
916 pack.attachments = buffers.length; // number of binary 'attachments'
917 return {packet: pack, buffers: buffers};
920 function _deconstructPacket(data, buffers) {
921 if (!data) return data;
924 var placeholder = { _placeholder: true, num: buffers.length };
927 } else if (isArray(data)) {
928 var newData = new Array(data.length);
929 for (var i = 0; i < data.length; i++) {
930 newData[i] = _deconstructPacket(data[i], buffers);
933 } else if (typeof data === 'object' && !(data instanceof Date)) {
935 for (var key in data) {
936 newData[key] = _deconstructPacket(data[key], buffers);
944 * Reconstructs a binary packet from its placeholder packet and buffers
946 * @param {Object} packet - event packet with placeholders
947 * @param {Array} buffers - binary buffers to put in placeholder positions
948 * @return {Object} reconstructed packet
952 exports.reconstructPacket = function(packet, buffers) {
953 packet.data = _reconstructPacket(packet.data, buffers);
954 packet.attachments = undefined; // no longer useful
958 function _reconstructPacket(data, buffers) {
959 if (!data) return data;
961 if (data && data._placeholder) {
962 return buffers[data.num]; // appropriate buffer (should be natural order anyway)
963 } else if (isArray(data)) {
964 for (var i = 0; i < data.length; i++) {
965 data[i] = _reconstructPacket(data[i], buffers);
967 } else if (typeof data === 'object') {
968 for (var key in data) {
969 data[key] = _reconstructPacket(data[key], buffers);
977 * Asynchronously removes Blobs or Files from data via
978 * FileReader's readAsArrayBuffer method. Used before encoding
979 * data as msgpack. Calls callback with the blobless data.
981 * @param {Object} data
982 * @param {Function} callback
986 exports.removeBlobs = function(data, callback) {
987 function _removeBlobs(obj, curKey, containingObject) {
988 if (!obj) return obj;
991 if ((withNativeBlob && obj instanceof Blob) ||
992 (withNativeFile && obj instanceof File)) {
996 var fileReader = new FileReader();
997 fileReader.onload = function() { // this.result == arraybuffer
998 if (containingObject) {
999 containingObject[curKey] = this.result;
1002 bloblessData = this.result;
1005 // if nothing pending its callback time
1006 if(! --pendingBlobs) {
1007 callback(bloblessData);
1011 fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
1012 } else if (isArray(obj)) { // handle array
1013 for (var i = 0; i < obj.length; i++) {
1014 _removeBlobs(obj[i], i, obj);
1016 } else if (typeof obj === 'object' && !isBuf(obj)) { // and object
1017 for (var key in obj) {
1018 _removeBlobs(obj[key], key, obj);
1023 var pendingBlobs = 0;
1024 var bloblessData = data;
1025 _removeBlobs(bloblessData);
1026 if (!pendingBlobs) {
1027 callback(bloblessData);
1034 /***/ (function(module, exports) {
1036 var toString = {}.toString;
1038 module.exports = Array.isArray || function (arr) {
1039 return toString.call(arr) == '[object Array]';
1045 /***/ (function(module, exports) {
1048 module.exports = isBuf;
1050 var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function';
1051 var withNativeArrayBuffer = typeof ArrayBuffer === 'function';
1053 var isView = function (obj) {
1054 return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : (obj.buffer instanceof ArrayBuffer);
1058 * Returns true if obj is a buffer or an arraybuffer.
1063 function isBuf(obj) {
1064 return (withNativeBuffer && Buffer.isBuffer(obj)) ||
1065 (withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)));
1071 /***/ (function(module, exports, __webpack_require__) {
1075 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
1078 * Module dependencies.
1081 var eio = __webpack_require__(10);
1082 var Socket = __webpack_require__(33);
1083 var Emitter = __webpack_require__(5);
1084 var parser = __webpack_require__(4);
1085 var on = __webpack_require__(35);
1086 var bind = __webpack_require__(36);
1087 var debug = __webpack_require__(3)('socket.io-client:manager');
1088 var indexOf = __webpack_require__(32);
1089 var Backoff = __webpack_require__(37);
1092 * IE6+ hasOwnProperty
1095 var has = Object.prototype.hasOwnProperty;
1101 module.exports = Manager;
1104 * `Manager` constructor.
1106 * @param {String} engine instance or engine uri/opts
1107 * @param {Object} options
1111 function Manager(uri, opts) {
1112 if (!(this instanceof Manager)) return new Manager(uri, opts);
1113 if (uri && 'object' === (typeof uri === 'undefined' ? 'undefined' : _typeof(uri))) {
1119 opts.path = opts.path || '/socket.io';
1123 this.reconnection(opts.reconnection !== false);
1124 this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
1125 this.reconnectionDelay(opts.reconnectionDelay || 1000);
1126 this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
1127 this.randomizationFactor(opts.randomizationFactor || 0.5);
1128 this.backoff = new Backoff({
1129 min: this.reconnectionDelay(),
1130 max: this.reconnectionDelayMax(),
1131 jitter: this.randomizationFactor()
1133 this.timeout(null == opts.timeout ? 20000 : opts.timeout);
1134 this.readyState = 'closed';
1136 this.connecting = [];
1137 this.lastPing = null;
1138 this.encoding = false;
1139 this.packetBuffer = [];
1140 var _parser = opts.parser || parser;
1141 this.encoder = new _parser.Encoder();
1142 this.decoder = new _parser.Decoder();
1143 this.autoConnect = opts.autoConnect !== false;
1144 if (this.autoConnect) this.open();
1148 * Propagate given event to sockets and emit on `this`
1153 Manager.prototype.emitAll = function () {
1154 this.emit.apply(this, arguments);
1155 for (var nsp in this.nsps) {
1156 if (has.call(this.nsps, nsp)) {
1157 this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
1163 * Update `socket.id` of all sockets
1168 Manager.prototype.updateSocketIds = function () {
1169 for (var nsp in this.nsps) {
1170 if (has.call(this.nsps, nsp)) {
1171 this.nsps[nsp].id = this.generateId(nsp);
1177 * generate `socket.id` for the given `nsp`
1179 * @param {String} nsp
1184 Manager.prototype.generateId = function (nsp) {
1185 return (nsp === '/' ? '' : nsp + '#') + this.engine.id;
1192 Emitter(Manager.prototype);
1195 * Sets the `reconnection` config.
1197 * @param {Boolean} true/false if it should automatically reconnect
1198 * @return {Manager} self or value
1202 Manager.prototype.reconnection = function (v) {
1203 if (!arguments.length) return this._reconnection;
1204 this._reconnection = !!v;
1209 * Sets the reconnection attempts config.
1211 * @param {Number} max reconnection attempts before giving up
1212 * @return {Manager} self or value
1216 Manager.prototype.reconnectionAttempts = function (v) {
1217 if (!arguments.length) return this._reconnectionAttempts;
1218 this._reconnectionAttempts = v;
1223 * Sets the delay between reconnections.
1225 * @param {Number} delay
1226 * @return {Manager} self or value
1230 Manager.prototype.reconnectionDelay = function (v) {
1231 if (!arguments.length) return this._reconnectionDelay;
1232 this._reconnectionDelay = v;
1233 this.backoff && this.backoff.setMin(v);
1237 Manager.prototype.randomizationFactor = function (v) {
1238 if (!arguments.length) return this._randomizationFactor;
1239 this._randomizationFactor = v;
1240 this.backoff && this.backoff.setJitter(v);
1245 * Sets the maximum delay between reconnections.
1247 * @param {Number} delay
1248 * @return {Manager} self or value
1252 Manager.prototype.reconnectionDelayMax = function (v) {
1253 if (!arguments.length) return this._reconnectionDelayMax;
1254 this._reconnectionDelayMax = v;
1255 this.backoff && this.backoff.setMax(v);
1260 * Sets the connection timeout. `false` to disable
1262 * @return {Manager} self or value
1266 Manager.prototype.timeout = function (v) {
1267 if (!arguments.length) return this._timeout;
1273 * Starts trying to reconnect if reconnection is enabled and we have not
1274 * started reconnecting yet
1279 Manager.prototype.maybeReconnectOnOpen = function () {
1280 // Only try to reconnect if it's the first time we're connecting
1281 if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {
1282 // keeps reconnection from firing twice for the same reconnection loop
1288 * Sets the current transport `socket`.
1290 * @param {Function} optional, callback
1291 * @return {Manager} self
1295 Manager.prototype.open = Manager.prototype.connect = function (fn, opts) {
1297 if (~this.readyState.indexOf('open')) return this;
1299 this.engine = eio(this.uri, this.opts);
1300 var socket = this.engine;
1302 this.readyState = 'opening';
1303 this.skipReconnect = false;
1306 var openSub = on(socket, 'open', function () {
1311 // emit `connect_error`
1312 var errorSub = on(socket, 'error', function (data) {
1315 self.readyState = 'closed';
1316 self.emitAll('connect_error', data);
1318 var err = new Error('Connection error');
1322 // Only do this if there is no fn to handle the error
1323 self.maybeReconnectOnOpen();
1327 // emit `connect_timeout`
1328 if (false !== this._timeout) {
1329 var timeout = this._timeout;
1332 var timer = setTimeout(function () {
1336 socket.emit('error', 'timeout');
1337 self.emitAll('connect_timeout', timeout);
1341 destroy: function destroy() {
1342 clearTimeout(timer);
1347 this.subs.push(openSub);
1348 this.subs.push(errorSub);
1354 * Called upon transport open.
1359 Manager.prototype.onopen = function () {
1365 this.readyState = 'open';
1369 var socket = this.engine;
1370 this.subs.push(on(socket, 'data', bind(this, 'ondata')));
1371 this.subs.push(on(socket, 'ping', bind(this, 'onping')));
1372 this.subs.push(on(socket, 'pong', bind(this, 'onpong')));
1373 this.subs.push(on(socket, 'error', bind(this, 'onerror')));
1374 this.subs.push(on(socket, 'close', bind(this, 'onclose')));
1375 this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
1379 * Called upon a ping.
1384 Manager.prototype.onping = function () {
1385 this.lastPing = new Date();
1386 this.emitAll('ping');
1390 * Called upon a packet.
1395 Manager.prototype.onpong = function () {
1396 this.emitAll('pong', new Date() - this.lastPing);
1405 Manager.prototype.ondata = function (data) {
1406 this.decoder.add(data);
1410 * Called when parser fully decodes a packet.
1415 Manager.prototype.ondecoded = function (packet) {
1416 this.emit('packet', packet);
1420 * Called upon socket error.
1425 Manager.prototype.onerror = function (err) {
1427 this.emitAll('error', err);
1431 * Creates a new socket for the given `nsp`.
1437 Manager.prototype.socket = function (nsp, opts) {
1438 var socket = this.nsps[nsp];
1440 socket = new Socket(this, nsp, opts);
1441 this.nsps[nsp] = socket;
1443 socket.on('connecting', onConnecting);
1444 socket.on('connect', function () {
1445 socket.id = self.generateId(nsp);
1448 if (this.autoConnect) {
1449 // manually call here since connecting event is fired before listening
1454 function onConnecting() {
1455 if (!~indexOf(self.connecting, socket)) {
1456 self.connecting.push(socket);
1464 * Called upon a socket close.
1466 * @param {Socket} socket
1469 Manager.prototype.destroy = function (socket) {
1470 var index = indexOf(this.connecting, socket);
1471 if (~index) this.connecting.splice(index, 1);
1472 if (this.connecting.length) return;
1480 * @param {Object} packet
1484 Manager.prototype.packet = function (packet) {
1487 if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;
1489 if (!self.encoding) {
1490 // encode, then write to engine with result
1491 self.encoding = true;
1492 this.encoder.encode(packet, function (encodedPackets) {
1493 for (var i = 0; i < encodedPackets.length; i++) {
1494 self.engine.write(encodedPackets[i], packet.options);
1496 self.encoding = false;
1497 self.processPacketQueue();
1500 // add packet to the queue
1501 self.packetBuffer.push(packet);
1506 * If packet buffer is non-empty, begins encoding the
1507 * next packet in line.
1512 Manager.prototype.processPacketQueue = function () {
1513 if (this.packetBuffer.length > 0 && !this.encoding) {
1514 var pack = this.packetBuffer.shift();
1520 * Clean up transport subscriptions and packet buffer.
1525 Manager.prototype.cleanup = function () {
1527 var subsLength = this.subs.length;
1528 for (var i = 0; i < subsLength; i++) {
1529 var sub = this.subs.shift();
1533 this.packetBuffer = [];
1534 this.encoding = false;
1535 this.lastPing = null;
1537 this.decoder.destroy();
1541 * Close the current socket.
1546 Manager.prototype.close = Manager.prototype.disconnect = function () {
1548 this.skipReconnect = true;
1549 this.reconnecting = false;
1550 if ('opening' === this.readyState) {
1551 // `onclose` will not fire because
1552 // an open event never happened
1555 this.backoff.reset();
1556 this.readyState = 'closed';
1557 if (this.engine) this.engine.close();
1561 * Called upon engine close.
1566 Manager.prototype.onclose = function (reason) {
1569 this.backoff.reset();
1570 this.readyState = 'closed';
1571 this.emit('close', reason);
1573 if (this._reconnection && !this.skipReconnect) {
1579 * Attempt a reconnection.
1584 Manager.prototype.reconnect = function () {
1585 if (this.reconnecting || this.skipReconnect) return this;
1589 if (this.backoff.attempts >= this._reconnectionAttempts) {
1591 this.backoff.reset();
1592 this.emitAll('reconnect_failed');
1593 this.reconnecting = false;
1595 var delay = this.backoff.duration();
1597 this.reconnecting = true;
1598 var timer = setTimeout(function () {
1599 if (self.skipReconnect) return;
1601 self.emitAll('reconnect_attempt', self.backoff.attempts);
1602 self.emitAll('reconnecting', self.backoff.attempts);
1604 // check again for the case socket closed in above events
1605 if (self.skipReconnect) return;
1607 self.open(function (err) {
1610 self.reconnecting = false;
1612 self.emitAll('reconnect_error', err.data);
1621 destroy: function destroy() {
1622 clearTimeout(timer);
1629 * Called upon successful reconnect.
1634 Manager.prototype.onreconnect = function () {
1635 var attempt = this.backoff.attempts;
1636 this.reconnecting = false;
1637 this.backoff.reset();
1638 this.updateSocketIds();
1639 this.emitAll('reconnect', attempt);
1644 /***/ (function(module, exports, __webpack_require__) {
1647 module.exports = __webpack_require__(11);
1655 module.exports.parser = __webpack_require__(18);
1660 /***/ (function(module, exports, __webpack_require__) {
1663 * Module dependencies.
1666 var transports = __webpack_require__(12);
1667 var Emitter = __webpack_require__(5);
1668 var debug = __webpack_require__(3)('engine.io-client:socket');
1669 var index = __webpack_require__(32);
1670 var parser = __webpack_require__(18);
1671 var parseuri = __webpack_require__(2);
1672 var parseqs = __webpack_require__(26);
1678 module.exports = Socket;
1681 * Socket constructor.
1683 * @param {String|Object} uri or options
1684 * @param {Object} options
1688 function Socket (uri, opts) {
1689 if (!(this instanceof Socket)) return new Socket(uri, opts);
1693 if (uri && 'object' === typeof uri) {
1699 uri = parseuri(uri);
1700 opts.hostname = uri.host;
1701 opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';
1702 opts.port = uri.port;
1703 if (uri.query) opts.query = uri.query;
1704 } else if (opts.host) {
1705 opts.hostname = parseuri(opts.host).host;
1708 this.secure = null != opts.secure ? opts.secure
1709 : (typeof location !== 'undefined' && 'https:' === location.protocol);
1711 if (opts.hostname && !opts.port) {
1712 // if no port is specified manually, use the protocol default
1713 opts.port = this.secure ? '443' : '80';
1716 this.agent = opts.agent || false;
1717 this.hostname = opts.hostname ||
1718 (typeof location !== 'undefined' ? location.hostname : 'localhost');
1719 this.port = opts.port || (typeof location !== 'undefined' && location.port
1721 : (this.secure ? 443 : 80));
1722 this.query = opts.query || {};
1723 if ('string' === typeof this.query) this.query = parseqs.decode(this.query);
1724 this.upgrade = false !== opts.upgrade;
1725 this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
1726 this.forceJSONP = !!opts.forceJSONP;
1727 this.jsonp = false !== opts.jsonp;
1728 this.forceBase64 = !!opts.forceBase64;
1729 this.enablesXDR = !!opts.enablesXDR;
1730 this.withCredentials = false !== opts.withCredentials;
1731 this.timestampParam = opts.timestampParam || 't';
1732 this.timestampRequests = opts.timestampRequests;
1733 this.transports = opts.transports || ['polling', 'websocket'];
1734 this.transportOptions = opts.transportOptions || {};
1735 this.readyState = '';
1736 this.writeBuffer = [];
1737 this.prevBufferLen = 0;
1738 this.policyPort = opts.policyPort || 843;
1739 this.rememberUpgrade = opts.rememberUpgrade || false;
1740 this.binaryType = null;
1741 this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
1742 this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;
1744 if (true === this.perMessageDeflate) this.perMessageDeflate = {};
1745 if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {
1746 this.perMessageDeflate.threshold = 1024;
1749 // SSL options for Node.js client
1750 this.pfx = opts.pfx || null;
1751 this.key = opts.key || null;
1752 this.passphrase = opts.passphrase || null;
1753 this.cert = opts.cert || null;
1754 this.ca = opts.ca || null;
1755 this.ciphers = opts.ciphers || null;
1756 this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? true : opts.rejectUnauthorized;
1757 this.forceNode = !!opts.forceNode;
1759 // detect ReactNative environment
1760 this.isReactNative = (typeof navigator !== 'undefined' && typeof navigator.product === 'string' && navigator.product.toLowerCase() === 'reactnative');
1762 // other options for Node.js or ReactNative client
1763 if (typeof self === 'undefined' || this.isReactNative) {
1764 if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {
1765 this.extraHeaders = opts.extraHeaders;
1768 if (opts.localAddress) {
1769 this.localAddress = opts.localAddress;
1775 this.upgrades = null;
1776 this.pingInterval = null;
1777 this.pingTimeout = null;
1780 this.pingIntervalTimer = null;
1781 this.pingTimeoutTimer = null;
1786 Socket.priorWebsocketSuccess = false;
1792 Emitter(Socket.prototype);
1800 Socket.protocol = parser.protocol; // this is an int
1803 * Expose deps for legacy compatibility
1804 * and standalone browser access.
1807 Socket.Socket = Socket;
1808 Socket.Transport = __webpack_require__(17);
1809 Socket.transports = __webpack_require__(12);
1810 Socket.parser = __webpack_require__(18);
1813 * Creates transport of the given type.
1815 * @param {String} transport name
1816 * @return {Transport}
1820 Socket.prototype.createTransport = function (name) {
1822 var query = clone(this.query);
1824 // append engine.io protocol identifier
1825 query.EIO = parser.protocol;
1828 query.transport = name;
1830 // per-transport options
1831 var options = this.transportOptions[name] || {};
1833 // session id if we already have one
1834 if (this.id) query.sid = this.id;
1836 var transport = new transports[name]({
1839 agent: options.agent || this.agent,
1840 hostname: options.hostname || this.hostname,
1841 port: options.port || this.port,
1842 secure: options.secure || this.secure,
1843 path: options.path || this.path,
1844 forceJSONP: options.forceJSONP || this.forceJSONP,
1845 jsonp: options.jsonp || this.jsonp,
1846 forceBase64: options.forceBase64 || this.forceBase64,
1847 enablesXDR: options.enablesXDR || this.enablesXDR,
1848 withCredentials: options.withCredentials || this.withCredentials,
1849 timestampRequests: options.timestampRequests || this.timestampRequests,
1850 timestampParam: options.timestampParam || this.timestampParam,
1851 policyPort: options.policyPort || this.policyPort,
1852 pfx: options.pfx || this.pfx,
1853 key: options.key || this.key,
1854 passphrase: options.passphrase || this.passphrase,
1855 cert: options.cert || this.cert,
1856 ca: options.ca || this.ca,
1857 ciphers: options.ciphers || this.ciphers,
1858 rejectUnauthorized: options.rejectUnauthorized || this.rejectUnauthorized,
1859 perMessageDeflate: options.perMessageDeflate || this.perMessageDeflate,
1860 extraHeaders: options.extraHeaders || this.extraHeaders,
1861 forceNode: options.forceNode || this.forceNode,
1862 localAddress: options.localAddress || this.localAddress,
1863 requestTimeout: options.requestTimeout || this.requestTimeout,
1864 protocols: options.protocols || void (0),
1865 isReactNative: this.isReactNative
1871 function clone (obj) {
1873 for (var i in obj) {
1874 if (obj.hasOwnProperty(i)) {
1882 * Initializes transport to use and starts probe.
1886 Socket.prototype.open = function () {
1888 if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {
1889 transport = 'websocket';
1890 } else if (0 === this.transports.length) {
1891 // Emit error on next tick so it can be listened to
1893 setTimeout(function () {
1894 self.emit('error', 'No transports available');
1898 transport = this.transports[0];
1900 this.readyState = 'opening';
1902 // Retry with the next transport if the transport is disabled (jsonp: false)
1904 transport = this.createTransport(transport);
1906 this.transports.shift();
1912 this.setTransport(transport);
1916 * Sets the current transport. Disables the existing one (if any).
1921 Socket.prototype.setTransport = function (transport) {
1925 if (this.transport) {
1927 this.transport.removeAllListeners();
1931 this.transport = transport;
1933 // set up transport listeners
1935 .on('drain', function () {
1938 .on('packet', function (packet) {
1939 self.onPacket(packet);
1941 .on('error', function (e) {
1944 .on('close', function () {
1945 self.onClose('transport close');
1950 * Probes a transport.
1952 * @param {String} transport name
1956 Socket.prototype.probe = function (name) {
1958 var transport = this.createTransport(name, { probe: 1 });
1962 Socket.priorWebsocketSuccess = false;
1964 function onTransportOpen () {
1965 if (self.onlyBinaryUpgrades) {
1966 var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
1967 failed = failed || upgradeLosesBinary;
1972 transport.send([{ type: 'ping', data: 'probe' }]);
1973 transport.once('packet', function (msg) {
1975 if ('pong' === msg.type && 'probe' === msg.data) {
1977 self.upgrading = true;
1978 self.emit('upgrading', transport);
1979 if (!transport) return;
1980 Socket.priorWebsocketSuccess = 'websocket' === transport.name;
1983 self.transport.pause(function () {
1985 if ('closed' === self.readyState) return;
1990 self.setTransport(transport);
1991 transport.send([{ type: 'upgrade' }]);
1992 self.emit('upgrade', transport);
1994 self.upgrading = false;
1999 var err = new Error('probe error');
2000 err.transport = transport.name;
2001 self.emit('upgradeError', err);
2006 function freezeTransport () {
2009 // Any callback called by transport should be ignored since now
2018 // Handle any error that happens while probing
2019 function onerror (err) {
2020 var error = new Error('probe error: ' + err);
2021 error.transport = transport.name;
2027 self.emit('upgradeError', error);
2030 function onTransportClose () {
2031 onerror('transport closed');
2034 // When the socket is closed while we're probing
2035 function onclose () {
2036 onerror('socket closed');
2039 // When the socket is upgraded while we're probing
2040 function onupgrade (to) {
2041 if (transport && to.name !== transport.name) {
2047 // Remove all listeners on the transport and on self
2048 function cleanup () {
2049 transport.removeListener('open', onTransportOpen);
2050 transport.removeListener('error', onerror);
2051 transport.removeListener('close', onTransportClose);
2052 self.removeListener('close', onclose);
2053 self.removeListener('upgrading', onupgrade);
2056 transport.once('open', onTransportOpen);
2057 transport.once('error', onerror);
2058 transport.once('close', onTransportClose);
2060 this.once('close', onclose);
2061 this.once('upgrading', onupgrade);
2067 * Called when connection is deemed open.
2072 Socket.prototype.onOpen = function () {
2074 this.readyState = 'open';
2075 Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;
2079 // we check for `readyState` in case an `open`
2080 // listener already closed the socket
2081 if ('open' === this.readyState && this.upgrade && this.transport.pause) {
2083 for (var i = 0, l = this.upgrades.length; i < l; i++) {
2084 this.probe(this.upgrades[i]);
2095 Socket.prototype.onPacket = function (packet) {
2096 if ('opening' === this.readyState || 'open' === this.readyState ||
2097 'closing' === this.readyState) {
2100 this.emit('packet', packet);
2102 // Socket is live - any packet counts
2103 this.emit('heartbeat');
2105 switch (packet.type) {
2107 this.onHandshake(JSON.parse(packet.data));
2116 var err = new Error('server error');
2117 err.code = packet.data;
2122 this.emit('data', packet.data);
2123 this.emit('message', packet.data);
2132 * Called upon handshake completion.
2134 * @param {Object} handshake obj
2138 Socket.prototype.onHandshake = function (data) {
2139 this.emit('handshake', data);
2141 this.transport.query.sid = data.sid;
2142 this.upgrades = this.filterUpgrades(data.upgrades);
2143 this.pingInterval = data.pingInterval;
2144 this.pingTimeout = data.pingTimeout;
2146 // In case open handler closes socket
2147 if ('closed' === this.readyState) return;
2150 // Prolong liveness of socket on heartbeat
2151 this.removeListener('heartbeat', this.onHeartbeat);
2152 this.on('heartbeat', this.onHeartbeat);
2156 * Resets ping timeout.
2161 Socket.prototype.onHeartbeat = function (timeout) {
2162 clearTimeout(this.pingTimeoutTimer);
2164 self.pingTimeoutTimer = setTimeout(function () {
2165 if ('closed' === self.readyState) return;
2166 self.onClose('ping timeout');
2167 }, timeout || (self.pingInterval + self.pingTimeout));
2171 * Pings server every `this.pingInterval` and expects response
2172 * within `this.pingTimeout` or closes connection.
2177 Socket.prototype.setPing = function () {
2179 clearTimeout(self.pingIntervalTimer);
2180 self.pingIntervalTimer = setTimeout(function () {
2183 self.onHeartbeat(self.pingTimeout);
2184 }, self.pingInterval);
2188 * Sends a ping packet.
2193 Socket.prototype.ping = function () {
2195 this.sendPacket('ping', function () {
2201 * Called on `drain` event
2206 Socket.prototype.onDrain = function () {
2207 this.writeBuffer.splice(0, this.prevBufferLen);
2209 // setting prevBufferLen = 0 is very important
2210 // for example, when upgrading, upgrade packet is sent over,
2211 // and a nonzero prevBufferLen could cause problems on `drain`
2212 this.prevBufferLen = 0;
2214 if (0 === this.writeBuffer.length) {
2222 * Flush write buffers.
2227 Socket.prototype.flush = function () {
2228 if ('closed' !== this.readyState && this.transport.writable &&
2229 !this.upgrading && this.writeBuffer.length) {
2231 this.transport.send(this.writeBuffer);
2232 // keep track of current length of writeBuffer
2233 // splice writeBuffer and callbackBuffer on `drain`
2234 this.prevBufferLen = this.writeBuffer.length;
2242 * @param {String} message.
2243 * @param {Function} callback function.
2244 * @param {Object} options.
2245 * @return {Socket} for chaining.
2249 Socket.prototype.write =
2250 Socket.prototype.send = function (msg, options, fn) {
2251 this.sendPacket('message', msg, options, fn);
2258 * @param {String} packet type.
2259 * @param {String} data.
2260 * @param {Object} options.
2261 * @param {Function} callback function.
2265 Socket.prototype.sendPacket = function (type, data, options, fn) {
2266 if ('function' === typeof data) {
2271 if ('function' === typeof options) {
2276 if ('closing' === this.readyState || 'closed' === this.readyState) {
2280 options = options || {};
2281 options.compress = false !== options.compress;
2288 this.emit('packetCreate', packet);
2289 this.writeBuffer.push(packet);
2290 if (fn) this.once('flush', fn);
2295 * Closes the connection.
2300 Socket.prototype.close = function () {
2301 if ('opening' === this.readyState || 'open' === this.readyState) {
2302 this.readyState = 'closing';
2306 if (this.writeBuffer.length) {
2307 this.once('drain', function () {
2308 if (this.upgrading) {
2314 } else if (this.upgrading) {
2322 self.onClose('forced close');
2324 self.transport.close();
2327 function cleanupAndClose () {
2328 self.removeListener('upgrade', cleanupAndClose);
2329 self.removeListener('upgradeError', cleanupAndClose);
2333 function waitForUpgrade () {
2334 // wait for upgrade to finish since we can't send packets while pausing a transport
2335 self.once('upgrade', cleanupAndClose);
2336 self.once('upgradeError', cleanupAndClose);
2343 * Called upon transport error
2348 Socket.prototype.onError = function (err) {
2350 Socket.priorWebsocketSuccess = false;
2351 this.emit('error', err);
2352 this.onClose('transport error', err);
2356 * Called upon transport close.
2361 Socket.prototype.onClose = function (reason, desc) {
2362 if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {
2367 clearTimeout(this.pingIntervalTimer);
2368 clearTimeout(this.pingTimeoutTimer);
2370 // stop event from firing again for transport
2371 this.transport.removeAllListeners('close');
2373 // ensure transport won't stay open
2374 this.transport.close();
2376 // ignore further transport communication
2377 this.transport.removeAllListeners();
2380 this.readyState = 'closed';
2386 this.emit('close', reason, desc);
2388 // clean buffers after, so users can still
2389 // grab the buffers on `close` event
2390 self.writeBuffer = [];
2391 self.prevBufferLen = 0;
2396 * Filters upgrades, returning only those matching client transports.
2398 * @param {Array} server upgrades
2403 Socket.prototype.filterUpgrades = function (upgrades) {
2404 var filteredUpgrades = [];
2405 for (var i = 0, j = upgrades.length; i < j; i++) {
2406 if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
2408 return filteredUpgrades;
2414 /***/ (function(module, exports, __webpack_require__) {
2417 * Module dependencies
2420 var XMLHttpRequest = __webpack_require__(13);
2421 var XHR = __webpack_require__(15);
2422 var JSONP = __webpack_require__(29);
2423 var websocket = __webpack_require__(30);
2426 * Export transports.
2429 exports.polling = polling;
2430 exports.websocket = websocket;
2433 * Polling transport polymorphic constructor.
2434 * Decides on xhr vs jsonp based on feature detection.
2439 function polling (opts) {
2443 var jsonp = false !== opts.jsonp;
2445 if (typeof location !== 'undefined') {
2446 var isSSL = 'https:' === location.protocol;
2447 var port = location.port;
2449 // some user agents have empty `location.port`
2451 port = isSSL ? 443 : 80;
2454 xd = opts.hostname !== location.hostname || port !== opts.port;
2455 xs = opts.secure !== isSSL;
2460 xhr = new XMLHttpRequest(opts);
2462 if ('open' in xhr && !opts.forceJSONP) {
2463 return new XHR(opts);
2465 if (!jsonp) throw new Error('JSONP disabled');
2466 return new JSONP(opts);
2473 /***/ (function(module, exports, __webpack_require__) {
2475 // browser shim for xmlhttprequest module
2477 var hasCORS = __webpack_require__(14);
2479 module.exports = function (opts) {
2480 var xdomain = opts.xdomain;
2482 // scheme must be same when usign XDomainRequest
2483 // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
2484 var xscheme = opts.xscheme;
2486 // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
2487 // https://github.com/Automattic/engine.io-client/pull/217
2488 var enablesXDR = opts.enablesXDR;
2490 // XMLHttpRequest can be disabled on IE
2492 if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
2493 return new XMLHttpRequest();
2497 // Use XDomainRequest for IE8 if enablesXDR is true
2498 // because loading bar keeps flashing when using jsonp-polling
2499 // https://github.com/yujiosaka/socke.io-ie8-loading-example
2501 if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {
2502 return new XDomainRequest();
2508 return new self[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');
2516 /***/ (function(module, exports) {
2522 * Logic borrowed from Modernizr:
2524 * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
2528 module.exports = typeof XMLHttpRequest !== 'undefined' &&
2529 'withCredentials' in new XMLHttpRequest();
2531 // if XMLHttp support is disabled in IE then it will throw
2532 // when trying to create
2533 module.exports = false;
2539 /***/ (function(module, exports, __webpack_require__) {
2541 /* global attachEvent */
2544 * Module requirements.
2547 var XMLHttpRequest = __webpack_require__(13);
2548 var Polling = __webpack_require__(16);
2549 var Emitter = __webpack_require__(5);
2550 var inherit = __webpack_require__(27);
2551 var debug = __webpack_require__(3)('engine.io-client:polling-xhr');
2557 module.exports = XHR;
2558 module.exports.Request = Request;
2564 function empty () {}
2567 * XHR Polling constructor.
2569 * @param {Object} opts
2573 function XHR (opts) {
2574 Polling.call(this, opts);
2575 this.requestTimeout = opts.requestTimeout;
2576 this.extraHeaders = opts.extraHeaders;
2578 if (typeof location !== 'undefined') {
2579 var isSSL = 'https:' === location.protocol;
2580 var port = location.port;
2582 // some user agents have empty `location.port`
2584 port = isSSL ? 443 : 80;
2587 this.xd = (typeof location !== 'undefined' && opts.hostname !== location.hostname) ||
2589 this.xs = opts.secure !== isSSL;
2594 * Inherits from Polling.
2597 inherit(XHR, Polling);
2600 * XHR supports binary
2603 XHR.prototype.supportsBinary = true;
2606 * Creates a request.
2608 * @param {String} method
2612 XHR.prototype.request = function (opts) {
2614 opts.uri = this.uri();
2617 opts.agent = this.agent || false;
2618 opts.supportsBinary = this.supportsBinary;
2619 opts.enablesXDR = this.enablesXDR;
2620 opts.withCredentials = this.withCredentials;
2622 // SSL options for Node.js client
2623 opts.pfx = this.pfx;
2624 opts.key = this.key;
2625 opts.passphrase = this.passphrase;
2626 opts.cert = this.cert;
2628 opts.ciphers = this.ciphers;
2629 opts.rejectUnauthorized = this.rejectUnauthorized;
2630 opts.requestTimeout = this.requestTimeout;
2632 // other options for Node.js client
2633 opts.extraHeaders = this.extraHeaders;
2635 return new Request(opts);
2641 * @param {String} data to send.
2642 * @param {Function} called upon flush.
2646 XHR.prototype.doWrite = function (data, fn) {
2647 var isBinary = typeof data !== 'string' && data !== undefined;
2648 var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
2650 req.on('success', fn);
2651 req.on('error', function (err) {
2652 self.onError('xhr post error', err);
2658 * Starts a poll cycle.
2663 XHR.prototype.doPoll = function () {
2665 var req = this.request();
2667 req.on('data', function (data) {
2670 req.on('error', function (err) {
2671 self.onError('xhr poll error', err);
2677 * Request constructor
2679 * @param {Object} options
2683 function Request (opts) {
2684 this.method = opts.method || 'GET';
2685 this.uri = opts.uri;
2686 this.xd = !!opts.xd;
2687 this.xs = !!opts.xs;
2688 this.async = false !== opts.async;
2689 this.data = undefined !== opts.data ? opts.data : null;
2690 this.agent = opts.agent;
2691 this.isBinary = opts.isBinary;
2692 this.supportsBinary = opts.supportsBinary;
2693 this.enablesXDR = opts.enablesXDR;
2694 this.withCredentials = opts.withCredentials;
2695 this.requestTimeout = opts.requestTimeout;
2697 // SSL options for Node.js client
2698 this.pfx = opts.pfx;
2699 this.key = opts.key;
2700 this.passphrase = opts.passphrase;
2701 this.cert = opts.cert;
2703 this.ciphers = opts.ciphers;
2704 this.rejectUnauthorized = opts.rejectUnauthorized;
2706 // other options for Node.js client
2707 this.extraHeaders = opts.extraHeaders;
2716 Emitter(Request.prototype);
2719 * Creates the XHR object and sends the request.
2724 Request.prototype.create = function () {
2725 var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };
2727 // SSL options for Node.js client
2728 opts.pfx = this.pfx;
2729 opts.key = this.key;
2730 opts.passphrase = this.passphrase;
2731 opts.cert = this.cert;
2733 opts.ciphers = this.ciphers;
2734 opts.rejectUnauthorized = this.rejectUnauthorized;
2736 var xhr = this.xhr = new XMLHttpRequest(opts);
2741 xhr.open(this.method, this.uri, this.async);
2743 if (this.extraHeaders) {
2744 xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
2745 for (var i in this.extraHeaders) {
2746 if (this.extraHeaders.hasOwnProperty(i)) {
2747 xhr.setRequestHeader(i, this.extraHeaders[i]);
2753 if ('POST' === this.method) {
2755 if (this.isBinary) {
2756 xhr.setRequestHeader('Content-type', 'application/octet-stream');
2758 xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
2764 xhr.setRequestHeader('Accept', '*/*');
2768 if ('withCredentials' in xhr) {
2769 xhr.withCredentials = this.withCredentials;
2772 if (this.requestTimeout) {
2773 xhr.timeout = this.requestTimeout;
2776 if (this.hasXDR()) {
2777 xhr.onload = function () {
2780 xhr.onerror = function () {
2781 self.onError(xhr.responseText);
2784 xhr.onreadystatechange = function () {
2785 if (xhr.readyState === 2) {
2787 var contentType = xhr.getResponseHeader('Content-Type');
2788 if (self.supportsBinary && contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') {
2789 xhr.responseType = 'arraybuffer';
2793 if (4 !== xhr.readyState) return;
2794 if (200 === xhr.status || 1223 === xhr.status) {
2797 // make sure the `error` event handler that's user-set
2798 // does not throw in the same tick and gets caught here
2799 setTimeout(function () {
2800 self.onError(typeof xhr.status === 'number' ? xhr.status : 0);
2807 xhr.send(this.data);
2809 // Need to defer since .create() is called directly fhrom the constructor
2810 // and thus the 'error' event can only be only bound *after* this exception
2811 // occurs. Therefore, also, we cannot throw here at all.
2812 setTimeout(function () {
2818 if (typeof document !== 'undefined') {
2819 this.index = Request.requestsCount++;
2820 Request.requests[this.index] = this;
2825 * Called upon successful response.
2830 Request.prototype.onSuccess = function () {
2831 this.emit('success');
2836 * Called if we have data.
2841 Request.prototype.onData = function (data) {
2842 this.emit('data', data);
2847 * Called upon error.
2852 Request.prototype.onError = function (err) {
2853 this.emit('error', err);
2863 Request.prototype.cleanup = function (fromError) {
2864 if ('undefined' === typeof this.xhr || null === this.xhr) {
2868 if (this.hasXDR()) {
2869 this.xhr.onload = this.xhr.onerror = empty;
2871 this.xhr.onreadystatechange = empty;
2880 if (typeof document !== 'undefined') {
2881 delete Request.requests[this.index];
2893 Request.prototype.onLoad = function () {
2898 contentType = this.xhr.getResponseHeader('Content-Type');
2900 if (contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') {
2901 data = this.xhr.response || this.xhr.responseText;
2903 data = this.xhr.responseText;
2914 * Check if it has XDomainRequest.
2919 Request.prototype.hasXDR = function () {
2920 return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR;
2924 * Aborts the request.
2929 Request.prototype.abort = function () {
2934 * Aborts pending requests when unloading the window. This is needed to prevent
2935 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
2939 Request.requestsCount = 0;
2940 Request.requests = {};
2942 if (typeof document !== 'undefined') {
2943 if (typeof attachEvent === 'function') {
2944 attachEvent('onunload', unloadHandler);
2945 } else if (typeof addEventListener === 'function') {
2946 var terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
2947 addEventListener(terminationEvent, unloadHandler, false);
2951 function unloadHandler () {
2952 for (var i in Request.requests) {
2953 if (Request.requests.hasOwnProperty(i)) {
2954 Request.requests[i].abort();
2962 /***/ (function(module, exports, __webpack_require__) {
2965 * Module dependencies.
2968 var Transport = __webpack_require__(17);
2969 var parseqs = __webpack_require__(26);
2970 var parser = __webpack_require__(18);
2971 var inherit = __webpack_require__(27);
2972 var yeast = __webpack_require__(28);
2973 var debug = __webpack_require__(3)('engine.io-client:polling');
2979 module.exports = Polling;
2982 * Is XHR2 supported?
2985 var hasXHR2 = (function () {
2986 var XMLHttpRequest = __webpack_require__(13);
2987 var xhr = new XMLHttpRequest({ xdomain: false });
2988 return null != xhr.responseType;
2992 * Polling interface.
2994 * @param {Object} opts
2998 function Polling (opts) {
2999 var forceBase64 = (opts && opts.forceBase64);
3000 if (!hasXHR2 || forceBase64) {
3001 this.supportsBinary = false;
3003 Transport.call(this, opts);
3007 * Inherits from Transport.
3010 inherit(Polling, Transport);
3016 Polling.prototype.name = 'polling';
3019 * Opens the socket (triggers polling). We write a PING message to determine
3020 * when the transport is open.
3025 Polling.prototype.doOpen = function () {
3032 * @param {Function} callback upon buffers are flushed and transport is paused
3036 Polling.prototype.pause = function (onPause) {
3039 this.readyState = 'pausing';
3043 self.readyState = 'paused';
3047 if (this.polling || !this.writable) {
3053 this.once('pollComplete', function () {
3059 if (!this.writable) {
3062 this.once('drain', function () {
3073 * Starts polling cycle.
3078 Polling.prototype.poll = function () {
3080 this.polling = true;
3086 * Overloads onData to detect payloads.
3091 Polling.prototype.onData = function (data) {
3094 var callback = function (packet, index, total) {
3095 // if its the first message we consider the transport open
3096 if ('opening' === self.readyState) {
3100 // if its a close packet, we close the ongoing requests
3101 if ('close' === packet.type) {
3106 // otherwise bypass onData and handle the message
3107 self.onPacket(packet);
3111 parser.decodePayload(data, this.socket.binaryType, callback);
3113 // if an event did not trigger closing
3114 if ('closed' !== this.readyState) {
3115 // if we got data we're not polling
3116 this.polling = false;
3117 this.emit('pollComplete');
3119 if ('open' === this.readyState) {
3128 * For polling, send a close packet.
3133 Polling.prototype.doClose = function () {
3138 self.write([{ type: 'close' }]);
3141 if ('open' === this.readyState) {
3145 // in case we're trying to close while
3146 // handshaking is in progress (GH-164)
3148 this.once('open', close);
3153 * Writes a packets payload.
3155 * @param {Array} data packets
3156 * @param {Function} drain callback
3160 Polling.prototype.write = function (packets) {
3162 this.writable = false;
3163 var callbackfn = function () {
3164 self.writable = true;
3168 parser.encodePayload(packets, this.supportsBinary, function (data) {
3169 self.doWrite(data, callbackfn);
3174 * Generates uri for connection.
3179 Polling.prototype.uri = function () {
3180 var query = this.query || {};
3181 var schema = this.secure ? 'https' : 'http';
3184 // cache busting is forced
3185 if (false !== this.timestampRequests) {
3186 query[this.timestampParam] = yeast();
3189 if (!this.supportsBinary && !query.sid) {
3193 query = parseqs.encode(query);
3195 // avoid port if default for schema
3196 if (this.port && (('https' === schema && Number(this.port) !== 443) ||
3197 ('http' === schema && Number(this.port) !== 80))) {
3198 port = ':' + this.port;
3201 // prepend ? to query
3203 query = '?' + query;
3206 var ipv6 = this.hostname.indexOf(':') !== -1;
3207 return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
3213 /***/ (function(module, exports, __webpack_require__) {
3216 * Module dependencies.
3219 var parser = __webpack_require__(18);
3220 var Emitter = __webpack_require__(5);
3226 module.exports = Transport;
3229 * Transport abstract constructor.
3231 * @param {Object} options.
3235 function Transport (opts) {
3236 this.path = opts.path;
3237 this.hostname = opts.hostname;
3238 this.port = opts.port;
3239 this.secure = opts.secure;
3240 this.query = opts.query;
3241 this.timestampParam = opts.timestampParam;
3242 this.timestampRequests = opts.timestampRequests;
3243 this.readyState = '';
3244 this.agent = opts.agent || false;
3245 this.socket = opts.socket;
3246 this.enablesXDR = opts.enablesXDR;
3247 this.withCredentials = opts.withCredentials;
3249 // SSL options for Node.js client
3250 this.pfx = opts.pfx;
3251 this.key = opts.key;
3252 this.passphrase = opts.passphrase;
3253 this.cert = opts.cert;
3255 this.ciphers = opts.ciphers;
3256 this.rejectUnauthorized = opts.rejectUnauthorized;
3257 this.forceNode = opts.forceNode;
3259 // results of ReactNative environment detection
3260 this.isReactNative = opts.isReactNative;
3262 // other options for Node.js client
3263 this.extraHeaders = opts.extraHeaders;
3264 this.localAddress = opts.localAddress;
3271 Emitter(Transport.prototype);
3276 * @param {String} str
3277 * @return {Transport} for chaining
3281 Transport.prototype.onError = function (msg, desc) {
3282 var err = new Error(msg);
3283 err.type = 'TransportError';
3284 err.description = desc;
3285 this.emit('error', err);
3290 * Opens the transport.
3295 Transport.prototype.open = function () {
3296 if ('closed' === this.readyState || '' === this.readyState) {
3297 this.readyState = 'opening';
3305 * Closes the transport.
3310 Transport.prototype.close = function () {
3311 if ('opening' === this.readyState || 'open' === this.readyState) {
3320 * Sends multiple packets.
3322 * @param {Array} packets
3326 Transport.prototype.send = function (packets) {
3327 if ('open' === this.readyState) {
3328 this.write(packets);
3330 throw new Error('Transport not open');
3340 Transport.prototype.onOpen = function () {
3341 this.readyState = 'open';
3342 this.writable = true;
3349 * @param {String} data
3353 Transport.prototype.onData = function (data) {
3354 var packet = parser.decodePacket(data, this.socket.binaryType);
3355 this.onPacket(packet);
3359 * Called with a decoded packet.
3362 Transport.prototype.onPacket = function (packet) {
3363 this.emit('packet', packet);
3367 * Called upon close.
3372 Transport.prototype.onClose = function () {
3373 this.readyState = 'closed';
3380 /***/ (function(module, exports, __webpack_require__) {
3383 * Module dependencies.
3386 var keys = __webpack_require__(19);
3387 var hasBinary = __webpack_require__(20);
3388 var sliceBuffer = __webpack_require__(21);
3389 var after = __webpack_require__(22);
3390 var utf8 = __webpack_require__(23);
3393 if (typeof ArrayBuffer !== 'undefined') {
3394 base64encoder = __webpack_require__(24);
3398 * Check if we are running an android browser. That requires us to use
3399 * ArrayBuffer with polling transports...
3401 * http://ghinda.net/jpeg-blob-ajax-android/
3404 var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);
3407 * Check if we are running in PhantomJS.
3408 * Uploading a Blob with PhantomJS does not work correctly, as reported here:
3409 * https://github.com/ariya/phantomjs/issues/11395
3412 var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);
3415 * When true, avoids using Blobs to encode payloads.
3418 var dontSendBlobs = isAndroid || isPhantomJS;
3421 * Current protocol version.
3424 exports.protocol = 3;
3430 var packets = exports.packets = {
3432 , close: 1 // non-ws
3440 var packetslist = keys(packets);
3443 * Premade error packet.
3446 var err = { type: 'error', data: 'parser error' };
3449 * Create a blob api even for blob builder when vendor prefixes exist
3452 var Blob = __webpack_require__(25);
3457 * <packet type id> [ <data> ]
3465 * Binary is encoded in an identical principle
3470 exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
3471 if (typeof supportsBinary === 'function') {
3472 callback = supportsBinary;
3473 supportsBinary = false;
3476 if (typeof utf8encode === 'function') {
3477 callback = utf8encode;
3481 var data = (packet.data === undefined)
3483 : packet.data.buffer || packet.data;
3485 if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) {
3486 return encodeArrayBuffer(packet, supportsBinary, callback);
3487 } else if (typeof Blob !== 'undefined' && data instanceof Blob) {
3488 return encodeBlob(packet, supportsBinary, callback);
3491 // might be an object with { base64: true, data: dataAsBase64String }
3492 if (data && data.base64) {
3493 return encodeBase64Object(packet, callback);
3496 // Sending data as a utf-8 string
3497 var encoded = packets[packet.type];
3499 // data fragment is optional
3500 if (undefined !== packet.data) {
3501 encoded += utf8encode ? utf8.encode(String(packet.data), { strict: false }) : String(packet.data);
3504 return callback('' + encoded);
3508 function encodeBase64Object(packet, callback) {
3509 // packet data is an object { base64: true, data: dataAsBase64String }
3510 var message = 'b' + exports.packets[packet.type] + packet.data.data;
3511 return callback(message);
3515 * Encode packet helpers for binary types
3518 function encodeArrayBuffer(packet, supportsBinary, callback) {
3519 if (!supportsBinary) {
3520 return exports.encodeBase64Packet(packet, callback);
3523 var data = packet.data;
3524 var contentArray = new Uint8Array(data);
3525 var resultBuffer = new Uint8Array(1 + data.byteLength);
3527 resultBuffer[0] = packets[packet.type];
3528 for (var i = 0; i < contentArray.length; i++) {
3529 resultBuffer[i+1] = contentArray[i];
3532 return callback(resultBuffer.buffer);
3535 function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
3536 if (!supportsBinary) {
3537 return exports.encodeBase64Packet(packet, callback);
3540 var fr = new FileReader();
3541 fr.onload = function() {
3542 exports.encodePacket({ type: packet.type, data: fr.result }, supportsBinary, true, callback);
3544 return fr.readAsArrayBuffer(packet.data);
3547 function encodeBlob(packet, supportsBinary, callback) {
3548 if (!supportsBinary) {
3549 return exports.encodeBase64Packet(packet, callback);
3552 if (dontSendBlobs) {
3553 return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
3556 var length = new Uint8Array(1);
3557 length[0] = packets[packet.type];
3558 var blob = new Blob([length.buffer, packet.data]);
3560 return callback(blob);
3564 * Encodes a packet with binary data in a base64 string
3566 * @param {Object} packet, has `type` and `data`
3567 * @return {String} base64 encoded message
3570 exports.encodeBase64Packet = function(packet, callback) {
3571 var message = 'b' + exports.packets[packet.type];
3572 if (typeof Blob !== 'undefined' && packet.data instanceof Blob) {
3573 var fr = new FileReader();
3574 fr.onload = function() {
3575 var b64 = fr.result.split(',')[1];
3576 callback(message + b64);
3578 return fr.readAsDataURL(packet.data);
3583 b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
3585 // iPhone Safari doesn't let you apply with typed arrays
3586 var typed = new Uint8Array(packet.data);
3587 var basic = new Array(typed.length);
3588 for (var i = 0; i < typed.length; i++) {
3589 basic[i] = typed[i];
3591 b64data = String.fromCharCode.apply(null, basic);
3593 message += btoa(b64data);
3594 return callback(message);
3598 * Decodes a packet. Changes format to Blob if requested.
3600 * @return {Object} with `type` and `data` (if any)
3604 exports.decodePacket = function (data, binaryType, utf8decode) {
3605 if (data === undefined) {
3609 if (typeof data === 'string') {
3610 if (data.charAt(0) === 'b') {
3611 return exports.decodeBase64Packet(data.substr(1), binaryType);
3615 data = tryDecode(data);
3616 if (data === false) {
3620 var type = data.charAt(0);
3622 if (Number(type) != type || !packetslist[type]) {
3626 if (data.length > 1) {
3627 return { type: packetslist[type], data: data.substring(1) };
3629 return { type: packetslist[type] };
3633 var asArray = new Uint8Array(data);
3634 var type = asArray[0];
3635 var rest = sliceBuffer(data, 1);
3636 if (Blob && binaryType === 'blob') {
3637 rest = new Blob([rest]);
3639 return { type: packetslist[type], data: rest };
3642 function tryDecode(data) {
3644 data = utf8.decode(data, { strict: false });
3652 * Decodes a packet encoded in a base64 string
3654 * @param {String} base64 encoded message
3655 * @return {Object} with `type` and `data` (if any)
3658 exports.decodeBase64Packet = function(msg, binaryType) {
3659 var type = packetslist[msg.charAt(0)];
3660 if (!base64encoder) {
3661 return { type: type, data: { base64: true, data: msg.substr(1) } };
3664 var data = base64encoder.decode(msg.substr(1));
3666 if (binaryType === 'blob' && Blob) {
3667 data = new Blob([data]);
3670 return { type: type, data: data };
3674 * Encodes multiple messages (payload).
3680 * 11:hello world2:hi
3682 * If any contents are binary, they will be encoded as base64 strings. Base64
3683 * encoded strings are marked with a b before the length specifier
3685 * @param {Array} packets
3689 exports.encodePayload = function (packets, supportsBinary, callback) {
3690 if (typeof supportsBinary === 'function') {
3691 callback = supportsBinary;
3692 supportsBinary = null;
3695 var isBinary = hasBinary(packets);
3697 if (supportsBinary && isBinary) {
3698 if (Blob && !dontSendBlobs) {
3699 return exports.encodePayloadAsBlob(packets, callback);
3702 return exports.encodePayloadAsArrayBuffer(packets, callback);
3705 if (!packets.length) {
3706 return callback('0:');
3709 function setLengthHeader(message) {
3710 return message.length + ':' + message;
3713 function encodeOne(packet, doneCallback) {
3714 exports.encodePacket(packet, !isBinary ? false : supportsBinary, false, function(message) {
3715 doneCallback(null, setLengthHeader(message));
3719 map(packets, encodeOne, function(err, results) {
3720 return callback(results.join(''));
3725 * Async array map using after
3728 function map(ary, each, done) {
3729 var result = new Array(ary.length);
3730 var next = after(ary.length, done);
3732 var eachWithIndex = function(i, el, cb) {
3733 each(el, function(error, msg) {
3739 for (var i = 0; i < ary.length; i++) {
3740 eachWithIndex(i, ary[i], next);
3745 * Decodes data when a payload is maybe expected. Possible binary contents are
3746 * decoded from their base64 representation
3748 * @param {String} data, callback method
3752 exports.decodePayload = function (data, binaryType, callback) {
3753 if (typeof data !== 'string') {
3754 return exports.decodePayloadAsBinary(data, binaryType, callback);
3757 if (typeof binaryType === 'function') {
3758 callback = binaryType;
3764 // parser error - ignoring payload
3765 return callback(err, 0, 1);
3768 var length = '', n, msg;
3770 for (var i = 0, l = data.length; i < l; i++) {
3771 var chr = data.charAt(i);
3778 if (length === '' || (length != (n = Number(length)))) {
3779 // parser error - ignoring payload
3780 return callback(err, 0, 1);
3783 msg = data.substr(i + 1, n);
3785 if (length != msg.length) {
3786 // parser error - ignoring payload
3787 return callback(err, 0, 1);
3791 packet = exports.decodePacket(msg, binaryType, false);
3793 if (err.type === packet.type && err.data === packet.data) {
3794 // parser error in individual packet - ignoring payload
3795 return callback(err, 0, 1);
3798 var ret = callback(packet, i + n, l);
3799 if (false === ret) return;
3807 if (length !== '') {
3808 // parser error - ignoring payload
3809 return callback(err, 0, 1);
3815 * Encodes multiple messages (payload) as binary.
3817 * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
3821 * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
3823 * @param {Array} packets
3824 * @return {ArrayBuffer} encoded payload
3828 exports.encodePayloadAsArrayBuffer = function(packets, callback) {
3829 if (!packets.length) {
3830 return callback(new ArrayBuffer(0));
3833 function encodeOne(packet, doneCallback) {
3834 exports.encodePacket(packet, true, true, function(data) {
3835 return doneCallback(null, data);
3839 map(packets, encodeOne, function(err, encodedPackets) {
3840 var totalLength = encodedPackets.reduce(function(acc, p) {
3842 if (typeof p === 'string'){
3847 return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
3850 var resultArray = new Uint8Array(totalLength);
3852 var bufferIndex = 0;
3853 encodedPackets.forEach(function(p) {
3854 var isString = typeof p === 'string';
3857 var view = new Uint8Array(p.length);
3858 for (var i = 0; i < p.length; i++) {
3859 view[i] = p.charCodeAt(i);
3864 if (isString) { // not true binary
3865 resultArray[bufferIndex++] = 0;
3866 } else { // true binary
3867 resultArray[bufferIndex++] = 1;
3870 var lenStr = ab.byteLength.toString();
3871 for (var i = 0; i < lenStr.length; i++) {
3872 resultArray[bufferIndex++] = parseInt(lenStr[i]);
3874 resultArray[bufferIndex++] = 255;
3876 var view = new Uint8Array(ab);
3877 for (var i = 0; i < view.length; i++) {
3878 resultArray[bufferIndex++] = view[i];
3882 return callback(resultArray.buffer);
3890 exports.encodePayloadAsBlob = function(packets, callback) {
3891 function encodeOne(packet, doneCallback) {
3892 exports.encodePacket(packet, true, true, function(encoded) {
3893 var binaryIdentifier = new Uint8Array(1);
3894 binaryIdentifier[0] = 1;
3895 if (typeof encoded === 'string') {
3896 var view = new Uint8Array(encoded.length);
3897 for (var i = 0; i < encoded.length; i++) {
3898 view[i] = encoded.charCodeAt(i);
3900 encoded = view.buffer;
3901 binaryIdentifier[0] = 0;
3904 var len = (encoded instanceof ArrayBuffer)
3905 ? encoded.byteLength
3908 var lenStr = len.toString();
3909 var lengthAry = new Uint8Array(lenStr.length + 1);
3910 for (var i = 0; i < lenStr.length; i++) {
3911 lengthAry[i] = parseInt(lenStr[i]);
3913 lengthAry[lenStr.length] = 255;
3916 var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
3917 doneCallback(null, blob);
3922 map(packets, encodeOne, function(err, results) {
3923 return callback(new Blob(results));
3928 * Decodes data when a payload is maybe expected. Strings are decoded by
3929 * interpreting each byte as a key code for entries marked to start with 0. See
3930 * description of encodePayloadAsBinary
3932 * @param {ArrayBuffer} data, callback method
3936 exports.decodePayloadAsBinary = function (data, binaryType, callback) {
3937 if (typeof binaryType === 'function') {
3938 callback = binaryType;
3942 var bufferTail = data;
3945 while (bufferTail.byteLength > 0) {
3946 var tailArray = new Uint8Array(bufferTail);
3947 var isString = tailArray[0] === 0;
3950 for (var i = 1; ; i++) {
3951 if (tailArray[i] === 255) break;
3953 // 310 = char length of Number.MAX_VALUE
3954 if (msgLength.length > 310) {
3955 return callback(err, 0, 1);
3958 msgLength += tailArray[i];
3961 bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
3962 msgLength = parseInt(msgLength);
3964 var msg = sliceBuffer(bufferTail, 0, msgLength);
3967 msg = String.fromCharCode.apply(null, new Uint8Array(msg));
3969 // iPhone Safari doesn't let you apply to typed arrays
3970 var typed = new Uint8Array(msg);
3972 for (var i = 0; i < typed.length; i++) {
3973 msg += String.fromCharCode(typed[i]);
3979 bufferTail = sliceBuffer(bufferTail, msgLength);
3982 var total = buffers.length;
3983 buffers.forEach(function(buffer, i) {
3984 callback(exports.decodePacket(buffer, binaryType, true), i, total);
3991 /***/ (function(module, exports) {
3995 * Gets the keys for an object.
3997 * @return {Array} keys
4001 module.exports = Object.keys || function keys (obj){
4003 var has = Object.prototype.hasOwnProperty;
4005 for (var i in obj) {
4006 if (has.call(obj, i)) {
4016 /***/ (function(module, exports, __webpack_require__) {
4018 /* global Blob File */
4021 * Module requirements.
4024 var isArray = __webpack_require__(7);
4026 var toString = Object.prototype.toString;
4027 var withNativeBlob = typeof Blob === 'function' ||
4028 typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]';
4029 var withNativeFile = typeof File === 'function' ||
4030 typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]';
4036 module.exports = hasBinary;
4039 * Checks for binary data.
4041 * Supports Buffer, ArrayBuffer, Blob and File.
4043 * @param {Object} anything
4047 function hasBinary (obj) {
4048 if (!obj || typeof obj !== 'object') {
4053 for (var i = 0, l = obj.length; i < l; i++) {
4054 if (hasBinary(obj[i])) {
4061 if ((typeof Buffer === 'function' && Buffer.isBuffer && Buffer.isBuffer(obj)) ||
4062 (typeof ArrayBuffer === 'function' && obj instanceof ArrayBuffer) ||
4063 (withNativeBlob && obj instanceof Blob) ||
4064 (withNativeFile && obj instanceof File)
4069 // see: https://github.com/Automattic/has-binary/pull/4
4070 if (obj.toJSON && typeof obj.toJSON === 'function' && arguments.length === 1) {
4071 return hasBinary(obj.toJSON(), true);
4074 for (var key in obj) {
4075 if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
4086 /***/ (function(module, exports) {
4089 * An abstraction for slicing an arraybuffer even when
4090 * ArrayBuffer.prototype.slice is not supported
4095 module.exports = function(arraybuffer, start, end) {
4096 var bytes = arraybuffer.byteLength;
4100 if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
4102 if (start < 0) { start += bytes; }
4103 if (end < 0) { end += bytes; }
4104 if (end > bytes) { end = bytes; }
4106 if (start >= bytes || start >= end || bytes === 0) {
4107 return new ArrayBuffer(0);
4110 var abv = new Uint8Array(arraybuffer);
4111 var result = new Uint8Array(end - start);
4112 for (var i = start, ii = 0; i < end; i++, ii++) {
4113 result[ii] = abv[i];
4115 return result.buffer;
4121 /***/ (function(module, exports) {
4123 module.exports = after
4125 function after(count, callback, err_cb) {
4127 err_cb = err_cb || noop
4130 return (count === 0) ? callback() : proxy
4132 function proxy(err, result) {
4133 if (proxy.count <= 0) {
4134 throw new Error('after called too many times')
4138 // after first error, rest are passed to err_cb
4142 // future error callbacks will go to error handler
4144 } else if (proxy.count === 0 && !bail) {
4145 callback(null, result)
4155 /***/ (function(module, exports) {
4157 /*! https://mths.be/utf8js v2.1.2 by @mathias */
4159 var stringFromCharCode = String.fromCharCode;
4161 // Taken from https://mths.be/punycode
4162 function ucs2decode(string) {
4165 var length = string.length;
4168 while (counter < length) {
4169 value = string.charCodeAt(counter++);
4170 if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
4171 // high surrogate, and there is a next character
4172 extra = string.charCodeAt(counter++);
4173 if ((extra & 0xFC00) == 0xDC00) { // low surrogate
4174 output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
4176 // unmatched surrogate; only append this code unit, in case the next
4177 // code unit is the high surrogate of a surrogate pair
4188 // Taken from https://mths.be/punycode
4189 function ucs2encode(array) {
4190 var length = array.length;
4194 while (++index < length) {
4195 value = array[index];
4196 if (value > 0xFFFF) {
4198 output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
4199 value = 0xDC00 | value & 0x3FF;
4201 output += stringFromCharCode(value);
4206 function checkScalarValue(codePoint, strict) {
4207 if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
4210 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
4211 ' is not a scalar value'
4218 /*--------------------------------------------------------------------------*/
4220 function createByte(codePoint, shift) {
4221 return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
4224 function encodeCodePoint(codePoint, strict) {
4225 if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
4226 return stringFromCharCode(codePoint);
4229 if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
4230 symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
4232 else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
4233 if (!checkScalarValue(codePoint, strict)) {
4236 symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
4237 symbol += createByte(codePoint, 6);
4239 else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
4240 symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
4241 symbol += createByte(codePoint, 12);
4242 symbol += createByte(codePoint, 6);
4244 symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
4248 function utf8encode(string, opts) {
4250 var strict = false !== opts.strict;
4252 var codePoints = ucs2decode(string);
4253 var length = codePoints.length;
4256 var byteString = '';
4257 while (++index < length) {
4258 codePoint = codePoints[index];
4259 byteString += encodeCodePoint(codePoint, strict);
4264 /*--------------------------------------------------------------------------*/
4266 function readContinuationByte() {
4267 if (byteIndex >= byteCount) {
4268 throw Error('Invalid byte index');
4271 var continuationByte = byteArray[byteIndex] & 0xFF;
4274 if ((continuationByte & 0xC0) == 0x80) {
4275 return continuationByte & 0x3F;
4278 // If we end up here, it’s not a continuation byte
4279 throw Error('Invalid continuation byte');
4282 function decodeSymbol(strict) {
4289 if (byteIndex > byteCount) {
4290 throw Error('Invalid byte index');
4293 if (byteIndex == byteCount) {
4298 byte1 = byteArray[byteIndex] & 0xFF;
4301 // 1-byte sequence (no continuation bytes)
4302 if ((byte1 & 0x80) == 0) {
4307 if ((byte1 & 0xE0) == 0xC0) {
4308 byte2 = readContinuationByte();
4309 codePoint = ((byte1 & 0x1F) << 6) | byte2;
4310 if (codePoint >= 0x80) {
4313 throw Error('Invalid continuation byte');
4317 // 3-byte sequence (may include unpaired surrogates)
4318 if ((byte1 & 0xF0) == 0xE0) {
4319 byte2 = readContinuationByte();
4320 byte3 = readContinuationByte();
4321 codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
4322 if (codePoint >= 0x0800) {
4323 return checkScalarValue(codePoint, strict) ? codePoint : 0xFFFD;
4325 throw Error('Invalid continuation byte');
4330 if ((byte1 & 0xF8) == 0xF0) {
4331 byte2 = readContinuationByte();
4332 byte3 = readContinuationByte();
4333 byte4 = readContinuationByte();
4334 codePoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0C) |
4335 (byte3 << 0x06) | byte4;
4336 if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
4341 throw Error('Invalid UTF-8 detected');
4347 function utf8decode(byteString, opts) {
4349 var strict = false !== opts.strict;
4351 byteArray = ucs2decode(byteString);
4352 byteCount = byteArray.length;
4354 var codePoints = [];
4356 while ((tmp = decodeSymbol(strict)) !== false) {
4357 codePoints.push(tmp);
4359 return ucs2encode(codePoints);
4371 /***/ (function(module, exports) {
4374 * base64-arraybuffer
4375 * https://github.com/niklasvh/base64-arraybuffer
4377 * Copyright (c) 2012 Niklas von Hertzen
4378 * Licensed under the MIT license.
4383 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4385 // Use a lookup table to find the index.
4386 var lookup = new Uint8Array(256);
4387 for (var i = 0; i < chars.length; i++) {
4388 lookup[chars.charCodeAt(i)] = i;
4391 exports.encode = function(arraybuffer) {
4392 var bytes = new Uint8Array(arraybuffer),
4393 i, len = bytes.length, base64 = "";
4395 for (i = 0; i < len; i+=3) {
4396 base64 += chars[bytes[i] >> 2];
4397 base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
4398 base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
4399 base64 += chars[bytes[i + 2] & 63];
4402 if ((len % 3) === 2) {
4403 base64 = base64.substring(0, base64.length - 1) + "=";
4404 } else if (len % 3 === 1) {
4405 base64 = base64.substring(0, base64.length - 2) + "==";
4411 exports.decode = function(base64) {
4412 var bufferLength = base64.length * 0.75,
4413 len = base64.length, i, p = 0,
4414 encoded1, encoded2, encoded3, encoded4;
4416 if (base64[base64.length - 1] === "=") {
4418 if (base64[base64.length - 2] === "=") {
4423 var arraybuffer = new ArrayBuffer(bufferLength),
4424 bytes = new Uint8Array(arraybuffer);
4426 for (i = 0; i < len; i+=4) {
4427 encoded1 = lookup[base64.charCodeAt(i)];
4428 encoded2 = lookup[base64.charCodeAt(i+1)];
4429 encoded3 = lookup[base64.charCodeAt(i+2)];
4430 encoded4 = lookup[base64.charCodeAt(i+3)];
4432 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
4433 bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
4434 bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
4444 /***/ (function(module, exports) {
4447 * Create a blob builder even when vendor prefixes exist
4450 var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
4451 typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder :
4452 typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
4453 typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
4457 * Check if Blob constructor is supported
4460 var blobSupported = (function() {
4462 var a = new Blob(['hi']);
4463 return a.size === 2;
4470 * Check if Blob constructor supports ArrayBufferViews
4471 * Fails in Safari 6, so we need to map to ArrayBuffers there.
4474 var blobSupportsArrayBufferView = blobSupported && (function() {
4476 var b = new Blob([new Uint8Array([1,2])]);
4477 return b.size === 2;
4484 * Check if BlobBuilder is supported
4487 var blobBuilderSupported = BlobBuilder
4488 && BlobBuilder.prototype.append
4489 && BlobBuilder.prototype.getBlob;
4492 * Helper function that maps ArrayBufferViews to ArrayBuffers
4493 * Used by BlobBuilder constructor and old browsers that didn't
4494 * support it in the Blob constructor.
4497 function mapArrayBufferViews(ary) {
4498 return ary.map(function(chunk) {
4499 if (chunk.buffer instanceof ArrayBuffer) {
4500 var buf = chunk.buffer;
4502 // if this is a subarray, make a copy so we only
4503 // include the subarray region from the underlying buffer
4504 if (chunk.byteLength !== buf.byteLength) {
4505 var copy = new Uint8Array(chunk.byteLength);
4506 copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
4517 function BlobBuilderConstructor(ary, options) {
4518 options = options || {};
4520 var bb = new BlobBuilder();
4521 mapArrayBufferViews(ary).forEach(function(part) {
4525 return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
4528 function BlobConstructor(ary, options) {
4529 return new Blob(mapArrayBufferViews(ary), options || {});
4532 if (typeof Blob !== 'undefined') {
4533 BlobBuilderConstructor.prototype = Blob.prototype;
4534 BlobConstructor.prototype = Blob.prototype;
4537 module.exports = (function() {
4538 if (blobSupported) {
4539 return blobSupportsArrayBufferView ? Blob : BlobConstructor;
4540 } else if (blobBuilderSupported) {
4541 return BlobBuilderConstructor;
4550 /***/ (function(module, exports) {
4553 * Compiles a querystring
4554 * Returns string representation of the object
4560 exports.encode = function (obj) {
4563 for (var i in obj) {
4564 if (obj.hasOwnProperty(i)) {
4565 if (str.length) str += '&';
4566 str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
4574 * Parses a simple querystring into an object
4576 * @param {String} qs
4580 exports.decode = function(qs){
4582 var pairs = qs.split('&');
4583 for (var i = 0, l = pairs.length; i < l; i++) {
4584 var pair = pairs[i].split('=');
4585 qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
4593 /***/ (function(module, exports) {
4596 module.exports = function(a, b){
4597 var fn = function(){};
4598 fn.prototype = b.prototype;
4599 a.prototype = new fn;
4600 a.prototype.constructor = a;
4605 /***/ (function(module, exports) {
4609 var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('')
4617 * Return a string representing the specified number.
4619 * @param {Number} num The number to convert.
4620 * @returns {String} The string representation of the number.
4623 function encode(num) {
4627 encoded = alphabet[num % length] + encoded;
4628 num = Math.floor(num / length);
4635 * Return the integer value specified by the given string.
4637 * @param {String} str The string to convert.
4638 * @returns {Number} The integer value represented by the string.
4641 function decode(str) {
4644 for (i = 0; i < str.length; i++) {
4645 decoded = decoded * length + map[str.charAt(i)];
4652 * Yeast: A tiny growing id generator.
4654 * @returns {String} A unique id.
4658 var now = encode(+new Date());
4660 if (now !== prev) return seed = 0, prev = now;
4661 return now +'.'+ encode(seed++);
4665 // Map each character to its index.
4667 for (; i < length; i++) map[alphabet[i]] = i;
4670 // Expose the `yeast`, `encode` and `decode` functions.
4672 yeast.encode = encode;
4673 yeast.decode = decode;
4674 module.exports = yeast;
4679 /***/ (function(module, exports, __webpack_require__) {
4681 /* WEBPACK VAR INJECTION */(function(global) {/**
4682 * Module requirements.
4685 var Polling = __webpack_require__(16);
4686 var inherit = __webpack_require__(27);
4692 module.exports = JSONPPolling;
4695 * Cached regular expressions.
4698 var rNewline = /\n/g;
4699 var rEscapedNewline = /\\n/g;
4702 * Global JSONP callbacks.
4711 function empty () { }
4714 * Until https://github.com/tc39/proposal-global is shipped.
4717 return typeof self !== 'undefined' ? self
4718 : typeof window !== 'undefined' ? window
4719 : typeof global !== 'undefined' ? global : {};
4723 * JSONP Polling constructor.
4725 * @param {Object} opts.
4729 function JSONPPolling (opts) {
4730 Polling.call(this, opts);
4732 this.query = this.query || {};
4734 // define global callbacks array if not present
4735 // we do this here (lazily) to avoid unneeded global pollution
4737 // we need to consider multiple engines in the same page
4738 var global = glob();
4739 callbacks = global.___eio = (global.___eio || []);
4742 // callback identifier
4743 this.index = callbacks.length;
4745 // add callback to jsonp global
4747 callbacks.push(function (msg) {
4751 // append to query string
4752 this.query.j = this.index;
4754 // prevent spurious errors from being emitted when the window is unloaded
4755 if (typeof addEventListener === 'function') {
4756 addEventListener('beforeunload', function () {
4757 if (self.script) self.script.onerror = empty;
4763 * Inherits from Polling.
4766 inherit(JSONPPolling, Polling);
4769 * JSONP only supports binary as base64 encoded strings
4772 JSONPPolling.prototype.supportsBinary = false;
4775 * Closes the socket.
4780 JSONPPolling.prototype.doClose = function () {
4782 this.script.parentNode.removeChild(this.script);
4787 this.form.parentNode.removeChild(this.form);
4792 Polling.prototype.doClose.call(this);
4796 * Starts a poll cycle.
4801 JSONPPolling.prototype.doPoll = function () {
4803 var script = document.createElement('script');
4806 this.script.parentNode.removeChild(this.script);
4810 script.async = true;
4811 script.src = this.uri();
4812 script.onerror = function (e) {
4813 self.onError('jsonp poll error', e);
4816 var insertAt = document.getElementsByTagName('script')[0];
4818 insertAt.parentNode.insertBefore(script, insertAt);
4820 (document.head || document.body).appendChild(script);
4822 this.script = script;
4824 var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);
4827 setTimeout(function () {
4828 var iframe = document.createElement('iframe');
4829 document.body.appendChild(iframe);
4830 document.body.removeChild(iframe);
4836 * Writes with a hidden iframe.
4838 * @param {String} data to send
4839 * @param {Function} called upon flush.
4843 JSONPPolling.prototype.doWrite = function (data, fn) {
4847 var form = document.createElement('form');
4848 var area = document.createElement('textarea');
4849 var id = this.iframeId = 'eio_iframe_' + this.index;
4852 form.className = 'socketio';
4853 form.style.position = 'absolute';
4854 form.style.top = '-1000px';
4855 form.style.left = '-1000px';
4857 form.method = 'POST';
4858 form.setAttribute('accept-charset', 'utf-8');
4860 form.appendChild(area);
4861 document.body.appendChild(form);
4867 this.form.action = this.uri();
4869 function complete () {
4874 function initIframe () {
4877 self.form.removeChild(self.iframe);
4879 self.onError('jsonp polling iframe removal error', e);
4884 // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
4885 var html = '<iframe src="javascript:0" name="' + self.iframeId + '">';
4886 iframe = document.createElement(html);
4888 iframe = document.createElement('iframe');
4889 iframe.name = self.iframeId;
4890 iframe.src = 'javascript:0';
4893 iframe.id = self.iframeId;
4895 self.form.appendChild(iframe);
4896 self.iframe = iframe;
4901 // escape \n to prevent it from being converted into \r\n by some UAs
4902 // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
4903 data = data.replace(rEscapedNewline, '\\\n');
4904 this.area.value = data.replace(rNewline, '\\n');
4910 if (this.iframe.attachEvent) {
4911 this.iframe.onreadystatechange = function () {
4912 if (self.iframe.readyState === 'complete') {
4917 this.iframe.onload = complete;
4921 /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
4925 /***/ (function(module, exports, __webpack_require__) {
4928 * Module dependencies.
4931 var Transport = __webpack_require__(17);
4932 var parser = __webpack_require__(18);
4933 var parseqs = __webpack_require__(26);
4934 var inherit = __webpack_require__(27);
4935 var yeast = __webpack_require__(28);
4936 var debug = __webpack_require__(3)('engine.io-client:websocket');
4938 var BrowserWebSocket, NodeWebSocket;
4940 if (typeof WebSocket !== 'undefined') {
4941 BrowserWebSocket = WebSocket;
4942 } else if (typeof self !== 'undefined') {
4943 BrowserWebSocket = self.WebSocket || self.MozWebSocket;
4946 if (typeof window === 'undefined') {
4948 NodeWebSocket = __webpack_require__(31);
4953 * Get either the `WebSocket` or `MozWebSocket` globals
4954 * in the browser or try to resolve WebSocket-compatible
4955 * interface exposed by `ws` for Node-like environment.
4958 var WebSocketImpl = BrowserWebSocket || NodeWebSocket;
4964 module.exports = WS;
4967 * WebSocket transport constructor.
4969 * @api {Object} connection options
4973 function WS (opts) {
4974 var forceBase64 = (opts && opts.forceBase64);
4976 this.supportsBinary = false;
4978 this.perMessageDeflate = opts.perMessageDeflate;
4979 this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;
4980 this.protocols = opts.protocols;
4981 if (!this.usingBrowserWebSocket) {
4982 WebSocketImpl = NodeWebSocket;
4984 Transport.call(this, opts);
4988 * Inherits from Transport.
4991 inherit(WS, Transport);
4999 WS.prototype.name = 'websocket';
5002 * WebSockets support binary
5005 WS.prototype.supportsBinary = true;
5013 WS.prototype.doOpen = function () {
5014 if (!this.check()) {
5015 // let probe timeout
5019 var uri = this.uri();
5020 var protocols = this.protocols;
5023 perMessageDeflate: this.perMessageDeflate
5026 // SSL options for Node.js client
5027 opts.pfx = this.pfx;
5028 opts.key = this.key;
5029 opts.passphrase = this.passphrase;
5030 opts.cert = this.cert;
5032 opts.ciphers = this.ciphers;
5033 opts.rejectUnauthorized = this.rejectUnauthorized;
5034 if (this.extraHeaders) {
5035 opts.headers = this.extraHeaders;
5037 if (this.localAddress) {
5038 opts.localAddress = this.localAddress;
5043 this.usingBrowserWebSocket && !this.isReactNative
5045 ? new WebSocketImpl(uri, protocols)
5046 : new WebSocketImpl(uri)
5047 : new WebSocketImpl(uri, protocols, opts);
5049 return this.emit('error', err);
5052 if (this.ws.binaryType === undefined) {
5053 this.supportsBinary = false;
5056 if (this.ws.supports && this.ws.supports.binary) {
5057 this.supportsBinary = true;
5058 this.ws.binaryType = 'nodebuffer';
5060 this.ws.binaryType = 'arraybuffer';
5063 this.addEventListeners();
5067 * Adds event listeners to the socket
5072 WS.prototype.addEventListeners = function () {
5075 this.ws.onopen = function () {
5078 this.ws.onclose = function () {
5081 this.ws.onmessage = function (ev) {
5082 self.onData(ev.data);
5084 this.ws.onerror = function (e) {
5085 self.onError('websocket error', e);
5090 * Writes data to socket.
5092 * @param {Array} array of packets.
5096 WS.prototype.write = function (packets) {
5098 this.writable = false;
5100 // encodePacket efficient as it uses WS framing
5101 // no need for encodePayload
5102 var total = packets.length;
5103 for (var i = 0, l = total; i < l; i++) {
5104 (function (packet) {
5105 parser.encodePacket(packet, self.supportsBinary, function (data) {
5106 if (!self.usingBrowserWebSocket) {
5107 // always create a new object (GH-437)
5109 if (packet.options) {
5110 opts.compress = packet.options.compress;
5113 if (self.perMessageDeflate) {
5114 var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
5115 if (len < self.perMessageDeflate.threshold) {
5116 opts.compress = false;
5121 // Sometimes the websocket has already been closed but the browser didn't
5122 // have a chance of informing us about it yet, in that case send will
5125 if (self.usingBrowserWebSocket) {
5126 // TypeError is thrown when passing the second argument on Safari
5129 self.ws.send(data, opts);
5144 // defer to next tick to allow Socket to clear writeBuffer
5145 setTimeout(function () {
5146 self.writable = true;
5158 WS.prototype.onClose = function () {
5159 Transport.prototype.onClose.call(this);
5168 WS.prototype.doClose = function () {
5169 if (typeof this.ws !== 'undefined') {
5175 * Generates uri for connection.
5180 WS.prototype.uri = function () {
5181 var query = this.query || {};
5182 var schema = this.secure ? 'wss' : 'ws';
5185 // avoid port if default for schema
5186 if (this.port && (('wss' === schema && Number(this.port) !== 443) ||
5187 ('ws' === schema && Number(this.port) !== 80))) {
5188 port = ':' + this.port;
5191 // append timestamp to URI
5192 if (this.timestampRequests) {
5193 query[this.timestampParam] = yeast();
5196 // communicate binary support capabilities
5197 if (!this.supportsBinary) {
5201 query = parseqs.encode(query);
5203 // prepend ? to query
5205 query = '?' + query;
5208 var ipv6 = this.hostname.indexOf(':') !== -1;
5209 return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
5213 * Feature detection for WebSocket.
5215 * @return {Boolean} whether this transport is available.
5219 WS.prototype.check = function () {
5220 return !!WebSocketImpl && !('__initialize' in WebSocketImpl && this.name === WS.prototype.name);
5226 /***/ (function(module, exports) {
5232 /***/ (function(module, exports) {
5235 var indexOf = [].indexOf;
5237 module.exports = function(arr, obj){
5238 if (indexOf) return arr.indexOf(obj);
5239 for (var i = 0; i < arr.length; ++i) {
5240 if (arr[i] === obj) return i;
5247 /***/ (function(module, exports, __webpack_require__) {
5251 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
5254 * Module dependencies.
5257 var parser = __webpack_require__(4);
5258 var Emitter = __webpack_require__(5);
5259 var toArray = __webpack_require__(34);
5260 var on = __webpack_require__(35);
5261 var bind = __webpack_require__(36);
5262 var debug = __webpack_require__(3)('socket.io-client:socket');
5263 var parseqs = __webpack_require__(26);
5264 var hasBin = __webpack_require__(20);
5270 module.exports = exports = Socket;
5273 * Internal events (blacklisted).
5274 * These events can't be emitted by the user.
5287 reconnect_attempt: 1,
5288 reconnect_failed: 1,
5296 * Shortcut to `Emitter#emit`.
5299 var emit = Emitter.prototype.emit;
5302 * `Socket` constructor.
5307 function Socket(io, nsp, opts) {
5310 this.json = this; // compat
5313 this.receiveBuffer = [];
5314 this.sendBuffer = [];
5315 this.connected = false;
5316 this.disconnected = true;
5318 if (opts && opts.query) {
5319 this.query = opts.query;
5321 if (this.io.autoConnect) this.open();
5328 Emitter(Socket.prototype);
5331 * Subscribe to open, close and packet events
5336 Socket.prototype.subEvents = function () {
5337 if (this.subs) return;
5340 this.subs = [on(io, 'open', bind(this, 'onopen')), on(io, 'packet', bind(this, 'onpacket')), on(io, 'close', bind(this, 'onclose'))];
5344 * "Opens" the socket.
5349 Socket.prototype.open = Socket.prototype.connect = function () {
5350 if (this.connected) return this;
5353 this.io.open(); // ensure open
5354 if ('open' === this.io.readyState) this.onopen();
5355 this.emit('connecting');
5360 * Sends a `message` event.
5362 * @return {Socket} self
5366 Socket.prototype.send = function () {
5367 var args = toArray(arguments);
5368 args.unshift('message');
5369 this.emit.apply(this, args);
5375 * If the event is in `events`, it's emitted normally.
5377 * @param {String} event name
5378 * @return {Socket} self
5382 Socket.prototype.emit = function (ev) {
5383 if (events.hasOwnProperty(ev)) {
5384 emit.apply(this, arguments);
5388 var args = toArray(arguments);
5390 type: (this.flags.binary !== undefined ? this.flags.binary : hasBin(args)) ? parser.BINARY_EVENT : parser.EVENT,
5394 packet.options = {};
5395 packet.options.compress = !this.flags || false !== this.flags.compress;
5397 // event ack callback
5398 if ('function' === typeof args[args.length - 1]) {
5400 this.acks[this.ids] = args.pop();
5401 packet.id = this.ids++;
5404 if (this.connected) {
5405 this.packet(packet);
5407 this.sendBuffer.push(packet);
5418 * @param {Object} packet
5422 Socket.prototype.packet = function (packet) {
5423 packet.nsp = this.nsp;
5424 this.io.packet(packet);
5428 * Called upon engine `open`.
5433 Socket.prototype.onopen = function () {
5435 // write connect packet if necessary
5436 if ('/' !== this.nsp) {
5438 var query = _typeof(this.query) === 'object' ? parseqs.encode(this.query) : this.query;
5440 this.packet({ type: parser.CONNECT, query: query });
5442 this.packet({ type: parser.CONNECT });
5448 * Called upon engine `close`.
5450 * @param {String} reason
5454 Socket.prototype.onclose = function (reason) {
5456 this.connected = false;
5457 this.disconnected = true;
5459 this.emit('disconnect', reason);
5463 * Called with socket packet.
5465 * @param {Object} packet
5469 Socket.prototype.onpacket = function (packet) {
5470 var sameNamespace = packet.nsp === this.nsp;
5471 var rootNamespaceError = packet.type === parser.ERROR && packet.nsp === '/';
5473 if (!sameNamespace && !rootNamespaceError) return;
5475 switch (packet.type) {
5476 case parser.CONNECT:
5481 this.onevent(packet);
5484 case parser.BINARY_EVENT:
5485 this.onevent(packet);
5492 case parser.BINARY_ACK:
5496 case parser.DISCONNECT:
5497 this.ondisconnect();
5501 this.emit('error', packet.data);
5507 * Called upon a server event.
5509 * @param {Object} packet
5513 Socket.prototype.onevent = function (packet) {
5514 var args = packet.data || [];
5516 if (null != packet.id) {
5518 args.push(this.ack(packet.id));
5521 if (this.connected) {
5522 emit.apply(this, args);
5524 this.receiveBuffer.push(args);
5529 * Produces an ack callback to emit with an event.
5534 Socket.prototype.ack = function (id) {
5537 return function () {
5538 // prevent double callbacks
5541 var args = toArray(arguments);
5544 type: hasBin(args) ? parser.BINARY_ACK : parser.ACK,
5552 * Called upon a server acknowlegement.
5554 * @param {Object} packet
5558 Socket.prototype.onack = function (packet) {
5559 var ack = this.acks[packet.id];
5560 if ('function' === typeof ack) {
5562 ack.apply(this, packet.data);
5563 delete this.acks[packet.id];
5568 * Called upon server connect.
5573 Socket.prototype.onconnect = function () {
5574 this.connected = true;
5575 this.disconnected = false;
5576 this.emit('connect');
5577 this.emitBuffered();
5581 * Emit buffered events (received and emitted).
5586 Socket.prototype.emitBuffered = function () {
5588 for (i = 0; i < this.receiveBuffer.length; i++) {
5589 emit.apply(this, this.receiveBuffer[i]);
5591 this.receiveBuffer = [];
5593 for (i = 0; i < this.sendBuffer.length; i++) {
5594 this.packet(this.sendBuffer[i]);
5596 this.sendBuffer = [];
5600 * Called upon server disconnect.
5605 Socket.prototype.ondisconnect = function () {
5608 this.onclose('io server disconnect');
5612 * Called upon forced client/server side disconnections,
5613 * this method ensures the manager stops tracking us and
5614 * that reconnections don't get triggered for this.
5619 Socket.prototype.destroy = function () {
5621 // clean subscriptions to avoid reconnections
5622 for (var i = 0; i < this.subs.length; i++) {
5623 this.subs[i].destroy();
5628 this.io.destroy(this);
5632 * Disconnects the socket manually.
5634 * @return {Socket} self
5638 Socket.prototype.close = Socket.prototype.disconnect = function () {
5639 if (this.connected) {
5641 this.packet({ type: parser.DISCONNECT });
5644 // remove socket from pool
5647 if (this.connected) {
5649 this.onclose('io client disconnect');
5655 * Sets the compress flag.
5657 * @param {Boolean} if `true`, compresses the sending data
5658 * @return {Socket} self
5662 Socket.prototype.compress = function (compress) {
5663 this.flags.compress = compress;
5668 * Sets the binary flag
5670 * @param {Boolean} whether the emitted data contains binary
5671 * @return {Socket} self
5675 Socket.prototype.binary = function (binary) {
5676 this.flags.binary = binary;
5682 /***/ (function(module, exports) {
5684 module.exports = toArray
5686 function toArray(list, index) {
5691 for (var i = index || 0; i < list.length; i++) {
5692 array[i - index] = list[i]
5701 /***/ (function(module, exports) {
5709 module.exports = on;
5712 * Helper for subscriptions.
5714 * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
5715 * @param {String} event name
5716 * @param {Function} callback
5720 function on(obj, ev, fn) {
5723 destroy: function destroy() {
5724 obj.removeListener(ev, fn);
5731 /***/ (function(module, exports) {
5737 var slice = [].slice;
5740 * Bind `obj` to `fn`.
5742 * @param {Object} obj
5743 * @param {Function|String} fn or string
5744 * @return {Function}
5748 module.exports = function(obj, fn){
5749 if ('string' == typeof fn) fn = obj[fn];
5750 if ('function' != typeof fn) throw new Error('bind() requires a function');
5751 var args = slice.call(arguments, 2);
5753 return fn.apply(obj, args.concat(slice.call(arguments)));
5760 /***/ (function(module, exports) {
5767 module.exports = Backoff;
5770 * Initialize backoff timer with `opts`.
5772 * - `min` initial timeout in milliseconds [100]
5773 * - `max` max timeout [10000]
5777 * @param {Object} opts
5781 function Backoff(opts) {
5783 this.ms = opts.min || 100;
5784 this.max = opts.max || 10000;
5785 this.factor = opts.factor || 2;
5786 this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
5791 * Return the backoff duration.
5797 Backoff.prototype.duration = function(){
5798 var ms = this.ms * Math.pow(this.factor, this.attempts++);
5800 var rand = Math.random();
5801 var deviation = Math.floor(rand * this.jitter * ms);
5802 ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
5804 return Math.min(ms, this.max) | 0;
5808 * Reset the number of attempts.
5813 Backoff.prototype.reset = function(){
5818 * Set the minimum duration
5823 Backoff.prototype.setMin = function(min){
5828 * Set the maximum duration
5833 Backoff.prototype.setMax = function(max){
5843 Backoff.prototype.setJitter = function(jitter){
5844 this.jitter = jitter;
5853 //# sourceMappingURL=socket.io.slim.dev.js.map