From 70846a69f76a9a6acbea404bccec36a8d642d387 Mon Sep 17 00:00:00 2001 From: Michael Mrowetz Date: Wed, 5 Apr 2017 22:47:09 +0900 Subject: [PATCH 1/5] update all connect based frameworks to latest versions --- project-skeletons/connect/config/default.yaml | 1 + project-skeletons/connect/package.json | 8 ++++---- project-skeletons/express/package.json | 8 ++++---- project-skeletons/hapi/package.json | 8 ++++---- project-skeletons/restify/package.json | 8 ++++---- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/project-skeletons/connect/config/default.yaml b/project-skeletons/connect/config/default.yaml index cbe55eba..fd82fa9f 100644 --- a/project-skeletons/connect/config/default.yaml +++ b/project-skeletons/connect/config/default.yaml @@ -25,6 +25,7 @@ swagger: swagger_controllers: - onError: json_error_handler - cors + - swagger_params_parser - swagger_security - _swagger_validate - express_compatibility diff --git a/project-skeletons/connect/package.json b/project-skeletons/connect/package.json index ba9e64b9..d08243e2 100644 --- a/project-skeletons/connect/package.json +++ b/project-skeletons/connect/package.json @@ -8,12 +8,12 @@ "license": "", "main": "app.js", "dependencies": { - "connect": "^3.3.5", - "swagger-connect": "^0.1.0" + "connect": "^3.6.0", + "swagger-connect": "^0.7.0" }, "devDependencies": { - "should": "^7.1.0", - "supertest": "^1.0.0" + "should": "^11.2.1", + "supertest": "^3.0.0" }, "scripts": { "start": "node app.js", diff --git a/project-skeletons/express/package.json b/project-skeletons/express/package.json index 32020545..1a9f7c50 100644 --- a/project-skeletons/express/package.json +++ b/project-skeletons/express/package.json @@ -8,12 +8,12 @@ "license": "", "main": "app.js", "dependencies": { - "express": "^4.12.3", - "swagger-express-mw": "^0.1.0" + "express": "^4.15.2", + "swagger-express-mw": "^0.7.0" }, "devDependencies": { - "should": "^7.1.0", - "supertest": "^1.0.0" + "should": "^11.2.1", + "supertest": "^3.0.0" }, "scripts": { "start": "node app.js", diff --git a/project-skeletons/hapi/package.json b/project-skeletons/hapi/package.json index b4708bdc..ebacabf5 100644 --- a/project-skeletons/hapi/package.json +++ b/project-skeletons/hapi/package.json @@ -8,12 +8,12 @@ "license": "", "main": "app.js", "dependencies": { - "hapi": "^10.0.0", - "swagger-hapi": "^0.1.0" + "hapi": "^16.1.1", + "swagger-hapi": "^0.7.0" }, "devDependencies": { - "should": "^7.1.0", - "supertest": "^1.0.0" + "should": "^11.2.1", + "supertest": "^3.0.0" }, "scripts": { "start": "node app.js", diff --git a/project-skeletons/restify/package.json b/project-skeletons/restify/package.json index 901b5090..fb3fdb21 100644 --- a/project-skeletons/restify/package.json +++ b/project-skeletons/restify/package.json @@ -8,12 +8,12 @@ "license": "", "main": "app.js", "dependencies": { - "restify": "^4.0.2", - "swagger-restify-mw": "^0.1.0" + "restify": "^4.3.0", + "swagger-restify-mw": "^0.7.0" }, "devDependencies": { - "should": "^7.1.0", - "supertest": "^1.0.0" + "should": "^11.2.1", + "supertest": "^3.0.0" }, "scripts": { "start": "node app.js", From facfaf3e169ac283b004b330b0ef30cd9a3a1ab4 Mon Sep 17 00:00:00 2001 From: Michael Mrowetz Date: Tue, 11 Apr 2017 12:16:06 +0900 Subject: [PATCH 2/5] fix typo --- .gitignore | 1 + docs/configuration.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index be222a27..2d6664e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # IDE files .idea +.vscode # Logs logs diff --git a/docs/configuration.md b/docs/configuration.md index 4b87ec6d..4f50e430 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,6 +1,6 @@ ## Configuration -** NOTE: The following applies to swagger-node apps replying on swagger-node-runner 0.5.x and better. (ie. Any app using swagger-connect 0.1.0, swagger-express-wm 0.1.0, swagger-hapi 0.1.0, swagger-restify 0.1.0, or swagger-sails 0.1.0 - or higher versions of the same.) ** +** NOTE: The following applies to swagger-node apps replying on swagger-node-runner 0.5.x and better. (ie. Any app using swagger-connect 0.1.0, swagger-express-mw 0.1.0, swagger-hapi 0.1.0, swagger-restify 0.1.0, or swagger-sails 0.1.0 - or higher versions of the same.) ** Swagger-Node application configuration is driven by the file `default.yaml` (by default) in the application's config directory. Configuration is driven by the [config](https://github.com/lorenwest/node-config/wiki/Configuration-Files) module, so reference its documentation to understand how you may set up configuration per environment and perform configuration overrides. By default, the configuration file looks something like this: From 8bc44f5629ad5e85a2d9474465950343a6030d3e Mon Sep 17 00:00:00 2001 From: Michael Mrowetz Date: Sat, 15 Apr 2017 16:56:34 +0900 Subject: [PATCH 3/5] update sails skeleton to sails 0.12.13 and swagger-sails-hook 0.7.0 --- project-skeletons/sails/.editorconfig | 10 + project-skeletons/sails/.gitignore | 134 ++- project-skeletons/sails/.sailsrc | 5 + project-skeletons/sails/Gruntfile.js | 107 +-- .../sails/api/policies/sessionAuth.js | 2 +- .../sails/api/responses/badRequest.js | 20 +- .../sails/api/responses/created.js | 60 ++ .../sails/api/responses/forbidden.js | 20 +- .../sails/api/responses/notFound.js | 20 +- project-skeletons/sails/api/responses/ok.js | 18 +- .../sails/api/responses/serverError.js | 20 +- project-skeletons/sails/app.js | 63 +- .../sails/assets/js/dependencies/sails.io.js | 875 ++++++++++++++---- project-skeletons/sails/assets/robots.txt | 2 +- project-skeletons/sails/config/blueprints.js | 17 +- project-skeletons/sails/config/bootstrap.js | 2 +- project-skeletons/sails/config/connections.js | 46 +- project-skeletons/sails/config/cors.js | 2 +- project-skeletons/sails/config/csrf.js | 4 +- project-skeletons/sails/config/default.yaml | 1 + project-skeletons/sails/config/globals.js | 2 +- project-skeletons/sails/config/http.js | 14 +- project-skeletons/sails/config/i18n.js | 4 +- project-skeletons/sails/config/local.js | 2 +- .../sails/config/locales/es.json | 2 +- project-skeletons/sails/config/log.js | 2 +- project-skeletons/sails/config/models.js | 4 +- project-skeletons/sails/config/policies.js | 4 +- project-skeletons/sails/config/routes.js | 4 +- project-skeletons/sails/config/session.js | 45 +- project-skeletons/sails/config/sockets.js | 34 +- project-skeletons/sails/config/views.js | 2 +- project-skeletons/sails/package.json | 40 +- project-skeletons/sails/tasks/config/clean.js | 19 +- .../sails/tasks/config/coffee.js | 49 +- .../sails/tasks/config/concat.js | 36 +- project-skeletons/sails/tasks/config/copy.js | 58 +- .../sails/tasks/config/cssmin.js | 24 +- project-skeletons/sails/tasks/config/jst.js | 59 +- project-skeletons/sails/tasks/config/less.js | 33 +- .../sails/tasks/config/sails-linker.js | 484 +++++----- project-skeletons/sails/tasks/config/sync.js | 30 +- .../sails/tasks/config/uglify.js | 20 +- project-skeletons/sails/tasks/config/watch.js | 31 +- project-skeletons/sails/tasks/pipeline.js | 41 +- .../sails/tasks/register/build.js | 33 +- .../sails/tasks/register/buildProd.js | 38 +- .../sails/tasks/register/compileAssets.js | 29 +- .../sails/tasks/register/default.js | 25 +- .../sails/tasks/register/linkAssets.js | 31 +- .../sails/tasks/register/linkAssetsBuild.js | 30 +- .../tasks/register/linkAssetsBuildProd.js | 30 +- .../sails/tasks/register/prod.js | 39 +- .../sails/tasks/register/syncAssets.js | 26 +- project-skeletons/sails/views/403.ejs | 66 +- project-skeletons/sails/views/404.ejs | 16 +- project-skeletons/sails/views/500.ejs | 16 +- project-skeletons/sails/views/homepage.ejs | 116 +-- project-skeletons/sails/views/layout.ejs | 20 +- 59 files changed, 1953 insertions(+), 1033 deletions(-) create mode 100644 project-skeletons/sails/.editorconfig create mode 100644 project-skeletons/sails/.sailsrc create mode 100644 project-skeletons/sails/api/responses/created.js diff --git a/project-skeletons/sails/.editorconfig b/project-skeletons/sails/.editorconfig new file mode 100644 index 00000000..0f099897 --- /dev/null +++ b/project-skeletons/sails/.editorconfig @@ -0,0 +1,10 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/project-skeletons/sails/.gitignore b/project-skeletons/sails/.gitignore index 65f91cd1..95f2d5dd 100644 --- a/project-skeletons/sails/.gitignore +++ b/project-skeletons/sails/.gitignore @@ -1,34 +1,120 @@ -# IDE files -.idea +################################################ +############### .gitignore ################## +################################################ +# +# This file is only relevant if you are using git. +# +# Files which match the splat patterns below will +# be ignored by git. This keeps random crap and +# sensitive credentials from being uploaded to +# your repository. It allows you to configure your +# app for your machine without accidentally +# committing settings which will smash the local +# settings of other developers on your team. +# +# Some reasonable defaults are included below, +# but, of course, you should modify/extend/prune +# to fit your needs! +################################################ -# Logs -logs -*.log -# Runtime data -pids -*.pid -*.seed -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov -# Coverage directory used by tools like istanbul -coverage +################################################ +# Local Configuration +# +# Explicitly ignore files which contain: +# +# 1. Sensitive information you'd rather not push to +# your git repository. +# e.g., your personal API keys or passwords. +# +# 2. Environment-specific configuration +# Basically, anything that would be annoying +# to have to change every time you do a +# `git pull` +# e.g., your local development database, or +# the S3 bucket you're using for file uploads +# development. +# +################################################ + +config/local.js + -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release -# Dependency directory -# Commenting this out is preferred by some people, see -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git + +################################################ +# Dependencies +# +# When releasing a production app, you may +# consider including your node_modules and +# bower_components directory in your git repo, +# but during development, its best to exclude it, +# since different developers may be working on +# different kernels, where dependencies would +# need to be recompiled anyway. +# +# More on that here about node_modules dir: +# http://www.futurealoof.com/posts/nodemodules-in-git.html +# (credit Mikeal Rogers, @mikeal) +# +# About bower_components dir, you can see this: +# http://addyosmani.com/blog/checking-in-front-end-dependencies/ +# (credit Addy Osmani, @addyosmani) +# +################################################ + node_modules +bower_components + + + + +################################################ +# Sails.js / Waterline / Grunt +# +# Files generated by Sails and Grunt, or related +# tasks and adapters. +################################################ +.tmp +dump.rdb + -# Users Environment Variables -.lock-wscript -# Runtime configuration for swagger app -config/runtime.yaml + + +################################################ +# Node.js / NPM +# +# Common files generated by Node, NPM, and the +# related ecosystem. +################################################ +lib-cov +*.seed +*.log +*.out +*.pid +npm-debug.log + + + + + +################################################ +# Miscellaneous +# +# Common files generated by text editors, +# operating systems, file systems, etc. +################################################ + +*~ +*# +.DS_STORE +.netbeans +nbproject +.idea +.node_history +.vscode +.DS_STORE \ No newline at end of file diff --git a/project-skeletons/sails/.sailsrc b/project-skeletons/sails/.sailsrc new file mode 100644 index 00000000..fa89f5e1 --- /dev/null +++ b/project-skeletons/sails/.sailsrc @@ -0,0 +1,5 @@ +{ + "generators": { + "modules": {} + } +} \ No newline at end of file diff --git a/project-skeletons/sails/Gruntfile.js b/project-skeletons/sails/Gruntfile.js index f4b2289a..212c569c 100644 --- a/project-skeletons/sails/Gruntfile.js +++ b/project-skeletons/sails/Gruntfile.js @@ -15,67 +15,68 @@ module.exports = function(grunt) { - // Load the include-all library in order to require all of our grunt - // configurations and task registrations dynamically. - var includeAll; - try { - includeAll = require('include-all'); - } catch (e0) { - try { - includeAll = require('sails/node_modules/include-all'); - } - catch(e1) { - console.error('Could not find `include-all` module.'); - console.error('Skipping grunt tasks...'); - console.error('To fix this, please run:'); - console.error('npm install include-all --save`'); - console.error(); + // Load the include-all library in order to require all of our grunt + // configurations and task registrations dynamically. + var includeAll; + try { + includeAll = require('include-all'); + } catch (e0) { + try { + includeAll = require('sails/node_modules/include-all'); + } catch (e1) { + console.error('Could not find `include-all` module.'); + console.error('Skipping grunt tasks...'); + console.error('To fix this, please run:'); + console.error('npm install include-all --save`'); + console.error(); - grunt.registerTask('default', []); - return; - } - } + grunt.registerTask('default', []); + return; + } + } - /** - * Loads Grunt configuration modules from the specified - * relative path. These modules should export a function - * that, when run, should either load/configure or register - * a Grunt task. - */ - function loadTasks(relPath) { - return includeAll({ - dirname: require('path').resolve(__dirname, relPath), - filter: /(.+)\.js$/ - }) || {}; - } + /** + * Loads Grunt configuration modules from the specified + * relative path. These modules should export a function + * that, when run, should either load/configure or register + * a Grunt task. + */ + function loadTasks(relPath) { + return includeAll({ + dirname: require('path').resolve(__dirname, relPath), + filter: /(.+)\.js$/, + excludeDirs: /^\.(git|svn)$/ + }) || {}; + } - /** - * Invokes the function from a Grunt configuration module with - * a single argument - the `grunt` object. - */ - function invokeConfigFn(tasks) { - for (var taskName in tasks) { - if (tasks.hasOwnProperty(taskName)) { - tasks[taskName](grunt); - } - } - } + /** + * Invokes the function from a Grunt configuration module with + * a single argument - the `grunt` object. + */ + function invokeConfigFn(tasks) { + for (var taskName in tasks) { + if (tasks.hasOwnProperty(taskName)) { + tasks[taskName](grunt); + } + } + } + // Load task functions + var taskConfigurations = loadTasks('./tasks/config'), + registerDefinitions = loadTasks('./tasks/register'); - // Load task functions - var taskConfigurations = loadTasks('./tasks/config'), - registerDefinitions = loadTasks('./tasks/register'); + // (ensure that a default task exists) + if (!registerDefinitions.default) { + registerDefinitions.default = function(grunt) { + grunt.registerTask('default', []); + }; + } - // (ensure that a default task exists) - if (!registerDefinitions.default) { - registerDefinitions.default = function (grunt) { grunt.registerTask('default', []); }; - } - - // Run task functions to configure Grunt. - invokeConfigFn(taskConfigurations); - invokeConfigFn(registerDefinitions); + // Run task functions to configure Grunt. + invokeConfigFn(taskConfigurations); + invokeConfigFn(registerDefinitions); }; diff --git a/project-skeletons/sails/api/policies/sessionAuth.js b/project-skeletons/sails/api/policies/sessionAuth.js index d3051684..8f9a2647 100644 --- a/project-skeletons/sails/api/policies/sessionAuth.js +++ b/project-skeletons/sails/api/policies/sessionAuth.js @@ -4,7 +4,7 @@ * @module :: Policy * @description :: Simple policy to allow any authenticated user * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;` - * @docs :: http://sailsjs.org/#!documentation/policies + * @docs :: http://sailsjs.org/#!/documentation/concepts/Policies * */ module.exports = function(req, res, next) { diff --git a/project-skeletons/sails/api/responses/badRequest.js b/project-skeletons/sails/api/responses/badRequest.js index 9f99b130..0d37825c 100644 --- a/project-skeletons/sails/api/responses/badRequest.js +++ b/project-skeletons/sails/api/responses/badRequest.js @@ -34,12 +34,13 @@ module.exports = function badRequest(data, options) { // Only include errors in response if application environment // is not set to 'production'. In production, we shouldn't // send back any identifying information about errors. - if (sails.config.environment === 'production') { + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { data = undefined; } // If the user-agent wants JSON, always respond with JSON - if (req.wantsJSON) { + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { return res.jsonx(data); } @@ -47,16 +48,27 @@ module.exports = function badRequest(data, options) { // If it was omitted, use an empty object (`{}`) options = (typeof options === 'string') ? { view: options } : options || {}; + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + // If a view was provided in options, serve it. // Otherwise try to guess an appropriate view, or if that doesn't // work, just send JSON. if (options.view) { - return res.view(options.view, { data: data }); + return res.view(options.view, { data: viewData, title: 'Bad Request' }); } // If no second argument provided, try to serve the implied view, // but fall back to sending JSON(P) if no view can be inferred. - else return res.guessView({ data: data }, function couldNotGuessView () { + else return res.guessView({ data: viewData, title: 'Bad Request' }, function couldNotGuessView () { return res.jsonx(data); }); diff --git a/project-skeletons/sails/api/responses/created.js b/project-skeletons/sails/api/responses/created.js new file mode 100644 index 00000000..31401134 --- /dev/null +++ b/project-skeletons/sails/api/responses/created.js @@ -0,0 +1,60 @@ +/** + * 201 (CREATED) Response + * + * Usage: + * return res.created(); + * return res.created(data); + * return res.created(data, 'auth/login'); + * + * @param {Object} data + * @param {String|Object} options + * - pass string to render specified view + */ + +module.exports = function created (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + sails.log.silly('res.created() :: Sending 201 ("CREATED") response'); + + // Set status code + res.status(201); + + // If appropriate, serve data as JSON(P) + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Created' }); + } + + // If no second argument provided, try to serve the implied view, + // but fall back to sending JSON(P) if no view can be inferred. + else return res.guessView({ data: viewData, title: 'Created' }, function couldNotGuessView () { + return res.jsonx(data); + }); + +}; diff --git a/project-skeletons/sails/api/responses/forbidden.js b/project-skeletons/sails/api/responses/forbidden.js index 16e4d81d..ca94852f 100644 --- a/project-skeletons/sails/api/responses/forbidden.js +++ b/project-skeletons/sails/api/responses/forbidden.js @@ -31,12 +31,13 @@ module.exports = function forbidden (data, options) { // Only include errors in response if application environment // is not set to 'production'. In production, we shouldn't // send back any identifying information about errors. - if (sails.config.environment === 'production') { + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { data = undefined; } // If the user-agent wants JSON, always respond with JSON - if (req.wantsJSON) { + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { return res.jsonx(data); } @@ -44,16 +45,27 @@ module.exports = function forbidden (data, options) { // If it was omitted, use an empty object (`{}`) options = (typeof options === 'string') ? { view: options } : options || {}; + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + // If a view was provided in options, serve it. // Otherwise try to guess an appropriate view, or if that doesn't // work, just send JSON. if (options.view) { - return res.view(options.view, { data: data }); + return res.view(options.view, { data: viewData, title: 'Forbidden' }); } // If no second argument provided, try to serve the default view, // but fall back to sending JSON(P) if any errors occur. - else return res.view('403', { data: data }, function (err, html) { + else return res.view('403', { data: viewData, title: 'Forbidden' }, function (err, html) { // If a view error occured, fall back to JSON(P). if (err) { diff --git a/project-skeletons/sails/api/responses/notFound.js b/project-skeletons/sails/api/responses/notFound.js index d14a200f..8f0cd035 100644 --- a/project-skeletons/sails/api/responses/notFound.js +++ b/project-skeletons/sails/api/responses/notFound.js @@ -36,12 +36,13 @@ module.exports = function notFound (data, options) { // Only include errors in response if application environment // is not set to 'production'. In production, we shouldn't // send back any identifying information about errors. - if (sails.config.environment === 'production') { + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { data = undefined; } // If the user-agent wants JSON, always respond with JSON - if (req.wantsJSON) { + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { return res.jsonx(data); } @@ -49,16 +50,27 @@ module.exports = function notFound (data, options) { // If it was omitted, use an empty object (`{}`) options = (typeof options === 'string') ? { view: options } : options || {}; + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + // If a view was provided in options, serve it. // Otherwise try to guess an appropriate view, or if that doesn't // work, just send JSON. if (options.view) { - return res.view(options.view, { data: data }); + return res.view(options.view, { data: viewData, title: 'Not Found' }); } // If no second argument provided, try to serve the default view, // but fall back to sending JSON(P) if any errors occur. - else return res.view('404', { data: data }, function (err, html) { + else return res.view('404', { data: viewData, title: 'Not Found' }, function (err, html) { // If a view error occured, fall back to JSON(P). if (err) { diff --git a/project-skeletons/sails/api/responses/ok.js b/project-skeletons/sails/api/responses/ok.js index 4351d2e3..eb701447 100644 --- a/project-skeletons/sails/api/responses/ok.js +++ b/project-skeletons/sails/api/responses/ok.js @@ -24,7 +24,8 @@ module.exports = function sendOK (data, options) { res.status(200); // If appropriate, serve data as JSON(P) - if (req.wantsJSON) { + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { return res.jsonx(data); } @@ -32,16 +33,27 @@ module.exports = function sendOK (data, options) { // If it was omitted, use an empty object (`{}`) options = (typeof options === 'string') ? { view: options } : options || {}; + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + // If a view was provided in options, serve it. // Otherwise try to guess an appropriate view, or if that doesn't // work, just send JSON. if (options.view) { - return res.view(options.view, { data: data }); + return res.view(options.view, { data: viewData, title: 'OK' }); } // If no second argument provided, try to serve the implied view, // but fall back to sending JSON(P) if no view can be inferred. - else return res.guessView({ data: data }, function couldNotGuessView () { + else return res.guessView({ data: viewData, title: 'OK' }, function couldNotGuessView () { return res.jsonx(data); }); diff --git a/project-skeletons/sails/api/responses/serverError.js b/project-skeletons/sails/api/responses/serverError.js index e08b4cee..537c248c 100644 --- a/project-skeletons/sails/api/responses/serverError.js +++ b/project-skeletons/sails/api/responses/serverError.js @@ -31,12 +31,13 @@ module.exports = function serverError (data, options) { // Only include errors in response if application environment // is not set to 'production'. In production, we shouldn't // send back any identifying information about errors. - if (sails.config.environment === 'production') { + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { data = undefined; } // If the user-agent wants JSON, always respond with JSON - if (req.wantsJSON) { + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { return res.jsonx(data); } @@ -44,16 +45,27 @@ module.exports = function serverError (data, options) { // If it was omitted, use an empty object (`{}`) options = (typeof options === 'string') ? { view: options } : options || {}; + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + // If a view was provided in options, serve it. // Otherwise try to guess an appropriate view, or if that doesn't // work, just send JSON. if (options.view) { - return res.view(options.view, { data: data }); + return res.view(options.view, { data: viewData, title: 'Server Error' }); } // If no second argument provided, try to serve the default view, // but fall back to sending JSON(P) if any errors occur. - else return res.view('500', { data: data }, function (err, html) { + else return res.view('500', { data: viewData, title: 'Server Error' }, function (err, html) { // If a view error occured, fall back to JSON(P). if (err) { diff --git a/project-skeletons/sails/app.js b/project-skeletons/sails/app.js index 85c0af7a..6b751708 100644 --- a/project-skeletons/sails/app.js +++ b/project-skeletons/sails/app.js @@ -18,42 +18,43 @@ * `node app.js --silent --port=80 --prod` */ -// Ensure we're in the project directory, so relative paths work as expected + +// Ensure we're in the project directory, so cwd-relative paths work as expected // no matter where we actually lift from. +// > Note: This is not required in order to lift, but it is a convenient default. process.chdir(__dirname); -// Ensure a "sails" can be located: -(function() { - var sails; - try { - sails = require('sails'); - } catch (e) { - console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.'); - console.error('To do that, run `npm install sails`'); - console.error(''); - console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.'); - console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,'); - console.error('but if it doesn\'t, the app will run with the global sails instead!'); - return; - } +// Attempt to import `sails`. +var sails; +try { + sails = require('sails'); +} catch (e) { + console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.'); + console.error('To do that, run `npm install sails`'); + console.error(''); + console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.'); + console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,'); + console.error('but if it doesn\'t, the app will run with the global sails instead!'); + return; +} - // Try to get `rc` dependency - var rc; +// --• +// Try to get `rc` dependency (for loading `.sailsrc` files). +var rc; +try { + rc = require('rc'); +} catch (e0) { try { - rc = require('rc'); - } catch (e0) { - try { - rc = require('sails/node_modules/rc'); - } catch (e1) { - console.error('Could not find dependency: `rc`.'); - console.error('Your `.sailsrc` file(s) will be ignored.'); - console.error('To resolve this, run:'); - console.error('npm install rc --save'); - rc = function () { return {}; }; - } + rc = require('sails/node_modules/rc'); + } catch (e1) { + console.error('Could not find dependency: `rc`.'); + console.error('Your `.sailsrc` file(s) will be ignored.'); + console.error('To resolve this, run:'); + console.error('npm install rc --save'); + rc = function () { return {}; }; } +} - // Start server - sails.lift(rc('sails')); -})(); +// Start server +sails.lift(rc('sails')); diff --git a/project-skeletons/sails/assets/js/dependencies/sails.io.js b/project-skeletons/sails/assets/js/dependencies/sails.io.js index e05e36bb..3486b9a1 100644 --- a/project-skeletons/sails/assets/js/dependencies/sails.io.js +++ b/project-skeletons/sails/assets/js/dependencies/sails.io.js @@ -1,9 +1,37 @@ -// socket.io-1.2.1 -// (from http://socket.io/download/) -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}};Manager.prototype.cleanup=function(){var sub;while(sub=this.subs.shift())sub.destroy();this.packetBuffer=[];this.encoding=false;this.decoder.destroy()};Manager.prototype.close=Manager.prototype.disconnect=function(){this.skipReconnect=true;this.readyState="closed";this.engine&&this.engine.close()};Manager.prototype.onclose=function(reason){debug("close");this.cleanup();this.readyState="closed";this.emit("close",reason);if(this._reconnection&&!this.skipReconnect){this.reconnect()}};Manager.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var self=this;this.attempts++;if(this.attempts>this._reconnectionAttempts){debug("reconnect failed");this.emitAll("reconnect_failed");this.reconnecting=false}else{var delay=this.attempts*this.reconnectionDelay();delay=Math.min(delay,this.reconnectionDelayMax());debug("will wait %dms before reconnect attempt",delay);this.reconnecting=true;var timer=setTimeout(function(){if(self.skipReconnect)return;debug("attempting reconnect");self.emitAll("reconnect_attempt",self.attempts);self.emitAll("reconnecting",self.attempts);if(self.skipReconnect)return;self.open(function(err){if(err){debug("reconnect attempt error");self.reconnecting=false;self.reconnect();self.emitAll("reconnect_error",err.data)}else{debug("reconnect success");self.onreconnect()}})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}};Manager.prototype.onreconnect=function(){var attempt=this.attempts;this.attempts=0;this.reconnecting=false;this.emitAll("reconnect",attempt)}},{"./on":4,"./socket":5,"./url":6,"component-bind":7,"component-emitter":8,debug:9,"engine.io-client":10,indexof:39,"object-component":40,"socket.io-parser":43}],4:[function(_dereq_,module,exports){module.exports=on;function on(obj,ev,fn){obj.on(ev,fn);return{destroy:function(){obj.removeListener(ev,fn)}}}},{}],5:[function(_dereq_,module,exports){var parser=_dereq_("socket.io-parser");var Emitter=_dereq_("component-emitter");var toArray=_dereq_("to-array");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:socket");var hasBin=_dereq_("has-binary");module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1};var emit=Emitter.prototype.emit;function Socket(io,nsp){this.io=io;this.nsp=nsp;this.json=this;this.ids=0;this.acks={};if(this.io.autoConnect)this.open();this.receiveBuffer=[];this.sendBuffer=[];this.connected=false;this.disconnected=true}Emitter(Socket.prototype);Socket.prototype.subEvents=function(){if(this.subs)return;var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]};Socket.prototype.open=Socket.prototype.connect=function(){if(this.connected)return this;this.subEvents();this.io.open();if("open"==this.io.readyState)this.onopen();return this};Socket.prototype.send=function(){var args=toArray(arguments);args.unshift("message");this.emit.apply(this,args);return this};Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev)){emit.apply(this,arguments);return this}var args=toArray(arguments);var parserType=parser.EVENT;if(hasBin(args)){parserType=parser.BINARY_EVENT}var packet={type:parserType,data:args};if("function"==typeof args[args.length-1]){debug("emitting packet with ack id %d",this.ids);this.acks[this.ids]=args.pop();packet.id=this.ids++}if(this.connected){this.packet(packet)}else{this.sendBuffer.push(packet)}return this};Socket.prototype.packet=function(packet){packet.nsp=this.nsp;this.io.packet(packet)};Socket.prototype.onopen=function(){debug("transport is open - connecting");if("/"!=this.nsp){this.packet({type:parser.CONNECT})}};Socket.prototype.onclose=function(reason){debug("close (%s)",reason);this.connected=false;this.disconnected=true;this.emit("disconnect",reason)};Socket.prototype.onpacket=function(packet){if(packet.nsp!=this.nsp)return;switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data);break}};Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args);if(null!=packet.id){debug("attaching ack callback to event");args.push(this.ack(packet.id))}if(this.connected){emit.apply(this,args)}else{this.receiveBuffer.push(args)}};Socket.prototype.ack=function(id){var self=this;var sent=false;return function(){if(sent)return;sent=true;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}};Socket.prototype.onack=function(packet){debug("calling ack %s with %j",packet.id,packet.data);var fn=this.acks[packet.id];fn.apply(this,packet.data);delete this.acks[packet.id]};Socket.prototype.onconnect=function(){this.connected=true;this.disconnected=false;this.emit("connect");this.emitBuffered()};Socket.prototype.emitBuffered=function(){var i;for(i=0;i=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"};debug.enabled=function(name){for(var i=0,len=debug.skips.length;i';iframe=document.createElement(html)}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId;iframe.src="javascript:0"}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();data=data.replace(rEscapedNewline,"\\\n");this.area.value=data.replace(rNewline,"\\n");try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){this.iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":17,"component-inherit":20}],16:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest");var Polling=_dereq_("./polling");var Emitter=_dereq_("component-emitter");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling-xhr");module.exports=XHR;module.exports.Request=Request;function empty(){}function XHR(opts){Polling.call(this,opts);if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}this.xd=opts.hostname!=global.location.hostname||port!=opts.port;this.xs=opts.secure!=isSSL}}inherit(XHR,Polling);XHR.prototype.supportsBinary=true;XHR.prototype.request=function(opts){opts=opts||{};opts.uri=this.uri();opts.xd=this.xd;opts.xs=this.xs;opts.agent=this.agent||false;opts.supportsBinary=this.supportsBinary;opts.enablesXDR=this.enablesXDR;return new Request(opts)};XHR.prototype.doWrite=function(data,fn){var isBinary=typeof data!=="string"&&data!==undefined;var req=this.request({method:"POST",data:data,isBinary:isBinary});var self=this;req.on("success",fn);req.on("error",function(err){self.onError("xhr post error",err)});this.sendXhr=req};XHR.prototype.doPoll=function(){debug("xhr poll");var req=this.request();var self=this;req.on("data",function(data){self.onData(data)});req.on("error",function(err){self.onError("xhr poll error",err)});this.pollXhr=req};function Request(opts){this.method=opts.method||"GET";this.uri=opts.uri;this.xd=!!opts.xd;this.xs=!!opts.xs;this.async=false!==opts.async;this.data=undefined!=opts.data?opts.data:null;this.agent=opts.agent;this.isBinary=opts.isBinary;this.supportsBinary=opts.supportsBinary;this.enablesXDR=opts.enablesXDR;this.create()}Emitter(Request.prototype);Request.prototype.create=function(){var xhr=this.xhr=new XMLHttpRequest({agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR});var self=this;try{debug("xhr open %s: %s",this.method,this.uri);xhr.open(this.method,this.uri,this.async);if(this.supportsBinary){xhr.responseType="arraybuffer"}if("POST"==this.method){try{if(this.isBinary){xhr.setRequestHeader("Content-type","application/octet-stream")}else{xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")}}catch(e){}}if("withCredentials"in xhr){xhr.withCredentials=true}if(this.hasXDR()){xhr.onload=function(){self.onLoad()};xhr.onerror=function(){self.onError(xhr.responseText)}}else{xhr.onreadystatechange=function(){if(4!=xhr.readyState)return;if(200==xhr.status||1223==xhr.status){self.onLoad()}else{setTimeout(function(){self.onError(xhr.status)},0)}}}debug("xhr data %s",this.data);xhr.send(this.data)}catch(e){setTimeout(function(){self.onError(e)},0);return}if(global.document){this.index=Request.requestsCount++;Request.requests[this.index]=this}};Request.prototype.onSuccess=function(){this.emit("success");this.cleanup()};Request.prototype.onData=function(data){this.emit("data",data);this.onSuccess()};Request.prototype.onError=function(err){this.emit("error",err);this.cleanup()};Request.prototype.cleanup=function(){if("undefined"==typeof this.xhr||null===this.xhr){return}if(this.hasXDR()){this.xhr.onload=this.xhr.onerror=empty}else{this.xhr.onreadystatechange=empty}try{this.xhr.abort()}catch(e){}if(global.document){delete Request.requests[this.index]}this.xhr=null};Request.prototype.onLoad=function(){var data;try{var contentType;try{contentType=this.xhr.getResponseHeader("Content-Type").split(";")[0]}catch(e){}if(contentType==="application/octet-stream"){data=this.xhr.response}else{if(!this.supportsBinary){data=this.xhr.responseText}else{data="ok"}}}catch(e){this.onError(e)}if(null!=data){this.onData(data)}};Request.prototype.hasXDR=function(){return"undefined"!==typeof global.XDomainRequest&&!this.xs&&this.enablesXDR};Request.prototype.abort=function(){this.cleanup()};if(global.document){Request.requestsCount=0;Request.requests={};if(global.attachEvent){global.attachEvent("onunload",unloadHandler)}else if(global.addEventListener){global.addEventListener("beforeunload",unloadHandler,false)}}function unloadHandler(){for(var i in Request.requests){if(Request.requests.hasOwnProperty(i)){Request.requests[i].abort()}}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":17,"component-emitter":8,"component-inherit":20,debug:21,xmlhttprequest:19}],17:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parseqs=_dereq_("parseqs");var parser=_dereq_("engine.io-parser");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling");module.exports=Polling;var hasXHR2=function(){var XMLHttpRequest=_dereq_("xmlhttprequest");var xhr=new XMLHttpRequest({xdomain:false});return null!=xhr.responseType}();function Polling(opts){var forceBase64=opts&&opts.forceBase64;if(!hasXHR2||forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(Polling,Transport);Polling.prototype.name="polling";Polling.prototype.doOpen=function(){this.poll()};Polling.prototype.pause=function(onPause){var pending=0;var self=this;this.readyState="pausing";function pause(){debug("paused");self.readyState="paused";onPause()}if(this.polling||!this.writable){var total=0;if(this.polling){debug("we are currently polling - waiting to pause");total++;this.once("pollComplete",function(){debug("pre-pause polling complete");--total||pause()})}if(!this.writable){debug("we are currently writing - waiting to pause");total++;this.once("drain",function(){debug("pre-pause writing complete");--total||pause()})}}else{pause()}};Polling.prototype.poll=function(){debug("polling");this.polling=true;this.doPoll();this.emit("poll")};Polling.prototype.onData=function(data){var self=this;debug("polling got data %s",data);var callback=function(packet,index,total){if("opening"==self.readyState){self.onOpen()}if("close"==packet.type){self.onClose();return false}self.onPacket(packet)};parser.decodePayload(data,this.socket.binaryType,callback);if("closed"!=this.readyState){this.polling=false;this.emit("pollComplete");if("open"==this.readyState){this.poll()}else{debug('ignoring poll - transport state "%s"',this.readyState)}}};Polling.prototype.doClose=function(){var self=this;function close(){debug("writing close packet");self.write([{type:"close"}])}if("open"==this.readyState){debug("transport open - closing");close()}else{debug("transport not open - deferring close");this.once("open",close)}};Polling.prototype.write=function(packets){var self=this;this.writable=false;var callbackfn=function(){self.writable=true;self.emit("drain")};var self=this;parser.encodePayload(packets,this.supportsBinary,function(data){self.doWrite(data,callbackfn)})};Polling.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"https":"http";var port="";if(false!==this.timestampRequests){query[this.timestampParam]=+new Date+"-"+Transport.timestamps++}if(!this.supportsBinary&&!query.sid){query.b64=1}query=parseqs.encode(query);if(this.port&&("https"==schema&&this.port!=443||"http"==schema&&this.port!=80)){port=":"+this.port}if(query.length){query="?"+query}return schema+"://"+this.hostname+port+this.path+query}},{"../transport":13,"component-inherit":20,debug:21,"engine.io-parser":24,parseqs:32,xmlhttprequest:19}],18:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parser=_dereq_("engine.io-parser");var parseqs=_dereq_("parseqs");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:websocket");var WebSocket=_dereq_("ws");module.exports=WS;function WS(opts){var forceBase64=opts&&opts.forceBase64;if(forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(WS,Transport);WS.prototype.name="websocket";WS.prototype.supportsBinary=true;WS.prototype.doOpen=function(){if(!this.check()){return}var self=this;var uri=this.uri();var protocols=void 0;var opts={agent:this.agent};this.ws=new WebSocket(uri,protocols,opts);if(this.ws.binaryType===undefined){this.supportsBinary=false}this.ws.binaryType="arraybuffer";this.addEventListeners()};WS.prototype.addEventListeners=function(){var self=this;this.ws.onopen=function(){self.onOpen()};this.ws.onclose=function(){self.onClose()};this.ws.onmessage=function(ev){self.onData(ev.data)};this.ws.onerror=function(e){self.onError("websocket error",e)}};if("undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)){WS.prototype.onData=function(data){var self=this;setTimeout(function(){Transport.prototype.onData.call(self,data)},0)}}WS.prototype.write=function(packets){var self=this;this.writable=false;for(var i=0,l=packets.length;i=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"==typeof console&&"function"==typeof console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){localStorage.removeItem("debug")}else{localStorage.debug=namespaces}}catch(e){}}function load(){var r;try{r=localStorage.debug}catch(e){}return r}exports.enable(load())},{"./debug":22}],22:[function(_dereq_,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=_dereq_("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms1){return{type:packetslist[type],data:data.substring(1)}}else{return{type:packetslist[type]}}}var asArray=new Uint8Array(data);var type=asArray[0];var rest=sliceBuffer(data,1);if(Blob&&binaryType==="blob"){rest=new Blob([rest])}return{type:packetslist[type],data:rest}};exports.decodeBase64Packet=function(msg,binaryType){var type=packetslist[msg.charAt(0)];if(!global.ArrayBuffer){return{type:type,data:{base64:true,data:msg.substr(1)}}}var data=base64encoder.decode(msg.substr(1));if(binaryType==="blob"&&Blob){data=new Blob([data])}return{type:type,data:data}};exports.encodePayload=function(packets,supportsBinary,callback){if(typeof supportsBinary=="function"){callback=supportsBinary;supportsBinary=null}if(supportsBinary){if(Blob&&!isAndroid){return exports.encodePayloadAsBlob(packets,callback)}return exports.encodePayloadAsArrayBuffer(packets,callback)}if(!packets.length){return callback("0:")}function setLengthHeader(message){return message.length+":"+message}function encodeOne(packet,doneCallback){exports.encodePacket(packet,supportsBinary,true,function(message){doneCallback(null,setLengthHeader(message))})}map(packets,encodeOne,function(err,results){return callback(results.join(""))})};function map(ary,each,done){var result=new Array(ary.length);var next=after(ary.length,done);var eachWithIndex=function(i,el,cb){each(el,function(error,msg){result[i]=msg;cb(error,result)})};for(var i=0;i0){var tailArray=new Uint8Array(bufferTail);var isString=tailArray[0]===0;var msgLength="";for(var i=1;;i++){if(tailArray[i]==255)break;if(msgLength.length>310){numberTooLong=true;break}msgLength+=tailArray[i]}if(numberTooLong)return callback(err,0,1);bufferTail=sliceBuffer(bufferTail,2+msgLength.length);msgLength=parseInt(msgLength);var msg=sliceBuffer(bufferTail,0,msgLength);if(isString){try{msg=String.fromCharCode.apply(null,new Uint8Array(msg))}catch(e){var typed=new Uint8Array(msg);msg="";for(var i=0;ibytes){end=bytes}if(start>=bytes||start>=end||bytes===0){return new ArrayBuffer(0)}var abv=new Uint8Array(arraybuffer);var result=new Uint8Array(end-start);for(var i=start,ii=0;i>2];base64+=chars[(bytes[i]&3)<<4|bytes[i+1]>>4];base64+=chars[(bytes[i+1]&15)<<2|bytes[i+2]>>6];base64+=chars[bytes[i+2]&63]}if(len%3===2){base64=base64.substring(0,base64.length-1)+"="}else if(len%3===1){base64=base64.substring(0,base64.length-2)+"=="}return base64};exports.decode=function(base64){var bufferLength=base64.length*.75,len=base64.length,i,p=0,encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==="="){bufferLength--;if(base64[base64.length-2]==="="){bufferLength--}}var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(i=0;i>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63}return arraybuffer}})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},{}],29:[function(_dereq_,module,exports){(function(global){var BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder||global.MSBlobBuilder||global.MozBlobBuilder;var blobSupported=function(){try{var b=new Blob(["hi"]);return b.size==2}catch(e){return false}}();var blobBuilderSupported=BlobBuilder&&BlobBuilder.prototype.append&&BlobBuilder.prototype.getBlob;function BlobBuilderConstructor(ary,options){options=options||{};var bb=new BlobBuilder;for(var i=0;i=55296&&value<=56319&&counter65535){value-=65536;output+=stringFromCharCode(value>>>10&1023|55296);value=56320|value&1023}output+=stringFromCharCode(value)}return output}function createByte(codePoint,shift){return stringFromCharCode(codePoint>>shift&63|128)}function encodeCodePoint(codePoint){if((codePoint&4294967168)==0){return stringFromCharCode(codePoint)}var symbol="";if((codePoint&4294965248)==0){symbol=stringFromCharCode(codePoint>>6&31|192)}else if((codePoint&4294901760)==0){symbol=stringFromCharCode(codePoint>>12&15|224);symbol+=createByte(codePoint,6)}else if((codePoint&4292870144)==0){symbol=stringFromCharCode(codePoint>>18&7|240);symbol+=createByte(codePoint,12);symbol+=createByte(codePoint,6)}symbol+=stringFromCharCode(codePoint&63|128);return symbol}function utf8encode(string){var codePoints=ucs2decode(string);var length=codePoints.length;var index=-1;var codePoint;var byteString="";while(++index=byteCount){throw Error("Invalid byte index")}var continuationByte=byteArray[byteIndex]&255;byteIndex++;if((continuationByte&192)==128){return continuationByte&63}throw Error("Invalid continuation byte")}function decodeSymbol(){var byte1;var byte2;var byte3;var byte4;var codePoint;if(byteIndex>byteCount){throw Error("Invalid byte index")}if(byteIndex==byteCount){return false}byte1=byteArray[byteIndex]&255;byteIndex++;if((byte1&128)==0){return byte1}if((byte1&224)==192){var byte2=readContinuationByte();codePoint=(byte1&31)<<6|byte2;if(codePoint>=128){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&240)==224){byte2=readContinuationByte();byte3=readContinuationByte();codePoint=(byte1&15)<<12|byte2<<6|byte3;if(codePoint>=2048){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&248)==240){byte2=readContinuationByte();byte3=readContinuationByte();byte4=readContinuationByte();codePoint=(byte1&15)<<18|byte2<<12|byte3<<6|byte4;if(codePoint>=65536&&codePoint<=1114111){return codePoint}}throw Error("Invalid UTF-8 detected")}var byteArray;var byteCount;var byteIndex;function utf8decode(byteString){byteArray=ucs2decode(byteString);byteCount=byteArray.length;byteIndex=0;var codePoints=[];var tmp;while((tmp=decodeSymbol())!==false){codePoints.push(tmp)}return ucs2encode(codePoints)}var utf8={version:"2.0.0",encode:utf8encode,decode:utf8decode};if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){define(function(){return utf8})}else if(freeExports&&!freeExports.nodeType){if(freeModule){freeModule.exports=utf8}else{var object={};var hasOwnProperty=object.hasOwnProperty;for(var key in utf8){hasOwnProperty.call(utf8,key)&&(freeExports[key]=utf8[key])}}}else{root.utf8=utf8}})(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],31:[function(_dereq_,module,exports){(function(global){var rvalidchars=/^[\],:{}\s]*$/;var rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g;var rtrimLeft=/^\s+/;var rtrimRight=/\s+$/;module.exports=function parsejson(data){if("string"!=typeof data||!data){return null}data=data.replace(rtrimLeft,"").replace(rtrimRight,"");if(global.JSON&&JSON.parse){return JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],32:[function(_dereq_,module,exports){exports.encode=function(obj){var str="";for(var i in obj){if(obj.hasOwnProperty(i)){if(str.length)str+="&";str+=encodeURIComponent(i)+"="+encodeURIComponent(obj[i])}}return str};exports.decode=function(qs){var qry={};var pairs=qs.split("&");for(var i=0,l=pairs.length;i1)))/4)-floor((year-1901+month)/100)+floor((year-1601+month)/400)}}if(!(isProperty={}.hasOwnProperty)){isProperty=function(property){var members={},constructor;if((members.__proto__=null,members.__proto__={toString:1},members).toString!=getClass){isProperty=function(property){var original=this.__proto__,result=property in(this.__proto__=null,this);this.__proto__=original;return result}}else{constructor=members.constructor;isProperty=function(property){var parent=(this.constructor||constructor).prototype;return property in this&&!(property in parent&&this[property]===parent[property])}}members=null;return isProperty.call(this,property)}}var PrimitiveTypes={"boolean":1,number:1,string:1,undefined:1};var isHostType=function(object,property){var type=typeof object[property];return type=="object"?!!object[property]:!PrimitiveTypes[type]};forEach=function(object,callback){var size=0,Properties,members,property;(Properties=function(){this.valueOf=0}).prototype.valueOf=0;members=new Properties;for(property in members){if(isProperty.call(members,property)){size++}}Properties=members=null;if(!size){members=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,length;var hasProperty=!isFunction&&typeof object.constructor!="function"&&isHostType(object,"hasOwnProperty")?object.hasOwnProperty:isProperty;for(property in object){if(!(isFunction&&property=="prototype")&&hasProperty.call(object,property)){callback(property)}}for(length=members.length;property=members[--length];hasProperty.call(object,property)&&callback(property));}}else if(size==2){forEach=function(object,callback){var members={},isFunction=getClass.call(object)==functionClass,property;for(property in object){if(!(isFunction&&property=="prototype")&&!isProperty.call(members,property)&&(members[property]=1)&&isProperty.call(object,property)){callback(property)}}}}else{forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,isConstructor;for(property in object){if(!(isFunction&&property=="prototype")&&isProperty.call(object,property)&&!(isConstructor=property==="constructor")){callback(property)}}if(isConstructor||isProperty.call(object,property="constructor")){callback(property)}}}return forEach(object,callback)};if(!has("json-stringify")){var Escapes={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"};var leadingZeroes="000000";var toPaddedString=function(width,value){return(leadingZeroes+(value||0)).slice(-width)};var unicodePrefix="\\u00";var quote=function(value){var result='"',index=0,length=value.length,isLarge=length>10&&charIndexBuggy,symbols;if(isLarge){symbols=value.split("")}for(;index-1/0&&value<1/0){if(getDay){date=floor(value/864e5);for(year=floor(date/365.2425)+1970-1;getDay(year+1,0)<=date;year++);for(month=floor((date-getDay(year,0))/30.42);getDay(year,month+1)<=date;month++);date=1+date-getDay(year,month);time=(value%864e5+864e5)%864e5;hours=floor(time/36e5)%24;minutes=floor(time/6e4)%60;seconds=floor(time/1e3)%60;milliseconds=time%1e3}else{year=value.getUTCFullYear();month=value.getUTCMonth();date=value.getUTCDate();hours=value.getUTCHours();minutes=value.getUTCMinutes();seconds=value.getUTCSeconds();milliseconds=value.getUTCMilliseconds()}value=(year<=0||year>=1e4?(year<0?"-":"+")+toPaddedString(6,year<0?-year:year):toPaddedString(4,year))+"-"+toPaddedString(2,month+1)+"-"+toPaddedString(2,date)+"T"+toPaddedString(2,hours)+":"+toPaddedString(2,minutes)+":"+toPaddedString(2,seconds)+"."+toPaddedString(3,milliseconds)+"Z"}else{value=null}}else if(typeof value.toJSON=="function"&&(className!=numberClass&&className!=stringClass&&className!=arrayClass||isProperty.call(value,"toJSON"))){value=value.toJSON(property)}}if(callback){value=callback.call(object,property,value)}if(value===null){return"null"}className=getClass.call(value);if(className==booleanClass){return""+value}else if(className==numberClass){return value>-1/0&&value<1/0?""+value:"null"}else if(className==stringClass){return quote(""+value)}if(typeof value=="object"){for(length=stack.length;length--;){if(stack[length]===value){throw TypeError()}}stack.push(value);results=[];prefix=indentation;indentation+=whitespace;if(className==arrayClass){for(index=0,length=value.length;index0){for(whitespace="",width>10&&(width=10);whitespace.length=48&&charCode<=57||charCode>=97&&charCode<=102||charCode>=65&&charCode<=70)){abort()}}value+=fromCharCode("0x"+source.slice(begin,Index));break;default:abort()}}else{if(charCode==34){break}charCode=source.charCodeAt(Index);begin=Index;while(charCode>=32&&charCode!=92&&charCode!=34){charCode=source.charCodeAt(++Index)}value+=source.slice(begin,Index)}}if(source.charCodeAt(Index)==34){Index++;return value}abort();default:begin=Index;if(charCode==45){isSigned=true;charCode=source.charCodeAt(++Index)}if(charCode>=48&&charCode<=57){if(charCode==48&&(charCode=source.charCodeAt(Index+1),charCode>=48&&charCode<=57)){abort()}isSigned=false;for(;Index=48&&charCode<=57);Index++);if(source.charCodeAt(Index)==46){position=++Index;for(;position=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}charCode=source.charCodeAt(Index);if(charCode==101||charCode==69){charCode=source.charCodeAt(++Index);if(charCode==43||charCode==45){Index++}for(position=Index;position=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}return+source.slice(begin,Index)}if(isSigned){abort()}if(source.slice(Index,Index+4)=="true"){Index+=4;return true}else if(source.slice(Index,Index+5)=="false"){Index+=5;return false}else if(source.slice(Index,Index+4)=="null"){Index+=4;return null}abort()}}return"$"};var get=function(value){var results,hasMembers;if(value=="$"){abort()}if(typeof value=="string"){if((charIndexBuggy?value.charAt(0):value[0])=="@"){return value.slice(1)}if(value=="["){results=[];for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="]"){break}if(hasMembers){if(value==","){value=lex();if(value=="]"){abort()}}else{abort()}}if(value==","){abort()}results.push(get(value))}return results}else if(value=="{"){results={};for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="}"){break}if(hasMembers){if(value==","){value=lex();if(value=="}"){abort()}}else{abort()}}if(value==","||typeof value!="string"||(charIndexBuggy?value.charAt(0):value[0])!="@"||lex()!=":"){abort()}results[value.slice(1)]=get(lex())}return results}abort()}return value};var update=function(source,property,callback){var element=walk(source,property,callback);if(element===undef){delete source[property]}else{source[property]=element}};var walk=function(source,property,callback){var value=source[property],length;if(typeof value=="object"&&value){if(getClass.call(value)==arrayClass){for(length=value.length;length--;){update(value,length,callback)}}else{forEach(value,function(property){update(value,property,callback)})}}return callback.call(source,property,value)};JSON3.parse=function(source,callback){var result,value;Index=0;Source=""+source;result=get(lex());if(lex()!="$"){abort()}Index=Source=null;return callback&&getClass.call(callback)==functionClass?walk((value={},value[""]=result,value),"",callback):result}}}if(isLoader){define(function(){return JSON3})}})(this)},{}],47:[function(_dereq_,module,exports){module.exports=toArray;function toArray(list,index){var array=[];index=index||0;for(var i=index||0;i0&&(this.extraHeaders=b.extraHeaders),this.open()}function e(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}var f=a("./transports"),g=a("component-emitter"),h=a("debug")("engine.io-client:socket"),i=a("indexof"),j=a("engine.io-parser"),k=a("parseuri"),l=a("parsejson"),m=a("parseqs");b.exports=d,d.priorWebsocketSuccess=!1,g(d.prototype),d.protocol=j.protocol,d.Socket=d,d.Transport=a("./transport"),d.transports=a("./transports"),d.parser=a("engine.io-parser"),d.prototype.createTransport=function(a){h('creating transport "%s"',a);var b=e(this.query);b.EIO=j.protocol,b.transport=a,this.id&&(b.sid=this.id);var c=new f[a]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:b,forceJSONP:this.forceJSONP,jsonp:this.jsonp,forceBase64:this.forceBase64,enablesXDR:this.enablesXDR,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this,pfx:this.pfx,key:this.key,passphrase:this.passphrase,cert:this.cert,ca:this.ca,ciphers:this.ciphers,rejectUnauthorized:this.rejectUnauthorized,perMessageDeflate:this.perMessageDeflate,extraHeaders:this.extraHeaders});return c},d.prototype.open=function(){var a;if(this.rememberUpgrade&&d.priorWebsocketSuccess&&-1!=this.transports.indexOf("websocket"))a="websocket";else{if(0===this.transports.length){var b=this;return void setTimeout(function(){b.emit("error","No transports available")},0)}a=this.transports[0]}this.readyState="opening";try{a=this.createTransport(a)}catch(c){return this.transports.shift(),void this.open()}a.open(),this.setTransport(a)},d.prototype.setTransport=function(a){h("setting transport %s",a.name);var b=this;this.transport&&(h("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=a,a.on("drain",function(){b.onDrain()}).on("packet",function(a){b.onPacket(a)}).on("error",function(a){b.onError(a)}).on("close",function(){b.onClose("transport close")})},d.prototype.probe=function(a){function b(){if(m.onlyBinaryUpgrades){var b=!this.supportsBinary&&m.transport.supportsBinary;l=l||b}l||(h('probe transport "%s" opened',a),k.send([{type:"ping",data:"probe"}]),k.once("packet",function(b){if(!l)if("pong"==b.type&&"probe"==b.data){if(h('probe transport "%s" pong',a),m.upgrading=!0,m.emit("upgrading",k),!k)return;d.priorWebsocketSuccess="websocket"==k.name,h('pausing current transport "%s"',m.transport.name),m.transport.pause(function(){l||"closed"!=m.readyState&&(h("changing transport and sending upgrade packet"),j(),m.setTransport(k),k.send([{type:"upgrade"}]),m.emit("upgrade",k),k=null,m.upgrading=!1,m.flush())})}else{h('probe transport "%s" failed',a);var c=new Error("probe error");c.transport=k.name,m.emit("upgradeError",c)}}))}function c(){l||(l=!0,j(),k.close(),k=null)}function e(b){var d=new Error("probe error: "+b);d.transport=k.name,c(),h('probe transport "%s" failed because of error: %s',a,b),m.emit("upgradeError",d)}function f(){e("transport closed")}function g(){e("socket closed")}function i(a){k&&a.name!=k.name&&(h('"%s" works - aborting "%s"',a.name,k.name),c())}function j(){k.removeListener("open",b),k.removeListener("error",e),k.removeListener("close",f),m.removeListener("close",g),m.removeListener("upgrading",i)}h('probing transport "%s"',a);var k=this.createTransport(a,{probe:1}),l=!1,m=this;d.priorWebsocketSuccess=!1,k.once("open",b),k.once("error",e),k.once("close",f),this.once("close",g),this.once("upgrading",i),k.open()},d.prototype.onOpen=function(){if(h("socket open"),this.readyState="open",d.priorWebsocketSuccess="websocket"==this.transport.name,this.emit("open"),this.flush(),"open"==this.readyState&&this.upgrade&&this.transport.pause){h("starting upgrade probes");for(var a=0,b=this.upgrades.length;b>a;a++)this.probe(this.upgrades[a])}},d.prototype.onPacket=function(a){if("opening"==this.readyState||"open"==this.readyState)switch(h('socket receive: type "%s", data "%s"',a.type,a.data),this.emit("packet",a),this.emit("heartbeat"),a.type){case"open":this.onHandshake(l(a.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var b=new Error("server error");b.code=a.data,this.onError(b);break;case"message":this.emit("data",a.data),this.emit("message",a.data)}else h('packet received with socket readyState "%s"',this.readyState)},d.prototype.onHandshake=function(a){this.emit("handshake",a),this.id=a.sid,this.transport.query.sid=a.sid,this.upgrades=this.filterUpgrades(a.upgrades),this.pingInterval=a.pingInterval,this.pingTimeout=a.pingTimeout,this.onOpen(),"closed"!=this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},d.prototype.onHeartbeat=function(a){clearTimeout(this.pingTimeoutTimer);var b=this;b.pingTimeoutTimer=setTimeout(function(){"closed"!=b.readyState&&b.onClose("ping timeout")},a||b.pingInterval+b.pingTimeout)},d.prototype.setPing=function(){var a=this;clearTimeout(a.pingIntervalTimer),a.pingIntervalTimer=setTimeout(function(){h("writing ping packet - expecting pong within %sms",a.pingTimeout),a.ping(),a.onHeartbeat(a.pingTimeout)},a.pingInterval)},d.prototype.ping=function(){var a=this;this.sendPacket("ping",function(){a.emit("ping")})},d.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emit("drain"):this.flush()},d.prototype.flush=function(){"closed"!=this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(h("flushing %d packets in socket",this.writeBuffer.length),this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emit("flush"))},d.prototype.write=d.prototype.send=function(a,b,c){return this.sendPacket("message",a,b,c),this},d.prototype.sendPacket=function(a,b,c,d){if("function"==typeof b&&(d=b,b=void 0),"function"==typeof c&&(d=c,c=null),"closing"!=this.readyState&&"closed"!=this.readyState){c=c||{},c.compress=!1!==c.compress;var e={type:a,data:b,options:c};this.emit("packetCreate",e),this.writeBuffer.push(e),d&&this.once("flush",d),this.flush()}},d.prototype.close=function(){function a(){d.onClose("forced close"),h("socket closing - telling transport to close"),d.transport.close()}function b(){d.removeListener("upgrade",b),d.removeListener("upgradeError",b),a()}function c(){d.once("upgrade",b),d.once("upgradeError",b)}if("opening"==this.readyState||"open"==this.readyState){this.readyState="closing";var d=this;this.writeBuffer.length?this.once("drain",function(){this.upgrading?c():a()}):this.upgrading?c():a()}return this},d.prototype.onError=function(a){h("socket error %j",a),d.priorWebsocketSuccess=!1,this.emit("error",a),this.onClose("transport error",a)},d.prototype.onClose=function(a,b){if("opening"==this.readyState||"open"==this.readyState||"closing"==this.readyState){h('socket close with reason: "%s"',a);var c=this;clearTimeout(this.pingIntervalTimer),clearTimeout(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),this.readyState="closed",this.id=null,this.emit("close",a,b),c.writeBuffer=[],c.prevBufferLen=0}},d.prototype.filterUpgrades=function(a){for(var b=[],c=0,d=a.length;d>c;c++)~i(this.transports,a[c])&&b.push(a[c]);return b}}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{})},{"./transport":4,"./transports":5,"component-emitter":15,debug:17,"engine.io-parser":19,indexof:23,parsejson:26,parseqs:27,parseuri:28}],4:[function(a,b,c){function d(a){this.path=a.path,this.hostname=a.hostname,this.port=a.port,this.secure=a.secure,this.query=a.query,this.timestampParam=a.timestampParam,this.timestampRequests=a.timestampRequests,this.readyState="",this.agent=a.agent||!1,this.socket=a.socket,this.enablesXDR=a.enablesXDR,this.pfx=a.pfx,this.key=a.key,this.passphrase=a.passphrase,this.cert=a.cert,this.ca=a.ca,this.ciphers=a.ciphers,this.rejectUnauthorized=a.rejectUnauthorized,this.extraHeaders=a.extraHeaders}var e=a("engine.io-parser"),f=a("component-emitter");b.exports=d,f(d.prototype),d.prototype.onError=function(a,b){var c=new Error(a);return c.type="TransportError",c.description=b,this.emit("error",c),this},d.prototype.open=function(){return("closed"==this.readyState||""==this.readyState)&&(this.readyState="opening",this.doOpen()),this},d.prototype.close=function(){return("opening"==this.readyState||"open"==this.readyState)&&(this.doClose(),this.onClose()),this},d.prototype.send=function(a){if("open"!=this.readyState)throw new Error("Transport not open");this.write(a)},d.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},d.prototype.onData=function(a){var b=e.decodePacket(a,this.socket.binaryType);this.onPacket(b)},d.prototype.onPacket=function(a){this.emit("packet",a)},d.prototype.onClose=function(){this.readyState="closed",this.emit("close")}},{"component-emitter":15,"engine.io-parser":19}],5:[function(a,b,c){(function(b){function d(a){var c,d=!1,h=!1,i=!1!==a.jsonp;if(b.location){var j="https:"==location.protocol,k=location.port;k||(k=j?443:80),d=a.hostname!=location.hostname||k!=a.port,h=a.secure!=j}if(a.xdomain=d,a.xscheme=h,c=new e(a),"open"in c&&!a.forceJSONP)return new f(a);if(!i)throw new Error("JSONP disabled");return new g(a)}var e=a("xmlhttprequest-ssl"),f=a("./polling-xhr"),g=a("./polling-jsonp"),h=a("./websocket");c.polling=d,c.websocket=h}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{})},{"./polling-jsonp":6,"./polling-xhr":7,"./websocket":9,"xmlhttprequest-ssl":10}],6:[function(a,b,c){(function(c){function d(){}function e(a){f.call(this,a),this.query=this.query||{},h||(c.___eio||(c.___eio=[]),h=c.___eio),this.index=h.length;var b=this;h.push(function(a){b.onData(a)}),this.query.j=this.index,c.document&&c.addEventListener&&c.addEventListener("beforeunload",function(){b.script&&(b.script.onerror=d)},!1)}var f=a("./polling"),g=a("component-inherit");b.exports=e;var h,i=/\n/g,j=/\\n/g;g(e,f),e.prototype.supportsBinary=!1,e.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null,this.iframe=null),f.prototype.doClose.call(this)},e.prototype.doPoll=function(){var a=this,b=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),b.async=!0,b.src=this.uri(),b.onerror=function(b){a.onError("jsonp poll error",b)};var c=document.getElementsByTagName("script")[0];c?c.parentNode.insertBefore(b,c):(document.head||document.body).appendChild(b),this.script=b;var d="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);d&&setTimeout(function(){var a=document.createElement("iframe");document.body.appendChild(a),document.body.removeChild(a)},100)},e.prototype.doWrite=function(a,b){function c(){d(),b()}function d(){if(e.iframe)try{e.form.removeChild(e.iframe)}catch(a){e.onError("jsonp polling iframe removal error",a)}try{var b='