aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/engine.io
diff options
context:
space:
mode:
authorYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
committerYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
commit67fdec20726e48ba3a934cb25bb30d47ec4a4f29 (patch)
tree37fd9f4f0b0c20103e1646fc83021e4765de3680 /node_modules/engine.io
downloadspanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz
spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/engine.io')
-rw-r--r--node_modules/engine.io/LICENSE19
-rw-r--r--node_modules/engine.io/README.md539
-rw-r--r--node_modules/engine.io/lib/engine.io.js126
-rw-r--r--node_modules/engine.io/lib/server.js579
-rw-r--r--node_modules/engine.io/lib/socket.js486
-rw-r--r--node_modules/engine.io/lib/transport.js128
-rw-r--r--node_modules/engine.io/lib/transports/index.js36
-rw-r--r--node_modules/engine.io/lib/transports/polling-jsonp.js75
-rw-r--r--node_modules/engine.io/lib/transports/polling-xhr.js69
-rw-r--r--node_modules/engine.io/lib/transports/polling.js407
-rw-r--r--node_modules/engine.io/lib/transports/websocket.js134
-rw-r--r--node_modules/engine.io/node_modules/accepts/HISTORY.md212
-rw-r--r--node_modules/engine.io/node_modules/accepts/LICENSE23
-rw-r--r--node_modules/engine.io/node_modules/accepts/README.md135
-rw-r--r--node_modules/engine.io/node_modules/accepts/index.js231
-rw-r--r--node_modules/engine.io/node_modules/accepts/package.json112
-rw-r--r--node_modules/engine.io/package.json137
17 files changed, 3448 insertions, 0 deletions
diff --git a/node_modules/engine.io/LICENSE b/node_modules/engine.io/LICENSE
new file mode 100644
index 0000000..6494c3c
--- /dev/null
+++ b/node_modules/engine.io/LICENSE
@@ -0,0 +1,19 @@
+(The MIT License)
+
+Copyright (c) 2014 Guillermo Rauch <guillermo@learnboost.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+and associated documentation files (the 'Software'), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/node_modules/engine.io/README.md b/node_modules/engine.io/README.md
new file mode 100644
index 0000000..1f5226d
--- /dev/null
+++ b/node_modules/engine.io/README.md
@@ -0,0 +1,539 @@
+
+# Engine.IO: the realtime engine
+
+[![Build Status](https://travis-ci.org/socketio/engine.io.svg?branch=master)](http://travis-ci.org/socketio/engine.io)
+[![NPM version](https://badge.fury.io/js/engine.io.svg)](http://badge.fury.io/js/engine.io)
+
+`Engine.IO` is the implementation of transport-based
+cross-browser/cross-device bi-directional communication layer for
+[Socket.IO](http://github.com/socketio/socket.io).
+
+## How to use
+
+### Server
+
+#### (A) Listening on a port
+
+```js
+var engine = require('engine.io');
+var server = engine.listen(80);
+
+server.on('connection', function(socket){
+ socket.send('utf 8 string');
+ socket.send(new Buffer([0, 1, 2, 3, 4, 5])); // binary data
+});
+```
+
+#### (B) Intercepting requests for a http.Server
+
+```js
+var engine = require('engine.io');
+var http = require('http').createServer().listen(3000);
+var server = engine.attach(http);
+
+server.on('connection', function (socket) {
+ socket.on('message', function(data){ });
+ socket.on('close', function(){ });
+});
+```
+
+#### (C) Passing in requests
+
+```js
+var engine = require('engine.io');
+var server = new engine.Server();
+
+server.on('connection', function(socket){
+ socket.send('hi');
+});
+
+// …
+httpServer.on('upgrade', function(req, socket, head){
+ server.handleUpgrade(req, socket, head);
+});
+httpServer.on('request', function(req, res){
+ server.handleRequest(req, res);
+});
+```
+
+### Client
+
+```html
+<script src="/path/to/engine.io.js"></script>
+<script>
+ var socket = new eio.Socket('ws://localhost/');
+ socket.on('open', function(){
+ socket.on('message', function(data){});
+ socket.on('close', function(){});
+ });
+</script>
+```
+
+For more information on the client refer to the
+[engine-client](http://github.com/learnboost/engine.io-client) repository.
+
+## What features does it have?
+
+- **Maximum reliability**. Connections are established even in the presence of:
+ - proxies and load balancers.
+ - personal firewall and antivirus software.
+ - for more information refer to **Goals** and **Architecture** sections
+- **Minimal client size** aided by:
+ - lazy loading of flash transports.
+ - lack of redundant transports.
+- **Scalable**
+ - load balancer friendly
+- **Future proof**
+- **100% Node.JS core style**
+ - No API sugar (left for higher level projects)
+ - Written in readable vanilla JavaScript
+
+## API
+
+### Server
+
+<hr><br>
+
+#### Top-level
+
+These are exposed by `require('engine.io')`:
+
+##### Events
+
+- `flush`
+ - Called when a socket buffer is being flushed.
+ - **Arguments**
+ - `Socket`: socket being flushed
+ - `Array`: write buffer
+- `drain`
+ - Called when a socket buffer is drained
+ - **Arguments**
+ - `Socket`: socket being flushed
+
+##### Properties
+
+- `protocol` _(Number)_: protocol revision number
+- `Server`: Server class constructor
+- `Socket`: Socket class constructor
+- `Transport` _(Function)_: transport constructor
+- `transports` _(Object)_: map of available transports
+
+##### Methods
+
+- `()`
+ - Returns a new `Server` instance. If the first argument is an `http.Server` then the
+ new `Server` instance will be attached to it. Otherwise, the arguments are passed
+ directly to the `Server` constructor.
+ - **Parameters**
+ - `http.Server`: optional, server to attach to.
+ - `Object`: optional, options object (see `Server#constructor` api docs below)
+
+ The following are identical ways to instantiate a server and then attach it.
+ ```js
+ var httpServer; // previously created with `http.createServer();` from node.js api.
+
+ // create a server first, and then attach
+ var eioServer = require('engine.io').Server();
+ eioServer.attach(httpServer);
+
+ // or call the module as a function to get `Server`
+ var eioServer = require('engine.io')();
+ eioServer.attach(httpServer);
+
+ // immediately attach
+ var eioServer = require('engine.io')(httpServer);
+ ```
+
+- `listen`
+ - Creates an `http.Server` which listens on the given port and attaches WS
+ to it. It returns `501 Not Implemented` for regular http requests.
+ - **Parameters**
+ - `Number`: port to listen on.
+ - `Object`: optional, options object
+ - `Function`: callback for `listen`.
+ - **Options**
+ - All options from `Server.attach` method, documented below.
+ - **Additionally** See Server `constructor` below for options you can pass for creating the new Server
+ - **Returns** `Server`
+- `attach`
+ - Captures `upgrade` requests for a `http.Server`. In other words, makes
+ a regular http.Server WebSocket-compatible.
+ - **Parameters**
+ - `http.Server`: server to attach to.
+ - `Object`: optional, options object
+ - **Options**
+ - All options from `Server.attach` method, documented below.
+ - **Additionally** See Server `constructor` below for options you can pass for creating the new Server
+ - **Returns** `Server` a new Server instance.
+
+<hr><br>
+
+#### Server
+
+The main server/manager. _Inherits from EventEmitter_.
+
+##### Events
+
+- `connection`
+ - Fired when a new connection is established.
+ - **Arguments**
+ - `Socket`: a Socket object
+
+##### Properties
+
+**Important**: if you plan to use Engine.IO in a scalable way, please
+keep in mind the properties below will only reflect the clients connected
+to a single process.
+
+- `clients` _(Object)_: hash of connected clients by id.
+- `clientsCount` _(Number)_: number of connected clients.
+
+##### Methods
+
+- **constructor**
+ - Initializes the server
+ - **Parameters**
+ - `Object`: optional, options object
+ - **Options**
+ - `pingTimeout` (`Number`): how many ms without a pong packet to
+ consider the connection closed (`60000`)
+ - `pingInterval` (`Number`): how many ms before sending a new ping
+ packet (`25000`)
+ - `upgradeTimeout` (`Number`): how many ms before an uncompleted transport upgrade is cancelled (`10000`)
+ - `maxHttpBufferSize` (`Number`): how many bytes or characters a message
+ can be, before closing the session (to avoid DoS). Default
+ value is `10E7`.
+ - `allowRequest` (`Function`): A function that receives a given handshake
+ or upgrade request as its first parameter, and can decide whether to
+ continue or not. The second argument is a function that needs to be
+ called with the decided information: `fn(err, success)`, where
+ `success` is a boolean value where false means that the request is
+ rejected, and err is an error code.
+ - `transports` (`<Array> String`): transports to allow connections
+ to (`['polling', 'websocket']`)
+ - `allowUpgrades` (`Boolean`): whether to allow transport upgrades
+ (`true`)
+ - `perMessageDeflate` (`Object|Boolean`): parameters of the WebSocket permessage-deflate extension
+ (see [ws module](https://github.com/einaros/ws) api docs). Set to `false` to disable. (`true`)
+ - `threshold` (`Number`): data is compressed only if the byte size is above this value (`1024`)
+ - `httpCompression` (`Object|Boolean`): parameters of the http compression for the polling transports
+ (see [zlib](http://nodejs.org/api/zlib.html#zlib_options) api docs). Set to `false` to disable. (`true`)
+ - `threshold` (`Number`): data is compressed only if the byte size is above this value (`1024`)
+ - `cookie` (`String|Boolean`): name of the HTTP cookie that
+ contains the client sid to send as part of handshake response
+ headers. Set to `false` to not send one. (`io`)
+ - `cookiePath` (`String|Boolean`): path of the above `cookie`
+ option. If false, no path will be sent, which means browsers will only send the cookie on the engine.io attached path (`/engine.io`).
+ Set false to not save io cookie on all requests. (`/`)
+ - `cookieHttpOnly` (`Boolean`): If `true` HttpOnly io cookie cannot be accessed by client-side APIs, such as JavaScript. (`true`) _This option has no effect if `cookie` or `cookiePath` is set to `false`._
+ - `wsEngine` (`String`): what WebSocket server implementation to use. Specified module must conform to the `ws` interface (see [ws module api docs](https://github.com/websockets/ws/blob/master/doc/ws.md)). Default value is `uws` (see [µWebSockets](https://github.com/uWebSockets/uWebSockets)).
+ - `initialPacket` (`Object`): an optional packet which will be concatenated to the handshake packet emitted by Engine.IO.
+- `close`
+ - Closes all clients
+ - **Returns** `Server` for chaining
+- `handleRequest`
+ - Called internally when a `Engine` request is intercepted.
+ - **Parameters**
+ - `http.IncomingMessage`: a node request object
+ - `http.ServerResponse`: a node response object
+ - **Returns** `Server` for chaining
+- `handleUpgrade`
+ - Called internally when a `Engine` ws upgrade is intercepted.
+ - **Parameters** (same as `upgrade` event)
+ - `http.IncomingMessage`: a node request object
+ - `net.Stream`: TCP socket for the request
+ - `Buffer`: legacy tail bytes
+ - **Returns** `Server` for chaining
+- `attach`
+ - Attach this Server instance to an `http.Server`
+ - Captures `upgrade` requests for a `http.Server`. In other words, makes
+ a regular http.Server WebSocket-compatible.
+ - **Parameters**
+ - `http.Server`: server to attach to.
+ - `Object`: optional, options object
+ - **Options**
+ - `path` (`String`): name of the path to capture (`/engine.io`).
+ - `destroyUpgrade` (`Boolean`): destroy unhandled upgrade requests (`true`)
+ - `destroyUpgradeTimeout` (`Number`): milliseconds after which unhandled requests are ended (`1000`)
+ - `handlePreflightRequest` (`Boolean|Function`): whether to let engine.io handle the OPTIONS requests. You can also pass a custom function to handle the requests (`true`)
+- `generateId`
+ - Generate a socket id.
+ - Overwrite this method to generate your custom socket id.
+ - **Parameters**
+ - `http.IncomingMessage`: a node request object
+ - **Returns** A socket id for connected client.
+
+<hr><br>
+
+#### Socket
+
+A representation of a client. _Inherits from EventEmitter_.
+
+##### Events
+
+- `close`
+ - Fired when the client is disconnected.
+ - **Arguments**
+ - `String`: reason for closing
+ - `Object`: description object (optional)
+- `message`
+ - Fired when the client sends a message.
+ - **Arguments**
+ - `String` or `Buffer`: Unicode string or Buffer with binary contents
+- `error`
+ - Fired when an error occurs.
+ - **Arguments**
+ - `Error`: error object
+- `flush`
+ - Called when the write buffer is being flushed.
+ - **Arguments**
+ - `Array`: write buffer
+- `drain`
+ - Called when the write buffer is drained
+- `packet`
+ - Called when a socket received a packet (`message`, `ping`)
+ - **Arguments**
+ - `type`: packet type
+ - `data`: packet data (if type is message)
+- `packetCreate`
+ - Called before a socket sends a packet (`message`, `pong`)
+ - **Arguments**
+ - `type`: packet type
+ - `data`: packet data (if type is message)
+
+##### Properties
+
+- `id` _(String)_: unique identifier
+- `server` _(Server)_: engine parent reference
+- `request` _(http.IncomingMessage)_: request that originated the Socket
+- `upgraded` _(Boolean)_: whether the transport has been upgraded
+- `readyState` _(String)_: opening|open|closing|closed
+- `transport` _(Transport)_: transport reference
+
+##### Methods
+
+- `send`:
+ - Sends a message, performing `message = toString(arguments[0])` unless
+ sending binary data, which is sent as is.
+ - **Parameters**
+ - `String` | `Buffer` | `ArrayBuffer` | `ArrayBufferView`: a string or any object implementing `toString()`, with outgoing data, or a Buffer or ArrayBuffer with binary data. Also any ArrayBufferView can be sent as is.
+ - `Object`: optional, options object
+ - `Function`: optional, a callback executed when the message gets flushed out by the transport
+ - **Options**
+ - `compress` (`Boolean`): whether to compress sending data. This option might be ignored and forced to be `true` when using polling. (`true`)
+ - **Returns** `Socket` for chaining
+- `close`
+ - Disconnects the client
+ - **Returns** `Socket` for chaining
+
+### Client
+
+<hr><br>
+
+Exposed in the `eio` global namespace (in the browser), or by
+`require('engine.io-client')` (in Node.JS).
+
+For the client API refer to the
+[engine-client](http://github.com/learnboost/engine.io-client) repository.
+
+## Debug / logging
+
+Engine.IO is powered by [debug](http://github.com/visionmedia/debug).
+In order to see all the debug output, run your app with the environment variable
+`DEBUG` including the desired scope.
+
+To see the output from all of Engine.IO's debugging scopes you can use:
+
+```
+DEBUG=engine* node myapp
+```
+
+## Transports
+
+- `polling`: XHR / JSONP polling transport.
+- `websocket`: WebSocket transport.
+
+## Plugins
+
+- [engine.io-conflation](https://github.com/EugenDueck/engine.io-conflation): Makes **conflation and aggregation** of messages straightforward.
+
+## Support
+
+The support channels for `engine.io` are the same as `socket.io`:
+ - irc.freenode.net **#socket.io**
+ - [Google Groups](http://groups.google.com/group/socket_io)
+ - [Website](http://socket.io)
+
+## Development
+
+To contribute patches, run tests or benchmarks, make sure to clone the
+repository:
+
+```
+git clone git://github.com/LearnBoost/engine.io.git
+```
+
+Then:
+
+```
+cd engine.io
+npm install
+```
+
+## Tests
+
+Tests run with `make test`. It runs the server tests that are aided by
+the usage of `engine.io-client`.
+
+Make sure `npm install` is run first.
+
+## Goals
+
+The main goal of `Engine` is ensuring the most reliable realtime communication.
+Unlike the previous Socket.IO core, it always establishes a long-polling
+connection first, then tries to upgrade to better transports that are "tested" on
+the side.
+
+During the lifetime of the Socket.IO projects, we've found countless drawbacks
+to relying on `HTML5 WebSocket` or `Flash Socket` as the first connection
+mechanisms.
+
+Both are clearly the _right way_ of establishing a bidirectional communication,
+with HTML5 WebSocket being the way of the future. However, to answer most business
+needs, alternative traditional HTTP 1.1 mechanisms are just as good as delivering
+the same solution.
+
+WebSocket based connections have two fundamental benefits:
+
+1. **Better server performance**
+ - _A: Load balancers_<br>
+ Load balancing a long polling connection poses a serious architectural nightmare
+ since requests can come from any number of open sockets by the user agent, but
+ they all need to be routed to the process and computer that owns the `Engine`
+ connection. This negatively impacts RAM and CPU usage.
+ - _B: Network traffic_<br>
+ WebSocket is designed around the premise that each message frame has to be
+ surrounded by the least amount of data. In HTTP 1.1 transports, each message
+ frame is surrounded by HTTP headers and chunked encoding frames. If you try to
+ send the message _"Hello world"_ with xhr-polling, the message ultimately
+ becomes larger than if you were to send it with WebSocket.
+ - _C: Lightweight parser_<br>
+ As an effect of **B**, the server has to do a lot more work to parse the network
+ data and figure out the message when traditional HTTP requests are used
+ (as in long polling). This means that another advantage of WebSocket is
+ less server CPU usage.
+
+2. **Better user experience**
+
+ Due to the reasons stated in point **1**, the most important effect of being able
+ to establish a WebSocket connection is raw data transfer speed, which translates
+ in _some_ cases in better user experience.
+
+ Applications with heavy realtime interaction (such as games) will benefit greatly,
+ whereas applications like realtime chat (Gmail/Facebook), newsfeeds (Facebook) or
+ timelines (Twitter) will have negligible user experience improvements.
+
+Having said this, attempting to establish a WebSocket connection directly so far has
+proven problematic:
+
+1. **Proxies**<br>
+ Many corporate proxies block WebSocket traffic.
+
+2. **Personal firewall and antivirus software**<br>
+ As a result of our research, we've found that at least 3 personal security
+ applications block WebSocket traffic.
+
+3. **Cloud application platforms**<br>
+ Platforms like Heroku or No.de have had trouble keeping up with the fast-paced
+ nature of the evolution of the WebSocket protocol. Applications therefore end up
+ inevitably using long polling, but the seamless installation experience of
+ Socket.IO we strive for (_"require() it and it just works"_) disappears.
+
+Some of these problems have solutions. In the case of proxies and personal programs,
+however, the solutions many times involve upgrading software. Experience has shown
+that relying on client software upgrades to deliver a business solution is
+fruitless: the very existence of this project has to do with a fragmented panorama
+of user agent distribution, with clients connecting with latest versions of the most
+modern user agents (Chrome, Firefox and Safari), but others with versions as low as
+IE 5.5.
+
+From the user perspective, an unsuccessful WebSocket connection can translate in
+up to at least 10 seconds of waiting for the realtime application to begin
+exchanging data. This **perceptively** hurts user experience.
+
+To summarize, **Engine** focuses on reliability and user experience first, marginal
+potential UX improvements and increased server performance second. `Engine` is the
+result of all the lessons learned with WebSocket in the wild.
+
+## Architecture
+
+The main premise of `Engine`, and the core of its existence, is the ability to
+swap transports on the fly. A connection starts as xhr-polling, but it can
+switch to WebSocket.
+
+The central problem this poses is: how do we switch transports without losing
+messages?
+
+`Engine` only switches from polling to another transport in between polling
+cycles. Since the server closes the connection after a certain timeout when
+there's no activity, and the polling transport implementation buffers messages
+in between connections, this ensures no message loss and optimal performance.
+
+Another benefit of this design is that we workaround almost all the limitations
+of **Flash Socket**, such as slow connection times, increased file size (we can
+safely lazy load it without hurting user experience), etc.
+
+## FAQ
+
+### Can I use engine without Socket.IO ?
+
+Absolutely. Although the recommended framework for building realtime applications
+is Socket.IO, since it provides fundamental features for real-world applications
+such as multiplexing, reconnection support, etc.
+
+`Engine` is to Socket.IO what Connect is to Express. An essential piece for building
+realtime frameworks, but something you _probably_ won't be using for building
+actual applications.
+
+### Does the server serve the client?
+
+No. The main reason is that `Engine` is meant to be bundled with frameworks.
+Socket.IO includes `Engine`, therefore serving two clients is not necessary. If
+you use Socket.IO, including
+
+```html
+<script src="/socket.io/socket.io.js">
+```
+
+has you covered.
+
+### Can I implement `Engine` in other languages?
+
+Absolutely. The [engine.io-protocol](https://github.com/LearnBoost/engine.io-protocol)
+repository contains the most up to date description of the specification
+at all times, and the parser implementation in JavaScript.
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2014 Guillermo Rauch &lt;guillermo@learnboost.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/engine.io/lib/engine.io.js b/node_modules/engine.io/lib/engine.io.js
new file mode 100644
index 0000000..2a211c2
--- /dev/null
+++ b/node_modules/engine.io/lib/engine.io.js
@@ -0,0 +1,126 @@
+/**
+ * Module dependencies.
+ */
+
+var http = require('http');
+
+/**
+ * Invoking the library as a function delegates to attach if the first argument
+ * is an `http.Server`.
+ *
+ * If there are no arguments or the first argument is an options object, then
+ * a new Server instance is returned.
+ *
+ * @param {http.Server} server (if specified, will be attached to by the new Server instance)
+ * @param {Object} options
+ * @return {Server} engine server
+ * @api public
+ */
+
+exports = module.exports = function () {
+ // backwards compatible use as `.attach`
+ // if first argument is an http server
+ if (arguments.length && arguments[0] instanceof http.Server) {
+ return attach.apply(this, arguments);
+ }
+
+ // if first argument is not an http server, then just make a regular eio server
+ return exports.Server.apply(null, arguments);
+};
+
+/**
+ * Protocol revision number.
+ *
+ * @api public
+ */
+
+exports.protocol = 1;
+
+/**
+ * Expose Server constructor.
+ *
+ * @api public
+ */
+
+exports.Server = require('./server');
+
+/**
+ * Expose Socket constructor.
+ *
+ * @api public
+ */
+
+exports.Socket = require('./socket');
+
+/**
+ * Expose Transport constructor.
+ *
+ * @api public
+ */
+
+exports.Transport = require('./transport');
+
+/**
+ * Expose mutable list of available transports.
+ *
+ * @api public
+ */
+
+exports.transports = require('./transports');
+
+/**
+ * Exports parser.
+ *
+ * @api public
+ */
+
+exports.parser = require('engine.io-parser');
+
+/**
+ * Creates an http.Server exclusively used for WS upgrades.
+ *
+ * @param {Number} port
+ * @param {Function} callback
+ * @param {Object} options
+ * @return {Server} websocket.io server
+ * @api public
+ */
+
+exports.listen = listen;
+
+function listen (port, options, fn) {
+ if ('function' === typeof options) {
+ fn = options;
+ options = {};
+ }
+
+ var server = http.createServer(function (req, res) {
+ res.writeHead(501);
+ res.end('Not Implemented');
+ });
+
+ // create engine server
+ var engine = exports.attach(server, options);
+ engine.httpServer = server;
+
+ server.listen(port, fn);
+
+ return engine;
+}
+
+/**
+ * Captures upgrade requests for a http.Server.
+ *
+ * @param {http.Server} server
+ * @param {Object} options
+ * @return {Server} engine server
+ * @api public
+ */
+
+exports.attach = attach;
+
+function attach (server, options) {
+ var engine = new exports.Server(options);
+ engine.attach(server, options);
+ return engine;
+}
diff --git a/node_modules/engine.io/lib/server.js b/node_modules/engine.io/lib/server.js
new file mode 100644
index 0000000..d52120a
--- /dev/null
+++ b/node_modules/engine.io/lib/server.js
@@ -0,0 +1,579 @@
+
+/**
+ * Module dependencies.
+ */
+
+var qs = require('querystring');
+var parse = require('url').parse;
+var base64id = require('base64id');
+var transports = require('./transports');
+var EventEmitter = require('events').EventEmitter;
+var Socket = require('./socket');
+var util = require('util');
+var debug = require('debug')('engine');
+var cookieMod = require('cookie');
+
+/**
+ * Module exports.
+ */
+
+module.exports = Server;
+
+/**
+ * Server constructor.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+function Server (opts) {
+ if (!(this instanceof Server)) {
+ return new Server(opts);
+ }
+
+ this.clients = {};
+ this.clientsCount = 0;
+
+ opts = opts || {};
+
+ this.wsEngine = opts.wsEngine || process.env.EIO_WS_ENGINE || 'uws';
+ this.pingTimeout = opts.pingTimeout || 60000;
+ this.pingInterval = opts.pingInterval || 25000;
+ this.upgradeTimeout = opts.upgradeTimeout || 10000;
+ this.maxHttpBufferSize = opts.maxHttpBufferSize || 10E7;
+ this.transports = opts.transports || Object.keys(transports);
+ this.allowUpgrades = false !== opts.allowUpgrades;
+ this.allowRequest = opts.allowRequest;
+ this.cookie = false !== opts.cookie ? (opts.cookie || 'io') : false;
+ this.cookiePath = false !== opts.cookiePath ? (opts.cookiePath || '/') : false;
+ this.cookieHttpOnly = false !== opts.cookieHttpOnly;
+ this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || true) : false;
+ this.httpCompression = false !== opts.httpCompression ? (opts.httpCompression || {}) : false;
+ this.initialPacket = opts.initialPacket;
+
+ var self = this;
+
+ // initialize compression options
+ ['perMessageDeflate', 'httpCompression'].forEach(function (type) {
+ var compression = self[type];
+ if (true === compression) self[type] = compression = {};
+ if (compression && null == compression.threshold) {
+ compression.threshold = 1024;
+ }
+ });
+
+ this.init();
+}
+
+/**
+ * Protocol errors mappings.
+ */
+
+Server.errors = {
+ UNKNOWN_TRANSPORT: 0,
+ UNKNOWN_SID: 1,
+ BAD_HANDSHAKE_METHOD: 2,
+ BAD_REQUEST: 3,
+ FORBIDDEN: 4
+};
+
+Server.errorMessages = {
+ 0: 'Transport unknown',
+ 1: 'Session ID unknown',
+ 2: 'Bad handshake method',
+ 3: 'Bad request',
+ 4: 'Forbidden'
+};
+
+/**
+ * Inherits from EventEmitter.
+ */
+
+util.inherits(Server, EventEmitter);
+
+/**
+ * Initialize websocket server
+ *
+ * @api private
+ */
+
+Server.prototype.init = function () {
+ if (!~this.transports.indexOf('websocket')) return;
+
+ if (this.ws) this.ws.close();
+
+ var wsModule;
+ try {
+ switch (this.wsEngine) {
+ case 'uws': wsModule = require('uws'); break;
+ case 'ws': wsModule = require('ws'); break;
+ default: throw new Error('unknown wsEngine');
+ }
+ } catch (ex) {
+ this.wsEngine = 'ws';
+ // keep require('ws') as separate expression for packers (browserify, etc)
+ wsModule = require('ws');
+ }
+ this.ws = new wsModule.Server({
+ noServer: true,
+ clientTracking: false,
+ perMessageDeflate: this.perMessageDeflate,
+ maxPayload: this.maxHttpBufferSize
+ });
+};
+
+/**
+ * Returns a list of available transports for upgrade given a certain transport.
+ *
+ * @return {Array}
+ * @api public
+ */
+
+Server.prototype.upgrades = function (transport) {
+ if (!this.allowUpgrades) return [];
+ return transports[transport].upgradesTo || [];
+};
+
+/**
+ * Verifies a request.
+ *
+ * @param {http.IncomingMessage}
+ * @return {Boolean} whether the request is valid
+ * @api private
+ */
+
+Server.prototype.verify = function (req, upgrade, fn) {
+ // transport check
+ var transport = req._query.transport;
+ if (!~this.transports.indexOf(transport)) {
+ debug('unknown transport "%s"', transport);
+ return fn(Server.errors.UNKNOWN_TRANSPORT, false);
+ }
+
+ // 'Origin' header check
+ var isOriginInvalid = checkInvalidHeaderChar(req.headers.origin);
+ if (isOriginInvalid) {
+ req.headers.origin = null;
+ return fn(Server.errors.BAD_REQUEST, false);
+ }
+
+ // sid check
+ var sid = req._query.sid;
+ if (sid) {
+ if (!this.clients.hasOwnProperty(sid)) {
+ return fn(Server.errors.UNKNOWN_SID, false);
+ }
+ if (!upgrade && this.clients[sid].transport.name !== transport) {
+ debug('bad request: unexpected transport without upgrade');
+ return fn(Server.errors.BAD_REQUEST, false);
+ }
+ } else {
+ // handshake is GET only
+ if ('GET' !== req.method) return fn(Server.errors.BAD_HANDSHAKE_METHOD, false);
+ if (!this.allowRequest) return fn(null, true);
+ return this.allowRequest(req, fn);
+ }
+
+ fn(null, true);
+};
+
+/**
+ * Prepares a request by processing the query string.
+ *
+ * @api private
+ */
+
+Server.prototype.prepare = function (req) {
+ // try to leverage pre-existing `req._query` (e.g: from connect)
+ if (!req._query) {
+ req._query = ~req.url.indexOf('?') ? qs.parse(parse(req.url).query) : {};
+ }
+};
+
+/**
+ * Closes all clients.
+ *
+ * @api public
+ */
+
+Server.prototype.close = function () {
+ debug('closing all open clients');
+ for (var i in this.clients) {
+ if (this.clients.hasOwnProperty(i)) {
+ this.clients[i].close(true);
+ }
+ }
+ if (this.ws) {
+ debug('closing webSocketServer');
+ this.ws.close();
+ // don't delete this.ws because it can be used again if the http server starts listening again
+ }
+ return this;
+};
+
+/**
+ * Handles an Engine.IO HTTP request.
+ *
+ * @param {http.IncomingMessage} request
+ * @param {http.ServerResponse|http.OutgoingMessage} response
+ * @api public
+ */
+
+Server.prototype.handleRequest = function (req, res) {
+ debug('handling "%s" http request "%s"', req.method, req.url);
+ this.prepare(req);
+ req.res = res;
+
+ var self = this;
+ this.verify(req, false, function (err, success) {
+ if (!success) {
+ sendErrorMessage(req, res, err);
+ return;
+ }
+
+ if (req._query.sid) {
+ debug('setting new request for existing client');
+ self.clients[req._query.sid].transport.onRequest(req);
+ } else {
+ self.handshake(req._query.transport, req);
+ }
+ });
+};
+
+/**
+ * Sends an Engine.IO Error Message
+ *
+ * @param {http.ServerResponse} response
+ * @param {code} error code
+ * @api private
+ */
+
+function sendErrorMessage (req, res, code) {
+ var headers = { 'Content-Type': 'application/json' };
+
+ var isForbidden = !Server.errorMessages.hasOwnProperty(code);
+ if (isForbidden) {
+ res.writeHead(403, headers);
+ res.end(JSON.stringify({
+ code: Server.errors.FORBIDDEN,
+ message: code || Server.errorMessages[Server.errors.FORBIDDEN]
+ }));
+ return;
+ }
+ if (req.headers.origin) {
+ headers['Access-Control-Allow-Credentials'] = 'true';
+ headers['Access-Control-Allow-Origin'] = req.headers.origin;
+ } else {
+ headers['Access-Control-Allow-Origin'] = '*';
+ }
+ res.writeHead(400, headers);
+ res.end(JSON.stringify({
+ code: code,
+ message: Server.errorMessages[code]
+ }));
+}
+
+/**
+ * generate a socket id.
+ * Overwrite this method to generate your custom socket id
+ *
+ * @param {Object} request object
+ * @api public
+ */
+
+Server.prototype.generateId = function (req) {
+ return base64id.generateId();
+};
+
+/**
+ * Handshakes a new client.
+ *
+ * @param {String} transport name
+ * @param {Object} request object
+ * @api private
+ */
+
+Server.prototype.handshake = function (transportName, req) {
+ var id = this.generateId(req);
+
+ debug('handshaking client "%s"', id);
+
+ try {
+ var transport = new transports[transportName](req);
+ if ('polling' === transportName) {
+ transport.maxHttpBufferSize = this.maxHttpBufferSize;
+ transport.httpCompression = this.httpCompression;
+ } else if ('websocket' === transportName) {
+ transport.perMessageDeflate = this.perMessageDeflate;
+ }
+
+ if (req._query && req._query.b64) {
+ transport.supportsBinary = false;
+ } else {
+ transport.supportsBinary = true;
+ }
+ } catch (e) {
+ sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
+ return;
+ }
+ var socket = new Socket(id, this, transport, req);
+ var self = this;
+
+ if (false !== this.cookie) {
+ transport.on('headers', function (headers) {
+ headers['Set-Cookie'] = cookieMod.serialize(self.cookie, id,
+ {
+ path: self.cookiePath,
+ httpOnly: self.cookiePath ? self.cookieHttpOnly : false
+ });
+ });
+ }
+
+ transport.onRequest(req);
+
+ this.clients[id] = socket;
+ this.clientsCount++;
+
+ socket.once('close', function () {
+ delete self.clients[id];
+ self.clientsCount--;
+ });
+
+ this.emit('connection', socket);
+};
+
+/**
+ * Handles an Engine.IO HTTP Upgrade.
+ *
+ * @api public
+ */
+
+Server.prototype.handleUpgrade = function (req, socket, upgradeHead) {
+ this.prepare(req);
+
+ var self = this;
+ this.verify(req, true, function (err, success) {
+ if (!success) {
+ abortConnection(socket, err);
+ return;
+ }
+
+ var head = new Buffer(upgradeHead.length); // eslint-disable-line node/no-deprecated-api
+ upgradeHead.copy(head);
+ upgradeHead = null;
+
+ // delegate to ws
+ self.ws.handleUpgrade(req, socket, head, function (conn) {
+ self.onWebSocket(req, conn);
+ });
+ });
+};
+
+/**
+ * Called upon a ws.io connection.
+ *
+ * @param {ws.Socket} websocket
+ * @api private
+ */
+
+Server.prototype.onWebSocket = function (req, socket) {
+ socket.on('error', onUpgradeError);
+
+ if (!transports[req._query.transport].prototype.handlesUpgrades) {
+ debug('transport doesnt handle upgraded requests');
+ socket.close();
+ return;
+ }
+
+ // get client id
+ var id = req._query.sid;
+
+ // keep a reference to the ws.Socket
+ req.websocket = socket;
+
+ if (id) {
+ var client = this.clients[id];
+ if (!client) {
+ debug('upgrade attempt for closed client');
+ socket.close();
+ } else if (client.upgrading) {
+ debug('transport has already been trying to upgrade');
+ socket.close();
+ } else if (client.upgraded) {
+ debug('transport had already been upgraded');
+ socket.close();
+ } else {
+ debug('upgrading existing transport');
+
+ // transport error handling takes over
+ socket.removeListener('error', onUpgradeError);
+
+ var transport = new transports[req._query.transport](req);
+ if (req._query && req._query.b64) {
+ transport.supportsBinary = false;
+ } else {
+ transport.supportsBinary = true;
+ }
+ transport.perMessageDeflate = this.perMessageDeflate;
+ client.maybeUpgrade(transport);
+ }
+ } else {
+ // transport error handling takes over
+ socket.removeListener('error', onUpgradeError);
+
+ this.handshake(req._query.transport, req);
+ }
+
+ function onUpgradeError () {
+ debug('websocket error before upgrade');
+ // socket.close() not needed
+ }
+};
+
+/**
+ * Captures upgrade requests for a http.Server.
+ *
+ * @param {http.Server} server
+ * @param {Object} options
+ * @api public
+ */
+
+Server.prototype.attach = function (server, options) {
+ var self = this;
+ options = options || {};
+ var path = (options.path || '/engine.io').replace(/\/$/, '');
+
+ var destroyUpgradeTimeout = options.destroyUpgradeTimeout || 1000;
+
+ // normalize path
+ path += '/';
+
+ function check (req) {
+ if ('OPTIONS' === req.method && false === options.handlePreflightRequest) {
+ return false;
+ }
+ return path === req.url.substr(0, path.length);
+ }
+
+ // cache and clean up listeners
+ var listeners = server.listeners('request').slice(0);
+ server.removeAllListeners('request');
+ server.on('close', self.close.bind(self));
+ server.on('listening', self.init.bind(self));
+
+ // add request handler
+ server.on('request', function (req, res) {
+ if (check(req)) {
+ debug('intercepting request for path "%s"', path);
+ if ('OPTIONS' === req.method && 'function' === typeof options.handlePreflightRequest) {
+ options.handlePreflightRequest.call(server, req, res);
+ } else {
+ self.handleRequest(req, res);
+ }
+ } else {
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i].call(server, req, res);
+ }
+ }
+ });
+
+ if (~self.transports.indexOf('websocket')) {
+ server.on('upgrade', function (req, socket, head) {
+ if (check(req)) {
+ self.handleUpgrade(req, socket, head);
+ } else if (false !== options.destroyUpgrade) {
+ // default node behavior is to disconnect when no handlers
+ // but by adding a handler, we prevent that
+ // and if no eio thing handles the upgrade
+ // then the socket needs to die!
+ setTimeout(function () {
+ if (socket.writable && socket.bytesWritten <= 0) {
+ return socket.end();
+ }
+ }, destroyUpgradeTimeout);
+ }
+ });
+ }
+};
+
+/**
+ * Closes the connection
+ *
+ * @param {net.Socket} socket
+ * @param {code} error code
+ * @api private
+ */
+
+function abortConnection (socket, code) {
+ if (socket.writable) {
+ var message = Server.errorMessages.hasOwnProperty(code) ? Server.errorMessages[code] : (code || '');
+ var length = Buffer.byteLength(message);
+ socket.write(
+ 'HTTP/1.1 400 Bad Request\r\n' +
+ 'Connection: close\r\n' +
+ 'Content-type: text/html\r\n' +
+ 'Content-Length: ' + length + '\r\n' +
+ '\r\n' +
+ message
+ );
+ }
+ socket.destroy();
+}
+
+/* eslint-disable */
+
+/**
+ * From https://github.com/nodejs/node/blob/v8.4.0/lib/_http_common.js#L303-L354
+ *
+ * True if val contains an invalid field-vchar
+ * field-value = *( field-content / obs-fold )
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+ * field-vchar = VCHAR / obs-text
+ *
+ * checkInvalidHeaderChar() is currently designed to be inlinable by v8,
+ * so take care when making changes to the implementation so that the source
+ * code size does not exceed v8's default max_inlined_source_size setting.
+ **/
+var validHdrChars = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // 0 - 15
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 32 - 47
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 48 - 63
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 80 - 95
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 112 - 127
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 128 ...
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // ... 255
+];
+
+function checkInvalidHeaderChar(val) {
+ val += '';
+ if (val.length < 1)
+ return false;
+ if (!validHdrChars[val.charCodeAt(0)])
+ return true;
+ if (val.length < 2)
+ return false;
+ if (!validHdrChars[val.charCodeAt(1)])
+ return true;
+ if (val.length < 3)
+ return false;
+ if (!validHdrChars[val.charCodeAt(2)])
+ return true;
+ if (val.length < 4)
+ return false;
+ if (!validHdrChars[val.charCodeAt(3)])
+ return true;
+ for (var i = 4; i < val.length; ++i) {
+ if (!validHdrChars[val.charCodeAt(i)])
+ return true;
+ }
+ return false;
+}
diff --git a/node_modules/engine.io/lib/socket.js b/node_modules/engine.io/lib/socket.js
new file mode 100644
index 0000000..177b25c
--- /dev/null
+++ b/node_modules/engine.io/lib/socket.js
@@ -0,0 +1,486 @@
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter;
+var util = require('util');
+var debug = require('debug')('engine:socket');
+
+/**
+ * Module exports.
+ */
+
+module.exports = Socket;
+
+/**
+ * Client class (abstract).
+ *
+ * @api private
+ */
+
+function Socket (id, server, transport, req) {
+ this.id = id;
+ this.server = server;
+ this.upgrading = false;
+ this.upgraded = false;
+ this.readyState = 'opening';
+ this.writeBuffer = [];
+ this.packetsFn = [];
+ this.sentCallbackFn = [];
+ this.cleanupFn = [];
+ this.request = req;
+
+ // Cache IP since it might not be in the req later
+ if (req.websocket && req.websocket._socket) {
+ this.remoteAddress = req.websocket._socket.remoteAddress;
+ } else {
+ this.remoteAddress = req.connection.remoteAddress;
+ }
+
+ this.checkIntervalTimer = null;
+ this.upgradeTimeoutTimer = null;
+ this.pingTimeoutTimer = null;
+
+ this.setTransport(transport);
+ this.onOpen();
+}
+
+/**
+ * Inherits from EventEmitter.
+ */
+
+util.inherits(Socket, EventEmitter);
+
+/**
+ * Called upon transport considered open.
+ *
+ * @api private
+ */
+
+Socket.prototype.onOpen = function () {
+ this.readyState = 'open';
+
+ // sends an `open` packet
+ this.transport.sid = this.id;
+ this.sendPacket('open', JSON.stringify({
+ sid: this.id,
+ upgrades: this.getAvailableUpgrades(),
+ pingInterval: this.server.pingInterval,
+ pingTimeout: this.server.pingTimeout
+ }));
+
+ if (this.server.initialPacket) {
+ this.sendPacket('message', this.server.initialPacket);
+ }
+
+ this.emit('open');
+ this.setPingTimeout();
+};
+
+/**
+ * Called upon transport packet.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+Socket.prototype.onPacket = function (packet) {
+ if ('open' === this.readyState) {
+ // export packet event
+ debug('packet');
+ this.emit('packet', packet);
+
+ // Reset ping timeout on any packet, incoming data is a good sign of
+ // other side's liveness
+ this.setPingTimeout();
+
+ switch (packet.type) {
+ case 'ping':
+ debug('got ping');
+ this.sendPacket('pong');
+ this.emit('heartbeat');
+ break;
+
+ case 'error':
+ this.onClose('parse error');
+ break;
+
+ case 'message':
+ this.emit('data', packet.data);
+ this.emit('message', packet.data);
+ break;
+ }
+ } else {
+ debug('packet received with closed socket');
+ }
+};
+
+/**
+ * Called upon transport error.
+ *
+ * @param {Error} error object
+ * @api private
+ */
+
+Socket.prototype.onError = function (err) {
+ debug('transport error');
+ this.onClose('transport error', err);
+};
+
+/**
+ * Sets and resets ping timeout timer based on client pings.
+ *
+ * @api private
+ */
+
+Socket.prototype.setPingTimeout = function () {
+ var self = this;
+ clearTimeout(self.pingTimeoutTimer);
+ self.pingTimeoutTimer = setTimeout(function () {
+ self.onClose('ping timeout');
+ }, self.server.pingInterval + self.server.pingTimeout);
+};
+
+/**
+ * Attaches handlers for the given transport.
+ *
+ * @param {Transport} transport
+ * @api private
+ */
+
+Socket.prototype.setTransport = function (transport) {
+ var onError = this.onError.bind(this);
+ var onPacket = this.onPacket.bind(this);
+ var flush = this.flush.bind(this);
+ var onClose = this.onClose.bind(this, 'transport close');
+
+ this.transport = transport;
+ this.transport.once('error', onError);
+ this.transport.on('packet', onPacket);
+ this.transport.on('drain', flush);
+ this.transport.once('close', onClose);
+ // this function will manage packet events (also message callbacks)
+ this.setupSendCallback();
+
+ this.cleanupFn.push(function () {
+ transport.removeListener('error', onError);
+ transport.removeListener('packet', onPacket);
+ transport.removeListener('drain', flush);
+ transport.removeListener('close', onClose);
+ });
+};
+
+/**
+ * Upgrades socket to the given transport
+ *
+ * @param {Transport} transport
+ * @api private
+ */
+
+Socket.prototype.maybeUpgrade = function (transport) {
+ debug('might upgrade socket transport from "%s" to "%s"'
+ , this.transport.name, transport.name);
+
+ this.upgrading = true;
+
+ var self = this;
+
+ // set transport upgrade timer
+ self.upgradeTimeoutTimer = setTimeout(function () {
+ debug('client did not complete upgrade - closing transport');
+ cleanup();
+ if ('open' === transport.readyState) {
+ transport.close();
+ }
+ }, this.server.upgradeTimeout);
+
+ function onPacket (packet) {
+ if ('ping' === packet.type && 'probe' === packet.data) {
+ transport.send([{ type: 'pong', data: 'probe' }]);
+ self.emit('upgrading', transport);
+ clearInterval(self.checkIntervalTimer);
+ self.checkIntervalTimer = setInterval(check, 100);
+ } else if ('upgrade' === packet.type && self.readyState !== 'closed') {
+ debug('got upgrade packet - upgrading');
+ cleanup();
+ self.transport.discard();
+ self.upgraded = true;
+ self.clearTransport();
+ self.setTransport(transport);
+ self.emit('upgrade', transport);
+ self.setPingTimeout();
+ self.flush();
+ if (self.readyState === 'closing') {
+ transport.close(function () {
+ self.onClose('forced close');
+ });
+ }
+ } else {
+ cleanup();
+ transport.close();
+ }
+ }
+
+ // we force a polling cycle to ensure a fast upgrade
+ function check () {
+ if ('polling' === self.transport.name && self.transport.writable) {
+ debug('writing a noop packet to polling for fast upgrade');
+ self.transport.send([{ type: 'noop' }]);
+ }
+ }
+
+ function cleanup () {
+ self.upgrading = false;
+
+ clearInterval(self.checkIntervalTimer);
+ self.checkIntervalTimer = null;
+
+ clearTimeout(self.upgradeTimeoutTimer);
+ self.upgradeTimeoutTimer = null;
+
+ transport.removeListener('packet', onPacket);
+ transport.removeListener('close', onTransportClose);
+ transport.removeListener('error', onError);
+ self.removeListener('close', onClose);
+ }
+
+ function onError (err) {
+ debug('client did not complete upgrade - %s', err);
+ cleanup();
+ transport.close();
+ transport = null;
+ }
+
+ function onTransportClose () {
+ onError('transport closed');
+ }
+
+ function onClose () {
+ onError('socket closed');
+ }
+
+ transport.on('packet', onPacket);
+ transport.once('close', onTransportClose);
+ transport.once('error', onError);
+
+ self.once('close', onClose);
+};
+
+/**
+ * Clears listeners and timers associated with current transport.
+ *
+ * @api private
+ */
+
+Socket.prototype.clearTransport = function () {
+ var cleanup;
+
+ var toCleanUp = this.cleanupFn.length;
+
+ for (var i = 0; i < toCleanUp; i++) {
+ cleanup = this.cleanupFn.shift();
+ cleanup();
+ }
+
+ // silence further transport errors and prevent uncaught exceptions
+ this.transport.on('error', function () {
+ debug('error triggered by discarded transport');
+ });
+
+ // ensure transport won't stay open
+ this.transport.close();
+
+ clearTimeout(this.pingTimeoutTimer);
+};
+
+/**
+ * Called upon transport considered closed.
+ * Possible reasons: `ping timeout`, `client error`, `parse error`,
+ * `transport error`, `server close`, `transport close`
+ */
+
+Socket.prototype.onClose = function (reason, description) {
+ if ('closed' !== this.readyState) {
+ this.readyState = 'closed';
+ clearTimeout(this.pingTimeoutTimer);
+ clearInterval(this.checkIntervalTimer);
+ this.checkIntervalTimer = null;
+ clearTimeout(this.upgradeTimeoutTimer);
+ var self = this;
+ // clean writeBuffer in next tick, so developers can still
+ // grab the writeBuffer on 'close' event
+ process.nextTick(function () {
+ self.writeBuffer = [];
+ });
+ this.packetsFn = [];
+ this.sentCallbackFn = [];
+ this.clearTransport();
+ this.emit('close', reason, description);
+ }
+};
+
+/**
+ * Setup and manage send callback
+ *
+ * @api private
+ */
+
+Socket.prototype.setupSendCallback = function () {
+ var self = this;
+ this.transport.on('drain', onDrain);
+
+ this.cleanupFn.push(function () {
+ self.transport.removeListener('drain', onDrain);
+ });
+
+ // the message was sent successfully, execute the callback
+ function onDrain () {
+ if (self.sentCallbackFn.length > 0) {
+ var seqFn = self.sentCallbackFn.splice(0, 1)[0];
+ if ('function' === typeof seqFn) {
+ debug('executing send callback');
+ seqFn(self.transport);
+ } else if (Array.isArray(seqFn)) {
+ debug('executing batch send callback');
+ for (var l = seqFn.length, i = 0; i < l; i++) {
+ if ('function' === typeof seqFn[i]) {
+ seqFn[i](self.transport);
+ }
+ }
+ }
+ }
+ }
+};
+
+/**
+ * Sends a message packet.
+ *
+ * @param {String} message
+ * @param {Object} options
+ * @param {Function} callback
+ * @return {Socket} for chaining
+ * @api public
+ */
+
+Socket.prototype.send =
+Socket.prototype.write = function (data, options, callback) {
+ this.sendPacket('message', data, options, callback);
+ return this;
+};
+
+/**
+ * Sends a packet.
+ *
+ * @param {String} packet type
+ * @param {String} optional, data
+ * @param {Object} options
+ * @api private
+ */
+
+Socket.prototype.sendPacket = function (type, data, options, callback) {
+ if ('function' === typeof options) {
+ callback = options;
+ options = null;
+ }
+
+ options = options || {};
+ options.compress = false !== options.compress;
+
+ if ('closing' !== this.readyState && 'closed' !== this.readyState) {
+ debug('sending packet "%s" (%s)', type, data);
+
+ var packet = {
+ type: type,
+ options: options
+ };
+ if (data) packet.data = data;
+
+ // exports packetCreate event
+ this.emit('packetCreate', packet);
+
+ this.writeBuffer.push(packet);
+
+ // add send callback to object, if defined
+ if (callback) this.packetsFn.push(callback);
+
+ this.flush();
+ }
+};
+
+/**
+ * Attempts to flush the packets buffer.
+ *
+ * @api private
+ */
+
+Socket.prototype.flush = function () {
+ if ('closed' !== this.readyState &&
+ this.transport.writable &&
+ this.writeBuffer.length) {
+ debug('flushing buffer to transport');
+ this.emit('flush', this.writeBuffer);
+ this.server.emit('flush', this, this.writeBuffer);
+ var wbuf = this.writeBuffer;
+ this.writeBuffer = [];
+ if (!this.transport.supportsFraming) {
+ this.sentCallbackFn.push(this.packetsFn);
+ } else {
+ this.sentCallbackFn.push.apply(this.sentCallbackFn, this.packetsFn);
+ }
+ this.packetsFn = [];
+ this.transport.send(wbuf);
+ this.emit('drain');
+ this.server.emit('drain', this);
+ }
+};
+
+/**
+ * Get available upgrades for this socket.
+ *
+ * @api private
+ */
+
+Socket.prototype.getAvailableUpgrades = function () {
+ var availableUpgrades = [];
+ var allUpgrades = this.server.upgrades(this.transport.name);
+ for (var i = 0, l = allUpgrades.length; i < l; ++i) {
+ var upg = allUpgrades[i];
+ if (this.server.transports.indexOf(upg) !== -1) {
+ availableUpgrades.push(upg);
+ }
+ }
+ return availableUpgrades;
+};
+
+/**
+ * Closes the socket and underlying transport.
+ *
+ * @param {Boolean} optional, discard
+ * @return {Socket} for chaining
+ * @api public
+ */
+
+Socket.prototype.close = function (discard) {
+ if ('open' !== this.readyState) return;
+
+ this.readyState = 'closing';
+
+ if (this.writeBuffer.length) {
+ this.once('drain', this.closeTransport.bind(this, discard));
+ return;
+ }
+
+ this.closeTransport(discard);
+};
+
+/**
+ * Closes the underlying transport.
+ *
+ * @param {Boolean} discard
+ * @api private
+ */
+
+Socket.prototype.closeTransport = function (discard) {
+ if (discard) this.transport.discard();
+ this.transport.close(this.onClose.bind(this, 'forced close'));
+};
diff --git a/node_modules/engine.io/lib/transport.js b/node_modules/engine.io/lib/transport.js
new file mode 100644
index 0000000..933dad5
--- /dev/null
+++ b/node_modules/engine.io/lib/transport.js
@@ -0,0 +1,128 @@
+
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter;
+var parser = require('engine.io-parser');
+var util = require('util');
+var debug = require('debug')('engine:transport');
+
+/**
+ * Expose the constructor.
+ */
+
+module.exports = Transport;
+
+/**
+ * Noop function.
+ *
+ * @api private
+ */
+
+function noop () {}
+
+/**
+ * Transport constructor.
+ *
+ * @param {http.IncomingMessage} request
+ * @api public
+ */
+
+function Transport (req) {
+ this.readyState = 'open';
+ this.discarded = false;
+}
+
+/**
+ * Inherits from EventEmitter.
+ */
+
+util.inherits(Transport, EventEmitter);
+
+/**
+ * Flags the transport as discarded.
+ *
+ * @api private
+ */
+
+Transport.prototype.discard = function () {
+ this.discarded = true;
+};
+
+/**
+ * Called with an incoming HTTP request.
+ *
+ * @param {http.IncomingMessage} request
+ * @api private
+ */
+
+Transport.prototype.onRequest = function (req) {
+ debug('setting request');
+ this.req = req;
+};
+
+/**
+ * Closes the transport.
+ *
+ * @api private
+ */
+
+Transport.prototype.close = function (fn) {
+ if ('closed' === this.readyState || 'closing' === this.readyState) return;
+
+ this.readyState = 'closing';
+ this.doClose(fn || noop);
+};
+
+/**
+ * Called with a transport error.
+ *
+ * @param {String} message error
+ * @param {Object} error description
+ * @api private
+ */
+
+Transport.prototype.onError = function (msg, desc) {
+ if (this.listeners('error').length) {
+ var err = new Error(msg);
+ err.type = 'TransportError';
+ err.description = desc;
+ this.emit('error', err);
+ } else {
+ debug('ignored transport error %s (%s)', msg, desc);
+ }
+};
+
+/**
+ * Called with parsed out a packets from the data stream.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+Transport.prototype.onPacket = function (packet) {
+ this.emit('packet', packet);
+};
+
+/**
+ * Called with the encoded packet data.
+ *
+ * @param {String} data
+ * @api private
+ */
+
+Transport.prototype.onData = function (data) {
+ this.onPacket(parser.decodePacket(data));
+};
+
+/**
+ * Called upon transport close.
+ *
+ * @api private
+ */
+
+Transport.prototype.onClose = function () {
+ this.readyState = 'closed';
+ this.emit('close');
+};
diff --git a/node_modules/engine.io/lib/transports/index.js b/node_modules/engine.io/lib/transports/index.js
new file mode 100644
index 0000000..fcff322
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/index.js
@@ -0,0 +1,36 @@
+
+/**
+ * Module dependencies.
+ */
+
+var XHR = require('./polling-xhr');
+var JSONP = require('./polling-jsonp');
+
+/**
+ * Export transports.
+ */
+
+module.exports = exports = {
+ polling: polling,
+ websocket: require('./websocket')
+};
+
+/**
+ * Export upgrades map.
+ */
+
+exports.polling.upgradesTo = ['websocket'];
+
+/**
+ * Polling polymorphic constructor.
+ *
+ * @api private
+ */
+
+function polling (req) {
+ if ('string' === typeof req._query.j) {
+ return new JSONP(req);
+ } else {
+ return new XHR(req);
+ }
+}
diff --git a/node_modules/engine.io/lib/transports/polling-jsonp.js b/node_modules/engine.io/lib/transports/polling-jsonp.js
new file mode 100644
index 0000000..62e66e7
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling-jsonp.js
@@ -0,0 +1,75 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Polling = require('./polling');
+var qs = require('querystring');
+var rDoubleSlashes = /\\\\n/g;
+var rSlashes = /(\\)?\\n/g;
+var util = require('util');
+
+/**
+ * Module exports.
+ */
+
+module.exports = JSONP;
+
+/**
+ * JSON-P polling transport.
+ *
+ * @api public
+ */
+
+function JSONP (req) {
+ Polling.call(this, req);
+
+ this.head = '___eio[' + (req._query.j || '').replace(/[^0-9]/g, '') + '](';
+ this.foot = ');';
+}
+
+/**
+ * Inherits from Polling.
+ */
+
+util.inherits(JSONP, Polling);
+
+/**
+ * Handles incoming data.
+ * Due to a bug in \n handling by browsers, we expect a escaped string.
+ *
+ * @api private
+ */
+
+JSONP.prototype.onData = function (data) {
+ // we leverage the qs module so that we get built-in DoS protection
+ // and the fast alternative to decodeURIComponent
+ data = qs.parse(data).d;
+ if ('string' === typeof data) {
+ // client will send already escaped newlines as \\\\n and newlines as \\n
+ // \\n must be replaced with \n and \\\\n with \\n
+ data = data.replace(rSlashes, function (match, slashes) {
+ return slashes ? match : '\n';
+ });
+ Polling.prototype.onData.call(this, data.replace(rDoubleSlashes, '\\n'));
+ }
+};
+
+/**
+ * Performs the write.
+ *
+ * @api private
+ */
+
+JSONP.prototype.doWrite = function (data, options, callback) {
+ // we must output valid javascript, not valid json
+ // see: http://timelessrepo.com/json-isnt-a-javascript-subset
+ var js = JSON.stringify(data)
+ .replace(/\u2028/g, '\\u2028')
+ .replace(/\u2029/g, '\\u2029');
+
+ // prepare response
+ data = this.head + js + this.foot;
+
+ Polling.prototype.doWrite.call(this, data, options, callback);
+};
diff --git a/node_modules/engine.io/lib/transports/polling-xhr.js b/node_modules/engine.io/lib/transports/polling-xhr.js
new file mode 100644
index 0000000..3562524
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling-xhr.js
@@ -0,0 +1,69 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Polling = require('./polling');
+var util = require('util');
+
+/**
+ * Module exports.
+ */
+
+module.exports = XHR;
+
+/**
+ * Ajax polling transport.
+ *
+ * @api public
+ */
+
+function XHR (req) {
+ Polling.call(this, req);
+}
+
+/**
+ * Inherits from Polling.
+ */
+
+util.inherits(XHR, Polling);
+
+/**
+ * Overrides `onRequest` to handle `OPTIONS`..
+ *
+ * @param {http.IncomingMessage}
+ * @api private
+ */
+
+XHR.prototype.onRequest = function (req) {
+ if ('OPTIONS' === req.method) {
+ var res = req.res;
+ var headers = this.headers(req);
+ headers['Access-Control-Allow-Headers'] = 'Content-Type';
+ res.writeHead(200, headers);
+ res.end();
+ } else {
+ Polling.prototype.onRequest.call(this, req);
+ }
+};
+
+/**
+ * Returns headers for a response.
+ *
+ * @param {http.IncomingMessage} request
+ * @param {Object} extra headers
+ * @api private
+ */
+
+XHR.prototype.headers = function (req, headers) {
+ headers = headers || {};
+
+ if (req.headers.origin) {
+ headers['Access-Control-Allow-Credentials'] = 'true';
+ headers['Access-Control-Allow-Origin'] = req.headers.origin;
+ } else {
+ headers['Access-Control-Allow-Origin'] = '*';
+ }
+
+ return Polling.prototype.headers.call(this, req, headers);
+};
diff --git a/node_modules/engine.io/lib/transports/polling.js b/node_modules/engine.io/lib/transports/polling.js
new file mode 100644
index 0000000..6c5c0cc
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/polling.js
@@ -0,0 +1,407 @@
+
+/**
+ * Module requirements.
+ */
+
+var Transport = require('../transport');
+var parser = require('engine.io-parser');
+var zlib = require('zlib');
+var accepts = require('accepts');
+var util = require('util');
+var debug = require('debug')('engine:polling');
+
+var compressionMethods = {
+ gzip: zlib.createGzip,
+ deflate: zlib.createDeflate
+};
+
+/**
+ * Exports the constructor.
+ */
+
+module.exports = Polling;
+
+/**
+ * HTTP polling constructor.
+ *
+ * @api public.
+ */
+
+function Polling (req) {
+ Transport.call(this, req);
+
+ this.closeTimeout = 30 * 1000;
+ this.maxHttpBufferSize = null;
+ this.httpCompression = null;
+}
+
+/**
+ * Inherits from Transport.
+ *
+ * @api public.
+ */
+
+util.inherits(Polling, Transport);
+
+/**
+ * Transport name
+ *
+ * @api public
+ */
+
+Polling.prototype.name = 'polling';
+
+/**
+ * Overrides onRequest.
+ *
+ * @param {http.IncomingMessage}
+ * @api private
+ */
+
+Polling.prototype.onRequest = function (req) {
+ var res = req.res;
+
+ if ('GET' === req.method) {
+ this.onPollRequest(req, res);
+ } else if ('POST' === req.method) {
+ this.onDataRequest(req, res);
+ } else {
+ res.writeHead(500);
+ res.end();
+ }
+};
+
+/**
+ * The client sends a request awaiting for us to send data.
+ *
+ * @api private
+ */
+
+Polling.prototype.onPollRequest = function (req, res) {
+ if (this.req) {
+ debug('request overlap');
+ // assert: this.res, '.req and .res should be (un)set together'
+ this.onError('overlap from client');
+ res.writeHead(500);
+ res.end();
+ return;
+ }
+
+ debug('setting request');
+
+ this.req = req;
+ this.res = res;
+
+ var self = this;
+
+ function onClose () {
+ self.onError('poll connection closed prematurely');
+ }
+
+ function cleanup () {
+ req.removeListener('close', onClose);
+ self.req = self.res = null;
+ }
+
+ req.cleanup = cleanup;
+ req.on('close', onClose);
+
+ this.writable = true;
+ this.emit('drain');
+
+ // if we're still writable but had a pending close, trigger an empty send
+ if (this.writable && this.shouldClose) {
+ debug('triggering empty send to append close packet');
+ this.send([{ type: 'noop' }]);
+ }
+};
+
+/**
+ * The client sends a request with data.
+ *
+ * @api private
+ */
+
+Polling.prototype.onDataRequest = function (req, res) {
+ if (this.dataReq) {
+ // assert: this.dataRes, '.dataReq and .dataRes should be (un)set together'
+ this.onError('data request overlap from client');
+ res.writeHead(500);
+ res.end();
+ return;
+ }
+
+ var isBinary = 'application/octet-stream' === req.headers['content-type'];
+
+ this.dataReq = req;
+ this.dataRes = res;
+
+ var chunks = isBinary ? new Buffer(0) : ''; // eslint-disable-line node/no-deprecated-api
+ var self = this;
+
+ function cleanup () {
+ req.removeListener('data', onData);
+ req.removeListener('end', onEnd);
+ req.removeListener('close', onClose);
+ self.dataReq = self.dataRes = chunks = null;
+ }
+
+ function onClose () {
+ cleanup();
+ self.onError('data request connection closed prematurely');
+ }
+
+ function onData (data) {
+ var contentLength;
+ if (isBinary) {
+ chunks = Buffer.concat([chunks, data]);
+ contentLength = chunks.length;
+ } else {
+ chunks += data;
+ contentLength = Buffer.byteLength(chunks);
+ }
+
+ if (contentLength > self.maxHttpBufferSize) {
+ chunks = isBinary ? new Buffer(0) : ''; // eslint-disable-line node/no-deprecated-api
+ req.connection.destroy();
+ }
+ }
+
+ function onEnd () {
+ self.onData(chunks);
+
+ var headers = {
+ // text/html is required instead of text/plain to avoid an
+ // unwanted download dialog on certain user-agents (GH-43)
+ 'Content-Type': 'text/html',
+ 'Content-Length': 2
+ };
+
+ res.writeHead(200, self.headers(req, headers));
+ res.end('ok');
+ cleanup();
+ }
+
+ req.on('close', onClose);
+ if (!isBinary) req.setEncoding('utf8');
+ req.on('data', onData);
+ req.on('end', onEnd);
+};
+
+/**
+ * Processes the incoming data payload.
+ *
+ * @param {String} encoded payload
+ * @api private
+ */
+
+Polling.prototype.onData = function (data) {
+ debug('received "%s"', data);
+ var self = this;
+ var callback = function (packet) {
+ if ('close' === packet.type) {
+ debug('got xhr close packet');
+ self.onClose();
+ return false;
+ }
+
+ self.onPacket(packet);
+ };
+
+ parser.decodePayload(data, callback);
+};
+
+/**
+ * Overrides onClose.
+ *
+ * @api private
+ */
+
+Polling.prototype.onClose = function () {
+ if (this.writable) {
+ // close pending poll request
+ this.send([{ type: 'noop' }]);
+ }
+ Transport.prototype.onClose.call(this);
+};
+
+/**
+ * Writes a packet payload.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+Polling.prototype.send = function (packets) {
+ this.writable = false;
+
+ if (this.shouldClose) {
+ debug('appending close packet to payload');
+ packets.push({ type: 'close' });
+ this.shouldClose();
+ this.shouldClose = null;
+ }
+
+ var self = this;
+ parser.encodePayload(packets, this.supportsBinary, function (data) {
+ var compress = packets.some(function (packet) {
+ return packet.options && packet.options.compress;
+ });
+ self.write(data, { compress: compress });
+ });
+};
+
+/**
+ * Writes data as response to poll request.
+ *
+ * @param {String} data
+ * @param {Object} options
+ * @api private
+ */
+
+Polling.prototype.write = function (data, options) {
+ debug('writing "%s"', data);
+ var self = this;
+ this.doWrite(data, options, function () {
+ self.req.cleanup();
+ });
+};
+
+/**
+ * Performs the write.
+ *
+ * @api private
+ */
+
+Polling.prototype.doWrite = function (data, options, callback) {
+ var self = this;
+
+ // explicit UTF-8 is required for pages not served under utf
+ var isString = typeof data === 'string';
+ var contentType = isString
+ ? 'text/plain; charset=UTF-8'
+ : 'application/octet-stream';
+
+ var headers = {
+ 'Content-Type': contentType
+ };
+
+ if (!this.httpCompression || !options.compress) {
+ respond(data);
+ return;
+ }
+
+ var len = isString ? Buffer.byteLength(data) : data.length;
+ if (len < this.httpCompression.threshold) {
+ respond(data);
+ return;
+ }
+
+ var encoding = accepts(this.req).encodings(['gzip', 'deflate']);
+ if (!encoding) {
+ respond(data);
+ return;
+ }
+
+ this.compress(data, encoding, function (err, data) {
+ if (err) {
+ self.res.writeHead(500);
+ self.res.end();
+ callback(err);
+ return;
+ }
+
+ headers['Content-Encoding'] = encoding;
+ respond(data);
+ });
+
+ function respond (data) {
+ headers['Content-Length'] = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
+ self.res.writeHead(200, self.headers(self.req, headers));
+ self.res.end(data);
+ callback();
+ }
+};
+
+/**
+ * Compresses data.
+ *
+ * @api private
+ */
+
+Polling.prototype.compress = function (data, encoding, callback) {
+ debug('compressing');
+
+ var buffers = [];
+ var nread = 0;
+
+ compressionMethods[encoding](this.httpCompression)
+ .on('error', callback)
+ .on('data', function (chunk) {
+ buffers.push(chunk);
+ nread += chunk.length;
+ })
+ .on('end', function () {
+ callback(null, Buffer.concat(buffers, nread));
+ })
+ .end(data);
+};
+
+/**
+ * Closes the transport.
+ *
+ * @api private
+ */
+
+Polling.prototype.doClose = function (fn) {
+ debug('closing');
+
+ var self = this;
+ var closeTimeoutTimer;
+
+ if (this.dataReq) {
+ debug('aborting ongoing data request');
+ this.dataReq.destroy();
+ }
+
+ if (this.writable) {
+ debug('transport writable - closing right away');
+ this.send([{ type: 'close' }]);
+ onClose();
+ } else if (this.discarded) {
+ debug('transport discarded - closing right away');
+ onClose();
+ } else {
+ debug('transport not writable - buffering orderly close');
+ this.shouldClose = onClose;
+ closeTimeoutTimer = setTimeout(onClose, this.closeTimeout);
+ }
+
+ function onClose () {
+ clearTimeout(closeTimeoutTimer);
+ fn();
+ self.onClose();
+ }
+};
+
+/**
+ * Returns headers for a response.
+ *
+ * @param {http.IncomingMessage} request
+ * @param {Object} extra headers
+ * @api private
+ */
+
+Polling.prototype.headers = function (req, headers) {
+ headers = headers || {};
+
+ // prevent XSS warnings on IE
+ // https://github.com/LearnBoost/socket.io/pull/1333
+ var ua = req.headers['user-agent'];
+ if (ua && (~ua.indexOf(';MSIE') || ~ua.indexOf('Trident/'))) {
+ headers['X-XSS-Protection'] = '0';
+ }
+
+ this.emit('headers', headers);
+ return headers;
+};
diff --git a/node_modules/engine.io/lib/transports/websocket.js b/node_modules/engine.io/lib/transports/websocket.js
new file mode 100644
index 0000000..7d5511b
--- /dev/null
+++ b/node_modules/engine.io/lib/transports/websocket.js
@@ -0,0 +1,134 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Transport = require('../transport');
+var parser = require('engine.io-parser');
+var util = require('util');
+var debug = require('debug')('engine:ws');
+
+/**
+ * Export the constructor.
+ */
+
+module.exports = WebSocket;
+
+/**
+ * WebSocket transport
+ *
+ * @param {http.IncomingMessage}
+ * @api public
+ */
+
+function WebSocket (req) {
+ Transport.call(this, req);
+ var self = this;
+ this.socket = req.websocket;
+ this.socket.on('message', this.onData.bind(this));
+ this.socket.once('close', this.onClose.bind(this));
+ this.socket.on('error', this.onError.bind(this));
+ this.socket.on('headers', onHeaders);
+ this.writable = true;
+ this.perMessageDeflate = null;
+
+ function onHeaders (headers) {
+ self.emit('headers', headers);
+ }
+}
+
+/**
+ * Inherits from Transport.
+ */
+
+util.inherits(WebSocket, Transport);
+
+/**
+ * Transport name
+ *
+ * @api public
+ */
+
+WebSocket.prototype.name = 'websocket';
+
+/**
+ * Advertise upgrade support.
+ *
+ * @api public
+ */
+
+WebSocket.prototype.handlesUpgrades = true;
+
+/**
+ * Advertise framing support.
+ *
+ * @api public
+ */
+
+WebSocket.prototype.supportsFraming = true;
+
+/**
+ * Processes the incoming data.
+ *
+ * @param {String} encoded packet
+ * @api private
+ */
+
+WebSocket.prototype.onData = function (data) {
+ debug('received "%s"', data);
+ Transport.prototype.onData.call(this, data);
+};
+
+/**
+ * Writes a packet payload.
+ *
+ * @param {Array} packets
+ * @api private
+ */
+
+WebSocket.prototype.send = function (packets) {
+ var self = this;
+
+ for (var i = 0; i < packets.length; i++) {
+ var packet = packets[i];
+ parser.encodePacket(packet, self.supportsBinary, send);
+ }
+
+ function send (data) {
+ debug('writing "%s"', data);
+
+ // always creates a new object since ws modifies it
+ var opts = {};
+ if (packet.options) {
+ opts.compress = packet.options.compress;
+ }
+
+ if (self.perMessageDeflate) {
+ var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length;
+ if (len < self.perMessageDeflate.threshold) {
+ opts.compress = false;
+ }
+ }
+
+ self.writable = false;
+ self.socket.send(data, opts, onEnd);
+ }
+
+ function onEnd (err) {
+ if (err) return self.onError('write error', err.stack);
+ self.writable = true;
+ self.emit('drain');
+ }
+};
+
+/**
+ * Closes the transport.
+ *
+ * @api private
+ */
+
+WebSocket.prototype.doClose = function (fn) {
+ debug('closing');
+ this.socket.close();
+ fn && fn();
+};
diff --git a/node_modules/engine.io/node_modules/accepts/HISTORY.md b/node_modules/engine.io/node_modules/accepts/HISTORY.md
new file mode 100644
index 0000000..0477ed7
--- /dev/null
+++ b/node_modules/engine.io/node_modules/accepts/HISTORY.md
@@ -0,0 +1,212 @@
+1.3.3 / 2016-05-02
+==================
+
+ * deps: mime-types@~2.1.11
+ - deps: mime-db@~1.23.0
+ * deps: negotiator@0.6.1
+ - perf: improve `Accept` parsing speed
+ - perf: improve `Accept-Charset` parsing speed
+ - perf: improve `Accept-Encoding` parsing speed
+ - perf: improve `Accept-Language` parsing speed
+
+1.3.2 / 2016-03-08
+==================
+
+ * deps: mime-types@~2.1.10
+ - Fix extension of `application/dash+xml`
+ - Update primary extension for `audio/mp4`
+ - deps: mime-db@~1.22.0
+
+1.3.1 / 2016-01-19
+==================
+
+ * deps: mime-types@~2.1.9
+ - deps: mime-db@~1.21.0
+
+1.3.0 / 2015-09-29
+==================
+
+ * deps: mime-types@~2.1.7
+ - deps: mime-db@~1.19.0
+ * deps: negotiator@0.6.0
+ - Fix including type extensions in parameters in `Accept` parsing
+ - Fix parsing `Accept` parameters with quoted equals
+ - Fix parsing `Accept` parameters with quoted semicolons
+ - Lazy-load modules from main entry point
+ - perf: delay type concatenation until needed
+ - perf: enable strict mode
+ - perf: hoist regular expressions
+ - perf: remove closures getting spec properties
+ - perf: remove a closure from media type parsing
+ - perf: remove property delete from media type parsing
+
+1.2.13 / 2015-09-06
+===================
+
+ * deps: mime-types@~2.1.6
+ - deps: mime-db@~1.18.0
+
+1.2.12 / 2015-07-30
+===================
+
+ * deps: mime-types@~2.1.4
+ - deps: mime-db@~1.16.0
+
+1.2.11 / 2015-07-16
+===================
+
+ * deps: mime-types@~2.1.3
+ - deps: mime-db@~1.15.0
+
+1.2.10 / 2015-07-01
+===================
+
+ * deps: mime-types@~2.1.2
+ - deps: mime-db@~1.14.0
+
+1.2.9 / 2015-06-08
+==================
+
+ * deps: mime-types@~2.1.1
+ - perf: fix deopt during mapping
+
+1.2.8 / 2015-06-07
+==================
+
+ * deps: mime-types@~2.1.0
+ - deps: mime-db@~1.13.0
+ * perf: avoid argument reassignment & argument slice
+ * perf: avoid negotiator recursive construction
+ * perf: enable strict mode
+ * perf: remove unnecessary bitwise operator
+
+1.2.7 / 2015-05-10
+==================
+
+ * deps: negotiator@0.5.3
+ - Fix media type parameter matching to be case-insensitive
+
+1.2.6 / 2015-05-07
+==================
+
+ * deps: mime-types@~2.0.11
+ - deps: mime-db@~1.9.1
+ * deps: negotiator@0.5.2
+ - Fix comparing media types with quoted values
+ - Fix splitting media types with quoted commas
+
+1.2.5 / 2015-03-13
+==================
+
+ * deps: mime-types@~2.0.10
+ - deps: mime-db@~1.8.0
+
+1.2.4 / 2015-02-14
+==================
+
+ * Support Node.js 0.6
+ * deps: mime-types@~2.0.9
+ - deps: mime-db@~1.7.0
+ * deps: negotiator@0.5.1
+ - Fix preference sorting to be stable for long acceptable lists
+
+1.2.3 / 2015-01-31
+==================
+
+ * deps: mime-types@~2.0.8
+ - deps: mime-db@~1.6.0
+
+1.2.2 / 2014-12-30
+==================
+
+ * deps: mime-types@~2.0.7
+ - deps: mime-db@~1.5.0
+
+1.2.1 / 2014-12-30
+==================
+
+ * deps: mime-types@~2.0.5
+ - deps: mime-db@~1.3.1
+
+1.2.0 / 2014-12-19
+==================
+
+ * deps: negotiator@0.5.0
+ - Fix list return order when large accepted list
+ - Fix missing identity encoding when q=0 exists
+ - Remove dynamic building of Negotiator class
+
+1.1.4 / 2014-12-10
+==================
+
+ * deps: mime-types@~2.0.4
+ - deps: mime-db@~1.3.0
+
+1.1.3 / 2014-11-09
+==================
+
+ * deps: mime-types@~2.0.3
+ - deps: mime-db@~1.2.0
+
+1.1.2 / 2014-10-14
+==================
+
+ * deps: negotiator@0.4.9
+ - Fix error when media type has invalid parameter
+
+1.1.1 / 2014-09-28
+==================
+
+ * deps: mime-types@~2.0.2
+ - deps: mime-db@~1.1.0
+ * deps: negotiator@0.4.8
+ - Fix all negotiations to be case-insensitive
+ - Stable sort preferences of same quality according to client order
+
+1.1.0 / 2014-09-02
+==================
+
+ * update `mime-types`
+
+1.0.7 / 2014-07-04
+==================
+
+ * Fix wrong type returned from `type` when match after unknown extension
+
+1.0.6 / 2014-06-24
+==================
+
+ * deps: negotiator@0.4.7
+
+1.0.5 / 2014-06-20
+==================
+
+ * fix crash when unknown extension given
+
+1.0.4 / 2014-06-19
+==================
+
+ * use `mime-types`
+
+1.0.3 / 2014-06-11
+==================
+
+ * deps: negotiator@0.4.6
+ - Order by specificity when quality is the same
+
+1.0.2 / 2014-05-29
+==================
+
+ * Fix interpretation when header not in request
+ * deps: pin negotiator@0.4.5
+
+1.0.1 / 2014-01-18
+==================
+
+ * Identity encoding isn't always acceptable
+ * deps: negotiator@~0.4.0
+
+1.0.0 / 2013-12-27
+==================
+
+ * Genesis
diff --git a/node_modules/engine.io/node_modules/accepts/LICENSE b/node_modules/engine.io/node_modules/accepts/LICENSE
new file mode 100644
index 0000000..0616607
--- /dev/null
+++ b/node_modules/engine.io/node_modules/accepts/LICENSE
@@ -0,0 +1,23 @@
+(The MIT License)
+
+Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
+Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/engine.io/node_modules/accepts/README.md b/node_modules/engine.io/node_modules/accepts/README.md
new file mode 100644
index 0000000..ae36676
--- /dev/null
+++ b/node_modules/engine.io/node_modules/accepts/README.md
@@ -0,0 +1,135 @@
+# accepts
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator). Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
+
+In addition to negotiator, it allows:
+
+- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.
+- Allows type shorthands such as `json`.
+- Returns `false` when no types match
+- Treats non-existent headers as `*`
+
+## Installation
+
+```sh
+npm install accepts
+```
+
+## API
+
+```js
+var accepts = require('accepts')
+```
+
+### accepts(req)
+
+Create a new `Accepts` object for the given `req`.
+
+#### .charset(charsets)
+
+Return the first accepted charset. If nothing in `charsets` is accepted,
+then `false` is returned.
+
+#### .charsets()
+
+Return the charsets that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .encoding(encodings)
+
+Return the first accepted encoding. If nothing in `encodings` is accepted,
+then `false` is returned.
+
+#### .encodings()
+
+Return the encodings that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .language(languages)
+
+Return the first accepted language. If nothing in `languages` is accepted,
+then `false` is returned.
+
+#### .languages()
+
+Return the languages that the request accepts, in the order of the client's
+preference (most preferred first).
+
+#### .type(types)
+
+Return the first accepted type (and it is returned as the same text as what
+appears in the `types` array). If nothing in `types` is accepted, then `false`
+is returned.
+
+The `types` array can contain full MIME types or file extensions. Any value
+that is not a full MIME types is passed to `require('mime-types').lookup`.
+
+#### .types()
+
+Return the types that the request accepts, in the order of the client's
+preference (most preferred first).
+
+## Examples
+
+### Simple type negotiation
+
+This simple example shows how to use `accepts` to return a different typed
+respond body based on what the client wants to accept. The server lists it's
+preferences in order and will get back the best match between the client and
+server.
+
+```js
+var accepts = require('accepts')
+var http = require('http')
+
+function app(req, res) {
+ var accept = accepts(req)
+
+ // the order of this list is significant; should be server preferred order
+ switch(accept.type(['json', 'html'])) {
+ case 'json':
+ res.setHeader('Content-Type', 'application/json')
+ res.write('{"hello":"world!"}')
+ break
+ case 'html':
+ res.setHeader('Content-Type', 'text/html')
+ res.write('<b>hello, world!</b>')
+ break
+ default:
+ // the fallback is text/plain, so no need to specify it above
+ res.setHeader('Content-Type', 'text/plain')
+ res.write('hello, world!')
+ break
+ }
+
+ res.end()
+}
+
+http.createServer(app).listen(3000)
+```
+
+You can test this out with the cURL program:
+```sh
+curl -I -H'Accept: text/html' http://localhost:3000/
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/accepts.svg
+[npm-url]: https://npmjs.org/package/accepts
+[node-version-image]: https://img.shields.io/node/v/accepts.svg
+[node-version-url]: http://nodejs.org/download/
+[travis-image]: https://img.shields.io/travis/jshttp/accepts/master.svg
+[travis-url]: https://travis-ci.org/jshttp/accepts
+[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts/master.svg
+[coveralls-url]: https://coveralls.io/r/jshttp/accepts
+[downloads-image]: https://img.shields.io/npm/dm/accepts.svg
+[downloads-url]: https://npmjs.org/package/accepts
diff --git a/node_modules/engine.io/node_modules/accepts/index.js b/node_modules/engine.io/node_modules/accepts/index.js
new file mode 100644
index 0000000..e80192a
--- /dev/null
+++ b/node_modules/engine.io/node_modules/accepts/index.js
@@ -0,0 +1,231 @@
+/*!
+ * accepts
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Negotiator = require('negotiator')
+var mime = require('mime-types')
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = Accepts
+
+/**
+ * Create a new Accepts object for the given req.
+ *
+ * @param {object} req
+ * @public
+ */
+
+function Accepts(req) {
+ if (!(this instanceof Accepts))
+ return new Accepts(req)
+
+ this.headers = req.headers
+ this.negotiator = new Negotiator(req)
+}
+
+/**
+ * Check if the given `type(s)` is acceptable, returning
+ * the best match when true, otherwise `undefined`, in which
+ * case you should respond with 406 "Not Acceptable".
+ *
+ * The `type` value may be a single mime type string
+ * such as "application/json", the extension name
+ * such as "json" or an array `["json", "html", "text/plain"]`. When a list
+ * or array is given the _best_ match, if any is returned.
+ *
+ * Examples:
+ *
+ * // Accept: text/html
+ * this.types('html');
+ * // => "html"
+ *
+ * // Accept: text/*, application/json
+ * this.types('html');
+ * // => "html"
+ * this.types('text/html');
+ * // => "text/html"
+ * this.types('json', 'text');
+ * // => "json"
+ * this.types('application/json');
+ * // => "application/json"
+ *
+ * // Accept: text/*, application/json
+ * this.types('image/png');
+ * this.types('png');
+ * // => undefined
+ *
+ * // Accept: text/*;q=.5, application/json
+ * this.types(['html', 'json']);
+ * this.types('html', 'json');
+ * // => "json"
+ *
+ * @param {String|Array} types...
+ * @return {String|Array|Boolean}
+ * @public
+ */
+
+Accepts.prototype.type =
+Accepts.prototype.types = function (types_) {
+ var types = types_
+
+ // support flattened arguments
+ if (types && !Array.isArray(types)) {
+ types = new Array(arguments.length)
+ for (var i = 0; i < types.length; i++) {
+ types[i] = arguments[i]
+ }
+ }
+
+ // no types, return all requested types
+ if (!types || types.length === 0) {
+ return this.negotiator.mediaTypes()
+ }
+
+ if (!this.headers.accept) return types[0];
+ var mimes = types.map(extToMime);
+ var accepts = this.negotiator.mediaTypes(mimes.filter(validMime));
+ var first = accepts[0];
+ if (!first) return false;
+ return types[mimes.indexOf(first)];
+}
+
+/**
+ * Return accepted encodings or best fit based on `encodings`.
+ *
+ * Given `Accept-Encoding: gzip, deflate`
+ * an array sorted by quality is returned:
+ *
+ * ['gzip', 'deflate']
+ *
+ * @param {String|Array} encodings...
+ * @return {String|Array}
+ * @public
+ */
+
+Accepts.prototype.encoding =
+Accepts.prototype.encodings = function (encodings_) {
+ var encodings = encodings_
+
+ // support flattened arguments
+ if (encodings && !Array.isArray(encodings)) {
+ encodings = new Array(arguments.length)
+ for (var i = 0; i < encodings.length; i++) {
+ encodings[i] = arguments[i]
+ }
+ }
+
+ // no encodings, return all requested encodings
+ if (!encodings || encodings.length === 0) {
+ return this.negotiator.encodings()
+ }
+
+ return this.negotiator.encodings(encodings)[0] || false
+}
+
+/**
+ * Return accepted charsets or best fit based on `charsets`.
+ *
+ * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
+ * an array sorted by quality is returned:
+ *
+ * ['utf-8', 'utf-7', 'iso-8859-1']
+ *
+ * @param {String|Array} charsets...
+ * @return {String|Array}
+ * @public
+ */
+
+Accepts.prototype.charset =
+Accepts.prototype.charsets = function (charsets_) {
+ var charsets = charsets_
+
+ // support flattened arguments
+ if (charsets && !Array.isArray(charsets)) {
+ charsets = new Array(arguments.length)
+ for (var i = 0; i < charsets.length; i++) {
+ charsets[i] = arguments[i]
+ }
+ }
+
+ // no charsets, return all requested charsets
+ if (!charsets || charsets.length === 0) {
+ return this.negotiator.charsets()
+ }
+
+ return this.negotiator.charsets(charsets)[0] || false
+}
+
+/**
+ * Return accepted languages or best fit based on `langs`.
+ *
+ * Given `Accept-Language: en;q=0.8, es, pt`
+ * an array sorted by quality is returned:
+ *
+ * ['es', 'pt', 'en']
+ *
+ * @param {String|Array} langs...
+ * @return {Array|String}
+ * @public
+ */
+
+Accepts.prototype.lang =
+Accepts.prototype.langs =
+Accepts.prototype.language =
+Accepts.prototype.languages = function (languages_) {
+ var languages = languages_
+
+ // support flattened arguments
+ if (languages && !Array.isArray(languages)) {
+ languages = new Array(arguments.length)
+ for (var i = 0; i < languages.length; i++) {
+ languages[i] = arguments[i]
+ }
+ }
+
+ // no languages, return all requested languages
+ if (!languages || languages.length === 0) {
+ return this.negotiator.languages()
+ }
+
+ return this.negotiator.languages(languages)[0] || false
+}
+
+/**
+ * Convert extnames to mime.
+ *
+ * @param {String} type
+ * @return {String}
+ * @private
+ */
+
+function extToMime(type) {
+ return type.indexOf('/') === -1
+ ? mime.lookup(type)
+ : type
+}
+
+/**
+ * Check if mime is valid.
+ *
+ * @param {String} type
+ * @return {String}
+ * @private
+ */
+
+function validMime(type) {
+ return typeof type === 'string';
+}
diff --git a/node_modules/engine.io/node_modules/accepts/package.json b/node_modules/engine.io/node_modules/accepts/package.json
new file mode 100644
index 0000000..c942c9b
--- /dev/null
+++ b/node_modules/engine.io/node_modules/accepts/package.json
@@ -0,0 +1,112 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "accepts@1.3.3",
+ "scope": null,
+ "escapedName": "accepts",
+ "name": "accepts",
+ "rawSpec": "1.3.3",
+ "spec": "1.3.3",
+ "type": "version"
+ },
+ "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/engine.io"
+ ]
+ ],
+ "_from": "accepts@1.3.3",
+ "_id": "accepts@1.3.3",
+ "_inCache": true,
+ "_location": "/engine.io/accepts",
+ "_nodeVersion": "4.4.3",
+ "_npmOperationalInternal": {
+ "host": "packages-16-east.internal.npmjs.com",
+ "tmp": "tmp/accepts-1.3.3.tgz_1462251932032_0.7092335098423064"
+ },
+ "_npmUser": {
+ "name": "dougwilson",
+ "email": "doug@somethingdoug.com"
+ },
+ "_npmVersion": "2.15.1",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "accepts@1.3.3",
+ "scope": null,
+ "escapedName": "accepts",
+ "name": "accepts",
+ "rawSpec": "1.3.3",
+ "spec": "1.3.3",
+ "type": "version"
+ },
+ "_requiredBy": [
+ "/engine.io"
+ ],
+ "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+ "_shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
+ "_shrinkwrap": null,
+ "_spec": "accepts@1.3.3",
+ "_where": "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/engine.io",
+ "bugs": {
+ "url": "https://github.com/jshttp/accepts/issues"
+ },
+ "contributors": [
+ {
+ "name": "Douglas Christopher Wilson",
+ "email": "doug@somethingdoug.com"
+ },
+ {
+ "name": "Jonathan Ong",
+ "email": "me@jongleberry.com",
+ "url": "http://jongleberry.com"
+ }
+ ],
+ "dependencies": {
+ "mime-types": "~2.1.11",
+ "negotiator": "0.6.1"
+ },
+ "description": "Higher-level content negotiation",
+ "devDependencies": {
+ "istanbul": "0.4.3",
+ "mocha": "~1.21.5"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
+ "tarball": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ },
+ "files": [
+ "LICENSE",
+ "HISTORY.md",
+ "index.js"
+ ],
+ "gitHead": "3e925b1e65ed7da2798849683d49814680dfa426",
+ "homepage": "https://github.com/jshttp/accepts#readme",
+ "keywords": [
+ "content",
+ "negotiation",
+ "accept",
+ "accepts"
+ ],
+ "license": "MIT",
+ "maintainers": [
+ {
+ "name": "dougwilson",
+ "email": "doug@somethingdoug.com"
+ }
+ ],
+ "name": "accepts",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/jshttp/accepts.git"
+ },
+ "scripts": {
+ "test": "mocha --reporter spec --check-leaks --bail test/",
+ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
+ "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
+ },
+ "version": "1.3.3"
+}
diff --git a/node_modules/engine.io/package.json b/node_modules/engine.io/package.json
new file mode 100644
index 0000000..8538ce2
--- /dev/null
+++ b/node_modules/engine.io/package.json
@@ -0,0 +1,137 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "engine.io@~3.1.0",
+ "scope": null,
+ "escapedName": "engine.io",
+ "name": "engine.io",
+ "rawSpec": "~3.1.0",
+ "spec": ">=3.1.0 <3.2.0",
+ "type": "range"
+ },
+ "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/socket.io"
+ ]
+ ],
+ "_from": "engine.io@>=3.1.0 <3.2.0",
+ "_id": "engine.io@3.1.3",
+ "_inCache": true,
+ "_location": "/engine.io",
+ "_nodeVersion": "6.10.3",
+ "_npmOperationalInternal": {
+ "host": "s3://npm-registry-packages",
+ "tmp": "tmp/engine.io-3.1.3.tgz_1507701591271_0.07751735299825668"
+ },
+ "_npmUser": {
+ "name": "darrachequesne",
+ "email": "damien.arrachequesne@gmail.com"
+ },
+ "_npmVersion": "3.10.10",
+ "_phantomChildren": {
+ "mime-types": "2.1.17",
+ "negotiator": "0.6.1"
+ },
+ "_requested": {
+ "raw": "engine.io@~3.1.0",
+ "scope": null,
+ "escapedName": "engine.io",
+ "name": "engine.io",
+ "rawSpec": "~3.1.0",
+ "spec": ">=3.1.0 <3.2.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/socket.io"
+ ],
+ "_resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.3.tgz",
+ "_shasum": "7aecf71bf8a310f9fa21461999c4fcc035f8a877",
+ "_shrinkwrap": null,
+ "_spec": "engine.io@~3.1.0",
+ "_where": "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/socket.io",
+ "author": {
+ "name": "Guillermo Rauch",
+ "email": "guillermo@learnboost.com"
+ },
+ "bugs": {
+ "url": "https://github.com/socketio/engine.io/issues"
+ },
+ "contributors": [
+ {
+ "name": "Eugen Dueck",
+ "url": "https://github.com/EugenDueck"
+ },
+ {
+ "name": "Afshin Mehrabani",
+ "url": "https://github.com/afshinm"
+ },
+ {
+ "name": "Christoph Dorn",
+ "url": "https://github.com/cadorn"
+ },
+ {
+ "name": "Mark Mokryn",
+ "email": "mokesmokes@gmail.com"
+ }
+ ],
+ "dependencies": {
+ "accepts": "1.3.3",
+ "base64id": "1.0.0",
+ "cookie": "0.3.1",
+ "debug": "~2.6.9",
+ "engine.io-parser": "~2.1.0",
+ "uws": "~0.14.4",
+ "ws": "~2.3.1"
+ },
+ "description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server",
+ "devDependencies": {
+ "babel-eslint": "^7.2.3",
+ "babel-preset-es2015": "^6.24.0",
+ "engine.io-client": "^3.1.1",
+ "eslint": "^4.5.0",
+ "eslint-config-standard": "^10.2.1",
+ "eslint-plugin-import": "^2.7.0",
+ "eslint-plugin-node": "^5.1.1",
+ "eslint-plugin-promise": "^3.5.0",
+ "eslint-plugin-standard": "^3.0.1",
+ "expect.js": "^0.3.1",
+ "mocha": "^3.2.0",
+ "s": "0.1.1",
+ "superagent": "0.15.4"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "7aecf71bf8a310f9fa21461999c4fcc035f8a877",
+ "tarball": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.3.tgz"
+ },
+ "files": [
+ "lib/"
+ ],
+ "gitHead": "3ee803af7233dfda7a202e17cb9eb0f1ef591b26",
+ "homepage": "https://github.com/socketio/engine.io",
+ "license": "MIT",
+ "main": "lib/engine.io",
+ "maintainers": [
+ {
+ "name": "darrachequesne",
+ "email": "damien.arrachequesne@gmail.com"
+ },
+ {
+ "name": "rauchg",
+ "email": "rauchg@gmail.com"
+ }
+ ],
+ "name": "engine.io",
+ "optionalDependencies": {
+ "uws": "~0.14.4"
+ },
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/socketio/engine.io.git"
+ },
+ "scripts": {
+ "lint": "eslint lib/ test/ *.js",
+ "test": "npm run lint && mocha && EIO_WS_ENGINE=ws mocha"
+ },
+ "version": "3.1.3"
+}