cordova-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CB-13056) Remove non platform-API platforms
Date Thu, 14 Dec 2017 06:22:51 GMT

    [ https://issues.apache.org/jira/browse/CB-13056?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16290396#comment-16290396 ] 

ASF GitHub Bot commented on CB-13056:
-------------------------------------

stevengill closed pull request #588: CB-13056 : Removed parsers & platformApi polyfill for webos, blackberry, & ubuntu
URL: https://github.com/apache/cordova-lib/pull/588
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/spec/cordova/fixtures/platforms/cordova-browser/README.md b/spec/cordova/fixtures/platforms/cordova-browser/README.md
index 186c2b75d..42be8d044 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/README.md
@@ -19,29 +19,26 @@
 #
 -->
 
-[![Build Status](https://travis-ci.org/apache/cordova-browser.svg)](https://travis-ci.org/apache/cordova-browser)
+[![Build status](https://travis-ci.org/apache/cordova-browser.svg?branch=master )](https://travis-ci.org/apache/cordova-browser.svg?branch=master )
+[![Build Status](https://ci.appveyor.com/api/projects/status/4oan2jjn7nlgfay3/branch/master?svg=true)](https://ci.appveyor.com/api/projects/status/4oan2jjn7nlgfay3/branch/master?svg=true)
 
 # Cordova Browser
 
-Target modern web browsers to build Cordova based applications. 
+Target modern web browsers to build Apache Cordova based applications.
 
 # Goals
 
-- Browser targeted deployment 
+- Browser targeted deployment
 - Surfacing native platform incompatibilities from the open web platform
-- Simplest possible reference implementation for future platform targets
-- Optimizing cordova.js 
-
-# TODO
-
-`bin/create`
-`bin/update`
-`bin/check_reqs`
-`bin/templates/scripts/cordova/build`
-`bin/templates/scripts/cordova/clean`
-`bin/templates/scripts/cordova/log`
-`bin/templates/scripts/cordova/emulate`
-`bin/templates/scripts/cordova/run`
-`bin/templates/scripts/cordova/version`
-`bin/templates/www`
+
+# PWA support
+
+## cordova-browser now includes support for progressive web apps (PWAs)
+
+- if your project supplies a `manifest.json` in the `www/` dir, it will be used
+    - a `manifest.json` will be generated otherwise
+- if your js code registers a service worker, it will also be used
+    - a generic cordova service worker will be installed that simply caches all files in the `www` dir.
+    - cache version is autoincremented for every build
+
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/VERSION b/spec/cordova/fixtures/platforms/cordova-browser/VERSION
index 5fb11aa65..f8ee15fd4 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/VERSION
+++ b/spec/cordova/fixtures/platforms/cordova-browser/VERSION
@@ -1 +1 @@
-4.2.0-dev
+5.1.0-dev
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/create b/spec/cordova/fixtures/platforms/cordova-browser/bin/create
index b0350224f..6d7374551 100755
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/create
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/create
@@ -18,18 +18,76 @@
        specific language governing permissions and limitations
        under the License.
 */
+// var path = require('path');
+// var create = require('./lib/create');
+// var args = process.argv;
+
+// // Support basic help commands
+// if(args.length < 3 || (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+//                     args[2] == 'help' || args[2] == '-help' || args[2] == '/help')) {
+//     console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name>');
+//     console.log('    <path_to_new_project>: Path to your new Cordova Browser project');
+//     console.log('    <package_name>: Package name, following reverse-domain style convention');
+//     console.log('    <project_name>: Project name');
+//     process.exitCode = 1;
+// } else {
+//     create.createProject(args[2], args[3], args[4], args[5]);
+// }
+
+/*
+ * create a Cordova project
+ *
+ * USAGE
+ *   ./create <path_to_new_project> <package_name> <project_name>
+ *
+ * EXAMPLE
+ *  ./create ~/Desktop/radness org.apache.cordova.radness Radness
+ */
+
 var path = require('path');
-var create = require('./lib/create');
-var args = process.argv;
-
-// Support basic help commands
-if(args.length < 3 || (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
-                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help')) {
-    console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name>');
-    console.log('    <path_to_new_project>: Path to your new Cordova Browser project');
-    console.log('    <package_name>: Package name, following reverse-domain style convention');
-    console.log('    <project_name>: Project name');
-    process.exit(1);
-} else {
-    create.createProject(args[2], args[3], args[4], args[5]).done();
+var ConfigParser = require('cordova-common').ConfigParser;
+var Api = require('./template/cordova/Api');
+
+
+var argv = require('nopt')({
+    'help' : Boolean,
+    'cli' : Boolean,
+    'shared' : Boolean, // alias for --link
+    'link' : Boolean
+}, { 'd' : '--verbose' });
+
+
+var projectPath = argv.argv.remain[0];
+
+if (argv.help || !projectPath) {
+    console.log('Usage: $0 [--link] [--cli] <path_to_new_project> <package_name> <project_name> [<project_template_dir>]');
+    console.log('   --link (optional): Link directly against the shared copy of the CordovaLib instead of a copy of it.');
+    console.log('   --cli (optional): Use the CLI-project template.');
+    console.log('   <path_to_new_project>: Path to your new Cordova iOS project');
+    console.log('   <package_name>: Package name, following reverse-domain style convention');
+    console.log('   <project_name>: Project name');
+    console.log('   <project_template_dir>: Path to project template (override).');
+    process.exit(0);
 }
+else {
+    var configPath = path.resolve(__dirname, 'template/config.xml');
+    var config = new ConfigParser(configPath);
+
+    // apply overrides (package and project names
+    if (argv.argv.remain[1]) {
+        config.setPackageName(argv.argv.remain[1]);
+    }
+    if (argv.argv.remain[2]) {
+        config.setName(argv.argv.remain[2]);
+    }
+
+    var options = {
+        cli: argv.cli,
+        link: argv.link || argv.shared,
+        customTemplate: argv.argv.remain[3],
+    };
+
+    Api.createPlatform(projectPath, config, options);
+}
+
+
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/check_reqs.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/check_reqs.js
index 720d7aae4..172aa38b1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/check_reqs.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/check_reqs.js
@@ -19,10 +19,8 @@ specific language governing permissions and limitations
 under the License.
 */
 
-//add methods as we determine what are the requirements
+// add methods as we determine what are the requirements
 
-var Q = require('q');
-
-module.exports.run = function() {
-    return Q.resolve();
+module.exports.run = function () {
+    return Promise.resolve();
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/create.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/create.js
index 2f77cc272..667d9ff06 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/create.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/create.js
@@ -19,63 +19,70 @@
  * under the License.
  */
 
-var fs = require('fs'),
-    shjs = require('shelljs'),
-    Q = require ('q'),
-    args = process.argv,
-    path = require('path'),
-    ROOT    = path.join(__dirname, '..', '..'),
-    check_reqs = require('./check_reqs');
+var fs = require('fs');
+var shell = require('shelljs');
+var path = require('path');
+var ROOT = path.join(__dirname, '..', '..');
+var events = require('cordova-common').events;
+var check_reqs = require('./check_reqs');
 
-module.exports.createProject = function(project_path,package_name,project_name){
+// exported method to create a project, returns a promise that resolves with null
+module.exports.createProject = function (project_path, package_name, project_name) {
+/*
+    // create the dest and the standard place for our api to live
+    // platforms/platformName/cordova/Api.js
+*/
 
-    var VERSION = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8');
+    events.emit('log', 'Creating Cordova project for cordova-browser:');
+    events.emit('log', '\tPath: ' + project_path);
+    events.emit('log', '\tName: ' + project_name);
 
     // Set default values for path, package and name
-    project_path = typeof project_path !== 'undefined' ? project_path : "CordovaExample";
+    project_path = project_path || 'CordovaExample';
 
     // Check if project already exists
     if (fs.existsSync(project_path)) {
-        console.error('Project already exists! Delete and recreate');
-        process.exit(2);
+        events.emit('error', 'Oops, destination already exists! Delete it and try again');
     }
 
     // Check that requirements are met and proper targets are installed
     if (!check_reqs.run()) {
-        console.error('Please make sure you meet the software requirements in order to build a browser cordova project');
-        process.exit(2);
+        // TODO: use events.emit
+        events.emit('error', 'Please make sure you meet the software requirements in order to build a browser cordova project');
     }
 
-    //copy template directory
-    shjs.cp('-r', path.join(ROOT, 'bin', 'templates', 'project', 'www'), project_path);
+    // copy template/cordova directory ( recursive )
+    shell.cp('-r', path.join(ROOT, 'bin/template/cordova'), project_path);
 
-    //create cordova/lib if it does not exist yet
-    if (!fs.existsSync(path.join(project_path,'cordova', 'lib'))) {
-        shjs.mkdir('-p', path.join(project_path,'cordova', 'lib'));
-    }
+    // copy template/www directory ( recursive )
+    shell.cp('-r', path.join(ROOT, 'bin/template/www'), project_path);
+
+    // recreate our node_modules structure in the new project
+    shell.cp('-r', path.join(ROOT, 'node_modules'),
+        path.join(project_path, 'cordova'));
+
+    // copy check_reqs file
+    shell.cp(path.join(ROOT, 'bin/lib/check_reqs.js'),
+        path.join(project_path, 'cordova/lib'));
 
-    //copy required node_modules
-    shjs.cp('-r', path.join(ROOT, 'node_modules'), path.join(project_path,'cordova'));
+    var platform_www = path.join(project_path, 'platform_www');
 
-    //copy check_reqs file
-    shjs.cp( path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(project_path,'cordova', 'lib'));
+    // copy cordova-js-src directory
+    shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), platform_www);
 
-    //copy cordova js file
-    shjs.cp('-r', path.join(ROOT, 'cordova-lib', 'cordova.js'), path.join(project_path,'www'));
+    // copy cordova js file to platform_www
+    shell.cp(path.join(ROOT, 'cordova-lib', 'cordova.js'), platform_www);
 
-    //copy cordova-js-src directory
-    shjs.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(project_path, 'platform_www'));
+    // copy favicon file to platform_www
+    shell.cp(path.join(ROOT, 'bin/template/www/favicon.ico'), platform_www);
 
-    //copy cordova directory
-    shjs.cp('-r', path.join(ROOT, 'bin', 'templates', 'project', 'cordova'), project_path);
-    [
-        'run',
-        'build',
-        'clean',
-        'version',
-    ].forEach(function(f) {
-         shjs.chmod(755, path.join(project_path, 'cordova', f));
-    });
+    // load manifest to write name/shortname
+    var manifest = require(path.join(ROOT, 'bin/template/www', 'manifest.json'));
+    manifest.name = project_name;
+    manifest.short_name = project_name;
+    // copy manifest file to platform_www
+    fs.writeFileSync(path.join(platform_www, 'manifest.json'),
+        JSON.stringify(manifest, null, 2), 'utf-8');
 
-    return Q.resolve();
+    return Promise.resolve();
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/update.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/update.js
index 47b57d74e..62e37e131 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/update.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/lib/update.js
@@ -17,40 +17,39 @@
        under the License.
 */
 
-var Q      = require('q'),
-    create = require('./create'),
-    fs     = require('fs'),
-    shell = require('shelljs');
+var Q = require('q');
+var create = require('./create');
+var fs = require('fs');
+var shell = require('shelljs');
 
 module.exports.help = function () {
-    console.log("WARNING : Make sure to back up your project before updating!");
-    console.log("Usage: update PathToProject ");
-    console.log("    PathToProject : The path the project you would like to update.");
-    console.log("examples:");
-    console.log("    update C:\\Users\\anonymous\\Desktop\\MyProject");
+    console.log('WARNING : Make sure to back up your project before updating!');
+    console.log('Usage: update PathToProject ');
+    console.log('    PathToProject : The path the project you would like to update.');
+    console.log('examples:');
+    console.log('    update C:\\Users\\anonymous\\Desktop\\MyProject');
 };
 
 module.exports.run = function (argv) {
     var projectPath = argv[2];
     if (!fs.existsSync(projectPath)) {
         // if specified project path is not valid then reject promise
-        Q.reject("Browser platform does not exist here: " + projectPath);
+        Q.reject('Browser platform does not exist here: ' + projectPath);
     }
     return Q().then(function () {
-        console.log("Removing existing browser platform.");
+        console.log('Removing existing browser platform.');
         shellfatal(shell.rm, '-rf', projectPath);
         create.createProject(projectPath);
     });
 };
 
-function shellfatal(shellFunc) {
+function shellfatal (shellFunc) {
     var slicedArgs = Array.prototype.slice.call(arguments, 1);
     var returnVal = null;
     try {
         shell.config.fatal = true;
         returnVal = shellFunc.apply(shell, slicedArgs);
-    }   
-    finally {
+    } finally {
         shell.config.fatal = false;
     }
     return returnVal;
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/config.xml b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/config.xml
new file mode 100644
index 000000000..a212661ef
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+<widget xmlns="http://www.w3.org/ns/widgets">
+
+</widget>
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/Api.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/Api.js
new file mode 100644
index 000000000..9752d2476
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/Api.js
@@ -0,0 +1,531 @@
+/**
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+'License'); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+    this file is found by cordova-lib when you attempt to
+    'cordova platform add PATH' where path is this repo.
+*/
+
+var shell = require('shelljs');
+var path = require('path');
+var fs = require('fs');
+
+var cdvcmn = require('cordova-common');
+var CordovaLogger = cdvcmn.CordovaLogger;
+var ConfigParser = cdvcmn.ConfigParser;
+var ActionStack = cdvcmn.ActionStack;
+var selfEvents = cdvcmn.events;
+var xmlHelpers = cdvcmn.xmlHelpers;
+var PlatformJson = cdvcmn.PlatformJson;
+var PlatformMunger = cdvcmn.ConfigChanges.PlatformMunger;
+var PluginInfoProvider = cdvcmn.PluginInfoProvider;
+
+var BrowserParser = require('./browser_parser');
+var PLATFORM_NAME = 'browser';
+
+function setupEvents (externalEventEmitter) {
+    if (externalEventEmitter) {
+        // This will make the platform internal events visible outside
+        selfEvents.forwardEventsTo(externalEventEmitter);
+        return externalEventEmitter;
+    }
+
+    // There is no logger if external emitter is not present,
+    // so attach a console logger
+    CordovaLogger.get().subscribe(selfEvents);
+    return selfEvents;
+}
+
+function Api (platform, platformRootDir, events) {
+
+    this.platform = platform || PLATFORM_NAME;
+
+    // MyApp/platforms/browser
+    this.root = path.resolve(__dirname, '..');
+    this.events = setupEvents(events);
+    this.parser = new BrowserParser(this.root);
+    this._handler = require('./browser_handler');
+
+    this.locations = {
+        platformRootDir: platformRootDir,
+        root: this.root,
+        www: path.join(this.root, 'www'),
+        res: path.join(this.root, 'res'),
+        platformWww: path.join(this.root, 'platform_www'),
+        configXml: path.join(this.root, 'config.xml'),
+        defaultConfigXml: path.join(this.root, 'cordova/defaults.xml'),
+        build: path.join(this.root, 'build'),
+        // NOTE: Due to platformApi spec we need to return relative paths here
+        cordovaJs: 'bin/templates/project/assets/www/cordova.js',
+        cordovaJsSrc: 'cordova-js-src'
+    };
+
+    this._platformJson = PlatformJson.load(this.root, platform);
+    this._pluginInfoProvider = new PluginInfoProvider();
+    this._munger = new PlatformMunger(platform, this.root, this._platformJson, this._pluginInfoProvider);
+}
+
+Api.createPlatform = function (dest, config, options, events) {
+
+    var creator = require('../../lib/create');
+    events = setupEvents(events);
+
+    var name = 'HelloCordova';
+    var id = 'io.cordova.hellocordova';
+    if (config) {
+        name = config.name();
+        id = config.packageName();
+    }
+
+    var result;
+    try {
+        // we create the project using our scripts in this platform
+        result = creator.createProject(dest, id, name, options)
+            .then(function () {
+                // after platform is created we return Api instance based on new Api.js location
+                // Api.js has been copied to the new project
+                // This is required to correctly resolve paths in the future api calls
+                var PlatformApi = require(path.resolve(dest, 'cordova/Api'));
+                return new PlatformApi('browser', dest, events);
+            });
+    } catch (e) {
+        events.emit('error', 'createPlatform is not callable from the browser project API.');
+        throw (e);
+    }
+    return result;
+};
+
+Api.updatePlatform = function (dest, options, events) {
+    // console.log("test-platform:Api:updatePlatform");
+    // todo?: create projectInstance and fulfill promise with it.
+    return Promise.resolve();
+};
+
+Api.prototype.getPlatformInfo = function () {
+    // console.log("browser-platform:Api:getPlatformInfo");
+    // return PlatformInfo object
+    return {
+        'locations': this.locations,
+        'root': this.root,
+        'name': this.platform,
+        'version': { 'version': '1.0.0' }, // um, todo!
+        'projectConfig': this.config
+    };
+};
+
+Api.prototype.prepare = function (cordovaProject, options) {
+
+    // First cleanup current config and merge project's one into own
+    var defaultConfigPath = path.join(this.locations.platformRootDir, 'cordova',
+        'defaults.xml');
+    var ownConfigPath = this.locations.configXml;
+    var sourceCfg = cordovaProject.projectConfig;
+
+    // If defaults.xml is present, overwrite platform config.xml with it.
+    // Otherwise save whatever is there as defaults so it can be
+    // restored or copy project config into platform if none exists.
+    if (fs.existsSync(defaultConfigPath)) {
+        this.events.emit('verbose', 'Generating config.xml from defaults for platform "' + this.platform + '"');
+        shell.cp('-f', defaultConfigPath, ownConfigPath);
+    } else if (fs.existsSync(ownConfigPath)) {
+        this.events.emit('verbose', 'Generating defaults.xml from own config.xml for platform "' + this.platform + '"');
+        shell.cp('-f', ownConfigPath, defaultConfigPath);
+    } else {
+        this.events.emit('verbose', 'case 3"' + this.platform + '"');
+        shell.cp('-f', sourceCfg.path, ownConfigPath);
+    }
+
+    // merge our configs
+    this.config = new ConfigParser(ownConfigPath);
+    xmlHelpers.mergeXml(cordovaProject.projectConfig.doc.getroot(),
+        this.config.doc.getroot(),
+        this.platform, true);
+    this.config.write();
+
+    // Update own www dir with project's www assets and plugins' assets and js-files
+    this.parser.update_www(cordovaProject, options);
+
+    // Copy or Create manifest.json
+    // todo: move this to a manifest helper module
+    // output path
+    var manifestPath = path.join(this.locations.www, 'manifest.json');
+    var srcManifestPath = path.join(cordovaProject.locations.www, 'manifest.json');
+    if (fs.existsSync(srcManifestPath)) {
+        // just blindly copy it to our output/www
+        // todo: validate it? ensure all properties we expect exist?
+        this.events.emit('verbose', 'copying ' + srcManifestPath + ' => ' + manifestPath);
+        shell.cp('-f', srcManifestPath, manifestPath);
+    } else {
+        var manifestJson = {
+            'background_color': '#FFF',
+            'display': 'standalone'
+        };
+        if (this.config) {
+            if (this.config.name()) {
+                manifestJson.name = this.config.name();
+            }
+            if (this.config.shortName()) {
+                manifestJson.short_name = this.config.shortName();
+            }
+            if (this.config.packageName()) {
+                manifestJson.version = this.config.packageName();
+            }
+            if (this.config.description()) {
+                manifestJson.description = this.config.description();
+            }
+            if (this.config.author()) {
+                manifestJson.author = this.config.author();
+            }
+            // icons
+            var icons = this.config.getStaticResources('browser', 'icon');
+            var manifestIcons = icons.map(function (icon) {
+                // given a tag like this :
+                // <icon src="res/ios/icon.png" width="57" height="57" density="mdpi" />
+                /* configParser returns icons that look like this :
+                {   src: 'res/ios/icon.png',
+                    target: undefined,
+                    density: 'mdpi',
+                    platform: null,
+                    width: 57,
+                    height: 57
+                } ******/
+                /* manifest expects them to be like this :
+                {   "src": "images/touch/icon-128x128.png",
+                    "type": "image/png",
+                    "sizes": "128x128"
+                } ******/
+                // ?Is it worth looking at file extentions?
+                return {'src': icon.src,
+                    'type': 'image/png',
+                    'sizes': (icon.width + 'x' + icon.height)};
+            });
+            manifestJson.icons = manifestIcons;
+
+            // orientation
+            // <preference name="Orientation" value="landscape" />
+            var oriPref = this.config.getGlobalPreference('Orientation');
+            if (oriPref) {
+                // if it's a supported value, use it
+                if (['landscape', 'portrait'].indexOf(oriPref) > -1) {
+                    manifestJson.orientation = oriPref;
+                } else { // anything else maps to 'any'
+                    manifestJson.orientation = 'any';
+                }
+            }
+
+            // get start_url
+            var contentNode = this.config.doc.find('content') || {'attrib': {'src': 'index.html'}}; // sensible default
+            manifestJson.start_url = contentNode.attrib.src;
+
+            // now we get some values from start_url page ...
+            var startUrlPath = path.join(cordovaProject.locations.www, manifestJson.start_url);
+            if (fs.existsSync(startUrlPath)) {
+                var contents = fs.readFileSync(startUrlPath, 'utf-8');
+                // matches <meta name="theme-color" content="#FF0044">
+                var themeColorRegex = /<meta(?=[^>]*name="theme-color")\s[^>]*content="([^>]*)"/i;
+                var result = themeColorRegex.exec(contents);
+                var themeColor;
+                if (result && result.length >= 2) {
+                    themeColor = result[1];
+                } else { // see if there is a preference in config.xml
+                    // <preference name="StatusBarBackgroundColor" value="#000000" />
+                    themeColor = this.config.getGlobalPreference('StatusBarBackgroundColor');
+                }
+                if (themeColor) {
+                    manifestJson.theme_color = themeColor;
+                }
+            }
+        }
+        fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 2), 'utf8');
+    }
+
+    // update project according to config.xml changes.
+    return this.parser.update_project(this.config, options);
+};
+
+Api.prototype.addPlugin = function (pluginInfo, installOptions) {
+
+    // console.log(new Error().stack);
+    if (!pluginInfo) {
+        return Promise.reject(new Error('The parameter is incorrect. The first parameter ' +
+            'should be valid PluginInfo instance'));
+    }
+
+    installOptions = installOptions || {};
+    installOptions.variables = installOptions.variables || {};
+    // CB-10108 platformVersion option is required for proper plugin installation
+    installOptions.platformVersion = installOptions.platformVersion ||
+        this.getPlatformInfo().version;
+
+    var self = this;
+    var actions = new ActionStack();
+    var projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);
+
+    // gather all files needs to be handled during install
+    pluginInfo.getFilesAndFrameworks(this.platform)
+        .concat(pluginInfo.getAssets(this.platform))
+        .concat(pluginInfo.getJsModules(this.platform))
+        .forEach(function (item) {
+            actions.push(actions.createAction(
+                self._getInstaller(item.itemType),
+                [item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile],
+                self._getUninstaller(item.itemType),
+                [item, pluginInfo.dir, pluginInfo.id, installOptions, projectFile]));
+        });
+
+    // run through the action stack
+    return actions.process(this.platform, this.root)
+        .then(function () {
+            if (projectFile) {
+                projectFile.write();
+            }
+
+            // Add PACKAGE_NAME variable into vars
+            if (!installOptions.variables.PACKAGE_NAME) {
+                installOptions.variables.PACKAGE_NAME = self._handler.package_name(self.root);
+            }
+
+            self._munger
+                // Ignore passed `is_top_level` option since platform itself doesn't know
+                // anything about managing dependencies - it's responsibility of caller.
+                .add_plugin_changes(pluginInfo, installOptions.variables, /* is_top_level= */true, /* should_increment= */true)
+                .save_all();
+
+            var targetDir = installOptions.usePlatformWww ?
+                self.getPlatformInfo().locations.platformWww :
+                self.getPlatformInfo().locations.www;
+
+            self._addModulesInfo(pluginInfo, targetDir);
+        });
+};
+
+Api.prototype.removePlugin = function (plugin, uninstallOptions) {
+    // console.log("NotImplemented :: browser-platform:Api:removePlugin ",plugin, uninstallOptions);
+
+    uninstallOptions = uninstallOptions || {};
+    // CB-10108 platformVersion option is required for proper plugin installation
+    uninstallOptions.platformVersion = uninstallOptions.platformVersion ||
+        this.getPlatformInfo().version;
+
+    var self = this;
+    var actions = new ActionStack();
+    var projectFile = this._handler.parseProjectFile && this._handler.parseProjectFile(this.root);
+
+    // queue up plugin files
+    plugin.getFilesAndFrameworks(this.platform)
+        .concat(plugin.getAssets(this.platform))
+        .concat(plugin.getJsModules(this.platform))
+        .forEach(function (item) {
+            actions.push(actions.createAction(
+                self._getUninstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile],
+                self._getInstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions, projectFile]));
+        });
+
+    // run through the action stack
+    return actions.process(this.platform, this.root)
+        .then(function () {
+            if (projectFile) {
+                projectFile.write();
+            }
+
+            self._munger
+                // Ignore passed `is_top_level` option since platform itself doesn't know
+                // anything about managing dependencies - it's responsibility of caller.
+                .remove_plugin_changes(plugin, /* is_top_level= */true)
+                .save_all();
+
+            var targetDir = uninstallOptions.usePlatformWww ?
+                self.getPlatformInfo().locations.platformWww :
+                self.getPlatformInfo().locations.www;
+
+            self._removeModulesInfo(plugin, targetDir);
+            // Remove stale plugin directory
+            // TODO: this should be done by plugin files uninstaller
+            shell.rm('-rf', path.resolve(self.root, 'Plugins', plugin.id));
+        });
+};
+
+Api.prototype._getInstaller = function (type) {
+    var self = this;
+    return function (item, plugin_dir, plugin_id, options, project) {
+        var installer = self._handler[type];
+
+        if (!installer) {
+            console.log('unrecognized type ' + type);
+
+        } else {
+            var wwwDest = options.usePlatformWww ?
+                self.getPlatformInfo().locations.platformWww :
+                self._handler.www_dir(self.root);
+
+            if (type === 'asset') {
+                installer.install(item, plugin_dir, wwwDest);
+            } else if (type === 'js-module') {
+                installer.install(item, plugin_dir, plugin_id, wwwDest);
+            } else {
+                installer.install(item, plugin_dir, self.root, plugin_id, options, project);
+            }
+        }
+    };
+};
+
+Api.prototype._getUninstaller = function (type) {
+    var self = this;
+    return function (item, plugin_dir, plugin_id, options, project) {
+        var installer = self._handler[type];
+
+        if (!installer) {
+            console.log('browser plugin uninstall: unrecognized type, skipping : ' + type);
+
+        } else {
+            var wwwDest = options.usePlatformWww ?
+                self.getPlatformInfo().locations.platformWww :
+                self._handler.www_dir(self.root);
+
+            if (['asset', 'js-module'].indexOf(type) > -1) {
+                return installer.uninstall(item, wwwDest, plugin_id);
+            } else {
+                return installer.uninstall(item, self.root, plugin_id, options, project);
+            }
+
+        }
+    };
+};
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ *   platform_json and cordova_plugins.js on disk.
+ *
+ * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
+ *   needs to be added.
+ * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
+ *   should be written to.
+ */
+Api.prototype._addModulesInfo = function (plugin, targetDir) {
+    var installedModules = this._platformJson.root.modules || [];
+
+    var installedPaths = installedModules.map(function (installedModule) {
+        return installedModule.file;
+    });
+
+    var modulesToInstall = plugin.getJsModules(this.platform)
+        .filter(function (moduleToInstall) {
+            return installedPaths.indexOf(moduleToInstall.file) === -1;
+        }).map(function (moduleToInstall) {
+            var moduleName = plugin.id + '.' + (moduleToInstall.name || moduleToInstall.src.match(/([^\/]+)\.js/)[1]);
+            var obj = {
+                file: ['plugins', plugin.id, moduleToInstall.src].join('/'), /* eslint no-useless-escape : 0 */
+                id: moduleName,
+                pluginId: plugin.id
+            };
+            if (moduleToInstall.clobbers.length > 0) {
+                obj.clobbers = moduleToInstall.clobbers.map(function (o) { return o.target; });
+            }
+            if (moduleToInstall.merges.length > 0) {
+                obj.merges = moduleToInstall.merges.map(function (o) { return o.target; });
+            }
+            if (moduleToInstall.runs) {
+                obj.runs = true;
+            }
+
+            return obj;
+        });
+
+    this._platformJson.root.modules = installedModules.concat(modulesToInstall);
+    if (!this._platformJson.root.plugin_metadata) {
+        this._platformJson.root.plugin_metadata = {};
+    }
+    this._platformJson.root.plugin_metadata[plugin.id] = plugin.version;
+
+    this._writePluginModules(targetDir);
+    this._platformJson.save();
+};
+/**
+ * Fetches all installed modules, generates cordova_plugins contents and writes
+ *   it to file.
+ *
+ * @param   {String}  targetDir  Directory, where write cordova_plugins.js to.
+ *   Ususally it is either <platform>/www or <platform>/platform_www
+ *   directories.
+ */
+Api.prototype._writePluginModules = function (targetDir) {
+    // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
+    var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
+    final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, '    ') + ';\n';
+    final_contents += 'module.exports.metadata = \n';
+    final_contents += '// TOP OF METADATA\n';
+    final_contents += JSON.stringify(this._platformJson.root.plugin_metadata || {}, null, '    ') + '\n';
+    final_contents += '// BOTTOM OF METADATA\n';
+    final_contents += '});'; // Close cordova.define.
+
+    shell.mkdir('-p', targetDir);
+    fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8');
+};
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ *   platform_json and cordova_plugins.js on disk.
+ *
+ * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
+ *   needs to be removed.
+ * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
+ *   should be written to.
+ */
+Api.prototype._removeModulesInfo = function (plugin, targetDir) {
+    var installedModules = this._platformJson.root.modules || [];
+    var modulesToRemove = plugin.getJsModules(this.platform)
+        .map(function (jsModule) {
+            return ['plugins', plugin.id, jsModule.src].join('/');
+        });
+
+    var updatedModules = installedModules
+        .filter(function (installedModule) {
+            return (modulesToRemove.indexOf(installedModule.file) === -1);
+        });
+
+    this._platformJson.root.modules = updatedModules;
+    if (this._platformJson.root.plugin_metadata) {
+        delete this._platformJson.root.plugin_metadata[plugin.id];
+    }
+
+    this._writePluginModules(targetDir);
+    this._platformJson.save();
+};
+
+Api.prototype.build = function (buildOptions) {
+    var self = this;
+    return require('./lib/check_reqs').run()
+        .then(function () {
+            return require('./lib/build').run.call(self, buildOptions);
+        });
+};
+
+Api.prototype.run = function (runOptions) {
+    return require('./lib/run').run(runOptions);
+};
+
+Api.prototype.clean = function (cleanOptions) {
+    return require('./lib/clean').run(cleanOptions);
+};
+
+Api.prototype.requirements = function () {
+    return require('./lib/check_reqs').run();
+};
+
+module.exports = Api;
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_handler.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_handler.js
new file mode 100644
index 000000000..3e12c25d1
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_handler.js
@@ -0,0 +1,131 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var path = require('path');
+var fs = require('fs');
+var shell = require('shelljs');
+var events = require('cordova-common').events;
+
+module.exports = {
+    www_dir: function (project_dir) {
+        return path.join(project_dir, 'www');
+    },
+    package_name: function (project_dir) {
+        // this method should the id from root config.xml => <widget id=xxx
+        // return common.package_name(project_dir, this.www_dir(project_dir));
+        // console.log('package_name called with ' + project_dir);
+        var pkgName = 'io.cordova.hellocordova';
+        var widget_id_regex = /(?:<widget\s+id=['"])(\S+)(?:['"])/;
+
+        var configPath = path.join(project_dir, 'config.xml');
+        if (fs.existsSync(configPath)) {
+            var configStr = fs.readFileSync(configPath, 'utf8');
+            var res = configStr.match(widget_id_regex);
+            if (res && res.length > 1) {
+                pkgName = res[1];
+            }
+        }
+        return pkgName;
+    },
+    'js-module': {
+        install: function (jsModule, plugin_dir, plugin_id, www_dir) {
+            // Copy the plugin's files into the www directory.
+            var moduleSource = path.resolve(plugin_dir, jsModule.src);
+            // Get module name based on existing 'name' attribute or filename
+            // Must use path.extname/path.basename instead of path.parse due to CB-9981
+            var moduleName = plugin_id + '.' + (jsModule.name || path.basename(jsModule.src, path.extname(jsModule.src)));
+
+            // Read in the file, prepend the cordova.define, and write it back out.
+            var scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
+            if (moduleSource.match(/.*\.json$/)) {
+                scriptContent = 'module.exports = ' + scriptContent;
+            }
+            scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) { ' + scriptContent + '\n});\n';
+
+            var moduleDestination = path.resolve(www_dir, 'plugins', plugin_id, jsModule.src);
+            shell.mkdir('-p', path.dirname(moduleDestination));
+            fs.writeFileSync(moduleDestination, scriptContent, 'utf-8');
+        },
+        uninstall: function (jsModule, www_dir, plugin_id) {
+            var pluginRelativePath = path.join('plugins', plugin_id, jsModule.src);
+            // common.removeFileAndParents(www_dir, pluginRelativePath);
+            console.log('js-module uninstall called : ' + pluginRelativePath);
+        }
+    },
+    'source-file': {
+        install: function (obj, plugin_dir, project_dir, plugin_id, options) {
+            // var dest = path.join(obj.targetDir, path.basename(obj.src));
+            // common.copyFile(plugin_dir, obj.src, project_dir, dest);
+            console.log('install called');
+        },
+        uninstall: function (obj, project_dir, plugin_id, options) {
+            // var dest = path.join(obj.targetDir, path.basename(obj.src));
+            // common.removeFile(project_dir, dest);
+            console.log('uninstall called');
+        }
+    },
+    'header-file': {
+        install: function (obj, plugin_dir, project_dir, plugin_id, options) {
+            events.emit('verbose', 'header-fileinstall is not supported for browser');
+        },
+        uninstall: function (obj, project_dir, plugin_id, options) {
+            events.emit('verbose', 'header-file.uninstall is not supported for browser');
+        }
+    },
+    'resource-file': {
+        install: function (obj, plugin_dir, project_dir, plugin_id, options) {
+            events.emit('verbose', 'resource-file.install is not supported for browser');
+        },
+        uninstall: function (obj, project_dir, plugin_id, options) {
+            events.emit('verbose', 'resource-file.uninstall is not supported for browser');
+        }
+    },
+    'framework': {
+        install: function (obj, plugin_dir, project_dir, plugin_id, options) {
+            events.emit('verbose', 'framework.install is not supported for browser');
+        },
+        uninstall: function (obj, project_dir, plugin_id, options) {
+            events.emit('verbose', 'framework.uninstall is not supported for browser');
+        }
+    },
+    'lib-file': {
+        install: function (obj, plugin_dir, project_dir, plugin_id, options) {
+            events.emit('verbose', 'lib-file.install is not supported for browser');
+        },
+        uninstall: function (obj, project_dir, plugin_id, options) {
+            events.emit('verbose', 'lib-file.uninstall is not supported for browser');
+        }
+    },
+    asset: {
+        install: function (asset, plugin_dir, wwwDest) {
+            var src = path.join(plugin_dir, asset.src);
+            var dest = path.join(wwwDest, asset.target);
+
+            if (fs.statSync(src).isDirectory()) {
+                shell.cp('-Rf', src + '/*', dest);
+            } else {
+                shell.cp('-f', src, dest);
+            }
+        },
+        uninstall: function (asset, wwwDest, plugin_id) {
+            shell.rm('-rf', path.join(wwwDest, asset.target));
+            shell.rm('-rf', path.join(wwwDest, 'plugins', plugin_id));
+        }
+    }
+};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_parser.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_parser.js
new file mode 100644
index 000000000..99397c3a5
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/browser_parser.js
@@ -0,0 +1,120 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var fs = require('fs');
+var path = require('path');
+var shell = require('shelljs');
+var CordovaError = require('cordova-common').CordovaError;
+var events = require('cordova-common').events;
+var FileUpdater = require('cordova-common').FileUpdater;
+
+function dirExists (dir) {
+    return fs.existsSync(dir) && fs.statSync(dir).isDirectory();
+}
+
+function browser_parser (project) {
+    if (!dirExists(project) || !dirExists(path.join(project, 'cordova'))) {
+        throw new CordovaError('The provided path "' + project + '" is not a valid browser project.');
+    }
+    this.path = project;
+}
+
+module.exports = browser_parser;
+
+// Returns a promise.
+browser_parser.prototype.update_from_config = function () {
+    return Promise.resolve();
+};
+
+browser_parser.prototype.www_dir = function () {
+    return path.join(this.path, 'www');
+};
+
+// Used for creating platform_www in projects created by older versions.
+browser_parser.prototype.cordovajs_path = function (libDir) {
+    var jsPath = path.join(libDir, 'cordova-lib', 'cordova.js');
+    return path.resolve(jsPath);
+};
+
+browser_parser.prototype.cordovajs_src_path = function (libDir) {
+    // console.log("cordovajs_src_path");
+    var jsPath = path.join(libDir, 'cordova-js-src');
+    return path.resolve(jsPath);
+};
+
+/**
+ * Logs all file operations via the verbose event stream, indented.
+ */
+function logFileOp (message) {
+    events.emit('verbose', '  ' + message);
+}
+
+// Replace the www dir with contents of platform_www and app www.
+browser_parser.prototype.update_www = function (cordovaProject, opts) {
+    var platform_www = path.join(this.path, 'platform_www');
+    var my_www = this.www_dir();
+    // add cordova www and platform_www to sourceDirs
+    var sourceDirs = [
+        path.relative(cordovaProject.root, cordovaProject.locations.www),
+        path.relative(cordovaProject.root, platform_www)
+    ];
+
+    // If project contains 'merges' for our platform, use them as another overrides
+    var merges_path = path.join(cordovaProject.root, 'merges', 'browser');
+    if (fs.existsSync(merges_path)) {
+        events.emit('verbose', 'Found "merges/browser" folder. Copying its contents into the browser project.');
+        // add merges/browser to sourceDirs
+        sourceDirs.push(path.join('merges', 'browser'));
+    }
+
+    // targetDir points to browser/www
+    var targetDir = path.relative(cordovaProject.root, my_www);
+    events.emit('verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir);
+    FileUpdater.mergeAndUpdateDir(sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
+};
+
+browser_parser.prototype.update_overrides = function () {
+    // console.log("update_overrides");
+
+    // TODO: ?
+    // var projectRoot = util.isCordova(this.path);
+    // var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'browser');
+    // if(fs.existsSync(mergesPath)) {
+    //     var overrides = path.join(mergesPath, '*');
+    //     shell.cp('-rf', overrides, this.www_dir());
+    // }
+};
+
+browser_parser.prototype.config_xml = function () {
+    return path.join(this.path, 'config.xml');
+};
+
+// Returns a promise.
+browser_parser.prototype.update_project = function (cfg) {
+    // console.log("update_project ",cfg);
+    var defer = this.update_from_config();
+    var self = this;
+    var www_dir = self.www_dir();
+    defer.then(function () {
+        self.update_overrides();
+        // Copy munged config.xml to platform www dir
+        shell.cp('-rf', path.join(www_dir, '..', 'config.xml'), www_dir);
+    });
+    return defer;
+};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/build b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/build
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/build
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/build
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/build.bat b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/build.bat
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/build.bat
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/build.bat
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/clean b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean
similarity index 95%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/clean
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean
index da21bc7ca..1852d66c1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/clean
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean
@@ -22,7 +22,6 @@
 
 var path = require('path'),
     clean = require('./lib/clean'),
-    reqs  = require('./lib/check_reqs'),
     args  = process.argv;
 
 // Support basic help commands
@@ -32,6 +31,6 @@ if ( args.length > 2
     console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'clean')) );
     process.exit(0);
 } else {
-    clean.cleanProject();
+    clean.run();
 }
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean.bat b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean.bat
new file mode 100644
index 000000000..5c572aaf1
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/clean.bat
@@ -0,0 +1,26 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+::
+:: http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License.
+
+@ECHO OFF
+SET script_path="%~dp0clean"
+IF EXIST %script_path% (
+        node %script_path% %*
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'clean' script in 'cordova' folder, aborting...>&2
+    EXIT /B 1
+)
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/defaults.xml b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/defaults.xml
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/defaults.xml
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/defaults.xml
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/build.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/build.js
new file mode 100644
index 000000000..01f3fb14a
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/build.js
@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var path = require('path');
+var check_reqs = require('./check_reqs');
+
+/**
+ * run
+ *   Creates a zip file int platform/build folder
+ */
+module.exports.run = function () {
+    return check_reqs.run();
+};
+
+module.exports.help = function () {
+    console.log('Usage: cordova build browser');
+    var wwwPath = path.resolve(path.join(__dirname, '../../www'));
+    console.log("Build will create the packaged app in '" + wwwPath + "'.");
+};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/clean.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/clean.js
similarity index 58%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/clean.js
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/clean.js
index 2e4367d28..6ee76751a 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/clean.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/clean.js
@@ -18,29 +18,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
- 
-var fs = require('fs'),
-    shjs = require('shelljs'),
-    path = require('path'),
-    check_reqs = require('./check_reqs'),
-    platformBuildDir = path.join('platforms', 'browser', 'build');
 
-exports.cleanProject = function(){
+var fs = require('fs');
+var shell = require('shelljs');
+var path = require('path');
+var check_reqs = require('./check_reqs');
+var platformBuildDir = path.join('platforms', 'browser', 'www');
 
-    // Check that requirements are (stil) met
+var run = function () {
+
+    // TODO: everything calls check_reqs ... why?
+    // Check that requirements are (still) met
     if (!check_reqs.run()) {
         console.error('Please make sure you meet the software requirements in order to clean an browser cordova project');
         process.exit(2);
     }
-    
-    console.log('Cleaning Browser project');
+
     try {
         if (fs.existsSync(platformBuildDir)) {
-            shjs.rm('-r', platformBuildDir);
+            shell.rm('-r', platformBuildDir);
         }
-    }
-    catch(err) {
-        console.log('could not remove '+platformBuildDir+' : '+err.message);
+    } catch (err) {
+        console.log('could not remove ' + platformBuildDir + ' : ' + err.message);
     }
 };
 
+module.exports.run = run;
+// just on the off chance something is still calling cleanProject, we will leave this here for a while
+module.exports.cleanProject = function () {
+    console.log('lib/clean will soon only export a `run` command, please update to not call `cleanProject`.');
+    return run();
+};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/run.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/run.js
new file mode 100644
index 000000000..fc586305b
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/lib/run.js
@@ -0,0 +1,65 @@
+#!/usr/bin/env node
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var fs = require('fs');
+var path = require('path');
+var url = require('url');
+var cordovaServe = require('cordova-serve');
+
+module.exports.run = function (args) {
+    // defaults
+    args.port = args.port || 8000;
+    args.target = args.target || 'default'; // make default the system browser
+
+    var wwwPath = path.join(__dirname, '../../www');
+    var manifestFilePath = path.resolve(path.join(wwwPath, 'manifest.json'));
+
+    var startPage;
+
+    // get start page from manifest
+    if (fs.existsSync(manifestFilePath)) {
+        try {
+            var manifest = require(manifestFilePath);
+            startPage = manifest.start_url;
+        } catch (err) {
+            console.log('failed to require manifest ... ' + err);
+        }
+    }
+
+    var server = cordovaServe();
+    server.servePlatform('browser', {port: args.port, noServerInfo: true})
+        .then(function () {
+            if (!startPage) {
+                // failing all else, set the default
+                startPage = 'index.html';
+            }
+            var projectUrl = url.resolve('http://localhost:' + server.port + '/', startPage);
+            console.log('startPage = ' + startPage);
+            console.log('Static file server running @ ' + projectUrl + '\nCTRL + C to shut down');
+            return server.launchBrowser({'target': args.target, 'url': projectUrl});
+        })
+        .catch(function (error) {
+            console.log(error.message || error.toString());
+            if (server.server) {
+                server.server.close();
+            }
+        });
+};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/log b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/log
new file mode 100755
index 000000000..bb6fb8cde
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/log
@@ -0,0 +1,20 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+console.log("cordova/log");
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/run b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/run
similarity index 65%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/run
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/run
index d4c690b17..b41e2994c 100755
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/run
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/run
@@ -10,7 +10,7 @@
        with the License.  You may obtain a copy of the License at
 
          http://www.apache.org/licenses/LICENSE-2.0
-    
+
        Unless required by applicable law or agreed to in writing,
        software distributed under the License is distributed on an
        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -23,6 +23,7 @@ var fs = require('fs'),
     path = require('path'),
     nopt  = require('nopt'),
     url = require('url'),
+    runForrest = require('./lib/run'),
     cordovaServe = require('cordova-serve');
 
 var args = process.argv;
@@ -34,27 +35,9 @@ function start(argv) {
     if(args.help) {
         help();
     }
-
-    // defaults
-    args.port = args.port || 8000;
-    args.target = args.target || "chrome";
-
-    var root = path.join(__dirname, '../'),
-        configFile = path.resolve(path.join(root, 'config.xml')),
-        configXML = fs.readFileSync(configFile, 'utf8'),
-        sourceFile = /<content[\s]+?src\s*=\s*"(.*?)"/i.exec(configXML);
-
-    var server = cordovaServe();
-    server.servePlatform('browser', {port: args.port, noServerInfo: true}).then(function () {
-        var projectUrl = url.resolve('http://localhost:' + server.port + '/', sourceFile ? sourceFile[1] : 'index.html');
-        console.log('Static file server running @ ' + projectUrl + '\nCTRL + C to shut down');
-        return cordovaServe.launchBrowser({target: args.target, url: projectUrl});
-    }).catch(function (error) {
-        console.log(error.message || error.toString());
-        if (server.server) {
-            server.server.close();
-        }
-    });
+    else {
+        return runForrest.run(args);
+    }
 }
 
 function help() {
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/run.bat b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/run.bat
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/run.bat
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/run.bat
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/version b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/version
similarity index 97%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/version
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/version
index 8acf18f92..bde86e631 100755
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/version
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/version
@@ -20,6 +20,6 @@
 */
 
 // Coho updates this line:
-var VERSION = "4.2.0-dev";
+var VERSION = "5.1.0-dev";
 
 console.log(VERSION);
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/version.bat b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/version.bat
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/version.bat
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/cordova/version.bat
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/css/index.css b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/css/index.css
similarity index 100%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/css/index.css
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/css/index.css
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/favicon.ico b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/favicon.ico
new file mode 100644
index 000000000..fa7a75876
Binary files /dev/null and b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/favicon.ico differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/logo.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/logo.png
new file mode 100644
index 000000000..44532795f
Binary files /dev/null and b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/logo.png differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/splash.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/splash.png
new file mode 100644
index 000000000..38acd8f8e
Binary files /dev/null and b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/img/splash.png differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/index.html b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/index.html
similarity index 92%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/index.html
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/index.html
index bde5741f4..42eb422f8 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/index.html
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/index.html
@@ -21,9 +21,10 @@
     <head>
         <meta charset="utf-8" />
         <meta name="format-detection" content="telephone=no" />
-        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="theme-color" content="#2196F3"/>
         <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
         <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <link rel="manifest" href="manifest.json">
         <title>Hello World</title>
     </head>
     <body>
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/js/index.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/js/index.js
similarity index 93%
rename from spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/js/index.js
rename to spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/js/index.js
index 31d9064eb..1750a54f6 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/js/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/js/index.js
@@ -18,25 +18,25 @@
  */
 var app = {
     // Application Constructor
-    initialize: function() {
+    initialize: function () {
         this.bindEvents();
     },
     // Bind Event Listeners
     //
     // Bind any events that are required on startup. Common events are:
     // 'load', 'deviceready', 'offline', and 'online'.
-    bindEvents: function() {
+    bindEvents: function () {
         document.addEventListener('deviceready', this.onDeviceReady, false);
     },
     // deviceready Event Handler
     //
     // The scope of 'this' is the event. In order to call the 'receivedEvent'
     // function, we must explicity call 'app.receivedEvent(...);'
-    onDeviceReady: function() {
+    onDeviceReady: function () {
         app.receivedEvent('deviceready');
     },
     // Update DOM on a Received Event
-    receivedEvent: function(id) {
+    receivedEvent: function (id) {
         var parentElement = document.getElementById(id);
         var listeningElement = parentElement.querySelector('.listening');
         var receivedElement = parentElement.querySelector('.received');
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/manifest.json b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/manifest.json
new file mode 100644
index 000000000..b7e398118
--- /dev/null
+++ b/spec/cordova/fixtures/platforms/cordova-browser/bin/template/www/manifest.json
@@ -0,0 +1,21 @@
+{
+  "name": "My App",
+  "short_name":"My Ap",
+  "description": "Description of your app from template",
+  "start_url": "index.html",
+  "scope":"index.html",
+  "icons": [{
+    "src": "img/logo.png",
+    "sizes": "192x192",
+    "type": "image/png"
+  }, {
+    "src": "img/splash.png",
+    "sizes": "512x512",
+    "type": "image/png"
+  }],
+  "default_locale": "en",
+  "display": "standalone",
+  "background_color":"#FFF",
+  "theme_color":"#000",
+  "orientation": "landscape"
+}
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/build.js b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/build.js
deleted file mode 100644
index fde751962..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/cordova/lib/build.js
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env node
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-var path    = require('path'),
-    fs      = require('fs'),
-    shjs    = require('shelljs'),
-    zip     = require('adm-zip'),
-    Q       = require('q'),
-    clean   = require('./clean'),
-    check_reqs = require('./check_reqs'),
-    platformWwwDir          = path.join('platforms', 'browser', 'www'),
-    platformBuildDir        = path.join('platforms', 'browser', 'build'),
-    packageFile             = path.join(platformBuildDir, 'package.zip');
-
-/**
- * run
- *   Creates a zip file int platform/build folder
- */
-module.exports.run = function(){
-
-    return check_reqs.run()
-    .then(function(){
-            return clean.cleanProject();
-        },
-        function checkReqsError(err){
-            console.error('Please make sure you meet the software requirements in order to build a browser cordova project');
-    })
-    .then(function(){
-
-        if (!fs.existsSync(platformBuildDir)) {
-            fs.mkdirSync(platformBuildDir);
-        }
-
-        // add the project to a zipfile
-        var zipFile = zip();
-        zipFile.addLocalFolder(platformWwwDir, '.');
-        zipFile.writeZip(packageFile);
-
-        return Q.resolve();
-
-    });
-};
-
-module.exports.help = function() {
-    console.log('Usage: cordova build browser');
-    console.log('Build will create the packaged app in \''+platformBuildDir+'\'.');
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/img/logo.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/img/logo.png
deleted file mode 100644
index 9519e7dd7..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/img/logo.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/manifest.webapp b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/manifest.webapp
deleted file mode 100644
index f24deb85e..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/manifest.webapp
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "name": "My App",
-  "description": "Description of your app",
-  "launch_path": "/index.html",
-  "icons": {
-    "128": "/img/logo.png"
-  },
-  "default_locale": "en",
-  "type": "privileged"
-}
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-36-ldpi.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-36-ldpi.png
deleted file mode 100644
index cd5032a4f..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-36-ldpi.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-48-mdpi.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-48-mdpi.png
deleted file mode 100644
index e79c6062c..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-48-mdpi.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-72-hdpi.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-72-hdpi.png
deleted file mode 100644
index 4d2763448..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-72-hdpi.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-96-xhdpi.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-96-xhdpi.png
deleted file mode 100644
index ec7ffbfbd..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/android/icon-96-xhdpi.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-48-type5.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-48-type5.png
deleted file mode 100644
index 8ad8bac07..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-48-type5.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-50-type3.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-50-type3.png
deleted file mode 100644
index c6ddf84d4..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-50-type3.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-80-type4.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-80-type4.png
deleted file mode 100644
index f86a27a98..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada-wac/icon-80-type4.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada/icon-128.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada/icon-128.png
deleted file mode 100644
index 3516df327..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/bada/icon-128.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry/icon-80.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry/icon-80.png
deleted file mode 100644
index f86a27a98..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry/icon-80.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry10/icon-80.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry10/icon-80.png
deleted file mode 100644
index f86a27a98..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/blackberry10/icon-80.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57-2x.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57-2x.png
deleted file mode 100644
index efd9c374f..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57-2x.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57.png
deleted file mode 100644
index c795fc4e8..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-57.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72-2x.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72-2x.png
deleted file mode 100644
index dd819da61..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72-2x.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72.png
deleted file mode 100644
index b1cfde7d2..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/ios/icon-72.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/tizen/icon-128.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/tizen/icon-128.png
deleted file mode 100644
index 3516df327..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/tizen/icon-128.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/webos/icon-64.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/webos/icon-64.png
deleted file mode 100644
index 03b38495e..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/webos/icon-64.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-173-tile.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-173-tile.png
deleted file mode 100644
index 4f15e2025..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-173-tile.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-48.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-48.png
deleted file mode 100644
index 8ad8bac07..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-48.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-62-tile.png b/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-62-tile.png
deleted file mode 100644
index aab606138..000000000
Binary files a/spec/cordova/fixtures/platforms/cordova-browser/bin/templates/project/www/res/icon/windows-phone/icon-62-tile.png and /dev/null differ
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/confighelper.js b/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/confighelper.js
index b6d606e27..4d999593e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/confighelper.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/confighelper.js
@@ -61,14 +61,9 @@ function readConfig(success, error) {
         }
     };
 
-    if ("ActiveXObject" in window) {
-        // Needed for XHR-ing via file:// protocol in IE
-        xhr = new window.ActiveXObject("MSXML2.XMLHTTP");
-        xhr.onreadystatechange = xhrStatusChangeHandler;
-    } else {
-        xhr = new XMLHttpRequest();
-        xhr.addEventListener("load", xhrStatusChangeHandler);
-    }
+    xhr = new XMLHttpRequest();
+    xhr.addEventListener("load", xhrStatusChangeHandler);
+
 
     try {
         xhr.open("get", "/config.xml", true);
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/platform.js b/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/platform.js
index 051405945..96eb943a4 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/platform.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/cordova-js-src/platform.js
@@ -21,7 +21,7 @@
 
 module.exports = {
     id: 'browser',
-    cordovaVersion: '3.4.0',
+    cordovaVersion: '4.2.0', // cordova-js
 
     bootstrap: function() {
 
@@ -32,16 +32,14 @@ module.exports = {
 
         channel.onNativeReady.fire();
 
-        // FIXME is this the right place to clobber pause/resume? I am guessing not
-        // FIXME pause/resume should be deprecated IN CORDOVA for pagevisiblity api
-        document.addEventListener('webkitvisibilitychange', function() {
-            if (document.webkitHidden) {
+        document.addEventListener("visibilitychange", function(){
+            if(document.hidden) {
                 channel.onPause.fire();
             }
             else {
                 channel.onResume.fire();
             }
-        }, false);
+        });
 
     // End of bootstrap
     }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/cordova-lib/cordova.js b/spec/cordova/fixtures/platforms/cordova-browser/cordova-lib/cordova.js
index d2edd37ff..798dc6cca 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/cordova-lib/cordova.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/cordova-lib/cordova.js
@@ -1,5 +1,5 @@
 // Platform: browser
-// c517ca811b4948b630e0b74dbae6c9637939da24
+// ff66178b108b93be36a1aafe341af17381a727a3
 /*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
@@ -19,35 +19,33 @@
  under the License.
 */
 ;(function() {
-var PLATFORM_VERSION_BUILD_LABEL = '4.2.0-dev';
+var PLATFORM_VERSION_BUILD_LABEL = '5.1.0-dev';
 // file: src/scripts/require.js
 
-/*jshint -W079 */
-/*jshint -W020 */
+/* jshint -W079 */
+/* jshint -W020 */
 
-var require,
-    define;
+var require;
+var define;
 
 (function () {
-    var modules = {},
+    var modules = {};
     // Stack of moduleIds currently being built.
-        requireStack = [],
+    var requireStack = [];
     // Map of module ID -> index into requireStack of modules currently being built.
-        inProgressModules = {},
-        SEPARATOR = ".";
-
-
-
-    function build(module) {
-        var factory = module.factory,
-            localRequire = function (id) {
-                var resultantId = id;
-                //Its a relative path, so lop off the last portion and add the id (minus "./")
-                if (id.charAt(0) === ".") {
-                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
-                }
-                return require(resultantId);
-            };
+    var inProgressModules = {};
+    var SEPARATOR = '.';
+
+    function build (module) {
+        var factory = module.factory;
+        var localRequire = function (id) {
+            var resultantId = id;
+            // Its a relative path, so lop off the last portion and add the id (minus "./")
+            if (id.charAt(0) === '.') {
+                resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
+            }
+            return require(resultantId);
+        };
         module.exports = {};
         delete module.factory;
         factory(localRequire, module.exports, module);
@@ -56,10 +54,10 @@ var require,
 
     require = function (id) {
         if (!modules[id]) {
-            throw "module " + id + " not found";
+            throw 'module ' + id + ' not found';
         } else if (id in inProgressModules) {
             var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
-            throw "Cycle in require graph: " + cycle;
+            throw 'Cycle in require graph: ' + cycle;
         }
         if (modules[id].factory) {
             try {
@@ -76,7 +74,7 @@ var require,
 
     define = function (id, factory) {
         if (modules[id]) {
-            throw "module " + id + " already defined";
+            throw 'module ' + id + ' already defined';
         }
 
         modules[id] = {
@@ -92,8 +90,8 @@ var require,
     define.moduleMap = modules;
 })();
 
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
+// Export for use in node
+if (typeof module === 'object' && typeof require === 'function') {
     module.exports.require = require;
     module.exports.define = define;
 }
@@ -103,15 +101,13 @@ define("cordova", function(require, exports, module) {
 
 // Workaround for Windows 10 in hosted environment case
 // http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
-if (window.cordova && !(window.cordova instanceof HTMLElement)) {
-    throw new Error("cordova already defined");
+if (window.cordova && !(window.cordova instanceof HTMLElement)) { // eslint-disable-line no-undef
+    throw new Error('cordova already defined');
 }
 
-
 var channel = require('cordova/channel');
 var platform = require('cordova/platform');
 
-
 /**
  * Intercept calls to addEventListener + removeEventListener and handle deviceready,
  * resume, and pause events.
@@ -124,48 +120,48 @@ var m_window_removeEventListener = window.removeEventListener;
 /**
  * Houses custom event handlers to intercept on document + window event listeners.
  */
-var documentEventHandlers = {},
-    windowEventHandlers = {};
+var documentEventHandlers = {};
+var windowEventHandlers = {};
 
-document.addEventListener = function(evt, handler, capture) {
+document.addEventListener = function (evt, handler, capture) {
     var e = evt.toLowerCase();
-    if (typeof documentEventHandlers[e] != 'undefined') {
+    if (typeof documentEventHandlers[e] !== 'undefined') {
         documentEventHandlers[e].subscribe(handler);
     } else {
         m_document_addEventListener.call(document, evt, handler, capture);
     }
 };
 
-window.addEventListener = function(evt, handler, capture) {
+window.addEventListener = function (evt, handler, capture) {
     var e = evt.toLowerCase();
-    if (typeof windowEventHandlers[e] != 'undefined') {
+    if (typeof windowEventHandlers[e] !== 'undefined') {
         windowEventHandlers[e].subscribe(handler);
     } else {
         m_window_addEventListener.call(window, evt, handler, capture);
     }
 };
 
-document.removeEventListener = function(evt, handler, capture) {
+document.removeEventListener = function (evt, handler, capture) {
     var e = evt.toLowerCase();
     // If unsubscribing from an event that is handled by a plugin
-    if (typeof documentEventHandlers[e] != "undefined") {
+    if (typeof documentEventHandlers[e] !== 'undefined') {
         documentEventHandlers[e].unsubscribe(handler);
     } else {
         m_document_removeEventListener.call(document, evt, handler, capture);
     }
 };
 
-window.removeEventListener = function(evt, handler, capture) {
+window.removeEventListener = function (evt, handler, capture) {
     var e = evt.toLowerCase();
     // If unsubscribing from an event that is handled by a plugin
-    if (typeof windowEventHandlers[e] != "undefined") {
+    if (typeof windowEventHandlers[e] !== 'undefined') {
         windowEventHandlers[e].unsubscribe(handler);
     } else {
         m_window_removeEventListener.call(window, evt, handler, capture);
     }
 };
 
-function createEvent(type, data) {
+function createEvent (type, data) {
     var event = document.createEvent('Events');
     event.initEvent(type, false, false);
     if (data) {
@@ -178,29 +174,32 @@ function createEvent(type, data) {
     return event;
 }
 
-
+/* eslint-disable no-undef */
 var cordova = {
-    define:define,
-    require:require,
-    version:PLATFORM_VERSION_BUILD_LABEL,
-    platformVersion:PLATFORM_VERSION_BUILD_LABEL,
-    platformId:platform.id,
+    define: define,
+    require: require,
+    version: PLATFORM_VERSION_BUILD_LABEL,
+    platformVersion: PLATFORM_VERSION_BUILD_LABEL,
+    platformId: platform.id,
+
+    /* eslint-enable no-undef */
+
     /**
      * Methods to add/remove your own addEventListener hijacking on document + window.
      */
-    addWindowEventHandler:function(event) {
+    addWindowEventHandler: function (event) {
         return (windowEventHandlers[event] = channel.create(event));
     },
-    addStickyDocumentEventHandler:function(event) {
+    addStickyDocumentEventHandler: function (event) {
         return (documentEventHandlers[event] = channel.createSticky(event));
     },
-    addDocumentEventHandler:function(event) {
+    addDocumentEventHandler: function (event) {
         return (documentEventHandlers[event] = channel.create(event));
     },
-    removeWindowEventHandler:function(event) {
+    removeWindowEventHandler: function (event) {
         delete windowEventHandlers[event];
     },
-    removeDocumentEventHandler:function(event) {
+    removeDocumentEventHandler: function (event) {
         delete documentEventHandlers[event];
     },
     /**
@@ -208,24 +207,23 @@ var cordova = {
      *
      * @return object
      */
-    getOriginalHandlers: function() {
+    getOriginalHandlers: function () {
         return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
-        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+            'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
     },
     /**
      * Method to fire event from native code
      * bNoDetach is required for events which cause an exception which needs to be caught in native code
      */
-    fireDocumentEvent: function(type, data, bNoDetach) {
+    fireDocumentEvent: function (type, data, bNoDetach) {
         var evt = createEvent(type, data);
-        if (typeof documentEventHandlers[type] != 'undefined') {
-            if( bNoDetach ) {
+        if (typeof documentEventHandlers[type] !== 'undefined') {
+            if (bNoDetach) {
                 documentEventHandlers[type].fire(evt);
-            }
-            else {
-                setTimeout(function() {
+            } else {
+                setTimeout(function () {
                     // Fire deviceready on listeners that were registered before cordova.js was loaded.
-                    if (type == 'deviceready') {
+                    if (type === 'deviceready') {
                         document.dispatchEvent(evt);
                     }
                     documentEventHandlers[type].fire(evt);
@@ -235,10 +233,10 @@ var cordova = {
             document.dispatchEvent(evt);
         }
     },
-    fireWindowEvent: function(type, data) {
-        var evt = createEvent(type,data);
-        if (typeof windowEventHandlers[type] != 'undefined') {
-            setTimeout(function() {
+    fireWindowEvent: function (type, data) {
+        var evt = createEvent(type, data);
+        if (typeof windowEventHandlers[type] !== 'undefined') {
+            setTimeout(function () {
                 windowEventHandlers[type].fire(evt);
             }, 0);
         } else {
@@ -252,7 +250,7 @@ var cordova = {
     // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
     // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
     callbackId: Math.floor(Math.random() * 2000000000),
-    callbacks:  {},
+    callbacks: {},
     callbackStatus: {
         NO_RESULT: 0,
         OK: 1,
@@ -269,14 +267,14 @@ var cordova = {
     /**
      * Called by native code when returning successful result from an action.
      */
-    callbackSuccess: function(callbackId, args) {
+    callbackSuccess: function (callbackId, args) {
         cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
     },
 
     /**
      * Called by native code when returning error result from an action.
      */
-    callbackError: function(callbackId, args) {
+    callbackError: function (callbackId, args) {
         // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
         // Derive success from status.
         cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
@@ -285,11 +283,11 @@ var cordova = {
     /**
      * Called by native code when returning the result from an action.
      */
-    callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) {
+    callbackFromNative: function (callbackId, isSuccess, status, args, keepCallback) {
         try {
             var callback = cordova.callbacks[callbackId];
             if (callback) {
-                if (isSuccess && status == cordova.callbackStatus.OK) {
+                if (isSuccess && status === cordova.callbackStatus.OK) {
                     callback.success && callback.success.apply(null, args);
                 } else if (!isSuccess) {
                     callback.fail && callback.fail.apply(null, args);
@@ -306,26 +304,24 @@ var cordova = {
                     delete cordova.callbacks[callbackId];
                 }
             }
-        }
-        catch (err) {
-            var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err;
+        } catch (err) {
+            var msg = 'Error in ' + (isSuccess ? 'Success' : 'Error') + ' callbackId: ' + callbackId + ' : ' + err;
             console && console.log && console.log(msg);
-            cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg });
+            cordova.fireWindowEvent('cordovacallbackerror', { 'message': msg });
             throw err;
         }
     },
-    addConstructor: function(func) {
-        channel.onCordovaReady.subscribe(function() {
+    addConstructor: function (func) {
+        channel.onCordovaReady.subscribe(function () {
             try {
                 func();
-            } catch(e) {
-                console.log("Failed to run constructor: " + e);
+            } catch (e) {
+                console.log('Failed to run constructor: ' + e);
             }
         });
     }
 };
 
-
 module.exports = cordova;
 
 });
@@ -346,29 +342,29 @@ var typeMap = {
     'O': 'Object'
 };
 
-function extractParamName(callee, argIndex) {
+function extractParamName (callee, argIndex) {
     return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
 }
 
-function checkArgs(spec, functionName, args, opt_callee) {
+function checkArgs (spec, functionName, args, opt_callee) {
     if (!moduleExports.enableChecks) {
         return;
     }
     var errMsg = null;
     var typeName;
     for (var i = 0; i < spec.length; ++i) {
-        var c = spec.charAt(i),
-            cUpper = c.toUpperCase(),
-            arg = args[i];
+        var c = spec.charAt(i);
+        var cUpper = c.toUpperCase();
+        var arg = args[i];
         // Asterix means allow anything.
-        if (c == '*') {
+        if (c === '*') {
             continue;
         }
         typeName = utils.typeName(arg);
-        if ((arg === null || arg === undefined) && c == cUpper) {
+        if ((arg === null || arg === undefined) && c === cUpper) {
             continue;
         }
-        if (typeName != typeMap[cUpper]) {
+        if (typeName !== typeMap[cUpper]) {
             errMsg = 'Expected ' + typeMap[cUpper];
             break;
         }
@@ -377,14 +373,14 @@ function checkArgs(spec, functionName, args, opt_callee) {
         errMsg += ', but got ' + typeName + '.';
         errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
         // Don't log when running unit tests.
-        if (typeof jasmine == 'undefined') {
+        if (typeof jasmine === 'undefined') {
             console.error(errMsg);
         }
         throw TypeError(errMsg);
     }
 }
 
-function getValue(value, defaultValue) {
+function getValue (value, defaultValue) {
     return value === undefined ? defaultValue : value;
 }
 
@@ -392,7 +388,6 @@ moduleExports.checkArgs = checkArgs;
 moduleExports.getValue = getValue;
 moduleExports.enableChecks = true;
 
-
 });
 
 // file: src/common/base64.js
@@ -400,58 +395,58 @@ define("cordova/base64", function(require, exports, module) {
 
 var base64 = exports;
 
-base64.fromArrayBuffer = function(arrayBuffer) {
+base64.fromArrayBuffer = function (arrayBuffer) {
     var array = new Uint8Array(arrayBuffer);
     return uint8ToBase64(array);
 };
 
-base64.toArrayBuffer = function(str) {
-    var decodedStr = typeof atob != 'undefined' ? atob(str) : new Buffer(str,'base64').toString('binary');
+base64.toArrayBuffer = function (str) {
+    var decodedStr = typeof atob !== 'undefined' ? atob(str) : Buffer.from(str, 'base64').toString('binary'); // eslint-disable-line no-undef
     var arrayBuffer = new ArrayBuffer(decodedStr.length);
     var array = new Uint8Array(arrayBuffer);
-    for (var i=0, len=decodedStr.length; i < len; i++) {
+    for (var i = 0, len = decodedStr.length; i < len; i++) {
         array[i] = decodedStr.charCodeAt(i);
     }
     return arrayBuffer;
 };
 
-//------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
 
 /* This code is based on the performance tests at http://jsperf.com/b64tests
  * This 12-bit-at-a-time algorithm was the best performing version on all
  * platforms tested.
  */
 
-var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64_6bit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 var b64_12bit;
 
-var b64_12bitTable = function() {
+var b64_12bitTable = function () {
     b64_12bit = [];
-    for (var i=0; i<64; i++) {
-        for (var j=0; j<64; j++) {
-            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
+    for (var i = 0; i < 64; i++) {
+        for (var j = 0; j < 64; j++) {
+            b64_12bit[i * 64 + j] = b64_6bit[i] + b64_6bit[j];
         }
     }
-    b64_12bitTable = function() { return b64_12bit; };
+    b64_12bitTable = function () { return b64_12bit; };
     return b64_12bit;
 };
 
-function uint8ToBase64(rawData) {
+function uint8ToBase64 (rawData) {
     var numBytes = rawData.byteLength;
-    var output="";
+    var output = '';
     var segment;
     var table = b64_12bitTable();
-    for (var i=0;i<numBytes-2;i+=3) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
+    for (var i = 0; i < numBytes - 2; i += 3) {
+        segment = (rawData[i] << 16) + (rawData[i + 1] << 8) + rawData[i + 2];
         output += table[segment >> 12];
         output += table[segment & 0xfff];
     }
-    if (numBytes - i == 2) {
-        segment = (rawData[i] << 16) + (rawData[i+1] << 8);
+    if (numBytes - i === 2) {
+        segment = (rawData[i] << 16) + (rawData[i + 1] << 8);
         output += table[segment >> 12];
         output += b64_6bit[(segment & 0xfff) >> 6];
         output += '=';
-    } else if (numBytes - i == 1) {
+    } else if (numBytes - i === 1) {
         segment = (rawData[i] << 16);
         output += table[segment >> 12];
         output += '==';
@@ -466,7 +461,7 @@ define("cordova/builder", function(require, exports, module) {
 
 var utils = require('cordova/utils');
 
-function each(objects, func, context) {
+function each (objects, func, context) {
     for (var prop in objects) {
         if (objects.hasOwnProperty(prop)) {
             func.apply(context, [objects[prop], prop]);
@@ -474,7 +469,7 @@ function each(objects, func, context) {
     }
 }
 
-function clobber(obj, key, value) {
+function clobber (obj, key, value) {
     exports.replaceHookForTesting(obj, key);
     var needsProperty = false;
     try {
@@ -484,15 +479,15 @@ function clobber(obj, key, value) {
     }
     // Getters can only be overridden by getters.
     if (needsProperty || obj[key] !== value) {
-        utils.defineGetter(obj, key, function() {
+        utils.defineGetter(obj, key, function () {
             return value;
         });
     }
 }
 
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+function assignOrWrapInDeprecateGetter (obj, key, value, message) {
     if (message) {
-        utils.defineGetter(obj, key, function() {
+        utils.defineGetter(obj, key, function () {
             console.log(message);
             delete obj[key];
             clobber(obj, key, value);
@@ -503,7 +498,7 @@ function assignOrWrapInDeprecateGetter(obj, key, value, message) {
     }
 }
 
-function include(parent, objects, clobber, merge) {
+function include (parent, objects, clobber, merge) {
     each(objects, function (obj, key) {
         try {
             var result = obj.path ? require(obj.path) : {};
@@ -523,7 +518,7 @@ function include(parent, objects, clobber, merge) {
                 result = parent[key];
             } else {
                 // Overwrite if not currently defined.
-                if (typeof parent[key] == 'undefined') {
+                if (typeof parent[key] === 'undefined') {
                     assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
                 } else {
                     // Set result to what already exists, so we can build children into it if they exist.
@@ -534,7 +529,7 @@ function include(parent, objects, clobber, merge) {
             if (obj.children) {
                 include(result, obj.children, clobber, merge);
             }
-        } catch(e) {
+        } catch (e) {
             utils.alert('Exception building Cordova JS globals: ' + e + ' for key "' + key + '"');
         }
     });
@@ -547,7 +542,7 @@ function include(parent, objects, clobber, merge) {
  * @param target Object to merge properties into.
  * @param src Object to merge properties from.
  */
-function recursiveMerge(target, src) {
+function recursiveMerge (target, src) {
     for (var prop in src) {
         if (src.hasOwnProperty(prop)) {
             if (target.prototype && target.prototype.constructor === target) {
@@ -564,26 +559,26 @@ function recursiveMerge(target, src) {
     }
 }
 
-exports.buildIntoButDoNotClobber = function(objects, target) {
+exports.buildIntoButDoNotClobber = function (objects, target) {
     include(target, objects, false, false);
 };
-exports.buildIntoAndClobber = function(objects, target) {
+exports.buildIntoAndClobber = function (objects, target) {
     include(target, objects, true, false);
 };
-exports.buildIntoAndMerge = function(objects, target) {
+exports.buildIntoAndMerge = function (objects, target) {
     include(target, objects, true, true);
 };
 exports.recursiveMerge = recursiveMerge;
 exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
+exports.replaceHookForTesting = function () {};
 
 });
 
 // file: src/common/channel.js
 define("cordova/channel", function(require, exports, module) {
 
-var utils = require('cordova/utils'),
-    nextGuid = 1;
+var utils = require('cordova/utils');
+var nextGuid = 1;
 
 /**
  * Custom pub-sub "channel" that can have functions subscribed to it
@@ -623,7 +618,7 @@ var utils = require('cordova/utils'),
  * @constructor
  * @param type  String the channel name
  */
-var Channel = function(type, sticky) {
+var Channel = function (type, sticky) {
     this.type = type;
     // Map of guid -> function.
     this.handlers = {};
@@ -636,69 +631,75 @@ var Channel = function(type, sticky) {
     // Function that is called when the first listener is subscribed, or when
     // the last listener is unsubscribed.
     this.onHasSubscribersChange = null;
-},
-    channel = {
-        /**
-         * Calls the provided function only after all of the channels specified
-         * have been fired. All channels must be sticky channels.
-         */
-        join: function(h, c) {
-            var len = c.length,
-                i = len,
-                f = function() {
-                    if (!(--i)) h();
-                };
-            for (var j=0; j<len; j++) {
-                if (c[j].state === 0) {
-                    throw Error('Can only use join with sticky channels.');
-                }
-                c[j].subscribe(f);
-            }
-            if (!len) h();
-        },
-        create: function(type) {
-            return channel[type] = new Channel(type, false);
-        },
-        createSticky: function(type) {
-            return channel[type] = new Channel(type, true);
-        },
-
-        /**
-         * cordova Channels that must fire before "deviceready" is fired.
-         */
-        deviceReadyChannelsArray: [],
-        deviceReadyChannelsMap: {},
-
-        /**
-         * Indicate that a feature needs to be initialized before it is ready to be used.
-         * This holds up Cordova's "deviceready" event until the feature has been initialized
-         * and Cordova.initComplete(feature) is called.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        waitForInitialization: function(feature) {
-            if (feature) {
-                var c = channel[feature] || this.createSticky(feature);
-                this.deviceReadyChannelsMap[feature] = c;
-                this.deviceReadyChannelsArray.push(c);
-            }
-        },
-
-        /**
-         * Indicate that initialization code has completed and the feature is ready to be used.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        initializationComplete: function(feature) {
-            var c = this.deviceReadyChannelsMap[feature];
-            if (c) {
-                c.fire();
+};
+var channel = {
+    /**
+     * Calls the provided function only after all of the channels specified
+     * have been fired. All channels must be sticky channels.
+     */
+    join: function (h, c) {
+        var len = c.length;
+        var i = len;
+        var f = function () {
+            if (!(--i)) h();
+        };
+        for (var j = 0; j < len; j++) {
+            if (c[j].state === 0) {
+                throw Error('Can only use join with sticky channels.');
             }
+            c[j].subscribe(f);
         }
-    };
+        if (!len) h();
+    },
+    /* eslint-disable no-return-assign */
+    create: function (type) {
+        return channel[type] = new Channel(type, false);
+    },
+    createSticky: function (type) {
+        return channel[type] = new Channel(type, true);
+    },
+    /* eslint-enable no-return-assign */
+    /**
+     * cordova Channels that must fire before "deviceready" is fired.
+     */
+    deviceReadyChannelsArray: [],
+    deviceReadyChannelsMap: {},
+
+    /**
+     * Indicate that a feature needs to be initialized before it is ready to be used.
+     * This holds up Cordova's "deviceready" event until the feature has been initialized
+     * and Cordova.initComplete(feature) is called.
+     *
+     * @param feature {String}     The unique feature name
+     */
+    waitForInitialization: function (feature) {
+        if (feature) {
+            var c = channel[feature] || this.createSticky(feature);
+            this.deviceReadyChannelsMap[feature] = c;
+            this.deviceReadyChannelsArray.push(c);
+        }
+    },
 
-function forceFunction(f) {
-    if (typeof f != 'function') throw "Function required as first argument!";
+    /**
+     * Indicate that initialization code has completed and the feature is ready to be used.
+     *
+     * @param feature {String}     The unique feature name
+     */
+    initializationComplete: function (feature) {
+        var c = this.deviceReadyChannelsMap[feature];
+        if (c) {
+            c.fire();
+        }
+    }
+};
+
+function checkSubscriptionArgument (argument) {
+    if (typeof argument !== 'function' && typeof argument.handleEvent !== 'function') {
+        throw new Error(
+            'Must provide a function or an EventListener object ' +
+                'implementing the handleEvent interface.'
+        );
+    }
 }
 
 /**
@@ -708,30 +709,41 @@ function forceFunction(f) {
  * and a guid that can be used to stop subscribing to the channel.
  * Returns the guid.
  */
-Channel.prototype.subscribe = function(f, c) {
-    // need a function to call
-    forceFunction(f);
-    if (this.state == 2) {
-        f.apply(c || this, this.fireArgs);
+Channel.prototype.subscribe = function (eventListenerOrFunction, eventListener) {
+    checkSubscriptionArgument(eventListenerOrFunction);
+    var handleEvent, guid;
+
+    if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
+        // Received an EventListener object implementing the handleEvent interface
+        handleEvent = eventListenerOrFunction.handleEvent;
+        eventListener = eventListenerOrFunction;
+    } else {
+        // Received a function to handle event
+        handleEvent = eventListenerOrFunction;
+    }
+
+    if (this.state === 2) {
+        handleEvent.apply(eventListener || this, this.fireArgs);
         return;
     }
 
-    var func = f,
-        guid = f.observer_guid;
-    if (typeof c == "object") { func = utils.close(c, f); }
+    guid = eventListenerOrFunction.observer_guid;
+    if (typeof eventListener === 'object') {
+        handleEvent = utils.close(eventListener, handleEvent);
+    }
 
     if (!guid) {
-        // first time any channel has seen this subscriber
+        // First time any channel has seen this subscriber
         guid = '' + nextGuid++;
     }
-    func.observer_guid = guid;
-    f.observer_guid = guid;
+    handleEvent.observer_guid = guid;
+    eventListenerOrFunction.observer_guid = guid;
 
     // Don't add the same handler more than once.
     if (!this.handlers[guid]) {
-        this.handlers[guid] = func;
+        this.handlers[guid] = handleEvent;
         this.numHandlers++;
-        if (this.numHandlers == 1) {
+        if (this.numHandlers === 1) {
             this.onHasSubscribersChange && this.onHasSubscribersChange();
         }
     }
@@ -740,12 +752,20 @@ Channel.prototype.subscribe = function(f, c) {
 /**
  * Unsubscribes the function with the given guid from the channel.
  */
-Channel.prototype.unsubscribe = function(f) {
-    // need a function to unsubscribe
-    forceFunction(f);
+Channel.prototype.unsubscribe = function (eventListenerOrFunction) {
+    checkSubscriptionArgument(eventListenerOrFunction);
+    var handleEvent, guid, handler;
+
+    if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
+        // Received an EventListener object implementing the handleEvent interface
+        handleEvent = eventListenerOrFunction.handleEvent;
+    } else {
+        // Received a function to handle event
+        handleEvent = eventListenerOrFunction;
+    }
 
-    var guid = f.observer_guid,
-        handler = this.handlers[guid];
+    guid = handleEvent.observer_guid;
+    handler = this.handlers[guid];
     if (handler) {
         delete this.handlers[guid];
         this.numHandlers--;
@@ -758,11 +778,11 @@ Channel.prototype.unsubscribe = function(f) {
 /**
  * Calls all functions subscribed to this channel.
  */
-Channel.prototype.fire = function(e) {
-    var fail = false,
-        fireArgs = Array.prototype.slice.call(arguments);
+Channel.prototype.fire = function (e) {
+    var fail = false; // eslint-disable-line no-unused-vars
+    var fireArgs = Array.prototype.slice.call(arguments);
     // Apply stickiness.
-    if (this.state == 1) {
+    if (this.state === 1) {
         this.state = 2;
         this.fireArgs = fireArgs;
     }
@@ -776,7 +796,7 @@ Channel.prototype.fire = function(e) {
         for (var i = 0; i < toCall.length; ++i) {
             toCall[i].apply(this, fireArgs);
         }
-        if (this.state == 2 && this.numHandlers) {
+        if (this.state === 2 && this.numHandlers) {
             this.numHandlers = 0;
             this.handlers = {};
             this.onHasSubscribersChange && this.onHasSubscribersChange();
@@ -784,7 +804,6 @@ Channel.prototype.fire = function(e) {
     }
 };
 
-
 // defining them here so they are ready super fast!
 // DOM event that is received when the web page is loaded and parsed.
 channel.createSticky('onDOMContentLoaded');
@@ -817,7 +836,7 @@ module.exports = channel;
 
 });
 
-// file: e:/cordova/cordova-browser/cordova-js-src/confighelper.js
+// file: /Users/steveng/repo/cordova/cordova-browser/cordova-js-src/confighelper.js
 define("cordova/confighelper", function(require, exports, module) {
 
 var config;
@@ -862,14 +881,9 @@ function readConfig(success, error) {
         }
     };
 
-    if ("ActiveXObject" in window) {
-        // Needed for XHR-ing via file:// protocol in IE
-        xhr = new window.ActiveXObject("MSXML2.XMLHTTP");
-        xhr.onreadystatechange = xhrStatusChangeHandler;
-    } else {
-        xhr = new XMLHttpRequest();
-        xhr.addEventListener("load", xhrStatusChangeHandler);
-    }
+    xhr = new XMLHttpRequest();
+    xhr.addEventListener("load", xhrStatusChangeHandler);
+
 
     try {
         xhr.open("get", "/config.xml", true);
@@ -897,7 +911,7 @@ exports.readConfig = readConfig;
 
 });
 
-// file: e:/cordova/cordova-browser/cordova-js-src/exec.js
+// file: /Users/steveng/repo/cordova/cordova-browser/cordova-js-src/exec.js
 define("cordova/exec", function(require, exports, module) {
 
 /*jslint sloppy:true, plusplus:true*/
@@ -999,31 +1013,31 @@ module.exports = function (success, fail, service, action, args) {
 // file: src/common/exec/proxy.js
 define("cordova/exec/proxy", function(require, exports, module) {
 
-
 // internal map of proxy function
 var CommandProxyMap = {};
 
 module.exports = {
 
     // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
-    add:function(id,proxyObj) {
-        console.log("adding proxy for " + id);
+    add: function (id, proxyObj) {
+        console.log('adding proxy for ' + id);
         CommandProxyMap[id] = proxyObj;
         return proxyObj;
     },
 
     // cordova.commandProxy.remove("Accelerometer");
-    remove:function(id) {
+    remove: function (id) {
         var proxy = CommandProxyMap[id];
         delete CommandProxyMap[id];
         CommandProxyMap[id] = null;
         return proxy;
     },
 
-    get:function(service,action) {
-        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+    get: function (service, action) {
+        return (CommandProxyMap[service] ? CommandProxyMap[service][action] : null);
     }
 };
+
 });
 
 // file: src/common/init.js
@@ -1038,16 +1052,16 @@ var utils = require('cordova/utils');
 
 var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
 
-function logUnfiredChannels(arr) {
+function logUnfiredChannels (arr) {
     for (var i = 0; i < arr.length; ++i) {
-        if (arr[i].state != 2) {
+        if (arr[i].state !== 2) {
             console.log('Channel not fired: ' + arr[i].type);
         }
     }
 }
 
-window.setTimeout(function() {
-    if (channel.onDeviceReady.state != 2) {
+window.setTimeout(function () {
+    if (channel.onDeviceReady.state !== 2) {
         console.log('deviceready has not fired after 5 seconds.');
         logUnfiredChannels(platformInitChannelsArray);
         logUnfiredChannels(channel.deviceReadyChannelsArray);
@@ -1056,20 +1070,19 @@ window.setTimeout(function() {
 
 // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
 // We replace it so that properties that can't be clobbered can instead be overridden.
-function replaceNavigator(origNavigator) {
-    var CordovaNavigator = function() {};
+function replaceNavigator (origNavigator) {
+    var CordovaNavigator = function () {};
     CordovaNavigator.prototype = origNavigator;
     var newNavigator = new CordovaNavigator();
     // This work-around really only applies to new APIs that are newer than Function.bind.
     // Without it, APIs such as getGamepads() break.
     if (CordovaNavigator.bind) {
         for (var key in origNavigator) {
-            if (typeof origNavigator[key] == 'function') {
+            if (typeof origNavigator[key] === 'function') {
                 newNavigator[key] = origNavigator[key].bind(origNavigator);
-            }
-            else {
-                (function(k) {
-                    utils.defineGetterSetter(newNavigator,key,function() {
+            } else {
+                (function (k) {
+                    utils.defineGetterSetter(newNavigator, key, function () {
                         return origNavigator[k];
                     });
                 })(key);
@@ -1085,12 +1098,12 @@ if (window.navigator) {
 
 if (!window.console) {
     window.console = {
-        log: function(){}
+        log: function () {}
     };
 }
 if (!window.console.warn) {
-    window.console.warn = function(msg) {
-        this.log("warn: " + msg);
+    window.console.warn = function (msg) {
+        this.log('warn: ' + msg);
     };
 }
 
@@ -1101,10 +1114,10 @@ channel.onActivated = cordova.addDocumentEventHandler('activated');
 channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
 
 // Listen for DOMContentLoaded and notify our channel subscribers.
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
+if (document.readyState === 'complete' || document.readyState === 'interactive') {
     channel.onDOMContentLoaded.fire();
 } else {
-    document.addEventListener('DOMContentLoaded', function() {
+    document.addEventListener('DOMContentLoaded', function () {
         channel.onDOMContentLoaded.fire();
     }, false);
 }
@@ -1125,8 +1138,8 @@ platform.bootstrap && platform.bootstrap();
 
 // Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
 // The delay allows the attached modules to be defined before the plugin loader looks for them.
-setTimeout(function() {
-    pluginloader.load(function() {
+setTimeout(function () {
+    pluginloader.load(function () {
         channel.onPluginsReady.fire();
     });
 }, 0);
@@ -1134,7 +1147,7 @@ setTimeout(function() {
 /**
  * Create all cordova objects once native side is ready.
  */
-channel.join(function() {
+channel.join(function () {
     modulemapper.mapModules(window);
 
     platform.initialize && platform.initialize();
@@ -1145,13 +1158,12 @@ channel.join(function() {
     // Fire onDeviceReady event once page has fully loaded, all
     // constructors have run and cordova info has been received from native
     // side.
-    channel.join(function() {
+    channel.join(function () {
         require('cordova').fireDocumentEvent('deviceready');
     }, channel.deviceReadyChannelsArray);
 
 }, platformInitChannelsArray);
 
-
 });
 
 // file: src/common/init_b.js
@@ -1169,16 +1181,16 @@ var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeRea
 // setting exec
 cordova.exec = require('cordova/exec');
 
-function logUnfiredChannels(arr) {
+function logUnfiredChannels (arr) {
     for (var i = 0; i < arr.length; ++i) {
-        if (arr[i].state != 2) {
+        if (arr[i].state !== 2) {
             console.log('Channel not fired: ' + arr[i].type);
         }
     }
 }
 
-window.setTimeout(function() {
-    if (channel.onDeviceReady.state != 2) {
+window.setTimeout(function () {
+    if (channel.onDeviceReady.state !== 2) {
         console.log('deviceready has not fired after 5 seconds.');
         logUnfiredChannels(platformInitChannelsArray);
         logUnfiredChannels(channel.deviceReadyChannelsArray);
@@ -1187,20 +1199,19 @@ window.setTimeout(function() {
 
 // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
 // We replace it so that properties that can't be clobbered can instead be overridden.
-function replaceNavigator(origNavigator) {
-    var CordovaNavigator = function() {};
+function replaceNavigator (origNavigator) {
+    var CordovaNavigator = function () {};
     CordovaNavigator.prototype = origNavigator;
     var newNavigator = new CordovaNavigator();
     // This work-around really only applies to new APIs that are newer than Function.bind.
     // Without it, APIs such as getGamepads() break.
     if (CordovaNavigator.bind) {
         for (var key in origNavigator) {
-            if (typeof origNavigator[key] == 'function') {
+            if (typeof origNavigator[key] === 'function') {
                 newNavigator[key] = origNavigator[key].bind(origNavigator);
-            }
-            else {
-                (function(k) {
-                    utils.defineGetterSetter(newNavigator,key,function() {
+            } else {
+                (function (k) {
+                    utils.defineGetterSetter(newNavigator, key, function () {
                         return origNavigator[k];
                     });
                 })(key);
@@ -1215,12 +1226,12 @@ if (window.navigator) {
 
 if (!window.console) {
     window.console = {
-        log: function(){}
+        log: function () {}
     };
 }
 if (!window.console.warn) {
-    window.console.warn = function(msg) {
-        this.log("warn: " + msg);
+    window.console.warn = function (msg) {
+        this.log('warn: ' + msg);
     };
 }
 
@@ -1231,10 +1242,10 @@ channel.onActivated = cordova.addDocumentEventHandler('activated');
 channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
 
 // Listen for DOMContentLoaded and notify our channel subscribers.
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
+if (document.readyState === 'complete' || document.readyState === 'interactive') {
     channel.onDOMContentLoaded.fire();
 } else {
-    document.addEventListener('DOMContentLoaded', function() {
+    document.addEventListener('DOMContentLoaded', function () {
         channel.onDOMContentLoaded.fire();
     }, false);
 }
@@ -1251,8 +1262,8 @@ platform.bootstrap && platform.bootstrap();
 
 // Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
 // The delay allows the attached modules to be defined before the plugin loader looks for them.
-setTimeout(function() {
-    pluginloader.load(function() {
+setTimeout(function () {
+    pluginloader.load(function () {
         channel.onPluginsReady.fire();
     });
 }, 0);
@@ -1260,7 +1271,7 @@ setTimeout(function() {
 /**
  * Create all cordova objects once native side is ready.
  */
-channel.join(function() {
+channel.join(function () {
     modulemapper.mapModules(window);
 
     platform.initialize && platform.initialize();
@@ -1271,7 +1282,7 @@ channel.join(function() {
     // Fire onDeviceReady event once page has fully loaded, all
     // constructors have run and cordova info has been received from native
     // side.
-    channel.join(function() {
+    channel.join(function () {
         require('cordova').fireDocumentEvent('deviceready');
     }, channel.deviceReadyChannelsArray);
 
@@ -1282,17 +1293,17 @@ channel.join(function() {
 // file: src/common/modulemapper.js
 define("cordova/modulemapper", function(require, exports, module) {
 
-var builder = require('cordova/builder'),
-    moduleMap = define.moduleMap,
-    symbolList,
-    deprecationMap;
+var builder = require('cordova/builder');
+var moduleMap = define.moduleMap; // eslint-disable-line no-undef
+var symbolList;
+var deprecationMap;
 
-exports.reset = function() {
+exports.reset = function () {
     symbolList = [];
     deprecationMap = {};
 };
 
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
     if (!(moduleName in moduleMap)) {
         throw new Error('Module ' + moduleName + ' does not exist.');
     }
@@ -1303,35 +1314,35 @@ function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
 }
 
 // Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.runs = function(moduleName) {
+exports.runs = function (moduleName) {
     addEntry('r', moduleName, null);
 };
 
-function prepareNamespace(symbolPath, context) {
+function prepareNamespace (symbolPath, context) {
     if (!symbolPath) {
         return context;
     }
     var parts = symbolPath.split('.');
     var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
+    for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
         cur = cur[part] = cur[part] || {};
     }
     return cur;
 }
 
-exports.mapModules = function(context) {
+exports.mapModules = function (context) {
     var origSymbols = {};
     context.CDV_origSymbols = origSymbols;
     for (var i = 0, len = symbolList.length; i < len; i += 3) {
@@ -1339,7 +1350,7 @@ exports.mapModules = function(context) {
         var moduleName = symbolList[i + 1];
         var module = require(moduleName);
         // <runs/>
-        if (strategy == 'r') {
+        if (strategy === 'r') {
             continue;
         }
         var symbolPath = symbolList[i + 2];
@@ -1351,9 +1362,9 @@ exports.mapModules = function(context) {
         var parentObj = prepareNamespace(namespace, context);
         var target = parentObj[lastName];
 
-        if (strategy == 'm' && target) {
+        if (strategy === 'm' && target) {
             builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+        } else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
             if (!(symbolPath in origSymbols)) {
                 origSymbols[symbolPath] = target;
             }
@@ -1362,7 +1373,7 @@ exports.mapModules = function(context) {
     }
 };
 
-exports.getOriginalSymbol = function(context, symbolPath) {
+exports.getOriginalSymbol = function (context, symbolPath) {
     var origSymbols = context.CDV_origSymbols;
     if (origSymbols && (symbolPath in origSymbols)) {
         return origSymbols[symbolPath];
@@ -1377,22 +1388,21 @@ exports.getOriginalSymbol = function(context, symbolPath) {
 
 exports.reset();
 
-
 });
 
 // file: src/common/modulemapper_b.js
 define("cordova/modulemapper_b", function(require, exports, module) {
 
-var builder = require('cordova/builder'),
-    symbolList = [],
-    deprecationMap;
+var builder = require('cordova/builder');
+var symbolList = [];
+var deprecationMap;
 
-exports.reset = function() {
+exports.reset = function () {
     symbolList = [];
     deprecationMap = {};
 };
 
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
     symbolList.push(strategy, moduleName, symbolPath);
     if (opt_deprecationMessage) {
         deprecationMap[symbolPath] = opt_deprecationMessage;
@@ -1400,35 +1410,35 @@ function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
 }
 
 // Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
     addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
 };
 
-exports.runs = function(moduleName) {
+exports.runs = function (moduleName) {
     addEntry('r', moduleName, null);
 };
 
-function prepareNamespace(symbolPath, context) {
+function prepareNamespace (symbolPath, context) {
     if (!symbolPath) {
         return context;
     }
     var parts = symbolPath.split('.');
     var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
+    for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
         cur = cur[part] = cur[part] || {};
     }
     return cur;
 }
 
-exports.mapModules = function(context) {
+exports.mapModules = function (context) {
     var origSymbols = {};
     context.CDV_origSymbols = origSymbols;
     for (var i = 0, len = symbolList.length; i < len; i += 3) {
@@ -1436,7 +1446,7 @@ exports.mapModules = function(context) {
         var moduleName = symbolList[i + 1];
         var module = require(moduleName);
         // <runs/>
-        if (strategy == 'r') {
+        if (strategy === 'r') {
             continue;
         }
         var symbolPath = symbolList[i + 2];
@@ -1448,9 +1458,9 @@ exports.mapModules = function(context) {
         var parentObj = prepareNamespace(namespace, context);
         var target = parentObj[lastName];
 
-        if (strategy == 'm' && target) {
+        if (strategy === 'm' && target) {
             builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+        } else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
             if (!(symbolPath in origSymbols)) {
                 origSymbols[symbolPath] = target;
             }
@@ -1459,7 +1469,7 @@ exports.mapModules = function(context) {
     }
 };
 
-exports.getOriginalSymbol = function(context, symbolPath) {
+exports.getOriginalSymbol = function (context, symbolPath) {
     var origSymbols = context.CDV_origSymbols;
     if (origSymbols && (symbolPath in origSymbols)) {
         return origSymbols[symbolPath];
@@ -1474,15 +1484,14 @@ exports.getOriginalSymbol = function(context, symbolPath) {
 
 exports.reset();
 
-
 });
 
-// file: e:/cordova/cordova-browser/cordova-js-src/platform.js
+// file: /Users/steveng/repo/cordova/cordova-browser/cordova-js-src/platform.js
 define("cordova/platform", function(require, exports, module) {
 
 module.exports = {
     id: 'browser',
-    cordovaVersion: '3.4.0',
+    cordovaVersion: '4.2.0', // cordova-js
 
     bootstrap: function() {
 
@@ -1493,16 +1502,14 @@ module.exports = {
 
         channel.onNativeReady.fire();
 
-        // FIXME is this the right place to clobber pause/resume? I am guessing not
-        // FIXME pause/resume should be deprecated IN CORDOVA for pagevisiblity api
-        document.addEventListener('webkitvisibilitychange', function() {
-            if (document.webkitHidden) {
+        document.addEventListener("visibilitychange", function(){
+            if(document.hidden) {
                 channel.onPause.fire();
             }
             else {
                 channel.onResume.fire();
             }
-        }, false);
+        });
 
     // End of bootstrap
     }
@@ -1514,12 +1521,11 @@ module.exports = {
 define("cordova/pluginloader", function(require, exports, module) {
 
 var modulemapper = require('cordova/modulemapper');
-var urlutil = require('cordova/urlutil');
 
 // Helper function to inject a <script> tag.
 // Exported for testing.
-exports.injectScript = function(url, onload, onerror) {
-    var script = document.createElement("script");
+exports.injectScript = function (url, onload, onerror) {
+    var script = document.createElement('script');
     // onload fires even when script fails loads with an error.
     script.onload = onload;
     // onerror fires for malformed URLs.
@@ -1528,13 +1534,13 @@ exports.injectScript = function(url, onload, onerror) {
     document.head.appendChild(script);
 };
 
-function injectIfNecessary(id, url, onload, onerror) {
+function injectIfNecessary (id, url, onload, onerror) {
     onerror = onerror || onload;
-    if (id in define.moduleMap) {
+    if (id in define.moduleMap) { // eslint-disable-line no-undef
         onload();
     } else {
-        exports.injectScript(url, function() {
-            if (id in define.moduleMap) {
+        exports.injectScript(url, function () {
+            if (id in define.moduleMap) { // eslint-disable-line no-undef
                 onload();
             } else {
                 onerror();
@@ -1543,9 +1549,9 @@ function injectIfNecessary(id, url, onload, onerror) {
     }
 }
 
-function onScriptLoadingComplete(moduleList, finishPluginLoading) {
+function onScriptLoadingComplete (moduleList, finishPluginLoading) {
     // Loop through all the plugins and then through their clobbers and merges.
-    for (var i = 0, module; module = moduleList[i]; i++) {
+    for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
         if (module.clobbers && module.clobbers.length) {
             for (var j = 0; j < module.clobbers.length; j++) {
                 modulemapper.clobbers(module.id, module.clobbers[j]);
@@ -1571,7 +1577,7 @@ function onScriptLoadingComplete(moduleList, finishPluginLoading) {
 // See plugman's plugin_loader.js for the details of this object.
 // This function is only called if the really is a plugins array that isn't empty.
 // Otherwise the onerror response handler will just call finishPluginLoading().
-function handlePluginsObject(path, moduleList, finishPluginLoading) {
+function handlePluginsObject (path, moduleList, finishPluginLoading) {
     // Now inject the scripts.
     var scriptCounter = moduleList.length;
 
@@ -1579,7 +1585,7 @@ function handlePluginsObject(path, moduleList, finishPluginLoading) {
         finishPluginLoading();
         return;
     }
-    function scriptLoadedCallback() {
+    function scriptLoadedCallback () {
         if (!--scriptCounter) {
             onScriptLoadingComplete(moduleList, finishPluginLoading);
         }
@@ -1590,13 +1596,13 @@ function handlePluginsObject(path, moduleList, finishPluginLoading) {
     }
 }
 
-function findCordovaPath() {
+function findCordovaPath () {
     var path = null;
     var scripts = document.getElementsByTagName('script');
     var term = '/cordova.js';
-    for (var n = scripts.length-1; n>-1; n--) {
+    for (var n = scripts.length - 1; n > -1; n--) {
         var src = scripts[n].src.replace(/\?.*$/, ''); // Strip any query param (CB-6007).
-        if (src.indexOf(term) == (src.length - term.length)) {
+        if (src.indexOf(term) === (src.length - term.length)) {
             path = src.substring(0, src.length - term.length) + '/';
             break;
         }
@@ -1607,19 +1613,18 @@ function findCordovaPath() {
 // Tries to load all plugins' js-modules.
 // This is an async process, but onDeviceReady is blocked on onPluginsReady.
 // onPluginsReady is fired when there are no plugins to load, or they are all done.
-exports.load = function(callback) {
+exports.load = function (callback) {
     var pathPrefix = findCordovaPath();
     if (pathPrefix === null) {
         console.log('Could not find cordova.js script tag. Plugin loading may fail.');
         pathPrefix = '';
     }
-    injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function() {
-        var moduleList = require("cordova/plugin_list");
+    injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function () {
+        var moduleList = require('cordova/plugin_list');
         handlePluginsObject(pathPrefix, moduleList, callback);
     }, callback);
 };
 
-
 });
 
 // file: src/common/pluginloader_b.js
@@ -1629,14 +1634,14 @@ var modulemapper = require('cordova/modulemapper');
 
 // Handler for the cordova_plugins.js content.
 // See plugman's plugin_loader.js for the details of this object.
-function handlePluginsObject(moduleList) {
+function handlePluginsObject (moduleList) {
     // if moduleList is not defined or empty, we've nothing to do
     if (!moduleList || !moduleList.length) {
         return;
     }
 
     // Loop through all the modules and then through their clobbers and merges.
-    for (var i = 0, module; module = moduleList[i]; i++) {
+    for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
         if (module.clobbers && module.clobbers.length) {
             for (var j = 0; j < module.clobbers.length; j++) {
                 modulemapper.clobbers(module.id, module.clobbers[j]);
@@ -1660,31 +1665,28 @@ function handlePluginsObject(moduleList) {
 // but the method accepts callback to be compatible with non-browserify flow.
 // onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
 // no plugins to load, or they are all done.
-exports.load = function(callback) {
-    var moduleList = require("cordova/plugin_list");
+exports.load = function (callback) {
+    var moduleList = require('cordova/plugin_list');
     handlePluginsObject(moduleList);
 
     callback();
 };
 
-
 });
 
 // file: src/common/urlutil.js
 define("cordova/urlutil", function(require, exports, module) {
 
-
 /**
  * For already absolute URLs, returns what is passed in.
  * For relative URLs, converts them to absolute ones.
  */
-exports.makeAbsolute = function makeAbsolute(url) {
+exports.makeAbsolute = function makeAbsolute (url) {
     var anchorEl = document.createElement('a');
     anchorEl.href = url;
     return anchorEl.href;
 };
 
-
 });
 
 // file: src/common/utils.js
@@ -1695,7 +1697,7 @@ var utils = exports;
 /**
  * Defines a property getter / setter for obj[key].
  */
-utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
+utils.defineGetterSetter = function (obj, key, getFunc, opt_setFunc) {
     if (Object.defineProperty) {
         var desc = {
             get: getFunc,
@@ -1718,13 +1720,13 @@ utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
  */
 utils.defineGetter = utils.defineGetterSetter;
 
-utils.arrayIndexOf = function(a, item) {
+utils.arrayIndexOf = function (a, item) {
     if (a.indexOf) {
         return a.indexOf(item);
     }
     var len = a.length;
     for (var i = 0; i < len; ++i) {
-        if (a[i] == item) {
+        if (a[i] === item) {
             return i;
         }
     }
@@ -1734,15 +1736,15 @@ utils.arrayIndexOf = function(a, item) {
 /**
  * Returns whether the item was found in the array.
  */
-utils.arrayRemove = function(a, item) {
+utils.arrayRemove = function (a, item) {
     var index = utils.arrayIndexOf(a, item);
-    if (index != -1) {
+    if (index !== -1) {
         a.splice(index, 1);
     }
-    return index != -1;
+    return index !== -1;
 };
 
-utils.typeName = function(val) {
+utils.typeName = function (val) {
     return Object.prototype.toString.call(val).slice(8, -1);
 };
 
@@ -1750,36 +1752,39 @@ utils.typeName = function(val) {
  * Returns an indication of whether the argument is an array or not
  */
 utils.isArray = Array.isArray ||
-                function(a) {return utils.typeName(a) == 'Array';};
+                function (a) { return utils.typeName(a) === 'Array'; };
 
 /**
  * Returns an indication of whether the argument is a Date or not
  */
-utils.isDate = function(d) {
+utils.isDate = function (d) {
     return (d instanceof Date);
 };
 
 /**
  * Does a deep clone of the object.
  */
-utils.clone = function(obj) {
-    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+utils.clone = function (obj) {
+    if (!obj || typeof obj === 'function' || utils.isDate(obj) || typeof obj !== 'object') {
         return obj;
     }
 
     var retVal, i;
 
-    if(utils.isArray(obj)){
+    if (utils.isArray(obj)) {
         retVal = [];
-        for(i = 0; i < obj.length; ++i){
+        for (i = 0; i < obj.length; ++i) {
             retVal.push(utils.clone(obj[i]));
         }
         return retVal;
     }
 
     retVal = {};
-    for(i in obj){
-        if(!(i in retVal) || retVal[i] != obj[i]) {
+    for (i in obj) {
+        // https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
+        // custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
+        // on cloning.
+        if ((!(i in retVal) || retVal[i] !== obj[i]) && typeof obj[i] !== 'undefined' && typeof obj[i] !== 'unknown') { // eslint-disable-line valid-typeof
             retVal[i] = utils.clone(obj[i]);
         }
     }
@@ -1789,20 +1794,20 @@ utils.clone = function(obj) {
 /**
  * Returns a wrapped version of the function
  */
-utils.close = function(context, func, params) {
-    return function() {
+utils.close = function (context, func, params) {
+    return function () {
         var args = params || arguments;
         return func.apply(context, args);
     };
 };
 
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
-    var uuidpart = "";
-    for (var i=0; i<length; i++) {
+// ------------------------------------------------------------------------------
+function UUIDcreatePart (length) {
+    var uuidpart = '';
+    for (var i = 0; i < length; i++) {
         var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
-        if (uuidchar.length == 1) {
-            uuidchar = "0" + uuidchar;
+        if (uuidchar.length === 1) {
+            uuidchar = '0' + uuidchar;
         }
         uuidpart += uuidchar;
     }
@@ -1812,7 +1817,7 @@ function UUIDcreatePart(length) {
 /**
  * Create a UUID
  */
-utils.createUUID = function() {
+utils.createUUID = function () {
     return UUIDcreatePart(4) + '-' +
         UUIDcreatePart(2) + '-' +
         UUIDcreatePart(2) + '-' +
@@ -1820,16 +1825,15 @@ utils.createUUID = function() {
         UUIDcreatePart(6);
 };
 
-
 /**
  * Extends a child object from a parent object using classical inheritance
  * pattern.
  */
-utils.extend = (function() {
+utils.extend = (function () {
     // proxy used to establish prototype chain
-    var F = function() {};
+    var F = function () {};
     // extend Child from Parent
-    return function(Child, Parent) {
+    return function (Child, Parent) {
 
         F.prototype = Parent.prototype;
         Child.prototype = new F();
@@ -1841,7 +1845,7 @@ utils.extend = (function() {
 /**
  * Alerts a message in any available way: alert or console.log.
  */
-utils.alert = function(msg) {
+utils.alert = function (msg) {
     if (window.alert) {
         window.alert(msg);
     } else if (console && console.log) {
@@ -1849,10 +1853,6 @@ utils.alert = function(msg) {
     }
 };
 
-
-
-
-
 });
 
 window.cordova = require('cordova');
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/LICENSE
index 19129e315..9bcfa9d7d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/LICENSE
@@ -1,3 +1,8 @@
+This software is dual-licensed under the ISC and MIT licenses.
+You may use this software under EITHER of the following licenses.
+
+----------
+
 The ISC License
 
 Copyright (c) Isaac Z. Schlueter and Contributors
@@ -13,3 +18,29 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+----------
+
+Copyright Isaac Z. Schlueter and Contributors
+All rights reserved.
+
+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/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/abbrev.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/abbrev.js
index 69cfeac52..7b1dc5d67 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/abbrev.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/abbrev.js
@@ -1,4 +1,3 @@
-
 module.exports = exports = abbrev.abbrev = abbrev
 
 abbrev.monkeyPatch = monkeyPatch
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/package.json
index 7a066cc36..886ab3946 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/abbrev/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "abbrev@1",
-        "scope": null,
-        "escapedName": "abbrev",
-        "name": "abbrev",
-        "rawSpec": "1",
-        "spec": ">=1.0.0 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/nopt"
-    ]
-  ],
-  "_from": "abbrev@>=1.0.0 <2.0.0",
-  "_id": "abbrev@1.0.9",
-  "_inCache": true,
+  "_from": "abbrev@1",
+  "_id": "abbrev@1.1.1",
+  "_inBundle": false,
+  "_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
   "_location": "/abbrev",
-  "_nodeVersion": "4.4.4",
-  "_npmOperationalInternal": {
-    "host": "packages-16-east.internal.npmjs.com",
-    "tmp": "tmp/abbrev-1.0.9.tgz_1466016055839_0.7825860097073019"
-  },
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_npmVersion": "3.9.1",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "abbrev@1",
-    "scope": null,
-    "escapedName": "abbrev",
     "name": "abbrev",
+    "escapedName": "abbrev",
     "rawSpec": "1",
-    "spec": ">=1.0.0 <2.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "1"
   },
   "_requiredBy": [
     "/nopt"
   ],
-  "_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
-  "_shasum": "91b4792588a7738c25f35dd6f63752a2f8776135",
-  "_shrinkwrap": null,
+  "_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+  "_shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8",
   "_spec": "abbrev@1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/nopt",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/nopt",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me"
@@ -52,38 +29,28 @@
   "bugs": {
     "url": "https://github.com/isaacs/abbrev-js/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Like ruby's abbrev module, but in js",
   "devDependencies": {
-    "tap": "^5.7.2"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135",
-    "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
+    "tap": "^10.1"
   },
   "files": [
     "abbrev.js"
   ],
-  "gitHead": "c386cd9dbb1d8d7581718c54d4ba944cc9298d6f",
   "homepage": "https://github.com/isaacs/abbrev-js#readme",
   "license": "ISC",
   "main": "abbrev.js",
-  "maintainers": [
-    {
-      "name": "isaacs",
-      "email": "i@izs.me"
-    }
-  ],
   "name": "abbrev",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
   },
   "scripts": {
-    "test": "tap test.js --cov"
+    "postpublish": "git push origin --all; git push origin --tags",
+    "postversion": "npm publish",
+    "preversion": "npm test",
+    "test": "tap test.js --100"
   },
-  "version": "1.0.9"
+  "version": "1.1.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/HISTORY.md
index 0477ed71c..aaf528172 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/HISTORY.md
@@ -1,3 +1,9 @@
+1.3.4 / 2017-08-22
+==================
+
+  * deps: mime-types@~2.1.16
+    - deps: mime-db@~1.29.0
+
 1.3.3 / 2016-05-02
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/README.md
index ae36676f2..6a2749a1a 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/README.md
@@ -6,23 +6,31 @@
 [![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.
+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 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
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```sh
-npm install accepts
+$ npm install accepts
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var accepts = require('accepts')
 ```
@@ -88,11 +96,11 @@ server.
 var accepts = require('accepts')
 var http = require('http')
 
-function app(req, res) {
+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'])) {
+  switch (accept.type(['json', 'html'])) {
     case 'json':
       res.setHeader('Content-Type', 'application/json')
       res.write('{"hello":"world!"}')
@@ -126,7 +134,7 @@ curl -I -H'Accept: text/html' http://localhost:3000/
 [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/
+[node-version-url]: https://nodejs.org/en/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
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/index.js
index e80192abf..e9b2f63fb 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/index.js
@@ -29,9 +29,10 @@ module.exports = Accepts
  * @public
  */
 
-function Accepts(req) {
-  if (!(this instanceof Accepts))
+function Accepts (req) {
+  if (!(this instanceof Accepts)) {
     return new Accepts(req)
+  }
 
   this.headers = req.headers
   this.negotiator = new Negotiator(req)
@@ -95,12 +96,18 @@ Accepts.prototype.types = function (types_) {
     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)];
+  // no accept header, return first given type
+  if (!this.headers.accept) {
+    return types[0]
+  }
+
+  var mimes = types.map(extToMime)
+  var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
+  var first = accepts[0]
+
+  return first
+    ? types[mimes.indexOf(first)]
+    : false
 }
 
 /**
@@ -212,7 +219,7 @@ Accepts.prototype.languages = function (languages_) {
  * @private
  */
 
-function extToMime(type) {
+function extToMime (type) {
   return type.indexOf('/') === -1
     ? mime.lookup(type)
     : type
@@ -226,6 +233,6 @@ function extToMime(type) {
  * @private
  */
 
-function validMime(type) {
-  return typeof type === 'string';
+function validMime (type) {
+  return typeof type === 'string'
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/package.json
index 1d3c106e5..98f4793b3 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/accepts/package.json
@@ -1,54 +1,32 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "accepts@~1.3.3",
-        "scope": null,
-        "escapedName": "accepts",
-        "name": "accepts",
-        "rawSpec": "~1.3.3",
-        "spec": ">=1.3.3 <1.4.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression"
-    ]
-  ],
-  "_from": "accepts@>=1.3.3 <1.4.0",
-  "_id": "accepts@1.3.3",
-  "_inCache": true,
+  "_from": "accepts@~1.3.4",
+  "_id": "accepts@1.3.4",
+  "_inBundle": false,
+  "_integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
   "_location": "/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",
+    "type": "range",
+    "registry": true,
+    "raw": "accepts@~1.3.4",
     "name": "accepts",
-    "rawSpec": "~1.3.3",
-    "spec": ">=1.3.3 <1.4.0",
-    "type": "range"
+    "escapedName": "accepts",
+    "rawSpec": "~1.3.4",
+    "saveSpec": null,
+    "fetchSpec": "~1.3.4"
   },
   "_requiredBy": [
     "/compression",
     "/express"
   ],
-  "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
-  "_shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
-  "_shrinkwrap": null,
-  "_spec": "accepts@~1.3.3",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression",
+  "_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+  "_shasum": "86246758c7dd6d21a6474ff084a4740ec05eb21f",
+  "_spec": "accepts@~1.3.4",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/compression",
   "bugs": {
     "url": "https://github.com/jshttp/accepts/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -61,19 +39,22 @@
     }
   ],
   "dependencies": {
-    "mime-types": "~2.1.11",
+    "mime-types": "~2.1.16",
     "negotiator": "0.6.1"
   },
+  "deprecated": false,
   "description": "Higher-level content negotiation",
   "devDependencies": {
-    "istanbul": "0.4.3",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "istanbul": "0.4.5",
     "mocha": "~1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
-    "tarball": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -82,7 +63,6 @@
     "HISTORY.md",
     "index.js"
   ],
-  "gitHead": "3e925b1e65ed7da2798849683d49814680dfa426",
   "homepage": "https://github.com/jshttp/accepts#readme",
   "keywords": [
     "content",
@@ -91,23 +71,16 @@
     "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": {
+    "lint": "eslint --plugin markdown --ext js,md .",
     "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"
+  "version": "1.3.4"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/README.md
deleted file mode 100644
index dd94d4797..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# ADM-ZIP for NodeJS
-
-ADM-ZIP is a pure JavaScript implementation for zip data compression for [NodeJS](http://nodejs.org/). 
-
-# Installation
-
-With [npm](http://npmjs.org) do:
-
-    $ npm install adm-zip
-	
-## What is it good for?
-The library allows you to:
-
-* decompress zip files directly to disk or in memory buffers
-* compress files and store them to disk in .zip format or in compressed buffers
-* update content of/add new/delete files from an existing .zip
-
-# Dependencies
-There are no other nodeJS libraries that ADM-ZIP is dependent of
-
-# Examples
-
-## Basic usage
-```javascript
-
-	var AdmZip = require('adm-zip');
-
-	// reading archives
-	var zip = new AdmZip("./my_file.zip");
-	var zipEntries = zip.getEntries(); // an array of ZipEntry records
-
-	zipEntries.forEach(function(zipEntry) {
-	    console.log(zipEntry.toString()); // outputs zip entries information
-		if (zipEntry.entryName == "my_file.txt") {
-		     console.log(zipEntry.data.toString('utf8')); 
-		}
-	});
-	// outputs the content of some_folder/my_file.txt
-	console.log(zip.readAsText("some_folder/my_file.txt")); 
-	// extracts the specified file to the specified location
-	zip.extractEntryTo(/*entry name*/"some_folder/my_file.txt", /*target path*/"/home/me/tempfolder", /*maintainEntryPath*/false, /*overwrite*/true);
-	// extracts everything
-	zip.extractAllTo(/*target path*/"/home/me/zipcontent/", /*overwrite*/true);
-	
-	
-	// creating archives
-	var zip = new AdmZip();
-	
-	// add file directly
-	zip.addFile("test.txt", new Buffer("inner content of the file"), "entry comment goes here");
-	// add local file
-	zip.addLocalFile("/home/me/some_picture.png");
-	// get everything as a buffer
-	var willSendthis = zip.toBuffer();
-	// or write everything to disk
-	zip.writeZip(/*target file name*/"/home/me/files.zip");
-	
-	
-	// ... more examples in the wiki
-```
-
-For more detailed information please check out the [wiki](https://github.com/cthackers/adm-zip/wiki).
-
-[![build status](https://secure.travis-ci.org/cthackers/adm-zip.png)](http://travis-ci.org/cthackers/adm-zip)
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/adm-zip.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/adm-zip.js
deleted file mode 100644
index 9ba4bd0fa..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/adm-zip.js
+++ /dev/null
@@ -1,475 +0,0 @@
-var fs = require("fs"),
-    pth = require("path");
-
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-var ZipEntry = require("./zipEntry"),
-    ZipFile =  require("./zipFile"),
-    Utils = require("./util");
-
-module.exports = function(/*String*/input) {
-    var _zip = undefined,
-        _filename = "";
-
-    if (input && typeof input === "string") { // load zip file
-        if (fs.existsSync(input)) {
-            _filename = input;
-            _zip = new ZipFile(input, Utils.Constants.FILE);
-        } else {
-           throw Utils.Errors.INVALID_FILENAME;
-        }
-    } else if(input && Buffer.isBuffer(input)) { // load buffer
-        _zip = new ZipFile(input, Utils.Constants.BUFFER);
-    } else { // create new zip file
-        _zip = new ZipFile(null, Utils.Constants.NONE);
-    }
-
-    function getEntry(/*Object*/entry) {
-        if (entry && _zip) {
-            var item;
-            // If entry was given as a file name
-            if (typeof entry === "string")
-                item = _zip.getEntry(entry);
-            // if entry was given as a ZipEntry object
-            if (typeof entry === "object" && entry.entryName != undefined && entry.header != undefined)
-                item =  _zip.getEntry(entry.entryName);
-
-            if (item) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    return {
-        /**
-         * Extracts the given entry from the archive and returns the content as a Buffer object
-         * @param entry ZipEntry object or String with the full path of the entry
-         *
-         * @return Buffer or Null in case of error
-         */
-        readFile : function(/*Object*/entry) {
-            var item = getEntry(entry);
-            return item && item.getData() || null;
-        },
-
-        /**
-         * Asynchronous readFile
-         * @param entry ZipEntry object or String with the full path of the entry
-         * @param callback
-         *
-         * @return Buffer or Null in case of error
-         */
-        readFileAsync : function(/*Object*/entry, /*Function*/callback) {
-            var item = getEntry(entry);
-            if (item) {
-                item.getDataAsync(callback);
-            } else {
-                callback(null,"getEntry failed for:" + entry)
-            }
-        },
-
-        /**
-         * Extracts the given entry from the archive and returns the content as plain text in the given encoding
-         * @param entry ZipEntry object or String with the full path of the entry
-         * @param encoding Optional. If no encoding is specified utf8 is used
-         *
-         * @return String
-         */
-        readAsText : function(/*Object*/entry, /*String - Optional*/encoding) {
-            var item = getEntry(entry);
-            if (item) {
-                var data = item.getData();
-                if (data && data.length) {
-                    return data.toString(encoding || "utf8");
-                }
-            }
-            return "";
-        },
-
-        /**
-         * Asynchronous readAsText
-         * @param entry ZipEntry object or String with the full path of the entry
-         * @param callback
-         * @param encoding Optional. If no encoding is specified utf8 is used
-         *
-         * @return String
-         */
-        readAsTextAsync : function(/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) {
-            var item = getEntry(entry);
-            if (item) {
-                item.getDataAsync(function(data) {
-                    if (data && data.length) {
-                        callback(data.toString(encoding || "utf8"));
-                    } else {
-                        callback("");
-                    }
-                })
-            } else {
-                callback("");
-            }
-        },
-
-        /**
-         * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
-         *
-         * @param entry
-         */
-        deleteFile : function(/*Object*/entry) { // @TODO: test deleteFile
-            var item = getEntry(entry);
-            if (item) {
-                _zip.deleteEntry(item.entryName);
-            }
-        },
-
-        /**
-         * Adds a comment to the zip. The zip must be rewritten after adding the comment.
-         *
-         * @param comment
-         */
-        addZipComment : function(/*String*/comment) { // @TODO: test addZipComment
-            _zip.comment = comment;
-        },
-
-        /**
-         * Returns the zip comment
-         *
-         * @return String
-         */
-        getZipComment : function() {
-            return _zip.comment || '';
-        },
-
-        /**
-         * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
-         * The comment cannot exceed 65535 characters in length
-         *
-         * @param entry
-         * @param comment
-         */
-        addZipEntryComment : function(/*Object*/entry,/*String*/comment) {
-            var item = getEntry(entry);
-            if (item) {
-                item.comment = comment;
-            }
-        },
-
-        /**
-         * Returns the comment of the specified entry
-         *
-         * @param entry
-         * @return String
-         */
-        getZipEntryComment : function(/*Object*/entry) {
-            var item = getEntry(entry);
-            if (item) {
-                return item.comment || '';
-            }
-            return ''
-        },
-
-        /**
-         * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
-         *
-         * @param entry
-         * @param content
-         */
-        updateFile : function(/*Object*/entry, /*Buffer*/content) {
-            var item = getEntry(entry);
-            if (item) {
-                item.setData(content);
-            }
-        },
-
-        /**
-         * Adds a file from the disk to the archive
-         *
-         * @param localPath
-         */
-        addLocalFile : function(/*String*/localPath, /*String*/zipPath, /*String*/zipName) {
-             if (fs.existsSync(localPath)) {
-                if(zipPath){
-                    zipPath=zipPath.split("\\").join("/");
-                    if(zipPath.charAt(zipPath.length - 1) != "/"){
-                        zipPath += "/";
-                    }
-                }else{
-                    zipPath="";
-                }
-                 var p = localPath.split("\\").join("/").split("/").pop();
-                
-                 if(zipName){
-                    this.addFile(zipPath+zipName, fs.readFileSync(localPath), "", 0)
-                 }else{
-                    this.addFile(zipPath+p, fs.readFileSync(localPath), "", 0)
-                 }
-             } else {
-                 throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
-             }
-        },
-
-        /**
-         * Adds a local directory and all its nested files and directories to the archive
-         *
-         * @param localPath
-         * @param zipPath optional path inside zip
-         * @param filter optional RegExp or Function if files match will
-         *               be included.
-         */
-        addLocalFolder : function(/*String*/localPath, /*String*/zipPath, /*RegExp|Function*/filter) {
-            if (filter === undefined) {
-              filter = function() { return true; };
-            } else if (filter instanceof RegExp) {
-              filter = function(filter) {
-                return function(filename) {
-                  return filter.test(filename);
-                }
-              }(filter);
-            }
-
-            if(zipPath){
-                zipPath=zipPath.split("\\").join("/");
-                if(zipPath.charAt(zipPath.length - 1) != "/"){
-                    zipPath += "/";
-                }
-            }else{
-                zipPath="";
-            }
-			localPath = localPath.split("\\").join("/"); //windows fix
-            localPath = pth.normalize(localPath);
-            if (localPath.charAt(localPath.length - 1) != "/")
-                localPath += "/";
-
-            if (fs.existsSync(localPath)) {
-
-                var items = Utils.findFiles(localPath),
-                    self = this;
-
-                if (items.length) {
-                    items.forEach(function(path) {
-						var p = path.split("\\").join("/").replace( new RegExp(localPath, 'i'), ""); //windows fix
-                        if (filter(p)) {
-                            if (p.charAt(p.length - 1) !== "/") {
-                                self.addFile(zipPath+p, fs.readFileSync(path), "", 0)
-                            } else {
-                                self.addFile(zipPath+p, new Buffer(0), "", 0)
-                            }
-                        }
-                    });
-                }
-            } else {
-                throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
-            }
-        },
-
-        /**
-         * Allows you to create a entry (file or directory) in the zip file.
-         * If you want to create a directory the entryName must end in / and a null buffer should be provided.
-         * Comment and attributes are optional
-         *
-         * @param entryName
-         * @param content
-         * @param comment
-         * @param attr
-         */
-        addFile : function(/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) {
-            var entry = new ZipEntry();
-            entry.entryName = entryName;
-            entry.comment = comment || "";
-            entry.attr = attr || 438; //0666;
-            if (entry.isDirectory && content.length) {
-               // throw Utils.Errors.DIRECTORY_CONTENT_ERROR;
-            }
-            entry.setData(content);
-            _zip.setEntry(entry);
-        },
-
-        /**
-         * Returns an array of ZipEntry objects representing the files and folders inside the archive
-         *
-         * @return Array
-         */
-        getEntries : function() {
-            if (_zip) {
-               return _zip.entries;
-            } else {
-                return [];
-            }
-        },
-
-        /**
-         * Returns a ZipEntry object representing the file or folder specified by ``name``.
-         *
-         * @param name
-         * @return ZipEntry
-         */
-        getEntry : function(/*String*/name) {
-            return getEntry(name);
-        },
-
-        /**
-         * Extracts the given entry to the given targetPath
-         * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
-         *
-         * @param entry ZipEntry object or String with the full path of the entry
-         * @param targetPath Target folder where to write the file
-         * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
-         *                          will be created in targetPath as well. Default is TRUE
-         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
-         *                  Default is FALSE
-         *
-         * @return Boolean
-         */
-        extractEntryTo : function(/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) {
-            overwrite = overwrite || false;
-            maintainEntryPath = typeof maintainEntryPath == "undefined" ? true : maintainEntryPath;
-
-            var item = getEntry(entry);
-            if (!item) {
-                throw Utils.Errors.NO_ENTRY;
-            }
-
-            var target = pth.resolve(targetPath, maintainEntryPath ? item.entryName : pth.basename(item.entryName));
-
-            if (item.isDirectory) {
-                target = pth.resolve(target, "..");
-                var children = _zip.getEntryChildren(item);
-                children.forEach(function(child) {
-                    if (child.isDirectory) return;
-                    var content = child.getData();
-                    if (!content) {
-                        throw Utils.Errors.CANT_EXTRACT_FILE;
-                    }
-                    Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? child.entryName : child.entryName.substr(item.entryName.length)), content, overwrite);
-                });
-                return true;
-            }
-
-            var content = item.getData();
-            if (!content) throw Utils.Errors.CANT_EXTRACT_FILE;
-
-            if (fs.existsSync(target) && !overwrite) {
-                throw Utils.Errors.CANT_OVERRIDE;
-            }
-            Utils.writeFileTo(target, content, overwrite);
-
-            return true;
-        },
-
-        /**
-         * Extracts the entire archive to the given location
-         *
-         * @param targetPath Target location
-         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
-         *                  Default is FALSE
-         */
-        extractAllTo : function(/*String*/targetPath, /*Boolean*/overwrite) {
-            overwrite = overwrite || false;
-            if (!_zip) {
-                throw Utils.Errors.NO_ZIP;
-            }
-
-            _zip.entries.forEach(function(entry) {
-                if (entry.isDirectory) {
-                    Utils.makeDir(pth.resolve(targetPath, entry.entryName.toString()));
-                    return;
-                }
-                var content = entry.getData();
-                if (!content) {
-                    throw Utils.Errors.CANT_EXTRACT_FILE + "2";
-                }
-                Utils.writeFileTo(pth.resolve(targetPath, entry.entryName.toString()), content, overwrite);
-            })
-        },
-
-        /**
-         * Asynchronous extractAllTo
-         *
-         * @param targetPath Target location
-         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
-         *                  Default is FALSE
-         * @param callback
-         */
-        extractAllToAsync : function(/*String*/targetPath, /*Boolean*/overwrite, /*Function*/callback) {
-            overwrite = overwrite || false;
-            if (!_zip) {
-                callback(new Error(Utils.Errors.NO_ZIP));
-                return;
-            }
-
-            var entries = _zip.entries;
-            var i = entries.length; 
-            entries.forEach(function(entry) {
-                if(i <= 0) return; // Had an error already
-
-                if (entry.isDirectory) {
-                    Utils.makeDir(pth.resolve(targetPath, entry.entryName.toString()));
-                    if(--i == 0)
-                        callback(undefined);
-                    return;
-                }
-                entry.getDataAsync(function(content) {
-                    if(i <= 0) return;
-                    if (!content) {
-                        i = 0;
-                        callback(new Error(Utils.Errors.CANT_EXTRACT_FILE + "2"));
-                        return;
-                    }
-                    Utils.writeFileToAsync(pth.resolve(targetPath, entry.entryName.toString()), content, overwrite, function(succ) {
-                        if(i <= 0) return;
-
-                        if(!succ) {
-                            i = 0;
-                            callback(new Error('Unable to write'));
-                            return;
-                        }
-
-                        if(--i == 0)
-                            callback(undefined);
-                    });
-                    
-                });
-            })
-        },
-
-        /**
-         * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
-         *
-         * @param targetFileName
-         * @param callback
-         */
-        writeZip : function(/*String*/targetFileName, /*Function*/callback) {
-            if (arguments.length == 1) {
-                if (typeof targetFileName == "function") {
-                    callback = targetFileName;
-                    targetFileName = "";
-                }
-            }
-
-            if (!targetFileName && _filename) {
-                targetFileName = _filename;
-            }
-            if (!targetFileName) return;
-
-            var zipData = _zip.compressToBuffer();
-            if (zipData) {
-                var ok = Utils.writeFileTo(targetFileName, zipData, true);
-                if (typeof callback == 'function') callback(!ok? new Error("failed"): null, "");
-            }
-        },
-
-        /**
-         * Returns the content of the entire zip file as a Buffer object
-         *
-         * @return Buffer
-         */
-        toBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) {
-            this.valueOf = 2;
-            if (typeof onSuccess == "function") {
-                _zip.toAsyncBuffer(onSuccess,onFail,onItemStart,onItemEnd);
-                return null;
-            }
-            return _zip.compressToBuffer()
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/entryHeader.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/entryHeader.js
deleted file mode 100644
index 9a0e1bdf2..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/entryHeader.js
+++ /dev/null
@@ -1,261 +0,0 @@
-var Utils = require("../util"),
-    Constants = Utils.Constants;
-
-/* The central directory file header */
-module.exports = function () {
-    var _verMade = 0x0A,
-        _version = 0x0A,
-        _flags = 0,
-        _method = 0,
-        _time = 0,
-        _crc = 0,
-        _compressedSize = 0,
-        _size = 0,
-        _fnameLen = 0,
-        _extraLen = 0,
-
-        _comLen = 0,
-        _diskStart = 0,
-        _inattr = 0,
-        _attr = 0,
-        _offset = 0;
-
-    var _dataHeader = {};
-
-    function setTime(val) {
-        var val = new Date(val);
-        _time = (val.getFullYear() - 1980 & 0x7f) << 25  // b09-16 years from 1980
-            | (val.getMonth() + 1) << 21                 // b05-08 month
-            | val.getDay() << 16                         // b00-04 hour
-
-            // 2 bytes time
-            | val.getHours() << 11    // b11-15 hour
-            | val.getMinutes() << 5   // b05-10 minute
-            | val.getSeconds() >> 1;  // b00-04 seconds divided by 2
-    }
-
-    setTime(+new Date());
-
-    return {
-        get made () { return _verMade; },
-        set made (val) { _verMade = val; },
-
-        get version () { return _version; },
-        set version (val) { _version = val },
-
-        get flags () { return _flags },
-        set flags (val) { _flags = val; },
-
-        get method () { return _method; },
-        set method (val) { _method = val; },
-
-        get time () { return new Date(
-            ((_time >> 25) & 0x7f) + 1980,
-            ((_time >> 21) & 0x0f) - 1,
-            (_time >> 16) & 0x1f,
-            (_time >> 11) & 0x1f,
-            (_time >> 5) & 0x3f,
-            (_time & 0x1f) << 1
-        );
-        },
-        set time (val) {
-            setTime(val);
-        },
-
-        get crc () { return _crc; },
-        set crc (val) { _crc = val; },
-
-        get compressedSize () { return _compressedSize; },
-        set compressedSize (val) { _compressedSize = val; },
-
-        get size () { return _size; },
-        set size (val) { _size = val; },
-
-        get fileNameLength () { return _fnameLen; },
-        set fileNameLength (val) { _fnameLen = val; },
-
-        get extraLength () { return _extraLen },
-        set extraLength (val) { _extraLen = val; },
-
-        get commentLength () { return _comLen },
-        set commentLength (val) { _comLen = val },
-
-        get diskNumStart () { return _diskStart },
-        set diskNumStart (val) { _diskStart = val },
-
-        get inAttr () { return _inattr },
-        set inAttr (val) { _inattr = val },
-
-        get attr () { return _attr },
-        set attr (val) { _attr = val },
-
-        get offset () { return _offset },
-        set offset (val) { _offset = val },
-
-        get encripted () { return (_flags & 1) == 1 },
-
-        get entryHeaderSize () {
-            return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
-        },
-
-        get realDataOffset () {
-            return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
-        },
-
-        get dataHeader () {
-            return _dataHeader;
-        },
-
-        loadDataHeaderFromBinary : function(/*Buffer*/input) {
-            var data = input.slice(_offset, _offset + Constants.LOCHDR);
-            // 30 bytes and should start with "PK\003\004"
-            if (data.readUInt32LE(0) != Constants.LOCSIG) {
-                throw Utils.Errors.INVALID_LOC;
-            }
-            _dataHeader = {
-                // version needed to extract
-                version : data.readUInt16LE(Constants.LOCVER),
-                // general purpose bit flag
-                flags : data.readUInt16LE(Constants.LOCFLG),
-                // compression method
-                method : data.readUInt16LE(Constants.LOCHOW),
-                // modification time (2 bytes time, 2 bytes date)
-                time : data.readUInt32LE(Constants.LOCTIM),
-                // uncompressed file crc-32 value
-                crc : data.readUInt32LE(Constants.LOCCRC),
-                // compressed size
-                compressedSize : data.readUInt32LE(Constants.LOCSIZ),
-                // uncompressed size
-                size : data.readUInt32LE(Constants.LOCLEN),
-                // filename length
-                fnameLen : data.readUInt16LE(Constants.LOCNAM),
-                // extra field length
-                extraLen : data.readUInt16LE(Constants.LOCEXT)
-            }
-        },
-
-        loadFromBinary : function(/*Buffer*/data) {
-            // data should be 46 bytes and start with "PK 01 02"
-            if (data.length != Constants.CENHDR || data.readUInt32LE(0) != Constants.CENSIG) {
-                throw Utils.Errors.INVALID_CEN;
-            }
-            // version made by
-            _verMade = data.readUInt16LE(Constants.CENVEM);
-            // version needed to extract
-            _version = data.readUInt16LE(Constants.CENVER);
-            // encrypt, decrypt flags
-            _flags = data.readUInt16LE(Constants.CENFLG);
-            // compression method
-            _method = data.readUInt16LE(Constants.CENHOW);
-            // modification time (2 bytes time, 2 bytes date)
-            _time = data.readUInt32LE(Constants.CENTIM);
-            // uncompressed file crc-32 value
-            _crc = data.readUInt32LE(Constants.CENCRC);
-            // compressed size
-            _compressedSize = data.readUInt32LE(Constants.CENSIZ);
-            // uncompressed size
-            _size = data.readUInt32LE(Constants.CENLEN);
-            // filename length
-            _fnameLen = data.readUInt16LE(Constants.CENNAM);
-            // extra field length
-            _extraLen = data.readUInt16LE(Constants.CENEXT);
-            // file comment length
-            _comLen = data.readUInt16LE(Constants.CENCOM);
-            // volume number start
-            _diskStart = data.readUInt16LE(Constants.CENDSK);
-            // internal file attributes
-            _inattr = data.readUInt16LE(Constants.CENATT);
-            // external file attributes
-            _attr = data.readUInt32LE(Constants.CENATX);
-            // LOC header offset
-            _offset = data.readUInt32LE(Constants.CENOFF);
-        },
-
-        dataHeaderToBinary : function() {
-            // LOC header size (30 bytes)
-            var data = new Buffer(Constants.LOCHDR);
-            // "PK\003\004"
-            data.writeUInt32LE(Constants.LOCSIG, 0);
-            // version needed to extract
-            data.writeUInt16LE(_version, Constants.LOCVER);
-            // general purpose bit flag
-            data.writeUInt16LE(_flags, Constants.LOCFLG);
-            // compression method
-            data.writeUInt16LE(_method, Constants.LOCHOW);
-            // modification time (2 bytes time, 2 bytes date)
-            data.writeUInt32LE(_time, Constants.LOCTIM);
-            // uncompressed file crc-32 value
-            data.writeUInt32LE(_crc, Constants.LOCCRC);
-            // compressed size
-            data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
-            // uncompressed size
-            data.writeUInt32LE(_size, Constants.LOCLEN);
-            // filename length
-            data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
-            // extra field length
-            data.writeUInt16LE(_extraLen, Constants.LOCEXT);
-            return data;
-        },
-
-        entryHeaderToBinary : function() {
-            // CEN header size (46 bytes)
-            var data = new Buffer(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
-            // "PK\001\002"
-            data.writeUInt32LE(Constants.CENSIG, 0);
-            // version made by
-            data.writeUInt16LE(_verMade, Constants.CENVEM);
-            // version needed to extract
-            data.writeUInt16LE(_version, Constants.CENVER);
-            // encrypt, decrypt flags
-            data.writeUInt16LE(_flags, Constants.CENFLG);
-            // compression method
-            data.writeUInt16LE(_method, Constants.CENHOW);
-            // modification time (2 bytes time, 2 bytes date)
-            data.writeUInt32LE(_time, Constants.CENTIM);
-            // uncompressed file crc-32 value
-            data.writeInt32LE(_crc, Constants.CENCRC, true);
-            // compressed size
-            data.writeUInt32LE(_compressedSize, Constants.CENSIZ);
-            // uncompressed size
-            data.writeUInt32LE(_size, Constants.CENLEN);
-            // filename length
-            data.writeUInt16LE(_fnameLen, Constants.CENNAM);
-            // extra field length
-            data.writeUInt16LE(_extraLen, Constants.CENEXT);
-            // file comment length
-            data.writeUInt16LE(_comLen, Constants.CENCOM);
-            // volume number start
-            data.writeUInt16LE(_diskStart, Constants.CENDSK);
-            // internal file attributes
-            data.writeUInt16LE(_inattr, Constants.CENATT);
-            // external file attributes
-            data.writeUInt32LE(_attr, Constants.CENATX);
-            // LOC header offset
-            data.writeUInt32LE(_offset, Constants.CENOFF);
-            // fill all with
-            data.fill(0x00, Constants.CENHDR);
-            return data;
-        },
-
-        toString : function() {
-            return '{\n' +
-                '\t"made" : ' + _verMade + ",\n" +
-                '\t"version" : ' + _version + ",\n" +
-                '\t"flags" : ' + _flags + ",\n" +
-                '\t"method" : ' + Utils.methodToString(_method) + ",\n" +
-                '\t"time" : ' + _time + ",\n" +
-                '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" +
-                '\t"compressedSize" : ' + _compressedSize + " bytes,\n" +
-                '\t"size" : ' + _size + " bytes,\n" +
-                '\t"fileNameLength" : ' + _fnameLen + ",\n" +
-                '\t"extraLength" : ' + _extraLen + " bytes,\n" +
-                '\t"commentLength" : ' + _comLen + " bytes,\n" +
-                '\t"diskNumStart" : ' + _diskStart + ",\n" +
-                '\t"inAttr" : ' + _inattr + ",\n" +
-                '\t"attr" : ' + _attr + ",\n" +
-                '\t"offset" : ' + _offset + ",\n" +
-                '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" +
-                '}';
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/index.js
deleted file mode 100644
index b54a7222f..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-exports.EntryHeader = require("./entryHeader");
-exports.MainHeader = require("./mainHeader");
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/mainHeader.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/mainHeader.js
deleted file mode 100644
index de8ae1a96..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/headers/mainHeader.js
+++ /dev/null
@@ -1,80 +0,0 @@
-var Utils = require("../util"),
-    Constants = Utils.Constants;
-
-/* The entries in the end of central directory */
-module.exports = function () {
-    var _volumeEntries = 0,
-        _totalEntries = 0,
-        _size = 0,
-        _offset = 0,
-        _commentLength = 0;
-
-    return {
-        get diskEntries () { return _volumeEntries },
-        set diskEntries (/*Number*/val) { _volumeEntries = _totalEntries = val; },
-
-        get totalEntries () { return _totalEntries },
-        set totalEntries (/*Number*/val) { _totalEntries = _volumeEntries = val; },
-
-        get size () { return _size },
-        set size (/*Number*/val) { _size = val; },
-
-        get offset () { return _offset },
-        set offset (/*Number*/val) { _offset = val; },
-
-        get commentLength () { return _commentLength },
-        set commentLength (/*Number*/val) { _commentLength = val; },
-
-        get mainHeaderSize () {
-            return Constants.ENDHDR + _commentLength;
-        },
-
-        loadFromBinary : function(/*Buffer*/data) {
-            // data should be 22 bytes and start with "PK 05 06"
-            if (data.length != Constants.ENDHDR || data.readUInt32LE(0) != Constants.ENDSIG)
-                throw Utils.Errors.INVALID_END;
-
-            // number of entries on this volume
-            _volumeEntries = data.readUInt16LE(Constants.ENDSUB);
-            // total number of entries
-            _totalEntries = data.readUInt16LE(Constants.ENDTOT);
-            // central directory size in bytes
-            _size = data.readUInt32LE(Constants.ENDSIZ);
-            // offset of first CEN header
-            _offset = data.readUInt32LE(Constants.ENDOFF);
-            // zip file comment length
-            _commentLength = data.readUInt16LE(Constants.ENDCOM);
-        },
-
-        toBinary : function() {
-           var b = new Buffer(Constants.ENDHDR + _commentLength);
-            // "PK 05 06" signature
-            b.writeUInt32LE(Constants.ENDSIG, 0);
-            b.writeUInt32LE(0, 4);
-            // number of entries on this volume
-            b.writeUInt16LE(_volumeEntries, Constants.ENDSUB);
-            // total number of entries
-            b.writeUInt16LE(_totalEntries, Constants.ENDTOT);
-            // central directory size in bytes
-            b.writeUInt32LE(_size, Constants.ENDSIZ);
-            // offset of first CEN header
-            b.writeUInt32LE(_offset, Constants.ENDOFF);
-            // zip file comment length
-            b.writeUInt16LE(_commentLength, Constants.ENDCOM);
-            // fill comment memory with spaces so no garbage is left there
-            b.fill(" ", Constants.ENDHDR);
-
-            return b;
-        },
-
-        toString : function() {
-            return '{\n' +
-                '\t"diskEntries" : ' + _volumeEntries + ",\n" +
-                '\t"totalEntries" : ' + _totalEntries + ",\n" +
-                '\t"size" : ' + _size + " bytes,\n" +
-                '\t"offset" : 0x' + _offset.toString(16).toUpperCase() + ",\n" +
-                '\t"commentLength" : 0x' + _commentLength + "\n" +
-            '}';
-        }
-    }
-};
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/deflater.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/deflater.js
deleted file mode 100644
index 34ef297fc..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/deflater.js
+++ /dev/null
@@ -1,1578 +0,0 @@
-/*
- * $Id: rawdeflate.js,v 0.5 2013/04/09 14:25:38 dankogai Exp dankogai $
- *
- * GNU General Public License, version 2 (GPL-2.0)
- *   http://opensource.org/licenses/GPL-2.0
- * Original:
- *  http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt
- */
-function JSDeflater(/*inbuff*/inbuf) {
-
-    /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
-     * Version: 1.0.1
-     * LastModified: Dec 25 1999
-     */
-
-    var WSIZE = 32768,		// Sliding Window size
-        zip_STORED_BLOCK = 0,
-        zip_STATIC_TREES = 1,
-        zip_DYN_TREES = 2,
-        zip_DEFAULT_LEVEL = 6,
-        zip_FULL_SEARCH = true,
-        zip_INBUFSIZ = 32768,	// Input buffer size
-        zip_INBUF_EXTRA = 64,	// Extra buffer
-        zip_OUTBUFSIZ = 1024 * 8,
-        zip_window_size = 2 * WSIZE,
-        MIN_MATCH = 3,
-        MAX_MATCH = 258,
-        zip_BITS = 16,
-        LIT_BUFSIZE = 0x2000,
-        zip_HASH_BITS = 13,
-        zip_DIST_BUFSIZE = LIT_BUFSIZE,
-        zip_HASH_SIZE = 1 << zip_HASH_BITS,
-        zip_HASH_MASK = zip_HASH_SIZE - 1,
-        zip_WMASK = WSIZE - 1,
-        zip_NIL = 0, // Tail of hash chains
-        zip_TOO_FAR = 4096,
-        zip_MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1,
-        zip_MAX_DIST = WSIZE - zip_MIN_LOOKAHEAD,
-        zip_SMALLEST = 1,
-        zip_MAX_BITS = 15,
-        zip_MAX_BL_BITS = 7,
-        zip_LENGTH_CODES = 29,
-        zip_LITERALS = 256,
-        zip_END_BLOCK = 256,
-        zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES,
-        zip_D_CODES = 30,
-        zip_BL_CODES = 19,
-        zip_REP_3_6 = 16,
-        zip_REPZ_3_10 = 17,
-        zip_REPZ_11_138 = 18,
-        zip_HEAP_SIZE = 2 * zip_L_CODES + 1,
-        zip_H_SHIFT = parseInt((zip_HASH_BITS + MIN_MATCH - 1) / MIN_MATCH);
-
-    var zip_free_queue, zip_qhead, zip_qtail, zip_initflag, zip_outbuf = null, zip_outcnt, zip_outoff, zip_complete,
-        zip_window, zip_d_buf, zip_l_buf, zip_prev, zip_bi_buf, zip_bi_valid, zip_block_start, zip_ins_h, zip_hash_head,
-        zip_prev_match, zip_match_available, zip_match_length, zip_prev_length, zip_strstart, zip_match_start, zip_eofile,
-        zip_lookahead, zip_max_chain_length, zip_max_lazy_match, zip_compr_level, zip_good_match, zip_nice_match,
-        zip_dyn_ltree, zip_dyn_dtree, zip_static_ltree, zip_static_dtree, zip_bl_tree, zip_l_desc, zip_d_desc, zip_bl_desc,
-        zip_bl_count, zip_heap, zip_heap_len, zip_heap_max, zip_depth, zip_length_code, zip_dist_code, zip_base_length,
-        zip_base_dist, zip_flag_buf, zip_last_lit, zip_last_dist, zip_last_flags, zip_flags, zip_flag_bit, zip_opt_len,
-        zip_static_len, zip_deflate_data, zip_deflate_pos;
-
-    var zip_DeflateCT = function () {
-        this.fc = 0; // frequency count or bit string
-        this.dl = 0; // father node in Huffman tree or length of bit string
-    };
-
-    var zip_DeflateTreeDesc = function () {
-        this.dyn_tree = null;	// the dynamic tree
-        this.static_tree = null;	// corresponding static tree or NULL
-        this.extra_bits = null;	// extra bits for each code or NULL
-        this.extra_base = 0;	// base index for extra_bits
-        this.elems = 0;		// max number of elements in the tree
-        this.max_length = 0;	// max bit length for the codes
-        this.max_code = 0;		// largest code with non zero frequency
-    };
-
-    /* Values for max_lazy_match, good_match and max_chain_length, depending on
-     * the desired pack level (0..9). The values given below have been tuned to
-     * exclude worst case performance for pathological files. Better values may be
-     * found for specific files.
-     */
-    var zip_DeflateConfiguration = function (a, b, c, d) {
-        this.good_length = a; // reduce lazy search above this match length
-        this.max_lazy = b;    // do not perform lazy search above this match length
-        this.nice_length = c; // quit search above this match length
-        this.max_chain = d;
-    };
-
-    var zip_DeflateBuffer = function () {
-        this.next = null;
-        this.len = 0;
-        this.ptr = new Array(zip_OUTBUFSIZ);
-        this.off = 0;
-    };
-
-    /* constant tables */
-    var zip_extra_lbits = new Array(
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0);
-    var zip_extra_dbits = new Array(
-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13);
-    var zip_extra_blbits = new Array(
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7);
-    var zip_bl_order = new Array(
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
-    var zip_configuration_table = new Array(
-        new zip_DeflateConfiguration(0, 0, 0, 0),
-        new zip_DeflateConfiguration(4, 4, 8, 4),
-        new zip_DeflateConfiguration(4, 5, 16, 8),
-        new zip_DeflateConfiguration(4, 6, 32, 32),
-        new zip_DeflateConfiguration(4, 4, 16, 16),
-        new zip_DeflateConfiguration(8, 16, 32, 32),
-        new zip_DeflateConfiguration(8, 16, 128, 128),
-        new zip_DeflateConfiguration(8, 32, 128, 256),
-        new zip_DeflateConfiguration(32, 128, 258, 1024),
-        new zip_DeflateConfiguration(32, 258, 258, 4096));
-
-
-    /* routines (deflate) */
-
-    var zip_deflate_start = function (level) {
-        var i;
-
-        if (!level)
-            level = zip_DEFAULT_LEVEL;
-        else if (level < 1)
-            level = 1;
-        else if (level > 9)
-            level = 9;
-
-        zip_compr_level = level;
-        zip_initflag = false;
-        zip_eofile = false;
-        if (zip_outbuf != null)
-            return;
-
-        zip_free_queue = zip_qhead = zip_qtail = null;
-        zip_outbuf = new Array(zip_OUTBUFSIZ);
-        zip_window = new Array(zip_window_size);
-        zip_d_buf = new Array(zip_DIST_BUFSIZE);
-        zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA);
-        zip_prev = new Array(1 << zip_BITS);
-        zip_dyn_ltree = new Array(zip_HEAP_SIZE);
-        for (i = 0; i < zip_HEAP_SIZE; i++) zip_dyn_ltree[i] = new zip_DeflateCT();
-        zip_dyn_dtree = new Array(2 * zip_D_CODES + 1);
-        for (i = 0; i < 2 * zip_D_CODES + 1; i++) zip_dyn_dtree[i] = new zip_DeflateCT();
-        zip_static_ltree = new Array(zip_L_CODES + 2);
-        for (i = 0; i < zip_L_CODES + 2; i++) zip_static_ltree[i] = new zip_DeflateCT();
-        zip_static_dtree = new Array(zip_D_CODES);
-        for (i = 0; i < zip_D_CODES; i++) zip_static_dtree[i] = new zip_DeflateCT();
-        zip_bl_tree = new Array(2 * zip_BL_CODES + 1);
-        for (i = 0; i < 2 * zip_BL_CODES + 1; i++) zip_bl_tree[i] = new zip_DeflateCT();
-        zip_l_desc = new zip_DeflateTreeDesc();
-        zip_d_desc = new zip_DeflateTreeDesc();
-        zip_bl_desc = new zip_DeflateTreeDesc();
-        zip_bl_count = new Array(zip_MAX_BITS + 1);
-        zip_heap = new Array(2 * zip_L_CODES + 1);
-        zip_depth = new Array(2 * zip_L_CODES + 1);
-        zip_length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
-        zip_dist_code = new Array(512);
-        zip_base_length = new Array(zip_LENGTH_CODES);
-        zip_base_dist = new Array(zip_D_CODES);
-        zip_flag_buf = new Array(parseInt(LIT_BUFSIZE / 8));
-    };
-
-    var zip_deflate_end = function () {
-        zip_free_queue = zip_qhead = zip_qtail = null;
-        zip_outbuf = null;
-        zip_window = null;
-        zip_d_buf = null;
-        zip_l_buf = null;
-        zip_prev = null;
-        zip_dyn_ltree = null;
-        zip_dyn_dtree = null;
-        zip_static_ltree = null;
-        zip_static_dtree = null;
-        zip_bl_tree = null;
-        zip_l_desc = null;
-        zip_d_desc = null;
-        zip_bl_desc = null;
-        zip_bl_count = null;
-        zip_heap = null;
-        zip_depth = null;
-        zip_length_code = null;
-        zip_dist_code = null;
-        zip_base_length = null;
-        zip_base_dist = null;
-        zip_flag_buf = null;
-    };
-
-    var zip_reuse_queue = function (p) {
-        p.next = zip_free_queue;
-        zip_free_queue = p;
-    };
-
-    var zip_new_queue = function () {
-        var p;
-
-        if (zip_free_queue != null) {
-            p = zip_free_queue;
-            zip_free_queue = zip_free_queue.next;
-        }
-        else
-            p = new zip_DeflateBuffer();
-        p.next = null;
-        p.len = p.off = 0;
-
-        return p;
-    };
-
-    var zip_head1 = function (i) {
-        return zip_prev[WSIZE + i];
-    };
-
-    var zip_head2 = function (i, val) {
-        return zip_prev[WSIZE + i] = val;
-    };
-
-    /* put_byte is used for the compressed output, put_ubyte for the
-     * uncompressed output. However unlzw() uses window for its
-     * suffix table instead of its output buffer, so it does not use put_ubyte
-     * (to be cleaned up).
-     */
-    var zip_put_byte = function (c) {
-        zip_outbuf[zip_outoff + zip_outcnt++] = c;
-        if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ)
-            zip_qoutbuf();
-    };
-
-    /* Output a 16 bit value, lsb first */
-    var zip_put_short = function (w) {
-        w &= 0xffff;
-        if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) {
-            zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff);
-            zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8);
-        } else {
-            zip_put_byte(w & 0xff);
-            zip_put_byte(w >>> 8);
-        }
-    };
-
-    /* ==========================================================================
-     * Insert string s in the dictionary and set match_head to the previous head
-     * of the hash chain (the most recent string with same hash key). Return
-     * the previous length of the hash chain.
-     * IN  assertion: all calls to to INSERT_STRING are made with consecutive
-     *    input characters and the first MIN_MATCH bytes of s are valid
-     *    (except for the last MIN_MATCH-1 bytes of the input file).
-     */
-    var zip_INSERT_STRING = function () {
-        zip_ins_h = ((zip_ins_h << zip_H_SHIFT)
-            ^ (zip_window[zip_strstart + MIN_MATCH - 1] & 0xff))
-            & zip_HASH_MASK;
-        zip_hash_head = zip_head1(zip_ins_h);
-        zip_prev[zip_strstart & zip_WMASK] = zip_hash_head;
-        zip_head2(zip_ins_h, zip_strstart);
-    };
-
-    /* Send a code of the given tree. c and tree must not have side effects */
-    var zip_SEND_CODE = function (c, tree) {
-        zip_send_bits(tree[c].fc, tree[c].dl);
-    };
-
-    /* Mapping from a distance to a distance code. dist is the distance - 1 and
-     * must not have side effects. dist_code[256] and dist_code[257] are never
-     * used.
-     */
-    var zip_D_CODE = function (dist) {
-        return (dist < 256 ? zip_dist_code[dist]
-            : zip_dist_code[256 + (dist >> 7)]) & 0xff;
-    };
-
-    /* ==========================================================================
-     * Compares to subtrees, using the tree depth as tie breaker when
-     * the subtrees have equal frequency. This minimizes the worst case length.
-     */
-    var zip_SMALLER = function (tree, n, m) {
-        return tree[n].fc < tree[m].fc ||
-            (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]);
-    };
-
-    /* ==========================================================================
-     * read string data
-     */
-    var zip_read_buff = function (buff, offset, n) {
-        var i;
-        for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++)
-            buff[offset + i] =
-                zip_deflate_data[zip_deflate_pos++] & 0xff;
-        return i;
-    };
-
-    /* ==========================================================================
-     * Initialize the "longest match" routines for a new file
-     */
-    var zip_lm_init = function () {
-        var j;
-
-        /* Initialize the hash table. */
-        for (j = 0; j < zip_HASH_SIZE; j++)
-            zip_prev[WSIZE + j] = 0;
-        zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy;
-        zip_good_match = zip_configuration_table[zip_compr_level].good_length;
-        if (!zip_FULL_SEARCH)
-            zip_nice_match = zip_configuration_table[zip_compr_level].nice_length;
-        zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain;
-
-        zip_strstart = 0;
-        zip_block_start = 0;
-
-        zip_lookahead = zip_read_buff(zip_window, 0, 2 * WSIZE);
-        if (zip_lookahead <= 0) {
-            zip_eofile = true;
-            zip_lookahead = 0;
-            return;
-        }
-        zip_eofile = false;
-        /* Make sure that we always have enough lookahead. This is important
-         * if input comes from a device such as a tty.
-         */
-        while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
-            zip_fill_window();
-
-        /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
-         * not important since only literal bytes will be emitted.
-         */
-        zip_ins_h = 0;
-        for (j = 0; j < MIN_MATCH - 1; j++) {
-            zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK;
-        }
-    };
-
-    /* ==========================================================================
-     * Set match_start to the longest match starting at the given string and
-     * return its length. Matches shorter or equal to prev_length are discarded,
-     * in which case the result is equal to prev_length and match_start is
-     * garbage.
-     * IN assertions: cur_match is the head of the hash chain for the current
-     *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
-     */
-    var zip_longest_match = function (cur_match) {
-        var chain_length = zip_max_chain_length; // max hash chain length
-        var scanp = zip_strstart; // current string
-        var matchp;		// matched string
-        var len;		// length of current match
-        var best_len = zip_prev_length;	// best match length so far
-
-        /* Stop when cur_match becomes <= limit. To simplify the code,
-         * we prevent matches with the string of window index 0.
-         */
-        var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL);
-
-        var strendp = zip_strstart + MAX_MATCH;
-        var scan_end1 = zip_window[scanp + best_len - 1];
-        var scan_end = zip_window[scanp + best_len];
-
-        /* Do not waste too much time if we already have a good match: */
-        if (zip_prev_length >= zip_good_match)
-            chain_length >>= 2;
-
-        do {
-            matchp = cur_match;
-
-            /* Skip to next match if the match length cannot increase
-             * or if the match length is less than 2:
-             */
-            if (zip_window[matchp + best_len] != scan_end ||
-                zip_window[matchp + best_len - 1] != scan_end1 ||
-                zip_window[matchp] != zip_window[scanp] ||
-                zip_window[++matchp] != zip_window[scanp + 1]) {
-                continue;
-            }
-
-            /* The check at best_len-1 can be removed because it will be made
-             * again later. (This heuristic is not always a win.)
-             * It is not necessary to compare scan[2] and match[2] since they
-             * are always equal when the other bytes match, given that
-             * the hash keys are equal and that HASH_BITS >= 8.
-             */
-            scanp += 2;
-            matchp++;
-
-            /* We check for insufficient lookahead only every 8th comparison;
-             * the 256th check will be made at strstart+258.
-             */
-            do {
-            } while (zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                zip_window[++scanp] == zip_window[++matchp] &&
-                scanp < strendp);
-
-            len = MAX_MATCH - (strendp - scanp);
-            scanp = strendp - MAX_MATCH;
-
-            if (len > best_len) {
-                zip_match_start = cur_match;
-                best_len = len;
-                if (zip_FULL_SEARCH) {
-                    if (len >= MAX_MATCH) break;
-                } else {
-                    if (len >= zip_nice_match) break;
-                }
-
-                scan_end1 = zip_window[scanp + best_len - 1];
-                scan_end = zip_window[scanp + best_len];
-            }
-        } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit
-            && --chain_length != 0);
-
-        return best_len;
-    };
-
-    /* ==========================================================================
-     * Fill the window when the lookahead becomes insufficient.
-     * Updates strstart and lookahead, and sets eofile if end of input file.
-     * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
-     * OUT assertions: at least one byte has been read, or eofile is set;
-     *    file reads are performed for at least two bytes (required for the
-     *    translate_eol option).
-     */
-    var zip_fill_window = function () {
-        var n, m;
-
-        // Amount of free space at the end of the window.
-        var more = zip_window_size - zip_lookahead - zip_strstart;
-
-        /* If the window is almost full and there is insufficient lookahead,
-         * move the upper half to the lower one to make room in the upper half.
-         */
-        if (more == -1) {
-            /* Very unlikely, but possible on 16 bit machine if strstart == 0
-             * and lookahead == 1 (input done one byte at time)
-             */
-            more--;
-        } else if (zip_strstart >= WSIZE + zip_MAX_DIST) {
-            /* By the IN assertion, the window is not empty so we can't confuse
-             * more == 0 with more == 64K on a 16 bit machine.
-             */
-            for (n = 0; n < WSIZE; n++)
-                zip_window[n] = zip_window[n + WSIZE];
-
-            zip_match_start -= WSIZE;
-            zip_strstart -= WSIZE;
-            /* we now have strstart >= MAX_DIST: */
-            zip_block_start -= WSIZE;
-
-            for (n = 0; n < zip_HASH_SIZE; n++) {
-                m = zip_head1(n);
-                zip_head2(n, m >= WSIZE ? m - WSIZE : zip_NIL);
-            }
-            for (n = 0; n < WSIZE; n++) {
-                /* If n is not on any hash chain, prev[n] is garbage but
-                 * its value will never be used.
-                 */
-                m = zip_prev[n];
-                zip_prev[n] = (m >= WSIZE ? m - WSIZE : zip_NIL);
-            }
-            more += WSIZE;
-        }
-        // At this point, more >= 2
-        if (!zip_eofile) {
-            n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more);
-            if (n <= 0)
-                zip_eofile = true;
-            else
-                zip_lookahead += n;
-        }
-    };
-
-    /* ==========================================================================
-     * Processes a new input file and return its compressed length. This
-     * function does not perform lazy evaluationof matches and inserts
-     * new strings in the dictionary only for unmatched strings or for short
-     * matches. It is used only for the fast compression options.
-     */
-    var zip_deflate_fast = function () {
-        while (zip_lookahead != 0 && zip_qhead == null) {
-            var flush; // set if current block must be flushed
-
-            /* Insert the string window[strstart .. strstart+2] in the
-             * dictionary, and set hash_head to the head of the hash chain:
-             */
-            zip_INSERT_STRING();
-
-            /* Find the longest match, discarding those <= prev_length.
-             * At this point we have always match_length < MIN_MATCH
-             */
-            if (zip_hash_head != zip_NIL &&
-                zip_strstart - zip_hash_head <= zip_MAX_DIST) {
-                /* To simplify the code, we prevent matches with the string
-                 * of window index 0 (in particular we have to avoid a match
-                 * of the string with itself at the start of the input file).
-                 */
-                zip_match_length = zip_longest_match(zip_hash_head);
-                /* longest_match() sets match_start */
-                if (zip_match_length > zip_lookahead)
-                    zip_match_length = zip_lookahead;
-            }
-            if (zip_match_length >= MIN_MATCH) {
-                flush = zip_ct_tally(zip_strstart - zip_match_start,
-                    zip_match_length - MIN_MATCH);
-                zip_lookahead -= zip_match_length;
-
-                /* Insert new strings in the hash table only if the match length
-                 * is not too large. This saves time but degrades compression.
-                 */
-                if (zip_match_length <= zip_max_lazy_match) {
-                    zip_match_length--; // string at strstart already in hash table
-                    do {
-                        zip_strstart++;
-                        zip_INSERT_STRING();
-                        /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                         * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
-                         * these bytes are garbage, but it does not matter since
-                         * the next lookahead bytes will be emitted as literals.
-                         */
-                    } while (--zip_match_length != 0);
-                    zip_strstart++;
-                } else {
-                    zip_strstart += zip_match_length;
-                    zip_match_length = 0;
-                    zip_ins_h = zip_window[zip_strstart] & 0xff;
-                    zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK;
-                }
-            } else {
-                /* No match, output a literal byte */
-                flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff);
-                zip_lookahead--;
-                zip_strstart++;
-            }
-            if (flush) {
-                zip_flush_block(0);
-                zip_block_start = zip_strstart;
-            }
-
-            /* Make sure that we always have enough lookahead, except
-             * at the end of the input file. We need MAX_MATCH bytes
-             * for the next match, plus MIN_MATCH bytes to insert the
-             * string following the next match.
-             */
-            while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
-                zip_fill_window();
-        }
-    };
-
-    var zip_deflate_better = function () {
-        /* Process the input block. */
-        while (zip_lookahead != 0 && zip_qhead == null) {
-            /* Insert the string window[strstart .. strstart+2] in the
-             * dictionary, and set hash_head to the head of the hash chain:
-             */
-            zip_INSERT_STRING();
-
-            /* Find the longest match, discarding those <= prev_length.
-             */
-            zip_prev_length = zip_match_length;
-            zip_prev_match = zip_match_start;
-            zip_match_length = MIN_MATCH - 1;
-
-            if (zip_hash_head != zip_NIL &&
-                zip_prev_length < zip_max_lazy_match &&
-                zip_strstart - zip_hash_head <= zip_MAX_DIST) {
-                /* To simplify the code, we prevent matches with the string
-                 * of window index 0 (in particular we have to avoid a match
-                 * of the string with itself at the start of the input file).
-                 */
-                zip_match_length = zip_longest_match(zip_hash_head);
-                /* longest_match() sets match_start */
-                if (zip_match_length > zip_lookahead)
-                    zip_match_length = zip_lookahead;
-
-                /* Ignore a length 3 match if it is too distant: */
-                if (zip_match_length == MIN_MATCH &&
-                    zip_strstart - zip_match_start > zip_TOO_FAR) {
-                    /* If prev_match is also MIN_MATCH, match_start is garbage
-                     * but we will ignore the current match anyway.
-                     */
-                    zip_match_length--;
-                }
-            }
-            /* If there was a match at the previous step and the current
-             * match is not better, output the previous match:
-             */
-            if (zip_prev_length >= MIN_MATCH &&
-                zip_match_length <= zip_prev_length) {
-                var flush; // set if current block must be flushed
-                flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match,
-                    zip_prev_length - MIN_MATCH);
-
-                /* Insert in hash table all strings up to the end of the match.
-                 * strstart-1 and strstart are already inserted.
-                 */
-                zip_lookahead -= zip_prev_length - 1;
-                zip_prev_length -= 2;
-                do {
-                    zip_strstart++;
-                    zip_INSERT_STRING();
-                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                     * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
-                     * these bytes are garbage, but it does not matter since the
-                     * next lookahead bytes will always be emitted as literals.
-                     */
-                } while (--zip_prev_length != 0);
-                zip_match_available = 0;
-                zip_match_length = MIN_MATCH - 1;
-                zip_strstart++;
-                if (flush) {
-                    zip_flush_block(0);
-                    zip_block_start = zip_strstart;
-                }
-            } else if (zip_match_available != 0) {
-                /* If there was no match at the previous position, output a
-                 * single literal. If there was a match but the current match
-                 * is longer, truncate the previous match to a single literal.
-                 */
-                if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) {
-                    zip_flush_block(0);
-                    zip_block_start = zip_strstart;
-                }
-                zip_strstart++;
-                zip_lookahead--;
-            } else {
-                /* There is no previous match to compare with, wait for
-                 * the next step to decide.
-                 */
-                zip_match_available = 1;
-                zip_strstart++;
-                zip_lookahead--;
-            }
-
-            /* Make sure that we always have enough lookahead, except
-             * at the end of the input file. We need MAX_MATCH bytes
-             * for the next match, plus MIN_MATCH bytes to insert the
-             * string following the next match.
-             */
-            while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
-                zip_fill_window();
-        }
-    };
-
-    var zip_init_deflate = function () {
-        if (zip_eofile)
-            return;
-        zip_bi_buf = 0;
-        zip_bi_valid = 0;
-        zip_ct_init();
-        zip_lm_init();
-
-        zip_qhead = null;
-        zip_outcnt = 0;
-        zip_outoff = 0;
-        zip_match_available = 0;
-
-        if (zip_compr_level <= 3) {
-            zip_prev_length = MIN_MATCH - 1;
-            zip_match_length = 0;
-        }
-        else {
-            zip_match_length = MIN_MATCH - 1;
-            zip_match_available = 0;
-            zip_match_available = 0;
-        }
-
-        zip_complete = false;
-    };
-
-    /* ==========================================================================
-     * Same as above, but achieves better compression. We use a lazy
-     * evaluation for matches: a match is finally adopted only if there is
-     * no better match at the next window position.
-     */
-    var zip_deflate_internal = function (buff, off, buff_size) {
-        var n;
-
-        if (!zip_initflag) {
-            zip_init_deflate();
-            zip_initflag = true;
-            if (zip_lookahead == 0) { // empty
-                zip_complete = true;
-                return 0;
-            }
-        }
-
-        if ((n = zip_qcopy(buff, off, buff_size)) == buff_size)
-            return buff_size;
-
-        if (zip_complete)
-            return n;
-
-        if (zip_compr_level <= 3) // optimized for speed
-            zip_deflate_fast();
-        else
-            zip_deflate_better();
-        if (zip_lookahead == 0) {
-            if (zip_match_available != 0)
-                zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff);
-            zip_flush_block(1);
-            zip_complete = true;
-        }
-        return n + zip_qcopy(buff, n + off, buff_size - n);
-    };
-
-    var zip_qcopy = function (buff, off, buff_size) {
-        var n, i, j;
-
-        n = 0;
-        while (zip_qhead != null && n < buff_size) {
-            i = buff_size - n;
-            if (i > zip_qhead.len)
-                i = zip_qhead.len;
-            for (j = 0; j < i; j++)
-                buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j];
-
-            zip_qhead.off += i;
-            zip_qhead.len -= i;
-            n += i;
-            if (zip_qhead.len == 0) {
-                var p;
-                p = zip_qhead;
-                zip_qhead = zip_qhead.next;
-                zip_reuse_queue(p);
-            }
-        }
-
-        if (n == buff_size)
-            return n;
-
-        if (zip_outoff < zip_outcnt) {
-            i = buff_size - n;
-            if (i > zip_outcnt - zip_outoff)
-                i = zip_outcnt - zip_outoff;
-            // System.arraycopy(outbuf, outoff, buff, off + n, i);
-            for (j = 0; j < i; j++)
-                buff[off + n + j] = zip_outbuf[zip_outoff + j];
-            zip_outoff += i;
-            n += i;
-            if (zip_outcnt == zip_outoff)
-                zip_outcnt = zip_outoff = 0;
-        }
-        return n;
-    };
-
-    /* ==========================================================================
-     * Allocate the match buffer, initialize the various tables and save the
-     * location of the internal file attribute (ascii/binary) and method
-     * (DEFLATE/STORE).
-     */
-    var zip_ct_init = function () {
-        var n;	// iterates over tree elements
-        var bits;	// bit counter
-        var length;	// length value
-        var code;	// code value
-        var dist;	// distance index
-
-        if (zip_static_dtree[0].dl != 0) return; // ct_init already called
-
-        zip_l_desc.dyn_tree = zip_dyn_ltree;
-        zip_l_desc.static_tree = zip_static_ltree;
-        zip_l_desc.extra_bits = zip_extra_lbits;
-        zip_l_desc.extra_base = zip_LITERALS + 1;
-        zip_l_desc.elems = zip_L_CODES;
-        zip_l_desc.max_length = zip_MAX_BITS;
-        zip_l_desc.max_code = 0;
-
-        zip_d_desc.dyn_tree = zip_dyn_dtree;
-        zip_d_desc.static_tree = zip_static_dtree;
-        zip_d_desc.extra_bits = zip_extra_dbits;
-        zip_d_desc.extra_base = 0;
-        zip_d_desc.elems = zip_D_CODES;
-        zip_d_desc.max_length = zip_MAX_BITS;
-        zip_d_desc.max_code = 0;
-
-        zip_bl_desc.dyn_tree = zip_bl_tree;
-        zip_bl_desc.static_tree = null;
-        zip_bl_desc.extra_bits = zip_extra_blbits;
-        zip_bl_desc.extra_base = 0;
-        zip_bl_desc.elems = zip_BL_CODES;
-        zip_bl_desc.max_length = zip_MAX_BL_BITS;
-        zip_bl_desc.max_code = 0;
-
-        // Initialize the mapping length (0..255) -> length code (0..28)
-        length = 0;
-        for (code = 0; code < zip_LENGTH_CODES - 1; code++) {
-            zip_base_length[code] = length;
-            for (n = 0; n < (1 << zip_extra_lbits[code]); n++)
-                zip_length_code[length++] = code;
-        }
-        /* Note that the length 255 (match length 258) can be represented
-         * in two different ways: code 284 + 5 bits or code 285, so we
-         * overwrite length_code[255] to use the best encoding:
-         */
-        zip_length_code[length - 1] = code;
-
-        /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-        dist = 0;
-        for (code = 0; code < 16; code++) {
-            zip_base_dist[code] = dist;
-            for (n = 0; n < (1 << zip_extra_dbits[code]); n++) {
-                zip_dist_code[dist++] = code;
-            }
-        }
-        dist >>= 7; // from now on, all distances are divided by 128
-        for (; code < zip_D_CODES; code++) {
-            zip_base_dist[code] = dist << 7;
-            for (n = 0; n < (1 << (zip_extra_dbits[code] - 7)); n++)
-                zip_dist_code[256 + dist++] = code;
-        }
-        // Construct the codes of the static literal tree
-        for (bits = 0; bits <= zip_MAX_BITS; bits++)
-            zip_bl_count[bits] = 0;
-        n = 0;
-        while (n <= 143) {
-            zip_static_ltree[n++].dl = 8;
-            zip_bl_count[8]++;
-        }
-        while (n <= 255) {
-            zip_static_ltree[n++].dl = 9;
-            zip_bl_count[9]++;
-        }
-        while (n <= 279) {
-            zip_static_ltree[n++].dl = 7;
-            zip_bl_count[7]++;
-        }
-        while (n <= 287) {
-            zip_static_ltree[n++].dl = 8;
-            zip_bl_count[8]++;
-        }
-        /* Codes 286 and 287 do not exist, but we must include them in the
-         * tree construction to get a canonical Huffman tree (longest code
-         * all ones)
-         */
-        zip_gen_codes(zip_static_ltree, zip_L_CODES + 1);
-
-        /* The static distance tree is trivial: */
-        for (n = 0; n < zip_D_CODES; n++) {
-            zip_static_dtree[n].dl = 5;
-            zip_static_dtree[n].fc = zip_bi_reverse(n, 5);
-        }
-
-        // Initialize the first block of the first file:
-        zip_init_block();
-    };
-
-    /* ==========================================================================
-     * Initialize a new block.
-     */
-    var zip_init_block = function () {
-        var n; // iterates over tree elements
-
-        // Initialize the trees.
-        for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0;
-        for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0;
-        for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0;
-
-        zip_dyn_ltree[zip_END_BLOCK].fc = 1;
-        zip_opt_len = zip_static_len = 0;
-        zip_last_lit = zip_last_dist = zip_last_flags = 0;
-        zip_flags = 0;
-        zip_flag_bit = 1;
-    };
-
-    /* ==========================================================================
-     * Restore the heap property by moving down the tree starting at node k,
-     * exchanging a node with the smallest of its two sons if necessary, stopping
-     * when the heap property is re-established (each father smaller than its
-     * two sons).
-     */
-    var zip_pqdownheap = function (tree,	// the tree to restore
-                                   k) {	// node to move down
-        var v = zip_heap[k];
-        var j = k << 1;	// left son of k
-
-        while (j <= zip_heap_len) {
-            // Set j to the smallest of the two sons:
-            if (j < zip_heap_len &&
-                zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j]))
-                j++;
-
-            // Exit if v is smaller than both sons
-            if (zip_SMALLER(tree, v, zip_heap[j]))
-                break;
-
-            // Exchange v with the smallest son
-            zip_heap[k] = zip_heap[j];
-            k = j;
-
-            // And continue down the tree, setting j to the left son of k
-            j <<= 1;
-        }
-        zip_heap[k] = v;
-    };
-
-    /* ==========================================================================
-     * Compute the optimal bit lengths for a tree and update the total bit length
-     * for the current block.
-     * IN assertion: the fields freq and dad are set, heap[heap_max] and
-     *    above are the tree nodes sorted by increasing frequency.
-     * OUT assertions: the field len is set to the optimal bit length, the
-     *     array bl_count contains the frequencies for each bit length.
-     *     The length opt_len is updated; static_len is also updated if stree is
-     *     not null.
-     */
-    var zip_gen_bitlen = function (desc) { // the tree descriptor
-        var tree = desc.dyn_tree;
-        var extra = desc.extra_bits;
-        var base = desc.extra_base;
-        var max_code = desc.max_code;
-        var max_length = desc.max_length;
-        var stree = desc.static_tree;
-        var h;		// heap index
-        var n, m;		// iterate over the tree elements
-        var bits;		// bit length
-        var xbits;		// extra bits
-        var f;		// frequency
-        var overflow = 0;	// number of elements with bit length too large
-
-        for (bits = 0; bits <= zip_MAX_BITS; bits++)
-            zip_bl_count[bits] = 0;
-
-        /* In a first pass, compute the optimal bit lengths (which may
-         * overflow in the case of the bit length tree).
-         */
-        tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap
-
-        for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) {
-            n = zip_heap[h];
-            bits = tree[tree[n].dl].dl + 1;
-            if (bits > max_length) {
-                bits = max_length;
-                overflow++;
-            }
-            tree[n].dl = bits;
-            // We overwrite tree[n].dl which is no longer needed
-
-            if (n > max_code)
-                continue; // not a leaf node
-
-            zip_bl_count[bits]++;
-            xbits = 0;
-            if (n >= base)
-                xbits = extra[n - base];
-            f = tree[n].fc;
-            zip_opt_len += f * (bits + xbits);
-            if (stree != null)
-                zip_static_len += f * (stree[n].dl + xbits);
-        }
-        if (overflow == 0)
-            return;
-
-        // This happens for example on obj2 and pic of the Calgary corpus
-
-        // Find the first bit length which could increase:
-        do {
-            bits = max_length - 1;
-            while (zip_bl_count[bits] == 0)
-                bits--;
-            zip_bl_count[bits]--;		// move one leaf down the tree
-            zip_bl_count[bits + 1] += 2;	// move one overflow item as its brother
-            zip_bl_count[max_length]--;
-            /* The brother of the overflow item also moves one step up,
-             * but this does not affect bl_count[max_length]
-             */
-            overflow -= 2;
-        } while (overflow > 0);
-
-        /* Now recompute all bit lengths, scanning in increasing frequency.
-         * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-         * lengths instead of fixing only the wrong ones. This idea is taken
-         * from 'ar' written by Haruhiko Okumura.)
-         */
-        for (bits = max_length; bits != 0; bits--) {
-            n = zip_bl_count[bits];
-            while (n != 0) {
-                m = zip_heap[--h];
-                if (m > max_code)
-                    continue;
-                if (tree[m].dl != bits) {
-                    zip_opt_len += (bits - tree[m].dl) * tree[m].fc;
-                    tree[m].fc = bits;
-                }
-                n--;
-            }
-        }
-    };
-
-    /* ==========================================================================
-     * Generate the codes for a given tree and bit counts (which need not be
-     * optimal).
-     * IN assertion: the array bl_count contains the bit length statistics for
-     * the given tree and the field len is set for all tree elements.
-     * OUT assertion: the field code is set for all tree elements of non
-     *     zero code length.
-     */
-    var zip_gen_codes = function (tree,	// the tree to decorate
-                                  max_code) {	// largest code with non zero frequency
-        var next_code = new Array(zip_MAX_BITS + 1); // next code value for each bit length
-        var code = 0;		// running code value
-        var bits;			// bit index
-        var n;			// code index
-
-        /* The distribution counts are first used to generate the code values
-         * without bit reversal.
-         */
-        for (bits = 1; bits <= zip_MAX_BITS; bits++) {
-            code = ((code + zip_bl_count[bits - 1]) << 1);
-            next_code[bits] = code;
-        }
-
-        /* Check that the bit counts in bl_count are consistent. The last code
-         * must be all ones.
-         */
-        for (n = 0; n <= max_code; n++) {
-            var len = tree[n].dl;
-            if (len == 0)
-                continue;
-            // Now reverse the bits
-            tree[n].fc = zip_bi_reverse(next_code[len]++, len);
-        }
-    };
-
-    /* ==========================================================================
-     * Construct one Huffman tree and assigns the code bit strings and lengths.
-     * Update the total bit length for the current block.
-     * IN assertion: the field freq is set for all tree elements.
-     * OUT assertions: the fields len and code are set to the optimal bit length
-     *     and corresponding code. The length opt_len is updated; static_len is
-     *     also updated if stree is not null. The field max_code is set.
-     */
-    var zip_build_tree = function (desc) { // the tree descriptor
-        var tree = desc.dyn_tree;
-        var stree = desc.static_tree;
-        var elems = desc.elems;
-        var n, m;		// iterate over heap elements
-        var max_code = -1;	// largest code with non zero frequency
-        var node = elems;	// next internal node of the tree
-
-        /* Construct the initial heap, with least frequent element in
-         * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-         * heap[0] is not used.
-         */
-        zip_heap_len = 0;
-        zip_heap_max = zip_HEAP_SIZE;
-
-        for (n = 0; n < elems; n++) {
-            if (tree[n].fc != 0) {
-                zip_heap[++zip_heap_len] = max_code = n;
-                zip_depth[n] = 0;
-            } else
-                tree[n].dl = 0;
-        }
-
-        /* The pkzip format requires that at least one distance code exists,
-         * and that at least one bit should be sent even if there is only one
-         * possible code. So to avoid special checks later on we force at least
-         * two codes of non zero frequency.
-         */
-        while (zip_heap_len < 2) {
-            var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0);
-            tree[xnew].fc = 1;
-            zip_depth[xnew] = 0;
-            zip_opt_len--;
-            if (stree != null)
-                zip_static_len -= stree[xnew].dl;
-            // new is 0 or 1 so it does not have extra bits
-        }
-        desc.max_code = max_code;
-
-        /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-         * establish sub-heaps of increasing lengths:
-         */
-        for (n = zip_heap_len >> 1; n >= 1; n--)
-            zip_pqdownheap(tree, n);
-
-        /* Construct the Huffman tree by repeatedly combining the least two
-         * frequent nodes.
-         */
-        do {
-            n = zip_heap[zip_SMALLEST];
-            zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--];
-            zip_pqdownheap(tree, zip_SMALLEST);
-
-            m = zip_heap[zip_SMALLEST];  // m = node of next least frequency
-
-            // keep the nodes sorted by frequency
-            zip_heap[--zip_heap_max] = n;
-            zip_heap[--zip_heap_max] = m;
-
-            // Create a new node father of n and m
-            tree[node].fc = tree[n].fc + tree[m].fc;
-            if (zip_depth[n] > zip_depth[m] + 1)
-                zip_depth[node] = zip_depth[n];
-            else
-                zip_depth[node] = zip_depth[m] + 1;
-            tree[n].dl = tree[m].dl = node;
-
-            // and insert the new node in the heap
-            zip_heap[zip_SMALLEST] = node++;
-            zip_pqdownheap(tree, zip_SMALLEST);
-
-        } while (zip_heap_len >= 2);
-
-        zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST];
-
-        /* At this point, the fields freq and dad are set. We can now
-         * generate the bit lengths.
-         */
-        zip_gen_bitlen(desc);
-
-        // The field len is now set, we can generate the bit codes
-        zip_gen_codes(tree, max_code);
-    };
-
-    /* ==========================================================================
-     * Scan a literal or distance tree to determine the frequencies of the codes
-     * in the bit length tree. Updates opt_len to take into account the repeat
-     * counts. (The contribution of the bit length codes will be added later
-     * during the construction of bl_tree.)
-     */
-    var zip_scan_tree = function (tree,// the tree to be scanned
-                                  max_code) {  // and its largest code of non zero frequency
-        var n;			// iterates over all tree elements
-        var prevlen = -1;		// last emitted length
-        var curlen;			// length of current code
-        var nextlen = tree[0].dl;	// length of next code
-        var count = 0;		// repeat count of the current code
-        var max_count = 7;		// max repeat count
-        var min_count = 4;		// min repeat count
-
-        if (nextlen == 0) {
-            max_count = 138;
-            min_count = 3;
-        }
-        tree[max_code + 1].dl = 0xffff; // guard
-
-        for (n = 0; n <= max_code; n++) {
-            curlen = nextlen;
-            nextlen = tree[n + 1].dl;
-            if (++count < max_count && curlen == nextlen)
-                continue;
-            else if (count < min_count)
-                zip_bl_tree[curlen].fc += count;
-            else if (curlen != 0) {
-                if (curlen != prevlen)
-                    zip_bl_tree[curlen].fc++;
-                zip_bl_tree[zip_REP_3_6].fc++;
-            } else if (count <= 10)
-                zip_bl_tree[zip_REPZ_3_10].fc++;
-            else
-                zip_bl_tree[zip_REPZ_11_138].fc++;
-            count = 0;
-            prevlen = curlen;
-            if (nextlen == 0) {
-                max_count = 138;
-                min_count = 3;
-            } else if (curlen == nextlen) {
-                max_count = 6;
-                min_count = 3;
-            } else {
-                max_count = 7;
-                min_count = 4;
-            }
-        }
-    };
-
-    /* ==========================================================================
-     * Send a literal or distance tree in compressed form, using the codes in
-     * bl_tree.
-     */
-    var zip_send_tree = function (tree, // the tree to be scanned
-                                  max_code) { // and its largest code of non zero frequency
-        var n;			// iterates over all tree elements
-        var prevlen = -1;		// last emitted length
-        var curlen;			// length of current code
-        var nextlen = tree[0].dl;	// length of next code
-        var count = 0;		// repeat count of the current code
-        var max_count = 7;		// max repeat count
-        var min_count = 4;		// min repeat count
-
-        /* tree[max_code+1].dl = -1; */
-        /* guard already set */
-        if (nextlen == 0) {
-            max_count = 138;
-            min_count = 3;
-        }
-
-        for (n = 0; n <= max_code; n++) {
-            curlen = nextlen;
-            nextlen = tree[n + 1].dl;
-            if (++count < max_count && curlen == nextlen) {
-                continue;
-            } else if (count < min_count) {
-                do {
-                    zip_SEND_CODE(curlen, zip_bl_tree);
-                } while (--count != 0);
-            } else if (curlen != 0) {
-                if (curlen != prevlen) {
-                    zip_SEND_CODE(curlen, zip_bl_tree);
-                    count--;
-                }
-                // Assert(count >= 3 && count <= 6, " 3_6?");
-                zip_SEND_CODE(zip_REP_3_6, zip_bl_tree);
-                zip_send_bits(count - 3, 2);
-            } else if (count <= 10) {
-                zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree);
-                zip_send_bits(count - 3, 3);
-            } else {
-                zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree);
-                zip_send_bits(count - 11, 7);
-            }
-            count = 0;
-            prevlen = curlen;
-            if (nextlen == 0) {
-                max_count = 138;
-                min_count = 3;
-            } else if (curlen == nextlen) {
-                max_count = 6;
-                min_count = 3;
-            } else {
-                max_count = 7;
-                min_count = 4;
-            }
-        }
-    };
-
-    /* ==========================================================================
-     * Construct the Huffman tree for the bit lengths and return the index in
-     * bl_order of the last bit length code to send.
-     */
-    var zip_build_bl_tree = function () {
-        var max_blindex;  // index of last bit length code of non zero freq
-
-        // Determine the bit length frequencies for literal and distance trees
-        zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code);
-        zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code);
-
-        // Build the bit length tree:
-        zip_build_tree(zip_bl_desc);
-        /* opt_len now includes the length of the tree representations, except
-         * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-         */
-
-        /* Determine the number of bit length codes to send. The pkzip format
-         * requires that at least 4 bit length codes be sent. (appnote.txt says
-         * 3 but the actual value used is 4.)
-         */
-        for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) {
-            if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break;
-        }
-        /* Update opt_len to include the bit length tree and counts */
-        zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
-        return max_blindex;
-    };
-
-    /* ==========================================================================
-     * Send the header for a block using dynamic Huffman trees: the counts, the
-     * lengths of the bit length codes, the literal tree and the distance tree.
-     * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-     */
-    var zip_send_all_trees = function (lcodes, dcodes, blcodes) { // number of codes for each tree
-        var rank; // index in bl_order
-        zip_send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
-        zip_send_bits(dcodes - 1, 5);
-        zip_send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
-        for (rank = 0; rank < blcodes; rank++) {
-            zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3);
-        }
-
-        // send the literal tree
-        zip_send_tree(zip_dyn_ltree, lcodes - 1);
-
-        // send the distance tree
-        zip_send_tree(zip_dyn_dtree, dcodes - 1);
-    };
-
-    /* ==========================================================================
-     * Determine the best encoding for the current block: dynamic trees, static
-     * trees or store, and output the encoded block to the zip file.
-     */
-    var zip_flush_block = function (eof) { // true if this is the last block for a file
-        var opt_lenb, static_lenb; // opt_len and static_len in bytes
-        var max_blindex;	// index of last bit length code of non zero freq
-        var stored_len;	// length of input block
-
-        stored_len = zip_strstart - zip_block_start;
-        zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items
-
-        // Construct the literal and distance trees
-        zip_build_tree(zip_l_desc);
-        zip_build_tree(zip_d_desc);
-        /* At this point, opt_len and static_len are the total bit lengths of
-         * the compressed block data, excluding the tree representations.
-         */
-
-        /* Build the bit length tree for the above two trees, and get the index
-         * in bl_order of the last bit length code to send.
-         */
-        max_blindex = zip_build_bl_tree();
-
-        // Determine the best encoding. Compute first the block length in bytes
-        opt_lenb = (zip_opt_len + 3 + 7) >> 3;
-        static_lenb = (zip_static_len + 3 + 7) >> 3;
-        if (static_lenb <= opt_lenb)
-            opt_lenb = static_lenb;
-        if (stored_len + 4 <= opt_lenb // 4: two words for the lengths
-            && zip_block_start >= 0) {
-            var i;
-
-            /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-             * Otherwise we can't have processed more than WSIZE input bytes since
-             * the last block flush, because compression would have been
-             * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-             * transform a block into a stored block.
-             */
-            zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3);
-            /* send block type */
-            zip_bi_windup();
-            /* align on byte boundary */
-            zip_put_short(stored_len);
-            zip_put_short(~stored_len);
-
-            // copy block
-            for (i = 0; i < stored_len; i++)
-                zip_put_byte(zip_window[zip_block_start + i]);
-
-        } else if (static_lenb == opt_lenb) {
-            zip_send_bits((zip_STATIC_TREES << 1) + eof, 3);
-            zip_compress_block(zip_static_ltree, zip_static_dtree);
-        } else {
-            zip_send_bits((zip_DYN_TREES << 1) + eof, 3);
-            zip_send_all_trees(zip_l_desc.max_code + 1,
-                zip_d_desc.max_code + 1,
-                max_blindex + 1);
-            zip_compress_block(zip_dyn_ltree, zip_dyn_dtree);
-        }
-
-        zip_init_block();
-
-        if (eof != 0)
-            zip_bi_windup();
-    };
-
-    /* ==========================================================================
-     * Save the match info and tally the frequency counts. Return true if
-     * the current block must be flushed.
-     */
-    var zip_ct_tally = function (dist, // distance of matched string
-                                 lc) { // match length-MIN_MATCH or unmatched char (if dist==0)
-        zip_l_buf[zip_last_lit++] = lc;
-        if (dist == 0) {
-            // lc is the unmatched char
-            zip_dyn_ltree[lc].fc++;
-        } else {
-            // Here, lc is the match length - MIN_MATCH
-            dist--;		    // dist = match distance - 1
-            zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++;
-            zip_dyn_dtree[zip_D_CODE(dist)].fc++;
-
-            zip_d_buf[zip_last_dist++] = dist;
-            zip_flags |= zip_flag_bit;
-        }
-        zip_flag_bit <<= 1;
-
-        // Output the flags if they fill a byte
-        if ((zip_last_lit & 7) == 0) {
-            zip_flag_buf[zip_last_flags++] = zip_flags;
-            zip_flags = 0;
-            zip_flag_bit = 1;
-        }
-        // Try to guess if it is profitable to stop the current block here
-        if (zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) {
-            // Compute an upper bound for the compressed length
-            var out_length = zip_last_lit * 8;
-            var in_length = zip_strstart - zip_block_start;
-            var dcode;
-
-            for (dcode = 0; dcode < zip_D_CODES; dcode++) {
-                out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]);
-            }
-            out_length >>= 3;
-            if (zip_last_dist < parseInt(zip_last_lit / 2) &&
-                out_length < parseInt(in_length / 2))
-                return true;
-        }
-        return (zip_last_lit == LIT_BUFSIZE - 1 ||
-            zip_last_dist == zip_DIST_BUFSIZE);
-        /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
-         * on 16 bit machines and because stored blocks are restricted to
-         * 64K-1 bytes.
-         */
-    };
-
-    /* ==========================================================================
-     * Send the block data compressed using the given Huffman trees
-     */
-    var zip_compress_block = function (ltree,	// literal tree
-                                       dtree) {	// distance tree
-        var dist;		// distance of matched string
-        var lc;		// match length or unmatched char (if dist == 0)
-        var lx = 0;		// running index in l_buf
-        var dx = 0;		// running index in d_buf
-        var fx = 0;		// running index in flag_buf
-        var flag = 0;	// current flags
-        var code;		// the code to send
-        var extra;		// number of extra bits to send
-
-        if (zip_last_lit != 0) do {
-            if ((lx & 7) == 0)
-                flag = zip_flag_buf[fx++];
-            lc = zip_l_buf[lx++] & 0xff;
-            if ((flag & 1) == 0) {
-                zip_SEND_CODE(lc, ltree);
-                /* send a literal byte */
-            } else {
-                // Here, lc is the match length - MIN_MATCH
-                code = zip_length_code[lc];
-                zip_SEND_CODE(code + zip_LITERALS + 1, ltree); // send the length code
-                extra = zip_extra_lbits[code];
-                if (extra != 0) {
-                    lc -= zip_base_length[code];
-                    zip_send_bits(lc, extra); // send the extra length bits
-                }
-                dist = zip_d_buf[dx++];
-                // Here, dist is the match distance - 1
-                code = zip_D_CODE(dist);
-                zip_SEND_CODE(code, dtree);	  // send the distance code
-                extra = zip_extra_dbits[code];
-                if (extra != 0) {
-                    dist -= zip_base_dist[code];
-                    zip_send_bits(dist, extra);   // send the extra distance bits
-                }
-            } // literal or match pair ?
-            flag >>= 1;
-        } while (lx < zip_last_lit);
-
-        zip_SEND_CODE(zip_END_BLOCK, ltree);
-    };
-
-    /* ==========================================================================
-     * Send a value on a given number of bits.
-     * IN assertion: length <= 16 and value fits in length bits.
-     */
-    var zip_Buf_size = 16; // bit size of bi_buf
-    var zip_send_bits = function (value,	// value to send
-                                  length) {	// number of bits
-        /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-         * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-         * unused bits in value.
-         */
-        if (zip_bi_valid > zip_Buf_size - length) {
-            zip_bi_buf |= (value << zip_bi_valid);
-            zip_put_short(zip_bi_buf);
-            zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid));
-            zip_bi_valid += length - zip_Buf_size;
-        } else {
-            zip_bi_buf |= value << zip_bi_valid;
-            zip_bi_valid += length;
-        }
-    };
-
-    /* ==========================================================================
-     * Reverse the first len bits of a code, using straightforward code (a faster
-     * method would use a table)
-     * IN assertion: 1 <= len <= 15
-     */
-    var zip_bi_reverse = function (code,	// the value to invert
-                                   len) {	// its bit length
-        var res = 0;
-        do {
-            res |= code & 1;
-            code >>= 1;
-            res <<= 1;
-        } while (--len > 0);
-        return res >> 1;
-    };
-
-    /* ==========================================================================
-     * Write out any remaining bits in an incomplete byte.
-     */
-    var zip_bi_windup = function () {
-        if (zip_bi_valid > 8) {
-            zip_put_short(zip_bi_buf);
-        } else if (zip_bi_valid > 0) {
-            zip_put_byte(zip_bi_buf);
-        }
-        zip_bi_buf = 0;
-        zip_bi_valid = 0;
-    };
-
-    var zip_qoutbuf = function () {
-        if (zip_outcnt != 0) {
-            var q, i;
-            q = zip_new_queue();
-            if (zip_qhead == null)
-                zip_qhead = zip_qtail = q;
-            else
-                zip_qtail = zip_qtail.next = q;
-            q.len = zip_outcnt - zip_outoff;
-            for (i = 0; i < q.len; i++)
-                q.ptr[i] = zip_outbuf[zip_outoff + i];
-            zip_outcnt = zip_outoff = 0;
-        }
-    };
-
-    function deflate(buffData, level) {
-        zip_deflate_data = buffData;
-        zip_deflate_pos = 0;
-        zip_deflate_start(level);
-
-        var buff = new Array(1024),
-            pages = [],
-            totalSize = 0,
-            i;
-
-        for (i = 0; i < 1024; i++) buff[i] = 0;
-        while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) {
-            var buf = new Buffer(buff.slice(0, i));
-            pages.push(buf);
-            totalSize += buf.length;
-        }
-
-        if (pages.length == 1) {
-            return pages[0];
-        }
-
-        var result = new Buffer(totalSize),
-            index = 0;
-
-        for (i = 0; i < pages.length; i++) {
-            pages[i].copy(result, index);
-            index = index + pages[i].length
-        }
-
-        return result;
-    }
-
-    return {
-        deflate: function () {
-            return deflate(inbuf, 8);
-        }
-    }
-}
-
-module.exports = function (/*Buffer*/inbuf) {
-
-    var zlib = require("zlib");
-
-    return {
-        deflate: function () {
-            return new JSDeflater(inbuf).deflate();
-        },
-
-        deflateAsync: function (/*Function*/callback) {
-            var tmp = zlib.createDeflateRaw({chunkSize:(parseInt(inbuf.length / 1024) + 1)*1024}),
-                parts = [], total = 0;
-            tmp.on('data', function(data) {
-                parts.push(data);
-                total += data.length;
-            });
-            tmp.on('end', function() {
-                var buf = new Buffer(total), written = 0;
-                buf.fill(0);
-
-                for (var i = 0; i < parts.length; i++) {
-                    var part = parts[i];
-                    part.copy(buf, written);
-                    written += part.length;
-                }
-                callback && callback(buf);
-            });
-            tmp.end(inbuf);
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/index.js
deleted file mode 100644
index 58c718da6..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-exports.Deflater = require("./deflater");
-exports.Inflater = require("./inflater");
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/inflater.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/inflater.js
deleted file mode 100644
index 3739d98a8..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/methods/inflater.js
+++ /dev/null
@@ -1,448 +0,0 @@
-var Buffer = require("buffer").Buffer;
-
-function JSInflater(/*Buffer*/input) {
-
-    var WSIZE = 0x8000,
-        slide = new Buffer(0x10000),
-        windowPos = 0,
-        fixedTableList = null,
-        fixedTableDist,
-        fixedLookup,
-        bitBuf = 0,
-        bitLen = 0,
-        method = -1,
-        eof = false,
-        copyLen = 0,
-        copyDist = 0,
-        tblList, tblDist, bitList, bitdist,
-
-        inputPosition = 0,
-
-        MASK_BITS = [0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff],
-        LENS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0],
-        LEXT = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99],
-        DISTS = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577],
-        DEXT = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13],
-        BITORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
-
-    function HuffTable(clen, cnum, cval, blist, elist, lookupm) {
-
-        this.status = 0;
-        this.root = null;
-        this.maxbit = 0;
-
-        var el, f, tail,
-            offsets = [],
-            countTbl = [],
-            sTbl = [],
-            values = [],
-            tentry = {extra: 0, bitcnt: 0, lbase: 0, next: null};
-
-        tail = this.root = null;
-        for(var i = 0; i < 0x11; i++)  { countTbl[i] = 0; sTbl[i] = 0; offsets[i] = 0; }
-        for(i = 0; i < 0x120; i++) values[i] = 0;
-
-        el = cnum > 256 ? clen[256] : 16;
-
-        var pidx = -1;
-        while (++pidx < cnum) countTbl[clen[pidx]]++;
-
-        if(countTbl[0] == cnum) return;
-
-        for(var j = 1; j <= 16; j++) if(countTbl[j] != 0) break;
-        var bitLen = j;
-        for(i = 16; i != 0; i--) if(countTbl[i] != 0) break;
-        var maxLen = i;
-
-        lookupm < j && (lookupm = j);
-
-        var dCodes = 1 << j;
-        for(; j < i; j++, dCodes <<= 1)
-            if((dCodes -= countTbl[j]) < 0) {
-                this.status = 2;
-                this.maxbit = lookupm;
-                return;
-            }
-
-        if((dCodes -= countTbl[i]) < 0) {
-            this.status = 2;
-            this.maxbit = lookupm;
-            return;
-        }
-
-        countTbl[i] += dCodes;
-        offsets[1] = j = 0;
-        pidx = 1;
-        var xp = 2;
-        while(--i > 0) offsets[xp++] = (j += countTbl[pidx++]);
-        pidx = 0;
-        i = 0;
-        do {
-            (j = clen[pidx++]) && (values[offsets[j]++] = i);
-        } while(++i < cnum);
-        cnum = offsets[maxLen];
-        offsets[0] = i = 0;
-        pidx = 0;
-
-        var level = -1,
-            w = sTbl[0] = 0,
-            cnode = null,
-            tblCnt = 0,
-            tblStack = [];
-
-        for(; bitLen <= maxLen; bitLen++) {
-            var kccnt = countTbl[bitLen];
-            while(kccnt-- > 0) {
-                while(bitLen > w + sTbl[1 + level]) {
-                    w += sTbl[1 + level];
-                    level++;
-                    tblCnt = (tblCnt = maxLen - w) > lookupm ? lookupm : tblCnt;
-                    if((f = 1 << (j = bitLen - w)) > kccnt + 1) {
-                        f -= kccnt + 1;
-                        xp = bitLen;
-                        while(++j < tblCnt) {
-                            if((f <<= 1) <= countTbl[++xp]) break;
-                            f -= countTbl[xp];
-                        }
-                    }
-                    if(w + j > el && w < el) j = el - w;
-                    tblCnt = 1 << j;
-                    sTbl[1 + level] = j;
-                    cnode = [];
-                    while (cnode.length < tblCnt) cnode.push({extra: 0, bitcnt: 0, lbase: 0, next: null});
-                    if (tail == null) {
-                        tail = this.root = {next:null, list:null};
-                    } else {
-                        tail = tail.next = {next:null, list:null}
-                    }
-                    tail.next = null;
-                    tail.list = cnode;
-
-                    tblStack[level] = cnode;
-
-                    if(level > 0) {
-                        offsets[level] = i;
-                        tentry.bitcnt = sTbl[level];
-                        tentry.extra = 16 + j;
-                        tentry.next = cnode;
-                        j = (i & ((1 << w) - 1)) >> (w - sTbl[level]);
-
-                        tblStack[level-1][j].extra = tentry.extra;
-                        tblStack[level-1][j].bitcnt = tentry.bitcnt;
-                        tblStack[level-1][j].lbase = tentry.lbase;
-                        tblStack[level-1][j].next = tentry.next;
-                    }
-                }
-                tentry.bitcnt = bitLen - w;
-                if(pidx >= cnum)
-                    tentry.extra = 99;
-                else if(values[pidx] < cval) {
-                    tentry.extra = (values[pidx] < 256 ? 16 : 15);
-                    tentry.lbase = values[pidx++];
-                } else {
-                    tentry.extra = elist[values[pidx] - cval];
-                    tentry.lbase = blist[values[pidx++] - cval];
-                }
-
-                f = 1 << (bitLen - w);
-                for(j = i >> w; j < tblCnt; j += f) {
-                    cnode[j].extra = tentry.extra;
-                    cnode[j].bitcnt = tentry.bitcnt;
-                    cnode[j].lbase = tentry.lbase;
-                    cnode[j].next = tentry.next;
-                }
-                for(j = 1 << (bitLen - 1); (i & j) != 0; j >>= 1)
-                    i ^= j;
-                i ^= j;
-                while((i & ((1 << w) - 1)) != offsets[level]) {
-                    w -= sTbl[level];
-                    level--;
-                }
-            }
-        }
-
-        this.maxbit = sTbl[1];
-        this.status = ((dCodes != 0 && maxLen != 1) ? 1 : 0);
-    }
-
-    function addBits(n) {
-        while(bitLen < n) {
-            bitBuf |= input[inputPosition++] << bitLen;
-            bitLen += 8;
-        }
-        return bitBuf;
-    }
-
-    function cutBits(n) {
-        bitLen -= n;
-        return bitBuf >>= n;
-    }
-
-    function maskBits(n) {
-        while(bitLen < n) {
-            bitBuf |= input[inputPosition++] << bitLen;
-            bitLen += 8;
-        }
-        var res = bitBuf & MASK_BITS[n];
-        bitBuf >>= n;
-        bitLen -= n;
-        return res;
-    }
-
-    function codes(buff, off, size) {
-        var e, t;
-        if(size == 0) return 0;
-
-        var n = 0;
-        for(;;) {
-            t = tblList.list[addBits(bitList) & MASK_BITS[bitList]];
-            e = t.extra;
-            while(e > 16) {
-                if(e == 99) return -1;
-                cutBits(t.bitcnt);
-                e -= 16;
-                t = t.next[addBits(e) & MASK_BITS[e]];
-                e = t.extra;
-            }
-            cutBits(t.bitcnt);
-            if(e == 16) {
-                windowPos &= WSIZE - 1;
-                buff[off + n++] = slide[windowPos++] = t.lbase;
-                if(n == size) return size;
-                continue;
-            }
-            if(e == 15) break;
-
-            copyLen = t.lbase + maskBits(e);
-            t = tblDist.list[addBits(bitdist) & MASK_BITS[bitdist]];
-            e = t.extra;
-
-            while(e > 16) {
-                if(e == 99) return -1;
-                cutBits(t.bitcnt);
-                e -= 16;
-                t = t.next[addBits(e) & MASK_BITS[e]];
-                e = t.extra
-            }
-            cutBits(t.bitcnt);
-            copyDist = windowPos - t.lbase - maskBits(e);
-
-            while(copyLen > 0 && n < size) {
-                copyLen--;
-                copyDist &= WSIZE - 1;
-                windowPos &= WSIZE - 1;
-                buff[off + n++] = slide[windowPos++] = slide[copyDist++];
-            }
-
-            if(n == size) return size;
-        }
-
-        method = -1; // done
-        return n;
-    }
-
-    function stored(buff, off, size) {
-        cutBits(bitLen & 7);
-        var n = maskBits(0x10);
-        if(n != ((~maskBits(0x10)) & 0xffff)) return -1;
-        copyLen = n;
-
-        n = 0;
-        while(copyLen > 0 && n < size) {
-            copyLen--;
-            windowPos &= WSIZE - 1;
-            buff[off + n++] = slide[windowPos++] = maskBits(8);
-        }
-
-        if(copyLen == 0) method = -1;
-        return n;
-    }
-
-    function fixed(buff, off, size) {
-        var fixed_bd = 0;
-        if(fixedTableList == null) {
-            var lengths = [];
-
-            for(var symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8;
-            for(; symbol < 256; symbol++) lengths[symbol] = 9;
-            for(; symbol < 280; symbol++) lengths[symbol] = 7;
-            for(; symbol < 288; symbol++) lengths[symbol] = 8;
-
-            fixedLookup = 7;
-
-            var htbl = new HuffTable(lengths, 288, 257, LENS, LEXT, fixedLookup);
-
-            if(htbl.status != 0) return -1;
-
-            fixedTableList = htbl.root;
-            fixedLookup = htbl.maxbit;
-
-            for(symbol = 0; symbol < 30; symbol++) lengths[symbol] = 5;
-            fixed_bd = 5;
-
-            htbl = new HuffTable(lengths, 30, 0, DISTS, DEXT, fixed_bd);
-            if(htbl.status > 1) {
-                fixedTableList = null;
-                return -1;
-            }
-            fixedTableDist = htbl.root;
-            fixed_bd = htbl.maxbit;
-        }
-
-        tblList = fixedTableList;
-        tblDist = fixedTableDist;
-        bitList = fixedLookup;
-        bitdist = fixed_bd;
-        return codes(buff, off, size);
-    }
-
-    function dynamic(buff, off, size) {
-        var ll = new Array(0x023C);
-
-        for (var m = 0; m < 0x023C; m++) ll[m] = 0;
-
-        var llencnt = 257 + maskBits(5),
-            dcodescnt = 1 + maskBits(5),
-            bitlencnt = 4 + maskBits(4);
-
-        if(llencnt > 286 || dcodescnt > 30) return -1;
-
-        for(var j = 0; j < bitlencnt; j++) ll[BITORDER[j]] = maskBits(3);
-        for(; j < 19; j++) ll[BITORDER[j]] = 0;
-
-        // build decoding table for trees--single level, 7 bit lookup
-        bitList = 7;
-        var hufTable = new HuffTable(ll, 19, 19, null, null, bitList);
-        if(hufTable.status != 0)
-            return -1;	// incomplete code set
-
-        tblList = hufTable.root;
-        bitList = hufTable.maxbit;
-        var lencnt = llencnt + dcodescnt,
-            i = 0,
-            lastLen = 0;
-        while(i < lencnt) {
-            var hufLcode = tblList.list[addBits(bitList) & MASK_BITS[bitList]];
-            j = hufLcode.bitcnt;
-            cutBits(j);
-            j = hufLcode.lbase;
-            if(j < 16)
-                ll[i++] = lastLen = j;
-            else if(j == 16) {
-                j = 3 + maskBits(2);
-                if(i + j > lencnt) return -1;
-                while(j-- > 0) ll[i++] = lastLen;
-            } else if(j == 17) {
-                j = 3 + maskBits(3);
-                if(i + j > lencnt) return -1;
-                while(j-- > 0) ll[i++] = 0;
-                lastLen = 0;
-            } else {
-                j = 11 + maskBits(7);
-                if(i + j > lencnt) return -1;
-                while(j-- > 0) ll[i++] = 0;
-                lastLen = 0;
-            }
-        }
-        bitList = 9;
-        hufTable = new HuffTable(ll, llencnt, 257, LENS, LEXT, bitList);
-        bitList == 0 && (hufTable.status = 1);
-
-        if (hufTable.status != 0) return -1;
-
-        tblList = hufTable.root;
-        bitList = hufTable.maxbit;
-
-        for(i = 0; i < dcodescnt; i++) ll[i] = ll[i + llencnt];
-        bitdist = 6;
-        hufTable = new HuffTable(ll, dcodescnt, 0, DISTS, DEXT, bitdist);
-        tblDist = hufTable.root;
-        bitdist = hufTable.maxbit;
-
-        if((bitdist == 0 && llencnt > 257) || hufTable.status != 0) return -1;
-
-        return codes(buff, off, size);
-    }
-
-    return {
-        inflate : function(/*Buffer*/outputBuffer) {
-            tblList = null;
-
-            var size = outputBuffer.length,
-                offset = 0, i;
-
-            while(offset < size) {
-                if(eof && method == -1) return;
-                if(copyLen > 0) {
-                    if(method != 0) {
-                        while(copyLen > 0 && offset < size) {
-                            copyLen--;
-                            copyDist &= WSIZE - 1;
-                            windowPos &= WSIZE - 1;
-                            outputBuffer[offset++] = (slide[windowPos++] = slide[copyDist++]);
-                        }
-                    } else {
-                        while(copyLen > 0 && offset < size) {
-                            copyLen--;
-                            windowPos &= WSIZE - 1;
-                            outputBuffer[offset++] = (slide[windowPos++] = maskBits(8));
-                        }
-                        copyLen == 0 && (method = -1); // done
-                    }
-                    if (offset == size) return;
-                }
-
-                if(method == -1) {
-                    if(eof) break;
-                    eof = maskBits(1) != 0;
-                    method = maskBits(2);
-                    tblList = null;
-                    copyLen = 0;
-                }
-                switch(method) {
-                    case 0: i = stored(outputBuffer, offset, size - offset); break;
-                    case 1: i = tblList != null ? codes(outputBuffer, offset, size - offset) : fixed(outputBuffer, offset, size - offset); break;
-                    case 2: i = tblList != null ? codes(outputBuffer, offset, size - offset) : dynamic(outputBuffer, offset, size - offset); break;
-                    default: i = -1; break;
-                }
-
-                if(i == -1) return;
-                offset += i;
-            }
-        }
-    };
-}
-
-module.exports = function(/*Buffer*/inbuf) {
-    var zlib = require("zlib");
-    return {
-        inflateAsync : function(/*Function*/callback) {
-            var tmp = zlib.createInflateRaw(),
-                parts = [], total = 0;
-            tmp.on('data', function(data) {
-                parts.push(data);
-                total += data.length;
-            });
-            tmp.on('end', function() {
-                var buf = new Buffer(total), written = 0;
-                buf.fill(0);
-
-                for (var i = 0; i < parts.length; i++) {
-                    var part = parts[i];
-                    part.copy(buf, written);
-                    written += part.length;
-                }
-                callback && callback(buf);
-            });
-            tmp.end(inbuf)
-        },
-
-        inflate : function(/*Buffer*/outputBuffer) {
-            var x = {
-                x: new JSInflater(inbuf)
-            };
-            x.x.inflate(outputBuffer);
-            delete(x.x);
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/package.json
deleted file mode 100644
index 00afae673..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/package.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
-  "_args": [
-    [
-      {
-        "raw": "adm-zip@^0.4.7",
-        "scope": null,
-        "escapedName": "adm-zip",
-        "name": "adm-zip",
-        "rawSpec": "^0.4.7",
-        "spec": ">=0.4.7 <0.5.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser"
-    ]
-  ],
-  "_from": "adm-zip@>=0.4.7 <0.5.0",
-  "_id": "adm-zip@0.4.7",
-  "_inCache": true,
-  "_location": "/adm-zip",
-  "_nodeVersion": "0.12.0",
-  "_npmUser": {
-    "name": "cthackers",
-    "email": "iacob.campia@gmail.com"
-  },
-  "_npmVersion": "2.5.1",
-  "_phantomChildren": {},
-  "_requested": {
-    "raw": "adm-zip@^0.4.7",
-    "scope": null,
-    "escapedName": "adm-zip",
-    "name": "adm-zip",
-    "rawSpec": "^0.4.7",
-    "spec": ">=0.4.7 <0.5.0",
-    "type": "range"
-  },
-  "_requiredBy": [
-    "/"
-  ],
-  "_resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
-  "_shasum": "8606c2cbf1c426ce8c8ec00174447fd49b6eafc1",
-  "_shrinkwrap": null,
-  "_spec": "adm-zip@^0.4.7",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser",
-  "author": {
-    "name": "Nasca Iacob",
-    "email": "sy@another-d-mention.ro",
-    "url": "https://github.com/cthackers"
-  },
-  "bugs": {
-    "url": "https://github.com/cthackers/adm-zip/issues",
-    "email": "sy@another-d-mention.ro"
-  },
-  "dependencies": {},
-  "description": "A Javascript implementation of zip for nodejs. Allows user to create or extract zip files both in memory or to/from disk",
-  "devDependencies": {},
-  "directories": {},
-  "dist": {
-    "shasum": "8606c2cbf1c426ce8c8ec00174447fd49b6eafc1",
-    "tarball": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz"
-  },
-  "engines": {
-    "node": ">=0.3.0"
-  },
-  "files": [
-    "adm-zip.js",
-    "headers",
-    "methods",
-    "util",
-    "zipEntry.js",
-    "zipFile.js"
-  ],
-  "gitHead": "6708a3e5788ff9e67ddba288397f7788a5c02855",
-  "homepage": "http://github.com/cthackers/adm-zip",
-  "keywords": [
-    "zip",
-    "methods",
-    "archive",
-    "unzip"
-  ],
-  "licenses": [
-    {
-      "type": "MIT",
-      "url": "https://raw.github.com/cthackers/adm-zip/master/MIT-LICENSE.txt"
-    }
-  ],
-  "main": "adm-zip.js",
-  "maintainers": [
-    {
-      "name": "cthackers",
-      "email": "sy@another-d-mention.ro"
-    }
-  ],
-  "name": "adm-zip",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/cthackers/adm-zip.git"
-  },
-  "scripts": {},
-  "version": "0.4.7"
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/constants.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/constants.js
deleted file mode 100644
index 02de1e9ad..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/constants.js
+++ /dev/null
@@ -1,115 +0,0 @@
-module.exports = {
-    /* The local file header */
-    LOCHDR           : 30, // LOC header size
-    LOCSIG           : 0x04034b50, // "PK\003\004"
-    LOCVER           : 4,	// version needed to extract
-    LOCFLG           : 6, // general purpose bit flag
-    LOCHOW           : 8, // compression method
-    LOCTIM           : 10, // modification time (2 bytes time, 2 bytes date)
-    LOCCRC           : 14, // uncompressed file crc-32 value
-    LOCSIZ           : 18, // compressed size
-    LOCLEN           : 22, // uncompressed size
-    LOCNAM           : 26, // filename length
-    LOCEXT           : 28, // extra field length
-
-    /* The Data descriptor */
-    EXTSIG           : 0x08074b50, // "PK\007\008"
-    EXTHDR           : 16, // EXT header size
-    EXTCRC           : 4, // uncompressed file crc-32 value
-    EXTSIZ           : 8, // compressed size
-    EXTLEN           : 12, // uncompressed size
-
-    /* The central directory file header */
-    CENHDR           : 46, // CEN header size
-    CENSIG           : 0x02014b50, // "PK\001\002"
-    CENVEM           : 4, // version made by
-    CENVER           : 6, // version needed to extract
-    CENFLG           : 8, // encrypt, decrypt flags
-    CENHOW           : 10, // compression method
-    CENTIM           : 12, // modification time (2 bytes time, 2 bytes date)
-    CENCRC           : 16, // uncompressed file crc-32 value
-    CENSIZ           : 20, // compressed size
-    CENLEN           : 24, // uncompressed size
-    CENNAM           : 28, // filename length
-    CENEXT           : 30, // extra field length
-    CENCOM           : 32, // file comment length
-    CENDSK           : 34, // volume number start
-    CENATT           : 36, // internal file attributes
-    CENATX           : 38, // external file attributes (host system dependent)
-    CENOFF           : 42, // LOC header offset
-
-    /* The entries in the end of central directory */
-    ENDHDR           : 22, // END header size
-    ENDSIG           : 0x06054b50, // "PK\005\006"
-    ENDSUB           : 8, // number of entries on this disk
-    ENDTOT           : 10, // total number of entries
-    ENDSIZ           : 12, // central directory size in bytes
-    ENDOFF           : 16, // offset of first CEN header
-    ENDCOM           : 20, // zip file comment length
-
-    /* Compression methods */
-    STORED           : 0, // no compression
-    SHRUNK           : 1, // shrunk
-    REDUCED1         : 2, // reduced with compression factor 1
-    REDUCED2         : 3, // reduced with compression factor 2
-    REDUCED3         : 4, // reduced with compression factor 3
-    REDUCED4         : 5, // reduced with compression factor 4
-    IMPLODED         : 6, // imploded
-    // 7 reserved
-    DEFLATED         : 8, // deflated
-    ENHANCED_DEFLATED: 9, // enhanced deflated
-    PKWARE           : 10,// PKWare DCL imploded
-    // 11 reserved
-    BZIP2            : 12, //  compressed using BZIP2
-    // 13 reserved
-    LZMA             : 14, // LZMA
-    // 15-17 reserved
-    IBM_TERSE        : 18, // compressed using IBM TERSE
-    IBM_LZ77         : 19, //IBM LZ77 z
-
-    /* General purpose bit flag */
-    FLG_ENC          : 0,  // encripted file
-    FLG_COMP1        : 1,  // compression option
-    FLG_COMP2        : 2,  // compression option
-    FLG_DESC         : 4,  // data descriptor
-    FLG_ENH          : 8,  // enhanced deflation
-    FLG_STR          : 16, // strong encryption
-    FLG_LNG          : 1024, // language encoding
-    FLG_MSK          : 4096, // mask header values
-
-    /* Load type */
-    FILE             : 0,
-    BUFFER           : 1,
-    NONE             : 2,
-
-    /* 4.5 Extensible data fields */
-    EF_ID            : 0,
-    EF_SIZE          : 2,
-
-    /* Header IDs */
-    ID_ZIP64         : 0x0001,
-    ID_AVINFO        : 0x0007,
-    ID_PFS           : 0x0008,
-    ID_OS2           : 0x0009,
-    ID_NTFS          : 0x000a,
-    ID_OPENVMS       : 0x000c,
-    ID_UNIX          : 0x000d,
-    ID_FORK          : 0x000e,
-    ID_PATCH         : 0x000f,
-    ID_X509_PKCS7    : 0x0014,
-    ID_X509_CERTID_F : 0x0015,
-    ID_X509_CERTID_C : 0x0016,
-    ID_STRONGENC     : 0x0017,
-    ID_RECORD_MGT    : 0x0018,
-    ID_X509_PKCS7_RL : 0x0019,
-    ID_IBM1          : 0x0065,
-    ID_IBM2          : 0x0066,
-    ID_POSZIP        : 0x4690,
-
-    EF_ZIP64_OR_32   : 0xffffffff,
-    EF_ZIP64_OR_16   : 0xffff,
-    EF_ZIP64_SUNCOMP : 0,
-    EF_ZIP64_SCOMP   : 8,
-    EF_ZIP64_RHO     : 16,
-    EF_ZIP64_DSN     : 24
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/errors.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/errors.js
deleted file mode 100644
index 50931c318..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/errors.js
+++ /dev/null
@@ -1,35 +0,0 @@
-module.exports = {
-    /* Header error messages */
-    "INVALID_LOC" : "Invalid LOC header (bad signature)",
-    "INVALID_CEN" : "Invalid CEN header (bad signature)",
-    "INVALID_END" : "Invalid END header (bad signature)",
-
-    /* ZipEntry error messages*/
-    "NO_DATA" : "Nothing to decompress",
-    "BAD_CRC" : "CRC32 checksum failed",
-    "FILE_IN_THE_WAY" : "There is a file in the way: %s",
-    "UNKNOWN_METHOD" : "Invalid/unsupported compression method",
-
-    /* Inflater error messages */
-    "AVAIL_DATA" : "inflate::Available inflate data did not terminate",
-    "INVALID_DISTANCE" : "inflate::Invalid literal/length or distance code in fixed or dynamic block",
-    "TO_MANY_CODES" : "inflate::Dynamic block code description: too many length or distance codes",
-    "INVALID_REPEAT_LEN" : "inflate::Dynamic block code description: repeat more than specified lengths",
-    "INVALID_REPEAT_FIRST" : "inflate::Dynamic block code description: repeat lengths with no first length",
-    "INCOMPLETE_CODES" : "inflate::Dynamic block code description: code lengths codes incomplete",
-    "INVALID_DYN_DISTANCE": "inflate::Dynamic block code description: invalid distance code lengths",
-    "INVALID_CODES_LEN": "inflate::Dynamic block code description: invalid literal/length code lengths",
-    "INVALID_STORE_BLOCK" : "inflate::Stored block length did not match one's complement",
-    "INVALID_BLOCK_TYPE" : "inflate::Invalid block type (type == 3)",
-
-    /* ADM-ZIP error messages */
-    "CANT_EXTRACT_FILE" : "Could not extract the file",
-    "CANT_OVERRIDE" : "Target file already exists",
-    "NO_ZIP" : "No zip file was loaded",
-    "NO_ENTRY" : "Entry doesn't exist",
-    "DIRECTORY_CONTENT_ERROR" : "A directory cannot have content",
-    "FILE_NOT_FOUND" : "File not found: %s",
-    "NOT_IMPLEMENTED" : "Not implemented",
-    "INVALID_FILENAME" : "Invalid filename",
-    "INVALID_FORMAT" : "Invalid or unsupported zip format. No END header found"
-};
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/fattr.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/fattr.js
deleted file mode 100644
index 4f247eacb..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/fattr.js
+++ /dev/null
@@ -1,84 +0,0 @@
-var fs = require("fs"),
-    pth = require("path");
-	
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-module.exports = function(/*String*/path) {
-
-    var _path = path || "",
-        _permissions = 0,
-        _obj = newAttr(),
-        _stat = null;
-
-    function newAttr() {
-        return {
-            directory : false,
-            readonly : false,
-            hidden : false,
-            executable : false,
-            mtime : 0,
-            atime : 0
-        }
-    }
-
-    if (_path && fs.existsSync(_path)) {
-        _stat = fs.statSync(_path);
-        _obj.directory = _stat.isDirectory();
-        _obj.mtime = _stat.mtime;
-        _obj.atime = _stat.atime;
-        _obj.executable = !!(1 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0]));
-        _obj.readonly = !!(2 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0]));
-        _obj.hidden = pth.basename(_path)[0] === ".";
-    } else {
-        console.warn("Invalid path: " + _path)
-    }
-
-    return {
-
-        get directory () {
-            return _obj.directory;
-        },
-
-        get readOnly () {
-            return _obj.readonly;
-        },
-
-        get hidden () {
-            return _obj.hidden;
-        },
-
-        get mtime () {
-            return _obj.mtime;
-        },
-
-        get atime () {
-           return _obj.atime;
-        },
-
-
-        get executable () {
-            return _obj.executable;
-        },
-
-        decodeAttributes : function(val) {
-
-        },
-
-        encodeAttributes : function (val) {
-
-        },
-
-        toString : function() {
-           return '{\n' +
-               '\t"path" : "' + _path + ",\n" +
-               '\t"isDirectory" : ' + _obj.directory + ",\n" +
-               '\t"isReadOnly" : ' + _obj.readonly + ",\n" +
-               '\t"isHidden" : ' + _obj.hidden + ",\n" +
-               '\t"isExecutable" : ' + _obj.executable + ",\n" +
-               '\t"mTime" : ' + _obj.mtime + "\n" +
-               '\t"aTime" : ' + _obj.atime + "\n" +
-           '}';
-        }
-    }
-
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/index.js
deleted file mode 100644
index d77b98098..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = require("./utils");
-module.exports.Constants = require("./constants");
-module.exports.Errors = require("./errors");
-module.exports.FileAttr = require("./fattr");
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/utils.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/utils.js
deleted file mode 100644
index 52a8ed9a1..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/util/utils.js
+++ /dev/null
@@ -1,199 +0,0 @@
-var fs = require("fs"),
-    pth = require('path');
-
-fs.existsSync = fs.existsSync || pth.existsSync;
-
-module.exports = (function() {
-
-    var crcTable = [],
-        Constants = require('./constants'),
-        Errors = require('./errors'),
-
-        PATH_SEPARATOR = pth.normalize("/");
-
-
-    function mkdirSync(/*String*/path) {
-        var resolvedPath = path.split(PATH_SEPARATOR)[0];
-        path.split(PATH_SEPARATOR).forEach(function(name) {
-            if (!name || name.substr(-1,1) == ":") return;
-            resolvedPath += PATH_SEPARATOR + name;
-            var stat;
-            try {
-                stat = fs.statSync(resolvedPath);
-            } catch (e) {
-                fs.mkdirSync(resolvedPath);
-            }
-            if (stat && stat.isFile())
-                throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
-        });
-    }
-
-    function findSync(/*String*/root, /*RegExp*/pattern, /*Boolean*/recoursive) {
-        if (typeof pattern === 'boolean') {
-            recoursive = pattern;
-            pattern = undefined;
-        }
-        var files = [];
-        fs.readdirSync(root).forEach(function(file) {
-            var path = pth.join(root, file);
-
-            if (fs.statSync(path).isDirectory() && recoursive)
-                files = files.concat(findSync(path, pattern, recoursive));
-
-            if (!pattern || pattern.test(path)) {
-                files.push(pth.normalize(path) + (fs.statSync(path).isDirectory() ? PATH_SEPARATOR : ""));
-            }
-
-        });
-        return files;
-    }
-
-    return {
-        makeDir : function(/*String*/path) {
-            mkdirSync(path);
-        },
-
-        crc32 : function(buf) {
-            var b = new Buffer(4);
-            if (!crcTable.length) {
-                for (var n = 0; n < 256; n++) {
-                    var c = n;
-                    for (var k = 8; --k >= 0;)  //
-                        if ((c & 1) != 0)  { c = 0xedb88320 ^ (c >>> 1); } else { c = c >>> 1; }
-                    if (c < 0) {
-                        b.writeInt32LE(c, 0);
-                        c = b.readUInt32LE(0);
-                    }
-                    crcTable[n] = c;
-                }
-            }
-            var crc = 0, off = 0, len = buf.length, c1 = ~crc;
-            while(--len >= 0) c1 = crcTable[(c1 ^ buf[off++]) & 0xff] ^ (c1 >>> 8);
-            crc = ~c1;
-            b.writeInt32LE(crc & 0xffffffff, 0);
-            return b.readUInt32LE(0);
-        },
-
-        methodToString : function(/*Number*/method) {
-            switch (method) {
-                case Constants.STORED:
-                    return 'STORED (' + method + ')';
-                case Constants.DEFLATED:
-                    return 'DEFLATED (' + method + ')';
-                default:
-                    return 'UNSUPPORTED (' + method + ')';
-            }
-
-        },
-
-        writeFileTo : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr) {
-            if (fs.existsSync(path)) {
-                if (!overwrite)
-                    return false; // cannot overwite
-
-                var stat = fs.statSync(path);
-                if (stat.isDirectory()) {
-                    return false;
-                }
-            }
-            var folder = pth.dirname(path);
-            if (!fs.existsSync(folder)) {
-                mkdirSync(folder);
-            }
-
-            var fd;
-            try {
-                fd = fs.openSync(path, 'w', 438); // 0666
-            } catch(e) {
-                fs.chmodSync(path, 438);
-                fd = fs.openSync(path, 'w', 438);
-            }
-            if (fd) {
-                fs.writeSync(fd, content, 0, content.length, 0);
-                fs.closeSync(fd);
-            }
-            fs.chmodSync(path, attr || 438);
-            return true;
-        },
-
-        writeFileToAsync : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr, /*Function*/callback) {
-            if(typeof attr === 'function') {
-                callback = attr;
-                attr = undefined;
-            }
-
-            fs.exists(path, function(exists) {
-                if(exists && !overwrite)
-                    return callback(false);
-
-                fs.stat(path, function(err, stat) {
-                    if(exists &&stat.isDirectory()) {
-                        return callback(false);
-                    }
-
-                    var folder = pth.dirname(path);
-                    fs.exists(folder, function(exists) {
-                        if(!exists)
-                            mkdirSync(folder);
-                        
-                        fs.open(path, 'w', 438, function(err, fd) {
-                            if(err) {
-                                fs.chmod(path, 438, function(err) {
-                                    fs.open(path, 'w', 438, function(err, fd) {
-                                        fs.write(fd, content, 0, content.length, 0, function(err, written, buffer) {
-                                            fs.close(fd, function(err) {
-                                                fs.chmod(path, attr || 438, function() {
-                                                    callback(true);
-                                                })
-                                            });
-                                        });
-                                    });
-                                })
-                            } else {
-                                if(fd) {
-                                    fs.write(fd, content, 0, content.length, 0, function(err, written, buffer) {
-                                        fs.close(fd, function(err) {
-                                            fs.chmod(path, attr || 438, function() {
-                                                callback(true);
-                                            })
-                                        });
-                                    });
-                                } else {
-                                    fs.chmod(path, attr || 438, function() {
-                                        callback(true);
-                                    })
-                                }
-                            }
-                        });
-                    })
-                })
-            })
-        },
-
-        findFiles : function(/*String*/path) {
-            return findSync(path, true);
-        },
-
-        getAttributes : function(/*String*/path) {
-
-        },
-
-        setAttributes : function(/*String*/path) {
-
-        },
-
-        toBuffer : function(input) {
-            if (Buffer.isBuffer(input)) {
-                return input;
-            } else {
-                if (input.length == 0) {
-                    return new Buffer(0)
-                }
-                return new Buffer(input, 'utf8');
-            }
-        },
-
-        Constants : Constants,
-        Errors : Errors
-    }
-})();
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipEntry.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipEntry.js
deleted file mode 100644
index 6b1309bc4..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipEntry.js
+++ /dev/null
@@ -1,284 +0,0 @@
-var Utils = require("./util"),
-    Headers = require("./headers"),
-    Constants = Utils.Constants,
-    Methods = require("./methods");
-
-module.exports = function (/*Buffer*/input) {
-
-    var _entryHeader = new Headers.EntryHeader(),
-        _entryName = new Buffer(0),
-        _comment = new Buffer(0),
-        _isDirectory = false,
-        uncompressedData = null,
-        _extra = new Buffer(0);
-
-    function getCompressedDataFromZip() {
-        if (!input || !Buffer.isBuffer(input)) {
-            return new Buffer(0);
-        }
-        _entryHeader.loadDataHeaderFromBinary(input);
-        return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize)
-    }
-
-    function crc32OK(data) {
-        // if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written
-        if (_entryHeader.flags & 0x8 != 0x8) {
-           if (Utils.crc32(data) != _entryHeader.crc) {
-               return false;
-           }
-        } else {
-            // @TODO: load and check data descriptor header
-            // The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure
-            // (optionally preceded by a 4-byte signature) immediately after the compressed data:
-        }
-        return true;
-    }
-
-    function decompress(/*Boolean*/async, /*Function*/callback, /*String*/pass) {
-        if(typeof callback === 'undefined' && typeof async === 'string') {
-            pass=async;
-            async=void 0;
-        }
-        if (_isDirectory) {
-            if (async && callback) {
-                callback(new Buffer(0), Utils.Errors.DIRECTORY_CONTENT_ERROR); //si added error.
-            }
-            return new Buffer(0);
-        }
-
-        var compressedData = getCompressedDataFromZip();
-       
-        if (compressedData.length == 0) {
-            if (async && callback) callback(compressedData, Utils.Errors.NO_DATA);//si added error.
-            return compressedData;
-        }
-
-        var data = new Buffer(_entryHeader.size);
-        data.fill(0);
-
-        switch (_entryHeader.method) {
-            case Utils.Constants.STORED:
-                compressedData.copy(data);
-                if (!crc32OK(data)) {
-                    if (async && callback) callback(data, Utils.Errors.BAD_CRC);//si added error
-                    return Utils.Errors.BAD_CRC;
-                } else {//si added otherwise did not seem to return data.
-                    if (async && callback) callback(data);
-                    return data;
-                }
-                break;
-            case Utils.Constants.DEFLATED:
-                var inflater = new Methods.Inflater(compressedData);
-                if (!async) {
-                    inflater.inflate(data);
-                    if (!crc32OK(data)) {
-                        console.warn(Utils.Errors.BAD_CRC + " " + _entryName.toString())
-                    }
-                    return data;
-                } else {
-                    inflater.inflateAsync(function(result) {
-                        result.copy(data, 0);
-                        if (!crc32OK(data)) {
-                            if (callback) callback(data, Utils.Errors.BAD_CRC); //si added error
-                        } else { //si added otherwise did not seem to return data.
-                            if (callback) callback(data);
-                        }
-                    })
-                }
-                break;
-            default:
-                if (async && callback) callback(new Buffer(0), Utils.Errors.UNKNOWN_METHOD);
-                return Utils.Errors.UNKNOWN_METHOD;
-        }
-    }
-
-    function compress(/*Boolean*/async, /*Function*/callback) {
-        if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) {
-            // no data set or the data wasn't changed to require recompression
-            if (async && callback) callback(getCompressedDataFromZip());
-            return getCompressedDataFromZip();
-        }
-
-        if (uncompressedData.length && !_isDirectory) {
-            var compressedData;
-            // Local file header
-            switch (_entryHeader.method) {
-                case Utils.Constants.STORED:
-                    _entryHeader.compressedSize = _entryHeader.size;
-
-                    compressedData = new Buffer(uncompressedData.length);
-                    uncompressedData.copy(compressedData);
-
-                    if (async && callback) callback(compressedData);
-                    return compressedData;
-
-                    break;
-                default:
-                case Utils.Constants.DEFLATED:
-
-                    var deflater = new Methods.Deflater(uncompressedData);
-                    if (!async) {
-                        var deflated = deflater.deflate();
-                        _entryHeader.compressedSize = deflated.length;
-                        return deflated;
-                    } else {
-                        deflater.deflateAsync(function(data) {
-                            compressedData = new Buffer(data.length);
-                            _entryHeader.compressedSize = data.length;
-                            data.copy(compressedData);
-                            callback && callback(compressedData);
-                        })
-                    }
-                    deflater = null;
-                    break;
-            }
-        } else {
-            if (async && callback) {
-                callback(new Buffer(0));
-            } else {
-                return new Buffer(0);
-            }
-        }
-    }
-
-    function readUInt64LE(buffer, offset) {
-        return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
-    }
-
-    function parseExtra(data) {
-        var offset = 0;
-        var signature, size, part;
-        while(offset<data.length) {
-            signature = data.readUInt16LE(offset);
-            offset += 2;
-            size = data.readUInt16LE(offset);
-            offset += 2;
-            part = data.slice(offset, offset+size);
-            offset += size;
-            if(Constants.ID_ZIP64 === signature) {
-                parseZip64ExtendedInformation(part);
-            }
-        }
-    }
-
-    //Override header field values with values from the ZIP64 extra field
-    function parseZip64ExtendedInformation(data) {
-        var size, compressedSize, offset, diskNumStart;
-
-        if(data.length >= Constants.EF_ZIP64_SCOMP) {
-            size = readUInt64LE(data, Constants.EF_ZIP64_SUNCOMP);
-            if(_entryHeader.size === Constants.EF_ZIP64_OR_32) {
-                _entryHeader.size = size;
-            }
-        }
-        if(data.length >= Constants.EF_ZIP64_RHO) {
-            compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
-            if(_entryHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
-                _entryHeader.compressedSize = compressedSize;
-            }
-        }
-        if(data.length >= Constants.EF_ZIP64_DSN) {
-            offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
-            if(_entryHeader.offset === Constants.EF_ZIP64_OR_32) {
-                _entryHeader.offset = offset;
-            }
-        }
-        if(data.length >= Constants.EF_ZIP64_DSN+4) {
-            diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
-            if(_entryHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
-                _entryHeader.diskNumStart = diskNumStart;
-            }
-        }
-    }
-
-
-    return {
-        get entryName () { return _entryName.toString(); },
-        get rawEntryName() { return _entryName; },
-        set entryName (val) {
-            _entryName = Utils.toBuffer(val);
-            var lastChar = _entryName[_entryName.length - 1];
-            _isDirectory = (lastChar == 47) || (lastChar == 92);
-            _entryHeader.fileNameLength = _entryName.length;
-        },
-
-        get extra () { return _extra; },
-        set extra (val) {
-            _extra = val;
-            _entryHeader.extraLength = val.length;
-            parseExtra(val);
-        },
-
-        get comment () { return _comment.toString(); },
-        set comment (val) {
-            _comment = Utils.toBuffer(val);
-            _entryHeader.commentLength = _comment.length;
-        },
-
-        get name () { var n = _entryName.toString(); return _isDirectory ? n.substr(n.length - 1).split("/").pop() : n.split("/").pop(); },
-        get isDirectory () { return _isDirectory },
-
-        getCompressedData : function() {
-            return compress(false, null)
-        },
-
-        getCompressedDataAsync : function(/*Function*/callback) {
-            compress(true, callback)
-        },
-
-        setData : function(value) {
-            uncompressedData = Utils.toBuffer(value);
-            if (!_isDirectory && uncompressedData.length) {
-                _entryHeader.size = uncompressedData.length;
-                _entryHeader.method = Utils.Constants.DEFLATED;
-                _entryHeader.crc = Utils.crc32(value);
-            } else { // folders and blank files should be stored
-                _entryHeader.method = Utils.Constants.STORED;
-            }
-        },
-
-        getData : function(pass) {
-            return decompress(false, null, pass);
-        },
-
-        getDataAsync : function(/*Function*/callback, pass) {
-            decompress(true, callback, pass)
-        },
-
-        set attr(attr) { _entryHeader.attr = attr; },
-        get attr() { return _entryHeader.attr; },
-
-        set header(/*Buffer*/data) {
-            _entryHeader.loadFromBinary(data);
-        },
-
-        get header() {
-            return _entryHeader;
-        },
-
-        packHeader : function() {
-            var header = _entryHeader.entryHeaderToBinary();
-            // add
-            _entryName.copy(header, Utils.Constants.CENHDR);
-            if (_entryHeader.extraLength) {
-                _extra.copy(header, Utils.Constants.CENHDR + _entryName.length)
-            }
-            if (_entryHeader.commentLength) {
-                _comment.copy(header, Utils.Constants.CENHDR + _entryName.length + _entryHeader.extraLength, _comment.length);
-            }
-            return header;
-        },
-
-        toString : function() {
-            return '{\n' +
-                '\t"entryName" : "' + _entryName.toString() + "\",\n" +
-                '\t"name" : "' + _entryName.toString().split("/").pop() + "\",\n" +
-                '\t"comment" : "' + _comment.toString() + "\",\n" +
-                '\t"isDirectory" : ' + _isDirectory + ",\n" +
-                '\t"header" : ' + _entryHeader.toString().replace(/\t/mg, "\t\t") + ",\n" +
-                '\t"compressedData" : <' + (input && input.length  + " bytes buffer" || "null") + ">\n" +
-                '\t"data" : <' + (uncompressedData && uncompressedData.length  + " bytes buffer" || "null") + ">\n" +
-                '}';
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipFile.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipFile.js
deleted file mode 100644
index 794afdb83..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/adm-zip/zipFile.js
+++ /dev/null
@@ -1,311 +0,0 @@
-var ZipEntry = require("./zipEntry"),
-    Headers = require("./headers"),
-    Utils = require("./util");
-
-module.exports = function(/*String|Buffer*/input, /*Number*/inputType) {
-    var entryList = [],
-        entryTable = {},
-        _comment = new Buffer(0),
-        filename = "",
-        fs = require("fs"),
-        inBuffer = null,
-        mainHeader = new Headers.MainHeader();
-
-    if (inputType == Utils.Constants.FILE) {
-        // is a filename
-        filename = input;
-        inBuffer = fs.readFileSync(filename);
-        readMainHeader();
-    } else if (inputType == Utils.Constants.BUFFER) {
-        // is a memory buffer
-        inBuffer = input;
-        readMainHeader();
-    } else {
-        // none. is a new file
-    }
-
-    function readEntries() {
-        entryTable = {};
-        entryList = new Array(mainHeader.diskEntries);  // total number of entries
-        var index = mainHeader.offset;  // offset of first CEN header
-        for(var i = 0; i < entryList.length; i++) {
-
-            var tmp = index,
-                entry = new ZipEntry(inBuffer);
-            entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR);
-
-            entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength);
-
-            if (entry.header.extraLength) {
-                entry.extra = inBuffer.slice(tmp, tmp += entry.header.extraLength);
-            }
-
-            if (entry.header.commentLength)
-                entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength);
-
-            index += entry.header.entryHeaderSize;
-
-            entryList[i] = entry;
-            entryTable[entry.entryName] = entry;
-        }
-    }
-
-    function readMainHeader() {
-        var i = inBuffer.length - Utils.Constants.ENDHDR, // END header size
-            n = Math.max(0, i - 0xFFFF), // 0xFFFF is the max zip file comment length
-            endOffset = -1; // Start offset of the END header
-
-        for (i; i >= n; i--) {
-            if (inBuffer[i] != 0x50) continue; // quick check that the byte is 'P'
-            if (inBuffer.readUInt32LE(i) == Utils.Constants.ENDSIG) { // "PK\005\006"
-                endOffset = i;
-                break;
-            }
-        }
-        if (!~endOffset)
-            throw Utils.Errors.INVALID_FORMAT;
-
-        mainHeader.loadFromBinary(inBuffer.slice(endOffset, endOffset + Utils.Constants.ENDHDR));
-        if (mainHeader.commentLength) {
-            _comment = inBuffer.slice(endOffset + Utils.Constants.ENDHDR);
-        }
-        readEntries();
-    }
-
-    return {
-        /**
-         * Returns an array of ZipEntry objects existent in the current opened archive
-         * @return Array
-         */
-        get entries () {
-            return entryList;
-        },
-
-        /**
-         * Archive comment
-         * @return {String}
-         */
-        get comment () { return _comment.toString(); },
-        set comment(val) {
-            mainHeader.commentLength = val.length;
-            _comment = val;
-        },
-
-        /**
-         * Returns a reference to the entry with the given name or null if entry is inexistent
-         *
-         * @param entryName
-         * @return ZipEntry
-         */
-        getEntry : function(/*String*/entryName) {
-            return entryTable[entryName] || null;
-        },
-
-        /**
-         * Adds the given entry to the entry list
-         *
-         * @param entry
-         */
-        setEntry : function(/*ZipEntry*/entry) {
-            entryList.push(entry);
-            entryTable[entry.entryName] = entry;
-            mainHeader.totalEntries = entryList.length;
-        },
-
-        /**
-         * Removes the entry with the given name from the entry list.
-         *
-         * If the entry is a directory, then all nested files and directories will be removed
-         * @param entryName
-         */
-        deleteEntry : function(/*String*/entryName) {
-            var entry = entryTable[entryName];
-            if (entry && entry.isDirectory) {
-                var _self = this;
-                this.getEntryChildren(entry).forEach(function(child) {
-                    if (child.entryName != entryName) {
-                        _self.deleteEntry(child.entryName)
-                    }
-                })
-            }
-            entryList.splice(entryList.indexOf(entry), 1);
-            delete(entryTable[entryName]);
-            mainHeader.totalEntries = entryList.length;
-        },
-
-        /**
-         *  Iterates and returns all nested files and directories of the given entry
-         *
-         * @param entry
-         * @return Array
-         */
-        getEntryChildren : function(/*ZipEntry*/entry) {
-            if (entry.isDirectory) {
-                var list = [],
-                    name = entry.entryName,
-                    len = name.length;
-
-                entryList.forEach(function(zipEntry) {
-                    if (zipEntry.entryName.substr(0, len) == name) {
-                        list.push(zipEntry);
-                    }
-                });
-                return list;
-            }
-            return []
-        },
-
-        /**
-         * Returns the zip file
-         *
-         * @return Buffer
-         */
-        compressToBuffer : function() {
-            if (entryList.length > 1) {
-                entryList.sort(function(a, b) {
-                    var nameA = a.entryName.toLowerCase();
-                    var nameB = b.entryName.toLowerCase();
-                    if (nameA < nameB) {return -1}
-                    if (nameA > nameB) {return 1}
-                    return 0;
-                });
-            }
-
-            var totalSize = 0,
-                dataBlock = [],
-                entryHeaders = [],
-                dindex = 0;
-
-            mainHeader.size = 0;
-            mainHeader.offset = 0;
-
-            entryList.forEach(function(entry) {
-                entry.header.offset = dindex;
-
-                // compress data and set local and entry header accordingly. Reason why is called first
-                var compressedData = entry.getCompressedData();
-                // data header
-                var dataHeader = entry.header.dataHeaderToBinary();
-                var postHeader = new Buffer(entry.entryName + entry.extra.toString());
-                var dataLength = dataHeader.length + postHeader.length + compressedData.length;
-
-                dindex += dataLength;
-
-                dataBlock.push(dataHeader);
-                dataBlock.push(postHeader);
-                dataBlock.push(compressedData);
-
-                var entryHeader = entry.packHeader();
-                entryHeaders.push(entryHeader);
-                mainHeader.size += entryHeader.length;
-                totalSize += (dataLength + entryHeader.length);
-            });
-
-            totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
-            // point to end of data and begining of central directory first record
-            mainHeader.offset = dindex;
-
-            dindex = 0;
-            var outBuffer = new Buffer(totalSize);
-            dataBlock.forEach(function(content) {
-                content.copy(outBuffer, dindex); // write data blocks
-                dindex += content.length;
-            });
-            entryHeaders.forEach(function(content) {
-                content.copy(outBuffer, dindex); // write central directory entries
-                dindex += content.length;
-            });
-
-            var mh = mainHeader.toBinary();
-            if (_comment) {
-                _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
-            }
-
-            mh.copy(outBuffer, dindex); // write main header
-
-            return outBuffer
-        },
-
-        toAsyncBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) {
-            if (entryList.length > 1) {
-                entryList.sort(function(a, b) {
-                    var nameA = a.entryName.toLowerCase();
-                    var nameB = b.entryName.toLowerCase();
-                    if (nameA > nameB) {return -1}
-                    if (nameA < nameB) {return 1}
-                    return 0;
-                });
-            }
-
-            var totalSize = 0,
-                dataBlock = [],
-                entryHeaders = [],
-                dindex = 0;
-
-            mainHeader.size = 0;
-            mainHeader.offset = 0;
-
-            var compress=function(entryList){
-                var self=arguments.callee;
-                var entry;
-                if(entryList.length){
-                    var entry=entryList.pop();
-                    var name=entry.entryName + entry.extra.toString();
-                    if(onItemStart)onItemStart(name);
-                    entry.getCompressedDataAsync(function(compressedData){
-                        if(onItemEnd)onItemEnd(name);
-
-                        entry.header.offset = dindex;
-                        // data header
-                        var dataHeader = entry.header.dataHeaderToBinary();
-                        var postHeader = new Buffer(name);
-                        var dataLength = dataHeader.length + postHeader.length + compressedData.length;
-
-                        dindex += dataLength;
-
-                        dataBlock.push(dataHeader);
-                        dataBlock.push(postHeader);
-                        dataBlock.push(compressedData);
-
-                        var entryHeader = entry.packHeader();
-                        entryHeaders.push(entryHeader);
-                        mainHeader.size += entryHeader.length;
-                        totalSize += (dataLength + entryHeader.length);
-
-                        if(entryList.length){
-                            self(entryList);
-                        }else{
-
-
-                            totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
-                            // point to end of data and begining of central directory first record
-                            mainHeader.offset = dindex;
-
-                            dindex = 0;
-                            var outBuffer = new Buffer(totalSize);
-                            dataBlock.forEach(function(content) {
-                                content.copy(outBuffer, dindex); // write data blocks
-                                dindex += content.length;
-                            });
-                            entryHeaders.forEach(function(content) {
-                                content.copy(outBuffer, dindex); // write central directory entries
-                                dindex += content.length;
-                            });
-
-                            var mh = mainHeader.toBinary();
-                            if (_comment) {
-                                _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
-                            }
-
-                            mh.copy(outBuffer, dindex); // write main header
-
-                            onSuccess(outBuffer);
-                        }
-                    });
-                }
-            };
-
-            compress(entryList);
-        }
-    }
-};
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-regex/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-regex/package.json
index ef8dbf4c8..cf8a52db5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-regex/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-regex/package.json
@@ -1,41 +1,19 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "ansi-regex@^2.0.0",
-        "scope": null,
-        "escapedName": "ansi-regex",
-        "name": "ansi-regex",
-        "rawSpec": "^2.0.0",
-        "spec": ">=2.0.0 <3.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi"
-    ]
-  ],
-  "_from": "ansi-regex@>=2.0.0 <3.0.0",
+  "_from": "ansi-regex@^2.0.0",
   "_id": "ansi-regex@2.1.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
   "_location": "/ansi-regex",
-  "_nodeVersion": "0.10.32",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/ansi-regex-2.1.1.tgz_1484363378013_0.4482989883981645"
-  },
-  "_npmUser": {
-    "name": "qix",
-    "email": "i.am.qix@gmail.com"
-  },
-  "_npmVersion": "2.14.2",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "ansi-regex@^2.0.0",
-    "scope": null,
-    "escapedName": "ansi-regex",
     "name": "ansi-regex",
+    "escapedName": "ansi-regex",
     "rawSpec": "^2.0.0",
-    "spec": ">=2.0.0 <3.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^2.0.0"
   },
   "_requiredBy": [
     "/has-ansi",
@@ -43,9 +21,8 @@
   ],
   "_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
   "_shasum": "c3b33ab5ee360d86e0e628f0468ae7ef27d654df",
-  "_shrinkwrap": null,
   "_spec": "ansi-regex@^2.0.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/has-ansi",
   "author": {
     "name": "Sindre Sorhus",
     "email": "sindresorhus@gmail.com",
@@ -54,24 +31,19 @@
   "bugs": {
     "url": "https://github.com/chalk/ansi-regex/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Regular expression for matching ANSI escape codes",
   "devDependencies": {
     "ava": "0.17.0",
     "xo": "0.16.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "c3b33ab5ee360d86e0e628f0468ae7ef27d654df",
-    "tarball": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
-  },
   "engines": {
     "node": ">=0.10.0"
   },
   "files": [
     "index.js"
   ],
-  "gitHead": "7c908e7b4eb6cd82bfe1295e33fdf6d166c7ed85",
   "homepage": "https://github.com/chalk/ansi-regex#readme",
   "keywords": [
     "ansi",
@@ -103,17 +75,22 @@
   "license": "MIT",
   "maintainers": [
     {
-      "name": "qix",
-      "email": "i.am.qix@gmail.com"
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
+    },
+    {
+      "name": "Joshua Appelman",
+      "email": "jappelman@xebia.com",
+      "url": "jbnicolai.com"
     },
     {
-      "name": "sindresorhus",
-      "email": "sindresorhus@gmail.com"
+      "name": "JD Ballard",
+      "email": "i.am.qix@gmail.com",
+      "url": "github.com/qix-"
     }
   ],
   "name": "ansi-regex",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/chalk/ansi-regex.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-styles/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-styles/package.json
index 68f0c461c..e70736e7a 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-styles/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ansi-styles/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "ansi-styles@^2.2.1",
-        "scope": null,
-        "escapedName": "ansi-styles",
-        "name": "ansi-styles",
-        "rawSpec": "^2.2.1",
-        "spec": ">=2.2.1 <3.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk"
-    ]
-  ],
-  "_from": "ansi-styles@>=2.2.1 <3.0.0",
+  "_from": "ansi-styles@^2.2.1",
   "_id": "ansi-styles@2.2.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
   "_location": "/ansi-styles",
-  "_nodeVersion": "4.3.0",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/ansi-styles-2.2.1.tgz_1459197317833_0.9694824463222176"
-  },
-  "_npmUser": {
-    "name": "sindresorhus",
-    "email": "sindresorhus@gmail.com"
-  },
-  "_npmVersion": "3.8.3",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "ansi-styles@^2.2.1",
-    "scope": null,
-    "escapedName": "ansi-styles",
     "name": "ansi-styles",
+    "escapedName": "ansi-styles",
     "rawSpec": "^2.2.1",
-    "spec": ">=2.2.1 <3.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^2.2.1"
   },
   "_requiredBy": [
     "/chalk"
   ],
   "_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
   "_shasum": "b432dd3358b634cf75e1e4664368240533c1ddbe",
-  "_shrinkwrap": null,
   "_spec": "ansi-styles@^2.2.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/chalk",
   "author": {
     "name": "Sindre Sorhus",
     "email": "sindresorhus@gmail.com",
@@ -53,23 +30,18 @@
   "bugs": {
     "url": "https://github.com/chalk/ansi-styles/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "ANSI escape codes for styling strings in the terminal",
   "devDependencies": {
     "mocha": "*"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "b432dd3358b634cf75e1e4664368240533c1ddbe",
-    "tarball": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
-  },
   "engines": {
     "node": ">=0.10.0"
   },
   "files": [
     "index.js"
   ],
-  "gitHead": "95c59b23be760108b6530ca1c89477c21b258032",
   "homepage": "https://github.com/chalk/ansi-styles#readme",
   "keywords": [
     "ansi",
@@ -96,13 +68,17 @@
   "license": "MIT",
   "maintainers": [
     {
-      "name": "sindresorhus",
-      "email": "sindresorhus@gmail.com"
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
+    },
+    {
+      "name": "Joshua Appelman",
+      "email": "jappelman@xebia.com",
+      "url": "jbnicolai.com"
     }
   ],
   "name": "ansi-styles",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/chalk/ansi-styles.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/array-flatten/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/array-flatten/package.json
index 16d80c2e5..787a2467a 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/array-flatten/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/array-flatten/package.json
@@ -1,46 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "array-flatten@1.1.1",
-        "scope": null,
-        "escapedName": "array-flatten",
-        "name": "array-flatten",
-        "rawSpec": "1.1.1",
-        "spec": "1.1.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "array-flatten@1.1.1",
   "_id": "array-flatten@1.1.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
   "_location": "/array-flatten",
-  "_nodeVersion": "2.3.3",
-  "_npmUser": {
-    "name": "blakeembrey",
-    "email": "hello@blakeembrey.com"
-  },
-  "_npmVersion": "2.11.3",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "array-flatten@1.1.1",
-    "scope": null,
-    "escapedName": "array-flatten",
     "name": "array-flatten",
+    "escapedName": "array-flatten",
     "rawSpec": "1.1.1",
-    "spec": "1.1.1",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "1.1.1"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
   "_shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2",
-  "_shrinkwrap": null,
   "_spec": "array-flatten@1.1.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Blake Embrey",
     "email": "hello@blakeembrey.com",
@@ -49,7 +30,8 @@
   "bugs": {
     "url": "https://github.com/blakeembrey/array-flatten/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Flatten an array of nested arrays into a single flat array",
   "devDependencies": {
     "istanbul": "^0.3.13",
@@ -57,16 +39,10 @@
     "pre-commit": "^1.0.7",
     "standard": "^3.7.3"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2",
-    "tarball": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
-  },
   "files": [
     "array-flatten.js",
     "LICENSE"
   ],
-  "gitHead": "1963a9189229d408e1e8f585a00c8be9edbd1803",
   "homepage": "https://github.com/blakeembrey/array-flatten",
   "keywords": [
     "array",
@@ -76,15 +52,7 @@
   ],
   "license": "MIT",
   "main": "array-flatten.js",
-  "maintainers": [
-    {
-      "name": "blakeembrey",
-      "email": "hello@blakeembrey.com"
-    }
-  ],
   "name": "array-flatten",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git://github.com/blakeembrey/array-flatten.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/History.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/History.md
index 559e06327..13d463ab1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/History.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/History.md
@@ -1,3 +1,20 @@
+3.0.0 / 2017-08-31
+==================
+
+  * Change "kB" to "KB" in format output
+  * Remove support for Node.js 0.6
+  * Remove support for ComponentJS
+
+2.5.0 / 2017-03-24
+==================
+
+  * Add option "unit"
+
+2.4.0 / 2016-06-01
+==================
+
+  * Add option "unitSeparator"
+
 2.3.0 / 2016-02-15
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/Readme.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/Readme.md
index dd19ff28e..9b53745d1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/Readme.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/Readme.md
@@ -3,24 +3,35 @@
 [![NPM Version][npm-image]][npm-url]
 [![NPM Downloads][downloads-image]][downloads-url]
 [![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
 
 Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa.
 
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```bash
+$ npm install bytes
+```
+
 ## Usage
 
 ```js
 var bytes = require('bytes');
 ```
 
-#### bytes.format(number value, [options]): string|null
+#### bytes.format(number value, [options]): string|null
 
 Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is
  rounded.
 
 **Arguments**
 
-| Name    | Type   | Description        |
-|---------|--------|--------------------|
+| Name    | Type     | Description        |
+|---------|----------|--------------------|
 | value   | `number` | Value in bytes     |
 | options | `Object` | Conversion options |
 
@@ -28,21 +39,23 @@ Format the given value in bytes into a string. If the value is negative, it is k
 
 | Property          | Type   | Description                                                                             |
 |-------------------|--------|-----------------------------------------------------------------------------------------|
-| decimalPlaces | `number`&#124;`null` | Maximum number of decimal places to include in output. Default value to `2`. |
-| fixedDecimals | `boolean`&#124;`null` | Whether to always display the maximum number of decimal places. Default value to `false` |
-| thousandsSeparator | `string`&#124;`null` | Example of values: `' '`, `','` and `.`... Default value to `' '`. |
+| decimalPlaces | `number`|`null` | Maximum number of decimal places to include in output. Default value to `2`. |
+| fixedDecimals | `boolean`|`null` | Whether to always display the maximum number of decimal places. Default value to `false` |
+| thousandsSeparator | `string`|`null` | Example of values: `' '`, `','` and `.`... Default value to `''`. |
+| unit | `string`|`null` | The unit in which the result will be returned (B/KB/MB/GB/TB). Default value to `''` (which means auto detect). |
+| unitSeparator | `string`|`null` | Separator to use between number and unit. Default value to `''`. |
 
 **Returns**
 
-| Name    | Type        | Description             |
-|---------|-------------|-------------------------|
-| results | `string`&#124;`null` | Return null upon error. String value otherwise. |
+| Name    | Type             | Description                                     |
+|---------|------------------|-------------------------------------------------|
+| results | `string`|`null` | Return null upon error. String value otherwise. |
 
 **Example**
 
 ```js
 bytes(1024);
-// output: '1kB'
+// output: '1KB'
 
 bytes(1000);
 // output: '1000B'
@@ -51,20 +64,25 @@ bytes(1000, {thousandsSeparator: ' '});
 // output: '1 000B'
 
 bytes(1024 * 1.7, {decimalPlaces: 0});
-// output: '2kB'
+// output: '2KB'
+
+bytes(1024, {unitSeparator: ' '});
+// output: '1 KB'
+
 ```
 
-#### bytes.parse(string value): number|null
+#### bytes.parse(string|number value): number|null
 
-Parse the string value into an integer in bytes. If no unit is given, it is assumed the value is in bytes.
+Parse the string value into an integer in bytes. If no unit is given, or `value`
+is a number, it is assumed the value is in bytes.
 
 Supported units and abbreviations are as follows and are case-insensitive:
 
-  * "b" for bytes
-  * "kb" for kilobytes
-  * "mb" for megabytes
-  * "gb" for gigabytes
-  * "tb" for terabytes
+  * `b` for bytes
+  * `kb` for kilobytes
+  * `mb` for megabytes
+  * `gb` for gigabytes
+  * `tb` for terabytes
 
 The units are in powers of two, not ten. This means 1kb = 1024b according to this parser.
 
@@ -72,34 +90,30 @@ The units are in powers of two, not ten. This means 1kb = 1024b according to thi
 
 | Name          | Type   | Description        |
 |---------------|--------|--------------------|
-| value   | `string` | String to parse.   |
+| value   | `string`|`number` | String to parse, or number in bytes.   |
 
 **Returns**
 
 | Name    | Type        | Description             |
 |---------|-------------|-------------------------|
-| results | `number`&#124;`null` | Return null upon error. Value in bytes otherwise. |
+| results | `number`|`null` | Return null upon error. Value in bytes otherwise. |
 
 **Example**
 
 ```js
-bytes('1kB');
+bytes('1KB');
 // output: 1024
 
 bytes('1024');
 // output: 1024
-```
-
-## Installation
 
-```bash
-npm install bytes --save
-component install visionmedia/bytes.js
+bytes(1024);
+// output: 1024
 ```
 
 ## License 
 
-[![npm](https://img.shields.io/npm/l/express.svg)](https://github.com/visionmedia/bytes.js/blob/master/LICENSE)
+[MIT](LICENSE)
 
 [downloads-image]: https://img.shields.io/npm/dm/bytes.svg
 [downloads-url]: https://npmjs.org/package/bytes
@@ -107,3 +121,5 @@ component install visionmedia/bytes.js
 [npm-url]: https://npmjs.org/package/bytes
 [travis-image]: https://img.shields.io/travis/visionmedia/bytes.js/master.svg
 [travis-url]: https://travis-ci.org/visionmedia/bytes.js
+[coveralls-image]: https://img.shields.io/coveralls/visionmedia/bytes.js/master.svg
+[coveralls-url]: https://coveralls.io/r/visionmedia/bytes.js?branch=master
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/index.js
index f71cca74f..1e39afd1d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/index.js
@@ -33,9 +33,6 @@ var map = {
   tb: ((1 << 30) * 1024)
 };
 
-// TODO: use is-finite module?
-var numberIsFinite = Number.isFinite || function (v) { return typeof v === 'number' && isFinite(v); };
-
 var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i;
 
 /**
@@ -47,6 +44,7 @@ var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i;
  *  decimalPlaces: [number]
  *  fixedDecimals: [boolean]
  *  thousandsSeparator: [string]
+ *  unitSeparator: [string]
  *  }} [options] bytes options.
  *
  * @returns {string|number|null}
@@ -75,30 +73,37 @@ function bytes(value, options) {
  * @param {number} [options.decimalPlaces=2]
  * @param {number} [options.fixedDecimals=false]
  * @param {string} [options.thousandsSeparator=]
+ * @param {string} [options.unit=]
+ * @param {string} [options.unitSeparator=]
  *
  * @returns {string|null}
  * @public
  */
 
 function format(value, options) {
-  if (!numberIsFinite(value)) {
+  if (!Number.isFinite(value)) {
     return null;
   }
 
   var mag = Math.abs(value);
   var thousandsSeparator = (options && options.thousandsSeparator) || '';
+  var unitSeparator = (options && options.unitSeparator) || '';
   var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
   var fixedDecimals = Boolean(options && options.fixedDecimals);
-  var unit = 'B';
-
-  if (mag >= map.tb) {
-    unit = 'TB';
-  } else if (mag >= map.gb) {
-    unit = 'GB';
-  } else if (mag >= map.mb) {
-    unit = 'MB';
-  } else if (mag >= map.kb) {
-    unit = 'kB';
+  var unit = (options && options.unit) || '';
+
+  if (!unit || !map[unit.toLowerCase()]) {
+    if (mag >= map.tb) {
+      unit = 'TB';
+    } else if (mag >= map.gb) {
+      unit = 'GB';
+    } else if (mag >= map.mb) {
+      unit = 'MB';
+    } else if (mag >= map.kb) {
+      unit = 'KB';
+    } else {
+      unit = 'B';
+    }
   }
 
   var val = value / map[unit.toLowerCase()];
@@ -112,7 +117,7 @@ function format(value, options) {
     str = str.replace(formatThousandsRegExp, thousandsSeparator);
   }
 
-  return str + unit;
+  return str + unitSeparator + unit;
 }
 
 /**
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/package.json
index 19ad7cc8a..f6f388871 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/bytes/package.json
@@ -1,50 +1,29 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "bytes@2.3.0",
-        "scope": null,
-        "escapedName": "bytes",
-        "name": "bytes",
-        "rawSpec": "2.3.0",
-        "spec": "2.3.0",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression"
-    ]
-  ],
-  "_from": "bytes@2.3.0",
-  "_id": "bytes@2.3.0",
-  "_inCache": true,
+  "_from": "bytes@3.0.0",
+  "_id": "bytes@3.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
   "_location": "/bytes",
-  "_nodeVersion": "4.2.3",
-  "_npmOperationalInternal": {
-    "host": "packages-6-west.internal.npmjs.com",
-    "tmp": "tmp/bytes-2.3.0.tgz_1455595208428_0.5990735022351146"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.14.7",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "bytes@2.3.0",
-    "scope": null,
-    "escapedName": "bytes",
+    "type": "version",
+    "registry": true,
+    "raw": "bytes@3.0.0",
     "name": "bytes",
-    "rawSpec": "2.3.0",
-    "spec": "2.3.0",
-    "type": "version"
+    "escapedName": "bytes",
+    "rawSpec": "3.0.0",
+    "saveSpec": null,
+    "fetchSpec": "3.0.0"
   },
   "_requiredBy": [
-    "/compression"
+    "/body-parser",
+    "/compression",
+    "/raw-body"
   ],
-  "_resolved": "https://registry.npmjs.org/bytes/-/bytes-2.3.0.tgz",
-  "_shasum": "d5b680a165b6201739acb611542aabc2d8ceb070",
-  "_shrinkwrap": null,
-  "_spec": "bytes@2.3.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression",
+  "_resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+  "_shasum": "d32815404d689699f85a4ea4fa8755dd13a96048",
+  "_spec": "bytes@3.0.0",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/compression",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca",
@@ -53,11 +32,7 @@
   "bugs": {
     "url": "https://github.com/visionmedia/bytes.js/issues"
   },
-  "component": {
-    "scripts": {
-      "bytes/index.js": "index.js"
-    }
-  },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Jed Watson",
@@ -68,15 +43,14 @@
       "email": "theo.fidry@gmail.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Utility to parse a string bytes to bytes and vice-versa",
   "devDependencies": {
-    "mocha": "1.21.5"
+    "mocha": "2.5.3",
+    "nyc": "10.3.2"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "d5b680a165b6201739acb611542aabc2d8ceb070",
-    "tarball": "https://registry.npmjs.org/bytes/-/bytes-2.3.0.tgz"
+  "engines": {
+    "node": ">= 0.8"
   },
   "files": [
     "History.md",
@@ -84,7 +58,6 @@
     "Readme.md",
     "index.js"
   ],
-  "gitHead": "c8be41b24b04e04992d5918356d5a4dd35fbf805",
   "homepage": "https://github.com/visionmedia/bytes.js#readme",
   "keywords": [
     "byte",
@@ -96,25 +69,15 @@
     "converter"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    }
-  ],
   "name": "bytes",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/visionmedia/bytes.js.git"
   },
   "scripts": {
-    "test": "mocha --check-leaks --reporter spec"
+    "test": "mocha --check-leaks --reporter spec",
+    "test-ci": "nyc --reporter=text npm test",
+    "test-cov": "nyc --reporter=html --reporter=text npm test"
   },
-  "version": "2.3.0"
+  "version": "3.0.0"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/chalk/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/chalk/package.json
index 6056177c7..f578c43e1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/chalk/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/chalk/package.json
@@ -1,53 +1,31 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "chalk@^1.1.1",
-        "scope": null,
-        "escapedName": "chalk",
-        "name": "chalk",
-        "rawSpec": "^1.1.1",
-        "spec": ">=1.1.1 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve"
-    ]
-  ],
-  "_from": "chalk@>=1.1.1 <2.0.0",
+  "_from": "chalk@^1.1.1",
   "_id": "chalk@1.1.3",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
   "_location": "/chalk",
-  "_nodeVersion": "0.10.32",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/chalk-1.1.3.tgz_1459210604109_0.3892582862172276"
-  },
-  "_npmUser": {
-    "name": "qix",
-    "email": "i.am.qix@gmail.com"
-  },
-  "_npmVersion": "2.14.2",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "chalk@^1.1.1",
-    "scope": null,
-    "escapedName": "chalk",
     "name": "chalk",
+    "escapedName": "chalk",
     "rawSpec": "^1.1.1",
-    "spec": ">=1.1.1 <2.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^1.1.1"
   },
   "_requiredBy": [
     "/cordova-serve"
   ],
   "_resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
   "_shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98",
-  "_shrinkwrap": null,
   "_spec": "chalk@^1.1.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/cordova-serve",
   "bugs": {
     "url": "https://github.com/chalk/chalk/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
     "ansi-styles": "^2.2.1",
     "escape-string-regexp": "^1.0.2",
@@ -55,6 +33,7 @@
     "strip-ansi": "^3.0.0",
     "supports-color": "^2.0.0"
   },
+  "deprecated": false,
   "description": "Terminal string styling done right. Much color.",
   "devDependencies": {
     "coveralls": "^2.11.2",
@@ -66,18 +45,12 @@
     "semver": "^4.3.3",
     "xo": "*"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98",
-    "tarball": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz"
-  },
   "engines": {
     "node": ">=0.10.0"
   },
   "files": [
     "index.js"
   ],
-  "gitHead": "0d8d8c204eb87a4038219131ad4d8369c9f59d24",
   "homepage": "https://github.com/chalk/chalk#readme",
   "keywords": [
     "color",
@@ -105,21 +78,22 @@
   "license": "MIT",
   "maintainers": [
     {
-      "name": "qix",
-      "email": "i.am.qix@gmail.com"
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
     },
     {
-      "name": "sindresorhus",
-      "email": "sindresorhus@gmail.com"
+      "name": "Joshua Appelman",
+      "email": "jappelman@xebia.com",
+      "url": "jbnicolai.com"
     },
     {
-      "name": "unicorn",
-      "email": "sindresorhus+unicorn@gmail.com"
+      "name": "JD Ballard",
+      "email": "i.am.qix@gmail.com",
+      "url": "github.com/qix-"
     }
   ],
   "name": "chalk",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/chalk/chalk.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/HISTORY.md
index 689678432..a4d38d1ed 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/HISTORY.md
@@ -1,3 +1,18 @@
+2.0.12 / 2017-10-20
+===================
+
+  * deps: mime-db@'>= 1.30.0 < 2'
+
+2.0.11 / 2017-07-27
+===================
+
+  * deps: mime-db@'>= 1.29.0 < 2'
+
+2.0.10 / 2017-03-23
+===================
+
+  * deps: mime-db@'>= 1.27.0 < 2'
+
 2.0.9 / 2016-10-31
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/README.md
index 6d8699d46..44029372b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/README.md
@@ -10,12 +10,14 @@ Compressible `Content-Type` / `mime` checking.
 
 ## Installation
 
-```bash
+```sh
 $ npm install compressible
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var compressible = require('compressible')
 ```
@@ -37,6 +39,8 @@ this module will fallback to `true` for the following types:
 If this module is not sure if a type is specifically compressible or specifically
 uncompressible, `undefined` is returned.
 
+<!-- eslint-disable no-undef -->
+
 ```js
 compressible('text/html') // => true
 compressible('image/png') // => false
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/index.js
index bf14ad72b..1184adad5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/index.js
@@ -20,8 +20,8 @@ var db = require('mime-db')
  * @private
  */
 
-var compressibleTypeRegExp = /^text\/|\+json$|\+text$|\+xml$/i
-var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/
+var COMPRESSIBLE_TYPE_REGEXP = /^text\/|\+(?:json|text|xml)$/i
+var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/
 
 /**
  * Module exports.
@@ -44,7 +44,7 @@ function compressible (type) {
   }
 
   // strip parameters
-  var match = extractTypeRegExp.exec(type)
+  var match = EXTRACT_TYPE_REGEXP.exec(type)
   var mime = match && match[1].toLowerCase()
   var data = db[mime]
 
@@ -54,5 +54,5 @@ function compressible (type) {
   }
 
   // fallback to regexp or unknown
-  return compressibleTypeRegExp.test(mime) || undefined
+  return COMPRESSIBLE_TYPE_REGEXP.test(mime) || undefined
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/package.json
index 404f4d181..27d871a3e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compressible/package.json
@@ -1,52 +1,31 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "compressible@~2.0.8",
-        "scope": null,
-        "escapedName": "compressible",
-        "name": "compressible",
-        "rawSpec": "~2.0.8",
-        "spec": ">=2.0.8 <2.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression"
-    ]
-  ],
-  "_from": "compressible@>=2.0.8 <2.1.0",
-  "_id": "compressible@2.0.9",
-  "_inCache": true,
+  "_from": "compressible@~2.0.11",
+  "_id": "compressible@2.0.12",
+  "_inBundle": false,
+  "_integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=",
   "_location": "/compressible",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/compressible-2.0.9.tgz_1477956262136_0.9366124230436981"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "compressible@~2.0.8",
-    "scope": null,
-    "escapedName": "compressible",
+    "type": "range",
+    "registry": true,
+    "raw": "compressible@~2.0.11",
     "name": "compressible",
-    "rawSpec": "~2.0.8",
-    "spec": ">=2.0.8 <2.1.0",
-    "type": "range"
+    "escapedName": "compressible",
+    "rawSpec": "~2.0.11",
+    "saveSpec": null,
+    "fetchSpec": "~2.0.11"
   },
   "_requiredBy": [
     "/compression"
   ],
-  "_resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.9.tgz",
-  "_shasum": "6daab4e2b599c2770dd9e21e7a891b1c5a755425",
-  "_shrinkwrap": null,
-  "_spec": "compressible@~2.0.8",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression",
+  "_resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz",
+  "_shasum": "c59a5c99db76767e9876500e271ef63b3493bd66",
+  "_spec": "compressible@~2.0.11",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/compression",
   "bugs": {
     "url": "https://github.com/jshttp/compressible/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -64,21 +43,20 @@
     }
   ],
   "dependencies": {
-    "mime-db": ">= 1.24.0 < 2"
+    "mime-db": ">= 1.30.0 < 2"
   },
+  "deprecated": false,
   "description": "Compressible Content-Type / mime checking",
   "devDependencies": {
-    "eslint": "3.9.1",
-    "eslint-config-standard": "6.2.1",
-    "eslint-plugin-promise": "3.3.0",
-    "eslint-plugin-standard": "2.0.1",
-    "istanbul": "0.4.5",
-    "mocha": "~1.21.5"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "6daab4e2b599c2770dd9e21e7a891b1c5a755425",
-    "tarball": "https://registry.npmjs.org/compressible/-/compressible-2.0.9.tgz"
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.2.0",
+    "eslint-plugin-promise": "3.6.0",
+    "eslint-plugin-standard": "3.0.1",
+    "mocha": "~1.21.5",
+    "nyc": "11.2.1"
   },
   "engines": {
     "node": ">= 0.6"
@@ -89,8 +67,7 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "9e750e00d459f01b9a16df504f87ad829bf2a518",
-  "homepage": "https://github.com/jshttp/compressible",
+  "homepage": "https://github.com/jshttp/compressible#readme",
   "keywords": [
     "compress",
     "gzip",
@@ -98,48 +75,16 @@
     "content-type"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "defunctzombie",
-      "email": "shtylman@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "federomero",
-      "email": "federomero@gmail.com"
-    },
-    {
-      "name": "fishrock123",
-      "email": "fishrock123@rocketmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "mscdex",
-      "email": "mscdex@mscdex.net"
-    },
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    }
-  ],
   "name": "compressible",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/compressible.git"
   },
   "scripts": {
-    "lint": "eslint .",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail --check-leaks test/",
-    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks",
-    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --check-leaks"
+    "test-cov": "nyc --reporter=html --reporter=text npm test",
+    "test-travis": "nyc --reporter=text npm test"
   },
-  "version": "2.0.9"
+  "version": "2.0.12"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/HISTORY.md
index 663f0de08..3cb6fbb8e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/HISTORY.md
@@ -1,3 +1,33 @@
+1.7.1 / 2017-09-26
+==================
+
+  * deps: accepts@~1.3.4
+    - deps: mime-types@~2.1.16
+  * deps: bytes@3.0.0
+  * deps: compressible@~2.0.11
+    - deps: mime-db@'>= 1.29.0 < 2'
+  * deps: debug@2.6.9
+  * deps: vary@~1.1.2
+    - perf: improve header token parsing speed
+
+1.7.0 / 2017-07-10
+==================
+
+  * Use `safe-buffer` for improved Buffer API
+  * deps: bytes@2.5.0
+  * deps: compressible@~2.0.10
+    - Fix regex fallback to not override `compressible: false` in db
+    - deps: mime-db@'>= 1.27.0 < 2'
+  * deps: debug@2.6.8
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable set to `3` or higher
+    - Fix error when running under React Native
+    - Fix `DEBUG_MAX_ARRAY_LENGTH`
+    - Use same color for same namespace
+    - deps: ms@2.0.0
+  * deps: vary@~1.1.1
+    - perf: hoist regular expression
+
 1.6.2 / 2016-05-12
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/README.md
index a5d599db6..662ba535f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/README.md
@@ -15,12 +15,18 @@ The following compression codings are supported:
 
 ## Install
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```bash
 $ npm install compression
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var compression = require('compression')
 ```
@@ -142,9 +148,13 @@ The default `filter` function. This is used to construct a custom filter
 function that is an extension of the default function.
 
 ```js
+var compression = require('compression')
+var express = require('express')
+
+var app = express()
 app.use(compression({filter: shouldCompress}))
 
-function shouldCompress(req, res) {
+function shouldCompress (req, res) {
   if (req.headers['x-no-compression']) {
     // don't compress responses with this request header
     return false
@@ -173,7 +183,7 @@ var express = require('express')
 
 var app = express()
 
-// compress all requests
+// compress all responses
 app.use(compression())
 
 // add all routes
@@ -191,7 +201,7 @@ actually make it to the client.
 
 ```js
 var compression = require('compression')
-var express     = require('express')
+var express = require('express')
 
 var app = express()
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/index.js
index c0e801e77..f190c6897 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/index.js
@@ -15,6 +15,7 @@
  */
 
 var accepts = require('accepts')
+var Buffer = require('safe-buffer').Buffer
 var bytes = require('bytes')
 var compressible = require('compressible')
 var debug = require('debug')('compression')
@@ -84,7 +85,7 @@ function compression (options) {
       }
 
       return stream
-        ? stream.write(new Buffer(chunk, encoding))
+        ? stream.write(Buffer.from(chunk, encoding))
         : _write.call(this, chunk, encoding)
     }
 
@@ -111,7 +112,7 @@ function compression (options) {
 
       // write Buffer for Node.js 0.8
       return chunk
-        ? stream.end(new Buffer(chunk, encoding))
+        ? stream.end(Buffer.from(chunk, encoding))
         : stream.end()
     }
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/package.json
index 1b339bae5..e88fa64c0 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/compression/package.json
@@ -1,53 +1,31 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "compression@^1.6.0",
-        "scope": null,
-        "escapedName": "compression",
-        "name": "compression",
-        "rawSpec": "^1.6.0",
-        "spec": ">=1.6.0 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve"
-    ]
-  ],
-  "_from": "compression@>=1.6.0 <2.0.0",
-  "_id": "compression@1.6.2",
-  "_inCache": true,
+  "_from": "compression@^1.6.0",
+  "_id": "compression@1.7.1",
+  "_inBundle": false,
+  "_integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=",
   "_location": "/compression",
-  "_nodeVersion": "4.4.3",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/compression-1.6.2.tgz_1463095977791_0.03453603922389448"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.1",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "compression@^1.6.0",
-    "scope": null,
-    "escapedName": "compression",
     "name": "compression",
+    "escapedName": "compression",
     "rawSpec": "^1.6.0",
-    "spec": ">=1.6.0 <2.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^1.6.0"
   },
   "_requiredBy": [
     "/cordova-serve"
   ],
-  "_resolved": "https://registry.npmjs.org/compression/-/compression-1.6.2.tgz",
-  "_shasum": "cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3",
-  "_shrinkwrap": null,
+  "_resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz",
+  "_shasum": "eff2603efc2e22cf86f35d2eb93589f9875373db",
   "_spec": "compression@^1.6.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/cordova-serve",
   "bugs": {
     "url": "https://github.com/expressjs/compression/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -60,28 +38,28 @@
     }
   ],
   "dependencies": {
-    "accepts": "~1.3.3",
-    "bytes": "2.3.0",
-    "compressible": "~2.0.8",
-    "debug": "~2.2.0",
+    "accepts": "~1.3.4",
+    "bytes": "3.0.0",
+    "compressible": "~2.0.11",
+    "debug": "2.6.9",
     "on-headers": "~1.0.1",
-    "vary": "~1.1.0"
+    "safe-buffer": "5.1.1",
+    "vary": "~1.1.2"
   },
+  "deprecated": false,
   "description": "Node.js compression middleware",
   "devDependencies": {
-    "eslint": "2.9.0",
-    "eslint-config-standard": "5.3.1",
-    "eslint-plugin-promise": "1.1.0",
-    "eslint-plugin-standard": "1.3.2",
-    "istanbul": "0.4.3",
-    "mocha": "2.4.5",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "istanbul": "0.4.5",
+    "mocha": "2.5.3",
     "supertest": "1.1.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3",
-    "tarball": "https://registry.npmjs.org/compression/-/compression-1.6.2.tgz"
-  },
   "engines": {
     "node": ">= 0.8.0"
   },
@@ -90,27 +68,18 @@
     "HISTORY.md",
     "index.js"
   ],
-  "gitHead": "b9c63ced82b9f719cd5d9fd250c8432b00752d89",
   "homepage": "https://github.com/expressjs/compression#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "compression",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/expressjs/compression.git"
   },
   "scripts": {
-    "lint": "eslint **/*.js",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --check-leaks --reporter spec --bail",
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot",
     "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec"
   },
-  "version": "1.6.2"
+  "version": "1.7.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-disposition/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-disposition/package.json
index 51dc2d99b..1d2ad519c 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-disposition/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-disposition/package.json
@@ -1,60 +1,38 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "content-disposition@0.5.2",
-        "scope": null,
-        "escapedName": "content-disposition",
-        "name": "content-disposition",
-        "rawSpec": "0.5.2",
-        "spec": "0.5.2",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "content-disposition@0.5.2",
   "_id": "content-disposition@0.5.2",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
   "_location": "/content-disposition",
-  "_nodeVersion": "4.6.0",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/content-disposition-0.5.2.tgz_1481246224565_0.35659545403905213"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.9",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "content-disposition@0.5.2",
-    "scope": null,
-    "escapedName": "content-disposition",
     "name": "content-disposition",
+    "escapedName": "content-disposition",
     "rawSpec": "0.5.2",
-    "spec": "0.5.2",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "0.5.2"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
   "_shasum": "0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4",
-  "_shrinkwrap": null,
   "_spec": "content-disposition@0.5.2",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/jshttp/content-disposition/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Create and parse Content-Disposition header",
   "devDependencies": {
     "eslint": "3.11.1",
@@ -64,11 +42,6 @@
     "istanbul": "0.4.5",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4",
-    "tarball": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -78,7 +51,6 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "2a08417377cf55678c9f870b305f3c6c088920f3",
   "homepage": "https://github.com/jshttp/content-disposition#readme",
   "keywords": [
     "content-disposition",
@@ -87,15 +59,7 @@
     "res"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "content-disposition",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/content-disposition.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/HISTORY.md
index 01652ff46..8f5cb7030 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/HISTORY.md
@@ -1,3 +1,13 @@
+1.0.4 / 2017-09-11
+==================
+
+  * perf: skip parameter parsing when no parameters
+
+1.0.3 / 2017-09-10
+==================
+
+  * perf: remove argument reassignment
+
 1.0.2 / 2016-05-09
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/index.js
index 61ba6b5a2..6ce03f208 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/index.js
@@ -20,9 +20,9 @@
  * obs-text      = %x80-FF
  * quoted-pair   = "\" ( HTAB / SP / VCHAR / obs-text )
  */
-var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g
-var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
-var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
+var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g
+var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
+var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
 
 /**
  * RegExp to match quoted-pair in RFC 7230 sec 3.2.6
@@ -30,21 +30,21 @@ var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
  * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
  * obs-text    = %x80-FF
  */
-var qescRegExp = /\\([\u000b\u0020-\u00ff])/g
+var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g
 
 /**
  * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6
  */
-var quoteRegExp = /([\\"])/g
+var QUOTE_REGEXP = /([\\"])/g
 
 /**
- * RegExp to match type in RFC 6838
+ * RegExp to match type in RFC 7231 sec 3.1.1.1
  *
  * media-type = type "/" subtype
  * type       = token
  * subtype    = token
  */
-var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
+var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
 
 /**
  * Module exports.
@@ -62,7 +62,7 @@ exports.parse = parse
  * @public
  */
 
-function format(obj) {
+function format (obj) {
   if (!obj || typeof obj !== 'object') {
     throw new TypeError('argument obj is required')
   }
@@ -70,7 +70,7 @@ function format(obj) {
   var parameters = obj.parameters
   var type = obj.type
 
-  if (!type || !typeRegExp.test(type)) {
+  if (!type || !TYPE_REGEXP.test(type)) {
     throw new TypeError('invalid type')
   }
 
@@ -84,7 +84,7 @@ function format(obj) {
     for (var i = 0; i < params.length; i++) {
       param = params[i]
 
-      if (!tokenRegExp.test(param)) {
+      if (!TOKEN_REGEXP.test(param)) {
         throw new TypeError('invalid parameter name')
       }
 
@@ -103,61 +103,61 @@ function format(obj) {
  * @public
  */
 
-function parse(string) {
+function parse (string) {
   if (!string) {
     throw new TypeError('argument string is required')
   }
 
-  if (typeof string === 'object') {
-    // support req/res-like objects as argument
-    string = getcontenttype(string)
+  // support req/res-like objects as argument
+  var header = typeof string === 'object'
+    ? getcontenttype(string)
+    : string
 
-    if (typeof string !== 'string') {
-      throw new TypeError('content-type header is missing from object');
-    }
-  }
-
-  if (typeof string !== 'string') {
+  if (typeof header !== 'string') {
     throw new TypeError('argument string is required to be a string')
   }
 
-  var index = string.indexOf(';')
+  var index = header.indexOf(';')
   var type = index !== -1
-    ? string.substr(0, index).trim()
-    : string.trim()
+    ? header.substr(0, index).trim()
+    : header.trim()
 
-  if (!typeRegExp.test(type)) {
+  if (!TYPE_REGEXP.test(type)) {
     throw new TypeError('invalid media type')
   }
 
-  var key
-  var match
   var obj = new ContentType(type.toLowerCase())
-  var value
 
-  paramRegExp.lastIndex = index
+  // parse parameters
+  if (index !== -1) {
+    var key
+    var match
+    var value
 
-  while (match = paramRegExp.exec(string)) {
-    if (match.index !== index) {
-      throw new TypeError('invalid parameter format')
-    }
+    PARAM_REGEXP.lastIndex = index
 
-    index += match[0].length
-    key = match[1].toLowerCase()
-    value = match[2]
+    while ((match = PARAM_REGEXP.exec(header))) {
+      if (match.index !== index) {
+        throw new TypeError('invalid parameter format')
+      }
 
-    if (value[0] === '"') {
-      // remove quotes and escapes
-      value = value
-        .substr(1, value.length - 2)
-        .replace(qescRegExp, '$1')
-    }
+      index += match[0].length
+      key = match[1].toLowerCase()
+      value = match[2]
 
-    obj.parameters[key] = value
-  }
+      if (value[0] === '"') {
+        // remove quotes and escapes
+        value = value
+          .substr(1, value.length - 2)
+          .replace(QESC_REGEXP, '$1')
+      }
 
-  if (index !== -1 && index !== string.length) {
-    throw new TypeError('invalid parameter format')
+      obj.parameters[key] = value
+    }
+
+    if (index !== header.length) {
+      throw new TypeError('invalid parameter format')
+    }
   }
 
   return obj
@@ -171,16 +171,22 @@ function parse(string) {
  * @private
  */
 
-function getcontenttype(obj) {
+function getcontenttype (obj) {
+  var header
+
   if (typeof obj.getHeader === 'function') {
     // res-like
-    return obj.getHeader('content-type')
+    header = obj.getHeader('content-type')
+  } else if (typeof obj.headers === 'object') {
+    // req-like
+    header = obj.headers && obj.headers['content-type']
   }
 
-  if (typeof obj.headers === 'object') {
-    // req-like
-    return obj.headers && obj.headers['content-type']
+  if (typeof header !== 'string') {
+    throw new TypeError('content-type header is missing from object')
   }
+
+  return header
 }
 
 /**
@@ -191,26 +197,26 @@ function getcontenttype(obj) {
  * @private
  */
 
-function qstring(val) {
+function qstring (val) {
   var str = String(val)
 
   // no need to quote tokens
-  if (tokenRegExp.test(str)) {
+  if (TOKEN_REGEXP.test(str)) {
     return str
   }
 
-  if (str.length > 0 && !textRegExp.test(str)) {
+  if (str.length > 0 && !TEXT_REGEXP.test(str)) {
     throw new TypeError('invalid parameter value')
   }
 
-  return '"' + str.replace(quoteRegExp, '\\$1') + '"'
+  return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
 }
 
 /**
  * Class to represent a content type.
  * @private
  */
-function ContentType(type) {
+function ContentType (type) {
   this.parameters = Object.create(null)
   this.type = type
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/package.json
index 82ac8536a..0f34f0402 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/content-type/package.json
@@ -1,50 +1,28 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "content-type@~1.0.2",
-        "scope": null,
-        "escapedName": "content-type",
-        "name": "content-type",
-        "rawSpec": "~1.0.2",
-        "spec": ">=1.0.2 <1.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "content-type@>=1.0.2 <1.1.0",
-  "_id": "content-type@1.0.2",
-  "_inCache": true,
+  "_from": "content-type@~1.0.4",
+  "_id": "content-type@1.0.4",
+  "_inBundle": false,
+  "_integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
   "_location": "/content-type",
-  "_nodeVersion": "4.4.3",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/content-type-1.0.2.tgz_1462852785748_0.5491233412176371"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.1",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "content-type@~1.0.2",
-    "scope": null,
-    "escapedName": "content-type",
+    "type": "range",
+    "registry": true,
+    "raw": "content-type@~1.0.4",
     "name": "content-type",
-    "rawSpec": "~1.0.2",
-    "spec": ">=1.0.2 <1.1.0",
-    "type": "range"
+    "escapedName": "content-type",
+    "rawSpec": "~1.0.4",
+    "saveSpec": null,
+    "fetchSpec": "~1.0.4"
   },
   "_requiredBy": [
+    "/body-parser",
     "/express"
   ],
-  "_resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
-  "_shasum": "b7d113aee7a8dd27bd21133c4dc2529df1721eed",
-  "_shrinkwrap": null,
-  "_spec": "content-type@~1.0.2",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+  "_shasum": "e138cc75e040c727b1966fe5e5f8c9aee256fe3b",
+  "_spec": "content-type@~1.0.4",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -52,17 +30,19 @@
   "bugs": {
     "url": "https://github.com/jshttp/content-type/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Create and parse HTTP Content-Type header",
   "devDependencies": {
-    "istanbul": "0.4.3",
+    "eslint": "3.19.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",
+    "istanbul": "0.4.5",
     "mocha": "~1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "b7d113aee7a8dd27bd21133c4dc2529df1721eed",
-    "tarball": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -72,7 +52,6 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "8118763adfbbac80cf1254191889330aec8b8be7",
   "homepage": "https://github.com/jshttp/content-type#readme",
   "keywords": [
     "content-type",
@@ -82,23 +61,16 @@
     "rfc7231"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "content-type",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/content-type.git"
   },
   "scripts": {
+    "lint": "eslint .",
     "test": "mocha --reporter spec --check-leaks --bail test/",
     "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
   },
-  "version": "1.0.2"
+  "version": "1.0.4"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie-signature/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie-signature/package.json
index d3de0d9d3..cc557441c 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie-signature/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie-signature/package.json
@@ -1,46 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "cookie-signature@1.0.6",
-        "scope": null,
-        "escapedName": "cookie-signature",
-        "name": "cookie-signature",
-        "rawSpec": "1.0.6",
-        "spec": "1.0.6",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "cookie-signature@1.0.6",
   "_id": "cookie-signature@1.0.6",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
   "_location": "/cookie-signature",
-  "_nodeVersion": "0.10.36",
-  "_npmUser": {
-    "name": "natevw",
-    "email": "natevw@yahoo.com"
-  },
-  "_npmVersion": "2.3.0",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "cookie-signature@1.0.6",
-    "scope": null,
-    "escapedName": "cookie-signature",
     "name": "cookie-signature",
+    "escapedName": "cookie-signature",
     "rawSpec": "1.0.6",
-    "spec": "1.0.6",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "1.0.6"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
   "_shasum": "e303a882b342cc3ee8ca513a79999734dab3ae2c",
-  "_shrinkwrap": null,
   "_spec": "cookie-signature@1.0.6",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@learnboost.com"
@@ -48,19 +29,15 @@
   "bugs": {
     "url": "https://github.com/visionmedia/node-cookie-signature/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {},
+  "deprecated": false,
   "description": "Sign and unsign cookies",
   "devDependencies": {
     "mocha": "*",
     "should": "*"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "e303a882b342cc3ee8ca513a79999734dab3ae2c",
-    "tarball": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
-  },
-  "gitHead": "391b56cf44d88c493491b7e3fc53208cfb976d2a",
-  "homepage": "https://github.com/visionmedia/node-cookie-signature",
+  "homepage": "https://github.com/visionmedia/node-cookie-signature#readme",
   "keywords": [
     "cookie",
     "sign",
@@ -68,19 +45,7 @@
   ],
   "license": "MIT",
   "main": "index",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "natevw",
-      "email": "natevw@yahoo.com"
-    }
-  ],
   "name": "cookie-signature",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/visionmedia/node-cookie-signature.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie/package.json
index 6066d9068..00bd39947 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cookie/package.json
@@ -1,49 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "cookie@0.3.1",
-        "scope": null,
-        "escapedName": "cookie",
-        "name": "cookie",
-        "rawSpec": "0.3.1",
-        "spec": "0.3.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "cookie@0.3.1",
   "_id": "cookie@0.3.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
   "_location": "/cookie",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/cookie-0.3.1.tgz_1464323556714_0.6435900838114321"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "cookie@0.3.1",
-    "scope": null,
-    "escapedName": "cookie",
     "name": "cookie",
+    "escapedName": "cookie",
     "rawSpec": "0.3.1",
-    "spec": "0.3.1",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "0.3.1"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
   "_shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb",
-  "_shrinkwrap": null,
   "_spec": "cookie@0.3.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Roman Shtylman",
     "email": "shtylman@gmail.com"
@@ -51,23 +29,19 @@
   "bugs": {
     "url": "https://github.com/jshttp/cookie/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "HTTP server cookie parsing and serialization",
   "devDependencies": {
     "istanbul": "0.4.3",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb",
-    "tarball": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -77,22 +51,13 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "e3c77d497d66c8b8d4b677b8954c1b192a09f0b3",
-  "homepage": "https://github.com/jshttp/cookie",
+  "homepage": "https://github.com/jshttp/cookie#readme",
   "keywords": [
     "cookie",
     "cookies"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "cookie",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/cookie.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/.jshintrc b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/.jshintrc
old mode 100755
new mode 100644
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/README.md
old mode 100755
new mode 100644
index 4d454477d..d65497540
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/README.md
@@ -19,31 +19,62 @@
 #
 -->
 
+[![Build status](https://ci.appveyor.com/api/projects/status/ewv1mhbvms0bfm26?svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-serve/branch/master)
+[![Build Status](https://travis-ci.org/apache/cordova-serve.svg?branch=master)](https://travis-ci.org/apache/cordova-serve)
+[![NPM](https://nodei.co/npm/cordova-serve.png)](https://nodei.co/npm/cordova-serve/)
+
 # cordova-serve
 This module can be used to serve up a Cordova application in the browser. It has no command-line, but rather is intended
 to be called using the following API:
 
 ``` js
-var serve = require('cordova-serve');
-serve.launchServer(opts);
-serve.servePlatform(platform, opts);
-serve.launchBrowser(ops);
+var cordovaServe = require('cordova-serve')();
+cordovaServe.launchServer(opts);
+cordovaServe.servePlatform(platform, opts);
+cordovaServe.launchBrowser(ops);
 ```
 
 ## launchServer()
 
 ``` js
-launchServer(opts);
+var cordovaServe = require('cordova-serve')();
+cordovaServe.launchServer(opts).then(function () {
+    var server = cordovaServe.server;
+    var root = cordovaServe.root;
+    var port = cordovaServe.port;
+
+    ...
+}, function (error) {
+    console.log('An error occurred: ' + error);
+});
 ```
 
 Launches a server with the specified options. Parameters:
 
 * **opts**: Options, as described below.
 
+Returns a promise that is fulfilled once the server has launched, or rejected if the server fails to launch. Once the
+promise is fulfilled, the following properties are available on the `cordovaServe` object:
+ 
+ * **cordovaServe.serve**: The Node http.Server instance.
+ * **cordovaServe.root**: The root that was specified, or cwd if none specified.
+ * **cordovaServe.port**: The port that was used (could be the requested port, the default port, or some incremented
+   value if the chosen port was in use).
+
 ## servePlatform()
 
 ``` js
-servePlatform(platform, opts);
+var cordovaServe = require('cordova-serve')();
+cordovaServe.servePlatform(platform, opts).then(function () {
+    var server = cordovaServe.server;
+    var port = cordovaServe.port;
+    var projectRoot = cordovaServe.projectRoot;
+    var platformRoot = cordovaServe.root;
+
+    ...
+}, function (error) {
+    console.log('An error occurred: ' + error);
+});
 ```
 
 Launches a server that serves up any Cordova platform (e.g. `browser`, `android` etc) from the current project.
@@ -53,10 +84,24 @@ Parameters:
   root folder, or any folder within it - `servePlatform()` will replace it with the platform's `www_dir` folder. If this
   value is not specified, the *cwd* will be used.
 
+Returns a promise that is fulfilled once the server has launched, or rejected if the server fails to launch. Once the
+promise is fulfilled, the following properties are available on the `cordovaServe` object:
+ 
+ * **cordovaServe.serve**: The Node http.Server instance.
+ * **cordovaServe.root**: The requested platform's `www` folder.
+ * **cordovaServe.projectRoot**: The root folder of the Cordova project.
+ * **cordovaServe.port**: The port that was used (could be the requested port, the default port, or some incremented
+   value if the chosen port was in use).
+
 ## launchBrowser()
 
 ``` js
-launchBrowser(opts);
+var cordovaServe = require('cordova-serve')();
+cordovaServe.launchBrowser(opts).then(function (stdout) {
+    console.log('Browser was launched successfully: ' + stdout);
+}, function (error) {
+    console.log('An error occurred: ' + error);
+});
 ```
 
 Launches a browser window pointing to the specified URL. The single parameter is an options object that supports the
@@ -64,7 +109,9 @@ following values (both optional):
 
 * **url**: The URL to open in the browser.
 * **target**: The name of the browser to launch. Can be any of the following: `chrome`, `chromium`, `firefox`, `ie`,
-  `opera`, `safari`. If no browser is specified, 
+  `opera`, `safari`. Defaults to `chrome` if no browser is specified.
+
+Returns a promise that is fulfilled once the browser has been launched, or rejected if an error occurs.
 
 ## The *opts* Options Object
 The opts object passed to `launchServer()` and `servePlatform()` supports the following values (all optional):
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/RELEASENOTES.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/RELEASENOTES.md
old mode 100755
new mode 100644
index cf9eab4a9..549a16f75
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/RELEASENOTES.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/RELEASENOTES.md
@@ -20,16 +20,30 @@
 -->
 # Cordova-serve Release Notes
 
-### 1.0.1 (Dec 21, 2016)
-* CB-12284 Include project root as additional root for static router
+### 2.0.0 (Aug 24, 2017)
+* [CB-13188](https://issues.apache.org/jira/browse/CB-13188) set serve to use default system browser if none is provided.
+* Change to `eslint` instead of `jshint`
+* remove `q` dependence completely. Added `server.spec`
+* added browser tests
+* Convert `src/browser` to use Promise api
+* Add License, Contributing, Notice, pr-template, ...
+* [CB-12785](https://issues.apache.org/jira/browse/CB-12785) added travis and appveyor
+* [CB-12762](https://issues.apache.org/jira/browse/CB-12762): updated common, fetch, and serve pkgJson to point pkgJson repo items to github mirrors
+* [CB-12665](https://issues.apache.org/jira/browse/CB-12665) removed enginestrict since it is deprecated
+* [CB-11977](https://issues.apache.org/jira/browse/CB-11977): updated engines and enginescript for common, fetch, and serve
+
+### 1.0.1 (Jan 17, 2017)
+* [CB-12284](https://issues.apache.org/jira/browse/CB-12284) Include project root as additional root for static router
+* Some corrections and enhancements for cordova-serve readme.
+* On Windows, verify browsers installed before launching.
 
 ### 1.0.0 (Oct 05, 2015)
 * Refactor cordova-serve to use Express.
 
 ### 0.1.3 (Aug 22, 2015)
 * Clean up cordova-serve console output.
-* CB-9546 cordova-serve.servePlatform() should provide project folders
-* CB-9545 Cordova-serve's 'noCache' option does not work in IE.
+* [CB-9546](https://issues.apache.org/jira/browse/CB-9546) cordova-serve.servePlatform() should provide project folders
+* [CB-9545](https://issues.apache.org/jira/browse/CB-9545) Cordova-serve's 'noCache' option does not work in IE.
 * Add support for --target=edge to launch app in Edge browser.
 
 ### 0.1.2 (June 15, 2015)
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/package.json
old mode 100755
new mode 100644
index 8be50564a..64e92dfb5
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "cordova-serve@^1.0.0",
-        "scope": null,
-        "escapedName": "cordova-serve",
-        "name": "cordova-serve",
-        "rawSpec": "^1.0.0",
-        "spec": ">=1.0.0 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser"
-    ]
-  ],
-  "_from": "cordova-serve@>=1.0.0 <2.0.0",
-  "_id": "cordova-serve@1.0.1",
-  "_inCache": true,
+  "_from": "cordova-serve@^2.0.0",
+  "_id": "cordova-serve@2.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-14NLg7GGYH4rjxlD4HPAYzNg6kM=",
   "_location": "/cordova-serve",
-  "_nodeVersion": "6.9.2",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/cordova-serve-1.0.1.tgz_1482379745792_0.331234929850325"
-  },
-  "_npmUser": {
-    "name": "timbarham",
-    "email": "npmjs@barhams.info"
-  },
-  "_npmVersion": "3.10.9",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "cordova-serve@^1.0.0",
-    "scope": null,
-    "escapedName": "cordova-serve",
+    "type": "range",
+    "registry": true,
+    "raw": "cordova-serve@^2.0.0",
     "name": "cordova-serve",
-    "rawSpec": "^1.0.0",
-    "spec": ">=1.0.0 <2.0.0",
-    "type": "range"
+    "escapedName": "cordova-serve",
+    "rawSpec": "^2.0.0",
+    "saveSpec": null,
+    "fetchSpec": "^2.0.0"
   },
   "_requiredBy": [
     "/"
   ],
-  "_resolved": "https://registry.npmjs.org/cordova-serve/-/cordova-serve-1.0.1.tgz",
-  "_shasum": "895c7fb4bbe630fa1c89feaf6d74779cbff66da7",
-  "_shrinkwrap": null,
-  "_spec": "cordova-serve@^1.0.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser",
+  "_resolved": "https://registry.npmjs.org/cordova-serve/-/cordova-serve-2.0.0.tgz",
+  "_shasum": "d7834b83b186607e2b8f1943e073c0633360ea43",
+  "_spec": "cordova-serve@^2.0.0",
+  "_where": "/Users/auso/cordova/cordova-browser",
   "author": {
     "name": "Apache Software Foundation"
   },
@@ -52,67 +29,48 @@
     "url": "https://issues.apache.org/jira/browse/CB",
     "email": "dev@cordova.apache.org"
   },
+  "bundleDependencies": false,
   "dependencies": {
     "chalk": "^1.1.1",
     "compression": "^1.6.0",
     "express": "^4.13.3",
-    "q": "^1.4.1"
+    "open": "0.0.5",
+    "shelljs": "^0.5.3"
   },
+  "deprecated": false,
   "description": "Apache Cordova server support for cordova-lib and cordova-browser.",
   "devDependencies": {
-    "jshint": "^2.8.0"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "895c7fb4bbe630fa1c89feaf6d74779cbff66da7",
-    "tarball": "https://registry.npmjs.org/cordova-serve/-/cordova-serve-1.0.1.tgz"
+    "eslint": "^4.0.0",
+    "eslint-config-semistandard": "^11.0.0",
+    "eslint-config-standard": "^10.2.1",
+    "eslint-plugin-import": "^2.3.0",
+    "eslint-plugin-node": "^5.0.0",
+    "eslint-plugin-promise": "^3.5.0",
+    "eslint-plugin-standard": "^3.0.1",
+    "jasmine": "^2.5.2",
+    "rewire": "^2.5.2"
   },
   "engines": {
-    "node": ">= 0.12.0",
+    "node": ">=4.0.0",
     "npm": ">= 2.5.1"
   },
+  "homepage": "https://github.com/apache/cordova-lib#readme",
   "keywords": [
     "cordova",
     "server",
     "apache"
   ],
   "license": "Apache-2.0",
-  "main": "serve.js",
-  "maintainers": [
-    {
-      "name": "bowserj",
-      "email": "bowserj@apache.org"
-    },
-    {
-      "name": "filmaj",
-      "email": "maj.fil@gmail.com"
-    },
-    {
-      "name": "purplecabbage",
-      "email": "purplecabbage@gmail.com"
-    },
-    {
-      "name": "shazron",
-      "email": "shazron@gmail.com"
-    },
-    {
-      "name": "stevegill",
-      "email": "stevengill97@gmail.com"
-    },
-    {
-      "name": "timbarham",
-      "email": "npmjs@barhams.info"
-    }
-  ],
+  "main": "src/main.js",
   "name": "cordova-serve",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
-    "url": "git://git-wip-us.apache.org/repos/asf/cordova-lib.git"
+    "url": "git+https://github.com/apache/cordova-lib.git"
   },
   "scripts": {
-    "jshint": "node node_modules/jshint/bin/jshint src"
+    "eslint": "node node_modules/eslint/bin/eslint ./src",
+    "jasmine": "jasmine JASMINE_CONFIG_PATH=spec/jasmine.json",
+    "test": "npm run eslint && npm run jasmine"
   },
-  "version": "1.0.1"
+  "version": "2.0.0"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/serve.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/serve.js
deleted file mode 100755
index 10d000a5c..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/serve.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- 'License'); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-var chalk = require('chalk'),
-    compression = require('compression'),
-    express = require('express'),
-    server = require('./src/server');
-
-module.exports = function () {
-    return new CordovaServe();
-};
-
-function CordovaServe() {
-    this.app = express();
-
-    // Attach this before anything else to provide status output
-    this.app.use(function (req, res, next) {
-        res.on('finish', function () {
-            var color = this.statusCode == '404' ? chalk.red : chalk.green;
-            var msg = color(this.statusCode) + ' ' + this.req.originalUrl;
-            var encoding = this._headers && this._headers['content-encoding'];
-            if (encoding) {
-                msg += chalk.gray(' (' + encoding + ')');
-            }
-            server.log(msg);
-        });
-        next();
-    });
-
-    // Turn on compression
-    this.app.use(compression());
-
-    this.servePlatform = require('./src/platform');
-    this.launchServer = server;
-}
-
-module.exports.launchBrowser = require('./src/browser');
-
-// Expose some useful express statics
-module.exports.Router = express.Router;
-module.exports.static = express.static;
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/browser.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/browser.js
old mode 100755
new mode 100644
index c701ca0b8..61f85093b
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/browser.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/browser.js
@@ -17,8 +17,15 @@
  under the License.
  */
 
-var exec = require('./exec'),
-    Q = require('q');
+/* globals Promise: true */
+
+var child_process = require('child_process');
+var fs = require('fs');
+var open = require('open');
+var exec = require('./exec');
+
+var NOT_INSTALLED = 'The browser target is not installed: %target%';
+var NOT_SUPPORTED = 'The browser target is not supported: %target%';
 
 /**
  * Launches the specified browser with the given URL.
@@ -27,31 +34,38 @@ var exec = require('./exec'),
  *   target - the target browser - ie, chrome, safari, opera, firefox or chromium
  *   url - the url to open in the browser
  *   dataDir - a data dir to provide to Chrome (can be used to force it to open in a new window)
- * @return {Q} Promise to launch the specified browser
+ * @return {Promise} Promise to launch the specified browser
  */
 module.exports = function (opts) {
-    var target = opts.target || 'chrome';
+
+    opts = opts || {};
+    var target = opts.target || 'default';
     var url = opts.url || '';
 
-    return getBrowser(target, opts.dataDir).then(function (browser) {
-        var args;
+    target = target.toLowerCase();
+    if (target === 'default') {
+        open(url);
+        return Promise.resolve();
+    } else {
+        return getBrowser(target, opts.dataDir).then(function (browser) {
+            var args;
+            var urlAdded = false;
 
-        var urlAdded = false;
-        switch (process.platform) {
+            switch (process.platform) {
             case 'darwin':
                 args = ['open'];
-                if (target == 'chrome') {
-                    // Chrome needs to be launched in a new window. Other browsers, particularly, opera does not work with this.        
+                if (target === 'chrome') {
+                    // Chrome needs to be launched in a new window. Other browsers, particularly, opera does not work with this.
                     args.push('-n');
                 }
                 args.push('-a', browser);
                 break;
             case 'win32':
-                // On Windows, we really want to use the "start" command. But, the rules regarding arguments with spaces, and 
-                // escaping them with quotes, can get really arcane. So the easiest way to deal with this is to pass off the 
-                // responsibility to "cmd /c", which has that logic built in. 
-                // 
-                // Furthermore, if "cmd /c" double-quoted the first parameter, then "start" will interpret it as a window title, 
+                // On Windows, we really want to use the "start" command. But, the rules regarding arguments with spaces, and
+                // escaping them with quotes, can get really arcane. So the easiest way to deal with this is to pass off the
+                // responsibility to "cmd /c", which has that logic built in.
+                //
+                // Furthermore, if "cmd /c" double-quoted the first parameter, then "start" will interpret it as a window title,
                 // so we need to add a dummy empty-string window title: http://stackoverflow.com/a/154090/3191
 
                 if (target === 'edge') {
@@ -66,17 +80,28 @@ module.exports = function (opts) {
                 // otherwise, use xdg-open.
                 args = [browser];
                 break;
-        }
+            }
 
-        if (!urlAdded) {
-            args.push(url);
-        }
-        var command = args.join(' ');
-        return exec(command);
-    });
+            if (!urlAdded) {
+                args.push(url);
+            }
+            var command = args.join(' ');
+            var result = exec(command);
+            result.catch(function () {
+                // Assume any error means that the browser is not installed and display that as a more friendly error.
+                throw new Error(NOT_INSTALLED.replace('%target%', target));
+            });
+            return result;
+
+            // return exec(command).catch(function (error) {
+            //     // Assume any error means that the browser is not installed and display that as a more friendly error.
+            //     throw new Error(NOT_INSTALLED.replace('%target%', target));
+            // });
+        });
+    }
 };
 
-function getBrowser(target, dataDir) {
+function getBrowser (target, dataDir) {
     dataDir = dataDir || 'temp_chrome_user_data_dir_for_cordova';
 
     var chromeArgs = ' --user-data-dir=/tmp/' + dataDir;
@@ -95,16 +120,119 @@ function getBrowser(target, dataDir) {
             'firefox': 'firefox',
             'opera': 'opera'
         },
-        'linux' : {
-            'chrome': 'google-chrome' + chromeArgs ,
+        'linux': {
+            'chrome': 'google-chrome' + chromeArgs,
             'chromium': 'chromium-browser' + chromeArgs,
             'firefox': 'firefox',
             'opera': 'opera'
         }
     };
-    target = target.toLowerCase();
+
     if (target in browsers[process.platform]) {
-        return Q(browsers[process.platform][target]);
+        var browser = browsers[process.platform][target];
+        return checkBrowserExistsWindows(browser, target).then(function () {
+            return Promise.resolve(browser);
+        });
+    } else {
+        return Promise.reject(NOT_SUPPORTED.replace('%target%', target));
+    }
+
+}
+
+// err might be null, in which case defaultMsg is used.
+// target MUST be defined or an error is thrown.
+function getErrorMessage (err, target, defaultMsg) {
+    var errMessage;
+    if (err) {
+        errMessage = err.toString();
+    } else {
+        errMessage = defaultMsg;
     }
-    return Q.reject('Browser target not supported: ' + target);
+    return errMessage.replace('%target%', target);
+}
+
+function checkBrowserExistsWindows (browser, target) {
+    var promise = new Promise(function (resolve, reject) {
+        // Windows displays a dialog if the browser is not installed. We'd prefer to avoid that.
+        if (process.platform === 'win32') {
+            if (target === 'edge') {
+                edgeSupported().then(function () {
+                    resolve();
+                })
+                    .catch(function (err) {
+                        var errMessage = getErrorMessage(err, target, NOT_INSTALLED);
+                        reject(errMessage);
+                    });
+            } else {
+                browserInstalled(browser).then(function () {
+                    resolve();
+                })
+                    .catch(function (err) {
+                        var errMessage = getErrorMessage(err, target, NOT_INSTALLED);
+                        reject(errMessage);
+                    });
+            }
+        } else {
+            resolve();
+        }
+
+    });
+    return promise;
+}
+
+function edgeSupported () {
+    var prom = new Promise(function (resolve, reject) {
+        child_process.exec('ver', function (err, stdout, stderr) {
+            if (err || stderr) {
+                reject(err || stderr);
+            } else {
+                var windowsVersion = stdout.match(/([0-9.])+/g)[0];
+                if (parseInt(windowsVersion) < 10) {
+                    reject(new Error('The browser target is not supported on this version of Windows: %target%'));
+                } else {
+                    resolve();
+                }
+            }
+        });
+    });
+    return prom;
+}
+
+var regItemPattern = /\s*\(Default\)\s+(REG_SZ)\s+([^\s].*)\s*/;
+function browserInstalled (browser) {
+    // On Windows, the 'start' command searches the path then 'App Paths' in the registry.
+    // We do the same here. Note that the start command uses the PATHEXT environment variable
+    // for the list of extensions to use if no extension is provided. We simplify that to just '.EXE'
+    // since that is what all the supported browsers use. Check path (simple but usually won't get a hit)
+
+    var promise = new Promise(function (resolve, reject) {
+        if (require('shelljs').which(browser)) {
+            return resolve();
+        } else {
+            var regQPre = 'reg QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\';
+            var regQPost = '.EXE" /v ""';
+            var regQuery = regQPre + browser.split(' ')[0] + regQPost;
+
+            child_process.exec(regQuery, function (err, stdout, stderr) {
+                if (err) {
+                    // The registry key does not exist, which just means the app is not installed.
+                    reject(err);
+                } else {
+                    var result = regItemPattern.exec(stdout);
+                    if (fs.existsSync(trimRegPath(result[2]))) {
+                        resolve();
+                    } else {
+                        // The default value is not a file that exists, which means the app is not installed.
+                        reject(new Error(NOT_INSTALLED));
+                    }
+                }
+            });
+        }
+    });
+    return promise;
+}
+
+function trimRegPath (path) {
+    // Trim quotes and whitespace
+    return path.replace(/^[\s"]+|[\s"]+$/g, '');
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/exec.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/exec.js
old mode 100755
new mode 100644
index d1c02a4e6..76d4d0cb9
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/exec.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/exec.js
@@ -17,30 +17,37 @@
  under the License.
  */
 
-var child_process = require('child_process'),
-    Q             = require('q');
+/* globals Promise: true */
+
+var child_process = require('child_process');
 
 /**
  * Executes the command specified.
  * @param  {string} cmd Command to execute
  * @param  {[string]}  opt_cwd Current working directory
- * @return {Q} promise a promise that either resolves with the stdout, or rejects with an error message and the stderr.
+ * @return {Promise} a promise that either resolves with the stdout, or rejects with an error message and the stderr.
  */
 module.exports = function (cmd, opt_cwd) {
-    var d = Q.defer();
-    try {
-        child_process.exec(cmd, {cwd: opt_cwd, maxBuffer: 1024000}, function (err, stdout, stderr) {
-            if (err) {
-                d.reject(new Error('Error executing "' + cmd + '": ' + stderr));
-            }
-            else {
-                d.resolve(stdout);
+    return new Promise(function (resolve, reject) {
+        try {
+            var opt = {cwd: opt_cwd, maxBuffer: 1024000};
+            var timerID = 0;
+            if (process.platform === 'linux') {
+                timerID = setTimeout(function () {
+                    resolve('linux-timeout');
+                }, 5000);
             }
-        });
-    } catch (e) {
-        console.error('error caught: ' + e);
-        d.reject(e);
-    }
-    return d.promise;
+            child_process.exec(cmd, opt, function (err, stdout, stderr) {
+                clearTimeout(timerID);
+                if (err) {
+                    reject(new Error('Error executing "' + cmd + '": ' + stderr));
+                } else {
+                    resolve(stdout);
+                }
+            });
+        } catch (e) {
+            console.error('error caught: ' + e);
+            reject(e);
+        }
+    });
 };
-
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/platform.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/platform.js
old mode 100755
new mode 100644
index 7abbb8103..f98cf2608
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/platform.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/platform.js
@@ -17,9 +17,10 @@
  under the License.
  */
 
-var fs     = require('fs'),
-    Q      = require('q'),
-    util   = require('./util');
+/* globals Promise: true */
+
+var fs = require('fs');
+var util = require('./util');
 
 /**
  * Launches a server where the root points to the specified platform in a Cordova project.
@@ -30,26 +31,31 @@ var fs     = require('fs'),
  * @returns {*|promise}
  */
 module.exports = function (platform, opts) {
+
+    // note: `this` is actually an instance of main.js CordovaServe
+    // this module is a mixin
     var that = this;
-    return Q().then(function () {
+    var retPromise = new Promise(function (resolve, reject) {
         if (!platform) {
-            throw new Error('A platform must be specified');
-        }
-
-        opts = opts || {};
-        var projectRoot = findProjectRoot(opts.root);
-        that.projectRoot = projectRoot;
+            reject(new Error('Error: A platform must be specified'));
+        } else {
+            opts = opts || {};
+            var projectRoot = findProjectRoot(opts.root);
+            that.projectRoot = projectRoot;
+            opts.root = util.getPlatformWwwRoot(projectRoot, platform);
 
-        opts.root = util.getPlatformWwwRoot(projectRoot, platform);
-        if (!fs.existsSync(opts.root)) {
-            throw new Error('Project does not include the specified platform: ' + platform);
+            if (!fs.existsSync(opts.root)) {
+                reject(new Error('Error: Project does not include the specified platform: ' + platform));
+            } else {
+                return resolve(that.launchServer(opts));
+            }
         }
 
-        return that.launchServer(opts);
     });
+    return retPromise;
 };
 
-function findProjectRoot(path) {
+function findProjectRoot (path) {
     var projectRoot = util.cordovaProjectRoot(path);
     if (!projectRoot) {
         if (!path) {
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/server.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/server.js
old mode 100755
new mode 100644
index 9040d2b58..8f4e9ee35
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/server.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/server.js
@@ -17,9 +17,10 @@
  under the License.
  */
 
-var chalk   = require('chalk'),
-    express = require('express'),
-    Q       = require('q');
+/* globals Promise: true */
+
+var chalk = require('chalk');
+var express = require('express');
 
 /**
  * @desc Launches a server with the specified options and optional custom handlers.
@@ -27,56 +28,60 @@ var chalk   = require('chalk'),
  * @returns {*|promise}
  */
 module.exports = function (opts) {
-    var deferred = Q.defer();
-
-    opts = opts || {};
-    var port = opts.port || 8000;
 
-    var log = module.exports.log = function (msg) {
-        if (!opts.noLogOutput) {
-            if (opts.events) {
-                opts.events.emit('log', msg);
-            } else {
-                console.log(msg);
-            }
-        }
-    };
+    var that = this;
+    var promise = new Promise(function (resolve, reject) {
 
-    var app = this.app;
-    var server = require('http').Server(app);
-    this.server = server;
+        opts = opts || {};
+        var port = opts.port || 8000;
 
-    if (opts.router) {
-        app.use(opts.router);
-    }
+        var log = module.exports.log = function (msg) {
+            if (!opts.noLogOutput) {
+                if (opts.events) {
+                    opts.events.emit('log', msg);
+                } else {
+                    console.log(msg);
+                }
+            }
+        };
 
-    if (opts.root) {
-        this.root = opts.root;
-        app.use(express.static(opts.root));
-    }
+        var app = that.app;
+        var server = require('http').Server(app);
+        that.server = server;
 
-    // If we have a project root, make that available as a static root also. This can be useful in cases where source
-    // files that have been transpiled (such as TypeScript) are located under the project root on a path that mirrors
-    // the the transpiled file's path under the platform root and is pointed to by a map file.
-    if (this.projectRoot) {
-        app.use(express.static(this.projectRoot));
-    }
+        if (opts.router) {
+            app.use(opts.router);
+        }
 
-    var that = this;
-    server.listen(port).on('listening', function () {
-        that.port = port;
-        if (!opts.noServerInfo) {
-            log('Static file server running on: ' + chalk.green('http://localhost:' + port) + ' (CTRL + C to shut down)');
+        if (opts.root) {
+            that.root = opts.root;
+            app.use(express.static(opts.root));
         }
-        deferred.resolve();
-    }).on('error', function (e) {
-        if (e && e.toString().indexOf('EADDRINUSE') !== -1) {
-            port++;
-            server.listen(port);
-        } else {
-            deferred.reject(e);
+
+        // If we have a project root, make that available as a static root also. This can be useful in cases where source
+        // files that have been transpiled (such as TypeScript) are located under the project root on a path that mirrors
+        // the the transpiled file's path under the platform root and is pointed to by a map file.
+        if (that.projectRoot) {
+            app.use(express.static(that.projectRoot));
         }
-    });
 
-    return deferred.promise;
+        var listener = server.listen(port);
+        listener.on('listening', function () {
+            that.port = port;
+            var message = 'Static file server running on: ' + chalk.green('http://localhost:' + port) + ' (CTRL + C to shut down)';
+            if (!opts.noServerInfo) {
+                log(message);
+            }
+            resolve(message);
+        });
+        listener.on('error', function (e) {
+            if (e && e.toString().indexOf('EADDRINUSE') > -1) {
+                port++;
+                server.listen(port);
+            } else {
+                reject(e);
+            }
+        });
+    });
+    return promise;
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/util.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/util.js
old mode 100755
new mode 100644
index 8fb076b3a..242e96f37
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/util.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve/src/util.js
@@ -17,8 +17,8 @@
  under the License.
  */
 
-var fs   = require('fs'),
-    path = require('path');
+var fs = require('fs');
+var path = require('path');
 
 // Some helpful utility stuff copied from cordova-lib. This is a bit nicer than taking a dependency on cordova-lib just
 // to get this minimal stuff. Hopefully we won't need the platform stuff (finding platform www_dir) once it is moved
@@ -41,12 +41,12 @@ var platforms = {
  * @param {string=} dir - the directory to start from (we check this directory then work up), or CWD if none specified.
  * @returns {string} - the Cordova project's root directory, or null if not found.
  */
-function cordovaProjectRoot(dir) {
+function cordovaProjectRoot (dir) {
     if (!dir) {
         // Prefer PWD over cwd so that symlinked dirs within your PWD work correctly.
         var pwd = process.env.PWD;
         var cwd = process.cwd();
-        if (pwd && pwd != cwd && pwd != 'undefined') {
+        if (pwd && pwd !== cwd && pwd !== 'undefined') {
             return cordovaProjectRoot(pwd) || cordovaProjectRoot(cwd);
         }
         return cordovaProjectRoot(cwd);
@@ -63,7 +63,7 @@ function cordovaProjectRoot(dir) {
         }
         var parentDir = path.normalize(path.join(dir, '..'));
         // Detect fs root.
-        if (parentDir == dir) {
+        if (parentDir === dir) {
             return bestReturnValueSoFar;
         }
         dir = parentDir;
@@ -71,15 +71,15 @@ function cordovaProjectRoot(dir) {
     return null;
 }
 
-function getPlatformWwwRoot(cordovaProjectRoot, platformName) {
+function getPlatformWwwRoot (cordovaProjectRoot, platformName) {
     var platform = platforms[platformName];
     if (!platform) {
-        throw new Error ('Unrecognized platform: ' + platformName);
+        throw new Error('Unrecognized platform: ' + platformName);
     }
     return path.join(cordovaProjectRoot, 'platforms', platformName, platform.www_dir);
 }
 
-function isRootDir(dir) {
+function isRootDir (dir) {
     if (fs.existsSync(path.join(dir, 'www'))) {
         if (fs.existsSync(path.join(dir, 'config.xml'))) {
             // For sure is.
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.jshintrc b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.jshintrc
deleted file mode 100644
index 299877f26..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.jshintrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "laxbreak": true
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.npmignore b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.npmignore
index 7e6163db0..5f60eecc8 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.npmignore
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/.npmignore
@@ -4,3 +4,6 @@ examples
 example
 *.sock
 dist
+yarn.lock
+coverage
+bower.json
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/History.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/History.md
deleted file mode 100644
index 854c9711c..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/History.md
+++ /dev/null
@@ -1,195 +0,0 @@
-
-2.2.0 / 2015-05-09
-==================
-
-  * package: update "ms" to v0.7.1 (#202, @dougwilson)
-  * README: add logging to file example (#193, @DanielOchoa)
-  * README: fixed a typo (#191, @amir-s)
-  * browser: expose `storage` (#190, @stephenmathieson)
-  * Makefile: add a `distclean` target (#189, @stephenmathieson)
-
-2.1.3 / 2015-03-13
-==================
-
-  * Updated stdout/stderr example (#186)
-  * Updated example/stdout.js to match debug current behaviour
-  * Renamed example/stderr.js to stdout.js
-  * Update Readme.md (#184)
-  * replace high intensity foreground color for bold (#182, #183)
-
-2.1.2 / 2015-03-01
-==================
-
-  * dist: recompile
-  * update "ms" to v0.7.0
-  * package: update "browserify" to v9.0.3
-  * component: fix "ms.js" repo location
-  * changed bower package name
-  * updated documentation about using debug in a browser
-  * fix: security error on safari (#167, #168, @yields)
-
-2.1.1 / 2014-12-29
-==================
-
-  * browser: use `typeof` to check for `console` existence
-  * browser: check for `console.log` truthiness (fix IE 8/9)
-  * browser: add support for Chrome apps
-  * Readme: added Windows usage remarks
-  * Add `bower.json` to properly support bower install
-
-2.1.0 / 2014-10-15
-==================
-
-  * node: implement `DEBUG_FD` env variable support
-  * package: update "browserify" to v6.1.0
-  * package: add "license" field to package.json (#135, @panuhorsmalahti)
-
-2.0.0 / 2014-09-01
-==================
-
-  * package: update "browserify" to v5.11.0
-  * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
-
-1.0.4 / 2014-07-15
-==================
-
-  * dist: recompile
-  * example: remove `console.info()` log usage
-  * example: add "Content-Type" UTF-8 header to browser example
-  * browser: place %c marker after the space character
-  * browser: reset the "content" color via `color: inherit`
-  * browser: add colors support for Firefox >= v31
-  * debug: prefer an instance `log()` function over the global one (#119)
-  * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
-
-1.0.3 / 2014-07-09
-==================
-
-  * Add support for multiple wildcards in namespaces (#122, @seegno)
-  * browser: fix lint
-
-1.0.2 / 2014-06-10
-==================
-
-  * browser: update color palette (#113, @gscottolson)
-  * common: make console logging function configurable (#108, @timoxley)
-  * node: fix %o colors on old node <= 0.8.x
-  * Makefile: find node path using shell/which (#109, @timoxley)
-
-1.0.1 / 2014-06-06
-==================
-
-  * browser: use `removeItem()` to clear localStorage
-  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
-  * package: add "contributors" section
-  * node: fix comment typo
-  * README: list authors
-
-1.0.0 / 2014-06-04
-==================
-
-  * make ms diff be global, not be scope
-  * debug: ignore empty strings in enable()
-  * node: make DEBUG_COLORS able to disable coloring
-  * *: export the `colors` array
-  * npmignore: don't publish the `dist` dir
-  * Makefile: refactor to use browserify
-  * package: add "browserify" as a dev dependency
-  * Readme: add Web Inspector Colors section
-  * node: reset terminal color for the debug content
-  * node: map "%o" to `util.inspect()`
-  * browser: map "%j" to `JSON.stringify()`
-  * debug: add custom "formatters"
-  * debug: use "ms" module for humanizing the diff
-  * Readme: add "bash" syntax highlighting
-  * browser: add Firebug color support
-  * browser: add colors for WebKit browsers
-  * node: apply log to `console`
-  * rewrite: abstract common logic for Node & browsers
-  * add .jshintrc file
-
-0.8.1 / 2014-04-14
-==================
-
-  * package: re-add the "component" section
-
-0.8.0 / 2014-03-30
-==================
-
-  * add `enable()` method for nodejs. Closes #27
-  * change from stderr to stdout
-  * remove unnecessary index.js file
-
-0.7.4 / 2013-11-13
-==================
-
-  * remove "browserify" key from package.json (fixes something in browserify)
-
-0.7.3 / 2013-10-30
-==================
-
-  * fix: catch localStorage security error when cookies are blocked (Chrome)
-  * add debug(err) support. Closes #46
-  * add .browser prop to package.json. Closes #42
-
-0.7.2 / 2013-02-06
-==================
-
-  * fix package.json
-  * fix: Mobile Safari (private mode) is broken with debug
-  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-
-0.7.1 / 2013-02-05
-==================
-
-  * add repository URL to package.json
-  * add DEBUG_COLORED to force colored output
-  * add browserify support
-  * fix component. Closes #24
-
-0.7.0 / 2012-05-04
-==================
-
-  * Added .component to package.json
-  * Added debug.component.js build
-
-0.6.0 / 2012-03-16
-==================
-
-  * Added support for "-" prefix in DEBUG [Vinay Pulim]
-  * Added `.enabled` flag to the node version [TooTallNate]
-
-0.5.0 / 2012-02-02
-==================
-
-  * Added: humanize diffs. Closes #8
-  * Added `debug.disable()` to the CS variant
-  * Removed padding. Closes #10
-  * Fixed: persist client-side variant again. Closes #9
-
-0.4.0 / 2012-02-01
-==================
-
-  * Added browser variant support for older browsers [TooTallNate]
-  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
-  * Added padding to diff (moved it to the right)
-
-0.3.0 / 2012-01-26
-==================
-
-  * Added millisecond diff when isatty, otherwise UTC string
-
-0.2.0 / 2012-01-22
-==================
-
-  * Added wildcard support
-
-0.1.0 / 2011-12-02
-==================
-
-  * Added: remove colors unless stderr isatty [TooTallNate]
-
-0.0.1 / 2010-01-03
-==================
-
-  * Initial release
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Makefile b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Makefile
index 5cf4a5962..584da8bf9 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Makefile
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Makefile
@@ -1,4 +1,3 @@
-
 # get Makefile directory name: http://stackoverflow.com/a/5982798/376773
 THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
 THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
@@ -6,31 +5,46 @@ THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
 # BIN directory
 BIN := $(THIS_DIR)/node_modules/.bin
 
+# Path
+PATH := node_modules/.bin:$(PATH)
+SHELL := /bin/bash
+
 # applications
 NODE ?= $(shell which node)
-NPM ?= $(NODE) $(shell which npm)
+YARN ?= $(shell which yarn)
+PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
 BROWSERIFY ?= $(NODE) $(BIN)/browserify
 
-all: dist/debug.js
+.FORCE:
 
 install: node_modules
 
-clean:
-	@rm -rf dist
+node_modules: package.json
+	@NODE_ENV= $(PKG) install
+	@touch node_modules
+
+lint: .FORCE
+	eslint browser.js debug.js index.js node.js
 
-dist:
-	@mkdir -p $@
+test-node: .FORCE
+	istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
+
+test-browser: .FORCE
+	mkdir -p dist
 
-dist/debug.js: node_modules browser.js debug.js dist
 	@$(BROWSERIFY) \
 		--standalone debug \
-		. > $@
+		. > dist/debug.js
 
-distclean: clean
-	@rm -rf node_modules
+	karma start --single-run
+	rimraf dist
 
-node_modules: package.json
-	@NODE_ENV= $(NPM) install
-	@touch node_modules
+test: .FORCE
+	concurrently \
+		"make test-node" \
+		"make test-browser"
+
+coveralls:
+	cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
 
 .PHONY: all install clean distclean
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Readme.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Readme.md
index b4f45e3cc..f67be6b31 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Readme.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/Readme.md
@@ -1,6 +1,12 @@
 # debug
+[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug)  [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master)  [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) 
+[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
 
-  tiny node.js debugging utility modelled after node core's debugging technique.
+
+
+A tiny node.js debugging utility modelled after node core's debugging technique.
+
+**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
 
 ## Installation
 
@@ -10,7 +16,7 @@ $ npm install debug
 
 ## Usage
 
- With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
+`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
 
 Example _app.js_:
 
@@ -59,6 +65,12 @@ setInterval(function(){
  set DEBUG=*,-not_this
  ```
 
+ Note that PowerShell uses different syntax to set environment variables.
+
+ ```cmd
+ $env:DEBUG = "*,-not_this"
+  ```
+
 Then, run the program to be debugged as usual.
 
 ## Millisecond diff
@@ -73,7 +85,7 @@ Then, run the program to be debugged as usual.
 
 ## Conventions
 
- If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
+  If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
 
 ## Wildcards
 
@@ -81,21 +93,69 @@ Then, run the program to be debugged as usual.
 
   You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
 
-## Browser support
+## Environment Variables
+
+  When running through Node.js, you can set a few environment variables that will
+  change the behavior of the debug logging:
+
+| Name      | Purpose                                         |
+|-----------|-------------------------------------------------|
+| `DEBUG`   | Enables/disables specific debugging namespaces. |
+| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth. |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+
+  __Note:__ The environment variables beginning with `DEBUG_` end up being
+  converted into an Options object that gets used with `%o`/`%O` formatters.
+  See the Node.js documentation for
+  [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+  for the complete list.
+
+## Formatters
 
-  Debug works in the browser as well, currently persisted by `localStorage`. Consider the situation shown below where you have `worker:a` and `worker:b`, and wish to debug both. Somewhere in the code on your page, include:
+
+  Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
+
+| Formatter | Representation |
+|-----------|----------------|
+| `%O`      | Pretty-print an Object on multiple lines. |
+| `%o`      | Pretty-print an Object all on a single line. |
+| `%s`      | String. |
+| `%d`      | Number (both integer and float). |
+| `%j`      | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
+| `%%`      | Single percent sign ('%'). This does not consume an argument. |
+
+### Custom formatters
+
+  You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
 
 ```js
-window.myDebug = require("debug");
+const createDebug = require('debug')
+createDebug.formatters.h = (v) => {
+  return v.toString('hex')
+}
+
+// …elsewhere
+const debug = createDebug('foo')
+debug('this is hex: %h', new Buffer('hello world'))
+//   foo this is hex: 68656c6c6f20776f726c6421 +0ms
 ```
 
-  ("debug" is a global object in the browser so we give this object a different name.) When your page is open in the browser, type the following in the console:
+## Browser support
+  You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
+  or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
+  if you don't want to build it yourself.
+
+  Debug's enable state is currently persisted by `localStorage`.
+  Consider the situation shown below where you have `worker:a` and `worker:b`,
+  and wish to debug both. You can enable this using `localStorage.debug`:
 
 ```js
-myDebug.enable("worker:*")
+localStorage.debug = 'worker:*'
 ```
 
-  Refresh the page. Debug output will continue to be sent to the console until it is disabled by typing `myDebug.disable()` in the console.
+And then refresh the page.
 
 ```js
 a = debug('worker:a');
@@ -121,9 +181,10 @@ setInterval(function(){
 
   ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
 
-### stderr vs stdout
 
-You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
+## Output streams
+
+  By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
 
 Example _stdout.js_:
 
@@ -147,26 +208,89 @@ error('now goes to stdout via console.info');
 log('still goes to stdout, but via console.info now');
 ```
 
-### Save debug output to a file
-
-You can save all debug statements to a file by piping them.
-
-Example:
-
-```bash
-$ DEBUG_FD=3 node your-app.js 3> whatever.log
-```
 
 ## Authors
 
  - TJ Holowaychuk
  - Nathan Rajlich
+ - Andrew Rhyne
+ 
+## Backers
+
+Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
+
+<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
+
+
+## Sponsors
+
+Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
+
+<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
 
 ## License
 
 (The MIT License)
 
-Copyright (c) 2014 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/bower.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/bower.json
deleted file mode 100644
index 6af573ff5..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/bower.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "name": "visionmedia-debug",
-  "main": "dist/debug.js",
-  "version": "2.2.0",
-  "homepage": "https://github.com/visionmedia/debug",
-  "authors": [
-    "TJ Holowaychuk <tj@vision-media.ca>"
-  ],
-  "description": "visionmedia-debug",
-  "moduleType": [
-    "amd",
-    "es6",
-    "globals",
-    "node"
-  ],
-  "keywords": [
-    "visionmedia",
-    "debug"
-  ],
-  "license": "MIT",
-  "ignore": [
-    "**/.*",
-    "node_modules",
-    "bower_components",
-    "test",
-    "tests"
-  ]
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/browser.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/browser.js
deleted file mode 100644
index 7c7645221..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/browser.js
+++ /dev/null
@@ -1,168 +0,0 @@
-
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-exports.storage = 'undefined' != typeof chrome
-               && 'undefined' != typeof chrome.storage
-                  ? chrome.storage.local
-                  : localstorage();
-
-/**
- * Colors.
- */
-
-exports.colors = [
-  'lightseagreen',
-  'forestgreen',
-  'goldenrod',
-  'dodgerblue',
-  'darkorchid',
-  'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
-  // is webkit? http://stackoverflow.com/a/16459606/376773
-  return ('WebkitAppearance' in document.documentElement.style) ||
-    // is firebug? http://stackoverflow.com/a/398120/376773
-    (window.console && (console.firebug || (console.exception && console.table))) ||
-    // is firefox >= v31?
-    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
-    (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
-  return JSON.stringify(v);
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-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));
-
-  // the final "%c" is somewhat tricky, because there could be other
-  // arguments passed either before or after the %c, so we need to
-  // figure out the correct index to insert the CSS into
-  var index = 0;
-  var lastC = 0;
-  args[0].replace(/%[a-z%]/g, function(match) {
-    if ('%%' === match) return;
-    index++;
-    if ('%c' === match) {
-      // we only are interested in the *last* %c
-      // (the user may have provided their own)
-      lastC = index;
-    }
-  });
-
-  args.splice(lastC, 0, c);
-  return args;
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
-  // this hackery is required for IE8/9, where
-  // the `console.log` function doesn't have 'apply'
-  return 'object' === typeof console
-    && console.log
-    && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  try {
-    if (null == namespaces) {
-      exports.storage.removeItem('debug');
-    } else {
-      exports.storage.debug = namespaces;
-    }
-  } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  var r;
-  try {
-    r = exports.storage.debug;
-  } catch(e) {}
-  return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
-
-function localstorage(){
-  try {
-    return window.localStorage;
-  } catch (e) {}
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/component.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/component.json
index ca1063724..9de26410f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/component.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/component.json
@@ -2,16 +2,16 @@
   "name": "debug",
   "repo": "visionmedia/debug",
   "description": "small debugging utility",
-  "version": "2.2.0",
+  "version": "2.6.9",
   "keywords": [
     "debug",
     "log",
     "debugger"
   ],
-  "main": "browser.js",
+  "main": "src/browser.js",
   "scripts": [
-    "browser.js",
-    "debug.js"
+    "src/browser.js",
+    "src/debug.js"
   ],
   "dependencies": {
     "rauchg/ms.js": "0.7.1"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/debug.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/debug.js
deleted file mode 100644
index 7571a8605..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/debug.js
+++ /dev/null
@@ -1,197 +0,0 @@
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = debug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require('ms');
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lowercased letter, i.e. "n".
- */
-
-exports.formatters = {};
-
-/**
- * Previously assigned color.
- */
-
-var prevColor = 0;
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- *
- * @return {Number}
- * @api private
- */
-
-function selectColor() {
-  return exports.colors[prevColor++ % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function debug(namespace) {
-
-  // define the `disabled` version
-  function disabled() {
-  }
-  disabled.enabled = false;
-
-  // define the `enabled` version
-  function enabled() {
-
-    var self = enabled;
-
-    // set `diff` timestamp
-    var curr = +new Date();
-    var ms = curr - (prevTime || curr);
-    self.diff = ms;
-    self.prev = prevTime;
-    self.curr = curr;
-    prevTime = curr;
-
-    // add the `color` if not set
-    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]) {
-      // anything else let's inspect with %o
-      args = ['%o'].concat(args);
-    }
-
-    // apply any `formatters` transformations
-    var index = 0;
-    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
-      // if we encounter an escaped % then don't increase the array index
-      if (match === '%%') return match;
-      index++;
-      var formatter = exports.formatters[format];
-      if ('function' === typeof formatter) {
-        var val = args[index];
-        match = formatter.call(self, val);
-
-        // now we need to remove `args[index]` since it's inlined in the `format`
-        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;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
-  exports.save(namespaces);
-
-  var split = (namespaces || '').split(/[\s,]+/);
-  var len = split.length;
-
-  for (var i = 0; i < len; i++) {
-    if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
-    if (namespaces[0] === '-') {
-      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
-    } else {
-      exports.names.push(new RegExp('^' + namespaces + '$'));
-    }
-  }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
-  exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
-  var i, len;
-  for (i = 0, len = exports.skips.length; i < len; i++) {
-    if (exports.skips[i].test(name)) {
-      return false;
-    }
-  }
-  for (i = 0, len = exports.names.length; i < len; i++) {
-    if (exports.names[i].test(name)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
-  if (val instanceof Error) return val.stack || val.message;
-  return val;
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/node.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/node.js
index 1d392a81d..7fc36fe6d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/node.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/node.js
@@ -1,209 +1 @@
-
-/**
- * Module dependencies.
- */
-
-var tty = require('tty');
-var util = require('util');
-
-/**
- * This is the Node.js implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [6, 2, 3, 4, 5, 1];
-
-/**
- * The file descriptor to write the `debug()` calls to.
- * Set the `DEBUG_FD` env variable to override with another value. i.e.:
- *
- *   $ DEBUG_FD=3 node script.js 3>debug.log
- */
-
-var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
-var stream = 1 === fd ? process.stdout :
-             2 === fd ? process.stderr :
-             createWritableStdioStream(fd);
-
-/**
- * Is stdout a TTY? Colored output is enabled when `true`.
- */
-
-function useColors() {
-  var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
-  if (0 === debugColors.length) {
-    return tty.isatty(fd);
-  } else {
-    return '0' !== debugColors
-        && 'no' !== debugColors
-        && 'false' !== debugColors
-        && 'disabled' !== debugColors;
-  }
-}
-
-/**
- * Map %o to `util.inspect()`, since Node doesn't do that out of the box.
- */
-
-var inspect = (4 === util.inspect.length ?
-  // node <= 0.8.x
-  function (v, colors) {
-    return util.inspect(v, void 0, void 0, colors);
-  } :
-  // node > 0.8.x
-  function (v, colors) {
-    return util.inspect(v, { colors: colors });
-  }
-);
-
-exports.formatters.o = function(v) {
-  return inspect(v, this.useColors)
-    .replace(/\s*\n\s*/g, ' ');
-};
-
-/**
- * Adds ANSI color escape codes if enabled.
- *
- * @api public
- */
-
-function formatArgs() {
-  var args = arguments;
-  var useColors = this.useColors;
-  var name = this.namespace;
-
-  if (useColors) {
-    var c = this.color;
-
-    args[0] = '  \u001b[3' + c + ';1m' + name + ' '
-      + '\u001b[0m'
-      + args[0] + '\u001b[3' + c + 'm'
-      + ' +' + exports.humanize(this.diff) + '\u001b[0m';
-  } else {
-    args[0] = new Date().toUTCString()
-      + ' ' + name + ' ' + args[0];
-  }
-  return args;
-}
-
-/**
- * Invokes `console.error()` with the specified arguments.
- */
-
-function log() {
-  return stream.write(util.format.apply(this, arguments) + '\n');
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  if (null == namespaces) {
-    // If you set a process.env field to null or undefined, it gets cast to the
-    // string 'null' or 'undefined'. Just delete instead.
-    delete process.env.DEBUG;
-  } else {
-    process.env.DEBUG = namespaces;
-  }
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  return process.env.DEBUG;
-}
-
-/**
- * Copied from `node/src/node.js`.
- *
- * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
- * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
- */
-
-function createWritableStdioStream (fd) {
-  var stream;
-  var tty_wrap = process.binding('tty_wrap');
-
-  // Note stream._type is used for test-module-load-list.js
-
-  switch (tty_wrap.guessHandleType(fd)) {
-    case 'TTY':
-      stream = new tty.WriteStream(fd);
-      stream._type = 'tty';
-
-      // Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    case 'FILE':
-      var fs = require('fs');
-      stream = new fs.SyncWriteStream(fd, { autoClose: false });
-      stream._type = 'fs';
-      break;
-
-    case 'PIPE':
-    case 'TCP':
-      var net = require('net');
-      stream = new net.Socket({
-        fd: fd,
-        readable: false,
-        writable: true
-      });
-
-      // FIXME Should probably have an option in net.Socket to create a
-      // stream from an existing fd which is writable only. But for now
-      // we'll just add this hack and set the `readable` member to false.
-      // Test: ./node test/fixtures/echo.js < /etc/passwd
-      stream.readable = false;
-      stream.read = null;
-      stream._type = 'pipe';
-
-      // FIXME Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    default:
-      // Probably an error on in uv_guess_handle()
-      throw new Error('Implement me. Unknown stream file type!');
-  }
-
-  // For supporting legacy API we put the FD here.
-  stream.fd = fd;
-
-  stream._isStdio = true;
-
-  return stream;
-}
-
-/**
- * Enable namespaces listed in `process.env.DEBUG` initially.
- */
-
-exports.enable(load());
+module.exports = require('./src/node');
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/package.json
index 778ef6e82..b70deac78 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/debug/package.json
@@ -1,57 +1,40 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "debug@~2.2.0",
-        "scope": null,
-        "escapedName": "debug",
-        "name": "debug",
-        "rawSpec": "~2.2.0",
-        "spec": ">=2.2.0 <2.3.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression"
-    ]
-  ],
-  "_from": "debug@>=2.2.0 <2.3.0",
-  "_id": "debug@2.2.0",
-  "_inCache": true,
+  "_from": "debug@2.6.9",
+  "_id": "debug@2.6.9",
+  "_inBundle": false,
+  "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
   "_location": "/debug",
-  "_nodeVersion": "0.12.2",
-  "_npmUser": {
-    "name": "tootallnate",
-    "email": "nathan@tootallnate.net"
-  },
-  "_npmVersion": "2.7.4",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "debug@~2.2.0",
-    "scope": null,
-    "escapedName": "debug",
+    "type": "version",
+    "registry": true,
+    "raw": "debug@2.6.9",
     "name": "debug",
-    "rawSpec": "~2.2.0",
-    "spec": ">=2.2.0 <2.3.0",
-    "type": "range"
+    "escapedName": "debug",
+    "rawSpec": "2.6.9",
+    "saveSpec": null,
+    "fetchSpec": "2.6.9"
   },
   "_requiredBy": [
+    "/body-parser",
     "/compression",
     "/express",
     "/finalhandler",
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
-  "_shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da",
-  "_shrinkwrap": null,
-  "_spec": "debug@~2.2.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression",
+  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+  "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
+  "_spec": "debug@2.6.9",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/compression",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca"
   },
-  "browser": "./browser.js",
+  "browser": "./src/browser.js",
   "bugs": {
     "url": "https://github.com/visionmedia/debug/issues"
   },
+  "bundleDependencies": false,
   "component": {
     "scripts": {
       "debug/index.js": "browser.js",
@@ -63,47 +46,47 @@
       "name": "Nathan Rajlich",
       "email": "nathan@tootallnate.net",
       "url": "http://n8.io"
+    },
+    {
+      "name": "Andrew Rhyne",
+      "email": "rhyneandrew@gmail.com"
     }
   ],
   "dependencies": {
-    "ms": "0.7.1"
+    "ms": "2.0.0"
   },
+  "deprecated": false,
   "description": "small debugging utility",
   "devDependencies": {
     "browserify": "9.0.3",
-    "mocha": "*"
+    "chai": "^3.5.0",
+    "concurrently": "^3.1.0",
+    "coveralls": "^2.11.15",
+    "eslint": "^3.12.1",
+    "istanbul": "^0.4.5",
+    "karma": "^1.3.0",
+    "karma-chai": "^0.1.0",
+    "karma-mocha": "^1.3.0",
+    "karma-phantomjs-launcher": "^1.0.2",
+    "karma-sinon": "^1.0.5",
+    "mocha": "^3.2.0",
+    "mocha-lcov-reporter": "^1.2.0",
+    "rimraf": "^2.5.4",
+    "sinon": "^1.17.6",
+    "sinon-chai": "^2.8.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "f87057e995b1a1f6ae6a4960664137bc56f039da",
-    "tarball": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz"
-  },
-  "gitHead": "b38458422b5aa8aa6d286b10dfe427e8a67e2b35",
-  "homepage": "https://github.com/visionmedia/debug",
+  "homepage": "https://github.com/visionmedia/debug#readme",
   "keywords": [
     "debug",
     "log",
     "debugger"
   ],
   "license": "MIT",
-  "main": "./node.js",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "tootallnate",
-      "email": "nathan@tootallnate.net"
-    }
-  ],
+  "main": "./src/index.js",
   "name": "debug",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git://github.com/visionmedia/debug.git"
   },
-  "scripts": {},
-  "version": "2.2.0"
+  "version": "2.6.9"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/History.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/History.md
index ace117154..f0016499d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/History.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/History.md
@@ -1,3 +1,9 @@
+1.1.1 / 2017-07-27
+==================
+
+  * Remove unnecessary `Buffer` loading
+  * Support Node.js 0.6 to 8.x
+
 1.1.0 / 2015-09-14
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/LICENSE
index 142ede386..84441fbb5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/LICENSE
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2014-2015 Douglas Christopher Wilson
+Copyright (c) 2014-2017 Douglas Christopher Wilson
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/Readme.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/Readme.md
index 09bb97995..9e7d8726c 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/Readme.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/Readme.md
@@ -27,6 +27,8 @@ track deprecations.
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var deprecate = require('depd')('my-module')
 ```
@@ -200,7 +202,7 @@ var deprecate = require('depd')('my-cool-module')
 
 // message automatically derived from function name
 // Object.oldfunction
-exports.oldfunction = deprecate.function(function oldfunction() {
+exports.oldfunction = deprecate.function(function oldfunction () {
   // all calls to function are deprecated
 })
 
@@ -276,6 +278,6 @@ deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
 [coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg
 [coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
 [node-image]: https://img.shields.io/node/v/depd.svg
-[node-url]: http://nodejs.org/download/
+[node-url]: https://nodejs.org/en/download/
 [gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
 [gratipay-url]: https://www.gratipay.com/dougwilson/
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/index.js
index fddcae875..73d81ab54 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/index.js
@@ -1,6 +1,6 @@
 /*!
  * depd
- * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * Copyright(c) 2014-2017 Douglas Christopher Wilson
  * MIT Licensed
  */
 
@@ -28,13 +28,13 @@ var basePath = process.cwd()
  * Determine if namespace is contained in the string.
  */
 
-function containsNamespace(str, namespace) {
+function containsNamespace (str, namespace) {
   var val = str.split(/[ ,]+/)
 
   namespace = String(namespace).toLowerCase()
 
-  for (var i = 0 ; i < val.length; i++) {
-    if (!(str = val[i])) continue;
+  for (var i = 0; i < val.length; i++) {
+    if (!(str = val[i])) continue
 
     // namespace contained
     if (str === '*' || str.toLowerCase() === namespace) {
@@ -49,14 +49,14 @@ function containsNamespace(str, namespace) {
  * Convert a data descriptor to accessor descriptor.
  */
 
-function convertDataDescriptorToAccessor(obj, prop, message) {
+function convertDataDescriptorToAccessor (obj, prop, message) {
   var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
   var value = descriptor.value
 
-  descriptor.get = function getter() { return value }
+  descriptor.get = function getter () { return value }
 
   if (descriptor.writable) {
-    descriptor.set = function setter(val) { return value = val }
+    descriptor.set = function setter (val) { return (value = val) }
   }
 
   delete descriptor.value
@@ -71,7 +71,7 @@ function convertDataDescriptorToAccessor(obj, prop, message) {
  * Create arguments string to keep arity.
  */
 
-function createArgumentsString(arity) {
+function createArgumentsString (arity) {
   var str = ''
 
   for (var i = 0; i < arity; i++) {
@@ -85,7 +85,7 @@ function createArgumentsString(arity) {
  * Create stack string from stack.
  */
 
-function createStackString(stack) {
+function createStackString (stack) {
   var str = this.name + ': ' + this.namespace
 
   if (this.message) {
@@ -103,7 +103,7 @@ function createStackString(stack) {
  * Create deprecate for namespace in caller.
  */
 
-function depd(namespace) {
+function depd (namespace) {
   if (!namespace) {
     throw new TypeError('argument namespace is required')
   }
@@ -112,7 +112,7 @@ function depd(namespace) {
   var site = callSiteLocation(stack[1])
   var file = site[0]
 
-  function deprecate(message) {
+  function deprecate (message) {
     // call to self as log
     log.call(deprecate, message)
   }
@@ -133,7 +133,7 @@ function depd(namespace) {
  * Determine if namespace is ignored.
  */
 
-function isignored(namespace) {
+function isignored (namespace) {
   /* istanbul ignore next: tested in a child processs */
   if (process.noDeprecation) {
     // --no-deprecation support
@@ -150,7 +150,7 @@ function isignored(namespace) {
  * Determine if namespace is traced.
  */
 
-function istraced(namespace) {
+function istraced (namespace) {
   /* istanbul ignore next: tested in a child processs */
   if (process.traceDeprecation) {
     // --trace-deprecation support
@@ -167,7 +167,7 @@ function istraced(namespace) {
  * Display deprecation message.
  */
 
-function log(message, site) {
+function log (message, site) {
   var haslisteners = eventListenerCount(process, 'deprecation') !== 0
 
   // abort early if no destination
@@ -240,15 +240,13 @@ function log(message, site) {
     : formatPlain
   var msg = format.call(this, message, caller, stack.slice(i))
   process.stderr.write(msg + '\n', 'utf8')
-
-  return
 }
 
 /**
  * Get call site location as array.
  */
 
-function callSiteLocation(callSite) {
+function callSiteLocation (callSite) {
   var file = callSite.getFileName() || '<anonymous>'
   var line = callSite.getLineNumber()
   var colm = callSite.getColumnNumber()
@@ -269,7 +267,7 @@ function callSiteLocation(callSite) {
  * Generate a default message from the site.
  */
 
-function defaultMessage(site) {
+function defaultMessage (site) {
   var callSite = site.callSite
   var funcName = site.name
 
@@ -300,12 +298,12 @@ function defaultMessage(site) {
  * Format deprecation message without color.
  */
 
-function formatPlain(msg, caller, stack) {
+function formatPlain (msg, caller, stack) {
   var timestamp = new Date().toUTCString()
 
-  var formatted = timestamp
-    + ' ' + this._namespace
-    + ' deprecated ' + msg
+  var formatted = timestamp +
+    ' ' + this._namespace +
+    ' deprecated ' + msg
 
   // add stack trace
   if (this._traced) {
@@ -327,10 +325,10 @@ function formatPlain(msg, caller, stack) {
  * Format deprecation message with color.
  */
 
-function formatColor(msg, caller, stack) {
-  var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
-    + ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
-    + ' \x1b[0m' + msg + '\x1b[39m' // reset
+function formatColor (msg, caller, stack) {
+  var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan
+    ' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow
+    ' \x1b[0m' + msg + '\x1b[39m' // reset
 
   // add stack trace
   if (this._traced) {
@@ -352,17 +350,17 @@ function formatColor(msg, caller, stack) {
  * Format call site location.
  */
 
-function formatLocation(callSite) {
-  return relative(basePath, callSite[0])
-    + ':' + callSite[1]
-    + ':' + callSite[2]
+function formatLocation (callSite) {
+  return relative(basePath, callSite[0]) +
+    ':' + callSite[1] +
+    ':' + callSite[2]
 }
 
 /**
  * Get the stack as array of call sites.
  */
 
-function getStack() {
+function getStack () {
   var limit = Error.stackTraceLimit
   var obj = {}
   var prep = Error.prepareStackTrace
@@ -386,7 +384,7 @@ function getStack() {
  * Capture call site stack from v8.
  */
 
-function prepareObjectStackTrace(obj, stack) {
+function prepareObjectStackTrace (obj, stack) {
   return stack
 }
 
@@ -394,23 +392,24 @@ function prepareObjectStackTrace(obj, stack) {
  * Return a wrapped function in a deprecation message.
  */
 
-function wrapfunction(fn, message) {
+function wrapfunction (fn, message) {
   if (typeof fn !== 'function') {
     throw new TypeError('argument fn must be a function')
   }
 
   var args = createArgumentsString(fn.length)
-  var deprecate = this
+  var deprecate = this // eslint-disable-line no-unused-vars
   var stack = getStack()
   var site = callSiteLocation(stack[1])
 
   site.name = fn.name
 
-  var deprecatedfn = eval('(function (' + args + ') {\n'
-    + '"use strict"\n'
-    + 'log.call(deprecate, message, site)\n'
-    + 'return fn.apply(this, arguments)\n'
-    + '})')
+   // eslint-disable-next-line no-eval
+  var deprecatedfn = eval('(function (' + args + ') {\n' +
+    '"use strict"\n' +
+    'log.call(deprecate, message, site)\n' +
+    'return fn.apply(this, arguments)\n' +
+    '})')
 
   return deprecatedfn
 }
@@ -419,7 +418,7 @@ function wrapfunction(fn, message) {
  * Wrap property in a deprecation message.
  */
 
-function wrapproperty(obj, prop, message) {
+function wrapproperty (obj, prop, message) {
   if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
     throw new TypeError('argument obj must be object')
   }
@@ -451,7 +450,7 @@ function wrapproperty(obj, prop, message) {
 
   // wrap getter
   if (typeof get === 'function') {
-    descriptor.get = function getter() {
+    descriptor.get = function getter () {
       log.call(deprecate, message, site)
       return get.apply(this, arguments)
     }
@@ -459,7 +458,7 @@ function wrapproperty(obj, prop, message) {
 
   // wrap setter
   if (typeof set === 'function') {
-    descriptor.set = function setter() {
+    descriptor.set = function setter () {
       log.call(deprecate, message, site)
       return set.apply(this, arguments)
     }
@@ -472,7 +471,7 @@ function wrapproperty(obj, prop, message) {
  * Create DeprecationError for deprecation
  */
 
-function DeprecationError(namespace, message, stack) {
+function DeprecationError (namespace, message, stack) {
   var error = new Error()
   var stackString
 
@@ -510,9 +509,9 @@ function DeprecationError(namespace, message, stack) {
       }
 
       // prepare stack trace
-      return stackString = createStackString.call(this, stack)
+      return (stackString = createStackString.call(this, stack))
     },
-    set: function setter(val) {
+    set: function setter (val) {
       stackString = val
     }
   })
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/browser/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/browser/index.js
index f464e0525..6be45cc20 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/browser/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/browser/index.js
@@ -17,12 +17,12 @@ module.exports = depd
  * Create deprecate for namespace in caller.
  */
 
-function depd(namespace) {
+function depd (namespace) {
   if (!namespace) {
     throw new TypeError('argument namespace is required')
   }
 
-  function deprecate(message) {
+  function deprecate (message) {
     // no-op in browser
   }
 
@@ -45,7 +45,7 @@ function depd(namespace) {
  * validation.
  */
 
-function wrapfunction(fn, message) {
+function wrapfunction (fn, message) {
   if (typeof fn !== 'function') {
     throw new TypeError('argument fn must be a function')
   }
@@ -60,7 +60,7 @@ function wrapfunction(fn, message) {
  * validation.
  */
 
-function wrapproperty(obj, prop, message) {
+function wrapproperty (obj, prop, message) {
   if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
     throw new TypeError('argument obj must be object')
   }
@@ -74,6 +74,4 @@ function wrapproperty(obj, prop, message) {
   if (!descriptor.configurable) {
     throw new TypeError('property must be configurable')
   }
-
-  return
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/buffer-concat.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/buffer-concat.js
deleted file mode 100644
index 4b7338102..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/buffer-concat.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-'use strict'
-
-/**
- * Module exports.
- */
-
-module.exports = bufferConcat
-
-/**
- * Concatenate an array of Buffers.
- */
-
-function bufferConcat(bufs) {
-  var length = 0
-
-  for (var i = 0, len = bufs.length; i < len; i++) {
-    length += bufs[i].length
-  }
-
-  var buf = new Buffer(length)
-  var pos = 0
-
-  for (var i = 0, len = bufs.length; i < len; i++) {
-    bufs[i].copy(buf, pos)
-    pos += bufs[i].length
-  }
-
-  return buf
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/callsite-tostring.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/callsite-tostring.js
index 9ecef3466..73186dc64 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/callsite-tostring.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/callsite-tostring.js
@@ -16,7 +16,7 @@ module.exports = callSiteToString
  * Format a CallSite file location to a string.
  */
 
-function callSiteFileLocation(callSite) {
+function callSiteFileLocation (callSite) {
   var fileName
   var fileLocation = ''
 
@@ -52,7 +52,7 @@ function callSiteFileLocation(callSite) {
  * Format a CallSite to a string.
  */
 
-function callSiteToString(callSite) {
+function callSiteToString (callSite) {
   var addSuffix = true
   var fileLocation = callSiteFileLocation(callSite)
   var functionName = callSite.getFunctionName()
@@ -97,7 +97,7 @@ function callSiteToString(callSite) {
  * Get constructor name of reviver.
  */
 
-function getConstructorName(obj) {
+function getConstructorName (obj) {
   var receiver = obj.receiver
   return (receiver.constructor && receiver.constructor.name) || null
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/event-listener-count.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/event-listener-count.js
index a05fceb79..3a8925d13 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/event-listener-count.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/event-listener-count.js
@@ -17,6 +17,6 @@ module.exports = eventListenerCount
  * Get the count of listeners on an event emitter of a specific type.
  */
 
-function eventListenerCount(emitter, type) {
+function eventListenerCount (emitter, type) {
   return emitter.listeners(type).length
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/index.js
index aa3c1de43..955b3336b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/lib/compat/index.js
@@ -11,7 +11,6 @@
  * @private
  */
 
-var Buffer = require('buffer')
 var EventEmitter = require('events').EventEmitter
 
 /**
@@ -19,16 +18,12 @@ var EventEmitter = require('events').EventEmitter
  * @public
  */
 
-lazyProperty(module.exports, 'bufferConcat', function bufferConcat() {
-  return Buffer.concat || require('./buffer-concat')
-})
-
-lazyProperty(module.exports, 'callSiteToString', function callSiteToString() {
+lazyProperty(module.exports, 'callSiteToString', function callSiteToString () {
   var limit = Error.stackTraceLimit
   var obj = {}
   var prep = Error.prepareStackTrace
 
-  function prepareObjectStackTrace(obj, stack) {
+  function prepareObjectStackTrace (obj, stack) {
     return stack
   }
 
@@ -47,7 +42,7 @@ lazyProperty(module.exports, 'callSiteToString', function callSiteToString() {
   return stack[0].toString ? toString : require('./callsite-tostring')
 })
 
-lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount() {
+lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount () {
   return EventEmitter.listenerCount || require('./event-listener-count')
 })
 
@@ -55,8 +50,8 @@ lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount()
  * Define a lazy property.
  */
 
-function lazyProperty(obj, prop, getter) {
-  function get() {
+function lazyProperty (obj, prop, getter) {
+  function get () {
     var val = getter()
 
     Object.defineProperty(obj, prop, {
@@ -79,6 +74,6 @@ function lazyProperty(obj, prop, getter) {
  * Call toString() on the obj
  */
 
-function toString(obj) {
+function toString (obj) {
   return obj.toString()
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/package.json
index ddb5654db..c664d3bd5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/depd/package.json
@@ -1,46 +1,30 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "depd@~1.1.0",
-        "scope": null,
-        "escapedName": "depd",
-        "name": "depd",
-        "rawSpec": "~1.1.0",
-        "spec": ">=1.1.0 <1.2.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "depd@>=1.1.0 <1.2.0",
-  "_id": "depd@1.1.0",
-  "_inCache": true,
+  "_from": "depd@~1.1.1",
+  "_id": "depd@1.1.1",
+  "_inBundle": false,
+  "_integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
   "_location": "/depd",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "depd@~1.1.0",
-    "scope": null,
-    "escapedName": "depd",
+    "type": "range",
+    "registry": true,
+    "raw": "depd@~1.1.1",
     "name": "depd",
-    "rawSpec": "~1.1.0",
-    "spec": ">=1.1.0 <1.2.0",
-    "type": "range"
+    "escapedName": "depd",
+    "rawSpec": "~1.1.1",
+    "saveSpec": null,
+    "fetchSpec": "~1.1.1"
   },
   "_requiredBy": [
+    "/body-parser",
     "/express",
+    "/http-errors",
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
-  "_shasum": "e1bd82c6aab6ced965b97b88b17ed3e528ca18c3",
-  "_shrinkwrap": null,
-  "_spec": "depd@~1.1.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+  "_shasum": "5783b4e1c459f06fa5ca27f991f3d06e7a310359",
+  "_spec": "depd@~1.1.1",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -49,19 +33,20 @@
   "bugs": {
     "url": "https://github.com/dougwilson/nodejs-depd/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Deprecate all the things",
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
-    "benchmark": "1.0.0",
-    "istanbul": "0.3.5",
+    "benchmark": "2.1.4",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "7.1.0",
+    "eslint-plugin-markdown": "1.0.0-beta.7",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "2.3.1",
+    "istanbul": "0.4.5",
     "mocha": "~1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "e1bd82c6aab6ced965b97b88b17ed3e528ca18c3",
-    "tarball": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -72,31 +57,23 @@
     "index.js",
     "Readme.md"
   ],
-  "gitHead": "78c659de20283e3a6bee92bda455e6daff01686a",
-  "homepage": "https://github.com/dougwilson/nodejs-depd",
+  "homepage": "https://github.com/dougwilson/nodejs-depd#readme",
   "keywords": [
     "deprecate",
     "deprecated"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "depd",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/dougwilson/nodejs-depd.git"
   },
   "scripts": {
     "bench": "node benchmark/index.js",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail test/",
     "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/",
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/"
   },
-  "version": "1.1.0"
+  "version": "1.1.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/destroy/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/destroy/package.json
index e0ddc2547..afc610791 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/destroy/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/destroy/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "destroy@~1.0.4",
-        "scope": null,
-        "escapedName": "destroy",
-        "name": "destroy",
-        "rawSpec": "~1.0.4",
-        "spec": ">=1.0.4 <1.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send"
-    ]
-  ],
-  "_from": "destroy@>=1.0.4 <1.1.0",
+  "_from": "destroy@~1.0.4",
   "_id": "destroy@1.0.4",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
   "_location": "/destroy",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "destroy@~1.0.4",
-    "scope": null,
-    "escapedName": "destroy",
     "name": "destroy",
+    "escapedName": "destroy",
     "rawSpec": "~1.0.4",
-    "spec": ">=1.0.4 <1.1.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.0.4"
   },
   "_requiredBy": [
     "/send"
   ],
   "_resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
   "_shasum": "978857442c44749e4206613e37946205826abd80",
-  "_shrinkwrap": null,
   "_spec": "destroy@~1.0.4",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/send",
   "author": {
     "name": "Jonathan Ong",
     "email": "me@jongleberry.com",
@@ -48,29 +30,24 @@
   "bugs": {
     "url": "https://github.com/stream-utils/destroy/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "destroy a stream if possible",
   "devDependencies": {
     "istanbul": "0.4.2",
     "mocha": "2.3.4"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "978857442c44749e4206613e37946205826abd80",
-    "tarball": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz"
-  },
   "files": [
     "index.js",
     "LICENSE"
   ],
-  "gitHead": "86edea01456f5fa1027f6a47250c34c713cbcc3b",
-  "homepage": "https://github.com/stream-utils/destroy",
+  "homepage": "https://github.com/stream-utils/destroy#readme",
   "keywords": [
     "stream",
     "streams",
@@ -80,19 +57,7 @@
     "fd"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "destroy",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/stream-utils/destroy.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ee-first/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ee-first/package.json
index 285110c6f..7eb6f66e3 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ee-first/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ee-first/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "ee-first@1.1.1",
-        "scope": null,
-        "escapedName": "ee-first",
-        "name": "ee-first",
-        "rawSpec": "1.1.1",
-        "spec": "1.1.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/on-finished"
-    ]
-  ],
   "_from": "ee-first@1.1.1",
   "_id": "ee-first@1.1.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
   "_location": "/ee-first",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "ee-first@1.1.1",
-    "scope": null,
-    "escapedName": "ee-first",
     "name": "ee-first",
+    "escapedName": "ee-first",
     "rawSpec": "1.1.1",
-    "spec": "1.1.1",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "1.1.1"
   },
   "_requiredBy": [
     "/on-finished"
   ],
   "_resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
   "_shasum": "590c61156b0ae2f4f0255732a158b266bc56b21d",
-  "_shrinkwrap": null,
   "_spec": "ee-first@1.1.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/on-finished",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/on-finished",
   "author": {
     "name": "Jonathan Ong",
     "email": "me@jongleberry.com",
@@ -48,43 +30,26 @@
   "bugs": {
     "url": "https://github.com/jonathanong/ee-first/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "return the first event in a set of ee/event pairs",
   "devDependencies": {
     "istanbul": "0.3.9",
     "mocha": "2.2.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "590c61156b0ae2f4f0255732a158b266bc56b21d",
-    "tarball": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
-  },
   "files": [
     "index.js",
     "LICENSE"
   ],
-  "gitHead": "512e0ce4cc3643f603708f965a97b61b1a9c0441",
-  "homepage": "https://github.com/jonathanong/ee-first",
+  "homepage": "https://github.com/jonathanong/ee-first#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "ee-first",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jonathanong/ee-first.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/encodeurl/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/encodeurl/package.json
index 86e99d96c..eaa97fdc4 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/encodeurl/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/encodeurl/package.json
@@ -1,62 +1,41 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "encodeurl@~1.0.1",
-        "scope": null,
-        "escapedName": "encodeurl",
-        "name": "encodeurl",
-        "rawSpec": "~1.0.1",
-        "spec": ">=1.0.1 <1.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "encodeurl@>=1.0.1 <1.1.0",
+  "_from": "encodeurl@~1.0.1",
   "_id": "encodeurl@1.0.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
   "_location": "/encodeurl",
-  "_nodeVersion": "4.4.3",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/encodeurl-1.0.1.tgz_1465519736251_0.09314409433864057"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.1",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "encodeurl@~1.0.1",
-    "scope": null,
-    "escapedName": "encodeurl",
     "name": "encodeurl",
+    "escapedName": "encodeurl",
     "rawSpec": "~1.0.1",
-    "spec": ">=1.0.1 <1.1.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.0.1"
   },
   "_requiredBy": [
     "/express",
+    "/finalhandler",
     "/send",
     "/serve-static"
   ],
   "_resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
   "_shasum": "79e3d58655346909fe6f0f45a5de68103b294d20",
-  "_shrinkwrap": null,
   "_spec": "encodeurl@~1.0.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/pillarjs/encodeurl/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Encode a URL to a percent-encoded form, excluding already-encoded sequences",
   "devDependencies": {
     "eslint": "2.11.1",
@@ -66,11 +45,6 @@
     "istanbul": "0.4.3",
     "mocha": "2.5.3"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "79e3d58655346909fe6f0f45a5de68103b294d20",
-    "tarball": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz"
-  },
   "engines": {
     "node": ">= 0.8"
   },
@@ -80,7 +54,6 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "39ed0c235fed4cea7d012038fd6bb0480561d226",
   "homepage": "https://github.com/pillarjs/encodeurl#readme",
   "keywords": [
     "encode",
@@ -88,15 +61,7 @@
     "url"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "encodeurl",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/pillarjs/encodeurl.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-html/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-html/package.json
index b3ace12b6..8e4f247d7 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-html/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-html/package.json
@@ -1,36 +1,19 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "escape-html@~1.0.3",
-        "scope": null,
-        "escapedName": "escape-html",
-        "name": "escape-html",
-        "rawSpec": "~1.0.3",
-        "spec": ">=1.0.3 <1.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "escape-html@>=1.0.3 <1.1.0",
+  "_from": "escape-html@~1.0.3",
   "_id": "escape-html@1.0.3",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
   "_location": "/escape-html",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "escape-html@~1.0.3",
-    "scope": null,
-    "escapedName": "escape-html",
     "name": "escape-html",
+    "escapedName": "escape-html",
     "rawSpec": "~1.0.3",
-    "spec": ">=1.0.3 <1.1.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.0.3"
   },
   "_requiredBy": [
     "/express",
@@ -40,49 +23,31 @@
   ],
   "_resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
   "_shasum": "0258eae4d3d0c0974de1c169188ef0051d1d1988",
-  "_shrinkwrap": null,
   "_spec": "escape-html@~1.0.3",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/component/escape-html/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Escape string for use in HTML",
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
     "benchmark": "1.0.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "0258eae4d3d0c0974de1c169188ef0051d1d1988",
-    "tarball": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
-  },
   "files": [
     "LICENSE",
     "Readme.md",
     "index.js"
   ],
-  "gitHead": "7ac2ea3977fcac3d4c5be8d2a037812820c65f28",
-  "homepage": "https://github.com/component/escape-html",
+  "homepage": "https://github.com/component/escape-html#readme",
   "keywords": [
     "escape",
     "html",
     "utility"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "escape-html",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/component/escape-html.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-string-regexp/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-string-regexp/package.json
index 8a4f7053a..1ecd0275a 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-string-regexp/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/escape-string-regexp/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "escape-string-regexp@^1.0.2",
-        "scope": null,
-        "escapedName": "escape-string-regexp",
-        "name": "escape-string-regexp",
-        "rawSpec": "^1.0.2",
-        "spec": ">=1.0.2 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk"
-    ]
-  ],
-  "_from": "escape-string-regexp@>=1.0.2 <2.0.0",
+  "_from": "escape-string-regexp@^1.0.2",
   "_id": "escape-string-regexp@1.0.5",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
   "_location": "/escape-string-regexp",
-  "_nodeVersion": "4.2.6",
-  "_npmOperationalInternal": {
-    "host": "packages-9-west.internal.npmjs.com",
-    "tmp": "tmp/escape-string-regexp-1.0.5.tgz_1456059312074_0.7245344955008477"
-  },
-  "_npmUser": {
-    "name": "jbnicolai",
-    "email": "jappelman@xebia.com"
-  },
-  "_npmVersion": "2.14.12",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "escape-string-regexp@^1.0.2",
-    "scope": null,
-    "escapedName": "escape-string-regexp",
     "name": "escape-string-regexp",
+    "escapedName": "escape-string-regexp",
     "rawSpec": "^1.0.2",
-    "spec": ">=1.0.2 <2.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^1.0.2"
   },
   "_requiredBy": [
     "/chalk"
   ],
   "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
   "_shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4",
-  "_shrinkwrap": null,
   "_spec": "escape-string-regexp@^1.0.2",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/chalk",
   "author": {
     "name": "Sindre Sorhus",
     "email": "sindresorhus@gmail.com",
@@ -53,25 +30,20 @@
   "bugs": {
     "url": "https://github.com/sindresorhus/escape-string-regexp/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Escape RegExp special characters",
   "devDependencies": {
     "ava": "*",
     "xo": "*"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4",
-    "tarball": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
-  },
   "engines": {
     "node": ">=0.8.0"
   },
   "files": [
     "index.js"
   ],
-  "gitHead": "db124a3e1aae9d692c4899e42a5c6c3e329eaa20",
-  "homepage": "https://github.com/sindresorhus/escape-string-regexp",
+  "homepage": "https://github.com/sindresorhus/escape-string-regexp#readme",
   "keywords": [
     "escape",
     "regex",
@@ -87,17 +59,17 @@
   "license": "MIT",
   "maintainers": [
     {
-      "name": "sindresorhus",
-      "email": "sindresorhus@gmail.com"
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
     },
     {
-      "name": "jbnicolai",
-      "email": "jappelman@xebia.com"
+      "name": "Joshua Boy Nicolai Appelman",
+      "email": "joshua@jbna.nl",
+      "url": "jbna.nl"
     }
   ],
   "name": "escape-string-regexp",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/sindresorhus/escape-string-regexp.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/HISTORY.md
index bd0f26df8..222b293de 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/HISTORY.md
@@ -1,3 +1,15 @@
+1.8.1 / 2017-09-12
+==================
+
+  * perf: replace regular expression with substring
+
+1.8.0 / 2017-02-18
+==================
+
+  * Use SHA1 instead of MD5 for ETag hashing
+    - Improves performance for larger entities
+    - Works with FIPS 140-2 OpenSSL configuration
+
 1.7.0 / 2015-06-08
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/LICENSE
index 142ede386..cab251c2b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/LICENSE
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2014-2015 Douglas Christopher Wilson
+Copyright (c) 2014-2016 Douglas Christopher Wilson
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/README.md
index 8da9e0591..09c2169e7 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/README.md
@@ -6,16 +6,25 @@
 [![Build Status][travis-image]][travis-url]
 [![Test Coverage][coveralls-image]][coveralls-url]
 
-Create simple ETags
+Create simple HTTP ETags
+
+This module generates HTTP ETags (as defined in RFC 7232) for use in
+HTTP responses.
 
 ## Installation
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```sh
 $ npm install etag
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var etag = require('etag')
 ```
@@ -27,6 +36,8 @@ body of the entity. Strings, `Buffer`s, and `fs.Stats` are accepted. By
 default, a strong ETag is generated except for `fs.Stats`, which will
 generate a weak ETag (this can be overwritten by `options.weak`).
 
+<!-- eslint-disable no-undef -->
+
 ```js
 res.setHeader('ETag', etag(body))
 ```
@@ -52,101 +63,84 @@ $ npm test
 ```bash
 $ npm run-script bench
 
-> etag@1.6.0 bench nodejs-etag
+> etag@1.8.1 bench nodejs-etag
 > node benchmark/index.js
 
-  http_parser@1.0
-  node@0.10.33
-  v8@3.14.5.9
-  ares@1.9.0-DEV
-  uv@0.10.29
-  zlib@1.2.3
-  modules@11
-  openssl@1.0.1j
+  http_parser@2.7.0
+  node@6.11.1
+  v8@5.1.281.103
+  uv@1.11.0
+  zlib@1.2.11
+  ares@1.10.1-DEV
+  icu@58.2
+  modules@48
+  openssl@1.0.2k
 
 > node benchmark/body0-100b.js
 
   100B body
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* buffer - strong x 289,198 ops/sec ±1.09% (190 runs sampled)
-* buffer - weak   x 287,838 ops/sec ±0.91% (189 runs sampled)
-* string - strong x 284,586 ops/sec ±1.05% (192 runs sampled)
-* string - weak   x 287,439 ops/sec ±0.82% (192 runs sampled)
+  buffer - strong x 258,647 ops/sec ±1.07% (180 runs sampled)
+  buffer - weak   x 263,812 ops/sec ±0.61% (184 runs sampled)
+  string - strong x 259,955 ops/sec ±1.19% (185 runs sampled)
+  string - weak   x 264,356 ops/sec ±1.09% (184 runs sampled)
 
 > node benchmark/body1-1kb.js
 
   1KB body
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* buffer - strong x 212,423 ops/sec ±0.75% (193 runs sampled)
-* buffer - weak   x 211,871 ops/sec ±0.74% (194 runs sampled)
-  string - strong x 205,291 ops/sec ±0.86% (194 runs sampled)
-  string - weak   x 208,463 ops/sec ±0.79% (192 runs sampled)
+  buffer - strong x 189,018 ops/sec ±1.12% (182 runs sampled)
+  buffer - weak   x 190,586 ops/sec ±0.81% (186 runs sampled)
+  string - strong x 144,272 ops/sec ±0.96% (188 runs sampled)
+  string - weak   x 145,380 ops/sec ±1.43% (187 runs sampled)
 
 > node benchmark/body2-5kb.js
 
   5KB body
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* buffer - strong x 92,901 ops/sec ±0.58% (195 runs sampled)
-* buffer - weak   x 93,045 ops/sec ±0.65% (192 runs sampled)
-  string - strong x 89,621 ops/sec ±0.68% (194 runs sampled)
-  string - weak   x 90,070 ops/sec ±0.70% (196 runs sampled)
+  buffer - strong x 92,435 ops/sec ±0.42% (188 runs sampled)
+  buffer - weak   x 92,373 ops/sec ±0.58% (189 runs sampled)
+  string - strong x 48,850 ops/sec ±0.56% (186 runs sampled)
+  string - weak   x 49,380 ops/sec ±0.56% (190 runs sampled)
 
 > node benchmark/body3-10kb.js
 
   10KB body
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* buffer - strong x 54,220 ops/sec ±0.85% (192 runs sampled)
-* buffer - weak   x 54,069 ops/sec ±0.83% (191 runs sampled)
-  string - strong x 53,078 ops/sec ±0.53% (194 runs sampled)
-  string - weak   x 53,849 ops/sec ±0.47% (197 runs sampled)
+  buffer - strong x 55,989 ops/sec ±0.93% (188 runs sampled)
+  buffer - weak   x 56,148 ops/sec ±0.55% (190 runs sampled)
+  string - strong x 27,345 ops/sec ±0.43% (188 runs sampled)
+  string - weak   x 27,496 ops/sec ±0.45% (190 runs sampled)
 
 > node benchmark/body4-100kb.js
 
   100KB body
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* buffer - strong x 6,673 ops/sec ±0.15% (197 runs sampled)
-* buffer - weak   x 6,716 ops/sec ±0.12% (198 runs sampled)
-  string - strong x 6,357 ops/sec ±0.14% (197 runs sampled)
-  string - weak   x 6,344 ops/sec ±0.21% (197 runs sampled)
+  buffer - strong x 7,083 ops/sec ±0.22% (190 runs sampled)
+  buffer - weak   x 7,115 ops/sec ±0.26% (191 runs sampled)
+  string - strong x 3,068 ops/sec ±0.34% (190 runs sampled)
+  string - weak   x 3,096 ops/sec ±0.35% (190 runs sampled)
 
 > node benchmark/stats.js
 
-  stats
+  stat
 
-  1 test completed.
-  2 tests completed.
-  3 tests completed.
   4 tests completed.
 
-* real - strong x 1,671,989 ops/sec ±0.13% (197 runs sampled)
-* real - weak   x 1,681,297 ops/sec ±0.12% (198 runs sampled)
-  fake - strong x   927,063 ops/sec ±0.14% (198 runs sampled)
-  fake - weak   x   914,461 ops/sec ±0.41% (191 runs sampled)
+  real - strong x 871,642 ops/sec ±0.34% (189 runs sampled)
+  real - weak   x 867,613 ops/sec ±0.39% (190 runs sampled)
+  fake - strong x 401,051 ops/sec ±0.40% (189 runs sampled)
+  fake - weak   x 400,100 ops/sec ±0.47% (188 runs sampled)
 ```
 
 ## License
@@ -156,7 +150,7 @@ $ npm run-script bench
 [npm-image]: https://img.shields.io/npm/v/etag.svg
 [npm-url]: https://npmjs.org/package/etag
 [node-version-image]: https://img.shields.io/node/v/etag.svg
-[node-version-url]: http://nodejs.org/download/
+[node-version-url]: https://nodejs.org/en/download/
 [travis-image]: https://img.shields.io/travis/jshttp/etag/master.svg
 [travis-url]: https://travis-ci.org/jshttp/etag
 [coveralls-image]: https://img.shields.io/coveralls/jshttp/etag/master.svg
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/index.js
index b582c84cd..2a585c91f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/index.js
@@ -1,6 +1,6 @@
 /*!
  * etag
- * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * Copyright(c) 2014-2016 Douglas Christopher Wilson
  * MIT Licensed
  */
 
@@ -26,7 +26,6 @@ var Stats = require('fs').Stats
  * @private
  */
 
-var base64PadCharRegExp = /=+$/
 var toString = Object.prototype.toString
 
 /**
@@ -37,18 +36,18 @@ var toString = Object.prototype.toString
  * @private
  */
 
-function entitytag(entity) {
+function entitytag (entity) {
   if (entity.length === 0) {
     // fast-path empty
-    return '"0-1B2M2Y8AsgTpgAmY7PhCfg"'
+    return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'
   }
 
   // compute hash of entity
   var hash = crypto
-    .createHash('md5')
+    .createHash('sha1')
     .update(entity, 'utf8')
     .digest('base64')
-    .replace(base64PadCharRegExp, '')
+    .substring(0, 27)
 
   // compute length of entity
   var len = typeof entity === 'string'
@@ -68,7 +67,7 @@ function entitytag(entity) {
  * @public
  */
 
-function etag(entity, options) {
+function etag (entity, options) {
   if (entity == null) {
     throw new TypeError('argument entity is required')
   }
@@ -102,18 +101,18 @@ function etag(entity, options) {
  * @api private
  */
 
-function isstats(obj) {
+function isstats (obj) {
   // genuine fs.Stats
   if (typeof Stats === 'function' && obj instanceof Stats) {
     return true
   }
 
   // quack quack
-  return obj && typeof obj === 'object'
-    && 'ctime' in obj && toString.call(obj.ctime) === '[object Date]'
-    && 'mtime' in obj && toString.call(obj.mtime) === '[object Date]'
-    && 'ino' in obj && typeof obj.ino === 'number'
-    && 'size' in obj && typeof obj.size === 'number'
+  return obj && typeof obj === 'object' &&
+    'ctime' in obj && toString.call(obj.ctime) === '[object Date]' &&
+    'mtime' in obj && toString.call(obj.mtime) === '[object Date]' &&
+    'ino' in obj && typeof obj.ino === 'number' &&
+    'size' in obj && typeof obj.size === 'number'
 }
 
 /**
@@ -124,7 +123,7 @@ function isstats(obj) {
  * @private
  */
 
-function stattag(stat) {
+function stattag (stat) {
   var mtime = stat.mtime.getTime().toString(16)
   var size = stat.size.toString(16)
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/package.json
index 240062c0f..632324e85 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/etag/package.json
@@ -1,49 +1,32 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "etag@~1.7.0",
-        "scope": null,
-        "escapedName": "etag",
-        "name": "etag",
-        "rawSpec": "~1.7.0",
-        "spec": ">=1.7.0 <1.8.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "etag@>=1.7.0 <1.8.0",
-  "_id": "etag@1.7.0",
-  "_inCache": true,
+  "_from": "etag@~1.8.1",
+  "_id": "etag@1.8.1",
+  "_inBundle": false,
+  "_integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
   "_location": "/etag",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "etag@~1.7.0",
-    "scope": null,
-    "escapedName": "etag",
+    "type": "range",
+    "registry": true,
+    "raw": "etag@~1.8.1",
     "name": "etag",
-    "rawSpec": "~1.7.0",
-    "spec": ">=1.7.0 <1.8.0",
-    "type": "range"
+    "escapedName": "etag",
+    "rawSpec": "~1.8.1",
+    "saveSpec": null,
+    "fetchSpec": "~1.8.1"
   },
   "_requiredBy": [
     "/express",
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz",
-  "_shasum": "03d30b5f67dd6e632d2945d30d6652731a34d5d8",
-  "_shrinkwrap": null,
-  "_spec": "etag@~1.7.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+  "_shasum": "41ae2eeb65efa62268aebfea83ac7d79299b0887",
+  "_spec": "etag@~1.8.1",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/jshttp/etag/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -54,19 +37,22 @@
       "email": "david.bjorklund@gmail.com"
     }
   ],
-  "dependencies": {},
-  "description": "Create simple ETags",
+  "deprecated": false,
+  "description": "Create simple HTTP ETags",
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
-    "benchmark": "1.0.0",
-    "istanbul": "0.3.14",
-    "mocha": "~1.21.4",
-    "seedrandom": "2.3.11"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "03d30b5f67dd6e632d2945d30d6652731a34d5d8",
-    "tarball": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz"
+    "benchmark": "2.1.4",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "istanbul": "0.4.5",
+    "mocha": "1.21.5",
+    "safe-buffer": "5.1.1",
+    "seedrandom": "2.4.3"
   },
   "engines": {
     "node": ">= 0.6"
@@ -77,32 +63,24 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "a511f5c8c930fd9546dbd88acb080f96bc788cfc",
-  "homepage": "https://github.com/jshttp/etag",
+  "homepage": "https://github.com/jshttp/etag#readme",
   "keywords": [
     "etag",
     "http",
     "res"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "etag",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/etag.git"
   },
   "scripts": {
     "bench": "node benchmark/index.js",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail --check-leaks 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.7.0"
+  "version": "1.8.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/History.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/History.md
index 4a706a4d1..fbf59a234 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/History.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/History.md
@@ -1,3 +1,215 @@
+4.16.2 / 2017-10-09
+===================
+
+  * Fix `TypeError` in `res.send` when given `Buffer` and `ETag` header set
+  * perf: skip parsing of entire `X-Forwarded-Proto` header
+
+4.16.1 / 2017-09-29
+===================
+
+  * deps: send@0.16.1
+  * deps: serve-static@1.13.1
+    - Fix regression when `root` is incorrectly set to a file
+    - deps: send@0.16.1
+
+4.16.0 / 2017-09-28
+===================
+
+  * Add `"json escape"` setting for `res.json` and `res.jsonp`
+  * Add `express.json` and `express.urlencoded` to parse bodies
+  * Add `options` argument to `res.download`
+  * Improve error message when autoloading invalid view engine
+  * Improve error messages when non-function provided as middleware
+  * Skip `Buffer` encoding when not generating ETag for small response
+  * Use `safe-buffer` for improved Buffer API
+  * deps: accepts@~1.3.4
+    - deps: mime-types@~2.1.16
+  * deps: content-type@~1.0.4
+    - perf: remove argument reassignment
+    - perf: skip parameter parsing when no parameters
+  * deps: etag@~1.8.1
+    - perf: replace regular expression with substring
+  * deps: finalhandler@1.1.0
+    - Use `res.headersSent` when available
+  * deps: parseurl@~1.3.2
+    - perf: reduce overhead for full URLs
+    - perf: unroll the "fast-path" `RegExp`
+  * deps: proxy-addr@~2.0.2
+    - Fix trimming leading / trailing OWS in `X-Forwarded-For`
+    - deps: forwarded@~0.1.2
+    - deps: ipaddr.js@1.5.2
+    - perf: reduce overhead when no `X-Forwarded-For` header
+  * deps: qs@6.5.1
+    - Fix parsing & compacting very deep objects
+  * deps: send@0.16.0
+    - Add 70 new types for file extensions
+    - Add `immutable` option
+    - Fix missing `</html>` in default error & redirects
+    - Set charset as "UTF-8" for .js and .json
+    - Use instance methods on steam to check for listeners
+    - deps: mime@1.4.1
+    - perf: improve path validation speed
+  * deps: serve-static@1.13.0
+    - Add 70 new types for file extensions
+    - Add `immutable` option
+    - Set charset as "UTF-8" for .js and .json
+    - deps: send@0.16.0
+  * deps: setprototypeof@1.1.0
+  * deps: utils-merge@1.0.1
+  * deps: vary@~1.1.2
+    - perf: improve header token parsing speed
+  * perf: re-use options object when generating ETags
+  * perf: remove dead `.charset` set in `res.jsonp`
+
+4.15.5 / 2017-09-24
+===================
+
+  * deps: debug@2.6.9
+  * deps: finalhandler@~1.0.6
+    - deps: debug@2.6.9
+    - deps: parseurl@~1.3.2
+  * deps: fresh@0.5.2
+    - Fix handling of modified headers with invalid dates
+    - perf: improve ETag match loop
+    - perf: improve `If-None-Match` token parsing
+  * deps: send@0.15.6
+    - Fix handling of modified headers with invalid dates
+    - deps: debug@2.6.9
+    - deps: etag@~1.8.1
+    - deps: fresh@0.5.2
+    - perf: improve `If-Match` token parsing
+  * deps: serve-static@1.12.6
+    - deps: parseurl@~1.3.2
+    - deps: send@0.15.6
+    - perf: improve slash collapsing
+
+4.15.4 / 2017-08-06
+===================
+
+  * deps: debug@2.6.8
+  * deps: depd@~1.1.1
+    - Remove unnecessary `Buffer` loading
+  * deps: finalhandler@~1.0.4
+    - deps: debug@2.6.8
+  * deps: proxy-addr@~1.1.5
+    - Fix array argument being altered
+    - deps: ipaddr.js@1.4.0
+  * deps: qs@6.5.0
+  * deps: send@0.15.4
+    - deps: debug@2.6.8
+    - deps: depd@~1.1.1
+    - deps: http-errors@~1.6.2
+  * deps: serve-static@1.12.4
+    - deps: send@0.15.4
+
+4.15.3 / 2017-05-16
+===================
+
+  * Fix error when `res.set` cannot add charset to `Content-Type`
+  * deps: debug@2.6.7
+    - Fix `DEBUG_MAX_ARRAY_LENGTH`
+    - deps: ms@2.0.0
+  * deps: finalhandler@~1.0.3
+    - Fix missing `</html>` in HTML document
+    - deps: debug@2.6.7
+  * deps: proxy-addr@~1.1.4
+    - deps: ipaddr.js@1.3.0
+  * deps: send@0.15.3
+    - deps: debug@2.6.7
+    - deps: ms@2.0.0
+  * deps: serve-static@1.12.3
+    - deps: send@0.15.3
+  * deps: type-is@~1.6.15
+    - deps: mime-types@~2.1.15
+  * deps: vary@~1.1.1
+    - perf: hoist regular expression
+
+4.15.2 / 2017-03-06
+===================
+
+  * deps: qs@6.4.0
+    - Fix regression parsing keys starting with `[`
+
+4.15.1 / 2017-03-05
+===================
+
+  * deps: send@0.15.1
+    - Fix issue when `Date.parse` does not return `NaN` on invalid date
+    - Fix strict violation in broken environments
+  * deps: serve-static@1.12.1
+    - Fix issue when `Date.parse` does not return `NaN` on invalid date
+    - deps: send@0.15.1
+
+4.15.0 / 2017-03-01
+===================
+
+  * Add debug message when loading view engine
+  * Add `next("router")` to exit from router
+  * Fix case where `router.use` skipped requests routes did not
+  * Remove usage of `res._headers` private field
+    - Improves compatibility with Node.js 8 nightly
+  * Skip routing when `req.url` is not set
+  * Use `%o` in path debug to tell types apart
+  * Use `Object.create` to setup request & response prototypes
+  * Use `setprototypeof` module to replace `__proto__` setting
+  * Use `statuses` instead of `http` module for status messages
+  * deps: debug@2.6.1
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable set to `3` or higher
+    - Fix error when running under React Native
+    - Use same color for same namespace
+    - deps: ms@0.7.2
+  * deps: etag@~1.8.0
+    - Use SHA1 instead of MD5 for ETag hashing
+    - Works with FIPS 140-2 OpenSSL configuration
+  * deps: finalhandler@~1.0.0
+    - Fix exception when `err` cannot be converted to a string
+    - Fully URL-encode the pathname in the 404
+    - Only include the pathname in the 404 message
+    - Send complete HTML document
+    - Set `Content-Security-Policy: default-src 'self'` header
+    - deps: debug@2.6.1
+  * deps: fresh@0.5.0
+    - Fix false detection of `no-cache` request directive
+    - Fix incorrect result when `If-None-Match` has both `*` and ETags
+    - Fix weak `ETag` matching to match spec
+    - perf: delay reading header values until needed
+    - perf: enable strict mode
+    - perf: hoist regular expressions
+    - perf: remove duplicate conditional
+    - perf: remove unnecessary boolean coercions
+    - perf: skip checking modified time if ETag check failed
+    - perf: skip parsing `If-None-Match` when no `ETag` header
+    - perf: use `Date.parse` instead of `new Date`
+  * deps: qs@6.3.1
+    - Fix array parsing from skipping empty values
+    - Fix compacting nested arrays
+  * deps: send@0.15.0
+    - Fix false detection of `no-cache` request directive
+    - Fix incorrect result when `If-None-Match` has both `*` and ETags
+    - Fix weak `ETag` matching to match spec
+    - Remove usage of `res._headers` private field
+    - Support `If-Match` and `If-Unmodified-Since` headers
+    - Use `res.getHeaderNames()` when available
+    - Use `res.headersSent` when available
+    - deps: debug@2.6.1
+    - deps: etag@~1.8.0
+    - deps: fresh@0.5.0
+    - deps: http-errors@~1.6.1
+  * deps: serve-static@1.12.0
+    - Fix false detection of `no-cache` request directive
+    - Fix incorrect result when `If-None-Match` has both `*` and ETags
+    - Fix weak `ETag` matching to match spec
+    - Remove usage of `res._headers` private field
+    - Send complete HTML document in redirect response
+    - Set default CSP header in redirect response
+    - Support `If-Match` and `If-Unmodified-Since` headers
+    - Use `res.getHeaderNames()` when available
+    - Use `res.headersSent` when available
+    - deps: send@0.15.0
+  * perf: add fast match path for `*` route
+  * perf: improve `req.ips` performance
+
 4.14.1 / 2017-01-28
 ===================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/Readme.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/Readme.md
index e9bfaeba2..3cd220325 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/Readme.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/Readme.md
@@ -21,10 +21,22 @@ app.listen(3000)
 
 ## Installation
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/).
+
+Before installing, [download and install Node.js](https://nodejs.org/en/download/).
+Node.js 0.10 or higher is required.
+
+Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```bash
 $ npm install express
 ```
 
+Follow [our installing guide](http://expressjs.com/en/starter/installing.html)
+for more information.
+
 ## Features
 
   * Robust routing
@@ -37,17 +49,16 @@ $ npm install express
 
 ## Docs & Community
 
-  * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/strongloop/expressjs.com)]
+  * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)]
   * [#express](https://webchat.freenode.net/?channels=express) on freenode IRC
-  * [Github Organization](https://github.com/expressjs) for Official Middleware & Modules
+  * [GitHub Organization](https://github.com/expressjs) for Official Middleware & Modules
   * Visit the [Wiki](https://github.com/expressjs/express/wiki)
   * [Google Group](https://groups.google.com/group/express-js) for discussion
   * [Gitter](https://gitter.im/expressjs/express) for support and discussion
-  * [Русскоязычная документация](http://jsman.ru/express/)
 
 **PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x).
 
-###Security Issues
+### Security Issues
 
 If you discover a security vulnerability in Express, please see [Security Policies and Procedures](Security.md).
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/application.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/application.js
index 0ee4def38..91f77d241 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/application.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/application.js
@@ -28,6 +28,7 @@ var deprecate = require('depd')('express');
 var flatten = require('array-flatten');
 var merge = require('utils-merge');
 var resolve = require('path').resolve;
+var setPrototypeOf = require('setprototypeof')
 var slice = Array.prototype.slice;
 
 /**
@@ -94,10 +95,10 @@ app.defaultConfiguration = function defaultConfiguration() {
     }
 
     // inherit protos
-    this.request.__proto__ = parent.request;
-    this.response.__proto__ = parent.response;
-    this.engines.__proto__ = parent.engines;
-    this.settings.__proto__ = parent.settings;
+    setPrototypeOf(this.request, parent.request)
+    setPrototypeOf(this.response, parent.response)
+    setPrototypeOf(this.engines, parent.engines)
+    setPrototypeOf(this.settings, parent.settings)
   });
 
   // setup locals
@@ -206,7 +207,7 @@ app.use = function use(fn) {
   var fns = flatten(slice.call(arguments, offset));
 
   if (fns.length === 0) {
-    throw new TypeError('app.use() requires middleware functions');
+    throw new TypeError('app.use() requires a middleware function')
   }
 
   // setup router
@@ -227,8 +228,8 @@ app.use = function use(fn) {
     router.use(path, function mounted_app(req, res, next) {
       var orig = req.app;
       fn.handle(req, res, function (err) {
-        req.__proto__ = orig.request;
-        res.__proto__ = orig.response;
+        setPrototypeOf(req, orig.request)
+        setPrototypeOf(res, orig.response)
         next(err);
       });
     });
@@ -261,9 +262,9 @@ app.route = function route(path) {
  *
  * By default will `require()` the engine based on the
  * file extension. For example if you try to render
- * a "foo.jade" file Express will invoke the following internally:
+ * a "foo.ejs" file Express will invoke the following internally:
  *
- *     app.engine('jade', require('jade').__express);
+ *     app.engine('ejs', require('ejs').__express);
  *
  * For engines that do not provide `.__express` out of the box,
  * or if you wish to "map" a different extension to the template engine
@@ -337,7 +338,7 @@ app.param = function param(name, fn) {
  * Assign `setting` to `val`, or return `setting`'s value.
  *
  *    app.set('foo', 'bar');
- *    app.get('foo');
+ *    app.set('foo');
  *    // => "bar"
  *
  * Mounted servers inherit their parent server's settings.
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/express.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/express.js
index 540c8be6f..485a8fc08 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/express.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/express.js
@@ -12,6 +12,7 @@
  * Module dependencies.
  */
 
+var bodyParser = require('body-parser')
 var EventEmitter = require('events').EventEmitter;
 var mixin = require('merge-descriptors');
 var proto = require('./application');
@@ -41,8 +42,16 @@ function createApplication() {
   mixin(app, EventEmitter.prototype, false);
   mixin(app, proto, false);
 
-  app.request = { __proto__: req, app: app };
-  app.response = { __proto__: res, app: app };
+  // expose the prototype that will get set on requests
+  app.request = Object.create(req, {
+    app: { configurable: true, enumerable: true, writable: true, value: app }
+  })
+
+  // expose the prototype that will get set on responses
+  app.response = Object.create(res, {
+    app: { configurable: true, enumerable: true, writable: true, value: app }
+  })
+
   app.init();
   return app;
 }
@@ -66,16 +75,16 @@ exports.Router = Router;
  * Expose middleware
  */
 
+exports.json = bodyParser.json
 exports.query = require('./middleware/query');
 exports.static = require('serve-static');
+exports.urlencoded = bodyParser.urlencoded
 
 /**
  * Replace removed middleware with an appropriate error message.
  */
 
-[
-  'json',
-  'urlencoded',
+;[
   'bodyParser',
   'compress',
   'cookieSession',
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/init.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/init.js
index f3119ed3a..dfd042747 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/init.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/init.js
@@ -8,6 +8,13 @@
 
 'use strict';
 
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var setPrototypeOf = require('setprototypeof')
+
 /**
  * Initialization middleware, exposing the
  * request and response to each other, as well
@@ -25,8 +32,8 @@ exports.init = function(app){
     res.req = req;
     req.next = next;
 
-    req.__proto__ = app.request;
-    res.__proto__ = app.response;
+    setPrototypeOf(req, app.request)
+    setPrototypeOf(res, app.response)
 
     res.locals = res.locals || Object.create(null);
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/query.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/query.js
index 5f76f8458..7e9166947 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/query.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/middleware/query.js
@@ -12,6 +12,7 @@
  * Module dependencies.
  */
 
+var merge = require('utils-merge')
 var parseUrl = require('parseurl');
 var qs = require('qs');
 
@@ -22,7 +23,7 @@ var qs = require('qs');
  */
 
 module.exports = function query(options) {
-  var opts = Object.create(options || null);
+  var opts = merge({}, options)
   var queryparse = qs.parse;
 
   if (typeof options === 'function') {
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/request.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/request.js
index 557d050ff..8bb86a9ac 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/request.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/request.js
@@ -25,11 +25,17 @@ var proxyaddr = require('proxy-addr');
 
 /**
  * Request prototype.
+ * @public
  */
 
-var req = exports = module.exports = {
-  __proto__: http.IncomingMessage.prototype
-};
+var req = Object.create(http.IncomingMessage.prototype)
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = req
 
 /**
  * Return request header.
@@ -309,8 +315,12 @@ defineGetter(req, 'protocol', function protocol(){
 
   // Note: X-Forwarded-Proto is normally only ever a
   //       single value, but this is to be safe.
-  proto = this.get('X-Forwarded-Proto') || proto;
-  return proto.split(/\s*,\s*/)[0];
+  var header = this.get('X-Forwarded-Proto') || proto
+  var index = header.indexOf(',')
+
+  return index !== -1
+    ? header.substring(0, index).trim()
+    : header.trim()
 });
 
 /**
@@ -356,7 +366,12 @@ defineGetter(req, 'ip', function ip(){
 defineGetter(req, 'ips', function ips() {
   var trust = this.app.get('trust proxy fn');
   var addrs = proxyaddr.all(this, trust);
-  return addrs.slice(1).reverse();
+
+  // reverse the order (to farthest -> closest)
+  // and remove socket address
+  addrs.reverse().pop()
+
+  return addrs
 });
 
 /**
@@ -447,14 +462,18 @@ defineGetter(req, 'host', deprecate.function(function host(){
 
 defineGetter(req, 'fresh', function(){
   var method = this.method;
-  var s = this.res.statusCode;
+  var res = this.res
+  var status = res.statusCode
 
   // GET or HEAD for weak freshness validation only
   if ('GET' !== method && 'HEAD' !== method) return false;
 
   // 2xx or 304 as per rfc2616 14.26
-  if ((s >= 200 && s < 300) || 304 === s) {
-    return fresh(this.headers, (this.res._headers || {}));
+  if ((status >= 200 && status < 300) || 304 === status) {
+    return fresh(this.headers, {
+      'etag': res.get('ETag'),
+      'last-modified': res.get('Last-Modified')
+    })
   }
 
   return false;
@@ -499,4 +518,4 @@ function defineGetter(obj, name, getter) {
     enumerable: true,
     get: getter
   });
-};
+}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/response.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/response.js
index 6128f450a..9c1796d37 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/response.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/response.js
@@ -12,6 +12,7 @@
  * @private
  */
 
+var Buffer = require('safe-buffer').Buffer
 var contentDisposition = require('content-disposition');
 var deprecate = require('depd')('express');
 var encodeUrl = require('encodeurl');
@@ -20,12 +21,12 @@ var http = require('http');
 var isAbsolute = require('./utils').isAbsolute;
 var onFinished = require('on-finished');
 var path = require('path');
+var statuses = require('statuses')
 var merge = require('utils-merge');
 var sign = require('cookie-signature').sign;
 var normalizeType = require('./utils').normalizeType;
 var normalizeTypes = require('./utils').normalizeTypes;
 var setCharset = require('./utils').setCharset;
-var statusCodes = http.STATUS_CODES;
 var cookie = require('cookie');
 var send = require('send');
 var extname = path.extname;
@@ -35,11 +36,17 @@ var vary = require('vary');
 
 /**
  * Response prototype.
+ * @public
  */
 
-var res = module.exports = {
-  __proto__: http.ServerResponse.prototype
-};
+var res = Object.create(http.ServerResponse.prototype)
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = res
 
 /**
  * Module variables.
@@ -89,7 +96,7 @@ res.links = function(links){
  *
  * Examples:
  *
- *     res.send(new Buffer('wahoo'));
+ *     res.send(Buffer.from('wahoo'));
  *     res.send({ some: 'json' });
  *     res.send('<p>some html</p>');
  *
@@ -100,7 +107,6 @@ res.links = function(links){
 res.send = function send(body) {
   var chunk = body;
   var encoding;
-  var len;
   var req = this.req;
   var type;
 
@@ -129,7 +135,7 @@ res.send = function send(body) {
 
     deprecate('res.send(status): Use res.sendStatus(status) instead');
     this.statusCode = chunk;
-    chunk = statusCodes[chunk];
+    chunk = statuses[chunk]
   }
 
   switch (typeof chunk) {
@@ -165,23 +171,33 @@ res.send = function send(body) {
     }
   }
 
+  // determine if ETag should be generated
+  var etagFn = app.get('etag fn')
+  var generateETag = !this.get('ETag') && typeof etagFn === 'function'
+
   // populate Content-Length
+  var len
   if (chunk !== undefined) {
-    if (!Buffer.isBuffer(chunk)) {
-      // convert chunk to Buffer; saves later double conversions
-      chunk = new Buffer(chunk, encoding);
+    if (Buffer.isBuffer(chunk)) {
+      // get length of Buffer
+      len = chunk.length
+    } else if (!generateETag && chunk.length < 1000) {
+      // just calculate length when no ETag + small chunk
+      len = Buffer.byteLength(chunk, encoding)
+    } else {
+      // convert chunk to Buffer and calculate
+      chunk = Buffer.from(chunk, encoding)
       encoding = undefined;
+      len = chunk.length
     }
 
-    len = chunk.length;
     this.set('Content-Length', len);
   }
 
   // populate ETag
   var etag;
-  var generateETag = len !== undefined && app.get('etag fn');
-  if (typeof generateETag === 'function' && !this.get('ETag')) {
-    if ((etag = generateETag(chunk, encoding))) {
+  if (generateETag && len !== undefined) {
+    if ((etag = etagFn(chunk, encoding))) {
       this.set('ETag', etag);
     }
   }
@@ -238,9 +254,10 @@ res.json = function json(obj) {
 
   // settings
   var app = this.app;
+  var escape = app.get('json escape')
   var replacer = app.get('json replacer');
   var spaces = app.get('json spaces');
-  var body = stringify(val, replacer, spaces);
+  var body = stringify(val, replacer, spaces, escape)
 
   // content-type
   if (!this.get('Content-Type')) {
@@ -280,9 +297,10 @@ res.jsonp = function jsonp(obj) {
 
   // settings
   var app = this.app;
+  var escape = app.get('json escape')
   var replacer = app.get('json replacer');
   var spaces = app.get('json spaces');
-  var body = stringify(val, replacer, spaces);
+  var body = stringify(val, replacer, spaces, escape)
   var callback = this.req.query[app.get('jsonp callback name')];
 
   // content-type
@@ -298,7 +316,6 @@ res.jsonp = function jsonp(obj) {
 
   // jsonp
   if (typeof callback === 'string' && callback.length !== 0) {
-    this.charset = 'utf-8';
     this.set('X-Content-Type-Options', 'nosniff');
     this.set('Content-Type', 'text/javascript');
 
@@ -334,7 +351,7 @@ res.jsonp = function jsonp(obj) {
  */
 
 res.sendStatus = function sendStatus(statusCode) {
-  var body = statusCodes[statusCode] || String(statusCode);
+  var body = statuses[statusCode] || String(statusCode)
 
   this.statusCode = statusCode;
   this.type('txt');
@@ -500,19 +517,29 @@ res.sendfile = deprecate.function(res.sendfile,
  * when the data transfer is complete, or when an error has
  * ocurred. Be sure to check `res.headersSent` if you plan to respond.
  *
- * This method uses `res.sendfile()`.
+ * Optionally providing an `options` object to use with `res.sendFile()`.
+ * This function will set the `Content-Disposition` header, overriding
+ * any `Content-Disposition` header passed as header options in order
+ * to set the attachment and filename.
+ *
+ * This method uses `res.sendFile()`.
  *
  * @public
  */
 
-res.download = function download(path, filename, callback) {
+res.download = function download (path, filename, options, callback) {
   var done = callback;
   var name = filename;
+  var opts = options || null
 
-  // support function as second arg
+  // support function as second or third arg
   if (typeof filename === 'function') {
     done = filename;
     name = null;
+    opts = null
+  } else if (typeof options === 'function') {
+    done = options
+    opts = null
   }
 
   // set Content-Disposition when file is sent
@@ -520,10 +547,26 @@ res.download = function download(path, filename, callback) {
     'Content-Disposition': contentDisposition(name || path)
   };
 
+  // merge user-provided headers
+  if (opts && opts.headers) {
+    var keys = Object.keys(opts.headers)
+    for (var i = 0; i < keys.length; i++) {
+      var key = keys[i]
+      if (key.toLowerCase() !== 'content-disposition') {
+        headers[key] = opts.headers[key]
+      }
+    }
+  }
+
+  // merge user-provided options
+  opts = Object.create(opts)
+  opts.headers = headers
+
   // Resolve the full path for sendFile
   var fullPath = resolve(path);
 
-  return this.sendFile(fullPath, { headers: headers }, done);
+  // send file
+  return this.sendFile(fullPath, opts, done)
 };
 
 /**
@@ -711,9 +754,14 @@ res.header = function header(field, val) {
       : String(val);
 
     // add charset to content-type
-    if (field.toLowerCase() === 'content-type' && !charsetRegExp.test(value)) {
-      var charset = mime.charsets.lookup(value.split(';')[0]);
-      if (charset) value += '; charset=' + charset.toLowerCase();
+    if (field.toLowerCase() === 'content-type') {
+      if (Array.isArray(value)) {
+        throw new TypeError('Content-Type cannot be set to an Array');
+      }
+      if (!charsetRegExp.test(value)) {
+        var charset = mime.charsets.lookup(value.split(';')[0]);
+        if (charset) value += '; charset=' + charset.toLowerCase();
+      }
     }
 
     this.setHeader(field, value);
@@ -771,7 +819,7 @@ res.clearCookie = function clearCookie(name, options) {
  *
  * @param {String} name
  * @param {String|Object} value
- * @param {Options} options
+ * @param {Object} [options]
  * @return {ServerResponse} for chaining
  * @public
  */
@@ -876,12 +924,12 @@ res.redirect = function redirect(url) {
   // Support text/{plain,html} by default
   this.format({
     text: function(){
-      body = statusCodes[status] + '. Redirecting to ' + address;
+      body = statuses[status] + '. Redirecting to ' + address
     },
 
     html: function(){
       var u = escapeHtml(address);
-      body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>';
+      body = '<p>' + statuses[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'
     },
 
     default: function(){
@@ -1052,14 +1100,38 @@ function sendfile(res, file, options, callback) {
 }
 
 /**
- * Stringify JSON, like JSON.stringify, but v8 optimized.
+ * Stringify JSON, like JSON.stringify, but v8 optimized, with the
+ * ability to escape characters that can trigger HTML sniffing.
+ *
+ * @param {*} value
+ * @param {function} replaces
+ * @param {number} spaces
+ * @param {boolean} escape
+ * @returns {string}
  * @private
  */
 
-function stringify(value, replacer, spaces) {
+function stringify (value, replacer, spaces, escape) {
   // v8 checks arguments.length for optimizing simple call
   // https://bugs.chromium.org/p/v8/issues/detail?id=4730
-  return replacer || spaces
+  var json = replacer || spaces
     ? JSON.stringify(value, replacer, spaces)
     : JSON.stringify(value);
+
+  if (escape) {
+    json = json.replace(/[<>&]/g, function (c) {
+      switch (c.charCodeAt(0)) {
+        case 0x3c:
+          return '\\u003c'
+        case 0x3e:
+          return '\\u003e'
+        case 0x26:
+          return '\\u0026'
+        default:
+          return c
+      }
+    })
+  }
+
+  return json
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/index.js
index dac251481..60727ed6d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/index.js
@@ -21,6 +21,7 @@ var debug = require('debug')('express:router');
 var deprecate = require('depd')('express');
 var flatten = require('array-flatten');
 var parseUrl = require('parseurl');
+var setPrototypeOf = require('setprototypeof')
 
 /**
  * Module variables.
@@ -47,7 +48,7 @@ var proto = module.exports = function(options) {
   }
 
   // mixin Router class functions
-  router.__proto__ = proto;
+  setPrototypeOf(router, proto)
 
   router.params = {};
   router._params = [];
@@ -137,11 +138,8 @@ proto.handle = function handle(req, res, out) {
 
   debug('dispatching %s %s', req.method, req.url);
 
-  var search = 1 + req.url.indexOf('?');
-  var pathlength = search ? search - 1 : req.url.length;
-  var fqdn = req.url[0] !== '/' && 1 + req.url.substr(0, pathlength).indexOf('://');
-  var protohost = fqdn ? req.url.substr(0, req.url.indexOf('/', 2 + fqdn)) : '';
   var idx = 0;
+  var protohost = getProtohost(req.url) || ''
   var removed = '';
   var slashAdded = false;
   var paramcalled = {};
@@ -193,6 +191,12 @@ proto.handle = function handle(req, res, out) {
       removed = '';
     }
 
+    // signal to exit router
+    if (layerError === 'router') {
+      setImmediate(done, null)
+      return
+    }
+
     // no more matching layers
     if (idx >= stack.length) {
       setImmediate(done, layerError);
@@ -282,18 +286,19 @@ proto.handle = function handle(req, res, out) {
   }
 
   function trim_prefix(layer, layerError, layerPath, path) {
-    var c = path[layerPath.length];
-    if (c && '/' !== c && '.' !== c) return next(layerError);
-
-     // Trim off the part of the url that matches the route
-     // middleware (.use stuff) needs to have the path stripped
     if (layerPath.length !== 0) {
+      // Validate path breaks on a path separator
+      var c = path[layerPath.length]
+      if (c && c !== '/' && c !== '.') return next(layerError)
+
+      // Trim off the part of the url that matches the route
+      // middleware (.use stuff) needs to have the path stripped
       debug('trim prefix (%s) from url %s', layerPath, req.url);
       removed = layerPath;
       req.url = protohost + req.url.substr(protohost.length + removed.length);
 
       // Ensure leading slash
-      if (!fqdn && req.url[0] !== '/') {
+      if (!protohost && req.url[0] !== '/') {
         req.url = '/' + req.url;
         slashAdded = true;
       }
@@ -351,11 +356,6 @@ proto.process_params = function process_params(layer, called, req, res, done) {
 
     paramIndex = 0;
     key = keys[i++];
-
-    if (!key) {
-      return done();
-    }
-
     name = key.name;
     paramVal = req.params[name];
     paramCallbacks = params[name];
@@ -448,18 +448,18 @@ proto.use = function use(fn) {
   var callbacks = flatten(slice.call(arguments, offset));
 
   if (callbacks.length === 0) {
-    throw new TypeError('Router.use() requires middleware functions');
+    throw new TypeError('Router.use() requires a middleware function')
   }
 
   for (var i = 0; i < callbacks.length; i++) {
     var fn = callbacks[i];
 
     if (typeof fn !== 'function') {
-      throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn));
+      throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
     }
 
     // add the middleware
-    debug('use %s %s', path, fn.name || '<anonymous>');
+    debug('use %o %s', path, fn.name || '<anonymous>')
 
     var layer = new Layer(path, {
       sensitive: this.caseSensitive,
@@ -531,6 +531,23 @@ function getPathname(req) {
   }
 }
 
+// Get get protocol + host for a URL
+function getProtohost(url) {
+  if (typeof url !== 'string' || url.length === 0 || url[0] === '/') {
+    return undefined
+  }
+
+  var searchIndex = url.indexOf('?')
+  var pathLength = searchIndex !== -1
+    ? searchIndex
+    : url.length
+  var fqdnIndex = url.substr(0, pathLength).indexOf('://')
+
+  return fqdnIndex !== -1
+    ? url.substr(0, url.indexOf('/', 3 + fqdnIndex))
+    : undefined
+}
+
 // get type for error message
 function gettype(obj) {
   var type = typeof obj;
@@ -609,7 +626,7 @@ function restore(fn, obj) {
     vals[i] = obj[props[i]];
   }
 
-  return function(err){
+  return function () {
     // restore vals
     for (var i = 0; i < props.length; i++) {
       obj[props[i]] = vals[i];
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/layer.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/layer.js
index fe9210cb9..4dc8e86d4 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/layer.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/layer.js
@@ -35,7 +35,7 @@ function Layer(path, options, fn) {
     return new Layer(path, options, fn);
   }
 
-  debug('new %s', path);
+  debug('new %o', path)
   var opts = options || {};
 
   this.handle = fn;
@@ -44,9 +44,9 @@ function Layer(path, options, fn) {
   this.path = undefined;
   this.regexp = pathRegexp(path, this.keys = [], opts);
 
-  if (path === '/' && opts.end === false) {
-    this.regexp.fast_slash = true;
-  }
+  // set fast path flags
+  this.regexp.fast_star = path === '*'
+  this.regexp.fast_slash = path === '/' && opts.end === false
 }
 
 /**
@@ -108,23 +108,28 @@ Layer.prototype.handle_request = function handle(req, res, next) {
  */
 
 Layer.prototype.match = function match(path) {
-  if (path == null) {
-    // no path, nothing matches
-    this.params = undefined;
-    this.path = undefined;
-    return false;
-  }
+  var match
+
+  if (path != null) {
+    // fast path non-ending match for / (any path matches)
+    if (this.regexp.fast_slash) {
+      this.params = {}
+      this.path = ''
+      return true
+    }
 
-  if (this.regexp.fast_slash) {
-    // fast path non-ending match for / (everything matches)
-    this.params = {};
-    this.path = '';
-    return true;
-  }
+    // fast path for * (everything matched in a param)
+    if (this.regexp.fast_star) {
+      this.params = {'0': decode_param(path)}
+      this.path = path
+      return true
+    }
 
-  var m = this.regexp.exec(path);
+    // match the path
+    match = this.regexp.exec(path)
+  }
 
-  if (!m) {
+  if (!match) {
     this.params = undefined;
     this.path = undefined;
     return false;
@@ -132,15 +137,15 @@ Layer.prototype.match = function match(path) {
 
   // store values
   this.params = {};
-  this.path = m[0];
+  this.path = match[0]
 
   var keys = this.keys;
   var params = this.params;
 
-  for (var i = 1; i < m.length; i++) {
+  for (var i = 1; i < match.length; i++) {
     var key = keys[i - 1];
     var prop = key.name;
-    var val = decode_param(m[i]);
+    var val = decode_param(match[i])
 
     if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
       params[prop] = val;
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/route.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/route.js
index 2788d7b73..178df0d51 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/route.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/router/route.js
@@ -44,7 +44,7 @@ function Route(path) {
   this.path = path;
   this.stack = [];
 
-  debug('new %s', path);
+  debug('new %o', path)
 
   // route handlers for various http methods
   this.methods = {};
@@ -112,10 +112,16 @@ Route.prototype.dispatch = function dispatch(req, res, done) {
   next();
 
   function next(err) {
+    // signal to exit route
     if (err && err === 'route') {
       return done();
     }
 
+    // signal to exit router
+    if (err && err === 'router') {
+      return done(err)
+    }
+
     var layer = stack[idx++];
     if (!layer) {
       return done(err);
@@ -169,7 +175,7 @@ Route.prototype.all = function all() {
 
     if (typeof handle !== 'function') {
       var type = toString.call(handle);
-      var msg = 'Route.all() requires callback functions but got a ' + type;
+      var msg = 'Route.all() requires a callback function but got a ' + type
       throw new TypeError(msg);
     }
 
@@ -192,11 +198,11 @@ methods.forEach(function(method){
 
       if (typeof handle !== 'function') {
         var type = toString.call(handle);
-        var msg = 'Route.' + method + '() requires callback functions but got a ' + type;
+        var msg = 'Route.' + method + '() requires a callback function but got a ' + type
         throw new Error(msg);
       }
 
-      debug('%s %s', method, this.path);
+      debug('%s %o', method, this.path)
 
       var layer = Layer('/', {}, handle);
       layer.method = method;
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/utils.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/utils.js
index f418c5807..bd81ac7f6 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/utils.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/utils.js
@@ -12,12 +12,12 @@
  * @api private
  */
 
+var Buffer = require('safe-buffer').Buffer
 var contentDisposition = require('content-disposition');
 var contentType = require('content-type');
 var deprecate = require('depd')('express');
 var flatten = require('array-flatten');
 var mime = require('send').mime;
-var basename = require('path').basename;
 var etag = require('etag');
 var proxyaddr = require('proxy-addr');
 var qs = require('qs');
@@ -32,13 +32,7 @@ var querystring = require('querystring');
  * @api private
  */
 
-exports.etag = function (body, encoding) {
-  var buf = !Buffer.isBuffer(body)
-    ? new Buffer(body, encoding)
-    : body;
-
-  return etag(buf, {weak: false});
-};
+exports.etag = createETagGenerator({ weak: false })
 
 /**
  * Return weak ETag for `body`.
@@ -49,13 +43,7 @@ exports.etag = function (body, encoding) {
  * @api private
  */
 
-exports.wetag = function wetag(body, encoding){
-  var buf = !Buffer.isBuffer(body)
-    ? new Buffer(body, encoding)
-    : body;
-
-  return etag(buf, {weak: true});
-};
+exports.wetag = createETagGenerator({ weak: true })
 
 /**
  * Check if `path` looks absolute.
@@ -274,6 +262,25 @@ exports.setCharset = function setCharset(type, charset) {
   return contentType.format(parsed);
 };
 
+/**
+ * Create an ETag generator function, generating ETags with
+ * the given options.
+ *
+ * @param {object} options
+ * @return {function}
+ * @private
+ */
+
+function createETagGenerator (options) {
+  return function generateETag (body, encoding) {
+    var buf = !Buffer.isBuffer(body)
+      ? Buffer.from(body, encoding)
+      : body
+
+    return etag(buf, options)
+  }
+}
+
 /**
  * Parse an extended query string with qs.
  *
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/view.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/view.js
index 52415d4c2..cf101caea 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/view.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/lib/view.js
@@ -16,7 +16,6 @@
 var debug = require('debug')('express:view');
 var path = require('path');
 var fs = require('fs');
-var utils = require('./utils');
 
 /**
  * Module variables.
@@ -75,7 +74,17 @@ function View(name, options) {
 
   if (!opts.engines[this.ext]) {
     // load engine
-    opts.engines[this.ext] = require(this.ext.substr(1)).__express;
+    var mod = this.ext.substr(1)
+    debug('require "%s"', mod)
+
+    // default engine export
+    var fn = require(mod).__express
+
+    if (typeof fn !== 'function') {
+      throw new Error('Module "' + mod + '" does not provide a view engine.')
+    }
+
+    opts.engines[this.ext] = fn
   }
 
   // store loaded engine
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/package.json
index 1c523fe6e..d75b2c7bb 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/express/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "express@^4.13.3",
-        "scope": null,
-        "escapedName": "express",
-        "name": "express",
-        "rawSpec": "^4.13.3",
-        "spec": ">=4.13.3 <5.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve"
-    ]
-  ],
-  "_from": "express@>=4.13.3 <5.0.0",
-  "_id": "express@4.14.1",
-  "_inCache": true,
+  "_from": "express@^4.13.3",
+  "_id": "express@4.16.2",
+  "_inBundle": false,
+  "_integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
   "_location": "/express",
-  "_nodeVersion": "4.6.1",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/express-4.14.1.tgz_1485642795215_0.5481494057457894"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.9",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "express@^4.13.3",
-    "scope": null,
-    "escapedName": "express",
     "name": "express",
+    "escapedName": "express",
     "rawSpec": "^4.13.3",
-    "spec": ">=4.13.3 <5.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^4.13.3"
   },
   "_requiredBy": [
     "/cordova-serve"
   ],
-  "_resolved": "https://registry.npmjs.org/express/-/express-4.14.1.tgz",
-  "_shasum": "646c237f766f148c2120aff073817b9e4d7e0d33",
-  "_shrinkwrap": null,
+  "_resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+  "_shasum": "e35c6dfe2d64b7dca0a5cd4f21781be3299e076c",
   "_spec": "express@^4.13.3",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/cordova-serve",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/cordova-serve",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca"
@@ -52,6 +29,7 @@
   "bugs": {
     "url": "https://github.com/expressjs/express/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Aaron Heckmann",
@@ -83,58 +61,59 @@
     }
   ],
   "dependencies": {
-    "accepts": "~1.3.3",
+    "accepts": "~1.3.4",
     "array-flatten": "1.1.1",
+    "body-parser": "1.18.2",
     "content-disposition": "0.5.2",
-    "content-type": "~1.0.2",
+    "content-type": "~1.0.4",
     "cookie": "0.3.1",
     "cookie-signature": "1.0.6",
-    "debug": "~2.2.0",
-    "depd": "~1.1.0",
+    "debug": "2.6.9",
+    "depd": "~1.1.1",
     "encodeurl": "~1.0.1",
     "escape-html": "~1.0.3",
-    "etag": "~1.7.0",
-    "finalhandler": "0.5.1",
-    "fresh": "0.3.0",
+    "etag": "~1.8.1",
+    "finalhandler": "1.1.0",
+    "fresh": "0.5.2",
     "merge-descriptors": "1.0.1",
     "methods": "~1.1.2",
     "on-finished": "~2.3.0",
-    "parseurl": "~1.3.1",
+    "parseurl": "~1.3.2",
     "path-to-regexp": "0.1.7",
-    "proxy-addr": "~1.1.3",
-    "qs": "6.2.0",
+    "proxy-addr": "~2.0.2",
+    "qs": "6.5.1",
     "range-parser": "~1.2.0",
-    "send": "0.14.2",
-    "serve-static": "~1.11.2",
-    "type-is": "~1.6.14",
-    "utils-merge": "1.0.0",
-    "vary": "~1.1.0"
+    "safe-buffer": "5.1.1",
+    "send": "0.16.1",
+    "serve-static": "1.13.1",
+    "setprototypeof": "1.1.0",
+    "statuses": "~1.3.1",
+    "type-is": "~1.6.15",
+    "utils-merge": "1.0.1",
+    "vary": "~1.1.2"
   },
+  "deprecated": false,
   "description": "Fast, unopinionated, minimalist web framework",
   "devDependencies": {
     "after": "0.8.2",
-    "body-parser": "1.16.0",
     "connect-redis": "~2.4.1",
     "cookie-parser": "~1.4.3",
-    "cookie-session": "~1.2.0",
-    "ejs": "2.5.5",
-    "express-session": "1.15.0",
+    "cookie-session": "1.3.2",
+    "ejs": "2.5.7",
+    "eslint": "2.13.1",
+    "express-session": "1.15.6",
+    "hbs": "4.0.1",
     "istanbul": "0.4.5",
-    "jade": "~1.11.0",
     "marked": "0.3.6",
-    "method-override": "~2.3.6",
-    "mocha": "3.2.0",
-    "morgan": "~1.7.0",
+    "method-override": "2.3.10",
+    "mocha": "3.5.3",
+    "morgan": "1.9.0",
     "multiparty": "4.1.3",
-    "should": "11.2.0",
+    "pbkdf2-password": "1.2.1",
+    "should": "13.1.0",
     "supertest": "1.2.0",
     "vhost": "~3.0.2"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "646c237f766f148c2120aff073817b9e4d7e0d33",
-    "tarball": "https://registry.npmjs.org/express/-/express-4.14.1.tgz"
-  },
   "engines": {
     "node": ">= 0.10.0"
   },
@@ -145,7 +124,6 @@
     "index.js",
     "lib/"
   ],
-  "gitHead": "0437c513f2dbc8d1dfc5a3e35fe35182bd3a671e",
   "homepage": "http://expressjs.com/",
   "keywords": [
     "express",
@@ -159,36 +137,17 @@
     "api"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "hacksparrow",
-      "email": "captain@hacksparrow.com"
-    },
-    {
-      "name": "jasnell",
-      "email": "jasnell@gmail.com"
-    },
-    {
-      "name": "mikeal",
-      "email": "mikeal.rogers@gmail.com"
-    }
-  ],
   "name": "express",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/expressjs/express.git"
   },
   "scripts": {
-    "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
-    "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
-    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
-    "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
+    "lint": "eslint .",
+    "test": "mocha --require test/support/env --reporter spec --bail --check-leaks --no-exit test/ test/acceptance/",
+    "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks --no-exit test/ test/acceptance/",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks --no-exit test/ test/acceptance/",
+    "test-tap": "mocha --require test/support/env --reporter tap --check-leaks --no-exit test/ test/acceptance/"
   },
-  "version": "4.14.1"
+  "version": "4.16.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/HISTORY.md
index 5070d224f..4f7244d78 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/HISTORY.md
@@ -1,3 +1,59 @@
+1.1.0 / 2017-09-24
+==================
+
+  * Use `res.headersSent` when available
+
+1.0.6 / 2017-09-22
+==================
+
+  * deps: debug@2.6.9
+
+1.0.5 / 2017-09-15
+==================
+
+  * deps: parseurl@~1.3.2
+    - perf: reduce overhead for full URLs
+    - perf: unroll the "fast-path" `RegExp`
+
+1.0.4 / 2017-08-03
+==================
+
+  * deps: debug@2.6.8
+
+1.0.3 / 2017-05-16
+==================
+
+  * deps: debug@2.6.7
+    - deps: ms@2.0.0
+
+1.0.2 / 2017-04-22
+==================
+
+  * deps: debug@2.6.4
+    - deps: ms@0.7.3
+
+1.0.1 / 2017-03-21
+==================
+
+  * Fix missing `</html>` in HTML document
+  * deps: debug@2.6.3
+    - Fix: `DEBUG_MAX_ARRAY_LENGTH`
+
+1.0.0 / 2017-02-15
+==================
+
+  * Fix exception when `err` cannot be converted to a string
+  * Fully URL-encode the pathname in the 404 message
+  * Only include the pathname in the 404 message
+  * Send complete HTML document
+  * Set `Content-Security-Policy: default-src 'self'` header
+  * deps: debug@2.6.1
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable set to `3` or higher
+    - Fix error when running under React Native
+    - Use same color for same namespace
+    - deps: ms@0.7.2
+
 0.5.1 / 2016-11-12
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/LICENSE
index 0fa162e97..fb3098277 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/LICENSE
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2014-2016 Douglas Christopher Wilson <doug@somethingdoug.com>
+Copyright (c) 2014-2017 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
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/README.md
index 84c3d2af1..6756f0cd2 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/README.md
@@ -20,7 +20,9 @@ $ npm install finalhandler
 
 ## API
 
-```
+<!-- eslint-disable no-unused-vars -->
+
+```js
 var finalhandler = require('finalhandler')
 ```
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/index.js
index e0719c598..42f0f7499 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/index.js
@@ -1,6 +1,6 @@
 /*!
  * finalhandler
- * Copyright(c) 2014-2016 Douglas Christopher Wilson
+ * Copyright(c) 2014-2017 Douglas Christopher Wilson
  * MIT Licensed
  */
 
@@ -12,8 +12,10 @@
  */
 
 var debug = require('debug')('finalhandler')
+var encodeUrl = require('encodeurl')
 var escapeHtml = require('escape-html')
 var onFinished = require('on-finished')
+var parseUrl = require('parseurl')
 var statuses = require('statuses')
 var unpipe = require('unpipe')
 
@@ -31,6 +33,30 @@ var defer = typeof setImmediate === 'function'
   : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)) }
 var isFinished = onFinished.isFinished
 
+/**
+ * Create a minimal HTML document.
+ *
+ * @param {string} message
+ * @private
+ */
+
+function createHtmlDocument (message) {
+  var body = escapeHtml(message)
+    .replace(NEWLINE_REGEXP, '<br>')
+    .replace(DOUBLE_SPACE_REGEXP, ' &nbsp;')
+
+  return '<!DOCTYPE html>\n' +
+    '<html lang="en">\n' +
+    '<head>\n' +
+    '<meta charset="utf-8">\n' +
+    '<title>Error</title>\n' +
+    '</head>\n' +
+    '<body>\n' +
+    '<pre>' + body + '</pre>\n' +
+    '</body>\n' +
+    '</html>\n'
+}
+
 /**
  * Module exports.
  * @public
@@ -59,10 +85,11 @@ function finalhandler (req, res, options) {
 
   return function (err) {
     var headers
+    var msg
     var status
 
     // ignore 404 on in-flight response
-    if (!err && res._header) {
+    if (!err && headersSent(res)) {
       debug('cannot 404 after headers sent')
       return
     }
@@ -82,16 +109,12 @@ function finalhandler (req, res, options) {
         status = getResponseStatusCode(res)
       }
 
-      // production gets a basic error message
-      var msg = env === 'production'
-        ? statuses[status]
-        : err.stack || err.toString()
-      msg = escapeHtml(msg)
-        .replace(NEWLINE_REGEXP, '<br>')
-        .replace(DOUBLE_SPACE_REGEXP, ' &nbsp;') + '\n'
+      // get error message
+      msg = getErrorMessage(err, status, env)
     } else {
+      // not found
       status = 404
-      msg = 'Cannot ' + escapeHtml(req.method) + ' ' + escapeHtml(req.originalUrl || req.url) + '\n'
+      msg = 'Cannot ' + req.method + ' ' + encodeUrl(parseUrl.original(req).pathname)
     }
 
     debug('default %s', status)
@@ -102,7 +125,7 @@ function finalhandler (req, res, options) {
     }
 
     // cannot actually respond
-    if (res._header) {
+    if (headersSent(res)) {
       debug('cannot %d after headers sent', status)
       req.socket.destroy()
       return
@@ -137,6 +160,32 @@ function getErrorHeaders (err) {
   return headers
 }
 
+/**
+ * Get message from Error object, fallback to status message.
+ *
+ * @param {Error} err
+ * @param {number} status
+ * @param {string} env
+ * @return {string}
+ * @private
+ */
+
+function getErrorMessage (err, status, env) {
+  var msg
+
+  if (env !== 'production') {
+    // use err.stack, which typically includes err.message
+    msg = err.stack
+
+    // fallback to err.toString() when possible
+    if (!msg && typeof err.toString === 'function') {
+      msg = err.toString()
+    }
+  }
+
+  return msg || statuses[status]
+}
+
 /**
  * Get status code from Error object.
  *
@@ -178,6 +227,20 @@ function getResponseStatusCode (res) {
   return status
 }
 
+/**
+ * Determine if the response headers have been sent.
+ *
+ * @param {object} res
+ * @returns {boolean}
+ * @private
+ */
+
+function headersSent (res) {
+  return typeof res.headersSent !== 'boolean'
+    ? Boolean(res._header)
+    : res.headersSent
+}
+
 /**
  * Send response.
  *
@@ -185,12 +248,15 @@ function getResponseStatusCode (res) {
  * @param {OutgoingMessage} res
  * @param {number} status
  * @param {object} headers
- * @param {string} body
+ * @param {string} message
  * @private
  */
 
-function send (req, res, status, headers, body) {
+function send (req, res, status, headers, message) {
   function write () {
+    // response body
+    var body = createHtmlDocument(message)
+
     // response status
     res.statusCode = status
     res.statusMessage = statuses[status]
@@ -198,7 +264,8 @@ function send (req, res, status, headers, body) {
     // response headers
     setHeaders(res, headers)
 
-    // security header for content sniffing
+    // security headers
+    res.setHeader('Content-Security-Policy', "default-src 'self'")
     res.setHeader('X-Content-Type-Options', 'nosniff')
 
     // standard headers
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/package.json
index 63cca7325..0d1fbde44 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/finalhandler/package.json
@@ -1,49 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "finalhandler@0.5.1",
-        "scope": null,
-        "escapedName": "finalhandler",
-        "name": "finalhandler",
-        "rawSpec": "0.5.1",
-        "spec": "0.5.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "finalhandler@0.5.1",
-  "_id": "finalhandler@0.5.1",
-  "_inCache": true,
+  "_from": "finalhandler@1.1.0",
+  "_id": "finalhandler@1.1.0",
+  "_inBundle": false,
+  "_integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
   "_location": "/finalhandler",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/finalhandler-0.5.1.tgz_1479018213560_0.8304649770725518"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "finalhandler@0.5.1",
-    "scope": null,
-    "escapedName": "finalhandler",
+    "type": "version",
+    "registry": true,
+    "raw": "finalhandler@1.1.0",
     "name": "finalhandler",
-    "rawSpec": "0.5.1",
-    "spec": "0.5.1",
-    "type": "version"
+    "escapedName": "finalhandler",
+    "rawSpec": "1.1.0",
+    "saveSpec": null,
+    "fetchSpec": "1.1.0"
   },
   "_requiredBy": [
     "/express"
   ],
-  "_resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz",
-  "_shasum": "2c400d8d4530935bc232549c5fa385ec07de6fcd",
-  "_shrinkwrap": null,
-  "_spec": "finalhandler@0.5.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+  "_shasum": "ce0b6855b45853e791b2fcc680046d88253dd7f5",
+  "_spec": "finalhandler@1.1.0",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -51,30 +29,32 @@
   "bugs": {
     "url": "https://github.com/pillarjs/finalhandler/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
-    "debug": "~2.2.0",
+    "debug": "2.6.9",
+    "encodeurl": "~1.0.1",
     "escape-html": "~1.0.3",
     "on-finished": "~2.3.0",
+    "parseurl": "~1.3.2",
     "statuses": "~1.3.1",
     "unpipe": "~1.0.0"
   },
+  "deprecated": false,
   "description": "Node.js final http responder",
   "devDependencies": {
-    "eslint": "3.10.0",
-    "eslint-config-standard": "6.2.1",
-    "eslint-plugin-markdown": "1.0.0-beta.3",
-    "eslint-plugin-promise": "3.3.2",
-    "eslint-plugin-standard": "2.0.1",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
     "istanbul": "0.4.5",
     "mocha": "2.5.3",
-    "readable-stream": "2.1.2",
+    "readable-stream": "2.3.3",
+    "safe-buffer": "5.1.1",
     "supertest": "1.1.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "2c400d8d4530935bc232549c5fa385ec07de6fcd",
-    "tarball": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz"
-  },
   "engines": {
     "node": ">= 0.8"
   },
@@ -83,18 +63,9 @@
     "HISTORY.md",
     "index.js"
   ],
-  "gitHead": "ae6137a81049eecb2d57341b1a9c4efed46a25da",
-  "homepage": "https://github.com/pillarjs/finalhandler",
+  "homepage": "https://github.com/pillarjs/finalhandler#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "finalhandler",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/pillarjs/finalhandler.git"
@@ -105,5 +76,5 @@
     "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
   },
-  "version": "0.5.1"
+  "version": "1.1.0"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/HISTORY.md
index 97fa1d102..2599a5573 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/HISTORY.md
@@ -1,3 +1,15 @@
+0.1.2 / 2017-09-14
+==================
+
+  * perf: improve header parsing
+  * perf: reduce overhead when no `X-Forwarded-For` header
+
+0.1.1 / 2017-09-10
+==================
+
+  * Fix trimming leading / trailing OWS
+  * perf: hoist regular expression
+
 0.1.0 / 2014-09-21
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/LICENSE
index b7dce6cf9..84441fbb5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/LICENSE
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2014 Douglas Christopher Wilson
+Copyright (c) 2014-2017 Douglas Christopher Wilson
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/README.md
index 2b4988fa2..c776ee54e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/README.md
@@ -10,6 +10,10 @@ Parse HTTP X-Forwarded-For header
 
 ## Installation
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```sh
 $ npm install forwarded
 ```
@@ -27,7 +31,7 @@ var addresses = forwarded(req)
 ```
 
 Parse the `X-Forwarded-For` header from the request. Returns an array
-of the addresses, including the socket address for the `req`. In reverse
+of the addresses, including the socket address for the `req`, in reverse
 order (i.e. index `0` is the socket address and the last index is the
 furthest address, typically the end-user).
 
@@ -41,13 +45,13 @@ $ npm test
 
 [MIT](LICENSE)
 
-[npm-image]: https://img.shields.io/npm/v/forwarded.svg?style=flat
+[npm-image]: https://img.shields.io/npm/v/forwarded.svg
 [npm-url]: https://npmjs.org/package/forwarded
-[node-version-image]: https://img.shields.io/node/v/forwarded.svg?style=flat
-[node-version-url]: http://nodejs.org/download/
-[travis-image]: https://img.shields.io/travis/jshttp/forwarded.svg?style=flat
+[node-version-image]: https://img.shields.io/node/v/forwarded.svg
+[node-version-url]: https://nodejs.org/en/download/
+[travis-image]: https://img.shields.io/travis/jshttp/forwarded/master.svg
 [travis-url]: https://travis-ci.org/jshttp/forwarded
-[coveralls-image]: https://img.shields.io/coveralls/jshttp/forwarded.svg?style=flat
+[coveralls-image]: https://img.shields.io/coveralls/jshttp/forwarded/master.svg
 [coveralls-url]: https://coveralls.io/r/jshttp/forwarded?branch=master
-[downloads-image]: https://img.shields.io/npm/dm/forwarded.svg?style=flat
+[downloads-image]: https://img.shields.io/npm/dm/forwarded.svg
 [downloads-url]: https://npmjs.org/package/forwarded
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/index.js
index 2f5c34088..7833b3de5 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/index.js
@@ -1,11 +1,14 @@
 /*!
  * forwarded
- * Copyright(c) 2014 Douglas Christopher Wilson
+ * Copyright(c) 2014-2017 Douglas Christopher Wilson
  * MIT Licensed
  */
 
+'use strict'
+
 /**
  * Module exports.
+ * @public
  */
 
 module.exports = forwarded
@@ -13,23 +16,61 @@ module.exports = forwarded
 /**
  * Get all addresses in the request, using the `X-Forwarded-For` header.
  *
- * @param {Object} req
- * @api public
+ * @param {object} req
+ * @return {array}
+ * @public
  */
 
-function forwarded(req) {
+function forwarded (req) {
   if (!req) {
     throw new TypeError('argument req is required')
   }
 
   // simple header parsing
-  var proxyAddrs = (req.headers['x-forwarded-for'] || '')
-    .split(/ *, */)
-    .filter(Boolean)
-    .reverse()
+  var proxyAddrs = parse(req.headers['x-forwarded-for'] || '')
   var socketAddr = req.connection.remoteAddress
   var addrs = [socketAddr].concat(proxyAddrs)
 
   // return all addresses
   return addrs
 }
+
+/**
+ * Parse the X-Forwarded-For header.
+ *
+ * @param {string} header
+ * @private
+ */
+
+function parse (header) {
+  var end = header.length
+  var list = []
+  var start = header.length
+
+  // gather addresses, backwards
+  for (var i = header.length - 1; i >= 0; i--) {
+    switch (header.charCodeAt(i)) {
+      case 0x20: /*   */
+        if (start === end) {
+          start = end = i
+        }
+        break
+      case 0x2c: /* , */
+        if (start !== end) {
+          list.push(header.substring(start, end))
+        }
+        start = end = i
+        break
+      default:
+        start = i
+        break
+    }
+  }
+
+  // final address
+  if (start !== end) {
+    list.push(header.substring(start, end))
+  }
+
+  return list
+}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/package.json
index d1b69b5d6..f68d7996f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/forwarded/package.json
@@ -1,64 +1,50 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "forwarded@~0.1.0",
-        "scope": null,
-        "escapedName": "forwarded",
-        "name": "forwarded",
-        "rawSpec": "~0.1.0",
-        "spec": ">=0.1.0 <0.2.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr"
-    ]
-  ],
-  "_from": "forwarded@>=0.1.0 <0.2.0",
-  "_id": "forwarded@0.1.0",
-  "_inCache": true,
+  "_from": "forwarded@~0.1.2",
+  "_id": "forwarded@0.1.2",
+  "_inBundle": false,
+  "_integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
   "_location": "/forwarded",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.21",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "forwarded@~0.1.0",
-    "scope": null,
-    "escapedName": "forwarded",
+    "type": "range",
+    "registry": true,
+    "raw": "forwarded@~0.1.2",
     "name": "forwarded",
-    "rawSpec": "~0.1.0",
-    "spec": ">=0.1.0 <0.2.0",
-    "type": "range"
+    "escapedName": "forwarded",
+    "rawSpec": "~0.1.2",
+    "saveSpec": null,
+    "fetchSpec": "~0.1.2"
   },
   "_requiredBy": [
     "/proxy-addr"
   ],
-  "_resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
-  "_shasum": "19ef9874c4ae1c297bcf078fde63a09b66a84363",
-  "_shrinkwrap": null,
-  "_spec": "forwarded@~0.1.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr",
+  "_resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+  "_shasum": "98c23dab1175657b8c0573e8ceccd91b0ff18c84",
+  "_spec": "forwarded@~0.1.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/proxy-addr",
   "bugs": {
     "url": "https://github.com/jshttp/forwarded/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Parse HTTP X-Forwarded-For header",
   "devDependencies": {
-    "istanbul": "0.3.2",
-    "mocha": "~1.21.4"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "19ef9874c4ae1c297bcf078fde63a09b66a84363",
-    "tarball": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz"
+    "beautify-benchmark": "0.2.4",
+    "benchmark": "2.1.4",
+    "eslint": "3.19.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",
+    "istanbul": "0.4.5",
+    "mocha": "1.21.5"
   },
   "engines": {
     "node": ">= 0.6"
@@ -69,31 +55,24 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "e9a9faeb3cfaadf40eb57d144fff26bca9b818e8",
-  "homepage": "https://github.com/jshttp/forwarded",
+  "homepage": "https://github.com/jshttp/forwarded#readme",
   "keywords": [
     "x-forwarded-for",
     "http",
     "req"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "forwarded",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/forwarded.git"
   },
   "scripts": {
+    "bench": "node benchmark/index.js",
+    "lint": "eslint .",
     "test": "mocha --reporter spec --bail --check-leaks 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": "0.1.0"
+  "version": "0.1.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/HISTORY.md
index 3c95fbb94..4586996a3 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/HISTORY.md
@@ -1,3 +1,34 @@
+0.5.2 / 2017-09-13
+==================
+
+  * Fix regression matching multiple ETags in `If-None-Match`
+  * perf: improve `If-None-Match` token parsing
+
+0.5.1 / 2017-09-11
+==================
+
+  * Fix handling of modified headers with invalid dates
+  * perf: improve ETag match loop
+
+0.5.0 / 2017-02-21
+==================
+
+  * Fix incorrect result when `If-None-Match` has both `*` and ETags
+  * Fix weak `ETag` matching to match spec
+  * perf: delay reading header values until needed
+  * perf: skip checking modified time if ETag check failed
+  * perf: skip parsing `If-None-Match` when no `ETag` header
+  * perf: use `Date.parse` instead of `new Date`
+
+0.4.0 / 2017-02-05
+==================
+
+  * Fix false detection of `no-cache` request directive
+  * perf: enable strict mode
+  * perf: hoist regular expressions
+  * perf: remove duplicate conditional
+  * perf: remove unnecessary boolean coercions
+
 0.3.0 / 2015-05-12
 ==================
 
@@ -30,6 +61,7 @@
 
 0.1.0 / 2012-06-15
 ==================
+
   * Add `If-None-Match: *` support
 
 0.0.1 / 2012-06-10
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/LICENSE
index f5273943a..1434ade75 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/LICENSE
@@ -1,6 +1,7 @@
 (The MIT License)
 
 Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
+Copyright (c) 2016-2017 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
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/README.md
index 0813e3092..1c1c680d1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/README.md
@@ -10,38 +10,99 @@ HTTP response freshness testing
 
 ## Installation
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```
 $ npm install fresh
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var fresh = require('fresh')
 ```
 
-### fresh(req, res)
+### fresh(reqHeaders, resHeaders)
+
+Check freshness of the response using request and response headers.
+
+When the response is still "fresh" in the client's cache `true` is
+returned, otherwise `false` is returned to indicate that the client
+cache is now stale and the full response should be sent.
+
+When a client sends the `Cache-Control: no-cache` request header to
+indicate an end-to-end reload request, this module will return `false`
+to make handling these requests transparent.
 
- Check freshness of `req` and `res` headers.
+## Known Issues
 
- When the cache is "fresh" __true__ is returned,
- otherwise __false__ is returned to indicate that
- the cache is now stale.
+This module is designed to only follow the HTTP specifications, not
+to work-around all kinda of client bugs (especially since this module
+typically does not recieve enough information to understand what the
+client actually is).
+
+There is a known issue that in certain versions of Safari, Safari
+will incorrectly make a request that allows this module to validate
+freshness of the resource even when Safari does not have a
+representation of the resource in the cache. The module
+[jumanji](https://www.npmjs.com/package/jumanji) can be used in
+an Express application to work-around this issue and also provides
+links to further reading on this Safari bug.
 
 ## Example
 
+### API usage
+
+<!-- eslint-disable no-redeclare, no-undef -->
+
 ```js
-var req = { 'if-none-match': 'tobi' };
-var res = { 'etag': 'luna' };
-fresh(req, res);
+var reqHeaders = { 'if-none-match': '"foo"' }
+var resHeaders = { 'etag': '"bar"' }
+fresh(reqHeaders, resHeaders)
 // => false
 
-var req = { 'if-none-match': 'tobi' };
-var res = { 'etag': 'tobi' };
-fresh(req, res);
+var reqHeaders = { 'if-none-match': '"foo"' }
+var resHeaders = { 'etag': '"foo"' }
+fresh(reqHeaders, resHeaders)
 // => true
 ```
 
+### Using with Node.js http server
+
+```js
+var fresh = require('fresh')
+var http = require('http')
+
+var server = http.createServer(function (req, res) {
+  // perform server logic
+  // ... including adding ETag / Last-Modified response headers
+
+  if (isFresh(req, res)) {
+    // client has a fresh copy of resource
+    res.statusCode = 304
+    res.end()
+    return
+  }
+
+  // send the resource
+  res.statusCode = 200
+  res.end('hello, world!')
+})
+
+function isFresh (req, res) {
+  return fresh(req.headers, {
+    'etag': res.getHeader('ETag'),
+    'last-modified': res.getHeader('Last-Modified')
+  })
+}
+
+server.listen(3000)
+```
+
 ## License
 
 [MIT](LICENSE)
@@ -49,7 +110,7 @@ fresh(req, res);
 [npm-image]: https://img.shields.io/npm/v/fresh.svg
 [npm-url]: https://npmjs.org/package/fresh
 [node-version-image]: https://img.shields.io/node/v/fresh.svg
-[node-version-url]: http://nodejs.org/download/
+[node-version-url]: https://nodejs.org/en/
 [travis-image]: https://img.shields.io/travis/jshttp/fresh/master.svg
 [travis-url]: https://travis-ci.org/jshttp/fresh
 [coveralls-image]: https://img.shields.io/coveralls/jshttp/fresh/master.svg
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/index.js
index a90087363..d154f5a7d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/index.js
@@ -1,57 +1,137 @@
+/*!
+ * fresh
+ * Copyright(c) 2012 TJ Holowaychuk
+ * Copyright(c) 2016-2017 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
 
 /**
- * Expose `fresh()`.
+ * RegExp to check for no-cache token in Cache-Control.
+ * @private
  */
 
-module.exports = fresh;
+var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/
 
 /**
- * Check freshness of `req` and `res` headers.
- *
- * When the cache is "fresh" __true__ is returned,
- * otherwise __false__ is returned to indicate that
- * the cache is now stale.
+ * Module exports.
+ * @public
+ */
+
+module.exports = fresh
+
+/**
+ * Check freshness of the response using request and response headers.
  *
- * @param {Object} req
- * @param {Object} res
+ * @param {Object} reqHeaders
+ * @param {Object} resHeaders
  * @return {Boolean}
- * @api public
+ * @public
  */
 
-function fresh(req, res) {
-  // defaults
-  var etagMatches = true;
-  var notModified = true;
-
+function fresh (reqHeaders, resHeaders) {
   // fields
-  var modifiedSince = req['if-modified-since'];
-  var noneMatch = req['if-none-match'];
-  var lastModified = res['last-modified'];
-  var etag = res['etag'];
-  var cc = req['cache-control'];
+  var modifiedSince = reqHeaders['if-modified-since']
+  var noneMatch = reqHeaders['if-none-match']
 
   // unconditional request
-  if (!modifiedSince && !noneMatch) return false;
-
-  // check for no-cache cache request directive
-  if (cc && cc.indexOf('no-cache') !== -1) return false;  
+  if (!modifiedSince && !noneMatch) {
+    return false
+  }
 
-  // parse if-none-match
-  if (noneMatch) noneMatch = noneMatch.split(/ *, */);
+  // Always return stale when Cache-Control: no-cache
+  // to support end-to-end reload requests
+  // https://tools.ietf.org/html/rfc2616#section-14.9.4
+  var cacheControl = reqHeaders['cache-control']
+  if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
+    return false
+  }
 
   // if-none-match
-  if (noneMatch) {
-    etagMatches = noneMatch.some(function (match) {
-      return match === '*' || match === etag || match === 'W/' + etag;
-    });
+  if (noneMatch && noneMatch !== '*') {
+    var etag = resHeaders['etag']
+
+    if (!etag) {
+      return false
+    }
+
+    var etagStale = true
+    var matches = parseTokenList(noneMatch)
+    for (var i = 0; i < matches.length; i++) {
+      var match = matches[i]
+      if (match === etag || match === 'W/' + etag || 'W/' + match === etag) {
+        etagStale = false
+        break
+      }
+    }
+
+    if (etagStale) {
+      return false
+    }
   }
 
   // if-modified-since
   if (modifiedSince) {
-    modifiedSince = new Date(modifiedSince);
-    lastModified = new Date(lastModified);
-    notModified = lastModified <= modifiedSince;
+    var lastModified = resHeaders['last-modified']
+    var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))
+
+    if (modifiedStale) {
+      return false
+    }
+  }
+
+  return true
+}
+
+/**
+ * Parse an HTTP Date into a number.
+ *
+ * @param {string} date
+ * @private
+ */
+
+function parseHttpDate (date) {
+  var timestamp = date && Date.parse(date)
+
+  // istanbul ignore next: guard against date.js Date.parse patching
+  return typeof timestamp === 'number'
+    ? timestamp
+    : NaN
+}
+
+/**
+ * Parse a HTTP token list.
+ *
+ * @param {string} str
+ * @private
+ */
+
+function parseTokenList (str) {
+  var end = 0
+  var list = []
+  var start = 0
+
+  // gather tokens
+  for (var i = 0, len = str.length; i < len; i++) {
+    switch (str.charCodeAt(i)) {
+      case 0x20: /*   */
+        if (start === end) {
+          start = end = i + 1
+        }
+        break
+      case 0x2c: /* , */
+        list.push(str.substring(start, end))
+        start = end = i + 1
+        break
+      default:
+        end = i + 1
+        break
+    }
   }
 
-  return !! (etagMatches && notModified);
+  // final token
+  list.push(str.substring(start, end))
+
+  return list
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/package.json
index 52e5a5eef..429b19f30 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/fresh/package.json
@@ -1,46 +1,28 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "fresh@0.3.0",
-        "scope": null,
-        "escapedName": "fresh",
-        "name": "fresh",
-        "rawSpec": "0.3.0",
-        "spec": "0.3.0",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "fresh@0.3.0",
-  "_id": "fresh@0.3.0",
-  "_inCache": true,
+  "_from": "fresh@0.5.2",
+  "_id": "fresh@0.5.2",
+  "_inBundle": false,
+  "_integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
   "_location": "/fresh",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "fresh@0.3.0",
-    "scope": null,
-    "escapedName": "fresh",
+    "type": "version",
+    "registry": true,
+    "raw": "fresh@0.5.2",
     "name": "fresh",
-    "rawSpec": "0.3.0",
-    "spec": "0.3.0",
-    "type": "version"
+    "escapedName": "fresh",
+    "rawSpec": "0.5.2",
+    "saveSpec": null,
+    "fetchSpec": "0.5.2"
   },
   "_requiredBy": [
     "/express",
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz",
-  "_shasum": "651f838e22424e7566de161d8358caa199f83d4f",
-  "_shrinkwrap": null,
-  "_spec": "fresh@0.3.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+  "_shasum": "3d8cadd90d976569fa835ab1f8e4b23a105605a7",
+  "_spec": "fresh@0.5.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca",
@@ -49,6 +31,7 @@
   "bugs": {
     "url": "https://github.com/jshttp/fresh/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -60,17 +43,21 @@
       "url": "http://jongleberry.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "HTTP response freshness testing",
   "devDependencies": {
-    "istanbul": "0.3.9",
+    "beautify-benchmark": "0.2.4",
+    "benchmark": "2.1.4",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "istanbul": "0.4.5",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "651f838e22424e7566de161d8358caa199f83d4f",
-    "tarball": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -79,8 +66,7 @@
     "LICENSE",
     "index.js"
   ],
-  "gitHead": "14616c9748368ca08cd6a955dd88ab659b778634",
-  "homepage": "https://github.com/jshttp/fresh",
+  "homepage": "https://github.com/jshttp/fresh#readme",
   "keywords": [
     "fresh",
     "http",
@@ -88,35 +74,17 @@
     "cache"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "jonathanong",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "fresh",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/fresh.git"
   },
   "scripts": {
+    "bench": "node benchmark/index.js",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail --check-leaks 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": "0.3.0"
+  "version": "0.5.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi/package.json
index e3817f742..e52f04f09 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/has-ansi/package.json
@@ -1,46 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "has-ansi@^2.0.0",
-        "scope": null,
-        "escapedName": "has-ansi",
-        "name": "has-ansi",
-        "rawSpec": "^2.0.0",
-        "spec": ">=2.0.0 <3.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk"
-    ]
-  ],
-  "_from": "has-ansi@>=2.0.0 <3.0.0",
+  "_from": "has-ansi@^2.0.0",
   "_id": "has-ansi@2.0.0",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
   "_location": "/has-ansi",
-  "_nodeVersion": "0.12.5",
-  "_npmUser": {
-    "name": "sindresorhus",
-    "email": "sindresorhus@gmail.com"
-  },
-  "_npmVersion": "2.11.2",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "has-ansi@^2.0.0",
-    "scope": null,
-    "escapedName": "has-ansi",
     "name": "has-ansi",
+    "escapedName": "has-ansi",
     "rawSpec": "^2.0.0",
-    "spec": ">=2.0.0 <3.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^2.0.0"
   },
   "_requiredBy": [
     "/chalk"
   ],
   "_resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
   "_shasum": "34f5049ce1ecdf2b0649af3ef24e45ed35416d91",
-  "_shrinkwrap": null,
   "_spec": "has-ansi@^2.0.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/chalk",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/chalk",
   "author": {
     "name": "Sindre Sorhus",
     "email": "sindresorhus@gmail.com",
@@ -49,26 +30,22 @@
   "bugs": {
     "url": "https://github.com/sindresorhus/has-ansi/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
     "ansi-regex": "^2.0.0"
   },
+  "deprecated": false,
   "description": "Check if a string has ANSI escape codes",
   "devDependencies": {
     "ava": "0.0.4"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "34f5049ce1ecdf2b0649af3ef24e45ed35416d91",
-    "tarball": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz"
-  },
   "engines": {
     "node": ">=0.10.0"
   },
   "files": [
     "index.js"
   ],
-  "gitHead": "0722275e1bef139fcd09137da6e5550c3cd368b9",
-  "homepage": "https://github.com/sindresorhus/has-ansi",
+  "homepage": "https://github.com/sindresorhus/has-ansi#readme",
   "keywords": [
     "ansi",
     "styles",
@@ -96,17 +73,17 @@
   "license": "MIT",
   "maintainers": [
     {
-      "name": "sindresorhus",
-      "email": "sindresorhus@gmail.com"
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
     },
     {
-      "name": "jbnicolai",
-      "email": "jappelman@xebia.com"
+      "name": "Joshua Appelman",
+      "email": "jappelman@xebia.com",
+      "url": "jbnicolai.com"
     }
   ],
   "name": "has-ansi",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/sindresorhus/has-ansi.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/HISTORY.md
index a7f080fc1..b6ee4a0ae 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/HISTORY.md
@@ -1,3 +1,24 @@
+2017-08-04 / 1.6.2
+==================
+
+  * deps: depd@1.1.1
+    - Remove unnecessary `Buffer` loading
+
+2017-02-20 / 1.6.1
+==================
+
+  * deps: setprototypeof@1.0.3
+    - Fix shim for old browsers
+
+2017-02-14 / 1.6.0
+==================
+
+  * Accept custom 4xx and 5xx status codes in factory
+  * Add deprecation message to `"I'mateapot"` export
+  * Deprecate passing status code as anything except first argument in factory
+  * Deprecate using non-error status codes
+  * Make `message` property enumerable for `HttpError`s
+
 2016-11-16 / 1.5.1
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/README.md
index 414397766..79663d82f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/README.md
@@ -44,8 +44,11 @@ All errors inherit from JavaScript `Error` and the exported `createError.HttpErr
 - `headers` - can be an object of header names to values to be sent to the
   client, defaulting to `undefined`. When defined, the key names should all
   be lower-cased
-- `message`
-- `status` and `statusCode` - the status code of the error, defaulting to `500`
+- `message` - the traditional error message, which should be kept short and all
+  single line
+- `status` - the status code of the error, mirroring `statusCode` for general
+  compatibility
+- `statusCode` - the status code of the error, defaulting to `500`
 
 ### createError([status], [message], [properties])
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/index.js
index 6130db8ab..9509303ed 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/index.js
@@ -12,6 +12,7 @@
  * @private
  */
 
+var deprecate = require('depd')('http-errors')
 var setPrototypeOf = require('setprototypeof')
 var statuses = require('statuses')
 var inherits = require('inherits')
@@ -27,6 +28,15 @@ module.exports.HttpError = createHttpErrorConstructor()
 // Populate exports for all constructors
 populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
 
+/**
+ * Get the code class of a status code.
+ * @private
+ */
+
+function codeClass (status) {
+  return Number(String(status).charAt(0) + '00')
+}
+
 /**
  * Create a new HTTP Error.
  *
@@ -53,6 +63,9 @@ function createError () {
         break
       case 'number':
         status = arg
+        if (i !== 0) {
+          deprecate('non-first-argument status code; replace with createError(' + arg + ', ...)')
+        }
         break
       case 'object':
         props = arg
@@ -60,12 +73,17 @@ function createError () {
     }
   }
 
-  if (typeof status !== 'number' || !statuses[status]) {
+  if (typeof status === 'number' && (status < 400 || status >= 600)) {
+    deprecate('non-error status code; use only 4xx or 5xx status codes')
+  }
+
+  if (typeof status !== 'number' ||
+    (!statuses[status] && (status < 400 || status >= 600))) {
     status = 500
   }
 
   // constructor
-  var HttpError = createError[status]
+  var HttpError = createError[status] || createError[codeClass(status)]
 
   if (!err) {
     // create error
@@ -75,7 +93,7 @@ function createError () {
     Error.captureStackTrace(err, createError)
   }
 
-  if (!HttpError || !(err instanceof HttpError)) {
+  if (!HttpError || !(err instanceof HttpError) || err.status !== status) {
     // add properties to generic error
     err.expose = status < 500
     err.status = err.statusCode = status
@@ -115,7 +133,8 @@ function createClientErrorConstructor (HttpError, name, code) {
 
   function ClientError (message) {
     // create the error object
-    var err = new Error(message != null ? message : statuses[code])
+    var msg = message != null ? message : statuses[code]
+    var err = new Error(msg)
 
     // capture a stack trace to the construction point
     Error.captureStackTrace(err, ClientError)
@@ -123,6 +142,14 @@ function createClientErrorConstructor (HttpError, name, code) {
     // adjust the [[Prototype]]
     setPrototypeOf(err, ClientError.prototype)
 
+    // redefine the error message
+    Object.defineProperty(err, 'message', {
+      enumerable: true,
+      configurable: true,
+      value: msg,
+      writable: true
+    })
+
     // redefine the error name
     Object.defineProperty(err, 'name', {
       enumerable: false,
@@ -153,7 +180,8 @@ function createServerErrorConstructor (HttpError, name, code) {
 
   function ServerError (message) {
     // create the error object
-    var err = new Error(message != null ? message : statuses[code])
+    var msg = message != null ? message : statuses[code]
+    var err = new Error(msg)
 
     // capture a stack trace to the construction point
     Error.captureStackTrace(err, ServerError)
@@ -161,6 +189,14 @@ function createServerErrorConstructor (HttpError, name, code) {
     // adjust the [[Prototype]]
     setPrototypeOf(err, ServerError.prototype)
 
+    // redefine the error message
+    Object.defineProperty(err, 'message', {
+      enumerable: true,
+      configurable: true,
+      value: msg,
+      writable: true
+    })
+
     // redefine the error name
     Object.defineProperty(err, 'name', {
       enumerable: false,
@@ -191,11 +227,11 @@ function populateConstructorExports (exports, codes, HttpError) {
     var CodeError
     var name = toIdentifier(statuses[code])
 
-    switch (String(code).charAt(0)) {
-      case '4':
+    switch (codeClass(code)) {
+      case 400:
         CodeError = createClientErrorConstructor(HttpError, name, code)
         break
-      case '5':
+      case 500:
         CodeError = createServerErrorConstructor(HttpError, name, code)
         break
     }
@@ -208,7 +244,8 @@ function populateConstructorExports (exports, codes, HttpError) {
   })
 
   // backwards-compatibility
-  exports["I'mateapot"] = exports.ImATeapot
+  exports["I'mateapot"] = deprecate.function(exports.ImATeapot,
+    '"I\'mateapot"; use "ImATeapot" instead')
 }
 
 /**
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/package.json
index 3136548b6..f9b3c0389 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/http-errors/package.json
@@ -1,49 +1,29 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "http-errors@~1.5.1",
-        "scope": null,
-        "escapedName": "http-errors",
-        "name": "http-errors",
-        "rawSpec": "~1.5.1",
-        "spec": ">=1.5.1 <1.6.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send"
-    ]
-  ],
-  "_from": "http-errors@>=1.5.1 <1.6.0",
-  "_id": "http-errors@1.5.1",
-  "_inCache": true,
+  "_from": "http-errors@~1.6.2",
+  "_id": "http-errors@1.6.2",
+  "_inBundle": false,
+  "_integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
   "_location": "/http-errors",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/http-errors-1.5.1.tgz_1479361411507_0.47469806275330484"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "http-errors@~1.5.1",
-    "scope": null,
-    "escapedName": "http-errors",
+    "type": "range",
+    "registry": true,
+    "raw": "http-errors@~1.6.2",
     "name": "http-errors",
-    "rawSpec": "~1.5.1",
-    "spec": ">=1.5.1 <1.6.0",
-    "type": "range"
+    "escapedName": "http-errors",
+    "rawSpec": "~1.6.2",
+    "saveSpec": null,
+    "fetchSpec": "~1.6.2"
   },
   "_requiredBy": [
+    "/body-parser",
+    "/raw-body",
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
-  "_shasum": "788c0d2c1de2c81b9e6e8c01843b6b97eb920750",
-  "_shrinkwrap": null,
-  "_spec": "http-errors@~1.5.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send",
+  "_resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+  "_shasum": "0a002cc85707192a7e7946ceedc11155f60ec736",
+  "_spec": "http-errors@~1.6.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/body-parser",
   "author": {
     "name": "Jonathan Ong",
     "email": "me@jongleberry.com",
@@ -52,6 +32,7 @@
   "bugs": {
     "url": "https://github.com/jshttp/http-errors/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Alan Plum",
@@ -63,25 +44,24 @@
     }
   ],
   "dependencies": {
+    "depd": "1.1.1",
     "inherits": "2.0.3",
-    "setprototypeof": "1.0.2",
+    "setprototypeof": "1.0.3",
     "statuses": ">= 1.3.1 < 2"
   },
+  "deprecated": false,
   "description": "Create HTTP error objects",
   "devDependencies": {
-    "eslint": "3.10.2",
-    "eslint-config-standard": "6.2.1",
-    "eslint-plugin-markdown": "1.0.0-beta.3",
-    "eslint-plugin-promise": "3.3.2",
-    "eslint-plugin-standard": "2.0.1",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
     "istanbul": "0.4.5",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "788c0d2c1de2c81b9e6e8c01843b6b97eb920750",
-    "tarball": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -91,30 +71,13 @@
     "LICENSE",
     "README.md"
   ],
-  "gitHead": "a55db90c7a2c0bafedb4bfa35a85eee5f53a37e9",
-  "homepage": "https://github.com/jshttp/http-errors",
+  "homepage": "https://github.com/jshttp/http-errors#readme",
   "keywords": [
     "http",
     "error"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "egeste",
-      "email": "npm@egeste.net"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "http-errors",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/http-errors.git"
@@ -125,5 +88,5 @@
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",
     "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot"
   },
-  "version": "1.5.1"
+  "version": "1.6.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/inherits/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/inherits/package.json
index 0f480a36f..65239d638 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/inherits/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/inherits/package.json
@@ -1,69 +1,42 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "inherits@2.0.3",
-        "scope": null,
-        "escapedName": "inherits",
-        "name": "inherits",
-        "rawSpec": "2.0.3",
-        "spec": "2.0.3",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/http-errors"
-    ]
-  ],
-  "_from": "inherits@2.0.3",
+  "_from": "inherits@2",
   "_id": "inherits@2.0.3",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
   "_location": "/inherits",
-  "_nodeVersion": "6.5.0",
-  "_npmOperationalInternal": {
-    "host": "packages-16-east.internal.npmjs.com",
-    "tmp": "tmp/inherits-2.0.3.tgz_1473295776489_0.08142363070510328"
-  },
-  "_npmUser": {
-    "name": "isaacs",
-    "email": "i@izs.me"
-  },
-  "_npmVersion": "3.10.7",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "inherits@2.0.3",
-    "scope": null,
-    "escapedName": "inherits",
+    "type": "range",
+    "registry": true,
+    "raw": "inherits@2",
     "name": "inherits",
-    "rawSpec": "2.0.3",
-    "spec": "2.0.3",
-    "type": "version"
+    "escapedName": "inherits",
+    "rawSpec": "2",
+    "saveSpec": null,
+    "fetchSpec": "2"
   },
   "_requiredBy": [
+    "/glob",
     "/http-errors"
   ],
   "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
   "_shasum": "633c2c83e3da42a502f52466022480f4208261de",
-  "_shrinkwrap": null,
-  "_spec": "inherits@2.0.3",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/http-errors",
+  "_spec": "inherits@2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/glob",
   "browser": "./inherits_browser.js",
   "bugs": {
     "url": "https://github.com/isaacs/inherits/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
   "devDependencies": {
     "tap": "^7.1.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "633c2c83e3da42a502f52466022480f4208261de",
-    "tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
-  },
   "files": [
     "inherits.js",
     "inherits_browser.js"
   ],
-  "gitHead": "e05d0fb27c61a3ec687214f0476386b765364d5f",
   "homepage": "https://github.com/isaacs/inherits#readme",
   "keywords": [
     "inheritance",
@@ -77,15 +50,7 @@
   ],
   "license": "ISC",
   "main": "./inherits.js",
-  "maintainers": [
-    {
-      "name": "isaacs",
-      "email": "i@izs.me"
-    }
-  ],
   "name": "inherits",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/inherits.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/Cakefile b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/Cakefile
index 7fd355a7b..a6de48f76 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/Cakefile
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/Cakefile
@@ -4,7 +4,7 @@ nodeunit     = require 'nodeunit'
 UglifyJS     = require 'uglify-js'
 
 task 'build', 'build the JavaScript files from CoffeeScript source', build = (cb) ->
-  source = fs.readFileSync 'src/ipaddr.coffee'
+  source = fs.readFileSync 'src/ipaddr.coffee', 'utf-8'
   fs.writeFileSync 'lib/ipaddr.js', CoffeeScript.compile source.toString()
 
   invoke 'test'
@@ -14,5 +14,5 @@ task 'test', 'run the bundled tests', (cb) ->
   nodeunit.reporters.default.run ['test']
 
 task 'compress', 'uglify the resulting javascript', (cb) ->
-  result = UglifyJS.minify('lib/ipaddr.js')
-  fs.writeFileSync('ipaddr.min.js', result.code)
+  source = fs.readFileSync 'lib/ipaddr.js', 'utf-8'
+  fs.writeFileSync('ipaddr.min.js', UglifyJS.minify(source).code)
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/LICENSE
index 3493f0dfc..f6b37b52d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2011 Peter Zotov <whitequark@whitequark.org>
+Copyright (C) 2011-2017 whitequark <whitequark@whitequark.org>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,4 @@ 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.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/README.md
index 1d2b42dc8..6876a3b82 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/README.md
@@ -43,7 +43,7 @@ or throws an `Error` if the passed string is not a valid representation of an
 IP address.
 
 The `ipaddr.process` method works just like the `ipaddr.parse` one, but it
-automatically converts IPv4-mapped IPv6 addresses to their IPv4 couterparts
+automatically converts IPv4-mapped IPv6 addresses to their IPv4 counterparts
 before returning. It is useful when you have a Node.js instance listening
 on an IPv6 socket, and the `net.ivp6.bindv6only` sysctl parameter (or its
 equivalent on non-Linux OS) is set to 0. In this case, you can accept IPv4
@@ -97,8 +97,7 @@ in the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `"unica
 (the default one) and `"reserved"`.
 
 You can match against your own range list by using
-`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both
-IPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:
+`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with a mix of IPv6 or IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:
 
 ```js
 var rangeList = {
@@ -108,7 +107,7 @@ var rangeList = {
     [ ipaddr.parse('2001:5c0::'), 32 ]  // freenet6
   ]
 };
-ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "he.net"
+ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "tunnelProviders"
 ```
 
 The addresses can be converted to their byte representation with `toByteArray()`.
@@ -155,6 +154,13 @@ var addr = ipaddr.parse("2001:db8:10::1234:DEAD");
 addr.parts // => [0x2001, 0xdb8, 0x10, 0, 0, 0, 0x1234, 0xdead]
 ```
 
+A IPv6 zone index can be accessed via `addr.zoneId`:
+
+```js
+var addr = ipaddr.parse("2001:db8::%eth0");
+addr.zoneId // => 'eth0'
+```
+
 #### IPv4 properties
 
 `toIPv4MappedAddress()` will return a corresponding IPv4-mapped IPv6 address.
@@ -174,6 +180,22 @@ ipaddr.IPv4.parse('255.255.255.240').prefixLengthFromSubnetMask() == 28
 ipaddr.IPv4.parse('255.192.164.0').prefixLengthFromSubnetMask()  == null
 ```
 
+`subnetMaskFromPrefixLength()` will return an IPv4 netmask for a valid CIDR prefix length.
+
+```js
+ipaddr.IPv4.subnetMaskFromPrefixLength(24) == "255.255.255.0"
+ipaddr.IPv4.subnetMaskFromPrefixLength(29) == "255.255.255.248"
+```
+
+`broadcastAddressFromCIDR()` will return the broadcast address for a given IPv4 interface and netmask in CIDR notation.
+```js
+ipaddr.IPv4.broadcastAddressFromCIDR("172.0.0.1/24") == "172.0.0.255"
+```
+`networkAddressFromCIDR()` will return the network address for a given IPv4 interface and netmask in CIDR notation.
+```js
+ipaddr.IPv4.networkAddressFromCIDR("172.0.0.1/24") == "172.0.0.0"
+```
+
 #### Conversion
 
 IPv4 and IPv6 can be converted bidirectionally to and from network byte order (MSB) byte arrays.
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/bower.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/bower.json
index e7c681fa2..96e98cdb6 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/bower.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "ipaddr.js",
-  "version": "1.2.0",
+  "version": "1.5.2",
   "homepage": "https://github.com/whitequark/ipaddr.js",
   "authors": [
     "whitequark <whitequark@whitequark.org>"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/ipaddr.min.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/ipaddr.min.js
index 803ff9507..52f9138a9 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/ipaddr.min.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/ipaddr.min.js
@@ -1 +1 @@
-(function(){var r,t,n,e,i,o,a,s;t={},s=this,"undefined"!=typeof module&&null!==module&&module.exports?module.exports=t:s.ipaddr=t,a=function(r,t,n,e){var i,o;if(r.length!==t.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");for(i=0;e>0;){if(o=n-e,o<0&&(o=0),r[i]>>o!==t[i]>>o)return!1;e-=n,i+=1}return!0},t.subnetMatch=function(r,t,n){var e,i,o,a,s;null==n&&(n="unicast");for(e in t)for(i=t[e],!i[0]||i[0]instanceof Array||(i=[i]),a=0,s=i.length;a<s;a++)if(o=i[a],r.match.apply(r,o))return e;return n},t.IPv4=function(){function r(r){var t,n,e;if(4!==r.length)throw new Error("ipaddr: ipv4 octet count should be 4");for(n=0,e=r.length;n<e;n++)if(t=r[n],!(0<=t&&t<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=r}return r.prototype.kind=function(){return"ipv4"},r.prototype.toString=function(){return this.octets.join(".")},r.prototype.toByteArray=function(){return this.octets.slice(0)},r.prototype.match=function(r,t){var n;if(void 0===t&&(n=r,r=n[0],t=n[1]),"ipv4"!==r.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return a(this.octets,r.octets,8,t)},r.prototype.SpecialRanges={unspecified:[[new r([0,0,0,0]),8]],broadcast:[[new r([255,255,255,255]),32]],multicast:[[new r([224,0,0,0]),4]],linkLocal:[[new r([169,254,0,0]),16]],loopback:[[new r([127,0,0,0]),8]],private:[[new r([10,0,0,0]),8],[new r([172,16,0,0]),12],[new r([192,168,0,0]),16]],reserved:[[new r([192,0,0,0]),24],[new r([192,0,2,0]),24],[new r([192,88,99,0]),24],[new r([198,51,100,0]),24],[new r([203,0,113,0]),24],[new r([240,0,0,0]),4]]},r.prototype.range=function(){return t.subnetMatch(this,this.SpecialRanges)},r.prototype.toIPv4MappedAddress=function(){return t.IPv6.parse("::ffff:"+this.toString())},r.prototype.prefixLengthFromSubnetMask=function(){var r,t,n,e,i,o,a;for(o={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0},r=0,e=!1,t=a=3;a>=0;t=a+=-1){if(n=this.octets[t],!(n in o))return null;if(i=o[n],e&&0!==i)return null;8!==i&&(e=!0),r+=i}return 32-r},r}(),n="(0?\\d+|0x[a-f0-9]+)",e={fourOctet:new RegExp("^"+n+"\\."+n+"\\."+n+"\\."+n+"$","i"),longValue:new RegExp("^"+n+"$","i")},t.IPv4.parser=function(r){var t,n,i,o,a;if(n=function(r){return"0"===r[0]&&"x"!==r[1]?parseInt(r,8):parseInt(r)},t=r.match(e.fourOctet))return function(){var r,e,o,a;for(o=t.slice(1,6),a=[],r=0,e=o.length;r<e;r++)i=o[r],a.push(n(i));return a}();if(t=r.match(e.longValue)){if(a=n(t[1]),a>4294967295||a<0)throw new Error("ipaddr: address outside defined range");return function(){var r,t;for(t=[],o=r=0;r<=24;o=r+=8)t.push(a>>o&255);return t}().reverse()}return null},t.IPv6=function(){function r(r){var t,n,e,i,o,a;if(16===r.length)for(this.parts=[],t=e=0;e<=14;t=e+=2)this.parts.push(r[t]<<8|r[t+1]);else{if(8!==r.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=r}for(a=this.parts,i=0,o=a.length;i<o;i++)if(n=a[i],!(0<=n&&n<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits")}return r.prototype.kind=function(){return"ipv6"},r.prototype.toString=function(){var r,t,n,e,i,o,a;for(i=function(){var r,n,e,i;for(e=this.parts,i=[],r=0,n=e.length;r<n;r++)t=e[r],i.push(t.toString(16));return i}.call(this),r=[],n=function(t){return r.push(t)},e=0,o=0,a=i.length;o<a;o++)switch(t=i[o],e){case 0:n("0"===t?"":t),e=1;break;case 1:"0"===t?e=2:n(t);break;case 2:"0"!==t&&(n(""),n(t),e=3);break;case 3:n(t)}return 2===e&&(n(""),n("")),r.join(":")},r.prototype.toByteArray=function(){var r,t,n,e,i;for(r=[],i=this.parts,n=0,e=i.length;n<e;n++)t=i[n],r.push(t>>8),r.push(255&t);return r},r.prototype.toNormalizedString=function(){var r;return function(){var t,n,e,i;for(e=this.parts,i=[],t=0,n=e.length;t<n;t++)r=e[t],i.push(r.toString(16));return i}.call(this).join(":")},r.prototype.match=function(r,t){var n;if(void 0===t&&(n=r,r=n[0],t=n[1]),"ipv6"!==r.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return a(this.parts,r.parts,16,t)},r.prototype.SpecialRanges={unspecified:[new r([0,0,0,0,0,0,0,0]),128],linkLocal:[new r([65152,0,0,0,0,0,0,0]),10],multicast:[new r([65280,0,0,0,0,0,0,0]),8],loopback:[new r([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new r([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new r([0,0,0,0,0,65535,0,0]),96],rfc6145:[new r([0,0,0,0,65535,0,0,0]),96],rfc6052:[new r([100,65435,0,0,0,0,0,0]),96],"6to4":[new r([8194,0,0,0,0,0,0,0]),16],teredo:[new r([8193,0,0,0,0,0,0,0]),32],reserved:[[new r([8193,3512,0,0,0,0,0,0]),32]]},r.prototype.range=function(){return t.subnetMatch(this,this.SpecialRanges)},r.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},r.prototype.toIPv4Address=function(){var r,n,e;if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");return e=this.parts.slice(-2),r=e[0],n=e[1],new t.IPv4([r>>8,255&r,n>>8,255&n])},r}(),i="(?:[0-9a-f]+::?)+",o={native:new RegExp("^(::)?("+i+")?([0-9a-f]+)?(::)?$","i"),transitional:new RegExp("^((?:"+i+")|(?:::)(?:"+i+")?)"+(""+n+"\\."+n+"\\."+n+"\\."+n+"$"),"i")},r=function(r,t){var n,e,i,o,a;if(r.indexOf("::")!==r.lastIndexOf("::"))return null;for(n=0,e=-1;(e=r.indexOf(":",e+1))>=0;)n++;if("::"===r.substr(0,2)&&n--,"::"===r.substr(-2,2)&&n--,n>t)return null;for(a=t-n,o=":";a--;)o+="0:";return r=r.replace("::",o),":"===r[0]&&(r=r.slice(1)),":"===r[r.length-1]&&(r=r.slice(0,-1)),function(){var t,n,e,o;for(e=r.split(":"),o=[],t=0,n=e.length;t<n;t++)i=e[t],o.push(parseInt(i,16));return o}()},t.IPv6.parser=function(t){var n,e,i,a,s,p;if(t.match(o.native))return r(t,8);if((n=t.match(o.transitional))&&(a=r(n[1].slice(0,-1),6))){for(i=[parseInt(n[2]),parseInt(n[3]),parseInt(n[4]),parseInt(n[5])],s=0,p=i.length;s<p;s++)if(e=i[s],!(0<=e&&e<=255))return null;return a.push(i[0]<<8|i[1]),a.push(i[2]<<8|i[3]),a}return null},t.IPv4.isIPv4=t.IPv6.isIPv6=function(r){return null!==this.parser(r)},t.IPv4.isValid=function(r){var t;try{return new this(this.parser(r)),!0}catch(r){return t=r,!1}},t.IPv4.isValidFourPartDecimal=function(r){return!(!t.IPv4.isValid(r)||!r.match(/^\d+(\.\d+){3}$/))},t.IPv6.isValid=function(r){var t;if("string"==typeof r&&r.indexOf(":")===-1)return!1;try{return new this(this.parser(r)),!0}catch(r){return t=r,!1}},t.IPv4.parse=t.IPv6.parse=function(r){var t;if(t=this.parser(r),null===t)throw new Error("ipaddr: string is not formatted like ip address");return new this(t)},t.IPv4.parseCIDR=function(r){var t,n;if((n=r.match(/^(.+)\/(\d+)$/))&&(t=parseInt(n[2]),t>=0&&t<=32))return[this.parse(n[1]),t];throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},t.IPv6.parseCIDR=function(r){var t,n;if((n=r.match(/^(.+)\/(\d+)$/))&&(t=parseInt(n[2]),t>=0&&t<=128))return[this.parse(n[1]),t];throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},t.isValid=function(r){return t.IPv6.isValid(r)||t.IPv4.isValid(r)},t.parse=function(r){if(t.IPv6.isValid(r))return t.IPv6.parse(r);if(t.IPv4.isValid(r))return t.IPv4.parse(r);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},t.parseCIDR=function(r){var n;try{return t.IPv6.parseCIDR(r)}catch(e){n=e;try{return t.IPv4.parseCIDR(r)}catch(r){throw n=r,new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},t.fromByteArray=function(r){var n;if(n=r.length,4===n)return new t.IPv4(r);if(16===n)return new t.IPv6(r);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},t.process=function(r){var t;return t=this.parse(r),"ipv6"===t.kind()&&t.isIPv4MappedAddress()?t.toIPv4Address():t}}).call(this);
\ No newline at end of file
+(function(){var r,t,n,e,i,o,a,s;t={},s=this,"undefined"!=typeof module&&null!==module&&module.exports?module.exports=t:s.ipaddr=t,a=function(r,t,n,e){var i,o;if(r.length!==t.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");for(i=0;e>0;){if((o=n-e)<0&&(o=0),r[i]>>o!=t[i]>>o)return!1;e-=n,i+=1}return!0},t.subnetMatch=function(r,t,n){var e,i,o,a,s;null==n&&(n="unicast");for(o in t)for(!(a=t[o])[0]||a[0]instanceof Array||(a=[a]),e=0,i=a.length;e<i;e++)if(s=a[e],r.kind()===s[0].kind()&&r.match.apply(r,s))return o;return n},t.IPv4=function(){function r(r){var t,n,e;if(4!==r.length)throw new Error("ipaddr: ipv4 octet count should be 4");for(t=0,n=r.length;t<n;t++)if(!(0<=(e=r[t])&&e<=255))throw new Error("ipaddr: ipv4 octet should fit in 8 bits");this.octets=r}return r.prototype.kind=function(){return"ipv4"},r.prototype.toString=function(){return this.octets.join(".")},r.prototype.toNormalizedString=function(){return this.toString()},r.prototype.toByteArray=function(){return this.octets.slice(0)},r.prototype.match=function(r,t){var n;if(void 0===t&&(r=(n=r)[0],t=n[1]),"ipv4"!==r.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return a(this.octets,r.octets,8,t)},r.prototype.SpecialRanges={unspecified:[[new r([0,0,0,0]),8]],broadcast:[[new r([255,255,255,255]),32]],multicast:[[new r([224,0,0,0]),4]],linkLocal:[[new r([169,254,0,0]),16]],loopback:[[new r([127,0,0,0]),8]],carrierGradeNat:[[new r([100,64,0,0]),10]],private:[[new r([10,0,0,0]),8],[new r([172,16,0,0]),12],[new r([192,168,0,0]),16]],reserved:[[new r([192,0,0,0]),24],[new r([192,0,2,0]),24],[new r([192,88,99,0]),24],[new r([198,51,100,0]),24],[new r([203,0,113,0]),24],[new r([240,0,0,0]),4]]},r.prototype.range=function(){return t.subnetMatch(this,this.SpecialRanges)},r.prototype.toIPv4MappedAddress=function(){return t.IPv6.parse("::ffff:"+this.toString())},r.prototype.prefixLengthFromSubnetMask=function(){var r,t,n,e,i,o,a;for(a={0:8,128:7,192:6,224:5,240:4,248:3,252:2,254:1,255:0},r=0,i=!1,t=n=3;n>=0;t=n+=-1){if(!((e=this.octets[t])in a))return null;if(o=a[e],i&&0!==o)return null;8!==o&&(i=!0),r+=o}return 32-r},r}(),n="(0?\\d+|0x[a-f0-9]+)",e={fourOctet:new RegExp("^"+n+"\\."+n+"\\."+n+"\\."+n+"$","i"),longValue:new RegExp("^"+n+"$","i")},t.IPv4.parser=function(r){var t,n,i,o,a;if(n=function(r){return"0"===r[0]&&"x"!==r[1]?parseInt(r,8):parseInt(r)},t=r.match(e.fourOctet))return function(){var r,e,o,a;for(a=[],r=0,e=(o=t.slice(1,6)).length;r<e;r++)i=o[r],a.push(n(i));return a}();if(t=r.match(e.longValue)){if((a=n(t[1]))>4294967295||a<0)throw new Error("ipaddr: address outside defined range");return function(){var r,t;for(t=[],o=r=0;r<=24;o=r+=8)t.push(a>>o&255);return t}().reverse()}return null},t.IPv6=function(){function r(r,t){var n,e,i,o,a,s;if(16===r.length)for(this.parts=[],n=e=0;e<=14;n=e+=2)this.parts.push(r[n]<<8|r[n+1]);else{if(8!==r.length)throw new Error("ipaddr: ipv6 part count should be 8 or 16");this.parts=r}for(i=0,o=(s=this.parts).length;i<o;i++)if(!(0<=(a=s[i])&&a<=65535))throw new Error("ipaddr: ipv6 part should fit in 16 bits");t&&(this.zoneId=t)}return r.prototype.kind=function(){return"ipv6"},r.prototype.toString=function(){var r,t,n,e,i,o,a,s,p;for(s=function(){var r,t,n,e;for(e=[],r=0,t=(n=this.parts).length;r<t;r++)i=n[r],e.push(i.toString(16));return e}.call(this),t=[],o=function(r){return t.push(r)},a=0,n=0,e=s.length;n<e;n++)switch(i=s[n],a){case 0:o("0"===i?"":i),a=1;break;case 1:"0"===i?a=2:o(i);break;case 2:"0"!==i&&(o(""),o(i),a=3);break;case 3:o(i)}return 2===a&&(o(""),o("")),r=t.join(":"),p="",this.zoneId&&(p="%"+this.zoneId),r+p},r.prototype.toByteArray=function(){var r,t,n,e,i;for(r=[],t=0,n=(i=this.parts).length;t<n;t++)e=i[t],r.push(e>>8),r.push(255&e);return r},r.prototype.toNormalizedString=function(){var r,t,n;return r=function(){var r,n,e,i;for(i=[],r=0,n=(e=this.parts).length;r<n;r++)t=e[r],i.push(t.toString(16));return i}.call(this).join(":"),n="",this.zoneId&&(n="%"+this.zoneId),r+n},r.prototype.match=function(r,t){var n;if(void 0===t&&(r=(n=r)[0],t=n[1]),"ipv6"!==r.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return a(this.parts,r.parts,16,t)},r.prototype.SpecialRanges={unspecified:[new r([0,0,0,0,0,0,0,0]),128],linkLocal:[new r([65152,0,0,0,0,0,0,0]),10],multicast:[new r([65280,0,0,0,0,0,0,0]),8],loopback:[new r([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new r([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new r([0,0,0,0,0,65535,0,0]),96],rfc6145:[new r([0,0,0,0,65535,0,0,0]),96],rfc6052:[new r([100,65435,0,0,0,0,0,0]),96],"6to4":[new r([8194,0,0,0,0,0,0,0]),16],teredo:[new r([8193,0,0,0,0,0,0,0]),32],reserved:[[new r([8193,3512,0,0,0,0,0,0]),32]]},r.prototype.range=function(){return t.subnetMatch(this,this.SpecialRanges)},r.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},r.prototype.toIPv4Address=function(){var r,n,e;if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");return e=this.parts.slice(-2),r=e[0],n=e[1],new t.IPv4([r>>8,255&r,n>>8,255&n])},r.prototype.prefixLengthFromSubnetMask=function(){var r,t,n,e,i,o,a;for(a={0:16,32768:15,49152:14,57344:13,61440:12,63488:11,64512:10,65024:9,65280:8,65408:7,65472:6,65504:5,65520:4,65528:3,65532:2,65534:1,65535:0},r=0,i=!1,t=n=7;n>=0;t=n+=-1){if(!((e=this.parts[t])in a))return null;if(o=a[e],i&&0!==o)return null;16!==o&&(i=!0),r+=o}return 128-r},r}(),i="(?:[0-9a-f]+::?)+",o={zoneIndex:new RegExp("%[0-9a-z]{1,}","i"),native:new RegExp("^(::)?("+i+")?([0-9a-f]+)?(::)?(%[0-9a-z]{1,})?$","i"),transitional:new RegExp("^((?:"+i+")|(?:::)(?:"+i+")?)"+n+"\\."+n+"\\."+n+"\\."+n+"(%[0-9a-z]{1,})?$","i")},r=function(r,t){var n,e,i,a,s,p;if(r.indexOf("::")!==r.lastIndexOf("::"))return null;for((p=(r.match(o.zoneIndex)||[])[0])&&(p=p.substring(1),r=r.replace(/%.+$/,"")),n=0,e=-1;(e=r.indexOf(":",e+1))>=0;)n++;if("::"===r.substr(0,2)&&n--,"::"===r.substr(-2,2)&&n--,n>t)return null;for(s=t-n,a=":";s--;)a+="0:";return":"===(r=r.replace("::",a))[0]&&(r=r.slice(1)),":"===r[r.length-1]&&(r=r.slice(0,-1)),t=function(){var t,n,e,o;for(o=[],t=0,n=(e=r.split(":")).length;t<n;t++)i=e[t],o.push(parseInt(i,16));return o}(),{parts:t,zoneId:p}},t.IPv6.parser=function(t){var n,e,i,a,s,p,u;if(o.native.test(t))return r(t,8);if((a=t.match(o.transitional))&&(u=a[6]||"",(n=r(a[1].slice(0,-1)+u,6)).parts)){for(e=0,i=(p=[parseInt(a[2]),parseInt(a[3]),parseInt(a[4]),parseInt(a[5])]).length;e<i;e++)if(!(0<=(s=p[e])&&s<=255))return null;return n.parts.push(p[0]<<8|p[1]),n.parts.push(p[2]<<8|p[3]),{parts:n.parts,zoneId:n.zoneId}}return null},t.IPv4.isIPv4=t.IPv6.isIPv6=function(r){return null!==this.parser(r)},t.IPv4.isValid=function(r){try{return new this(this.parser(r)),!0}catch(r){return r,!1}},t.IPv4.isValidFourPartDecimal=function(r){return!(!t.IPv4.isValid(r)||!r.match(/^\d+(\.\d+){3}$/))},t.IPv6.isValid=function(r){var t;if("string"==typeof r&&-1===r.indexOf(":"))return!1;try{return t=this.parser(r),new this(t.parts,t.zoneId),!0}catch(r){return r,!1}},t.IPv4.parse=function(r){var t;if(null===(t=this.parser(r)))throw new Error("ipaddr: string is not formatted like ip address");return new this(t)},t.IPv6.parse=function(r){var t;if(null===(t=this.parser(r)).parts)throw new Error("ipaddr: string is not formatted like ip address");return new this(t.parts,t.zoneId)},t.IPv4.parseCIDR=function(r){var t,n;if((n=r.match(/^(.+)\/(\d+)$/))&&(t=parseInt(n[2]))>=0&&t<=32)return[this.parse(n[1]),t];throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},t.IPv4.subnetMaskFromPrefixLength=function(r){var t,n,e;if((r=parseInt(r))<0||r>32)throw new Error("ipaddr: invalid IPv4 prefix length");for(e=[0,0,0,0],n=0,t=Math.floor(r/8);n<t;)e[n]=255,n++;return t<4&&(e[t]=Math.pow(2,r%8)-1<<8-r%8),new this(e)},t.IPv4.broadcastAddressFromCIDR=function(r){var t,n,e,i,o;try{for(e=(t=this.parseCIDR(r))[0].toByteArray(),o=this.subnetMaskFromPrefixLength(t[1]).toByteArray(),i=[],n=0;n<4;)i.push(parseInt(e[n],10)|255^parseInt(o[n],10)),n++;return new this(i)}catch(r){throw r,new Error("ipaddr: the address does not have IPv4 CIDR format")}},t.IPv4.networkAddressFromCIDR=function(r){var t,n,e,i,o;try{for(e=(t=this.parseCIDR(r))[0].toByteArray(),o=this.subnetMaskFromPrefixLength(t[1]).toByteArray(),i=[],n=0;n<4;)i.push(parseInt(e[n],10)&parseInt(o[n],10)),n++;return new this(i)}catch(r){throw r,new Error("ipaddr: the address does not have IPv4 CIDR format")}},t.IPv6.parseCIDR=function(r){var t,n;if((n=r.match(/^(.+)\/(\d+)$/))&&(t=parseInt(n[2]))>=0&&t<=128)return[this.parse(n[1]),t];throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},t.isValid=function(r){return t.IPv6.isValid(r)||t.IPv4.isValid(r)},t.parse=function(r){if(t.IPv6.isValid(r))return t.IPv6.parse(r);if(t.IPv4.isValid(r))return t.IPv4.parse(r);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},t.parseCIDR=function(r){try{return t.IPv6.parseCIDR(r)}catch(n){n;try{return t.IPv4.parseCIDR(r)}catch(r){throw r,new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format")}}},t.fromByteArray=function(r){var n;if(4===(n=r.length))return new t.IPv4(r);if(16===n)return new t.IPv6(r);throw new Error("ipaddr: the binary input is neither an IPv6 nor IPv4 address")},t.process=function(r){var t;return"ipv6"===(t=this.parse(r)).kind()&&t.isIPv4MappedAddress()?t.toIPv4Address():t}}).call(this);
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/lib/ipaddr.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/lib/ipaddr.js
index 0b3e7b3c0..360230bac 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/lib/ipaddr.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/lib/ipaddr.js
@@ -1,5 +1,5 @@
 (function() {
-  var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root;
+  var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root, zoneIndex;
 
   ipaddr = {};
 
@@ -32,7 +32,7 @@
   };
 
   ipaddr.subnetMatch = function(address, rangeList, defaultName) {
-    var rangeName, rangeSubnets, subnet, _i, _len;
+    var k, len, rangeName, rangeSubnets, subnet;
     if (defaultName == null) {
       defaultName = 'unicast';
     }
@@ -41,10 +41,12 @@
       if (rangeSubnets[0] && !(rangeSubnets[0] instanceof Array)) {
         rangeSubnets = [rangeSubnets];
       }
-      for (_i = 0, _len = rangeSubnets.length; _i < _len; _i++) {
-        subnet = rangeSubnets[_i];
-        if (address.match.apply(address, subnet)) {
-          return rangeName;
+      for (k = 0, len = rangeSubnets.length; k < len; k++) {
+        subnet = rangeSubnets[k];
+        if (address.kind() === subnet[0].kind()) {
+          if (address.match.apply(address, subnet)) {
+            return rangeName;
+          }
         }
       }
     }
@@ -53,12 +55,12 @@
 
   ipaddr.IPv4 = (function() {
     function IPv4(octets) {
-      var octet, _i, _len;
+      var k, len, octet;
       if (octets.length !== 4) {
         throw new Error("ipaddr: ipv4 octet count should be 4");
       }
-      for (_i = 0, _len = octets.length; _i < _len; _i++) {
-        octet = octets[_i];
+      for (k = 0, len = octets.length; k < len; k++) {
+        octet = octets[k];
         if (!((0 <= octet && octet <= 255))) {
           throw new Error("ipaddr: ipv4 octet should fit in 8 bits");
         }
@@ -74,14 +76,18 @@
       return this.octets.join(".");
     };
 
+    IPv4.prototype.toNormalizedString = function() {
+      return this.toString();
+    };
+
     IPv4.prototype.toByteArray = function() {
       return this.octets.slice(0);
     };
 
     IPv4.prototype.match = function(other, cidrRange) {
-      var _ref;
+      var ref;
       if (cidrRange === void 0) {
-        _ref = other, other = _ref[0], cidrRange = _ref[1];
+        ref = other, other = ref[0], cidrRange = ref[1];
       }
       if (other.kind() !== 'ipv4') {
         throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");
@@ -95,6 +101,7 @@
       multicast: [[new IPv4([224, 0, 0, 0]), 4]],
       linkLocal: [[new IPv4([169, 254, 0, 0]), 16]],
       loopback: [[new IPv4([127, 0, 0, 0]), 8]],
+      carrierGradeNat: [[new IPv4([100, 64, 0, 0]), 10]],
       "private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]],
       reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]]
     };
@@ -108,7 +115,7 @@
     };
 
     IPv4.prototype.prefixLengthFromSubnetMask = function() {
-      var cidr, i, octet, stop, zeros, zerotable, _i;
+      var cidr, i, k, octet, stop, zeros, zerotable;
       zerotable = {
         0: 8,
         128: 7,
@@ -122,7 +129,7 @@
       };
       cidr = 0;
       stop = false;
-      for (i = _i = 3; _i >= 0; i = _i += -1) {
+      for (i = k = 3; k >= 0; i = k += -1) {
         octet = this.octets[i];
         if (octet in zerotable) {
           zeros = zerotable[octet];
@@ -162,14 +169,14 @@
     };
     if (match = string.match(ipv4Regexes.fourOctet)) {
       return (function() {
-        var _i, _len, _ref, _results;
-        _ref = match.slice(1, 6);
-        _results = [];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          part = _ref[_i];
-          _results.push(parseIntAuto(part));
+        var k, len, ref, results;
+        ref = match.slice(1, 6);
+        results = [];
+        for (k = 0, len = ref.length; k < len; k++) {
+          part = ref[k];
+          results.push(parseIntAuto(part));
         }
-        return _results;
+        return results;
       })();
     } else if (match = string.match(ipv4Regexes.longValue)) {
       value = parseIntAuto(match[1]);
@@ -177,12 +184,12 @@
         throw new Error("ipaddr: address outside defined range");
       }
       return ((function() {
-        var _i, _results;
-        _results = [];
-        for (shift = _i = 0; _i <= 24; shift = _i += 8) {
-          _results.push((value >> shift) & 0xff);
+        var k, results;
+        results = [];
+        for (shift = k = 0; k <= 24; shift = k += 8) {
+          results.push((value >> shift) & 0xff);
         }
-        return _results;
+        return results;
       })()).reverse();
     } else {
       return null;
@@ -190,11 +197,11 @@
   };
 
   ipaddr.IPv6 = (function() {
-    function IPv6(parts) {
-      var i, part, _i, _j, _len, _ref;
+    function IPv6(parts, zoneId) {
+      var i, k, l, len, part, ref;
       if (parts.length === 16) {
         this.parts = [];
-        for (i = _i = 0; _i <= 14; i = _i += 2) {
+        for (i = k = 0; k <= 14; i = k += 2) {
           this.parts.push((parts[i] << 8) | parts[i + 1]);
         }
       } else if (parts.length === 8) {
@@ -202,13 +209,16 @@
       } else {
         throw new Error("ipaddr: ipv6 part count should be 8 or 16");
       }
-      _ref = this.parts;
-      for (_j = 0, _len = _ref.length; _j < _len; _j++) {
-        part = _ref[_j];
+      ref = this.parts;
+      for (l = 0, len = ref.length; l < len; l++) {
+        part = ref[l];
         if (!((0 <= part && part <= 0xffff))) {
           throw new Error("ipaddr: ipv6 part should fit in 16 bits");
         }
       }
+      if (zoneId) {
+        this.zoneId = zoneId;
+      }
     }
 
     IPv6.prototype.kind = function() {
@@ -216,24 +226,24 @@
     };
 
     IPv6.prototype.toString = function() {
-      var compactStringParts, part, pushPart, state, stringParts, _i, _len;
+      var addr, compactStringParts, k, len, part, pushPart, state, stringParts, suffix;
       stringParts = (function() {
-        var _i, _len, _ref, _results;
-        _ref = this.parts;
-        _results = [];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          part = _ref[_i];
-          _results.push(part.toString(16));
+        var k, len, ref, results;
+        ref = this.parts;
+        results = [];
+        for (k = 0, len = ref.length; k < len; k++) {
+          part = ref[k];
+          results.push(part.toString(16));
         }
-        return _results;
+        return results;
       }).call(this);
       compactStringParts = [];
       pushPart = function(part) {
         return compactStringParts.push(part);
       };
       state = 0;
-      for (_i = 0, _len = stringParts.length; _i < _len; _i++) {
-        part = stringParts[_i];
+      for (k = 0, len = stringParts.length; k < len; k++) {
+        part = stringParts[k];
         switch (state) {
           case 0:
             if (part === '0') {
@@ -265,15 +275,20 @@
         pushPart('');
         pushPart('');
       }
-      return compactStringParts.join(":");
+      addr = compactStringParts.join(":");
+      suffix = '';
+      if (this.zoneId) {
+        suffix = '%' + this.zoneId;
+      }
+      return addr + suffix;
     };
 
     IPv6.prototype.toByteArray = function() {
-      var bytes, part, _i, _len, _ref;
+      var bytes, k, len, part, ref;
       bytes = [];
-      _ref = this.parts;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        part = _ref[_i];
+      ref = this.parts;
+      for (k = 0, len = ref.length; k < len; k++) {
+        part = ref[k];
         bytes.push(part >> 8);
         bytes.push(part & 0xff);
       }
@@ -281,23 +296,28 @@
     };
 
     IPv6.prototype.toNormalizedString = function() {
-      var part;
-      return ((function() {
-        var _i, _len, _ref, _results;
-        _ref = this.parts;
-        _results = [];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          part = _ref[_i];
-          _results.push(part.toString(16));
+      var addr, part, suffix;
+      addr = ((function() {
+        var k, len, ref, results;
+        ref = this.parts;
+        results = [];
+        for (k = 0, len = ref.length; k < len; k++) {
+          part = ref[k];
+          results.push(part.toString(16));
         }
-        return _results;
+        return results;
       }).call(this)).join(":");
+      suffix = '';
+      if (this.zoneId) {
+        suffix = '%' + this.zoneId;
+      }
+      return addr + suffix;
     };
 
     IPv6.prototype.match = function(other, cidrRange) {
-      var _ref;
+      var ref;
       if (cidrRange === void 0) {
-        _ref = other, other = _ref[0], cidrRange = _ref[1];
+        ref = other, other = ref[0], cidrRange = ref[1];
       }
       if (other.kind() !== 'ipv6') {
         throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");
@@ -328,30 +348,79 @@
     };
 
     IPv6.prototype.toIPv4Address = function() {
-      var high, low, _ref;
+      var high, low, ref;
       if (!this.isIPv4MappedAddress()) {
         throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");
       }
-      _ref = this.parts.slice(-2), high = _ref[0], low = _ref[1];
+      ref = this.parts.slice(-2), high = ref[0], low = ref[1];
       return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff]);
     };
 
+    IPv6.prototype.prefixLengthFromSubnetMask = function() {
+      var cidr, i, k, part, stop, zeros, zerotable;
+      zerotable = {
+        0: 16,
+        32768: 15,
+        49152: 14,
+        57344: 13,
+        61440: 12,
+        63488: 11,
+        64512: 10,
+        65024: 9,
+        65280: 8,
+        65408: 7,
+        65472: 6,
+        65504: 5,
+        65520: 4,
+        65528: 3,
+        65532: 2,
+        65534: 1,
+        65535: 0
+      };
+      cidr = 0;
+      stop = false;
+      for (i = k = 7; k >= 0; i = k += -1) {
+        part = this.parts[i];
+        if (part in zerotable) {
+          zeros = zerotable[part];
+          if (stop && zeros !== 0) {
+            return null;
+          }
+          if (zeros !== 16) {
+            stop = true;
+          }
+          cidr += zeros;
+        } else {
+          return null;
+        }
+      }
+      return 128 - cidr;
+    };
+
     return IPv6;
 
   })();
 
   ipv6Part = "(?:[0-9a-f]+::?)+";
 
+  zoneIndex = "%[0-9a-z]{1,}";
+
   ipv6Regexes = {
-    "native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?$", 'i'),
-    transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + ("" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$"), 'i')
+    zoneIndex: new RegExp(zoneIndex, 'i'),
+    "native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?(" + zoneIndex + ")?$", 'i'),
+    transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + (ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part) + ("(" + zoneIndex + ")?$"), 'i')
   };
 
   expandIPv6 = function(string, parts) {
-    var colonCount, lastColon, part, replacement, replacementCount;
+    var colonCount, lastColon, part, replacement, replacementCount, zoneId;
     if (string.indexOf('::') !== string.lastIndexOf('::')) {
       return null;
     }
+    zoneId = (string.match(ipv6Regexes['zoneIndex']) || [])[0];
+    if (zoneId) {
+      zoneId = zoneId.substring(1);
+      string = string.replace(/%.+$/, '');
+    }
     colonCount = 0;
     lastColon = -1;
     while ((lastColon = string.indexOf(':', lastColon + 1)) >= 0) {
@@ -378,35 +447,43 @@
     if (string[string.length - 1] === ':') {
       string = string.slice(0, -1);
     }
-    return (function() {
-      var _i, _len, _ref, _results;
-      _ref = string.split(":");
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        part = _ref[_i];
-        _results.push(parseInt(part, 16));
+    parts = (function() {
+      var k, len, ref, results;
+      ref = string.split(":");
+      results = [];
+      for (k = 0, len = ref.length; k < len; k++) {
+        part = ref[k];
+        results.push(parseInt(part, 16));
       }
-      return _results;
+      return results;
     })();
+    return {
+      parts: parts,
+      zoneId: zoneId
+    };
   };
 
   ipaddr.IPv6.parser = function(string) {
-    var match, octet, octets, parts, _i, _len;
-    if (string.match(ipv6Regexes['native'])) {
+    var addr, k, len, match, octet, octets, zoneId;
+    if (ipv6Regexes['native'].test(string)) {
       return expandIPv6(string, 8);
     } else if (match = string.match(ipv6Regexes['transitional'])) {
-      parts = expandIPv6(match[1].slice(0, -1), 6);
-      if (parts) {
+      zoneId = match[6] || '';
+      addr = expandIPv6(match[1].slice(0, -1) + zoneId, 6);
+      if (addr.parts) {
         octets = [parseInt(match[2]), parseInt(match[3]), parseInt(match[4]), parseInt(match[5])];
-        for (_i = 0, _len = octets.length; _i < _len; _i++) {
-          octet = octets[_i];
+        for (k = 0, len = octets.length; k < len; k++) {
+          octet = octets[k];
           if (!((0 <= octet && octet <= 255))) {
             return null;
           }
         }
-        parts.push(octets[0] << 8 | octets[1]);
-        parts.push(octets[2] << 8 | octets[3]);
-        return parts;
+        addr.parts.push(octets[0] << 8 | octets[1]);
+        addr.parts.push(octets[2] << 8 | octets[3]);
+        return {
+          parts: addr.parts,
+          zoneId: addr.zoneId
+        };
       }
     }
     return null;
@@ -421,8 +498,8 @@
     try {
       new this(this.parser(string));
       return true;
-    } catch (_error) {
-      e = _error;
+    } catch (error1) {
+      e = error1;
       return false;
     }
   };
@@ -436,20 +513,21 @@
   };
 
   ipaddr.IPv6.isValid = function(string) {
-    var e;
+    var addr, e;
     if (typeof string === "string" && string.indexOf(":") === -1) {
       return false;
     }
     try {
-      new this(this.parser(string));
+      addr = this.parser(string);
+      new this(addr.parts, addr.zoneId);
       return true;
-    } catch (_error) {
-      e = _error;
+    } catch (error1) {
+      e = error1;
       return false;
     }
   };
 
-  ipaddr.IPv4.parse = ipaddr.IPv6.parse = function(string) {
+  ipaddr.IPv4.parse = function(string) {
     var parts;
     parts = this.parser(string);
     if (parts === null) {
@@ -458,6 +536,15 @@
     return new this(parts);
   };
 
+  ipaddr.IPv6.parse = function(string) {
+    var addr;
+    addr = this.parser(string);
+    if (addr.parts === null) {
+      throw new Error("ipaddr: string is not formatted like ip address");
+    }
+    return new this(addr.parts, addr.zoneId);
+  };
+
   ipaddr.IPv4.parseCIDR = function(string) {
     var maskLength, match;
     if (match = string.match(/^(.+)\/(\d+)$/)) {
@@ -469,6 +556,63 @@
     throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range");
   };
 
+  ipaddr.IPv4.subnetMaskFromPrefixLength = function(prefix) {
+    var filledOctetCount, j, octets;
+    prefix = parseInt(prefix);
+    if (prefix < 0 || prefix > 32) {
+      throw new Error('ipaddr: invalid IPv4 prefix length');
+    }
+    octets = [0, 0, 0, 0];
+    j = 0;
+    filledOctetCount = Math.floor(prefix / 8);
+    while (j < filledOctetCount) {
+      octets[j] = 255;
+      j++;
+    }
+    if (filledOctetCount < 4) {
+      octets[filledOctetCount] = Math.pow(2, prefix % 8) - 1 << 8 - (prefix % 8);
+    }
+    return new this(octets);
+  };
+
+  ipaddr.IPv4.broadcastAddressFromCIDR = function(string) {
+    var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets;
+    try {
+      cidr = this.parseCIDR(string);
+      ipInterfaceOctets = cidr[0].toByteArray();
+      subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
+      octets = [];
+      i = 0;
+      while (i < 4) {
+        octets.push(parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255);
+        i++;
+      }
+      return new this(octets);
+    } catch (error1) {
+      error = error1;
+      throw new Error('ipaddr: the address does not have IPv4 CIDR format');
+    }
+  };
+
+  ipaddr.IPv4.networkAddressFromCIDR = function(string) {
+    var cidr, error, i, ipInterfaceOctets, octets, subnetMaskOctets;
+    try {
+      cidr = this.parseCIDR(string);
+      ipInterfaceOctets = cidr[0].toByteArray();
+      subnetMaskOctets = this.subnetMaskFromPrefixLength(cidr[1]).toByteArray();
+      octets = [];
+      i = 0;
+      while (i < 4) {
+        octets.push(parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10));
+        i++;
+      }
+      return new this(octets);
+    } catch (error1) {
+      error = error1;
+      throw new Error('ipaddr: the address does not have IPv4 CIDR format');
+    }
+  };
+
   ipaddr.IPv6.parseCIDR = function(string) {
     var maskLength, match;
     if (match = string.match(/^(.+)\/(\d+)$/)) {
@@ -498,12 +642,12 @@
     var e;
     try {
       return ipaddr.IPv6.parseCIDR(string);
-    } catch (_error) {
-      e = _error;
+    } catch (error1) {
+      e = error1;
       try {
         return ipaddr.IPv4.parseCIDR(string);
-      } catch (_error) {
-        e = _error;
+      } catch (error1) {
+        e = error1;
         throw new Error("ipaddr: the address has neither IPv6 nor IPv4 CIDR format");
       }
     }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/package.json
index 08a01d896..01ea5f52f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/package.json
@@ -1,49 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "ipaddr.js@1.2.0",
-        "scope": null,
-        "escapedName": "ipaddr.js",
-        "name": "ipaddr.js",
-        "rawSpec": "1.2.0",
-        "spec": "1.2.0",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr"
-    ]
-  ],
-  "_from": "ipaddr.js@1.2.0",
-  "_id": "ipaddr.js@1.2.0",
-  "_inCache": true,
+  "_from": "ipaddr.js@1.5.2",
+  "_id": "ipaddr.js@1.5.2",
+  "_inBundle": false,
+  "_integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=",
   "_location": "/ipaddr.js",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/ipaddr.js-1.2.0.tgz_1467971539814_0.6815996605437249"
-  },
-  "_npmUser": {
-    "name": "whitequark",
-    "email": "whitequark@whitequark.org"
-  },
-  "_npmVersion": "1.4.21",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "ipaddr.js@1.2.0",
-    "scope": null,
-    "escapedName": "ipaddr.js",
+    "type": "version",
+    "registry": true,
+    "raw": "ipaddr.js@1.5.2",
     "name": "ipaddr.js",
-    "rawSpec": "1.2.0",
-    "spec": "1.2.0",
-    "type": "version"
+    "escapedName": "ipaddr.js",
+    "rawSpec": "1.5.2",
+    "saveSpec": null,
+    "fetchSpec": "1.5.2"
   },
   "_requiredBy": [
     "/proxy-addr"
   ],
-  "_resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz",
-  "_shasum": "8aba49c9192799585bdd643e0ccb50e8ae777ba4",
-  "_shrinkwrap": null,
-  "_spec": "ipaddr.js@1.2.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr",
+  "_resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+  "_shasum": "d4b505bde9946987ccf0fc58d9010ff9607e3fa0",
+  "_spec": "ipaddr.js@1.5.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/proxy-addr",
   "author": {
     "name": "whitequark",
     "email": "whitequark@whitequark.org"
@@ -51,24 +29,21 @@
   "bugs": {
     "url": "https://github.com/whitequark/ipaddr.js/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {},
+  "deprecated": false,
   "description": "A library for manipulating IPv4 and IPv6 addresses in JavaScript.",
   "devDependencies": {
-    "coffee-script": "~1.6",
+    "coffee-script": "~1.12.6",
     "nodeunit": ">=0.8.2 <0.8.7",
-    "uglify-js": "latest"
+    "uglify-js": "~3.0.19"
   },
   "directories": {
     "lib": "./lib"
   },
-  "dist": {
-    "shasum": "8aba49c9192799585bdd643e0ccb50e8ae777ba4",
-    "tarball": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz"
-  },
   "engines": {
     "node": ">= 0.10"
   },
-  "gitHead": "87bcb487f1a6739101231e71b111da2823540398",
   "homepage": "https://github.com/whitequark/ipaddr.js#readme",
   "keywords": [
     "ip",
@@ -77,15 +52,7 @@
   ],
   "license": "MIT",
   "main": "./lib/ipaddr",
-  "maintainers": [
-    {
-      "name": "whitequark",
-      "email": "whitequark@whitequark.org"
-    }
-  ],
   "name": "ipaddr.js",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git://github.com/whitequark/ipaddr.js.git"
@@ -93,5 +60,5 @@
   "scripts": {
     "test": "cake build test"
   },
-  "version": "1.2.0"
+  "version": "1.5.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/src/ipaddr.coffee b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/src/ipaddr.coffee
index 45ffc34b3..6d7236e4e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/src/ipaddr.coffee
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/src/ipaddr.coffee
@@ -28,6 +28,8 @@ matchCIDR = (first, second, partSize, cidrBits) ->
   return true
 
 # An utility function to ease named range matching. See examples below.
+# rangeList can contain both IPv4 and IPv6 subnet entries and will not throw errors
+# on matching IPv4 addresses to IPv6 ranges or vice versa.
 ipaddr.subnetMatch = (address, rangeList, defaultName='unicast') ->
   for rangeName, rangeSubnets of rangeList
     # ECMA5 Array.isArray isn't available everywhere
@@ -35,7 +37,9 @@ ipaddr.subnetMatch = (address, rangeList, defaultName='unicast') ->
       rangeSubnets = [ rangeSubnets ]
 
     for subnet in rangeSubnets
-      return rangeName if address.match.apply(address, subnet)
+      if address.kind() == subnet[0].kind()
+        if address.match.apply(address, subnet)
+          return rangeName
 
   return defaultName
 
@@ -62,6 +66,10 @@ class ipaddr.IPv4
   toString: ->
     return @octets.join "."
 
+  # Symmetrical method strictly for aligning with the IPv6 methods.
+  toNormalizedString: ->
+    return this.toString()
+
   # Returns an array of byte-sized values in network order (MSB first)
   toByteArray: ->
     return @octets.slice(0) # octets.clone
@@ -77,6 +85,7 @@ class ipaddr.IPv4
     return matchCIDR(this.octets, other.octets, 8, cidrRange)
 
   # Special IPv4 address ranges.
+  # See also https://en.wikipedia.org/wiki/Reserved_IP_addresses
   SpecialRanges:
     unspecified: [
       [ new IPv4([0,     0,    0,   0]),  8 ]
@@ -93,6 +102,9 @@ class ipaddr.IPv4
     loopback: [ # RFC5735
       [ new IPv4([127,   0,    0,   0]), 8  ]
     ]
+    carrierGradeNat: [ # RFC6598
+      [ new IPv4([100,   64,   0,   0]), 10 ]
+    ]
     private: [ # RFC1918
       [ new IPv4([10,    0,    0,   0]), 8  ]
       [ new IPv4([172,   16,   0,   0]), 12 ]
@@ -181,7 +193,7 @@ class ipaddr.IPv6
   # Constructs an IPv6 address from an array of eight 16-bit parts
   # or sixteen 8-bit parts in network order (MSB first).
   # Throws an error if the input is invalid.
-  constructor: (parts) ->
+  constructor: (parts, zoneId) ->
     if parts.length == 16
       @parts = []
       for i in [0..14] by 2
@@ -195,6 +207,9 @@ class ipaddr.IPv6
       if !(0 <= part <= 0xffff)
         throw new Error "ipaddr: ipv6 part should fit in 16 bits"
 
+    if zoneId
+      @zoneId = zoneId
+
   # The 'kind' method exists on both IPv4 and IPv6 classes.
   kind: ->
     return 'ipv6'
@@ -234,7 +249,13 @@ class ipaddr.IPv6
       pushPart('')
       pushPart('')
 
-    return compactStringParts.join ":"
+    addr = compactStringParts.join ":"
+
+    suffix = ''
+    if @zoneId
+      suffix = '%' + @zoneId
+
+    return addr + suffix
 
   # Returns an array of byte-sized values in network order (MSB first)
   toByteArray: ->
@@ -248,7 +269,13 @@ class ipaddr.IPv6
   # Returns the address in expanded format with all zeroes included, like
   # 2001:db8:8:66:0:0:0:1
   toNormalizedString: ->
-    return (part.toString(16) for part in @parts).join ":"
+    addr = (part.toString(16) for part in @parts).join ":"
+
+    suffix = ''
+    if @zoneId
+      suffix = '%' + @zoneId
+
+    return addr + suffix
 
   # Checks if this address matches other one within given CIDR range.
   match: (other, cidrRange) ->
@@ -294,15 +321,58 @@ class ipaddr.IPv6
 
     return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff])
 
+  # returns a number of leading ones in IPv6 address, making sure that
+  # the rest is a solid sequence of 0's (valid netmask)
+  # returns either the CIDR length or null if mask is not valid
+  prefixLengthFromSubnetMask: ->
+    # number of zeroes in octet
+    zerotable =
+      0    : 16
+      32768: 15
+      49152: 14
+      57344: 13
+      61440: 12
+      63488: 11
+      64512: 10
+      65024: 9
+      65280: 8
+      65408: 7
+      65472: 6
+      65504: 5
+      65520: 4
+      65528: 3
+      65532: 2
+      65534: 1
+      65535: 0
+
+    cidr = 0
+    # non-zero encountered stop scanning for zeroes
+    stop = false
+    for i in [7..0] by -1
+      part = @parts[i]
+      if part of zerotable
+        zeros = zerotable[part]
+        if stop and zeros != 0
+          return null
+        unless zeros == 16
+          stop = true
+        cidr += zeros
+      else
+        return null
+    return 128 - cidr
+
 # IPv6-matching regular expressions.
 # For IPv6, the task is simpler: it is enough to match the colon-delimited
 # hexadecimal IPv6 and a transitional variant with dotted-decimal IPv4 at
 # the end.
 ipv6Part = "(?:[0-9a-f]+::?)+"
+zoneIndex = "%[0-9a-z]{1,}"
 ipv6Regexes =
-  native:       new RegExp "^(::)?(#{ipv6Part})?([0-9a-f]+)?(::)?$", 'i'
+  zoneIndex:    new RegExp zoneIndex, 'i'
+  native:       new RegExp "^(::)?(#{ipv6Part})?([0-9a-f]+)?(::)?(#{zoneIndex})?$", 'i'
   transitional: new RegExp "^((?:#{ipv6Part})|(?:::)(?:#{ipv6Part})?)" +
-                           "#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}$", 'i'
+                           "#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}\\.#{ipv4Part}" +
+                           "(#{zoneIndex})?$", 'i'
 
 # Expand :: in an IPv6 address or address part consisting of `parts` groups.
 expandIPv6 = (string, parts) ->
@@ -310,6 +380,12 @@ expandIPv6 = (string, parts) ->
   if string.indexOf('::') != string.lastIndexOf('::')
     return null
 
+  # Remove zone index and save it for later
+  zoneId = (string.match(ipv6Regexes['zoneIndex']) || [])[0]
+  if zoneId
+    zoneId = zoneId.substring(1)
+    string = string.replace(/%.+$/, '')
+
   # How many parts do we already have?
   colonCount = 0
   lastColon = -1
@@ -338,25 +414,27 @@ expandIPv6 = (string, parts) ->
   string = string[1..-1] if string[0] == ':'
   string = string[0..-2] if string[string.length-1] == ':'
 
-  return (parseInt(part, 16) for part in string.split(":"))
+  parts = (parseInt(part, 16) for part in string.split(":"))
+  return { parts: parts, zoneId: zoneId }
 
 # Parse an IPv6 address.
 ipaddr.IPv6.parser = (string) ->
-  if string.match(ipv6Regexes['native'])
+  if ipv6Regexes['native'].test(string)
     return expandIPv6(string, 8)
 
   else if match = string.match(ipv6Regexes['transitional'])
-    parts = expandIPv6(match[1][0..-2], 6)
-    if parts
+    zoneId = match[6] || ''
+    addr = expandIPv6(match[1][0..-2] + zoneId, 6)
+    if addr.parts
       octets = [parseInt(match[2]), parseInt(match[3]),
                 parseInt(match[4]), parseInt(match[5])]
       for octet in octets
         if !(0 <= octet <= 255)
           return null
 
-      parts.push(octets[0] << 8 | octets[1])
-      parts.push(octets[2] << 8 | octets[3])
-      return parts
+      addr.parts.push(octets[0] << 8 | octets[1])
+      addr.parts.push(octets[2] << 8 | octets[3])
+      return { parts: addr.parts, zoneId: addr.zoneId }
 
   return null
 
@@ -385,20 +463,28 @@ ipaddr.IPv6.isValid = (string) ->
     return false
 
   try
-    new this(@parser(string))
+    addr = @parser(string)
+    new this(addr.parts, addr.zoneId)
     return true
   catch e
     return false
 
 # Tries to parse and validate a string with IPv4/IPv6 address.
 # Throws an error if it fails.
-ipaddr.IPv4.parse = ipaddr.IPv6.parse = (string) ->
+ipaddr.IPv4.parse = (string) ->
   parts = @parser(string)
   if parts == null
     throw new Error "ipaddr: string is not formatted like ip address"
 
   return new this(parts)
 
+ipaddr.IPv6.parse = (string) ->
+  addr = @parser(string)
+  if addr.parts == null
+    throw new Error "ipaddr: string is not formatted like ip address"
+
+  return new this(addr.parts, addr.zoneId)
+
 ipaddr.IPv4.parseCIDR = (string) ->
   if match = string.match(/^(.+)\/(\d+)$/)
     maskLength = parseInt(match[2])
@@ -407,6 +493,55 @@ ipaddr.IPv4.parseCIDR = (string) ->
 
   throw new Error "ipaddr: string is not formatted like an IPv4 CIDR range"
 
+# A utility function to return subnet mask in IPv4 format given the prefix length
+ipaddr.IPv4.subnetMaskFromPrefixLength = (prefix) ->
+  prefix = parseInt(prefix)
+  if prefix < 0 or prefix > 32
+    throw new Error('ipaddr: invalid IPv4 prefix length')
+  octets = [0, 0, 0, 0]
+  j = 0
+  filledOctetCount = Math.floor(prefix / 8)
+  while j < filledOctetCount
+    octets[j] = 255
+    j++
+  if filledOctetCount < 4
+    octets[filledOctetCount] = Math.pow(2, (prefix % 8)) - 1 << 8 - (prefix % 8)
+  new @(octets)
+
+# A utility function to return broadcast address given the IPv4 interface and prefix length in CIDR notation
+ipaddr.IPv4.broadcastAddressFromCIDR = (string) ->
+  try
+    cidr = @parseCIDR(string)
+    ipInterfaceOctets = cidr[0].toByteArray()
+    subnetMaskOctets = @subnetMaskFromPrefixLength(cidr[1]).toByteArray()
+    octets = []
+    i = 0
+    while i < 4
+      # Broadcast address is bitwise OR between ip interface and inverted mask
+      octets.push parseInt(ipInterfaceOctets[i], 10) | parseInt(subnetMaskOctets[i], 10) ^ 255
+      i++
+    return new @(octets)
+  catch error
+    throw new Error('ipaddr: the address does not have IPv4 CIDR format')
+  return
+
+# A utility function to return network address given the IPv4 interface and prefix length in CIDR notation
+ipaddr.IPv4.networkAddressFromCIDR = (string) ->
+  try
+    cidr = @parseCIDR(string)
+    ipInterfaceOctets = cidr[0].toByteArray()
+    subnetMaskOctets = @subnetMaskFromPrefixLength(cidr[1]).toByteArray()
+    octets = []
+    i = 0
+    while i < 4
+      # Network address is bitwise AND between ip interface and mask
+      octets.push parseInt(ipInterfaceOctets[i], 10) & parseInt(subnetMaskOctets[i], 10)
+      i++
+    return new @(octets)
+  catch error
+    throw new Error('ipaddr: the address does not have IPv4 CIDR format')
+  return
+
 ipaddr.IPv6.parseCIDR = (string) ->
   if match = string.match(/^(.+)\/(\d+)$/)
     maskLength = parseInt(match[2])
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/test/ipaddr.test.coffee b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/test/ipaddr.test.coffee
index b8ef0b913..eef7a091b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/test/ipaddr.test.coffee
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ipaddr.js/test/ipaddr.test.coffee
@@ -21,6 +21,7 @@ module.exports =
   'converts IPv4 to string correctly': (test) ->
     addr = new ipaddr.IPv4([192, 168, 1, 1])
     test.equal(addr.toString(), '192.168.1.1')
+    test.equal(addr.toNormalizedString(), '192.168.1.1')
     test.done()
 
   'returns correct kind for IPv4': (test) ->
@@ -97,6 +98,8 @@ module.exports =
     test.equal(ipaddr.IPv4.parse('0.0.0.0').range(),         'unspecified')
     test.equal(ipaddr.IPv4.parse('0.1.0.0').range(),         'unspecified')
     test.equal(ipaddr.IPv4.parse('10.1.0.1').range(),        'private')
+    test.equal(ipaddr.IPv4.parse('100.64.0.0').range(),      'carrierGradeNat')
+    test.equal(ipaddr.IPv4.parse('100.127.255.255').range(), 'carrierGradeNat')
     test.equal(ipaddr.IPv4.parse('192.168.2.1').range(),     'private')
     test.equal(ipaddr.IPv4.parse('224.100.0.1').range(),     'multicast')
     test.equal(ipaddr.IPv4.parse('169.254.15.0').range(),    'linkLocal')
@@ -140,6 +143,46 @@ module.exports =
     test.equal(new ipaddr.IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]).toString(), '2001:db8::')
     test.done()
 
+  'returns IPv6 zoneIndex': (test) ->
+    addr = new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1], 'utun0')
+    test.equal(addr.toNormalizedString(), '2001:db8:f53a:0:0:0:0:1%utun0')
+    test.equal(addr.toString(), '2001:db8:f53a::1%utun0')
+
+    test.equal(
+      ipaddr.parse('2001:db8:f53a::1%2').toString(),
+      '2001:db8:f53a::1%2'
+    )
+    test.equal(
+      ipaddr.parse('2001:db8:f53a::1%WAT').toString(),
+      '2001:db8:f53a::1%WAT'
+    )
+    test.equal(
+      ipaddr.parse('2001:db8:f53a::1%sUp').toString(),
+      '2001:db8:f53a::1%sUp'
+    )
+
+    test.done()
+
+  'returns IPv6 zoneIndex for IPv4-mapped IPv6 addresses': (test) ->
+    addr = ipaddr.parse('::ffff:192.168.1.1%eth0')
+    test.equal(addr.toNormalizedString(), '0:0:0:0:0:ffff:c0a8:101%eth0')
+    test.equal(addr.toString(), '::ffff:c0a8:101%eth0')
+
+    test.equal(
+      ipaddr.parse('::ffff:192.168.1.1%2').toString(),
+      '::ffff:c0a8:101%2'
+    )
+    test.equal(
+      ipaddr.parse('::ffff:192.168.1.1%WAT').toString(),
+      '::ffff:c0a8:101%WAT'
+    )
+    test.equal(
+      ipaddr.parse('::ffff:192.168.1.1%sUp').toString(),
+      '::ffff:c0a8:101%sUp'
+    )
+
+    test.done()
+
   'returns correct kind for IPv6': (test) ->
     addr = new ipaddr.IPv6([0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1])
     test.equal(addr.kind(), 'ipv6')
@@ -154,21 +197,27 @@ module.exports =
     test.equal(ipaddr.IPv6.isIPv6('2001:db8:F53A::1'),     true)
     test.equal(ipaddr.IPv6.isIPv6('200001::1'),            true)
     test.equal(ipaddr.IPv6.isIPv6('::ffff:192.168.1.1'),   true)
+    test.equal(ipaddr.IPv6.isIPv6('::ffff:192.168.1.1%z'), true)
     test.equal(ipaddr.IPv6.isIPv6('::ffff:300.168.1.1'),   false)
     test.equal(ipaddr.IPv6.isIPv6('::ffff:300.168.1.1:0'), false)
     test.equal(ipaddr.IPv6.isIPv6('fe80::wtf'),            false)
+    test.equal(ipaddr.IPv6.isIPv6('fe80::%'),              false)
     test.done()
 
   'validates IPv6 addresses': (test) ->
     test.equal(ipaddr.IPv6.isValid('2001:db8:F53A::1'),     true)
     test.equal(ipaddr.IPv6.isValid('200001::1'),            false)
     test.equal(ipaddr.IPv6.isValid('::ffff:192.168.1.1'),   true)
+    test.equal(ipaddr.IPv6.isValid('::ffff:192.168.1.1%z'), true)
     test.equal(ipaddr.IPv6.isValid('::ffff:300.168.1.1'),   false)
     test.equal(ipaddr.IPv6.isValid('::ffff:300.168.1.1:0'), false)
     test.equal(ipaddr.IPv6.isValid('::ffff:222.1.41.9000'), false)
     test.equal(ipaddr.IPv6.isValid('2001:db8::F53A::1'),    false)
     test.equal(ipaddr.IPv6.isValid('fe80::wtf'),            false)
+    test.equal(ipaddr.IPv6.isValid('fe80::%'),              false)
     test.equal(ipaddr.IPv6.isValid('2002::2:'),             false)
+    test.equal(ipaddr.IPv6.isValid('::%z'),                 true)
+
     test.equal(ipaddr.IPv6.isValid(undefined),              false)
     test.done()
 
@@ -178,6 +227,8 @@ module.exports =
     test.deepEqual(ipaddr.IPv6.parse('2001:db8:F53A::').parts, [0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 0])
     test.deepEqual(ipaddr.IPv6.parse('::1').parts, [0, 0, 0, 0, 0, 0, 0, 1])
     test.deepEqual(ipaddr.IPv6.parse('::').parts, [0, 0, 0, 0, 0, 0, 0, 0])
+    test.deepEqual(ipaddr.IPv6.parse('::%z').parts, [0, 0, 0, 0, 0, 0, 0, 0])
+    test.deepEqual(ipaddr.IPv6.parse('::%z').zoneId, 'z')
     test.done()
 
   'barfs at invalid IPv6': (test) ->
@@ -192,7 +243,10 @@ module.exports =
     test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f53b::1:1'), 48), false)
     test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f531::1:1'), 44), true)
     test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f500::1'), 40),   true)
+    test.equal(addr.match(ipaddr.IPv6.parse('2001:db8:f500::1%z'), 40), true)
+    test.equal(addr.match(ipaddr.IPv6.parse('2001:db9:f500::1'), 40),   false)
     test.equal(addr.match(ipaddr.IPv6.parse('2001:db9:f500::1'), 40),   false)
+    test.equal(addr.match(ipaddr.IPv6.parse('2001:db9:f500::1%z'), 40), false)
     test.equal(addr.match(addr, 128), true)
     test.done()
 
@@ -203,7 +257,9 @@ module.exports =
     test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db8:f53b::1:1/48')), false)
     test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db8:f531::1:1/44')), true)
     test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db8:f500::1/40')),   true)
+    test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db8:f500::1%z/40')), true)
     test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db9:f500::1/40')),   false)
+    test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db9:f500::1%z/40')), false)
     test.equal(addr.match(ipaddr.IPv6.parseCIDR('2001:db8:f53a::1/128')),  true)
     test.throws ->
       ipaddr.IPv6.parseCIDR('2001:db8:f53a::1')
@@ -238,11 +294,13 @@ module.exports =
     test.equal(ipaddr.IPv6.parse('2001::4242').range(),                'teredo')
     test.equal(ipaddr.IPv6.parse('2001:db8::3210').range(),            'reserved')
     test.equal(ipaddr.IPv6.parse('2001:470:8:66::1').range(),          'unicast')
+    test.equal(ipaddr.IPv6.parse('2001:470:8:66::1%z').range(),        'unicast')
     test.done()
 
   'is able to determine IP address type': (test) ->
     test.equal(ipaddr.parse('8.8.8.8').kind(), 'ipv4')
     test.equal(ipaddr.parse('2001:db8:3312::1').kind(), 'ipv6')
+    test.equal(ipaddr.parse('2001:db8:3312::1%z').kind(), 'ipv6')
     test.done()
 
   'throws an error if tried to parse an invalid address': (test) ->
@@ -254,6 +312,7 @@ module.exports =
     test.equal(ipaddr.process('8.8.8.8').kind(), 'ipv4')
     test.equal(ipaddr.process('2001:db8:3312::1').kind(), 'ipv6')
     test.equal(ipaddr.process('::ffff:192.168.1.1').kind(), 'ipv4')
+    test.equal(ipaddr.process('::ffff:192.168.1.1%z').kind(), 'ipv4')
     test.done()
 
   'correctly converts IPv6 and IPv4 addresses to byte arrays': (test) ->
@@ -262,6 +321,9 @@ module.exports =
     # Fuck yeah. The first byte of Google's IPv6 address is 42. 42!
     test.deepEqual(ipaddr.parse('2a00:1450:8007::68').toByteArray(),
           [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68 ])
+    test.deepEqual(ipaddr.parse('2a00:1450:8007::68%z').toByteArray(),
+          [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68 ])
+
     test.done()
 
   'correctly parses 1 as an IPv4 address': (test) ->
@@ -284,6 +346,7 @@ module.exports =
 
   'does not hang on ::8:8:8:8:8:8:8:8:8': (test) ->
     test.equal(ipaddr.IPv6.isValid('::8:8:8:8:8:8:8:8:8'), false)
+    test.equal(ipaddr.IPv6.isValid('::8:8:8:8:8:8:8:8:8%z'), false)
     test.done()
 
   'subnetMatch does not fail on empty range': (test) ->
@@ -296,6 +359,22 @@ module.exports =
     test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,3,4]), {subnet: []}, false), false)
     test.done()
 
+  'subnetMatch does not fail on IPv4 when looking for IPv6': (test) ->
+    rangelist = {subnet6: ipaddr.parseCIDR('fe80::/64')}
+    test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,3,4]), rangelist, false), false)
+    test.done()
+
+  'subnetMatch does not fail on IPv6 when looking for IPv4': (test) ->
+    rangelist = {subnet4: ipaddr.parseCIDR('1.2.3.0/24')}
+    test.equal(ipaddr.subnetMatch(new ipaddr.IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 1]), rangelist, false), false)
+    test.done()
+
+  'subnetMatch can use a hybrid IPv4/IPv6 range list': (test) ->
+    rangelist = {dual64: [ipaddr.parseCIDR('1.2.4.0/24'), ipaddr.parseCIDR('2001:1:2:3::/64')]}
+    test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,4,1]), rangelist, false), 'dual64')
+    test.equal(ipaddr.subnetMatch(new ipaddr.IPv6([0x2001, 1, 2, 3, 0, 0, 0, 1]), rangelist, false), 'dual64')
+    test.done()
+
   'is able to determine IP address type from byte array input': (test) ->
     test.equal(ipaddr.fromByteArray([0x7f, 0, 0, 1]).kind(), 'ipv4')
     test.equal(ipaddr.fromByteArray([0x20, 0x01, 0xd, 0xb8, 0xf5, 0x3a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]).kind(), 'ipv6')
@@ -342,3 +421,63 @@ module.exports =
     test.equal(ipaddr.IPv4.parse('255.0.255.0').prefixLengthFromSubnetMask(), null)
     test.done()
 
+  'prefixLengthFromSubnetMask returns proper CIDR notation for standard IPv6 masks': (test) ->
+    test.equal(ipaddr.IPv6.parse('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').prefixLengthFromSubnetMask(), 128)
+    test.equal(ipaddr.IPv6.parse('ffff:ffff:ffff:ffff::').prefixLengthFromSubnetMask(), 64)
+    test.equal(ipaddr.IPv6.parse('ffff:ffff:ffff:ff80::').prefixLengthFromSubnetMask(), 57)
+    test.equal(ipaddr.IPv6.parse('ffff:ffff:ffff::').prefixLengthFromSubnetMask(), 48)
+    test.equal(ipaddr.IPv6.parse('ffff:ffff:ffff::%z').prefixLengthFromSubnetMask(), 48)
+    test.equal(ipaddr.IPv6.parse('::').prefixLengthFromSubnetMask(), 0)
+    test.equal(ipaddr.IPv6.parse('::%z').prefixLengthFromSubnetMask(), 0)
+    # negative cases
+    test.equal(ipaddr.IPv6.parse('2001:db8::').prefixLengthFromSubnetMask(), null)
+    test.equal(ipaddr.IPv6.parse('ffff:0:0:ffff::').prefixLengthFromSubnetMask(), null)
+    test.equal(ipaddr.IPv6.parse('ffff:0:0:ffff::%z').prefixLengthFromSubnetMask(), null)
+    test.done()
+
+  'subnetMaskFromPrefixLength returns correct IPv4 subnet mask given prefix length': (test) ->
+
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(0), "0.0.0.0");
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(1), "128.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(2), "192.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(3), "224.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(4), "240.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(5), "248.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(6), "252.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(7), "254.0.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(8), "255.0.0.0");
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(9), "255.128.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(10), "255.192.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(11), "255.224.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(12), "255.240.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(13), "255.248.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(14), "255.252.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(15), "255.254.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(16), "255.255.0.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(17), "255.255.128.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(18), "255.255.192.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(19), "255.255.224.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(20), "255.255.240.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(21), "255.255.248.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(22), "255.255.252.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(23), "255.255.254.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(24), "255.255.255.0")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(25), "255.255.255.128")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(26), "255.255.255.192")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(27), "255.255.255.224")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(28), "255.255.255.240")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(29), "255.255.255.248")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(30), "255.255.255.252")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(31), "255.255.255.254")
+    test.equal(ipaddr.IPv4.subnetMaskFromPrefixLength(32), "255.255.255.255")
+    test.done()
+
+  'broadcastAddressFromCIDR returns correct IPv4 broadcast address': (test) ->
+    test.equal(ipaddr.IPv4.broadcastAddressFromCIDR("172.0.0.1/24"), "172.0.0.255")
+    test.equal(ipaddr.IPv4.broadcastAddressFromCIDR("172.0.0.1/26"), "172.0.0.63")
+    test.done()
+
+  'networkAddressFromCIDR returns correct IPv4 network address': (test) ->
+    test.equal(ipaddr.IPv4.networkAddressFromCIDR("172.0.0.1/24"), "172.0.0.0")
+    test.equal(ipaddr.IPv4.networkAddressFromCIDR("172.0.0.1/5"), "168.0.0.0")
+    test.done()
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/media-typer/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/media-typer/package.json
index d8781818e..a6954f63e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/media-typer/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/media-typer/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "media-typer@0.3.0",
-        "scope": null,
-        "escapedName": "media-typer",
-        "name": "media-typer",
-        "rawSpec": "0.3.0",
-        "spec": "0.3.0",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/type-is"
-    ]
-  ],
   "_from": "media-typer@0.3.0",
   "_id": "media-typer@0.3.0",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
   "_location": "/media-typer",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.21",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "media-typer@0.3.0",
-    "scope": null,
-    "escapedName": "media-typer",
     "name": "media-typer",
+    "escapedName": "media-typer",
     "rawSpec": "0.3.0",
-    "spec": "0.3.0",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "0.3.0"
   },
   "_requiredBy": [
     "/type-is"
   ],
   "_resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
   "_shasum": "8710d7af0aa626f8fffa1ce00168545263255748",
-  "_shrinkwrap": null,
   "_spec": "media-typer@0.3.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/type-is",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/type-is",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -47,18 +29,14 @@
   "bugs": {
     "url": "https://github.com/jshttp/media-typer/issues"
   },
-  "dependencies": {},
+  "bundleDependencies": false,
+  "deprecated": false,
   "description": "Simple RFC 6838 media type parser and formatter",
   "devDependencies": {
     "istanbul": "0.3.2",
     "mocha": "~1.21.4",
     "should": "~4.0.4"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "8710d7af0aa626f8fffa1ce00168545263255748",
-    "tarball": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -67,18 +45,9 @@
     "HISTORY.md",
     "index.js"
   ],
-  "gitHead": "d49d41ffd0bb5a0655fa44a59df2ec0bfc835b16",
-  "homepage": "https://github.com/jshttp/media-typer",
+  "homepage": "https://github.com/jshttp/media-typer#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "media-typer",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/media-typer.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/merge-descriptors/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/merge-descriptors/package.json
index 2f9bb580f..0d1aaae92 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/merge-descriptors/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/merge-descriptors/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "merge-descriptors@1.0.1",
-        "scope": null,
-        "escapedName": "merge-descriptors",
-        "name": "merge-descriptors",
-        "rawSpec": "1.0.1",
-        "spec": "1.0.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "merge-descriptors@1.0.1",
   "_id": "merge-descriptors@1.0.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
   "_location": "/merge-descriptors",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "merge-descriptors@1.0.1",
-    "scope": null,
-    "escapedName": "merge-descriptors",
     "name": "merge-descriptors",
+    "escapedName": "merge-descriptors",
     "rawSpec": "1.0.1",
-    "spec": "1.0.1",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "1.0.1"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
   "_shasum": "b00aaa556dd8b44568150ec9d1b953f3f90cbb61",
-  "_shrinkwrap": null,
   "_spec": "merge-descriptors@1.0.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Jonathan Ong",
     "email": "me@jongleberry.com",
@@ -48,6 +30,7 @@
   "bugs": {
     "url": "https://github.com/component/merge-descriptors/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -58,107 +41,21 @@
       "email": "grabbou@gmail.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Merge objects using descriptors",
   "devDependencies": {
     "istanbul": "0.4.1",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "b00aaa556dd8b44568150ec9d1b953f3f90cbb61",
-    "tarball": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz"
-  },
   "files": [
     "HISTORY.md",
     "LICENSE",
     "README.md",
     "index.js"
   ],
-  "gitHead": "f26c49c3b423b0b2ac31f6e32a84e1632f2d7ac2",
-  "homepage": "https://github.com/component/merge-descriptors",
+  "homepage": "https://github.com/component/merge-descriptors#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "anthonyshort",
-      "email": "antshort@gmail.com"
-    },
-    {
-      "name": "clintwood",
-      "email": "clint@anotherway.co.za"
-    },
-    {
-      "name": "dfcreative",
-      "email": "df.creative@gmail.com"
-    },
-    {
-      "name": "dominicbarnes",
-      "email": "dominic@dbarnes.info"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "ianstormtaylor",
-      "email": "ian@ianstormtaylor.com"
-    },
-    {
-      "name": "jonathanong",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "juliangruber",
-      "email": "julian@juliangruber.com"
-    },
-    {
-      "name": "mattmueller",
-      "email": "mattmuelle@gmail.com"
-    },
-    {
-      "name": "queckezz",
-      "email": "fabian.eichenberger@gmail.com"
-    },
-    {
-      "name": "stephenmathieson",
-      "email": "me@stephenmathieson.com"
-    },
-    {
-      "name": "thehydroimpulse",
-      "email": "dnfagnan@gmail.com"
-    },
-    {
-      "name": "timaschew",
-      "email": "timaschew@gmail.com"
-    },
-    {
-      "name": "timoxley",
-      "email": "secoif@gmail.com"
-    },
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "tootallnate",
-      "email": "nathan@tootallnate.net"
-    },
-    {
-      "name": "trevorgerhardt",
-      "email": "trevorgerhardt@gmail.com"
-    },
-    {
-      "name": "yields",
-      "email": "yields@icloud.com"
-    }
-  ],
   "name": "merge-descriptors",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/component/merge-descriptors.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/methods/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/methods/package.json
index 37770e53b..09a064e00 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/methods/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/methods/package.json
@@ -1,51 +1,34 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "methods@~1.1.2",
-        "scope": null,
-        "escapedName": "methods",
-        "name": "methods",
-        "rawSpec": "~1.1.2",
-        "spec": ">=1.1.2 <1.2.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "methods@>=1.1.2 <1.2.0",
+  "_from": "methods@~1.1.2",
   "_id": "methods@1.1.2",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
   "_location": "/methods",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "methods@~1.1.2",
-    "scope": null,
-    "escapedName": "methods",
     "name": "methods",
+    "escapedName": "methods",
     "rawSpec": "~1.1.2",
-    "spec": ">=1.1.2 <1.2.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.1.2"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
   "_shasum": "5529a4d67654134edcc5266656835b0f851afcee",
-  "_shrinkwrap": null,
   "_spec": "methods@~1.1.2",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "browser": {
     "http": false
   },
   "bugs": {
     "url": "https://github.com/jshttp/methods/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -62,17 +45,12 @@
       "url": "http://tjholowaychuk.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "HTTP methods that node supports",
   "devDependencies": {
     "istanbul": "0.4.1",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "5529a4d67654134edcc5266656835b0f851afcee",
-    "tarball": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -81,34 +59,13 @@
     "HISTORY.md",
     "LICENSE"
   ],
-  "gitHead": "25d257d913f1b94bd2d73581521ff72c81469140",
-  "homepage": "https://github.com/jshttp/methods",
+  "homepage": "https://github.com/jshttp/methods#readme",
   "keywords": [
     "http",
     "methods"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "jonathanong",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "methods",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/methods.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/HISTORY.md
index 27b2a1175..b2870c40e 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/HISTORY.md
@@ -1,139 +1,91 @@
+1.30.0 / 2017-08-27
+===================
+
+  * Add `application/vnd.ms-outlook`
+  * Add `application/x-arj`
+  * Add extension `.mjs` to `application/javascript`
+  * Add glTF types and extensions
+  * Add new upstream MIME types
+  * Add `text/x-org`
+  * Add VirtualBox MIME types
+  * Fix `source` records for `video/*` types that are IANA
+  * Update `font/opentype` to registered `font/otf`
+
+1.29.0 / 2017-07-10
+===================
+
+  * Add `application/fido.trusted-apps+json`
+  * Add extension `.wadl` to `application/vnd.sun.wadl+xml`
+  * Add new upstream MIME types
+  * Add `UTF-8` as default charset for `text/css`
+
+1.28.0 / 2017-05-14
+===================
+
+  * Add new upstream MIME types
+  * Add extension `.gz` to `application/gzip`
+  * Update extensions `.md` and `.markdown` to be `text/markdown`
+
+1.27.0 / 2017-03-16
+===================
+
+  * Add new upstream MIME types
+  * Add `image/apng` with extension `.apng`
+
 1.26.0 / 2017-01-14
 ===================
 
-  * Add `application/coap-payload`
-  * Add `application/cose`
-  * Add `application/cose-key`
-  * Add `application/cose-key-set`
-  * Add `application/mud+json`
-  * Add `application/trig`
-  * Add `application/vnd.dataresource+json`
-  * Add `application/vnd.hc+json`
-  * Add `application/vnd.tableschema+json`
-  * Add `application/yang-patch+json`
-  * Add `application/yang-patch+xml`
+  * Add new upstream MIME types
   * Add extension `.geojson` to `application/geo+json`
 
 1.25.0 / 2016-11-11
 ===================
 
-  * Add `application/dicom+json`
-  * Add `application/dicom+xml`
-  * Add `application/vnd.openstreetmap.data+xml`
-  * Add `application/vnd.tri.onesource`
-  * Add `application/yang-data+json`
-  * Add `application/yang-data+xml`
+  * Add new upstream MIME types
 
 1.24.0 / 2016-09-18
 ===================
 
-  * Add `application/clue_info+xml`
-  * Add `application/geo+json`
-  * Add `application/lgr+xml`
-  * Add `application/vnd.amazon.mobi8-ebook`
-  * Add `application/vnd.chess-pgn`
-  * Add `application/vnd.comicbook+zip`
-  * Add `application/vnd.d2l.coursepackage1p0+zip`
-  * Add `application/vnd.espass-espass+zip`
-  * Add `application/vnd.nearst.inv+json`
-  * Add `application/vnd.oma.lwm2m+json`
-  * Add `application/vnd.oma.lwm2m+tlv`
-  * Add `application/vnd.quarantainenet`
-  * Add `application/vnd.rar`
   * Add `audio/mp3`
-  * Add `image/dicom-rle`
-  * Add `image/emf`
-  * Add `image/jls`
-  * Add `image/wmf`
-  * Add `model/gltf+json`
-  * Add `text/vnd.ascii-art`
+  * Add new upstream MIME types
 
 1.23.0 / 2016-05-01
 ===================
 
-  * Add `application/efi`
-  * Add `application/vnd.3gpp.sms+xml`
-  * Add `application/vnd.3lightssoftware.imagescal`
-  * Add `application/vnd.coreos.ignition+json`
-  * Add `application/vnd.desmume.movie`
-  * Add `application/vnd.onepager`
-  * Add `application/vnd.vel+json`
-  * Add `text/prs.prop.logic`
-  * Add `video/encaprtp`
-  * Add `video/h265`
-  * Add `video/iso.segment`
-  * Add `video/raptorfec`
-  * Add `video/rtploopback`
-  * Add `video/vnd.radgamettools.bink`
-  * Add `video/vnd.radgamettools.smacker`
-  * Add `video/vp8`
+  * Add new upstream MIME types
   * Add extension `.3gpp` to `audio/3gpp`
 
 1.22.0 / 2016-02-15
 ===================
 
-  * Add `application/ppsp-tracker+json`
-  * Add `application/problem+json`
-  * Add `application/problem+xml`
-  * Add `application/vnd.hdt`
-  * Add `application/vnd.ms-printschematicket+xml`
-  * Add `model/vnd.rosette.annotated-data-model`
   * Add `text/slim`
   * Add extension `.rng` to `application/xml`
+  * Add new upstream MIME types
   * Fix extension of `application/dash+xml` to be `.mpd`
   * Update primary extension to `.m4a` for `audio/mp4`
 
 1.21.0 / 2016-01-06
 ===================
 
-  * Add `application/emergencycalldata.comment+xml`
-  * Add `application/emergencycalldata.deviceinfo+xml`
-  * Add `application/emergencycalldata.providerinfo+xml`
-  * Add `application/emergencycalldata.serviceinfo+xml`
-  * Add `application/emergencycalldata.subscriberinfo+xml`
-  * Add `application/vnd.filmit.zfc`
-  * Add `application/vnd.google-apps.document`
-  * Add `application/vnd.google-apps.presentation`
-  * Add `application/vnd.google-apps.spreadsheet`
-  * Add `application/vnd.mapbox-vector-tile`
-  * Add `application/vnd.ms-printdevicecapabilities+xml`
-  * Add `application/vnd.ms-windows.devicepairing`
-  * Add `application/vnd.ms-windows.nwprinting.oob`
-  * Add `application/vnd.tml`
-  * Add `audio/evs`
+  * Add Google document types
+  * Add new upstream MIME types
 
 1.20.0 / 2015-11-10
 ===================
 
-  * Add `application/cdni`
-  * Add `application/csvm+json`
-  * Add `application/rfc+xml`
-  * Add `application/vnd.3gpp.access-transfer-events+xml`
-  * Add `application/vnd.3gpp.srvcc-ext+xml`
-  * Add `application/vnd.ms-windows.wsd.oob`
-  * Add `application/vnd.oxli.countgraph`
-  * Add `application/vnd.pagerduty+json`
   * Add `text/x-suse-ymp`
+  * Add new upstream MIME types
 
 1.19.0 / 2015-09-17
 ===================
 
-  * Add `application/vnd.3gpp-prose-pc3ch+xml`
-  * Add `application/vnd.3gpp.srvcc-info+xml`
   * Add `application/vnd.apple.pkpass`
-  * Add `application/vnd.drive+json`
+  * Add new upstream MIME types
 
 1.18.0 / 2015-09-03
 ===================
 
-  * Add `application/pkcs12`
-  * Add `application/vnd.3gpp-prose+xml`
-  * Add `application/vnd.3gpp.mid-call+xml`
-  * Add `application/vnd.3gpp.state-and-event-info+xml`
-  * Add `application/vnd.anki`
-  * Add `application/vnd.firemonkeys.cloudcell`
-  * Add `application/vnd.openblox.game+xml`
-  * Add `application/vnd.openblox.game-binary`
+  * Add new upstream MIME types
 
 1.17.0 / 2015-08-13
 ===================
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/README.md
index 7662440bb..320c1c925 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/README.md
@@ -62,6 +62,18 @@ If unknown, every property could be `undefined`.
 To edit the database, only make PRs against `src/custom.json` or
 `src/custom-suffix.json`.
 
+The `src/custom.json` file is a JSON object with the MIME type as the keys
+and the values being an object with the following keys:
+
+- `compressible` - leave out if you don't know, otherwise `true`/`false` for
+  if the data represented by the time is typically compressible.
+- `extensions` - include an array of file extensions that are associated with
+  the type.
+- `notes` - human-readable notes about the type, typically what the type is.
+- `sources` - include an array of URLs of where the MIME type and the associated
+  extensions are sourced from. This needs to be a [primary source](https://en.wikipedia.org/wiki/Primary_source);
+  links to type aggregating sites and Wikipedia are _not acceptible_.
+
 To update the build, run `npm run build`.
 
 ## Adding Custom Media Types
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/db.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/db.json
index 400b9e1ad..0fc2a72fd 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/db.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/db.json
@@ -128,6 +128,9 @@
   "application/cbor": {
     "source": "iana"
   },
+  "application/cccex": {
+    "source": "iana"
+  },
   "application/ccmp+xml": {
     "source": "iana"
   },
@@ -312,9 +315,15 @@
   "application/emergencycalldata.comment+xml": {
     "source": "iana"
   },
+  "application/emergencycalldata.control+xml": {
+    "source": "iana"
+  },
   "application/emergencycalldata.deviceinfo+xml": {
     "source": "iana"
   },
+  "application/emergencycalldata.ecall.msd": {
+    "source": "iana"
+  },
   "application/emergencycalldata.providerinfo+xml": {
     "source": "iana"
   },
@@ -324,6 +333,9 @@
   "application/emergencycalldata.subscriberinfo+xml": {
     "source": "iana"
   },
+  "application/emergencycalldata.veds+xml": {
+    "source": "iana"
+  },
   "application/emma+xml": {
     "source": "iana",
     "extensions": ["emma"]
@@ -357,6 +369,9 @@
   "application/fdt+xml": {
     "source": "iana"
   },
+  "application/fido.trusted-apps+json": {
+    "compressible": true
+  },
   "application/fits": {
     "source": "iana"
   },
@@ -384,6 +399,12 @@
     "compressible": true,
     "extensions": ["geojson"]
   },
+  "application/geo+json-seq": {
+    "source": "iana"
+  },
+  "application/geoxacml+xml": {
+    "source": "iana"
+  },
   "application/gml+xml": {
     "source": "iana",
     "extensions": ["gml"]
@@ -398,7 +419,8 @@
   },
   "application/gzip": {
     "source": "iana",
-    "compressible": false
+    "compressible": false,
+    "extensions": ["gz"]
   },
   "application/h224": {
     "source": "iana"
@@ -482,7 +504,11 @@
     "source": "iana",
     "charset": "UTF-8",
     "compressible": true,
-    "extensions": ["js"]
+    "extensions": ["js","mjs"]
+  },
+  "application/jf2feed+json": {
+    "source": "iana",
+    "compressible": true
   },
   "application/jose": {
     "source": "iana"
@@ -668,6 +694,9 @@
   "application/mikey": {
     "source": "iana"
   },
+  "application/mmt-usd+xml": {
+    "source": "iana"
+  },
   "application/mods+xml": {
     "source": "iana",
     "extensions": ["mods"]
@@ -726,6 +755,12 @@
     "source": "iana",
     "extensions": ["mxf"]
   },
+  "application/n-quads": {
+    "source": "iana"
+  },
+  "application/n-triples": {
+    "source": "iana"
+  },
   "application/nasdata": {
     "source": "iana"
   },
@@ -789,6 +824,9 @@
   "application/parityfec": {
     "source": "iana"
   },
+  "application/passport": {
+    "source": "iana"
+  },
   "application/patch-ops-error+xml": {
     "source": "iana",
     "extensions": ["xer"]
@@ -965,6 +1003,15 @@
     "source": "iana",
     "extensions": ["rs"]
   },
+  "application/route-apd+xml": {
+    "source": "iana"
+  },
+  "application/route-s-tsid+xml": {
+    "source": "iana"
+  },
+  "application/route-usd+xml": {
+    "source": "iana"
+  },
   "application/rpki-ghostbusters": {
     "source": "iana",
     "extensions": ["gbr"]
@@ -973,6 +1020,9 @@
     "source": "iana",
     "extensions": ["mft"]
   },
+  "application/rpki-publication": {
+    "source": "iana"
+  },
   "application/rpki-roa": {
     "source": "iana",
     "extensions": ["roa"]
@@ -1227,6 +1277,9 @@
   "application/vividence.scriptfile": {
     "source": "apache"
   },
+  "application/vnd.1000minds.decision-model+xml": {
+    "source": "iana"
+  },
   "application/vnd.3gpp-prose+xml": {
     "source": "iana"
   },
@@ -1239,6 +1292,15 @@
   "application/vnd.3gpp.bsf+xml": {
     "source": "iana"
   },
+  "application/vnd.3gpp.gmop+xml": {
+    "source": "iana"
+  },
+  "application/vnd.3gpp.mcptt-info+xml": {
+    "source": "iana"
+  },
+  "application/vnd.3gpp.mcptt-mbms-usage-info+xml": {
+    "source": "iana"
+  },
   "application/vnd.3gpp.mid-call+xml": {
     "source": "iana"
   },
@@ -1400,6 +1462,10 @@
     "source": "iana",
     "compressible": true
   },
+  "application/vnd.apothekende.reservation+json": {
+    "source": "iana",
+    "compressible": true
+  },
   "application/vnd.apple.installer+xml": {
     "source": "iana",
     "extensions": ["mpkg"]
@@ -1446,9 +1512,15 @@
     "source": "iana",
     "compressible": true
   },
+  "application/vnd.bint.med-content": {
+    "source": "iana"
+  },
   "application/vnd.biopax.rdf+xml": {
     "source": "iana"
   },
+  "application/vnd.blink-idb-value-wrapper": {
+    "source": "iana"
+  },
   "application/vnd.blueice.multipass": {
     "source": "iana",
     "extensions": ["mpm"]
@@ -1476,6 +1548,10 @@
   "application/vnd.canon-lips": {
     "source": "iana"
   },
+  "application/vnd.capasystems-pg+json": {
+    "source": "iana",
+    "compressible": true
+  },
   "application/vnd.cendio.thinlinc.clientconf": {
     "source": "iana"
   },
@@ -1636,6 +1712,10 @@
     "source": "iana",
     "extensions": ["rdz"]
   },
+  "application/vnd.datapackage+json": {
+    "source": "iana",
+    "compressible": true
+  },
   "application/vnd.dataresource+json": {
     "source": "iana",
     "compressible": true
@@ -1815,6 +1895,12 @@
   "application/vnd.ecowin.seriesupdate": {
     "source": "iana"
   },
+  "application/vnd.efi.img": {
+    "source": "iana"
+  },
+  "application/vnd.efi.iso": {
+    "source": "iana"
+  },
   "application/vnd.emclient.accessrequest+xml": {
     "source": "iana"
   },
@@ -1927,6 +2013,15 @@
   "application/vnd.eudora.data": {
     "source": "iana"
   },
+  "application/vnd.evolv.ecig.profile": {
+    "source": "iana"
+  },
+  "application/vnd.evolv.ecig.settings": {
+    "source": "iana"
+  },
+  "application/vnd.evolv.ecig.theme": {
+    "source": "iana"
+  },
   "application/vnd.ezpix-album": {
     "source": "iana",
     "extensions": ["ez2"]
@@ -2222,6 +2317,10 @@
     "source": "iana",
     "extensions": ["sfd-hdstx"]
   },
+  "application/vnd.hyper-item+json": {
+    "source": "iana",
+    "compressible": true
+  },
   "application/vnd.hyperdrive+json": {
     "source": "iana",
     "compressible": true
@@ -2262,6 +2361,12 @@
     "source": "iana",
     "extensions": ["igl"]
   },
+  "application/vnd.imagemeter.folder+zip": {
+    "source": "iana"
+  },
+  "application/vnd.imagemeter.image+zip": {
+    "source": "iana"
+  },
   "application/vnd.immervision-ivp": {
     "source": "iana",
     "extensions": ["ivp"]
@@ -2480,6 +2585,10 @@
     "source": "iana",
     "extensions": ["sse"]
   },
+  "application/vnd.las.las+json": {
+    "source": "iana",
+    "compressible": true
+  },
   "application/vnd.las.las+xml": {
     "source": "iana",
     "extensions": ["lasxml"]
@@ -2587,6 +2696,9 @@
   "application/vnd.microsoft.portable-executable": {
     "source": "iana"
   },
+  "application/vnd.microsoft.windows.thumbnail-cache": {
+    "source": "iana"
+  },
   "application/vnd.miele+json": {
     "source": "iana",
     "compressible": true
@@ -2732,6 +2844,10 @@
     "source": "apache",
     "compressible": true
   },
+  "application/vnd.ms-outlook": {
+    "compressible": false,
+    "extensions": ["msg"]
+  },
   "application/vnd.ms-package.obfuscated-opentype": {
     "source": "apache"
   },
@@ -3059,6 +3175,9 @@
   "application/vnd.obn": {
     "source": "iana"
   },
+  "application/vnd.ocf+cbor": {
+    "source": "iana"
+  },
   "application/vnd.oftn.l10n+json": {
     "source": "iana",
     "compressible": true
@@ -3228,6 +3347,21 @@
   "application/vnd.onepager": {
     "source": "iana"
   },
+  "application/vnd.onepagertamp": {
+    "source": "iana"
+  },
+  "application/vnd.onepagertamx": {
+    "source": "iana"
+  },
+  "application/vnd.onepagertat": {
+    "source": "iana"
+  },
+  "application/vnd.onepagertatp": {
+    "source": "iana"
+  },
+  "application/vnd.onepagertatx": {
+    "source": "iana"
+  },
   "application/vnd.openblox.game+xml": {
     "source": "iana"
   },
@@ -3800,6 +3934,9 @@
     "source": "iana",
     "extensions": ["ipk"]
   },
+  "application/vnd.sigrok.session": {
+    "source": "iana"
+  },
   "application/vnd.simtech-mindmapper": {
     "source": "iana",
     "extensions": ["twd","twds"]
@@ -3882,7 +4019,9 @@
     "source": "iana"
   },
   "application/vnd.sun.wadl+xml": {
-    "source": "iana"
+    "source": "iana",
+    "compressible": true,
+    "extensions": ["wadl"]
   },
   "application/vnd.sun.xml.calc": {
     "source": "apache",
@@ -4326,6 +4465,10 @@
     "source": "apache",
     "extensions": ["dmg"]
   },
+  "application/x-arj": {
+    "compressible": false,
+    "extensions": ["arj"]
+  },
   "application/x-authorware-bin": {
     "source": "apache",
     "extensions": ["aab","x32","u32","vox"]
@@ -4789,6 +4932,38 @@
     "source": "apache",
     "extensions": ["ustar"]
   },
+  "application/x-virtualbox-hdd": {
+    "compressible": true,
+    "extensions": ["hdd"]
+  },
+  "application/x-virtualbox-ova": {
+    "compressible": true,
+    "extensions": ["ova"]
+  },
+  "application/x-virtualbox-ovf": {
+    "compressible": true,
+    "extensions": ["ovf"]
+  },
+  "application/x-virtualbox-vbox": {
+    "compressible": true,
+    "extensions": ["vbox"]
+  },
+  "application/x-virtualbox-vbox-extpack": {
+    "compressible": false,
+    "extensions": ["vbox-extpack"]
+  },
+  "application/x-virtualbox-vdi": {
+    "compressible": true,
+    "extensions": ["vdi"]
+  },
+  "application/x-virtualbox-vhd": {
+    "compressible": true,
+    "extensions": ["vhd"]
+  },
+  "application/x-virtualbox-vmdk": {
+    "compressible": true,
+    "extensions": ["vmdk"]
+  },
   "application/x-wais-source": {
     "source": "apache",
     "extensions": ["src"]
@@ -5156,6 +5331,18 @@
   "audio/lpc": {
     "source": "iana"
   },
+  "audio/melp": {
+    "source": "iana"
+  },
+  "audio/melp1200": {
+    "source": "iana"
+  },
+  "audio/melp2400": {
+    "source": "iana"
+  },
+  "audio/melp600": {
+    "source": "iana"
+  },
   "audio/midi": {
     "source": "apache",
     "extensions": ["mid","midi","kar","rmi"]
@@ -5395,6 +5582,9 @@
   "audio/vnd.octel.sbc": {
     "source": "iana"
   },
+  "audio/vnd.presonus.multitrack": {
+    "source": "iana"
+  },
   "audio/vnd.qcelp": {
     "source": "iana"
   },
@@ -5525,10 +5715,14 @@
     "source": "apache",
     "extensions": ["xyz"]
   },
-  "font/opentype": {
+  "font/otf": {
     "compressible": true,
     "extensions": ["otf"]
   },
+  "image/apng": {
+    "compressible": false,
+    "extensions": ["apng"]
+  },
   "image/bmp": {
     "source": "iana",
     "compressible": true,
@@ -5882,9 +6076,17 @@
   "message/vnd.wfa.wsc": {
     "source": "iana"
   },
+  "model/3mf": {
+    "source": "iana"
+  },
   "model/gltf+json": {
     "source": "iana",
-    "compressible": true
+    "compressible": true,
+    "extensions": ["gltf"]
+  },
+  "model/gltf-binary": {
+    "compressible": true,
+    "extensions": ["glb"]
   },
   "model/iges": {
     "source": "iana",
@@ -6015,6 +6217,9 @@
     "source": "iana",
     "compressible": false
   },
+  "multipart/vnd.bint.med-plus": {
+    "source": "iana"
+  },
   "multipart/voice-message": {
     "source": "iana"
   },
@@ -6044,6 +6249,7 @@
   },
   "text/css": {
     "source": "iana",
+    "charset": "UTF-8",
     "compressible": true,
     "extensions": ["css"]
   },
@@ -6102,7 +6308,9 @@
     "extensions": ["less"]
   },
   "text/markdown": {
-    "source": "iana"
+    "source": "iana",
+    "compressible": true,
+    "extensions": ["markdown","md"]
   },
   "text/mathml": {
     "source": "nginx",
@@ -6175,6 +6383,9 @@
   "text/slim": {
     "extensions": ["slim","slm"]
   },
+  "text/strings": {
+    "source": "iana"
+  },
   "text/stylus": {
     "extensions": ["stylus","styl"]
   },
@@ -6349,7 +6560,7 @@
   },
   "text/x-markdown": {
     "compressible": true,
-    "extensions": ["markdown","md","mkd"]
+    "extensions": ["mkd"]
   },
   "text/x-nfo": {
     "source": "apache",
@@ -6359,6 +6570,10 @@
     "source": "apache",
     "extensions": ["opml"]
   },
+  "text/x-org": {
+    "compressible": true,
+    "extensions": ["org"]
+  },
   "text/x-pascal": {
     "source": "apache",
     "extensions": ["p","pas"]
@@ -6409,266 +6624,266 @@
     "extensions": ["yaml","yml"]
   },
   "video/1d-interleaved-parityfec": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/3gpp": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["3gp","3gpp"]
   },
   "video/3gpp-tt": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/3gpp2": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["3g2"]
   },
   "video/bmpeg": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/bt656": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/celb": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/dv": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/encaprtp": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/h261": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["h261"]
   },
   "video/h263": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["h263"]
   },
   "video/h263-1998": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/h263-2000": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/h264": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["h264"]
   },
   "video/h264-rcdo": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/h264-svc": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/h265": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/iso.segment": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/jpeg": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["jpgv"]
   },
   "video/jpeg2000": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/jpm": {
     "source": "apache",
     "extensions": ["jpm","jpgm"]
   },
   "video/mj2": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["mj2","mjp2"]
   },
   "video/mp1s": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/mp2p": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/mp2t": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["ts"]
   },
   "video/mp4": {
-    "source": "apache",
+    "source": "iana",
     "compressible": false,
     "extensions": ["mp4","mp4v","mpg4"]
   },
   "video/mp4v-es": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/mpeg": {
-    "source": "apache",
+    "source": "iana",
     "compressible": false,
     "extensions": ["mpeg","mpg","mpe","m1v","m2v"]
   },
   "video/mpeg4-generic": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/mpv": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/nv": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/ogg": {
-    "source": "apache",
+    "source": "iana",
     "compressible": false,
     "extensions": ["ogv"]
   },
   "video/parityfec": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/pointer": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/quicktime": {
-    "source": "apache",
+    "source": "iana",
     "compressible": false,
     "extensions": ["qt","mov"]
   },
   "video/raptorfec": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/raw": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/rtp-enc-aescm128": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/rtploopback": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/rtx": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/smpte292m": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/ulpfec": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vc1": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.cctv": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.dece.hd": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvh","uvvh"]
   },
   "video/vnd.dece.mobile": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvm","uvvm"]
   },
   "video/vnd.dece.mp4": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.dece.pd": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvp","uvvp"]
   },
   "video/vnd.dece.sd": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvs","uvvs"]
   },
   "video/vnd.dece.video": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvv","uvvv"]
   },
   "video/vnd.directv.mpeg": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.directv.mpeg-tts": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.dlna.mpeg-tts": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.dvb.file": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["dvb"]
   },
   "video/vnd.fvt": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["fvt"]
   },
   "video/vnd.hns.video": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.1dparityfec-1010": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.1dparityfec-2005": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.2dparityfec-1010": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.2dparityfec-2005": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.ttsavc": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.iptvforum.ttsmpeg2": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.motorola.video": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.motorola.videop": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.mpegurl": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["mxu","m4u"]
   },
   "video/vnd.ms-playready.media.pyv": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["pyv"]
   },
   "video/vnd.nokia.interleaved-multimedia": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.nokia.videovoip": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.objectvideo": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.radgamettools.bink": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.radgamettools.smacker": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.sealed.mpeg1": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.sealed.mpeg4": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.sealed.swf": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.sealedmedia.softseal.mov": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/vnd.uvvu.mp4": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["uvu","uvvu"]
   },
   "video/vnd.vivo": {
-    "source": "apache",
+    "source": "iana",
     "extensions": ["viv"]
   },
   "video/vp8": {
-    "source": "apache"
+    "source": "iana"
   },
   "video/webm": {
     "source": "apache",
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/package.json
index 455fd36d2..7f1fad8f1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-db/package.json
@@ -1,54 +1,32 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "mime-db@~1.26.0",
-        "scope": null,
-        "escapedName": "mime-db",
-        "name": "mime-db",
-        "rawSpec": "~1.26.0",
-        "spec": ">=1.26.0 <1.27.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/mime-types"
-    ]
-  ],
-  "_from": "mime-db@>=1.26.0 <1.27.0",
-  "_id": "mime-db@1.26.0",
-  "_inCache": true,
+  "_from": "mime-db@~1.30.0",
+  "_id": "mime-db@1.30.0",
+  "_inBundle": false,
+  "_integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
   "_location": "/mime-db",
-  "_nodeVersion": "4.6.1",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/mime-db-1.26.0.tgz_1484453096877_0.39498970191925764"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.9",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "mime-db@~1.26.0",
-    "scope": null,
-    "escapedName": "mime-db",
+    "type": "range",
+    "registry": true,
+    "raw": "mime-db@~1.30.0",
     "name": "mime-db",
-    "rawSpec": "~1.26.0",
-    "spec": ">=1.26.0 <1.27.0",
-    "type": "range"
+    "escapedName": "mime-db",
+    "rawSpec": "~1.30.0",
+    "saveSpec": null,
+    "fetchSpec": "~1.30.0"
   },
   "_requiredBy": [
     "/compressible",
     "/mime-types"
   ],
-  "_resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz",
-  "_shasum": "eaffcd0e4fc6935cf8134da246e2e6c35305adff",
-  "_shrinkwrap": null,
-  "_spec": "mime-db@~1.26.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/mime-types",
+  "_resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+  "_shasum": "74c643da2dd9d6a45399963465b26d5ca7d71f01",
+  "_spec": "mime-db@~1.30.0",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/mime-types",
   "bugs": {
     "url": "https://github.com/jshttp/mime-db/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -65,28 +43,25 @@
       "url": "http://github.com/broofa"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Media Type Database",
   "devDependencies": {
-    "bluebird": "3.4.7",
+    "bluebird": "3.5.0",
     "co": "4.6.0",
     "cogent": "1.0.1",
-    "csv-parse": "1.1.9",
-    "eslint": "3.13.1",
-    "eslint-config-standard": "6.2.1",
-    "eslint-plugin-promise": "3.3.0",
-    "eslint-plugin-standard": "2.0.1",
+    "csv-parse": "1.2.1",
+    "eslint": "3.19.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",
     "gnode": "0.1.2",
-    "istanbul": "0.4.5",
     "mocha": "1.21.5",
-    "raw-body": "2.2.0",
+    "nyc": "11.1.0",
+    "raw-body": "2.3.0",
     "stream-to-array": "2.3.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "eaffcd0e4fc6935cf8134da246e2e6c35305adff",
-    "tarball": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -97,7 +72,6 @@
     "db.json",
     "index.js"
   ],
-  "gitHead": "1d9ff30e45b07a506a20f25df3a3c7106d219e24",
   "homepage": "https://github.com/jshttp/mime-db#readme",
   "keywords": [
     "mime",
@@ -109,19 +83,7 @@
     "charsets"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "mime-db",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/mime-db.git"
@@ -131,9 +93,9 @@
     "fetch": "gnode scripts/fetch-apache && gnode scripts/fetch-iana && gnode scripts/fetch-nginx",
     "lint": "eslint .",
     "test": "mocha --reporter spec --bail --check-leaks 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/",
+    "test-cov": "nyc --reporter=html --reporter=text npm test",
+    "test-travis": "nyc --reporter=text npm test",
     "update": "npm run fetch && npm run build"
   },
-  "version": "1.26.0"
+  "version": "1.30.0"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/HISTORY.md
index 85b59f007..7517c11a7 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/HISTORY.md
@@ -1,3 +1,34 @@
+2.1.17 / 2017-09-01
+===================
+
+  * deps: mime-db@~1.30.0
+    - Add `application/vnd.ms-outlook`
+    - Add `application/x-arj`
+    - Add extension `.mjs` to `application/javascript`
+    - Add glTF types and extensions
+    - Add new upstream MIME types
+    - Add `text/x-org`
+    - Add VirtualBox MIME types
+    - Fix `source` records for `video/*` types that are IANA
+    - Update `font/opentype` to registered `font/otf`
+
+2.1.16 / 2017-07-24
+===================
+
+  * deps: mime-db@~1.29.0
+    - Add `application/fido.trusted-apps+json`
+    - Add extension `.wadl` to `application/vnd.sun.wadl+xml`
+    - Add extension `.gz` to `application/gzip`
+    - Add new upstream MIME types
+    - Update extensions `.md` and `.markdown` to be `text/markdown`
+
+2.1.15 / 2017-03-23
+===================
+
+  * deps: mime-db@~1.27.0
+    - Add new mime types
+    - Add `image/apng`
+
 2.1.14 / 2017-01-14
 ===================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/README.md
index e77d615d3..571031c90 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/README.md
@@ -8,25 +8,30 @@
 
 The ultimate javascript content-type utility.
 
-Similar to [node-mime](https://github.com/broofa/node-mime), except:
+Similar to [the `mime` module](https://www.npmjs.com/package/mime), except:
 
-- __No fallbacks.__ Instead of naively returning the first available type, `mime-types` simply returns `false`,
-  so do `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
+- __No fallbacks.__ Instead of naively returning the first available type,
+  `mime-types` simply returns `false`, so do
+  `var type = mime.lookup('unrecognized') || 'application/octet-stream'`.
 - No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`.
-- Additional mime types are added such as jade and stylus via [mime-db](https://github.com/jshttp/mime-db)
 - No `.define()` functionality
+- Bug fixes for `.lookup(path)`
 
 Otherwise, the API is compatible.
 
 ## Install
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```sh
 $ npm install mime-types
 ```
 
 ## Adding Types
 
-All mime types are based on [mime-db](https://github.com/jshttp/mime-db),
+All mime types are based on [mime-db](https://www.npmjs.com/package/mime-db),
 so open a PR there if you'd like to add mime types.
 
 ## API
@@ -43,7 +48,7 @@ Lookup the content-type associated with a file.
 
 ```js
 mime.lookup('json')             // 'application/json'
-mime.lookup('.md')              // 'text/x-markdown'
+mime.lookup('.md')              // 'text/markdown'
 mime.lookup('file.html')        // 'text/html'
 mime.lookup('folder/file.js')   // 'application/javascript'
 mime.lookup('folder/.htaccess') // false
@@ -76,7 +81,7 @@ mime.extension('application/octet-stream') // 'bin'
 Lookup the implied default charset of a content-type.
 
 ```js
-mime.charset('text/x-markdown') // 'UTF-8'
+mime.charset('text/markdown') // 'UTF-8'
 ```
 
 ### var type = mime.types[extension]
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/index.js
index 9226ca584..b9f34d599 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/index.js
@@ -20,8 +20,8 @@ var extname = require('path').extname
  * @private
  */
 
-var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/
-var textTypeRegExp = /^text\//i
+var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/
+var TEXT_TYPE_REGEXP = /^text\//i
 
 /**
  * Module exports.
@@ -52,7 +52,7 @@ function charset (type) {
   }
 
   // TODO: use media-typer
-  var match = extractTypeRegExp.exec(type)
+  var match = EXTRACT_TYPE_REGEXP.exec(type)
   var mime = match && db[match[1].toLowerCase()]
 
   if (mime && mime.charset) {
@@ -60,7 +60,7 @@ function charset (type) {
   }
 
   // default text/* to utf-8
-  if (match && textTypeRegExp.test(match[1])) {
+  if (match && TEXT_TYPE_REGEXP.test(match[1])) {
     return 'UTF-8'
   }
 
@@ -110,7 +110,7 @@ function extension (type) {
   }
 
   // TODO: use media-typer
-  var match = extractTypeRegExp.exec(type)
+  var match = EXTRACT_TYPE_REGEXP.exec(type)
 
   // get extensions
   var exts = match && exports.extensions[match[1].toLowerCase()]
@@ -175,7 +175,7 @@ function populateMaps (extensions, types) {
         var to = preference.indexOf(mime.source)
 
         if (types[extension] !== 'application/octet-stream' &&
-          from > to || (from === to && types[extension].substr(0, 12) === 'application/')) {
+          (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) {
           // skip the remapping
           continue
         }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/package.json
index f87aaf79b..41409c13b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime-types/package.json
@@ -1,54 +1,32 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "mime-types@~2.1.11",
-        "scope": null,
-        "escapedName": "mime-types",
-        "name": "mime-types",
-        "rawSpec": "~2.1.11",
-        "spec": ">=2.1.11 <2.2.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/accepts"
-    ]
-  ],
-  "_from": "mime-types@>=2.1.11 <2.2.0",
-  "_id": "mime-types@2.1.14",
-  "_inCache": true,
+  "_from": "mime-types@~2.1.16",
+  "_id": "mime-types@2.1.17",
+  "_inBundle": false,
+  "_integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
   "_location": "/mime-types",
-  "_nodeVersion": "4.6.1",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/mime-types-2.1.14.tgz_1484458141358_0.7563668976072222"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.9",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "mime-types@~2.1.11",
-    "scope": null,
-    "escapedName": "mime-types",
+    "type": "range",
+    "registry": true,
+    "raw": "mime-types@~2.1.16",
     "name": "mime-types",
-    "rawSpec": "~2.1.11",
-    "spec": ">=2.1.11 <2.2.0",
-    "type": "range"
+    "escapedName": "mime-types",
+    "rawSpec": "~2.1.16",
+    "saveSpec": null,
+    "fetchSpec": "~2.1.16"
   },
   "_requiredBy": [
     "/accepts",
     "/type-is"
   ],
-  "_resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz",
-  "_shasum": "f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee",
-  "_shrinkwrap": null,
-  "_spec": "mime-types@~2.1.11",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/accepts",
+  "_resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+  "_shasum": "09d7a393f03e995a79f8af857b70a9e0ab16557a",
+  "_spec": "mime-types@~2.1.16",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/accepts",
   "bugs": {
     "url": "https://github.com/jshttp/mime-types/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -66,22 +44,20 @@
     }
   ],
   "dependencies": {
-    "mime-db": "~1.26.0"
+    "mime-db": "~1.30.0"
   },
+  "deprecated": false,
   "description": "The ultimate javascript content-type utility.",
   "devDependencies": {
-    "eslint": "3.13.1",
-    "eslint-config-standard": "6.2.1",
-    "eslint-plugin-promise": "3.4.0",
-    "eslint-plugin-standard": "2.0.1",
+    "eslint": "3.19.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",
     "istanbul": "0.4.5",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee",
-    "tarball": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -90,30 +66,13 @@
     "LICENSE",
     "index.js"
   ],
-  "gitHead": "d7d15e50fe6b3a2da79d855015d25efa50e9f157",
   "homepage": "https://github.com/jshttp/mime-types#readme",
   "keywords": [
     "mime",
     "types"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "fishrock123",
-      "email": "fishrock123@rocketmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "mime-types",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/mime-types.git"
@@ -124,5 +83,5 @@
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/test.js",
     "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot test/test.js"
   },
-  "version": "2.1.14"
+  "version": "2.1.17"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/.npmignore b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/.npmignore
deleted file mode 100644
index e69de29bb..000000000
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/LICENSE
index 451fc4550..d3f46f7e1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/LICENSE
@@ -1,3 +1,5 @@
+The MIT License (MIT)
+
 Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/build/test.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/build/test.js
index 58b9ba7c8..010c42b98 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/build/test.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/build/test.js
@@ -43,15 +43,18 @@ assert.equal(undefined, mime.extension('unrecognized'));
 
 assert.equal('application/font-woff', mime.lookup('file.woff'));
 assert.equal('application/octet-stream', mime.lookup('file.buffer'));
-assert.equal('audio/mp4', mime.lookup('file.m4a'));
-assert.equal('font/opentype', mime.lookup('file.otf'));
+// TODO: Uncomment once #157 is resolved
+// assert.equal('audio/mp4', mime.lookup('file.m4a'));
+assert.equal('font/otf', mime.lookup('file.otf'));
 
 //
 // Test charsets
 //
 
 assert.equal('UTF-8', mime.charsets.lookup('text/plain'));
-assert.equal(undefined, mime.charsets.lookup(mime.types.js));
+assert.equal('UTF-8', mime.charsets.lookup(mime.types.js));
+assert.equal('UTF-8', mime.charsets.lookup(mime.types.json));
+assert.equal(undefined, mime.charsets.lookup(mime.types.bin));
 assert.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
 
 console.log('\nAll tests passed');
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/mime.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/mime.js
index 341b6a5c4..d7efbde70 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/mime.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/mime.js
@@ -22,9 +22,9 @@ Mime.prototype.define = function (map) {
   for (var type in map) {
     var exts = map[type];
     for (var i = 0; i < exts.length; i++) {
-      if (process.env.DEBUG_MIME && this.types[exts]) {
-        console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
-          this.types[exts] + ' to ' + type);
+      if (process.env.DEBUG_MIME && this.types[exts[i]]) {
+        console.warn((this._loading || "define()").replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
+          this.types[exts[i]] + ' to ' + type);
       }
 
       this.types[exts[i]] = type;
@@ -67,7 +67,7 @@ Mime.prototype.load = function(file) {
  * Lookup a mime type based on extension
  */
 Mime.prototype.lookup = function(path, fallback) {
-  var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase();
+  var ext = path.replace(/^.*[\.\/\\]/, '').toLowerCase();
 
   return this.types[ext] || fallback || this.default_type;
 };
@@ -101,7 +101,7 @@ mime.Mime = Mime;
 mime.charsets = {
   lookup: function(mimeType, fallback) {
     // Assume text types are utf8
-    return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
+    return (/^text\/|^application\/(javascript|json)/).test(mimeType) ? 'UTF-8' : fallback;
   }
 };
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/package.json
index 453bdd76a..4684b8817 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "mime@1.3.4",
-        "scope": null,
-        "escapedName": "mime",
-        "name": "mime",
-        "rawSpec": "1.3.4",
-        "spec": "1.3.4",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send"
-    ]
-  ],
-  "_from": "mime@1.3.4",
-  "_id": "mime@1.3.4",
-  "_inCache": true,
+  "_from": "mime@1.4.1",
+  "_id": "mime@1.4.1",
+  "_inBundle": false,
+  "_integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
   "_location": "/mime",
-  "_npmUser": {
-    "name": "broofa",
-    "email": "robert@broofa.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "mime@1.3.4",
-    "scope": null,
-    "escapedName": "mime",
+    "type": "version",
+    "registry": true,
+    "raw": "mime@1.4.1",
     "name": "mime",
-    "rawSpec": "1.3.4",
-    "spec": "1.3.4",
-    "type": "version"
+    "escapedName": "mime",
+    "rawSpec": "1.4.1",
+    "saveSpec": null,
+    "fetchSpec": "1.4.1"
   },
   "_requiredBy": [
     "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
-  "_shasum": "115f9e3b6b3daf2959983cb38f149a2d40eb5d53",
-  "_shrinkwrap": null,
-  "_spec": "mime@1.3.4",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send",
+  "_resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+  "_shasum": "121f9ebc49e3766f311a76e1fa1c8003c4b03aa6",
+  "_spec": "mime@1.4.1",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/send",
   "author": {
     "name": "Robert Kieffer",
     "email": "robert@broofa.com",
@@ -51,6 +33,7 @@
   "bugs": {
     "url": "https://github.com/broofa/node-mime/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Benjamin Thomas",
@@ -59,41 +42,19 @@
     }
   ],
   "dependencies": {},
+  "deprecated": false,
   "description": "A comprehensive library for mime-type mapping",
   "devDependencies": {
-    "mime-db": "^1.2.0"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "115f9e3b6b3daf2959983cb38f149a2d40eb5d53",
-    "tarball": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz"
+    "mime-db": "1.30.0"
   },
-  "gitHead": "1628f6e0187095009dcef4805c3a49706f137974",
-  "homepage": "https://github.com/broofa/node-mime",
+  "homepage": "https://github.com/broofa/node-mime#readme",
   "keywords": [
     "util",
     "mime"
   ],
-  "licenses": [
-    {
-      "type": "MIT",
-      "url": "https://raw.github.com/broofa/node-mime/master/LICENSE"
-    }
-  ],
+  "license": "MIT",
   "main": "mime.js",
-  "maintainers": [
-    {
-      "name": "broofa",
-      "email": "robert@broofa.com"
-    },
-    {
-      "name": "bentomas",
-      "email": "benjamin@benjaminthomas.org"
-    }
-  ],
   "name": "mime",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "url": "git+https://github.com/broofa/node-mime.git",
     "type": "git"
@@ -102,5 +63,5 @@
     "prepublish": "node build/build.js > types.json",
     "test": "node build/test.js"
   },
-  "version": "1.3.4"
+  "version": "1.4.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/types.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/types.json
index c674b1c8f..5369cd1ca 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/types.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/mime/types.json
@@ -1 +1 @@
-{"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomsvc+xml":["atomsvc"],"application/ccxml+xml":["ccxml"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mdp"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma"],"application/emma+xml":["emma"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/font-tdpfr":["pfr"],"application/font-woff":["woff"],"application/font-woff2":["woff2"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/java-archive":["jar"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/prs.cww":["cww"],"application/pskc+xml":["pskcxml"],"application/rdf+xml":["rdf"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/voicexml+xml":["vxml"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":["dmg"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["deb","udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-otf":["otf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-ttf":["ttf","ttc"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-install-instructions":["install"],"application/x-iso9660-image":["iso"],"application/x-java-jnlp-file":["jnlp"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdownload":["exe","dll","com","bat","msi"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["wmf","wmz","emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-nzb":["nzb"],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["rar"],"application/x-research-info-systems":["ris"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["obj"],"application/x-ustar":["ustar"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt"],"application/x-xfig":["fig"],"application/x-xliff+xml":["xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"application/xaml+xml":["xaml"],"application/xcap-diff+xml":["xdf"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xml":["xml","xsl","xsd"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/adpcm":["adp"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mp4":["mp4a","m4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/webm":["weba"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-wav":["wav"],"audio/xm":["xm"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"font/opentype":["otf"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/g3fax":["g3"],"image/gif":["gif"],"image/ief":["ief"],"image/jpeg":["jpeg","jpg","jpe"],"image/ktx":["ktx"],"image/png":["png"],"image/prs.btif":["btif"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/tiff":["tiff","tif"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":["sub"],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/webp":["webp"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["ico"],"image/x-mrsid-image":["sid"],"image/x-pcx":["pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/rfc822":["eml","mime"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.vtu":["vtu"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["x3db","x3dbz"],"model/x3d+vrml":["x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee"],"text/css":["css"],"text/csv":["csv"],"text/hjson":["hjson"],"text/html":["html","htm"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/prs.lines.tag":["dsc"],"text/richtext":["rtx"],"text/sgml":["sgml","sgm"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/vtt":["vtt"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["markdown","md","mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-pascal":["p","pas"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/jpeg":["jpgv"],"video/jpm":["jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/webm":["webm"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]}
+{"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomsvc+xml":["atomsvc"],"application/bdoc":["bdoc"],"application/ccxml+xml":["ccxml"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma"],"application/emma+xml":["emma"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/font-tdpfr":["pfr"],"application/font-woff":["woff"],"application/font-woff2":["woff2"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/prs.cww":["cww"],"application/pskc+xml":["pskcxml"],"application/rdf+xml":["rdf"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.apple.pkpass":["pkpass"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-apps.document":["gdoc"],"application/vnd.google-apps.presentation":["gslides"],"application/vnd.google-apps.spreadsheet":["gsheet"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.hydrostatix.sof-data":["sfd-hdstx"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-outlook":["msg"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.n-gage.symbian.install":["n-gage"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.wadl+xml":["wadl"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/voicexml+xml":["vxml"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":["dmg"],"application/x-arj":["arj"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bdoc":["bdoc"],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-cocoa":["cco"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["deb","udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-otf":["otf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-ttf":["ttf","ttc"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-httpd-php":["php"],"application/x-install-instructions":["install"],"application/x-iso9660-image":["iso"],"application/x-java-archive-diff":["jardiff"],"application/x-java-jnlp-file":["jnlp"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-makeself":["run"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdos-program":["exe"],"application/x-msdownload":["exe","dll","com","bat","msi"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["wmf","wmz","emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-ns-proxy-autoconfig":["pac"],"application/x-nzb":["nzb"],"application/x-perl":["pl","pm"],"application/x-pilot":["prc","pdb"],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["rar"],"application/x-redhat-package-manager":["rpm"],"application/x-research-info-systems":["ris"],"application/x-sea":["sea"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl","tk"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["obj"],"application/x-ustar":["ustar"],"application/x-virtualbox-hdd":["hdd"],"application/x-virtualbox-ova":["ova"],"application/x-virtualbox-ovf":["ovf"],"application/x-virtualbox-vbox":["vbox"],"application/x-virtualbox-vbox-extpack":["vbox-extpack"],"application/x-virtualbox-vdi":["vdi"],"application/x-virtualbox-vhd":["vhd"],"application/x-virtualbox-vmdk":["vmdk"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt","pem"],"application/x-xfig":["fig"],"application/x-xliff+xml":["xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"application/xaml+xml":["xaml"],"application/xcap-diff+xml":["xdf"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["3gpp"],"audio/adpcm":["adp"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mp3":["mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/wav":["wav"],"audio/wave":["wav"],"audio/webm":["weba"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-m4a":["m4a"],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-realaudio":["ra"],"audio/x-wav":["wav"],"audio/xm":["xm"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"font/otf":["otf"],"image/apng":["apng"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/g3fax":["g3"],"image/gif":["gif"],"image/ief":["ief"],"image/jpeg":["jpeg","jpg","jpe"],"image/ktx":["ktx"],"image/png":["png"],"image/prs.btif":["btif"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/tiff":["tiff","tif"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":["sub"],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/webp":["webp"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["ico"],"image/x-jng":["jng"],"image/x-mrsid-image":["sid"],"image/x-ms-bmp":["bmp"],"image/x-pcx":["pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/rfc822":["eml","mime"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.vtu":["vtu"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["x3db","x3dbz"],"model/x3d+vrml":["x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/hjson":["hjson"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/prs.lines.tag":["dsc"],"text/richtext":["rtx"],"text/rtf":["rtf"],"text/sgml":["sgml","sgm"],"text/slim":["slim","slm"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/vtt":["vtt"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-org":["org"],"text/x-pascal":["p","pas"],"text/x-processing":["pde"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-suse-ymp":["ymp"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"text/xml":["xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/jpeg":["jpgv"],"video/jpm":["jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/webm":["webm"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/.npmignore b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/.npmignore
deleted file mode 100644
index d1aa0ce42..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules
-test
-History.md
-Makefile
-component.json
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/History.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/History.md
deleted file mode 100644
index 32fdfc176..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/History.md
+++ /dev/null
@@ -1,66 +0,0 @@
-
-0.7.1 / 2015-04-20
-==================
-
-  * prevent extraordinary long inputs (@evilpacket)
-  * Fixed broken readme link
-
-0.7.0 / 2014-11-24
-==================
-
- * add time abbreviations, updated tests and readme for the new units
- * fix example in the readme.
- * add LICENSE file
-
-0.6.2 / 2013-12-05
-==================
-
- * Adding repository section to package.json to suppress warning from NPM.
-
-0.6.1 / 2013-05-10
-==================
-
-  * fix singularization [visionmedia]
-
-0.6.0 / 2013-03-15
-==================
-
-  * fix minutes
-
-0.5.1 / 2013-02-24
-==================
-
-  * add component namespace
-
-0.5.0 / 2012-11-09
-==================
-
-  * add short formatting as default and .long option
-  * add .license property to component.json
-  * add version to component.json
-
-0.4.0 / 2012-10-22
-==================
-
-  * add rounding to fix crazy decimals
-
-0.3.0 / 2012-09-07
-==================
-
-  * fix `ms(<String>)` [visionmedia]
-
-0.2.0 / 2012-09-03
-==================
-
-  * add component.json [visionmedia]
-  * add days support [visionmedia]
-  * add hours support [visionmedia]
-  * add minutes support [visionmedia]
-  * add seconds support [visionmedia]
-  * add ms string support [visionmedia]
-  * refactor tests to facilitate ms(number) [visionmedia]
-
-0.1.0 / 2012-03-07
-==================
-
-  * Initial release
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/LICENSE
deleted file mode 100644
index 6c07561b6..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Guillermo Rauch <rauchg@gmail.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/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/README.md
index 9b4fd0358..84a9974cc 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/README.md
@@ -1,4 +1,11 @@
-# ms.js: miliseconds conversion utility
+# ms
+
+[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)
+[![Slack Channel](http://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)
+
+Use this package to easily convert various time formats to milliseconds.
+
+## Examples
 
 ```js
 ms('2 days')  // 172800000
@@ -8,28 +15,37 @@ ms('2.5 hrs') // 9000000
 ms('2h')      // 7200000
 ms('1m')      // 60000
 ms('5s')      // 5000
+ms('1y')      // 31557600000
 ms('100')     // 100
 ```
 
+### Convert from milliseconds
+
 ```js
 ms(60000)             // "1m"
 ms(2 * 60000)         // "2m"
 ms(ms('10 hours'))    // "10h"
 ```
 
+### Time format written-out
+
 ```js
 ms(60000, { long: true })             // "1 minute"
 ms(2 * 60000, { long: true })         // "2 minutes"
 ms(ms('10 hours'), { long: true })    // "10 hours"
 ```
 
-- Node/Browser compatible. Published as [`ms`](https://www.npmjs.org/package/ms) in [NPM](http://nodejs.org/download).
+## Features
+
+- Works both in [node](https://nodejs.org) and in the browser.
 - If a number is supplied to `ms`, a string with a unit is returned.
-- If a string that contains the number is supplied, it returns it as
-a number (e.g: it returns `100` for `'100'`).
-- If you pass a string with a number and a valid unit, the number of
-equivalent ms is returned.
+- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).
+- If you pass a string with a number and a valid unit, the number of equivalent ms is returned.
+
+## Caught a bug?
 
-## License
+1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
+2. Link the package to the global module directory: `npm link`
+3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!
 
-MIT
+As always, you can run the tests using: `npm test`
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/index.js
index 4f9277169..6a522b16b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/index.js
@@ -16,17 +16,24 @@ var y = d * 365.25;
  *  - `long` verbose formatting [false]
  *
  * @param {String|Number} val
- * @param {Object} options
+ * @param {Object} [options]
+ * @throws {Error} throw an error if val is not a non-empty string or a number
  * @return {String|Number}
  * @api public
  */
 
-module.exports = function(val, options){
+module.exports = function(val, options) {
   options = options || {};
-  if ('string' == typeof val) return parse(val);
-  return options.long
-    ? long(val)
-    : short(val);
+  var type = typeof val;
+  if (type === 'string' && val.length > 0) {
+    return parse(val);
+  } else if (type === 'number' && isNaN(val) === false) {
+    return options.long ? fmtLong(val) : fmtShort(val);
+  }
+  throw new Error(
+    'val is not a non-empty string or a valid number. val=' +
+      JSON.stringify(val)
+  );
 };
 
 /**
@@ -38,10 +45,16 @@ module.exports = function(val, options){
  */
 
 function parse(str) {
-  str = '' + str;
-  if (str.length > 10000) return;
-  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
-  if (!match) return;
+  str = String(str);
+  if (str.length > 100) {
+    return;
+  }
+  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
+    str
+  );
+  if (!match) {
+    return;
+  }
   var n = parseFloat(match[1]);
   var type = (match[2] || 'ms').toLowerCase();
   switch (type) {
@@ -79,6 +92,8 @@ function parse(str) {
     case 'msec':
     case 'ms':
       return n;
+    default:
+      return undefined;
   }
 }
 
@@ -90,11 +105,19 @@ function parse(str) {
  * @api private
  */
 
-function short(ms) {
-  if (ms >= 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';
+function fmtShort(ms) {
+  if (ms >= 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';
 }
 
@@ -106,12 +129,12 @@ function short(ms) {
  * @api private
  */
 
-function long(ms) {
-  return plural(ms, d, 'day')
-    || plural(ms, h, 'hour')
-    || plural(ms, m, 'minute')
-    || plural(ms, s, 'second')
-    || ms + ' ms';
+function fmtLong(ms) {
+  return plural(ms, d, 'day') ||
+    plural(ms, h, 'hour') ||
+    plural(ms, m, 'minute') ||
+    plural(ms, s, 'second') ||
+    ms + ' ms';
 }
 
 /**
@@ -119,7 +142,11 @@ function long(ms) {
  */
 
 function plural(ms, n, name) {
-  if (ms < n) return;
-  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
+  if (ms < n) {
+    return;
+  }
+  if (ms < n * 1.5) {
+    return Math.floor(ms / n) + ' ' + name;
+  }
   return Math.ceil(ms / n) + ' ' + name + 's';
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/package.json
index 9b315a026..07d07249b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/ms/package.json
@@ -1,82 +1,70 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "ms@0.7.1",
-        "scope": null,
-        "escapedName": "ms",
-        "name": "ms",
-        "rawSpec": "0.7.1",
-        "spec": "0.7.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/debug"
-    ]
-  ],
-  "_from": "ms@0.7.1",
-  "_id": "ms@0.7.1",
-  "_inCache": true,
+  "_from": "ms@2.0.0",
+  "_id": "ms@2.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
   "_location": "/ms",
-  "_nodeVersion": "0.12.2",
-  "_npmUser": {
-    "name": "rauchg",
-    "email": "rauchg@gmail.com"
-  },
-  "_npmVersion": "2.7.5",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "ms@0.7.1",
-    "scope": null,
-    "escapedName": "ms",
+    "type": "version",
+    "registry": true,
+    "raw": "ms@2.0.0",
     "name": "ms",
-    "rawSpec": "0.7.1",
-    "spec": "0.7.1",
-    "type": "version"
+    "escapedName": "ms",
+    "rawSpec": "2.0.0",
+    "saveSpec": null,
+    "fetchSpec": "2.0.0"
   },
   "_requiredBy": [
-    "/debug"
+    "/debug",
+    "/send"
   ],
-  "_resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
-  "_shasum": "9cd13c03adbff25b65effde7ce864ee952017098",
-  "_shrinkwrap": null,
-  "_spec": "ms@0.7.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/debug",
+  "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+  "_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
+  "_spec": "ms@2.0.0",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/debug",
   "bugs": {
-    "url": "https://github.com/guille/ms.js/issues"
-  },
-  "component": {
-    "scripts": {
-      "ms/index.js": "index.js"
-    }
+    "url": "https://github.com/zeit/ms/issues"
   },
-  "dependencies": {},
-  "description": "Tiny ms conversion utility",
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Tiny milisecond conversion utility",
   "devDependencies": {
-    "expect.js": "*",
-    "mocha": "*",
-    "serve": "*"
+    "eslint": "3.19.0",
+    "expect.js": "0.3.1",
+    "husky": "0.13.3",
+    "lint-staged": "3.4.1",
+    "mocha": "3.4.1"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "9cd13c03adbff25b65effde7ce864ee952017098",
-    "tarball": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
-  },
-  "gitHead": "713dcf26d9e6fd9dbc95affe7eff9783b7f1b909",
-  "homepage": "https://github.com/guille/ms.js",
-  "main": "./index",
-  "maintainers": [
-    {
-      "name": "rauchg",
-      "email": "rauchg@gmail.com"
+  "eslintConfig": {
+    "extends": "eslint:recommended",
+    "env": {
+      "node": true,
+      "es6": true
     }
+  },
+  "files": [
+    "index.js"
   ],
+  "homepage": "https://github.com/zeit/ms#readme",
+  "license": "MIT",
+  "lint-staged": {
+    "*.js": [
+      "npm run lint",
+      "prettier --single-quote --write",
+      "git add"
+    ]
+  },
+  "main": "./index",
   "name": "ms",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
-    "url": "git://github.com/guille/ms.js.git"
+    "url": "git+https://github.com/zeit/ms.git"
+  },
+  "scripts": {
+    "lint": "eslint lib/* bin/*",
+    "precommit": "lint-staged",
+    "test": "mocha tests.js"
   },
-  "scripts": {},
-  "version": "0.7.1"
+  "version": "2.0.0"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/negotiator/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/negotiator/package.json
index 9ebb1b820..c37cdf47f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/negotiator/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/negotiator/package.json
@@ -1,53 +1,31 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "negotiator@0.6.1",
-        "scope": null,
-        "escapedName": "negotiator",
-        "name": "negotiator",
-        "rawSpec": "0.6.1",
-        "spec": "0.6.1",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/accepts"
-    ]
-  ],
   "_from": "negotiator@0.6.1",
   "_id": "negotiator@0.6.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
   "_location": "/negotiator",
-  "_nodeVersion": "4.4.3",
-  "_npmOperationalInternal": {
-    "host": "packages-16-east.internal.npmjs.com",
-    "tmp": "tmp/negotiator-0.6.1.tgz_1462250848695_0.027451182017102838"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.1",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "negotiator@0.6.1",
-    "scope": null,
-    "escapedName": "negotiator",
     "name": "negotiator",
+    "escapedName": "negotiator",
     "rawSpec": "0.6.1",
-    "spec": "0.6.1",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "0.6.1"
   },
   "_requiredBy": [
     "/accepts"
   ],
   "_resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
   "_shasum": "2b327184e8992101177b28563fb5e7102acd0ca9",
-  "_shrinkwrap": null,
   "_spec": "negotiator@0.6.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/accepts",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/accepts",
   "bugs": {
     "url": "https://github.com/jshttp/negotiator/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -63,17 +41,12 @@
       "url": "http://blog.izs.me/"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "HTTP content negotiation",
   "devDependencies": {
     "istanbul": "0.4.3",
     "mocha": "~1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "2b327184e8992101177b28563fb5e7102acd0ca9",
-    "tarball": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -84,7 +57,6 @@
     "index.js",
     "README.md"
   ],
-  "gitHead": "751c381c32707f238143cd65d78520e16f4ef9e5",
   "homepage": "https://github.com/jshttp/negotiator#readme",
   "keywords": [
     "http",
@@ -95,23 +67,7 @@
     "accept-charset"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "federomero",
-      "email": "federomero@gmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "negotiator",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/negotiator.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/nopt/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/nopt/package.json
index 2880f1662..19cb67bba 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/nopt/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/nopt/package.json
@@ -1,46 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "nopt@^3.0.6",
-        "scope": null,
-        "escapedName": "nopt",
-        "name": "nopt",
-        "rawSpec": "^3.0.6",
-        "spec": ">=3.0.6 <4.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser"
-    ]
-  ],
-  "_from": "nopt@>=3.0.6 <4.0.0",
+  "_from": "nopt@^3.0.6",
   "_id": "nopt@3.0.6",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
   "_location": "/nopt",
-  "_nodeVersion": "4.2.1",
-  "_npmUser": {
-    "name": "othiym23",
-    "email": "ogd@aoaioxxysz.net"
-  },
-  "_npmVersion": "2.14.10",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "nopt@^3.0.6",
-    "scope": null,
-    "escapedName": "nopt",
     "name": "nopt",
+    "escapedName": "nopt",
     "rawSpec": "^3.0.6",
-    "spec": ">=3.0.6 <4.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^3.0.6"
   },
   "_requiredBy": [
     "/"
   ],
   "_resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
   "_shasum": "c6465dbf08abcd4db359317f79ac68a646b28ff9",
-  "_shrinkwrap": null,
   "_spec": "nopt@^3.0.6",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser",
+  "_where": "/Users/auso/cordova/cordova-browser",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me",
@@ -52,39 +33,19 @@
   "bugs": {
     "url": "https://github.com/npm/nopt/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
     "abbrev": "1"
   },
+  "deprecated": false,
   "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.",
   "devDependencies": {
     "tap": "^1.2.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "c6465dbf08abcd4db359317f79ac68a646b28ff9",
-    "tarball": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz"
-  },
-  "gitHead": "10a750c9bb99c1950160353459e733ac2aa18cb6",
   "homepage": "https://github.com/npm/nopt#readme",
   "license": "ISC",
   "main": "lib/nopt.js",
-  "maintainers": [
-    {
-      "name": "isaacs",
-      "email": "i@izs.me"
-    },
-    {
-      "name": "othiym23",
-      "email": "ogd@aoaioxxysz.net"
-    },
-    {
-      "name": "zkat",
-      "email": "kat@sykosomatic.org"
-    }
-  ],
   "name": "nopt",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/npm/nopt.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-finished/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-finished/package.json
index 21dce8ca7..a2c529ca7 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-finished/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-finished/package.json
@@ -1,50 +1,34 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "on-finished@~2.3.0",
-        "scope": null,
-        "escapedName": "on-finished",
-        "name": "on-finished",
-        "rawSpec": "~2.3.0",
-        "spec": ">=2.3.0 <2.4.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "on-finished@>=2.3.0 <2.4.0",
+  "_from": "on-finished@~2.3.0",
   "_id": "on-finished@2.3.0",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
   "_location": "/on-finished",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "on-finished@~2.3.0",
-    "scope": null,
-    "escapedName": "on-finished",
     "name": "on-finished",
+    "escapedName": "on-finished",
     "rawSpec": "~2.3.0",
-    "spec": ">=2.3.0 <2.4.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~2.3.0"
   },
   "_requiredBy": [
+    "/body-parser",
     "/express",
     "/finalhandler",
     "/send"
   ],
   "_resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
   "_shasum": "20f1336481b083cd75337992a16971aa2d906947",
-  "_shrinkwrap": null,
   "_spec": "on-finished@~2.3.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/jshttp/on-finished/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -59,16 +43,12 @@
   "dependencies": {
     "ee-first": "1.1.1"
   },
+  "deprecated": false,
   "description": "Execute a callback when a request closes, finishes, or errors",
   "devDependencies": {
     "istanbul": "0.3.9",
     "mocha": "2.2.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "20f1336481b083cd75337992a16971aa2d906947",
-    "tarball": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz"
-  },
   "engines": {
     "node": ">= 0.8"
   },
@@ -77,22 +57,9 @@
     "LICENSE",
     "index.js"
   ],
-  "gitHead": "34babcb58126a416fcf5205768204f2e12699dda",
-  "homepage": "https://github.com/jshttp/on-finished",
+  "homepage": "https://github.com/jshttp/on-finished#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "on-finished",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/on-finished.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-headers/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-headers/package.json
index d1f04be7e..00e08f067 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-headers/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/on-headers/package.json
@@ -1,45 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "on-headers@~1.0.1",
-        "scope": null,
-        "escapedName": "on-headers",
-        "name": "on-headers",
-        "rawSpec": "~1.0.1",
-        "spec": ">=1.0.1 <1.1.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression"
-    ]
-  ],
-  "_from": "on-headers@>=1.0.1 <1.1.0",
+  "_from": "on-headers@~1.0.1",
   "_id": "on-headers@1.0.1",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
   "_location": "/on-headers",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "on-headers@~1.0.1",
-    "scope": null,
-    "escapedName": "on-headers",
     "name": "on-headers",
+    "escapedName": "on-headers",
     "rawSpec": "~1.0.1",
-    "spec": ">=1.0.1 <1.1.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.0.1"
   },
   "_requiredBy": [
     "/compression"
   ],
   "_resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
   "_shasum": "928f5d0f470d49342651ea6794b0857c100693f7",
-  "_shrinkwrap": null,
   "_spec": "on-headers@~1.0.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/compression",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/compression",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -47,18 +29,15 @@
   "bugs": {
     "url": "https://github.com/jshttp/on-headers/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {},
+  "deprecated": false,
   "description": "Execute a listener when a response is about to write headers",
   "devDependencies": {
     "istanbul": "0.3.21",
     "mocha": "2.3.3",
     "supertest": "1.1.0"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "928f5d0f470d49342651ea6794b0857c100693f7",
-    "tarball": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz"
-  },
   "engines": {
     "node": ">= 0.8"
   },
@@ -68,8 +47,7 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "ab0156a979d72353cfe666cccb3639e016b00280",
-  "homepage": "https://github.com/jshttp/on-headers",
+  "homepage": "https://github.com/jshttp/on-headers#readme",
   "keywords": [
     "event",
     "headers",
@@ -77,19 +55,7 @@
     "onheaders"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    }
-  ],
   "name": "on-headers",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/on-headers.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/HISTORY.md
index 395041ee6..4803393a9 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/HISTORY.md
@@ -1,3 +1,9 @@
+1.3.2 / 2017-09-09
+==================
+
+  * perf: reduce overhead for full URLs
+  * perf: unroll the "fast-path" `RegExp`
+
 1.3.1 / 2016-01-17
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/LICENSE
index ec7dfe7be..27653d3db 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/LICENSE
@@ -2,7 +2,7 @@
 (The MIT License)
 
 Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
-Copyright (c) 2014 Douglas Christopher Wilson <doug@somethingdoug.com>
+Copyright (c) 2014-2017 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
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/README.md
index f4796ebbc..a5ccc51b0 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/README.md
@@ -10,7 +10,11 @@ Parse a URL with memoization.
 
 ## Install
 
-```bash
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
 $ npm install parseurl
 ```
 
@@ -40,68 +44,68 @@ does not change will return a cached parsed object, rather than parsing again.
 ```bash
 $ npm run-script bench
 
-> parseurl@1.3.1 bench nodejs-parseurl
+> parseurl@1.3.2 bench nodejs-parseurl
 > node benchmark/index.js
 
+  http_parser@2.7.0
+  node@4.8.4
+  v8@4.5.103.47
+  uv@1.9.1
+  zlib@1.2.11
+  ares@1.10.1-DEV
+  icu@56.1
+  modules@46
+  openssl@1.0.2k
+
 > node benchmark/fullurl.js
 
   Parsing URL "http://localhost:8888/foo/bar?user=tj&pet=fluffy"
 
-  1 test completed.
-  2 tests completed.
   3 tests completed.
 
-  fasturl   x 1,290,780 ops/sec ±0.46% (195 runs sampled)
-  nativeurl x    56,401 ops/sec ±0.22% (196 runs sampled)
-  parseurl  x    55,231 ops/sec ±0.22% (194 runs sampled)
+  fasturl   x 1,246,766 ops/sec ±0.74% (188 runs sampled)
+  nativeurl x    91,536 ops/sec ±0.54% (189 runs sampled)
+  parseurl  x    90,645 ops/sec ±0.38% (189 runs sampled)
 
 > node benchmark/pathquery.js
 
   Parsing URL "/foo/bar?user=tj&pet=fluffy"
 
-  1 test completed.
-  2 tests completed.
   3 tests completed.
 
-  fasturl   x 1,986,668 ops/sec ±0.27% (190 runs sampled)
-  nativeurl x    98,740 ops/sec ±0.21% (195 runs sampled)
-  parseurl  x 2,628,171 ops/sec ±0.36% (195 runs sampled)
+  fasturl   x 2,077,650 ops/sec ±0.69% (186 runs sampled)
+  nativeurl x   638,669 ops/sec ±0.67% (189 runs sampled)
+  parseurl  x 2,431,842 ops/sec ±0.71% (189 runs sampled)
 
 > node benchmark/samerequest.js
 
   Parsing URL "/foo/bar?user=tj&pet=fluffy" on same request object
 
-  1 test completed.
-  2 tests completed.
   3 tests completed.
 
-  fasturl   x  2,184,468 ops/sec ±0.40% (194 runs sampled)
-  nativeurl x     99,437 ops/sec ±0.71% (194 runs sampled)
-  parseurl  x 10,498,005 ops/sec ±0.61% (186 runs sampled)
+  fasturl   x  2,135,391 ops/sec ±0.69% (188 runs sampled)
+  nativeurl x    672,809 ops/sec ±3.83% (186 runs sampled)
+  parseurl  x 11,604,947 ops/sec ±0.70% (189 runs sampled)
 
 > node benchmark/simplepath.js
 
   Parsing URL "/foo/bar"
 
-  1 test completed.
-  2 tests completed.
   3 tests completed.
 
-  fasturl   x 4,535,825 ops/sec ±0.27% (191 runs sampled)
-  nativeurl x    98,769 ops/sec ±0.54% (191 runs sampled)
-  parseurl  x 4,164,865 ops/sec ±0.34% (192 runs sampled)
+  fasturl   x 4,961,391 ops/sec ±0.97% (186 runs sampled)
+  nativeurl x   914,931 ops/sec ±0.83% (186 runs sampled)
+  parseurl  x 7,559,196 ops/sec ±0.66% (188 runs sampled)
 
 > node benchmark/slash.js
 
   Parsing URL "/"
 
-  1 test completed.
-  2 tests completed.
   3 tests completed.
 
-  fasturl   x 4,908,405 ops/sec ±0.42% (191 runs sampled)
-  nativeurl x   100,945 ops/sec ±0.59% (188 runs sampled)
-  parseurl  x 4,333,208 ops/sec ±0.27% (194 runs sampled)
+  fasturl   x  4,053,379 ops/sec ±0.91% (187 runs sampled)
+  nativeurl x    963,999 ops/sec ±0.58% (189 runs sampled)
+  parseurl  x 11,516,143 ops/sec ±0.58% (188 runs sampled)
 ```
 
 ## License
@@ -111,7 +115,7 @@ $ npm run-script bench
 [npm-image]: https://img.shields.io/npm/v/parseurl.svg
 [npm-url]: https://npmjs.org/package/parseurl
 [node-version-image]: https://img.shields.io/node/v/parseurl.svg
-[node-version-url]: http://nodejs.org/download/
+[node-version-url]: https://nodejs.org/en/download/
 [travis-image]: https://img.shields.io/travis/pillarjs/parseurl/master.svg
 [travis-url]: https://travis-ci.org/pillarjs/parseurl
 [coveralls-image]: https://img.shields.io/coveralls/pillarjs/parseurl/master.svg
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/index.js
index 56cc6ec7e..603eabe12 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/index.js
@@ -1,7 +1,7 @@
 /*!
  * parseurl
  * Copyright(c) 2014 Jonathan Ong
- * Copyright(c) 2014 Douglas Christopher Wilson
+ * Copyright(c) 2014-2017 Douglas Christopher Wilson
  * MIT Licensed
  */
 
@@ -9,6 +9,7 @@
 
 /**
  * Module dependencies.
+ * @private
  */
 
 var url = require('url')
@@ -16,14 +17,8 @@ var parse = url.parse
 var Url = url.Url
 
 /**
- * Pattern for a simple path case.
- * See: https://github.com/joyent/node/pull/7878
- */
-
-var simplePathRegExp = /^(\/\/?(?!\/)[^\?#\s]*)(\?[^#\s]*)?$/
-
-/**
- * Exports.
+ * Module exports.
+ * @public
  */
 
 module.exports = parseurl
@@ -34,10 +29,10 @@ module.exports.original = originalurl
  *
  * @param {ServerRequest} req
  * @return {Object}
- * @api public
+ * @public
  */
 
-function parseurl(req) {
+function parseurl (req) {
   var url = req.url
 
   if (url === undefined) {
@@ -56,7 +51,7 @@ function parseurl(req) {
   parsed = fastparse(url)
   parsed._raw = url
 
-  return req._parsedUrl = parsed
+  return (req._parsedUrl = parsed)
 };
 
 /**
@@ -64,10 +59,10 @@ function parseurl(req) {
  *
  * @param {ServerRequest} req
  * @return {Object}
- * @api public
+ * @public
  */
 
-function originalurl(req) {
+function originalurl (req) {
   var url = req.originalUrl
 
   if (typeof url !== 'string') {
@@ -86,7 +81,7 @@ function originalurl(req) {
   parsed = fastparse(url)
   parsed._raw = url
 
-  return req._parsedOriginalUrl = parsed
+  return (req._parsedOriginalUrl = parsed)
 };
 
 /**
@@ -94,31 +89,52 @@ function originalurl(req) {
  *
  * @param {string} str
  * @return {Object}
- * @api private
+ * @private
  */
 
-function fastparse(str) {
-  // Try fast path regexp
-  // See: https://github.com/joyent/node/pull/7878
-  var simplePath = typeof str === 'string' && simplePathRegExp.exec(str)
-
-  // Construct simple URL
-  if (simplePath) {
-    var pathname = simplePath[1]
-    var search = simplePath[2] || null
-    var url = Url !== undefined
-      ? new Url()
-      : {}
-    url.path = str
-    url.href = str
-    url.pathname = pathname
-    url.search = search
-    url.query = search && search.substr(1)
-
-    return url
+function fastparse (str) {
+  if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
+    return parse(str)
   }
 
-  return parse(str)
+  var pathname = str
+  var query = null
+  var search = null
+
+  // This takes the regexp from https://github.com/joyent/node/pull/7878
+  // Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
+  // And unrolls it into a for loop
+  for (var i = 1; i < str.length; i++) {
+    switch (str.charCodeAt(i)) {
+      case 0x3f: /* ?  */
+        if (search === null) {
+          pathname = str.substring(0, i)
+          query = str.substring(i + 1)
+          search = str.substring(i)
+        }
+        break
+      case 0x09: /* \t */
+      case 0x0a: /* \n */
+      case 0x0c: /* \f */
+      case 0x0d: /* \r */
+      case 0x20: /*    */
+      case 0x23: /* #  */
+      case 0xa0:
+      case 0xfeff:
+        return parse(str)
+    }
+  }
+
+  var url = Url !== undefined
+    ? new Url()
+    : {}
+  url.path = str
+  url.href = str
+  url.pathname = pathname
+  url.query = query
+  url.search = search
+
+  return url
 }
 
 /**
@@ -127,12 +143,12 @@ function fastparse(str) {
  * @param {string} url
  * @param {object} parsedUrl
  * @return {boolean}
- * @api private
+ * @private
  */
 
-function fresh(url, parsedUrl) {
-  return typeof parsedUrl === 'object'
-    && parsedUrl !== null
-    && (Url === undefined || parsedUrl instanceof Url)
-    && parsedUrl._raw === url
+function fresh (url, parsedUrl) {
+  return typeof parsedUrl === 'object' &&
+    parsedUrl !== null &&
+    (Url === undefined || parsedUrl instanceof Url) &&
+    parsedUrl._raw === url
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/package.json
index 9117781ab..0e16fee45 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/parseurl/package.json
@@ -1,73 +1,58 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "parseurl@~1.3.1",
-        "scope": null,
-        "escapedName": "parseurl",
-        "name": "parseurl",
-        "rawSpec": "~1.3.1",
-        "spec": ">=1.3.1 <1.4.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "parseurl@>=1.3.1 <1.4.0",
-  "_id": "parseurl@1.3.1",
-  "_inCache": true,
+  "_from": "parseurl@~1.3.2",
+  "_id": "parseurl@1.3.2",
+  "_inBundle": false,
+  "_integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
   "_location": "/parseurl",
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "parseurl@~1.3.1",
-    "scope": null,
-    "escapedName": "parseurl",
+    "type": "range",
+    "registry": true,
+    "raw": "parseurl@~1.3.2",
     "name": "parseurl",
-    "rawSpec": "~1.3.1",
-    "spec": ">=1.3.1 <1.4.0",
-    "type": "range"
+    "escapedName": "parseurl",
+    "rawSpec": "~1.3.2",
+    "saveSpec": null,
+    "fetchSpec": "~1.3.2"
   },
   "_requiredBy": [
     "/express",
+    "/finalhandler",
     "/serve-static"
   ],
-  "_resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
-  "_shasum": "c8ab8c9223ba34888aa64a297b28853bec18da56",
-  "_shrinkwrap": null,
-  "_spec": "parseurl@~1.3.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
-  "author": {
-    "name": "Jonathan Ong",
-    "email": "me@jongleberry.com",
-    "url": "http://jongleberry.com"
-  },
+  "_resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+  "_shasum": "fc289d4ed8993119460c156253262cdc8de65bf3",
+  "_spec": "parseurl@~1.3.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/pillarjs/parseurl/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
       "email": "doug@somethingdoug.com"
+    },
+    {
+      "name": "Jonathan Ong",
+      "email": "me@jongleberry.com",
+      "url": "http://jongleberry.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "parse a url with memoization",
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
-    "benchmark": "2.0.0",
+    "benchmark": "2.1.4",
+    "eslint": "3.19.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",
     "fast-url-parser": "1.1.3",
-    "istanbul": "0.4.2",
-    "mocha": "~1.21.5"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "c8ab8c9223ba34888aa64a297b28853bec18da56",
-    "tarball": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz"
+    "istanbul": "0.4.5",
+    "mocha": "2.5.3"
   },
   "engines": {
     "node": ">= 0.8"
@@ -78,47 +63,19 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "6d22d376d75b927ab2b5347ce3a1d6735133dd43",
-  "homepage": "https://github.com/pillarjs/parseurl",
+  "homepage": "https://github.com/pillarjs/parseurl#readme",
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "mscdex",
-      "email": "mscdex@mscdex.net"
-    },
-    {
-      "name": "fishrock123",
-      "email": "fishrock123@rocketmail.com"
-    },
-    {
-      "name": "defunctzombie",
-      "email": "shtylman@gmail.com"
-    }
-  ],
   "name": "parseurl",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/pillarjs/parseurl.git"
   },
   "scripts": {
     "bench": "node benchmark/index.js",
+    "lint": "eslint .",
     "test": "mocha --check-leaks --bail --reporter spec test/",
     "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/",
     "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/"
   },
-  "version": "1.3.1"
+  "version": "1.3.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/path-to-regexp/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/path-to-regexp/package.json
index 59fa7b808..c12138646 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/path-to-regexp/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/path-to-regexp/package.json
@@ -1,213 +1,53 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "path-to-regexp@0.1.7",
-        "scope": null,
-        "escapedName": "path-to-regexp",
-        "name": "path-to-regexp",
-        "rawSpec": "0.1.7",
-        "spec": "0.1.7",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
   "_from": "path-to-regexp@0.1.7",
   "_id": "path-to-regexp@0.1.7",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
   "_location": "/path-to-regexp",
-  "_nodeVersion": "2.3.3",
-  "_npmUser": {
-    "name": "blakeembrey",
-    "email": "hello@blakeembrey.com"
-  },
-  "_npmVersion": "2.13.2",
   "_phantomChildren": {},
   "_requested": {
+    "type": "version",
+    "registry": true,
     "raw": "path-to-regexp@0.1.7",
-    "scope": null,
-    "escapedName": "path-to-regexp",
     "name": "path-to-regexp",
+    "escapedName": "path-to-regexp",
     "rawSpec": "0.1.7",
-    "spec": "0.1.7",
-    "type": "version"
+    "saveSpec": null,
+    "fetchSpec": "0.1.7"
   },
   "_requiredBy": [
     "/express"
   ],
   "_resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
   "_shasum": "df604178005f522f15eb4490e7247a1bfaa67f8c",
-  "_shrinkwrap": null,
   "_spec": "path-to-regexp@0.1.7",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/component/path-to-regexp/issues"
   },
+  "bundleDependencies": false,
   "component": {
     "scripts": {
       "path-to-regexp": "index.js"
     }
   },
-  "dependencies": {},
+  "deprecated": false,
   "description": "Express style path to RegExp utility",
   "devDependencies": {
     "istanbul": "^0.2.6",
     "mocha": "^1.17.1"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "df604178005f522f15eb4490e7247a1bfaa67f8c",
-    "tarball": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
-  },
   "files": [
     "index.js",
     "LICENSE"
   ],
-  "gitHead": "039118d6c3c186d3f176c73935ca887a32a33d93",
   "homepage": "https://github.com/component/path-to-regexp#readme",
   "keywords": [
     "express",
     "regexp"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    },
-    {
-      "name": "hughsk",
-      "email": "hughskennedy@gmail.com"
-    },
-    {
-      "name": "timaschew",
-      "email": "timaschew@gmail.com"
-    },
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "dominicbarnes",
-      "email": "dominic@dbarnes.info"
-    },
-    {
-      "name": "tootallnate",
-      "email": "nathan@tootallnate.net"
-    },
-    {
-      "name": "rauchg",
-      "email": "rauchg@gmail.com"
-    },
-    {
-      "name": "retrofox",
-      "email": "rdsuarez@gmail.com"
-    },
-    {
-      "name": "coreh",
-      "email": "thecoreh@gmail.com"
-    },
-    {
-      "name": "forbeslindesay",
-      "email": "forbes@lindesay.co.uk"
-    },
-    {
-      "name": "kelonye",
-      "email": "kelonyemitchel@gmail.com"
-    },
-    {
-      "name": "mattmueller",
-      "email": "mattmuelle@gmail.com"
-    },
-    {
-      "name": "yields",
-      "email": "yields@icloud.com"
-    },
-    {
-      "name": "anthonyshort",
-      "email": "antshort@gmail.com"
-    },
-    {
-      "name": "ianstormtaylor",
-      "email": "ian@ianstormtaylor.com"
-    },
-    {
-      "name": "cristiandouce",
-      "email": "cristian@gravityonmars.com"
-    },
-    {
-      "name": "swatinem",
-      "email": "arpad.borsos@googlemail.com"
-    },
-    {
-      "name": "stagas",
-      "email": "gstagas@gmail.com"
-    },
-    {
-      "name": "amasad",
-      "email": "amjad.masad@gmail.com"
-    },
-    {
-      "name": "juliangruber",
-      "email": "julian@juliangruber.com"
-    },
-    {
-      "name": "calvinfo",
-      "email": "calvin@calv.info"
-    },
-    {
-      "name": "blakeembrey",
-      "email": "hello@blakeembrey.com"
-    },
-    {
-      "name": "timoxley",
-      "email": "secoif@gmail.com"
-    },
-    {
-      "name": "jonathanong",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "queckezz",
-      "email": "fabian.eichenberger@gmail.com"
-    },
-    {
-      "name": "nami-doc",
-      "email": "vendethiel@hotmail.fr"
-    },
-    {
-      "name": "clintwood",
-      "email": "clint@anotherway.co.za"
-    },
-    {
-      "name": "thehydroimpulse",
-      "email": "dnfagnan@gmail.com"
-    },
-    {
-      "name": "stephenmathieson",
-      "email": "me@stephenmathieson.com"
-    },
-    {
-      "name": "trevorgerhardt",
-      "email": "trevorgerhardt@gmail.com"
-    },
-    {
-      "name": "dfcreative",
-      "email": "df.creative@gmail.com"
-    },
-    {
-      "name": "defunctzombie",
-      "email": "shtylman@gmail.com"
-    }
-  ],
   "name": "path-to-regexp",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/component/path-to-regexp.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/HISTORY.md
index ac845a09a..c1c8205b6 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/HISTORY.md
@@ -1,3 +1,34 @@
+2.0.2 / 2017-09-24
+==================
+
+  * deps: forwarded@~0.1.2
+    - perf: improve header parsing
+    - perf: reduce overhead when no `X-Forwarded-For` header
+
+2.0.1 / 2017-09-10
+==================
+
+  * deps: forwarded@~0.1.1
+    - Fix trimming leading / trailing OWS
+    - perf: hoist regular expression
+  * deps: ipaddr.js@1.5.2
+
+2.0.0 / 2017-08-08
+==================
+
+  * Drop support for Node.js below 0.10
+
+1.1.5 / 2017-07-25
+==================
+
+  * Fix array argument being altered
+  * deps: ipaddr.js@1.4.0
+
+1.1.4 / 2017-03-24
+==================
+
+  * deps: ipaddr.js@1.3.0
+
 1.1.3 / 2017-01-14
 ==================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/README.md
index 1bffc764e..22d7e14f2 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/README.md
@@ -10,12 +10,18 @@ Determine address of proxied request
 
 ## Install
 
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
 ```sh
 $ npm install proxy-addr
 ```
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var proxyaddr = require('proxy-addr')
 ```
@@ -28,15 +34,19 @@ The `trust` argument is a function that returns `true` if you trust
 the address, `false` if you don't. The closest untrusted address is
 returned.
 
+<!-- eslint-disable no-undef -->
+
 ```js
-proxyaddr(req, function(addr){ return addr === '127.0.0.1' })
-proxyaddr(req, function(addr, i){ return i < 1 })
+proxyaddr(req, function (addr) { return addr === '127.0.0.1' })
+proxyaddr(req, function (addr, i) { return i < 1 })
 ```
 
 The `trust` arugment may also be a single IP address string or an
 array of trusted addresses, as plain IP addresses, CIDR-formatted
 strings, or IP/netmask strings.
 
+<!-- eslint-disable no-undef -->
+
 ```js
 proxyaddr(req, '127.0.0.1')
 proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])
@@ -46,6 +56,8 @@ proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])
 This module also supports IPv6. Your IPv6 addresses will be normalized
 automatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).
 
+<!-- eslint-disable no-undef -->
+
 ```js
 proxyaddr(req, '::1')
 proxyaddr(req, ['::1/128', 'fe80::/10'])
@@ -58,6 +70,8 @@ not have to specify both `::ffff:a00:1` and `10.0.0.1`.
 As a convenience, this module also takes certain pre-defined names
 in addition to IP addresses, which expand into IP addresses:
 
+<!-- eslint-disable no-undef -->
+
 ```js
 proxyaddr(req, 'loopback')
 proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])
@@ -82,6 +96,8 @@ Return all the addresses of the request, optionally stopping at the
 first untrusted. This array is ordered from closest to furthest
 (i.e. `arr[0] === req.connection.remoteAddress`).
 
+<!-- eslint-disable no-undef -->
+
 ```js
 proxyaddr.all(req)
 ```
@@ -89,6 +105,8 @@ proxyaddr.all(req)
 The optional `trust` argument takes the same arguments as `trust`
 does in `proxyaddr(req, trust)`.
 
+<!-- eslint-disable no-undef -->
+
 ```js
 proxyaddr.all(req, 'loopback')
 ```
@@ -99,9 +117,11 @@ Compiles argument `val` into a `trust` function. This function takes
 the same arguments as `trust` does in `proxyaddr(req, trust)` and
 returns a function suitable for `proxyaddr(req, trust)`.
 
+<!-- eslint-disable no-undef, no-unused-vars -->
+
 ```js
 var trust = proxyaddr.compile('localhost')
-var addr  = proxyaddr(req, trust)
+var addr = proxyaddr(req, trust)
 ```
 
 This function is meant to be optimized for use against every request.
@@ -127,7 +147,7 @@ $ npm run-script bench
 [npm-image]: https://img.shields.io/npm/v/proxy-addr.svg
 [npm-url]: https://npmjs.org/package/proxy-addr
 [node-version-image]: https://img.shields.io/node/v/proxy-addr.svg
-[node-version-url]: http://nodejs.org/download/
+[node-version-url]: https://nodejs.org/en/download/
 [travis-image]: https://img.shields.io/travis/jshttp/proxy-addr/master.svg
 [travis-url]: https://travis-ci.org/jshttp/proxy-addr
 [coveralls-image]: https://img.shields.io/coveralls/jshttp/proxy-addr/master.svg
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/index.js
index 0b3cf0b2e..50c561f7d 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/index.js
@@ -8,36 +8,40 @@
 
 /**
  * Module exports.
+ * @public
  */
 
-module.exports = proxyaddr;
-module.exports.all = alladdrs;
-module.exports.compile = compile;
+module.exports = proxyaddr
+module.exports.all = alladdrs
+module.exports.compile = compile
 
 /**
  * Module dependencies.
+ * @private
  */
 
-var forwarded = require('forwarded');
-var ipaddr = require('ipaddr.js');
+var forwarded = require('forwarded')
+var ipaddr = require('ipaddr.js')
 
 /**
  * Variables.
+ * @private
  */
 
-var digitre = /^[0-9]+$/;
-var isip = ipaddr.isValid;
-var parseip = ipaddr.parse;
+var DIGIT_REGEXP = /^[0-9]+$/
+var isip = ipaddr.isValid
+var parseip = ipaddr.parse
 
 /**
  * Pre-defined IP ranges.
+ * @private
  */
 
-var ipranges = {
+var IP_RANGES = {
   linklocal: ['169.254.0.0/16', 'fe80::/10'],
   loopback: ['127.0.0.1/8', '::1/128'],
   uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']
-};
+}
 
 /**
  * Get all addresses in the request, optionally stopping
@@ -45,164 +49,166 @@ var ipranges = {
  *
  * @param {Object} request
  * @param {Function|Array|String} [trust]
- * @api public
+ * @public
  */
 
-function alladdrs(req, trust) {
+function alladdrs (req, trust) {
   // get addresses
-  var addrs = forwarded(req);
+  var addrs = forwarded(req)
 
   if (!trust) {
     // Return all addresses
-    return addrs;
+    return addrs
   }
 
   if (typeof trust !== 'function') {
-    trust = compile(trust);
+    trust = compile(trust)
   }
 
   for (var i = 0; i < addrs.length - 1; i++) {
-    if (trust(addrs[i], i)) continue;
+    if (trust(addrs[i], i)) continue
 
-    addrs.length = i + 1;
+    addrs.length = i + 1
   }
 
-  return addrs;
+  return addrs
 }
 
 /**
  * Compile argument into trust function.
  *
  * @param {Array|String} val
- * @api private
+ * @private
  */
 
-function compile(val) {
+function compile (val) {
   if (!val) {
-    throw new TypeError('argument is required');
+    throw new TypeError('argument is required')
   }
 
-  var trust = typeof val === 'string'
-    ? [val]
-    : val;
+  var trust
 
-  if (!Array.isArray(trust)) {
-    throw new TypeError('unsupported trust argument');
+  if (typeof val === 'string') {
+    trust = [val]
+  } else if (Array.isArray(val)) {
+    trust = val.slice()
+  } else {
+    throw new TypeError('unsupported trust argument')
   }
 
   for (var i = 0; i < trust.length; i++) {
-    val = trust[i];
+    val = trust[i]
 
-    if (!ipranges.hasOwnProperty(val)) {
-      continue;
+    if (!IP_RANGES.hasOwnProperty(val)) {
+      continue
     }
 
     // Splice in pre-defined range
-    val = ipranges[val];
-    trust.splice.apply(trust, [i, 1].concat(val));
-    i += val.length - 1;
+    val = IP_RANGES[val]
+    trust.splice.apply(trust, [i, 1].concat(val))
+    i += val.length - 1
   }
 
-  return compileTrust(compileRangeSubnets(trust));
+  return compileTrust(compileRangeSubnets(trust))
 }
 
 /**
  * Compile `arr` elements into range subnets.
  *
  * @param {Array} arr
- * @api private
+ * @private
  */
 
-function compileRangeSubnets(arr) {
-  var rangeSubnets = new Array(arr.length);
+function compileRangeSubnets (arr) {
+  var rangeSubnets = new Array(arr.length)
 
   for (var i = 0; i < arr.length; i++) {
-    rangeSubnets[i] = parseipNotation(arr[i]);
+    rangeSubnets[i] = parseipNotation(arr[i])
   }
 
-  return rangeSubnets;
+  return rangeSubnets
 }
 
 /**
  * Compile range subnet array into trust function.
  *
  * @param {Array} rangeSubnets
- * @api private
+ * @private
  */
 
-function compileTrust(rangeSubnets) {
+function compileTrust (rangeSubnets) {
   // Return optimized function based on length
-  var len = rangeSubnets.length;
+  var len = rangeSubnets.length
   return len === 0
     ? trustNone
     : len === 1
     ? trustSingle(rangeSubnets[0])
-    : trustMulti(rangeSubnets);
+    : trustMulti(rangeSubnets)
 }
 
 /**
  * Parse IP notation string into range subnet.
  *
  * @param {String} note
- * @api private
+ * @private
  */
 
-function parseipNotation(note) {
-  var pos = note.lastIndexOf('/');
+function parseipNotation (note) {
+  var pos = note.lastIndexOf('/')
   var str = pos !== -1
     ? note.substring(0, pos)
-    : note;
+    : note
 
   if (!isip(str)) {
-    throw new TypeError('invalid IP address: ' + str);
+    throw new TypeError('invalid IP address: ' + str)
   }
 
-  var ip = parseip(str);
+  var ip = parseip(str)
 
   if (pos === -1 && ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) {
     // Store as IPv4
-    ip = ip.toIPv4Address();
+    ip = ip.toIPv4Address()
   }
 
   var max = ip.kind() === 'ipv6'
     ? 128
-    : 32;
+    : 32
 
   var range = pos !== -1
     ? note.substring(pos + 1, note.length)
-    : null;
+    : null
 
   if (range === null) {
-    range = max;
-  } else if (digitre.test(range)) {
-    range = parseInt(range, 10);
+    range = max
+  } else if (DIGIT_REGEXP.test(range)) {
+    range = parseInt(range, 10)
   } else if (ip.kind() === 'ipv4' && isip(range)) {
-    range = parseNetmask(range);
+    range = parseNetmask(range)
   } else {
-    range = null;
+    range = null
   }
 
   if (range <= 0 || range > max) {
-    throw new TypeError('invalid range on address: ' + note);
+    throw new TypeError('invalid range on address: ' + note)
   }
 
-  return [ip, range];
+  return [ip, range]
 }
 
 /**
  * Parse netmask string into CIDR range.
  *
  * @param {String} netmask
- * @api private
+ * @private
  */
 
-function parseNetmask(netmask) {
-  var ip = parseip(netmask);
-  var kind = ip.kind();
+function parseNetmask (netmask) {
+  var ip = parseip(netmask)
+  var kind = ip.kind()
 
   return kind === 'ipv4'
     ? ip.prefixLengthFromSubnetMask()
-    : null;
+    : null
 }
 
 /**
@@ -210,112 +216,112 @@ function parseNetmask(netmask) {
  *
  * @param {Object} request
  * @param {Function|Array|String} trust
- * @api public
+ * @public
  */
 
-function proxyaddr(req, trust) {
+function proxyaddr (req, trust) {
   if (!req) {
-    throw new TypeError('req argument is required');
+    throw new TypeError('req argument is required')
   }
 
   if (!trust) {
-    throw new TypeError('trust argument is required');
+    throw new TypeError('trust argument is required')
   }
 
-  var addrs = alladdrs(req, trust);
-  var addr = addrs[addrs.length - 1];
+  var addrs = alladdrs(req, trust)
+  var addr = addrs[addrs.length - 1]
 
-  return addr;
+  return addr
 }
 
 /**
  * Static trust function to trust nothing.
  *
- * @api private
+ * @private
  */
 
-function trustNone() {
-  return false;
+function trustNone () {
+  return false
 }
 
 /**
  * Compile trust function for multiple subnets.
  *
  * @param {Array} subnets
- * @api private
+ * @private
  */
 
-function trustMulti(subnets) {
-  return function trust(addr) {
-    if (!isip(addr)) return false;
+function trustMulti (subnets) {
+  return function trust (addr) {
+    if (!isip(addr)) return false
 
-    var ip = parseip(addr);
-    var ipconv;
-    var kind = ip.kind();
+    var ip = parseip(addr)
+    var ipconv
+    var kind = ip.kind()
 
     for (var i = 0; i < subnets.length; i++) {
-      var subnet = subnets[i];
-      var subnetip = subnet[0];
-      var subnetkind = subnetip.kind();
-      var subnetrange = subnet[1];
-      var trusted = ip;
+      var subnet = subnets[i]
+      var subnetip = subnet[0]
+      var subnetkind = subnetip.kind()
+      var subnetrange = subnet[1]
+      var trusted = ip
 
       if (kind !== subnetkind) {
         if (subnetkind === 'ipv4' && !ip.isIPv4MappedAddress()) {
           // Incompatible IP addresses
-          continue;
+          continue
         }
 
         if (!ipconv) {
           // Convert IP to match subnet IP kind
           ipconv = subnetkind === 'ipv4'
             ? ip.toIPv4Address()
-            : ip.toIPv4MappedAddress();
+            : ip.toIPv4MappedAddress()
         }
 
-        trusted = ipconv;
+        trusted = ipconv
       }
 
       if (trusted.match(subnetip, subnetrange)) {
-        return true;
+        return true
       }
     }
 
-    return false;
-  };
+    return false
+  }
 }
 
 /**
  * Compile trust function for single subnet.
  *
  * @param {Object} subnet
- * @api private
+ * @private
  */
 
-function trustSingle(subnet) {
-  var subnetip = subnet[0];
-  var subnetkind = subnetip.kind();
-  var subnetisipv4 = subnetkind === 'ipv4';
-  var subnetrange = subnet[1];
+function trustSingle (subnet) {
+  var subnetip = subnet[0]
+  var subnetkind = subnetip.kind()
+  var subnetisipv4 = subnetkind === 'ipv4'
+  var subnetrange = subnet[1]
 
-  return function trust(addr) {
-    if (!isip(addr)) return false;
+  return function trust (addr) {
+    if (!isip(addr)) return false
 
-    var ip = parseip(addr);
-    var kind = ip.kind();
+    var ip = parseip(addr)
+    var kind = ip.kind()
 
     if (kind !== subnetkind) {
       if (subnetisipv4 && !ip.isIPv4MappedAddress()) {
         // Incompatible IP addresses
-        return false;
+        return false
       }
 
       // Convert IP to match subnet IP kind
       ip = subnetisipv4
         ? ip.toIPv4Address()
-        : ip.toIPv4MappedAddress();
+        : ip.toIPv4MappedAddress()
     }
 
-    return ip.match(subnetip, subnetrange);
-  };
+    return ip.match(subnetip, subnetrange)
+  }
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/package.json
index 4ed15bc2a..fd3e0ac3b 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/proxy-addr/package.json
@@ -1,50 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "proxy-addr@~1.1.3",
-        "scope": null,
-        "escapedName": "proxy-addr",
-        "name": "proxy-addr",
-        "rawSpec": "~1.1.3",
-        "spec": ">=1.1.3 <1.2.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "proxy-addr@>=1.1.3 <1.2.0",
-  "_id": "proxy-addr@1.1.3",
-  "_inCache": true,
+  "_from": "proxy-addr@~2.0.2",
+  "_id": "proxy-addr@2.0.2",
+  "_inBundle": false,
+  "_integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
   "_location": "/proxy-addr",
-  "_nodeVersion": "4.6.1",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/proxy-addr-1.1.3.tgz_1484460061440_0.03347301739268005"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "2.15.9",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "proxy-addr@~1.1.3",
-    "scope": null,
-    "escapedName": "proxy-addr",
+    "type": "range",
+    "registry": true,
+    "raw": "proxy-addr@~2.0.2",
     "name": "proxy-addr",
-    "rawSpec": "~1.1.3",
-    "spec": ">=1.1.3 <1.2.0",
-    "type": "range"
+    "escapedName": "proxy-addr",
+    "rawSpec": "~2.0.2",
+    "saveSpec": null,
+    "fetchSpec": "~2.0.2"
   },
   "_requiredBy": [
     "/express"
   ],
-  "_resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.3.tgz",
-  "_shasum": "dc97502f5722e888467b3fa2297a7b1ff47df074",
-  "_shrinkwrap": null,
-  "_spec": "proxy-addr@~1.1.3",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+  "_shasum": "6571504f47bb988ec8180253f85dd7e14952bdec",
+  "_spec": "proxy-addr@~2.0.2",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
@@ -52,24 +29,28 @@
   "bugs": {
     "url": "https://github.com/jshttp/proxy-addr/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
-    "forwarded": "~0.1.0",
-    "ipaddr.js": "1.2.0"
+    "forwarded": "~0.1.2",
+    "ipaddr.js": "1.5.2"
   },
+  "deprecated": false,
   "description": "Determine address of proxied request",
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
-    "benchmark": "2.1.3",
-    "istanbul": "0.4.5",
-    "mocha": "~1.21.5"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "dc97502f5722e888467b3fa2297a7b1ff47df074",
-    "tarball": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.3.tgz"
+    "benchmark": "2.1.4",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-markdown": "1.0.0-beta.6",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "mocha": "3.5.3",
+    "nyc": "10.3.2"
   },
   "engines": {
-    "node": ">= 0.6"
+    "node": ">= 0.10"
   },
   "files": [
     "LICENSE",
@@ -77,7 +58,6 @@
     "README.md",
     "index.js"
   ],
-  "gitHead": "0724490937983255e7687812594c97c36ebca90b",
   "homepage": "https://github.com/jshttp/proxy-addr#readme",
   "keywords": [
     "ip",
@@ -85,24 +65,17 @@
     "x-forwarded-for"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    }
-  ],
   "name": "proxy-addr",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/proxy-addr.git"
   },
   "scripts": {
     "bench": "node benchmark/index.js",
+    "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail --check-leaks 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/"
+    "test-cov": "nyc --reporter=text npm test",
+    "test-travis": "nyc --reporter=html --reporter=text npm test"
   },
-  "version": "1.1.3"
+  "version": "2.0.2"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/CHANGES.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/CHANGES.md
index cd351fdb8..766fcdc21 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/CHANGES.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/CHANGES.md
@@ -1,4 +1,18 @@
 
+## 1.5.1
+
+ - Q.any now annotates its error message to clarify that Q.any was involved and
+   includes only the last error emitted. (Ivan Etchart)
+ - Avoid domain.dispose during tests in preparation for Node.js 9. (Anna
+   Henningsen)
+
+## 1.5.0
+
+ - Q.any gives an error message from the last rejected promise
+ - Throw if callback supplied to "finally" is invalid (@grahamrhay)
+ - Long stack trace improvements, can now construct long stack traces
+   across rethrows.
+
 ## 1.4.1
 
  - Address an issue that prevented Q from being used as a `<script>` for
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/LICENSE b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/LICENSE
index 8a706b59c..9ce1ea591 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/LICENSE
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2009–2014 Kristopher Michael Kowal. All rights reserved.
+Copyright 2009–2017 Kristopher Michael Kowal. All rights reserved.
 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
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/README.md
index 9065bfa7f..d2f57a6f6 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/README.md
@@ -1,17 +1,10 @@
-[![Build Status](https://secure.travis-ci.org/kriskowal/q.png?branch=master)](http://travis-ci.org/kriskowal/q)
+[![Build Status](https://secure.travis-ci.org/kriskowal/q.svg?branch=master)](http://travis-ci.org/kriskowal/q)
+[![CDNJS](https://img.shields.io/cdnjs/v/q.js.svg)](https://cdnjs.com/libraries/q.js)
 
 <a href="http://promises-aplus.github.com/promises-spec">
-    <img src="http://kriskowal.github.io/q/q.png"
-         align="right" alt="Q logo" />
+    <img src="http://kriskowal.github.io/q/q.png" align="right" alt="Q logo" />
 </a>
 
-*This is Q version 1, from the `v1` branch in Git. This documentation applies to
-the latest of both the version 1 and version 0.9 release trains. These releases
-are stable. There will be no further releases of 0.9 after 0.9.7 which is nearly
-equivalent to version 1.0.0. All further releases of `q@~1.0` will be backward
-compatible. The version 2 release train introduces significant and
-backward-incompatible changes and is experimental at this time.*
-
 If a function cannot return a value or throw an exception without
 blocking, it can return a promise instead.  A promise is an object
 that represents the return value or the thrown exception that the
@@ -80,7 +73,7 @@ The Q module can be loaded as:
     the [q](https://npmjs.org/package/q) package
 -   An AMD module
 -   A [component](https://github.com/component/component) as ``microjs/q``
--   Using [bower](http://bower.io/) as `q#1.0.1`
+-   Using [bower](http://bower.io/) as `q#^1.4.1`
 -   Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)
 
 Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more.
@@ -386,7 +379,7 @@ return funcs.reduce(Q.when, Q(initialVal));
 
 ### Handling Errors
 
-One sometimes-unintuive aspect of promises is that if you throw an
+One sometimes-unintuitive aspect of promises is that if you throw an
 exception in the fulfillment handler, it will not be caught by the error
 handler.
 
@@ -876,6 +869,6 @@ You can view the results of the Q test suite [in your browser][tests]!
 
 ## License
 
-Copyright 2009–2015 Kristopher Michael Kowal and contributors
+Copyright 2009–2017 Kristopher Michael Kowal and contributors
 MIT License (enclosed)
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/package.json
index 1cd6eb40e..161821628 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/package.json
@@ -1,47 +1,27 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "q@^1.4.1",
-        "scope": null,
-        "escapedName": "q",
-        "name": "q",
-        "rawSpec": "^1.4.1",
-        "spec": ">=1.4.1 <2.0.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser"
-    ]
-  ],
-  "_from": "q@>=1.4.1 <2.0.0",
-  "_id": "q@1.4.1",
-  "_inCache": true,
+  "_from": "q@^1.4.1",
+  "_id": "q@1.5.1",
+  "_inBundle": false,
+  "_integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
   "_location": "/q",
-  "_nodeVersion": "1.8.1",
-  "_npmUser": {
-    "name": "kriskowal",
-    "email": "kris.kowal@cixar.com"
-  },
-  "_npmVersion": "2.8.3",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "q@^1.4.1",
-    "scope": null,
-    "escapedName": "q",
     "name": "q",
+    "escapedName": "q",
     "rawSpec": "^1.4.1",
-    "spec": ">=1.4.1 <2.0.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "^1.4.1"
   },
   "_requiredBy": [
-    "/",
-    "/cordova-serve"
+    "/cordova-common"
   ],
-  "_resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
-  "_shasum": "55705bcd93c5f3673530c2c2cbc0c2b3addc286e",
-  "_shrinkwrap": null,
+  "_resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+  "_shasum": "7e32f75b41381291d04611f1bf14109ac00651d7",
   "_spec": "q@^1.4.1",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/cordova-common",
   "author": {
     "name": "Kris Kowal",
     "email": "kris@cixar.com",
@@ -50,6 +30,7 @@
   "bugs": {
     "url": "http://github.com/kriskowal/q/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Kris Kowal",
@@ -68,6 +49,7 @@
     }
   ],
   "dependencies": {},
+  "deprecated": false,
   "description": "A library for promises (CommonJS/Promises/A,B,D)",
   "devDependencies": {
     "cover": "*",
@@ -83,10 +65,6 @@
   "directories": {
     "test": "./spec"
   },
-  "dist": {
-    "shasum": "55705bcd93c5f3673530c2c2cbc0c2b3addc286e",
-    "tarball": "https://registry.npmjs.org/q/-/q-1.4.1.tgz"
-  },
   "engines": {
     "node": ">=0.6.0",
     "teleport": ">=0.2.0"
@@ -96,7 +74,6 @@
     "q.js",
     "queue.js"
   ],
-  "gitHead": "d373079d3620152e3d60e82f27265a09ee0e81bd",
   "homepage": "https://github.com/kriskowal/q",
   "keywords": [
     "q",
@@ -112,23 +89,9 @@
     "browser",
     "node"
   ],
-  "license": {
-    "type": "MIT",
-    "url": "http://github.com/kriskowal/q/raw/master/LICENSE"
-  },
+  "license": "MIT",
   "main": "q.js",
-  "maintainers": [
-    {
-      "name": "kriskowal",
-      "email": "kris.kowal@cixar.com"
-    },
-    {
-      "name": "domenic",
-      "email": "domenic@domenicdenicola.com"
-    }
-  ],
   "name": "q",
-  "optionalDependencies": {},
   "overlay": {
     "teleport": {
       "dependencies": {
@@ -136,7 +99,6 @@
       }
     }
   },
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git://github.com/kriskowal/q.git"
@@ -147,8 +109,8 @@
     "lint": "jshint q.js",
     "minify": "grunt",
     "prepublish": "grunt",
-    "test": "jasmine-node spec && promises-aplus-tests spec/aplus-adapter",
+    "test": "npm ls -s && jasmine-node spec && promises-aplus-tests spec/aplus-adapter && npm run -s lint",
     "test-browser": "opener spec/q-spec.html"
   },
-  "version": "1.4.1"
+  "version": "1.5.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/q.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/q.js
index cf5339e33..6e4679582 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/q.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/q/q.js
@@ -1,8 +1,8 @@
 // vim:ts=4:sts=4:sw=4:
 /*!
  *
- * Copyright 2009-2012 Kris Kowal under the terms of the MIT
- * license found at http://github.com/kriskowal/q/raw/master/LICENSE
+ * Copyright 2009-2017 Kris Kowal under the terms of the MIT
+ * license found at https://github.com/kriskowal/q/blob/v1/LICENSE
  *
  * With parts by Tyler Close
  * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
@@ -190,7 +190,7 @@ var nextTick =(function () {
         //   `setTimeout`. In this case `setImmediate` is preferred because
         //    it is faster. Browserify's `process.toString()` yields
         //   "[object Object]", while in a real Node environment
-        //   `process.nextTick()` yields "[object process]".
+        //   `process.toString()` yields "[object process]".
         isNodeJS = true;
 
         requestTick = function () {
@@ -327,6 +327,11 @@ var object_create = Object.create || function (prototype) {
     return new Type();
 };
 
+var object_defineProperty = Object.defineProperty || function (obj, prop, descriptor) {
+    obj[prop] = descriptor.value;
+    return obj;
+};
+
 var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
 
 var object_keys = Object.keys || function (object) {
@@ -377,19 +382,20 @@ function makeStackTraceLong(error, promise) {
         promise.stack &&
         typeof error === "object" &&
         error !== null &&
-        error.stack &&
-        error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
+        error.stack
     ) {
         var stacks = [];
         for (var p = promise; !!p; p = p.source) {
-            if (p.stack) {
+            if (p.stack && (!error.__minimumStackCounter__ || error.__minimumStackCounter__ > p.stackCounter)) {
+                object_defineProperty(error, "__minimumStackCounter__", {value: p.stackCounter, configurable: true});
                 stacks.unshift(p.stack);
             }
         }
         stacks.unshift(error.stack);
 
         var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
-        error.stack = filterStackString(concatedStacks);
+        var stack = filterStackString(concatedStacks);
+        object_defineProperty(error, "stack", {value: stack, configurable: true});
     }
 }
 
@@ -516,6 +522,14 @@ Q.nextTick = nextTick;
  */
 Q.longStackSupport = false;
 
+/**
+ * The counter is used to determine the stopping point for building
+ * long stack traces. In makeStackTraceLong we walk backwards through
+ * the linked list of promises, only stacks which were created before
+ * the rejection are concatenated.
+ */
+var longStackCounter = 1;
+
 // enable long stacks if Q_DEBUG is set
 if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
     Q.longStackSupport = true;
@@ -588,6 +602,7 @@ function defer() {
             // At the same time, cut off the first line; it's always just
             // "[object Promise]\n", as per the `toString`.
             promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
+            promise.stackCounter = longStackCounter++;
         }
     }
 
@@ -597,7 +612,12 @@ function defer() {
 
     function become(newPromise) {
         resolvedPromise = newPromise;
-        promise.source = newPromise;
+
+        if (Q.longStackSupport && hasStacks) {
+            // Only hold a reference to the new promise if long stacks
+            // are enabled to reduce memory usage
+            promise.source = newPromise;
+        }
 
         array_reduce(messages, function (undefined, message) {
             Q.nextTick(function () {
@@ -725,7 +745,7 @@ Promise.prototype.join = function (that) {
             // TODO: "===" should be Object.is or equiv
             return x;
         } else {
-            throw new Error("Can't join: not the same: " + x + " " + y);
+            throw new Error("Q can't join: not the same: " + x + " " + y);
         }
     });
 };
@@ -1622,13 +1642,15 @@ function any(promises) {
         function onFulfilled(result) {
             deferred.resolve(result);
         }
-        function onRejected() {
+        function onRejected(err) {
             pendingCount--;
             if (pendingCount === 0) {
-                deferred.reject(new Error(
-                    "Can't get fulfillment value from any promise, all " +
-                    "promises were rejected."
-                ));
+                var rejection = err || new Error("" + err);
+
+                rejection.message = ("Q can't get fulfillment value from any promise, all " +
+                    "promises were rejected. Last error message: " + rejection.message);
+
+                deferred.reject(rejection);
             }
         }
         function onProgress(progress) {
@@ -1752,6 +1774,9 @@ Q["finally"] = function (object, callback) {
 
 Promise.prototype.fin = // XXX legacy
 Promise.prototype["finally"] = function (callback) {
+    if (!callback || typeof callback.apply !== "function") {
+        throw new Error("Q can't apply finally callback");
+    }
     callback = Q(callback);
     return this.then(function (value) {
         return callback.fcall().then(function () {
@@ -1915,6 +1940,9 @@ Promise.prototype.nfcall = function (/*...args*/) {
  */
 Q.nfbind =
 Q.denodeify = function (callback /*...args*/) {
+    if (callback === undefined) {
+        throw new Error("Q can't wrap an undefined function");
+    }
     var baseArgs = array_slice(arguments, 1);
     return function () {
         var nodeArgs = baseArgs.concat(array_slice(arguments));
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.eslintrc b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.eslintrc
index 1faac273f..a33d179e7 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.eslintrc
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.eslintrc
@@ -1,19 +1,19 @@
 {
-	"root": true,
+    "root": true,
 
-	"extends": "@ljharb",
+    "extends": "@ljharb",
 
-	"rules": {
-		"complexity": [2, 22],
-		"consistent-return": [1],
-		"id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
-		"indent": [2, 4],
-		"max-params": [2, 9],
-		"max-statements": [2, 36],
-		"no-extra-parens": [1],
-		"no-continue": [1],
-		"no-magic-numbers": 0,
-		"no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
-		"operator-linebreak": 1
-	}
+    "rules": {
+        "complexity": [2, 28],
+        "consistent-return": 1,
+		"func-name-matching": 0,
+        "id-length": [2, { "min": 1, "max": 25, "properties": "never" }],
+        "indent": [2, 4],
+        "max-params": [2, 12],
+        "max-statements": [2, 45],
+        "no-continue": 1,
+        "no-magic-numbers": 0,
+        "no-restricted-syntax": [2, "BreakStatement", "DebuggerStatement", "ForInStatement", "LabeledStatement", "WithStatement"],
+        "operator-linebreak": [2, "before"],
+    }
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.jscs.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.jscs.json
deleted file mode 100644
index 3d099c4b1..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/.jscs.json
+++ /dev/null
@@ -1,176 +0,0 @@
-{
-	"es3": true,
-
-	"additionalRules": [],
-
-	"requireSemicolons": true,
-
-	"disallowMultipleSpaces": true,
-
-	"disallowIdentifierNames": [],
-
-	"requireCurlyBraces": {
-		"allExcept": [],
-		"keywords": ["if", "else", "for", "while", "do", "try", "catch"]
-	},
-
-	"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
-
-	"disallowSpaceAfterKeywords": [],
-
-	"disallowSpaceBeforeComma": true,
-	"disallowSpaceAfterComma": false,
-	"disallowSpaceBeforeSemicolon": true,
-
-	"disallowNodeTypes": [
-		"DebuggerStatement",
-		"ForInStatement",
-		"LabeledStatement",
-		"SwitchCase",
-		"SwitchStatement",
-		"WithStatement"
-	],
-
-	"requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
-
-	"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
-	"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
-	"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
-	"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
-	"disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
-
-	"requireSpaceBetweenArguments": true,
-
-	"disallowSpacesInsideParentheses": true,
-
-	"disallowSpacesInsideArrayBrackets": true,
-
-	"disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
-
-	"disallowSpaceAfterObjectKeys": true,
-
-	"requireCommaBeforeLineBreak": true,
-
-	"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
-	"requireSpaceAfterPrefixUnaryOperators": [],
-
-	"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
-	"requireSpaceBeforePostfixUnaryOperators": [],
-
-	"disallowSpaceBeforeBinaryOperators": [],
-	"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
-
-	"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
-	"disallowSpaceAfterBinaryOperators": [],
-
-	"disallowImplicitTypeConversion": ["binary", "string"],
-
-	"disallowKeywords": ["with", "eval"],
-
-	"requireKeywordsOnNewLine": [],
-	"disallowKeywordsOnNewLine": ["else"],
-
-	"requireLineFeedAtFileEnd": true,
-
-	"disallowTrailingWhitespace": true,
-
-	"disallowTrailingComma": true,
-
-	"excludeFiles": ["node_modules/**", "vendor/**"],
-
-	"disallowMultipleLineStrings": true,
-
-	"requireDotNotation": { "allExcept": ["keywords"] },
-
-	"requireParenthesesAroundIIFE": true,
-
-	"validateLineBreaks": "LF",
-
-	"validateQuoteMarks": {
-		"escape": true,
-		"mark": "'"
-	},
-
-	"disallowOperatorBeforeLineBreak": [],
-
-	"requireSpaceBeforeKeywords": [
-		"do",
-		"for",
-		"if",
-		"else",
-		"switch",
-		"case",
-		"try",
-		"catch",
-		"finally",
-		"while",
-		"with",
-		"return"
-	],
-
-	"validateAlignedFunctionParameters": {
-		"lineBreakAfterOpeningBraces": true,
-		"lineBreakBeforeClosingBraces": true
-	},
-
-	"requirePaddingNewLinesBeforeExport": true,
-
-	"validateNewlineAfterArrayElements": {
-		"maximum": 1
-	},
-
-	"requirePaddingNewLinesAfterUseStrict": true,
-
-	"disallowArrowFunctions": true,
-
-	"disallowMultiLineTernary": true,
-
-	"validateOrderInObjectKeys": "asc-insensitive",
-
-	"disallowIdenticalDestructuringNames": true,
-
-	"disallowNestedTernaries": { "maxLevel": 1 },
-
-	"requireSpaceAfterComma": { "allExcept": ["trailing"] },
-	"requireAlignedMultilineParams": false,
-
-	"requireSpacesInGenerator": {
-		"afterStar": true
-	},
-
-	"disallowSpacesInGenerator": {
-		"beforeStar": true
-	},
-
-	"disallowVar": false,
-
-	"requireArrayDestructuring": false,
-
-	"requireEnhancedObjectLiterals": false,
-
-	"requireObjectDestructuring": false,
-
-	"requireEarlyReturn": false,
-
-	"requireCapitalizedConstructorsNew": {
-		"allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
-	},
-
-	"requireImportAlphabetized": false,
-
-    "requireSpaceBeforeObjectValues": true,
-    "requireSpaceBeforeDestructuredValues": true,
-
-	"disallowSpacesInsideTemplateStringPlaceholders": true,
-
-    "disallowArrayDestructuringReturn": false,
-
-    "requireNewlineBeforeSingleStatementsInIf": false,
-
-	"disallowUnusedVariables": true,
-
-	"requireSpacesInsideImportedObjectBraces": true,
-
-	"requireUseStrict": true
-}
-
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CHANGELOG.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CHANGELOG.md
index e318a054a..71d5a3e8f 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CHANGELOG.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CHANGELOG.md
@@ -1,13 +1,111 @@
+## **6.5.1**
+- [Fix] Fix parsing & compacting very deep objects (#224)
+- [Refactor] name utils functions
+- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`
+- [Tests] up to `node` `v8.4`; use `nvm install-latest-npm` so newer npm doesn’t break older node
+- [Tests] Use precise dist for Node.js 0.6 runtime (#225)
+- [Tests] make 0.6 required, now that it’s passing
+- [Tests] on `node` `v8.2`; fix npm on node 0.6
+
+## **6.5.0**
+- [New] add `utils.assign`
+- [New] pass default encoder/decoder to custom encoder/decoder functions (#206)
+- [New] `parse`/`stringify`: add `ignoreQueryPrefix`/`addQueryPrefix` options, respectively (#213)
+- [Fix] Handle stringifying empty objects with addQueryPrefix (#217)
+- [Fix] do not mutate `options` argument (#207)
+- [Refactor] `parse`: cache index to reuse in else statement (#182)
+- [Docs] add various badges to readme (#208)
+- [Dev Deps] update `eslint`, `browserify`, `iconv-lite`, `tape`
+- [Tests] up to `node` `v8.1`, `v7.10`, `v6.11`; npm v4.6 breaks on node < v1; npm v5+ breaks on node < v4
+- [Tests] add `editorconfig-tools`
+
+## **6.4.0**
+- [New] `qs.stringify`: add `encodeValuesOnly` option
+- [Fix] follow `allowPrototypes` option during merge (#201, #201)
+- [Fix] support keys starting with brackets (#202, #200)
+- [Fix] chmod a-x
+- [Dev Deps] update `eslint`
+- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
+- [eslint] reduce warnings
+
+## **6.3.2**
+- [Fix] follow `allowPrototypes` option during merge (#201, #200)
+- [Dev Deps] update `eslint`
+- [Fix] chmod a-x
+- [Fix] support keys starting with brackets (#202, #200)
+- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
+
+## **6.3.1**
+- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties (thanks, @snyk!)
+- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `iconv-lite`, `qs-iconv`, `tape`
+- [Tests] on all node minors; improve test matrix
+- [Docs] document stringify option `allowDots` (#195)
+- [Docs] add empty object and array values example (#195)
+- [Docs] Fix minor inconsistency/typo (#192)
+- [Docs] document stringify option `sort` (#191)
+- [Refactor] `stringify`: throw faster with an invalid encoder
+- [Refactor] remove unnecessary escapes (#184)
+- Remove contributing.md, since `qs` is no longer part of `hapi` (#183)
+
+## **6.3.0**
+- [New] Add support for RFC 1738 (#174, #173)
+- [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159)
+- [Fix] ensure `utils.merge` handles merging two arrays
+- [Refactor] only constructors should be capitalized
+- [Refactor] capitalized var names are for constructors only
+- [Refactor] avoid using a sparse array
+- [Robustness] `formats`: cache `String#replace`
+- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`; add `safe-publish-latest`
+- [Tests] up to `node` `v6.8`, `v4.6`; improve test matrix
+- [Tests] flesh out arrayLimit/arrayFormat tests (#107)
+- [Tests] skip Object.create tests when null objects are not available
+- [Tests] Turn on eslint for test files (#175)
+
+## **6.2.3**
+- [Fix] follow `allowPrototypes` option during merge (#201, #200)
+- [Fix] chmod a-x
+- [Fix] support keys starting with brackets (#202, #200)
+- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
+
+## **6.2.2**
+- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
+
+## **6.2.1**
+- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
+- [Refactor] Be explicit and use `Object.prototype.hasOwnProperty.call`
+- [Tests] remove `parallelshell` since it does not reliably report failures
+- [Tests] up to `node` `v6.3`, `v5.12`
+- [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config`, `qs-iconv`
+
 ## [**6.2.0**](https://github.com/ljharb/qs/issues?milestone=36&state=closed)
 - [New] pass Buffers to the encoder/decoder directly (#161)
 - [New] add "encoder" and "decoder" options, for custom param encoding/decoding (#160)
 - [Fix] fix compacting of nested sparse arrays (#150)
 
+## **6.1.2
+- [Fix] follow `allowPrototypes` option during merge (#201, #200)
+- [Fix] chmod a-x
+- [Fix] support keys starting with brackets (#202, #200)
+- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
+
+## **6.1.1**
+- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
+
 ## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=35&state=closed)
 - [New] allowDots option for `stringify` (#151)
 - [Fix] "sort" option should work at a depth of 3 or more (#151)
 - [Fix] Restore `dist` directory; will be removed in v7 (#148)
 
+## **6.0.4**
+- [Fix] follow `allowPrototypes` option during merge (#201, #200)
+- [Fix] chmod a-x
+- [Fix] support keys starting with brackets (#202, #200)
+- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds
+
+## **6.0.3**
+- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties
+- [Fix] Restore `dist` directory; will be removed in v7 (#148)
+
 ## [**6.0.2**](https://github.com/ljharb/qs/issues?milestone=33&state=closed)
 - Revert ES6 requirement and restore support for node down to v0.8.
 
@@ -17,6 +115,9 @@
 ## [**6.0.0**](https://github.com/ljharb/qs/issues?milestone=31&state=closed)
 - [**#124**](https://github.com/ljharb/qs/issues/124) Use ES6 and drop support for node < v4
 
+## **5.2.1**
+- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
+
 ## [**5.2.0**](https://github.com/ljharb/qs/issues?milestone=30&state=closed)
 - [**#64**](https://github.com/ljharb/qs/issues/64) Add option to sort object keys in the query string
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CONTRIBUTING.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CONTRIBUTING.md
deleted file mode 100644
index 892836159..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/dist/qs.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/dist/qs.js
index 4cc6f3067..713c6d1e8 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/dist/qs.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/dist/qs.js
@@ -1,122 +1,150 @@
 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
 'use strict';
 
-var Stringify = require('./stringify');
-var Parse = require('./parse');
+var replace = String.prototype.replace;
+var percentTwenties = /%20/g;
 
 module.exports = {
-    stringify: Stringify,
-    parse: Parse
+    'default': 'RFC3986',
+    formatters: {
+        RFC1738: function (value) {
+            return replace.call(value, percentTwenties, '+');
+        },
+        RFC3986: function (value) {
+            return value;
+        }
+    },
+    RFC1738: 'RFC1738',
+    RFC3986: 'RFC3986'
 };
 
-},{"./parse":2,"./stringify":3}],2:[function(require,module,exports){
+},{}],2:[function(require,module,exports){
 'use strict';
 
-var Utils = require('./utils');
+var stringify = require('./stringify');
+var parse = require('./parse');
+var formats = require('./formats');
+
+module.exports = {
+    formats: formats,
+    parse: parse,
+    stringify: stringify
+};
+
+},{"./formats":1,"./parse":3,"./stringify":4}],3:[function(require,module,exports){
+'use strict';
+
+var utils = require('./utils');
+
+var has = Object.prototype.hasOwnProperty;
 
 var defaults = {
+    allowDots: false,
+    allowPrototypes: false,
+    arrayLimit: 20,
+    decoder: utils.decode,
     delimiter: '&',
     depth: 5,
-    arrayLimit: 20,
     parameterLimit: 1000,
-    strictNullHandling: false,
     plainObjects: false,
-    allowPrototypes: false,
-    allowDots: false,
-    decoder: Utils.decode
+    strictNullHandling: false
 };
 
-var parseValues = function parseValues(str, options) {
+var parseValues = function parseQueryStringValues(str, options) {
     var obj = {};
-    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
+    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
+    var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
+    var parts = cleanStr.split(options.delimiter, limit);
 
     for (var i = 0; i < parts.length; ++i) {
         var part = parts[i];
-        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
 
-        if (pos === -1) {
-            obj[options.decoder(part)] = '';
+        var bracketEqualsPos = part.indexOf(']=');
+        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
 
-            if (options.strictNullHandling) {
-                obj[options.decoder(part)] = null;
-            }
+        var key, val;
+        if (pos === -1) {
+            key = options.decoder(part, defaults.decoder);
+            val = options.strictNullHandling ? null : '';
         } else {
-            var key = options.decoder(part.slice(0, pos));
-            var val = options.decoder(part.slice(pos + 1));
-
-            if (Object.prototype.hasOwnProperty.call(obj, key)) {
-                obj[key] = [].concat(obj[key]).concat(val);
-            } else {
-                obj[key] = val;
-            }
+            key = options.decoder(part.slice(0, pos), defaults.decoder);
+            val = options.decoder(part.slice(pos + 1), defaults.decoder);
+        }
+        if (has.call(obj, key)) {
+            obj[key] = [].concat(obj[key]).concat(val);
+        } else {
+            obj[key] = val;
         }
     }
 
     return obj;
 };
 
-var parseObject = function parseObject(chain, val, options) {
-    if (!chain.length) {
-        return val;
-    }
+var parseObject = function (chain, val, options) {
+    var leaf = val;
 
-    var root = chain.shift();
+    for (var i = chain.length - 1; i >= 0; --i) {
+        var obj;
+        var root = chain[i];
 
-    var obj;
-    if (root === '[]') {
-        obj = [];
-        obj = obj.concat(parseObject(chain, val, options));
-    } else {
-        obj = options.plainObjects ? Object.create(null) : {};
-        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
-        var index = parseInt(cleanRoot, 10);
-        if (
-            !isNaN(index) &&
-            root !== cleanRoot &&
-            String(index) === cleanRoot &&
-            index >= 0 &&
-            (options.parseArrays && index <= options.arrayLimit)
-        ) {
+        if (root === '[]') {
             obj = [];
-            obj[index] = parseObject(chain, val, options);
+            obj = obj.concat(leaf);
         } else {
-            obj[cleanRoot] = parseObject(chain, val, options);
+            obj = options.plainObjects ? Object.create(null) : {};
+            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
+            var index = parseInt(cleanRoot, 10);
+            if (
+                !isNaN(index)
+                && root !== cleanRoot
+                && String(index) === cleanRoot
+                && index >= 0
+                && (options.parseArrays && index <= options.arrayLimit)
+            ) {
+                obj = [];
+                obj[index] = leaf;
+            } else {
+                obj[cleanRoot] = leaf;
+            }
         }
+
+        leaf = obj;
     }
 
-    return obj;
+    return leaf;
 };
 
-var parseKeys = function parseKeys(givenKey, val, options) {
+var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
     if (!givenKey) {
         return;
     }
 
     // Transform dot notation to bracket notation
-    var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey;
+    var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
 
     // The regex chunks
 
-    var parent = /^([^\[\]]*)/;
-    var child = /(\[[^\[\]]*\])/g;
+    var brackets = /(\[[^[\]]*])/;
+    var child = /(\[[^[\]]*])/g;
 
     // Get the parent
 
-    var segment = parent.exec(key);
+    var segment = brackets.exec(key);
+    var parent = segment ? key.slice(0, segment.index) : key;
 
     // Stash the parent if it exists
 
     var keys = [];
-    if (segment[1]) {
+    if (parent) {
         // If we aren't using plain objects, optionally prefix keys
         // that would overwrite object prototype properties
-        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
+        if (!options.plainObjects && has.call(Object.prototype, parent)) {
             if (!options.allowPrototypes) {
                 return;
             }
         }
 
-        keys.push(segment[1]);
+        keys.push(parent);
     }
 
     // Loop through children appending to the array until we hit depth
@@ -124,9 +152,9 @@ var parseKeys = function parseKeys(givenKey, val, options) {
     var i = 0;
     while ((segment = child.exec(key)) !== null && i < options.depth) {
         i += 1;
-        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
+        if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
             if (!options.allowPrototypes) {
-                continue;
+                return;
             }
         }
         keys.push(segment[1]);
@@ -142,13 +170,14 @@ var parseKeys = function parseKeys(givenKey, val, options) {
 };
 
 module.exports = function (str, opts) {
-    var options = opts || {};
+    var options = opts ? utils.assign({}, opts) : {};
 
     if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
         throw new TypeError('Decoder has to be a function.');
     }
 
-    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
+    options.ignoreQueryPrefix = options.ignoreQueryPrefix === true;
+    options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
     options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
     options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
     options.parseArrays = options.parseArrays !== false;
@@ -172,56 +201,77 @@ module.exports = function (str, opts) {
     for (var i = 0; i < keys.length; ++i) {
         var key = keys[i];
         var newObj = parseKeys(key, tempObj[key], options);
-        obj = Utils.merge(obj, newObj, options);
+        obj = utils.merge(obj, newObj, options);
     }
 
-    return Utils.compact(obj);
+    return utils.compact(obj);
 };
 
-},{"./utils":4}],3:[function(require,module,exports){
+},{"./utils":5}],4:[function(require,module,exports){
 'use strict';
 
-var Utils = require('./utils');
+var utils = require('./utils');
+var formats = require('./formats');
 
 var arrayPrefixGenerators = {
-    brackets: function brackets(prefix) {
+    brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
         return prefix + '[]';
     },
-    indices: function indices(prefix, key) {
+    indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
         return prefix + '[' + key + ']';
     },
-    repeat: function repeat(prefix) {
+    repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
         return prefix;
     }
 };
 
+var toISO = Date.prototype.toISOString;
+
 var defaults = {
     delimiter: '&',
-    strictNullHandling: false,
-    skipNulls: false,
     encode: true,
-    encoder: Utils.encode
+    encoder: utils.encode,
+    encodeValuesOnly: false,
+    serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
+        return toISO.call(date);
+    },
+    skipNulls: false,
+    strictNullHandling: false
 };
 
-var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
+var stringify = function stringify( // eslint-disable-line func-name-matching
+    object,
+    prefix,
+    generateArrayPrefix,
+    strictNullHandling,
+    skipNulls,
+    encoder,
+    filter,
+    sort,
+    allowDots,
+    serializeDate,
+    formatter,
+    encodeValuesOnly
+) {
     var obj = object;
     if (typeof filter === 'function') {
         obj = filter(prefix, obj);
     } else if (obj instanceof Date) {
-        obj = obj.toISOString();
+        obj = serializeDate(obj);
     } else if (obj === null) {
         if (strictNullHandling) {
-            return encoder ? encoder(prefix) : prefix;
+            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix;
         }
 
         obj = '';
     }
 
-    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
+    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
         if (encoder) {
-            return [encoder(prefix) + '=' + encoder(obj)];
+            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder);
+            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))];
         }
-        return [prefix + '=' + String(obj)];
+        return [formatter(prefix) + '=' + formatter(String(obj))];
     }
 
     var values = [];
@@ -246,9 +296,35 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
         }
 
         if (Array.isArray(obj)) {
-            values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
+            values = values.concat(stringify(
+                obj[key],
+                generateArrayPrefix(prefix, key),
+                generateArrayPrefix,
+                strictNullHandling,
+                skipNulls,
+                encoder,
+                filter,
+                sort,
+                allowDots,
+                serializeDate,
+                formatter,
+                encodeValuesOnly
+            ));
         } else {
-            values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
+            values = values.concat(stringify(
+                obj[key],
+                prefix + (allowDots ? '.' + key : '[' + key + ']'),
+                generateArrayPrefix,
+                strictNullHandling,
+                skipNulls,
+                encoder,
+                filter,
+                sort,
+                allowDots,
+                serializeDate,
+                formatter,
+                encodeValuesOnly
+            ));
         }
     }
 
@@ -257,26 +333,36 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
 
 module.exports = function (object, opts) {
     var obj = object;
-    var options = opts || {};
+    var options = opts ? utils.assign({}, opts) : {};
+
+    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
+        throw new TypeError('Encoder has to be a function.');
+    }
+
     var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
     var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
     var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
     var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
-    var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
+    var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
     var sort = typeof options.sort === 'function' ? options.sort : null;
     var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
+    var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
+    var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
+    if (typeof options.format === 'undefined') {
+        options.format = formats['default'];
+    } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
+        throw new TypeError('Unknown format option provided.');
+    }
+    var formatter = formats.formatters[options.format];
     var objKeys;
     var filter;
 
-    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
-        throw new TypeError('Encoder has to be a function.');
-    }
-
     if (typeof options.filter === 'function') {
         filter = options.filter;
         obj = filter('', obj);
     } else if (Array.isArray(options.filter)) {
-        objKeys = filter = options.filter;
+        filter = options.filter;
+        objKeys = filter;
     }
 
     var keys = [];
@@ -311,26 +397,67 @@ module.exports = function (object, opts) {
             continue;
         }
 
-        keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
-    }
-
-    return keys.join(delimiter);
+        keys = keys.concat(stringify(
+            obj[key],
+            key,
+            generateArrayPrefix,
+            strictNullHandling,
+            skipNulls,
+            encode ? encoder : null,
+            filter,
+            sort,
+            allowDots,
+            serializeDate,
+            formatter,
+            encodeValuesOnly
+        ));
+    }
+
+    var joined = keys.join(delimiter);
+    var prefix = options.addQueryPrefix === true ? '?' : '';
+
+    return joined.length > 0 ? prefix + joined : '';
 };
 
-},{"./utils":4}],4:[function(require,module,exports){
+},{"./formats":1,"./utils":5}],5:[function(require,module,exports){
 'use strict';
 
+var has = Object.prototype.hasOwnProperty;
+
 var hexTable = (function () {
-    var array = new Array(256);
+    var array = [];
     for (var i = 0; i < 256; ++i) {
-        array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
+        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
     }
 
     return array;
 }());
 
-exports.arrayToObject = function (source, options) {
-    var obj = options.plainObjects ? Object.create(null) : {};
+var compactQueue = function compactQueue(queue) {
+    var obj;
+
+    while (queue.length) {
+        var item = queue.pop();
+        obj = item.obj[item.prop];
+
+        if (Array.isArray(obj)) {
+            var compacted = [];
+
+            for (var j = 0; j < obj.length; ++j) {
+                if (typeof obj[j] !== 'undefined') {
+                    compacted.push(obj[j]);
+                }
+            }
+
+            item.obj[item.prop] = compacted;
+        }
+    }
+
+    return obj;
+};
+
+exports.arrayToObject = function arrayToObject(source, options) {
+    var obj = options && options.plainObjects ? Object.create(null) : {};
     for (var i = 0; i < source.length; ++i) {
         if (typeof source[i] !== 'undefined') {
             obj[i] = source[i];
@@ -340,7 +467,7 @@ exports.arrayToObject = function (source, options) {
     return obj;
 };
 
-exports.merge = function (target, source, options) {
+exports.merge = function merge(target, source, options) {
     if (!source) {
         return target;
     }
@@ -349,7 +476,9 @@ exports.merge = function (target, source, options) {
         if (Array.isArray(target)) {
             target.push(source);
         } else if (typeof target === 'object') {
-            target[source] = true;
+            if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
+                target[source] = true;
+            }
         } else {
             return [target, source];
         }
@@ -366,10 +495,25 @@ exports.merge = function (target, source, options) {
         mergeTarget = exports.arrayToObject(target, options);
     }
 
+    if (Array.isArray(target) && Array.isArray(source)) {
+        source.forEach(function (item, i) {
+            if (has.call(target, i)) {
+                if (target[i] && typeof target[i] === 'object') {
+                    target[i] = exports.merge(target[i], item, options);
+                } else {
+                    target.push(item);
+                }
+            } else {
+                target[i] = item;
+            }
+        });
+        return target;
+    }
+
     return Object.keys(source).reduce(function (acc, key) {
         var value = source[key];
 
-        if (Object.prototype.hasOwnProperty.call(acc, key)) {
+        if (has.call(acc, key)) {
             acc[key] = exports.merge(acc[key], value, options);
         } else {
             acc[key] = value;
@@ -378,6 +522,13 @@ exports.merge = function (target, source, options) {
     }, mergeTarget);
 };
 
+exports.assign = function assignSingleSource(target, source) {
+    return Object.keys(source).reduce(function (acc, key) {
+        acc[key] = source[key];
+        return acc;
+    }, target);
+};
+
 exports.decode = function (str) {
     try {
         return decodeURIComponent(str.replace(/\+/g, ' '));
@@ -386,7 +537,7 @@ exports.decode = function (str) {
     }
 };
 
-exports.encode = function (str) {
+exports.encode = function encode(str) {
     // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
     // It has been adapted here for stricter adherence to RFC 3986
     if (str.length === 0) {
@@ -400,13 +551,13 @@ exports.encode = function (str) {
         var c = string.charCodeAt(i);
 
         if (
-            c === 0x2D || // -
-            c === 0x2E || // .
-            c === 0x5F || // _
-            c === 0x7E || // ~
-            (c >= 0x30 && c <= 0x39) || // 0-9
-            (c >= 0x41 && c <= 0x5A) || // a-z
-            (c >= 0x61 && c <= 0x7A) // A-Z
+            c === 0x2D // -
+            || c === 0x2E // .
+            || c === 0x5F // _
+            || c === 0x7E // ~
+            || (c >= 0x30 && c <= 0x39) // 0-9
+            || (c >= 0x41 && c <= 0x5A) // a-z
+            || (c >= 0x61 && c <= 0x7A) // A-Z
         ) {
             out += string.charAt(i);
             continue;
@@ -429,53 +580,42 @@ exports.encode = function (str) {
 
         i += 1;
         c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
-        out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
+        out += hexTable[0xF0 | (c >> 18)]
+            + hexTable[0x80 | ((c >> 12) & 0x3F)]
+            + hexTable[0x80 | ((c >> 6) & 0x3F)]
+            + hexTable[0x80 | (c & 0x3F)];
     }
 
     return out;
 };
 
-exports.compact = function (obj, references) {
-    if (typeof obj !== 'object' || obj === null) {
-        return obj;
-    }
-
-    var refs = references || [];
-    var lookup = refs.indexOf(obj);
-    if (lookup !== -1) {
-        return refs[lookup];
-    }
-
-    refs.push(obj);
+exports.compact = function compact(value) {
+    var queue = [{ obj: { o: value }, prop: 'o' }];
+    var refs = [];
 
-    if (Array.isArray(obj)) {
-        var compacted = [];
+    for (var i = 0; i < queue.length; ++i) {
+        var item = queue[i];
+        var obj = item.obj[item.prop];
 
-        for (var i = 0; i < obj.length; ++i) {
-            if (obj[i] && typeof obj[i] === 'object') {
-                compacted.push(exports.compact(obj[i], refs));
-            } else if (typeof obj[i] !== 'undefined') {
-                compacted.push(obj[i]);
+        var keys = Object.keys(obj);
+        for (var j = 0; j < keys.length; ++j) {
+            var key = keys[j];
+            var val = obj[key];
+            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
+                queue.push({ obj: obj, prop: key });
+                refs.push(val);
             }
         }
-
-        return compacted;
     }
 
-    var keys = Object.keys(obj);
-    for (var j = 0; j < keys.length; ++j) {
-        var key = keys[j];
-        obj[key] = exports.compact(obj[key], refs);
-    }
-
-    return obj;
+    return compactQueue(queue);
 };
 
-exports.isRegExp = function (obj) {
+exports.isRegExp = function isRegExp(obj) {
     return Object.prototype.toString.call(obj) === '[object RegExp]';
 };
 
-exports.isBuffer = function (obj) {
+exports.isBuffer = function isBuffer(obj) {
     if (obj === null || typeof obj === 'undefined') {
         return false;
     }
@@ -483,5 +623,5 @@ exports.isBuffer = function (obj) {
     return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
 };
 
-},{}]},{},[1])(1)
+},{}]},{},[2])(2)
 });
\ No newline at end of file
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/index.js
old mode 100755
new mode 100644
index 190195902..0d6a97dcf
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/index.js
@@ -1,9 +1,11 @@
 'use strict';
 
-var Stringify = require('./stringify');
-var Parse = require('./parse');
+var stringify = require('./stringify');
+var parse = require('./parse');
+var formats = require('./formats');
 
 module.exports = {
-    stringify: Stringify,
-    parse: Parse
+    formats: formats,
+    parse: parse,
+    stringify: stringify
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/parse.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/parse.js
old mode 100755
new mode 100644
index bf70fd8de..8c9872ecc
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/parse.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/parse.js
@@ -1,110 +1,116 @@
 'use strict';
 
-var Utils = require('./utils');
+var utils = require('./utils');
+
+var has = Object.prototype.hasOwnProperty;
 
 var defaults = {
+    allowDots: false,
+    allowPrototypes: false,
+    arrayLimit: 20,
+    decoder: utils.decode,
     delimiter: '&',
     depth: 5,
-    arrayLimit: 20,
     parameterLimit: 1000,
-    strictNullHandling: false,
     plainObjects: false,
-    allowPrototypes: false,
-    allowDots: false,
-    decoder: Utils.decode
+    strictNullHandling: false
 };
 
-var parseValues = function parseValues(str, options) {
+var parseValues = function parseQueryStringValues(str, options) {
     var obj = {};
-    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
+    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
+    var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
+    var parts = cleanStr.split(options.delimiter, limit);
 
     for (var i = 0; i < parts.length; ++i) {
         var part = parts[i];
-        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
 
-        if (pos === -1) {
-            obj[options.decoder(part)] = '';
+        var bracketEqualsPos = part.indexOf(']=');
+        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
 
-            if (options.strictNullHandling) {
-                obj[options.decoder(part)] = null;
-            }
+        var key, val;
+        if (pos === -1) {
+            key = options.decoder(part, defaults.decoder);
+            val = options.strictNullHandling ? null : '';
         } else {
-            var key = options.decoder(part.slice(0, pos));
-            var val = options.decoder(part.slice(pos + 1));
-
-            if (Object.prototype.hasOwnProperty.call(obj, key)) {
-                obj[key] = [].concat(obj[key]).concat(val);
-            } else {
-                obj[key] = val;
-            }
+            key = options.decoder(part.slice(0, pos), defaults.decoder);
+            val = options.decoder(part.slice(pos + 1), defaults.decoder);
+        }
+        if (has.call(obj, key)) {
+            obj[key] = [].concat(obj[key]).concat(val);
+        } else {
+            obj[key] = val;
         }
     }
 
     return obj;
 };
 
-var parseObject = function parseObject(chain, val, options) {
-    if (!chain.length) {
-        return val;
-    }
+var parseObject = function (chain, val, options) {
+    var leaf = val;
+
+    for (var i = chain.length - 1; i >= 0; --i) {
+        var obj;
+        var root = chain[i];
 
-    var root = chain.shift();
-
-    var obj;
-    if (root === '[]') {
-        obj = [];
-        obj = obj.concat(parseObject(chain, val, options));
-    } else {
-        obj = options.plainObjects ? Object.create(null) : {};
-        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
-        var index = parseInt(cleanRoot, 10);
-        if (
-            !isNaN(index) &&
-            root !== cleanRoot &&
-            String(index) === cleanRoot &&
-            index >= 0 &&
-            (options.parseArrays && index <= options.arrayLimit)
-        ) {
+        if (root === '[]') {
             obj = [];
-            obj[index] = parseObject(chain, val, options);
+            obj = obj.concat(leaf);
         } else {
-            obj[cleanRoot] = parseObject(chain, val, options);
+            obj = options.plainObjects ? Object.create(null) : {};
+            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
+            var index = parseInt(cleanRoot, 10);
+            if (
+                !isNaN(index)
+                && root !== cleanRoot
+                && String(index) === cleanRoot
+                && index >= 0
+                && (options.parseArrays && index <= options.arrayLimit)
+            ) {
+                obj = [];
+                obj[index] = leaf;
+            } else {
+                obj[cleanRoot] = leaf;
+            }
         }
+
+        leaf = obj;
     }
 
-    return obj;
+    return leaf;
 };
 
-var parseKeys = function parseKeys(givenKey, val, options) {
+var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
     if (!givenKey) {
         return;
     }
 
     // Transform dot notation to bracket notation
-    var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey;
+    var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
 
     // The regex chunks
 
-    var parent = /^([^\[\]]*)/;
-    var child = /(\[[^\[\]]*\])/g;
+    var brackets = /(\[[^[\]]*])/;
+    var child = /(\[[^[\]]*])/g;
 
     // Get the parent
 
-    var segment = parent.exec(key);
+    var segment = brackets.exec(key);
+    var parent = segment ? key.slice(0, segment.index) : key;
 
     // Stash the parent if it exists
 
     var keys = [];
-    if (segment[1]) {
+    if (parent) {
         // If we aren't using plain objects, optionally prefix keys
         // that would overwrite object prototype properties
-        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
+        if (!options.plainObjects && has.call(Object.prototype, parent)) {
             if (!options.allowPrototypes) {
                 return;
             }
         }
 
-        keys.push(segment[1]);
+        keys.push(parent);
     }
 
     // Loop through children appending to the array until we hit depth
@@ -112,9 +118,9 @@ var parseKeys = function parseKeys(givenKey, val, options) {
     var i = 0;
     while ((segment = child.exec(key)) !== null && i < options.depth) {
         i += 1;
-        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
+        if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
             if (!options.allowPrototypes) {
-                continue;
+                return;
             }
         }
         keys.push(segment[1]);
@@ -130,13 +136,14 @@ var parseKeys = function parseKeys(givenKey, val, options) {
 };
 
 module.exports = function (str, opts) {
-    var options = opts || {};
+    var options = opts ? utils.assign({}, opts) : {};
 
     if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
         throw new TypeError('Decoder has to be a function.');
     }
 
-    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
+    options.ignoreQueryPrefix = options.ignoreQueryPrefix === true;
+    options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
     options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
     options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
     options.parseArrays = options.parseArrays !== false;
@@ -160,8 +167,8 @@ module.exports = function (str, opts) {
     for (var i = 0; i < keys.length; ++i) {
         var key = keys[i];
         var newObj = parseKeys(key, tempObj[key], options);
-        obj = Utils.merge(obj, newObj, options);
+        obj = utils.merge(obj, newObj, options);
     }
 
-    return Utils.compact(obj);
+    return utils.compact(obj);
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/stringify.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/stringify.js
old mode 100755
new mode 100644
index 6e1c9a263..ab915ac46
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/stringify.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/stringify.js
@@ -1,46 +1,67 @@
 'use strict';
 
-var Utils = require('./utils');
+var utils = require('./utils');
+var formats = require('./formats');
 
 var arrayPrefixGenerators = {
-    brackets: function brackets(prefix) {
+    brackets: function brackets(prefix) { // eslint-disable-line func-name-matching
         return prefix + '[]';
     },
-    indices: function indices(prefix, key) {
+    indices: function indices(prefix, key) { // eslint-disable-line func-name-matching
         return prefix + '[' + key + ']';
     },
-    repeat: function repeat(prefix) {
+    repeat: function repeat(prefix) { // eslint-disable-line func-name-matching
         return prefix;
     }
 };
 
+var toISO = Date.prototype.toISOString;
+
 var defaults = {
     delimiter: '&',
-    strictNullHandling: false,
-    skipNulls: false,
     encode: true,
-    encoder: Utils.encode
+    encoder: utils.encode,
+    encodeValuesOnly: false,
+    serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching
+        return toISO.call(date);
+    },
+    skipNulls: false,
+    strictNullHandling: false
 };
 
-var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
+var stringify = function stringify( // eslint-disable-line func-name-matching
+    object,
+    prefix,
+    generateArrayPrefix,
+    strictNullHandling,
+    skipNulls,
+    encoder,
+    filter,
+    sort,
+    allowDots,
+    serializeDate,
+    formatter,
+    encodeValuesOnly
+) {
     var obj = object;
     if (typeof filter === 'function') {
         obj = filter(prefix, obj);
     } else if (obj instanceof Date) {
-        obj = obj.toISOString();
+        obj = serializeDate(obj);
     } else if (obj === null) {
         if (strictNullHandling) {
-            return encoder ? encoder(prefix) : prefix;
+            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix;
         }
 
         obj = '';
     }
 
-    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
+    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) {
         if (encoder) {
-            return [encoder(prefix) + '=' + encoder(obj)];
+            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder);
+            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))];
         }
-        return [prefix + '=' + String(obj)];
+        return [formatter(prefix) + '=' + formatter(String(obj))];
     }
 
     var values = [];
@@ -65,9 +86,35 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
         }
 
         if (Array.isArray(obj)) {
-            values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
+            values = values.concat(stringify(
+                obj[key],
+                generateArrayPrefix(prefix, key),
+                generateArrayPrefix,
+                strictNullHandling,
+                skipNulls,
+                encoder,
+                filter,
+                sort,
+                allowDots,
+                serializeDate,
+                formatter,
+                encodeValuesOnly
+            ));
         } else {
-            values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
+            values = values.concat(stringify(
+                obj[key],
+                prefix + (allowDots ? '.' + key : '[' + key + ']'),
+                generateArrayPrefix,
+                strictNullHandling,
+                skipNulls,
+                encoder,
+                filter,
+                sort,
+                allowDots,
+                serializeDate,
+                formatter,
+                encodeValuesOnly
+            ));
         }
     }
 
@@ -76,26 +123,36 @@ var stringify = function stringify(object, prefix, generateArrayPrefix, strictNu
 
 module.exports = function (object, opts) {
     var obj = object;
-    var options = opts || {};
+    var options = opts ? utils.assign({}, opts) : {};
+
+    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
+        throw new TypeError('Encoder has to be a function.');
+    }
+
     var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
     var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
     var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
     var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
-    var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
+    var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder;
     var sort = typeof options.sort === 'function' ? options.sort : null;
     var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
+    var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate;
+    var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly;
+    if (typeof options.format === 'undefined') {
+        options.format = formats['default'];
+    } else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) {
+        throw new TypeError('Unknown format option provided.');
+    }
+    var formatter = formats.formatters[options.format];
     var objKeys;
     var filter;
 
-    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
-        throw new TypeError('Encoder has to be a function.');
-    }
-
     if (typeof options.filter === 'function') {
         filter = options.filter;
         obj = filter('', obj);
     } else if (Array.isArray(options.filter)) {
-        objKeys = filter = options.filter;
+        filter = options.filter;
+        objKeys = filter;
     }
 
     var keys = [];
@@ -130,8 +187,24 @@ module.exports = function (object, opts) {
             continue;
         }
 
-        keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
+        keys = keys.concat(stringify(
+            obj[key],
+            key,
+            generateArrayPrefix,
+            strictNullHandling,
+            skipNulls,
+            encode ? encoder : null,
+            filter,
+            sort,
+            allowDots,
+            serializeDate,
+            formatter,
+            encodeValuesOnly
+        ));
     }
 
-    return keys.join(delimiter);
+    var joined = keys.join(delimiter);
+    var prefix = options.addQueryPrefix === true ? '?' : '';
+
+    return joined.length > 0 ? prefix + joined : '';
 };
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/utils.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/utils.js
old mode 100755
new mode 100644
index 2c5c8ee50..06cae2f09
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/utils.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/lib/utils.js
@@ -1,16 +1,41 @@
 'use strict';
 
+var has = Object.prototype.hasOwnProperty;
+
 var hexTable = (function () {
-    var array = new Array(256);
+    var array = [];
     for (var i = 0; i < 256; ++i) {
-        array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
+        array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
     }
 
     return array;
 }());
 
-exports.arrayToObject = function (source, options) {
-    var obj = options.plainObjects ? Object.create(null) : {};
+var compactQueue = function compactQueue(queue) {
+    var obj;
+
+    while (queue.length) {
+        var item = queue.pop();
+        obj = item.obj[item.prop];
+
+        if (Array.isArray(obj)) {
+            var compacted = [];
+
+            for (var j = 0; j < obj.length; ++j) {
+                if (typeof obj[j] !== 'undefined') {
+                    compacted.push(obj[j]);
+                }
+            }
+
+            item.obj[item.prop] = compacted;
+        }
+    }
+
+    return obj;
+};
+
+exports.arrayToObject = function arrayToObject(source, options) {
+    var obj = options && options.plainObjects ? Object.create(null) : {};
     for (var i = 0; i < source.length; ++i) {
         if (typeof source[i] !== 'undefined') {
             obj[i] = source[i];
@@ -20,7 +45,7 @@ exports.arrayToObject = function (source, options) {
     return obj;
 };
 
-exports.merge = function (target, source, options) {
+exports.merge = function merge(target, source, options) {
     if (!source) {
         return target;
     }
@@ -29,7 +54,9 @@ exports.merge = function (target, source, options) {
         if (Array.isArray(target)) {
             target.push(source);
         } else if (typeof target === 'object') {
-            target[source] = true;
+            if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) {
+                target[source] = true;
+            }
         } else {
             return [target, source];
         }
@@ -46,10 +73,25 @@ exports.merge = function (target, source, options) {
         mergeTarget = exports.arrayToObject(target, options);
     }
 
+    if (Array.isArray(target) && Array.isArray(source)) {
+        source.forEach(function (item, i) {
+            if (has.call(target, i)) {
+                if (target[i] && typeof target[i] === 'object') {
+                    target[i] = exports.merge(target[i], item, options);
+                } else {
+                    target.push(item);
+                }
+            } else {
+                target[i] = item;
+            }
+        });
+        return target;
+    }
+
     return Object.keys(source).reduce(function (acc, key) {
         var value = source[key];
 
-        if (Object.prototype.hasOwnProperty.call(acc, key)) {
+        if (has.call(acc, key)) {
             acc[key] = exports.merge(acc[key], value, options);
         } else {
             acc[key] = value;
@@ -58,6 +100,13 @@ exports.merge = function (target, source, options) {
     }, mergeTarget);
 };
 
+exports.assign = function assignSingleSource(target, source) {
+    return Object.keys(source).reduce(function (acc, key) {
+        acc[key] = source[key];
+        return acc;
+    }, target);
+};
+
 exports.decode = function (str) {
     try {
         return decodeURIComponent(str.replace(/\+/g, ' '));
@@ -66,7 +115,7 @@ exports.decode = function (str) {
     }
 };
 
-exports.encode = function (str) {
+exports.encode = function encode(str) {
     // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
     // It has been adapted here for stricter adherence to RFC 3986
     if (str.length === 0) {
@@ -80,13 +129,13 @@ exports.encode = function (str) {
         var c = string.charCodeAt(i);
 
         if (
-            c === 0x2D || // -
-            c === 0x2E || // .
-            c === 0x5F || // _
-            c === 0x7E || // ~
-            (c >= 0x30 && c <= 0x39) || // 0-9
-            (c >= 0x41 && c <= 0x5A) || // a-z
-            (c >= 0x61 && c <= 0x7A) // A-Z
+            c === 0x2D // -
+            || c === 0x2E // .
+            || c === 0x5F // _
+            || c === 0x7E // ~
+            || (c >= 0x30 && c <= 0x39) // 0-9
+            || (c >= 0x41 && c <= 0x5A) // a-z
+            || (c >= 0x61 && c <= 0x7A) // A-Z
         ) {
             out += string.charAt(i);
             continue;
@@ -109,53 +158,42 @@ exports.encode = function (str) {
 
         i += 1;
         c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
-        out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
+        out += hexTable[0xF0 | (c >> 18)]
+            + hexTable[0x80 | ((c >> 12) & 0x3F)]
+            + hexTable[0x80 | ((c >> 6) & 0x3F)]
+            + hexTable[0x80 | (c & 0x3F)];
     }
 
     return out;
 };
 
-exports.compact = function (obj, references) {
-    if (typeof obj !== 'object' || obj === null) {
-        return obj;
-    }
-
-    var refs = references || [];
-    var lookup = refs.indexOf(obj);
-    if (lookup !== -1) {
-        return refs[lookup];
-    }
-
-    refs.push(obj);
-
-    if (Array.isArray(obj)) {
-        var compacted = [];
-
-        for (var i = 0; i < obj.length; ++i) {
-            if (obj[i] && typeof obj[i] === 'object') {
-                compacted.push(exports.compact(obj[i], refs));
-            } else if (typeof obj[i] !== 'undefined') {
-                compacted.push(obj[i]);
+exports.compact = function compact(value) {
+    var queue = [{ obj: { o: value }, prop: 'o' }];
+    var refs = [];
+
+    for (var i = 0; i < queue.length; ++i) {
+        var item = queue[i];
+        var obj = item.obj[item.prop];
+
+        var keys = Object.keys(obj);
+        for (var j = 0; j < keys.length; ++j) {
+            var key = keys[j];
+            var val = obj[key];
+            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
+                queue.push({ obj: obj, prop: key });
+                refs.push(val);
             }
         }
-
-        return compacted;
     }
 
-    var keys = Object.keys(obj);
-    for (var j = 0; j < keys.length; ++j) {
-        var key = keys[j];
-        obj[key] = exports.compact(obj[key], refs);
-    }
-
-    return obj;
+    return compactQueue(queue);
 };
 
-exports.isRegExp = function (obj) {
+exports.isRegExp = function isRegExp(obj) {
     return Object.prototype.toString.call(obj) === '[object RegExp]';
 };
 
-exports.isBuffer = function (obj) {
+exports.isBuffer = function isBuffer(obj) {
     if (obj === null || typeof obj === 'undefined') {
         return false;
     }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/package.json
index 7aed9ed6a..ec2f72cb1 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/package.json
@@ -1,53 +1,32 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "qs@6.2.0",
-        "scope": null,
-        "escapedName": "qs",
-        "name": "qs",
-        "rawSpec": "6.2.0",
-        "spec": "6.2.0",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "qs@6.2.0",
-  "_id": "qs@6.2.0",
-  "_inCache": true,
+  "_from": "qs@6.5.1",
+  "_id": "qs@6.5.1",
+  "_inBundle": false,
+  "_integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
   "_location": "/qs",
-  "_nodeVersion": "6.1.0",
-  "_npmOperationalInternal": {
-    "host": "packages-12-west.internal.npmjs.com",
-    "tmp": "tmp/qs-6.2.0.tgz_1462749349998_0.03372702235355973"
-  },
-  "_npmUser": {
-    "name": "ljharb",
-    "email": "ljharb@gmail.com"
-  },
-  "_npmVersion": "3.8.6",
   "_phantomChildren": {},
   "_requested": {
-    "raw": "qs@6.2.0",
-    "scope": null,
-    "escapedName": "qs",
+    "type": "version",
+    "registry": true,
+    "raw": "qs@6.5.1",
     "name": "qs",
-    "rawSpec": "6.2.0",
-    "spec": "6.2.0",
-    "type": "version"
+    "escapedName": "qs",
+    "rawSpec": "6.5.1",
+    "saveSpec": null,
+    "fetchSpec": "6.5.1"
   },
   "_requiredBy": [
+    "/body-parser",
     "/express"
   ],
-  "_resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz",
-  "_shasum": "3b7848c03c2dece69a9522b0fae8c4126d745f3b",
-  "_shrinkwrap": null,
-  "_spec": "qs@6.2.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+  "_shasum": "349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8",
+  "_spec": "qs@6.5.1",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "bugs": {
     "url": "https://github.com/ljharb/qs/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Jordan Harband",
@@ -56,27 +35,24 @@
     }
   ],
   "dependencies": {},
+  "deprecated": false,
   "description": "A querystring parser that supports nesting and arrays, with a depth limit",
   "devDependencies": {
-    "@ljharb/eslint-config": "^4.0.0",
-    "browserify": "^13.0.1",
+    "@ljharb/eslint-config": "^12.2.1",
+    "browserify": "^14.4.0",
     "covert": "^1.1.0",
-    "eslint": "^2.9.0",
+    "editorconfig-tools": "^0.1.1",
+    "eslint": "^4.6.1",
     "evalmd": "^0.0.17",
-    "iconv-lite": "^0.4.13",
+    "iconv-lite": "^0.4.18",
     "mkdirp": "^0.5.1",
-    "parallelshell": "^2.0.0",
-    "tape": "^4.5.1"
-  },
-  "directories": {},
-  "dist": {
-    "shasum": "3b7848c03c2dece69a9522b0fae8c4126d745f3b",
-    "tarball": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz"
+    "qs-iconv": "^1.0.4",
+    "safe-publish-latest": "^1.1.1",
+    "tape": "^4.8.0"
   },
   "engines": {
     "node": ">=0.6"
   },
-  "gitHead": "d67d315b606c6bb809fedcbeebbbdb7f863852aa",
   "homepage": "https://github.com/ljharb/qs",
   "keywords": [
     "querystring",
@@ -84,23 +60,7 @@
   ],
   "license": "BSD-3-Clause",
   "main": "lib/index.js",
-  "maintainers": [
-    {
-      "name": "hueniverse",
-      "email": "eran@hammer.io"
-    },
-    {
-      "name": "ljharb",
-      "email": "ljharb@gmail.com"
-    },
-    {
-      "name": "nlf",
-      "email": "quitlahok@gmail.com"
-    }
-  ],
   "name": "qs",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/ljharb/qs.git"
@@ -108,12 +68,13 @@
   "scripts": {
     "coverage": "covert test",
     "dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js",
-    "lint": "eslint lib/*.js text/*.js",
-    "prepublish": "npm run dist",
-    "pretest": "parallelshell 'npm run --silent readme' 'npm run --silent lint'",
+    "lint": "eslint lib/*.js test/*.js",
+    "prelint": "editorconfig-tools check * lib/* test/*",
+    "prepublish": "safe-publish-latest && npm run dist",
+    "pretest": "npm run --silent readme && npm run --silent lint",
     "readme": "evalmd README.md",
     "test": "npm run --silent coverage",
     "tests-only": "node test"
   },
-  "version": "6.2.0"
+  "version": "6.5.1"
 }
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/index.js
index b6a7d9526..5e6bc8fbd 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/index.js
@@ -1,3 +1,5 @@
+'use strict';
+
 require('./parse');
 
 require('./stringify');
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/parse.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/parse.js
old mode 100755
new mode 100644
index 1b79daf53..d7d864192
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/parse.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/parse.js
@@ -2,11 +2,12 @@
 
 var test = require('tape');
 var qs = require('../');
+var utils = require('../lib/utils');
 var iconv = require('iconv-lite');
 
 test('parse()', function (t) {
     t.test('parses a simple string', function (st) {
-        st.deepEqual(qs.parse('0=foo'), { '0': 'foo' });
+        st.deepEqual(qs.parse('0=foo'), { 0: 'foo' });
         st.deepEqual(qs.parse('foo=c++'), { foo: 'c  ' });
         st.deepEqual(qs.parse('a[>=]=23'), { a: { '>=': '23' } });
         st.deepEqual(qs.parse('a[<=>]==23'), { a: { '<=>': '=23' } });
@@ -64,8 +65,15 @@ test('parse()', function (t) {
         st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
         st.deepEqual(qs.parse('a[0]=b&a=c'), { a: ['b', 'c'] });
         st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] });
-        st.deepEqual(qs.parse('a[1]=b&a=c'), { a: ['b', 'c'] });
-        st.deepEqual(qs.parse('a=b&a[1]=c'), { a: ['b', 'c'] });
+
+        st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
+        st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
+        st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
+
+        st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
+        st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
+        st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
+
         st.end();
     });
 
@@ -78,13 +86,15 @@ test('parse()', function (t) {
     t.test('allows to specify array indices', function (st) {
         st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] });
         st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] });
+        st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 20 }), { a: ['c'] });
+        st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 0 }), { a: { 1: 'c' } });
         st.deepEqual(qs.parse('a[1]=c'), { a: ['c'] });
         st.end();
     });
 
-    t.test('limits specific array indices to 20', function (st) {
-        st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
-        st.deepEqual(qs.parse('a[21]=a'), { a: { '21': 'a' } });
+    t.test('limits specific array indices to arrayLimit', function (st) {
+        st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] });
+        st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } });
         st.end();
     });
 
@@ -115,14 +125,17 @@ test('parse()', function (t) {
     });
 
     t.test('transforms arrays to objects', function (st) {
-        st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
-        st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
-        st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
-        st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
-        st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
+        st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } });
+        st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', 0: 'bar' } });
+        st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', 0: 'bar' } });
+        st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } });
+        st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } });
         st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
-        st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c'), { a: { '0': 'b', t: 'u', c: true } });
-        st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y'), { a: { '0': 'b', '1': 'c', x: 'y' } });
+
+        st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: false }), { a: { 0: 'b', t: 'u' } });
+        st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } });
+        st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } });
+        st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } });
         st.end();
     });
 
@@ -132,18 +145,16 @@ test('parse()', function (t) {
         st.deepEqual(qs.parse('foo[0][0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } });
         st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15'], bar: '2' }] });
         st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15', '16'], bar: '2' }] });
-        st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
-        st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
-        st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { '0': 'bar', bad: 'baz' } });
-        st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
+        st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } });
+        st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } });
+        st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { 0: 'bar', bad: 'baz' } });
+        st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } });
         st.deepEqual(qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true }), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
         st.end();
     });
 
-    t.deepEqual(qs.parse('a[b]=c&a=d'), { a: { b: 'c', d: true } }, 'can add keys to objects');
-
     t.test('correctly prunes undefined values when converting an array to an object', function (st) {
-        st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } });
+        st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { 2: 'b', 99999999: 'c' } });
         st.end();
     });
 
@@ -155,7 +166,7 @@ test('parse()', function (t) {
     });
 
     t.test('doesn\'t produce empty keys', function (st) {
-        st.deepEqual(qs.parse('_r=1&'), { '_r': '1' });
+        st.deepEqual(qs.parse('_r=1&'), { _r: '1' });
         st.end();
     });
 
@@ -174,17 +185,42 @@ test('parse()', function (t) {
 
     t.test('allows for empty strings in arrays', function (st) {
         st.deepEqual(qs.parse('a[]=b&a[]=&a[]=c'), { a: ['b', '', 'c'] });
-        st.deepEqual(qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true }), { a: ['b', null, 'c', ''] });
-        st.deepEqual(qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true }), { a: ['b', '', 'c', null] });
-        st.deepEqual(qs.parse('a[]=&a[]=b&a[]=c'), { a: ['', 'b', 'c'] });
+
+        st.deepEqual(
+            qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true, arrayLimit: 20 }),
+            { a: ['b', null, 'c', ''] },
+            'with arrayLimit 20 + array indices: null then empty string works'
+        );
+        st.deepEqual(
+            qs.parse('a[]=b&a[]&a[]=c&a[]=', { strictNullHandling: true, arrayLimit: 0 }),
+            { a: ['b', null, 'c', ''] },
+            'with arrayLimit 0 + array brackets: null then empty string works'
+        );
+
+        st.deepEqual(
+            qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true, arrayLimit: 20 }),
+            { a: ['b', '', 'c', null] },
+            'with arrayLimit 20 + array indices: empty string then null works'
+        );
+        st.deepEqual(
+            qs.parse('a[]=b&a[]=&a[]=c&a[]', { strictNullHandling: true, arrayLimit: 0 }),
+            { a: ['b', '', 'c', null] },
+            'with arrayLimit 0 + array brackets: empty string then null works'
+        );
+
+        st.deepEqual(
+            qs.parse('a[]=&a[]=b&a[]=c'),
+            { a: ['', 'b', 'c'] },
+            'array brackets: empty strings work'
+        );
         st.end();
     });
 
     t.test('compacts sparse arrays', function (st) {
-        st.deepEqual(qs.parse('a[10]=1&a[2]=2'), { a: ['2', '1'] });
-        st.deepEqual(qs.parse('a[1][b][2][c]=1'), { a: [{ b: [{ c: '1' }] }] });
-        st.deepEqual(qs.parse('a[1][2][3][c]=1'), { a: [[[{ c: '1' }]]] });
-        st.deepEqual(qs.parse('a[1][2][3][c][1]=1'), { a: [[[{ c: ['1'] }]]] });
+        st.deepEqual(qs.parse('a[10]=1&a[2]=2', { arrayLimit: 20 }), { a: ['2', '1'] });
+        st.deepEqual(qs.parse('a[1][b][2][c]=1', { arrayLimit: 20 }), { a: [{ b: [{ c: '1' }] }] });
+        st.deepEqual(qs.parse('a[1][2][3][c]=1', { arrayLimit: 20 }), { a: [[[{ c: '1' }]]] });
+        st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { arrayLimit: 20 }), { a: [[[{ c: ['1'] }]]] });
         st.end();
     });
 
@@ -201,8 +237,8 @@ test('parse()', function (t) {
     });
 
     t.test('continues parsing when no parent is found', function (st) {
-        st.deepEqual(qs.parse('[]=&a=b'), { '0': '', a: 'b' });
-        st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { '0': null, a: 'b' });
+        st.deepEqual(qs.parse('[]=&a=b'), { 0: '', a: 'b' });
+        st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { 0: null, a: 'b' });
         st.deepEqual(qs.parse('[foo]=bar'), { foo: 'bar' });
         st.end();
     });
@@ -213,7 +249,9 @@ test('parse()', function (t) {
             str = str + '&' + str;
         }
 
-        st.doesNotThrow(function () { qs.parse(str); });
+        st.doesNotThrow(function () {
+            qs.parse(str);
+        });
 
         st.end();
     });
@@ -256,14 +294,21 @@ test('parse()', function (t) {
     });
 
     t.test('allows overriding array limit', function (st) {
-        st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { '0': 'b' } });
+        st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } });
         st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } });
-        st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { '0': 'b', '1': 'c' } });
+        st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
         st.end();
     });
 
     t.test('allows disabling array parsing', function (st) {
-        st.deepEqual(qs.parse('a[0]=b&a[1]=c', { parseArrays: false }), { a: { '0': 'b', '1': 'c' } });
+        st.deepEqual(qs.parse('a[0]=b&a[1]=c', { parseArrays: false }), { a: { 0: 'b', 1: 'c' } });
+        st.end();
+    });
+
+    t.test('allows for query string prefix', function (st) {
+        st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' });
+        st.deepEqual(qs.parse('foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' });
+        st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: false }), { '?foo': 'bar' });
         st.end();
     });
 
@@ -307,13 +352,13 @@ test('parse()', function (t) {
 
     t.test('parses an object and not child values', function (st) {
         var input = {
-            'user[name]': { 'pop[bob]': { 'test': 3 } },
+            'user[name]': { 'pop[bob]': { test: 3 } },
             'user[email]': null
         };
 
         var expected = {
             user: {
-                name: { 'pop[bob]': { 'test': 3 } },
+                name: { 'pop[bob]': { test: 3 } },
                 email: null
             }
         };
@@ -351,7 +396,34 @@ test('parse()', function (t) {
         st.end();
     });
 
-    t.test('parses plain objects correctly', function (st) {
+    t.test('does not crash when parsing deep objects', function (st) {
+        var parsed;
+        var str = 'foo';
+
+        for (var i = 0; i < 5000; i++) {
+            str += '[p]';
+        }
+
+        str += '=bar';
+
+        st.doesNotThrow(function () {
+            parsed = qs.parse(str, { depth: 5000 });
+        });
+
+        st.equal('foo' in parsed, true, 'parsed has "foo" property');
+
+        var depth = 0;
+        var ref = parsed.foo;
+        while ((ref = ref.p)) {
+            depth += 1;
+        }
+
+        st.equal(depth, 5000, 'parsed is 5000 properties deep');
+
+        st.end();
+    });
+
+    t.test('parses null objects correctly', { skip: !Object.create }, function (st) {
         var a = Object.create(null);
         a.b = 'c';
 
@@ -374,13 +446,75 @@ test('parse()', function (t) {
         st.end();
     });
 
+    t.test('does not allow overwriting prototype properties', function (st) {
+        st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {});
+        st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {});
+
+        st.deepEqual(
+            qs.parse('toString', { allowPrototypes: false }),
+            {},
+            'bare "toString" results in {}'
+        );
+
+        st.end();
+    });
+
     t.test('can allow overwriting prototype properties', function (st) {
-        st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } }, { prototype: false });
-        st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' }, { prototype: false });
+        st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } });
+        st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' });
+
+        st.deepEqual(
+            qs.parse('toString', { allowPrototypes: true }),
+            { toString: '' },
+            'bare "toString" results in { toString: "" }'
+        );
+
         st.end();
     });
 
-    t.test('can return plain objects', function (st) {
+    t.test('params starting with a closing bracket', function (st) {
+        st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
+        st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
+        st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' });
+        st.end();
+    });
+
+    t.test('params starting with a starting bracket', function (st) {
+        st.deepEqual(qs.parse('[=toString'), { '[': 'toString' });
+        st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' });
+        st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' });
+        st.end();
+    });
+
+    t.test('add keys to objects', function (st) {
+        st.deepEqual(
+            qs.parse('a[b]=c&a=d'),
+            { a: { b: 'c', d: true } },
+            'can add keys to objects'
+        );
+
+        st.deepEqual(
+            qs.parse('a[b]=c&a=toString'),
+            { a: { b: 'c' } },
+            'can not overwrite prototype'
+        );
+
+        st.deepEqual(
+            qs.parse('a[b]=c&a=toString', { allowPrototypes: true }),
+            { a: { b: 'c', toString: true } },
+            'can overwrite prototype with allowPrototypes true'
+        );
+
+        st.deepEqual(
+            qs.parse('a[b]=c&a=toString', { plainObjects: true }),
+            { a: { b: 'c', toString: true } },
+            'can overwrite prototype with plainObjects true'
+        );
+
+        st.end();
+    });
+
+    t.test('can return null objects', { skip: !Object.create }, function (st) {
         var expected = Object.create(null);
         expected.a = Object.create(null);
         expected.a.b = 'c';
@@ -389,7 +523,7 @@ test('parse()', function (t) {
         st.deepEqual(qs.parse(null, { plainObjects: true }), Object.create(null));
         var expectedArray = Object.create(null);
         expectedArray.a = Object.create(null);
-        expectedArray.a['0'] = 'b';
+        expectedArray.a[0] = 'b';
         expectedArray.a.c = 'd';
         st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray);
         st.end();
@@ -398,13 +532,12 @@ test('parse()', function (t) {
     t.test('can parse with custom encoding', function (st) {
         st.deepEqual(qs.parse('%8c%a7=%91%e5%8d%e3%95%7b', {
             decoder: function (str) {
-                var reg = /\%([0-9A-F]{2})/ig;
+                var reg = /%([0-9A-F]{2})/ig;
                 var result = [];
-                var parts;
-                var last = 0;
-                while (parts = reg.exec(str)) {
+                var parts = reg.exec(str);
+                while (parts) {
                     result.push(parseInt(parts[1], 16));
-                    last = parts.index + parts[0].length;
+                    parts = reg.exec(str);
                 }
                 return iconv.decode(new Buffer(result), 'shift_jis').toString();
             }
@@ -412,12 +545,29 @@ test('parse()', function (t) {
         st.end();
     });
 
+    t.test('receives the default decoder as a second argument', function (st) {
+        st.plan(1);
+        qs.parse('a', {
+            decoder: function (str, defaultDecoder) {
+                st.equal(defaultDecoder, utils.decode);
+            }
+        });
+        st.end();
+    });
+
     t.test('throws error with wrong decoder', function (st) {
-        st.throws(function () {
-            qs.parse({}, {
-                decoder: 'string'
-            });
+        st['throws'](function () {
+            qs.parse({}, { decoder: 'string' });
         }, new TypeError('Decoder has to be a function.'));
         st.end();
     });
+
+    t.test('does not mutate the options argument', function (st) {
+        var options = {};
+        qs.parse('a[b]=true', options);
+        st.deepEqual(options, {});
+        st.end();
+    });
+
+    t.end();
 });
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/stringify.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/stringify.js
old mode 100755
new mode 100644
index 699397e33..124a99dca
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/stringify.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/stringify.js
@@ -2,6 +2,7 @@
 
 var test = require('tape');
 var qs = require('../');
+var utils = require('../lib/utils');
 var iconv = require('iconv-lite');
 
 test('stringify()', function (t) {
@@ -17,6 +18,16 @@ test('stringify()', function (t) {
         st.end();
     });
 
+    t.test('adds query prefix', function (st) {
+        st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b');
+        st.end();
+    });
+
+    t.test('with query prefix, outputs blank string given an empty object', function (st) {
+        st.equal(qs.stringify({}, { addQueryPrefix: true }), '');
+        st.end();
+    });
+
     t.test('stringifies a nested object', function (st) {
         st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');
         st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }), 'a%5Bb%5D%5Bc%5D%5Bd%5D=e');
@@ -30,7 +41,21 @@ test('stringify()', function (t) {
     });
 
     t.test('stringifies an array value', function (st) {
-        st.equal(qs.stringify({ a: ['b', 'c', 'd'] }), 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d');
+        st.equal(
+            qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }),
+            'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
+            'indices => indices'
+        );
+        st.equal(
+            qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }),
+            'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify({ a: ['b', 'c', 'd'] }),
+            'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
+            'default => indices'
+        );
         st.end();
     });
 
@@ -39,7 +64,6 @@ test('stringify()', function (t) {
         st.end();
     });
 
-
     t.test('omits nested nulls when asked', function (st) {
         st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c');
         st.end();
@@ -51,29 +75,149 @@ test('stringify()', function (t) {
     });
 
     t.test('stringifies a nested array value', function (st) {
+        st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
+        st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d');
         st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
         st.end();
     });
 
     t.test('stringifies a nested array value with dots notation', function (st) {
-        st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encode: false }), 'a.b[0]=c&a.b[1]=d');
+        st.equal(
+            qs.stringify(
+                { a: { b: ['c', 'd'] } },
+                { allowDots: true, encode: false, arrayFormat: 'indices' }
+            ),
+            'a.b[0]=c&a.b[1]=d',
+            'indices: stringifies with dots + indices'
+        );
+        st.equal(
+            qs.stringify(
+                { a: { b: ['c', 'd'] } },
+                { allowDots: true, encode: false, arrayFormat: 'brackets' }
+            ),
+            'a.b[]=c&a.b[]=d',
+            'brackets: stringifies with dots + brackets'
+        );
+        st.equal(
+            qs.stringify(
+                { a: { b: ['c', 'd'] } },
+                { allowDots: true, encode: false }
+            ),
+            'a.b[0]=c&a.b[1]=d',
+            'default: stringifies with dots + indices'
+        );
         st.end();
     });
 
     t.test('stringifies an object inside an array', function (st) {
-        st.equal(qs.stringify({ a: [{ b: 'c' }] }), 'a%5B0%5D%5Bb%5D=c');
-        st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }), 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1');
+        st.equal(
+            qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
+            'a%5B0%5D%5Bb%5D=c',
+            'indices => brackets'
+        );
+        st.equal(
+            qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }),
+            'a%5B%5D%5Bb%5D=c',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify({ a: [{ b: 'c' }] }),
+            'a%5B0%5D%5Bb%5D=c',
+            'default => indices'
+        );
+
+        st.equal(
+            qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }),
+            'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
+            'indices => indices'
+        );
+
+        st.equal(
+            qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets' }),
+            'a%5B%5D%5Bb%5D%5Bc%5D%5B%5D=1',
+            'brackets => brackets'
+        );
+
+        st.equal(
+            qs.stringify({ a: [{ b: { c: [1] } }] }),
+            'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
+            'default => indices'
+        );
+
         st.end();
     });
 
     t.test('stringifies an array with mixed objects and primitives', function (st) {
-        st.equal(qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }), 'a[0][b]=1&a[1]=2&a[2]=3');
+        st.equal(
+            qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'indices' }),
+            'a[0][b]=1&a[1]=2&a[2]=3',
+            'indices => indices'
+        );
+        st.equal(
+            qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'brackets' }),
+            'a[][b]=1&a[]=2&a[]=3',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }),
+            'a[0][b]=1&a[1]=2&a[2]=3',
+            'default => indices'
+        );
+
         st.end();
     });
 
     t.test('stringifies an object inside an array with dots notation', function (st) {
-        st.equal(qs.stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false }), 'a[0].b=c');
-        st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false }), 'a[0].b.c[0]=1');
+        st.equal(
+            qs.stringify(
+                { a: [{ b: 'c' }] },
+                { allowDots: true, encode: false, arrayFormat: 'indices' }
+            ),
+            'a[0].b=c',
+            'indices => indices'
+        );
+        st.equal(
+            qs.stringify(
+                { a: [{ b: 'c' }] },
+                { allowDots: true, encode: false, arrayFormat: 'brackets' }
+            ),
+            'a[].b=c',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify(
+                { a: [{ b: 'c' }] },
+                { allowDots: true, encode: false }
+            ),
+            'a[0].b=c',
+            'default => indices'
+        );
+
+        st.equal(
+            qs.stringify(
+                { a: [{ b: { c: [1] } }] },
+                { allowDots: true, encode: false, arrayFormat: 'indices' }
+            ),
+            'a[0].b.c[0]=1',
+            'indices => indices'
+        );
+        st.equal(
+            qs.stringify(
+                { a: [{ b: { c: [1] } }] },
+                { allowDots: true, encode: false, arrayFormat: 'brackets' }
+            ),
+            'a[].b.c[]=1',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify(
+                { a: [{ b: { c: [1] } }] },
+                { allowDots: true, encode: false }
+            ),
+            'a[0].b.c[0]=1',
+            'default => indices'
+        );
+
         st.end();
     });
 
@@ -126,7 +270,7 @@ test('stringify()', function (t) {
         st.end();
     });
 
-    t.test('stringifies an empty object', function (st) {
+    t.test('stringifies a null object', { skip: !Object.create }, function (st) {
         var obj = Object.create(null);
         obj.a = 'b';
         st.equal(qs.stringify(obj), 'a=b');
@@ -141,10 +285,8 @@ test('stringify()', function (t) {
         st.end();
     });
 
-    t.test('stringifies an object with an empty object as a child', function (st) {
-        var obj = {
-            a: Object.create(null)
-        };
+    t.test('stringifies an object with a null object as a child', { skip: !Object.create }, function (st) {
+        var obj = { a: Object.create(null) };
 
         obj.a.b = 'c';
         st.equal(qs.stringify(obj), 'a%5Bb%5D=c');
@@ -216,7 +358,32 @@ test('stringify()', function (t) {
     t.test('selects properties when filter=array', function (st) {
         st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b');
         st.equal(qs.stringify({ a: 1 }, { filter: [] }), '');
-        st.equal(qs.stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2] }), 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3');
+
+        st.equal(
+            qs.stringify(
+                { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
+                { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' }
+            ),
+            'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
+            'indices => indices'
+        );
+        st.equal(
+            qs.stringify(
+                { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
+                { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' }
+            ),
+            'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3',
+            'brackets => brackets'
+        );
+        st.equal(
+            qs.stringify(
+                { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
+                { filter: ['a', 'b', 0, 2] }
+            ),
+            'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
+            'default => indices'
+        );
+
         st.end();
     });
 
@@ -224,12 +391,12 @@ test('stringify()', function (t) {
         var calls = 0;
         var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } };
         var filterFunc = function (prefix, value) {
-            calls++;
+            calls += 1;
             if (calls === 1) {
                 st.equal(prefix, '', 'prefix is empty');
                 st.equal(value, obj);
             } else if (prefix === 'c') {
-                return;
+                return void 0;
             } else if (value instanceof Date) {
                 st.equal(prefix, 'e[f]');
                 return value.getTime();
@@ -250,28 +417,44 @@ test('stringify()', function (t) {
     });
 
     t.test('can sort the keys', function (st) {
-        var sort = function (a, b) { return a.localeCompare(b); };
+        var sort = function (a, b) {
+            return a.localeCompare(b);
+        };
         st.equal(qs.stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y');
         st.equal(qs.stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a');
         st.end();
     });
 
     t.test('can sort the keys at depth 3 or more too', function (st) {
-        var sort = function (a, b) { return a.localeCompare(b); };
-        st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: sort, encode: false }), 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb');
-        st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: null, encode: false }), 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b');
+        var sort = function (a, b) {
+            return a.localeCompare(b);
+        };
+        st.equal(
+            qs.stringify(
+                { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
+                { sort: sort, encode: false }
+            ),
+            'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb'
+        );
+        st.equal(
+            qs.stringify(
+                { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
+                { sort: null, encode: false }
+            ),
+            'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b'
+        );
         st.end();
     });
 
     t.test('can stringify with custom encoding', function (st) {
-        st.equal(qs.stringify({ 県: '大阪府', '': ''}, {
+        st.equal(qs.stringify({ 県: '大阪府', '': '' }, {
             encoder: function (str) {
                 if (str.length === 0) {
                     return '';
                 }
                 var buf = iconv.encode(str, 'shiftjis');
                 var result = [];
-                for (var i=0; i < buf.length; ++i) {
+                for (var i = 0; i < buf.length; ++i) {
                     result.push(buf.readUInt8(i).toString(16));
                 }
                 return '%' + result.join('%');
@@ -280,18 +463,24 @@ test('stringify()', function (t) {
         st.end();
     });
 
+    t.test('receives the default encoder as a second argument', function (st) {
+        st.plan(2);
+        qs.stringify({ a: 1 }, {
+            encoder: function (str, defaultEncoder) {
+                st.equal(defaultEncoder, utils.encode);
+            }
+        });
+        st.end();
+    });
+
     t.test('throws error with wrong encoder', function (st) {
-        st.throws(function () {
-            qs.stringify({}, {
-                encoder: 'string'
-            });
+        st['throws'](function () {
+            qs.stringify({}, { encoder: 'string' });
         }, new TypeError('Encoder has to be a function.'));
         st.end();
     });
 
-    t.test('can use custom encoder for a buffer object', {
-        skip: typeof Buffer === 'undefined'
-    }, function (st) {
+    t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) {
         st.equal(qs.stringify({ a: new Buffer([1]) }, {
             encoder: function (buffer) {
                 if (typeof buffer === 'string') {
@@ -302,4 +491,106 @@ test('stringify()', function (t) {
         }), 'a=b');
         st.end();
     });
+
+    t.test('serializeDate option', function (st) {
+        var date = new Date();
+        st.equal(
+            qs.stringify({ a: date }),
+            'a=' + date.toISOString().replace(/:/g, '%3A'),
+            'default is toISOString'
+        );
+
+        var mutatedDate = new Date();
+        mutatedDate.toISOString = function () {
+            throw new SyntaxError();
+        };
+        st['throws'](function () {
+            mutatedDate.toISOString();
+        }, SyntaxError);
+        st.equal(
+            qs.stringify({ a: mutatedDate }),
+            'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'),
+            'toISOString works even when method is not locally present'
+        );
+
+        var specificDate = new Date(6);
+        st.equal(
+            qs.stringify(
+                { a: specificDate },
+                { serializeDate: function (d) { return d.getTime() * 7; } }
+            ),
+            'a=42',
+            'custom serializeDate function called'
+        );
+
+        st.end();
+    });
+
+    t.test('RFC 1738 spaces serialization', function (st) {
+        st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
+        st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
+        st.end();
+    });
+
+    t.test('RFC 3986 spaces serialization', function (st) {
+        st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
+        st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
+        st.end();
+    });
+
+    t.test('Backward compatibility to RFC 3986', function (st) {
+        st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
+        st.end();
+    });
+
+    t.test('Edge cases and unknown formats', function (st) {
+        ['UFO1234', false, 1234, null, {}, []].forEach(
+            function (format) {
+                st['throws'](
+                    function () {
+                        qs.stringify({ a: 'b c' }, { format: format });
+                    },
+                    new TypeError('Unknown format option provided.')
+                );
+            }
+        );
+        st.end();
+    });
+
+    t.test('encodeValuesOnly', function (st) {
+        st.equal(
+            qs.stringify(
+                { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
+                { encodeValuesOnly: true }
+            ),
+            'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'
+        );
+        st.equal(
+            qs.stringify(
+                { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }
+            ),
+            'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h'
+        );
+        st.end();
+    });
+
+    t.test('encodeValuesOnly - strictNullHandling', function (st) {
+        st.equal(
+            qs.stringify(
+                { a: { b: null } },
+                { encodeValuesOnly: true, strictNullHandling: true }
+            ),
+            'a[b]'
+        );
+        st.end();
+    });
+
+    t.test('does not mutate the options argument', function (st) {
+        var options = {};
+        qs.stringify({}, options);
+        st.deepEqual(options, {});
+        st.end();
+    });
+
+    t.end();
 });
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/utils.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/utils.js
old mode 100755
new mode 100644
index 4a8d8246c..eff4011a4
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/utils.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/qs/test/utils.js
@@ -5,5 +5,30 @@ var utils = require('../lib/utils');
 
 test('merge()', function (t) {
     t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key');
+
+    var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } });
+    t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array');
+
+    var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } });
+    t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array');
+
+    var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' });
+    t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array');
+
+    var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] });
+    t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] });
+
+    t.end();
+});
+
+test('assign()', function (t) {
+    var target = { a: 1, b: 2 };
+    var source = { b: 3, c: 4 };
+    var result = utils.assign(target, source);
+
+    t.equal(result, target, 'returns the target');
+    t.deepEqual(target, { a: 1, b: 3, c: 4 }, 'target and source are merged');
+    t.deepEqual(source, { b: 3, c: 4 }, 'source is untouched');
+
     t.end();
 });
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/range-parser/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/range-parser/package.json
index 69b0e86e8..efd3f6097 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/range-parser/package.json
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/range-parser/package.json
@@ -1,40 +1,19 @@
 {
-  "_args": [
-    [
-      {
-        "raw": "range-parser@~1.2.0",
-        "scope": null,
-        "escapedName": "range-parser",
-        "name": "range-parser",
-        "rawSpec": "~1.2.0",
-        "spec": ">=1.2.0 <1.3.0",
-        "type": "range"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express"
-    ]
-  ],
-  "_from": "range-parser@>=1.2.0 <1.3.0",
+  "_from": "range-parser@~1.2.0",
   "_id": "range-parser@1.2.0",
-  "_inCache": true,
+  "_inBundle": false,
+  "_integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
   "_location": "/range-parser",
-  "_npmOperationalInternal": {
-    "host": "packages-16-east.internal.npmjs.com",
-    "tmp": "tmp/range-parser-1.2.0.tgz_1464803293097_0.6830497414339334"
-  },
-  "_npmUser": {
-    "name": "dougwilson",
-    "email": "doug@somethingdoug.com"
-  },
-  "_npmVersion": "1.4.28",
   "_phantomChildren": {},
   "_requested": {
+    "type": "range",
+    "registry": true,
     "raw": "range-parser@~1.2.0",
-    "scope": null,
-    "escapedName": "range-parser",
     "name": "range-parser",
+    "escapedName": "range-parser",
     "rawSpec": "~1.2.0",
-    "spec": ">=1.2.0 <1.3.0",
-    "type": "range"
+    "saveSpec": null,
+    "fetchSpec": "~1.2.0"
   },
   "_requiredBy": [
     "/express",
@@ -42,9 +21,8 @@
   ],
   "_resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
   "_shasum": "f49be6b487894ddc40dcc94a322f611092e00d5e",
-  "_shrinkwrap": null,
   "_spec": "range-parser@~1.2.0",
-  "_where": "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/express",
+  "_where": "/Users/auso/cordova/cordova-browser/node_modules/express",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca",
@@ -53,6 +31,7 @@
   "bugs": {
     "url": "https://github.com/jshttp/range-parser/issues"
   },
+  "bundleDependencies": false,
   "contributors": [
     {
       "name": "Douglas Christopher Wilson",
@@ -68,7 +47,7 @@
       "url": "http://jongleberry.com"
     }
   ],
-  "dependencies": {},
+  "deprecated": false,
   "description": "Range header field string parser",
   "devDependencies": {
     "eslint": "2.11.1",
@@ -78,11 +57,6 @@
     "istanbul": "0.4.3",
     "mocha": "1.21.5"
   },
-  "directories": {},
-  "dist": {
-    "shasum": "f49be6b487894ddc40dcc94a322f611092e00d5e",
-    "tarball": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz"
-  },
   "engines": {
     "node": ">= 0.6"
   },
@@ -91,35 +65,14 @@
     "LICENSE",
     "index.js"
   ],
-  "gitHead": "0665aca31639d799dee1d35fb10970799559ec48",
-  "homepage": "https://github.com/jshttp/range-parser",
+  "homepage": "https://github.com/jshttp/range-parser#readme",
   "keywords": [
     "range",
     "parser",
     "http"
   ],
   "license": "MIT",
-  "maintainers": [
-    {
-      "name": "dougwilson",
-      "email": "doug@somethingdoug.com"
-    },
-    {
-      "name": "jonathanong",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "jongleberry",
-      "email": "jonathanrichardong@gmail.com"
-    },
-    {
-      "name": "tjholowaychuk",
-      "email": "tj@vision-media.ca"
-    }
-  ],
   "name": "range-parser",
-  "optionalDependencies": {},
-  "readme": "ERROR: No README data found!",
   "repository": {
     "type": "git",
     "url": "git+https://github.com/jshttp/range-parser.git"
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/HISTORY.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/HISTORY.md
index d8123cca7..1865dcd16 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/HISTORY.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/HISTORY.md
@@ -1,3 +1,99 @@
+0.16.1 / 2017-09-29
+===================
+
+  * Fix regression in edge-case behavior for empty `path`
+
+0.16.0 / 2017-09-27
+===================
+
+  * Add `immutable` option
+  * Fix missing `</html>` in default error & redirects
+  * Use instance methods on steam to check for listeners
+  * deps: mime@1.4.1
+    - Add 70 new types for file extensions
+    - Set charset as "UTF-8" for .js and .json
+  * perf: improve path validation speed
+
+0.15.6 / 2017-09-22
+===================
+
+  * deps: debug@2.6.9
+  * perf: improve `If-Match` token parsing
+
+0.15.5 / 2017-09-20
+===================
+
+  * deps: etag@~1.8.1
+    - perf: replace regular expression with substring
+  * deps: fresh@0.5.2
+    - Fix handling of modified headers with invalid dates
+    - perf: improve ETag match loop
+    - perf: improve `If-None-Match` token parsing
+
+0.15.4 / 2017-08-05
+===================
+
+  * deps: debug@2.6.8
+  * deps: depd@~1.1.1
+    - Remove unnecessary `Buffer` loading
+  * deps: http-errors@~1.6.2
+    - deps: depd@1.1.1
+
+0.15.3 / 2017-05-16
+===================
+
+  * deps: debug@2.6.7
+    - deps: ms@2.0.0
+  * deps: ms@2.0.0
+
+0.15.2 / 2017-04-26
+===================
+
+  * deps: debug@2.6.4
+    - Fix `DEBUG_MAX_ARRAY_LENGTH`
+    - deps: ms@0.7.3
+  * deps: ms@1.0.0
+
+0.15.1 / 2017-03-04
+===================
+
+  * Fix issue when `Date.parse` does not return `NaN` on invalid date
+  * Fix strict violation in broken environments
+
+0.15.0 / 2017-02-25
+===================
+
+  * Support `If-Match` and `If-Unmodified-Since` headers
+  * Add `res` and `path` arguments to `directory` event
+  * Remove usage of `res._headers` private field
+    - Improves compatibility with Node.js 8 nightly
+  * Send complete HTML document in redirect & error responses
+  * Set default CSP header in redirect & error responses
+  * Use `res.getHeaderNames()` when available
+  * Use `res.headersSent` when available
+  * deps: debug@2.6.1
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable set to `3` or higher
+    - Fix error when running under React Native
+    - Use same color for same namespace
+    - deps: ms@0.7.2
+  * deps: etag@~1.8.0
+  * deps: fresh@0.5.0
+    - Fix false detection of `no-cache` request directive
+    - Fix incorrect result when `If-None-Match` has both `*` and ETags
+    - Fix weak `ETag` matching to match spec
+    - perf: delay reading header values until needed
+    - perf: enable strict mode
+    - perf: hoist regular expressions
+    - perf: remove duplicate conditional
+    - perf: remove unnecessary boolean coercions
+    - perf: skip checking modified time if ETag check failed
+    - perf: skip parsing `If-None-Match` when no `ETag` header
+    - perf: use `Date.parse` instead of `new Date`
+  * deps: http-errors@~1.6.1
+    - Make `message` property enumerable for `HttpError`s
+    - deps: setprototypeof@1.0.3
+
 0.14.2 / 2017-01-23
 ===================
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/README.md
index 0453578c4..ca591ed4c 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/README.md
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/README.md
@@ -8,9 +8,10 @@
 [![Gratipay][gratipay-image]][gratipay-url]
 
 Send is a library for streaming files from the file system as a http response
-supporting partial responses (Ranges), conditional-GET negotiation, high test
-coverage, and granular events which may be leveraged to take appropriate actions
-in your application or framework.
+supporting partial responses (Ranges), conditional-GET negotiation (If-Match,
+If-Unmodified-Since, If-None-Match, If-Modified-Since), high test coverage,
+and granular events which may be leveraged to take appropriate actions in your
+application or framework.
 
 Looking to serve up entire folders mapped to URLs? Try [serve-static](https://www.npmjs.org/package/serve-static).
 
@@ -26,6 +27,8 @@ $ npm install send
 
 ## API
 
+<!-- eslint-disable no-unused-vars -->
+
 ```js
 var send = require('send')
 ```
@@ -47,7 +50,7 @@ of the `Range` request header.
 ##### cacheControl
 
 Enable or disable setting `Cache-Control` response header, defaults to
-true. Disabling this will ignore the `maxAge` option.
+true. Disabling this will ignore the `immutable` and `maxAge` options.
 
 ##### dotfiles
 
@@ -83,6 +86,14 @@ in the given order. By default, this is disabled (set to `false`). An
 example value that will serve extension-less HTML files: `['html', 'htm']`.
 This is skipped if the requested file already has an extension.
 
+##### immutable
+
+Enable or diable the `immutable` directive in the `Cache-Control` response
+header, defaults to `false`. If set to `true`, the `maxAge` option should
+also be specified to enable caching. The `immutable` directive will prevent
+supported clients from making conditional requests during the life of the
+`maxAge` option to check if the file has changed.
+
 ##### index
 
 By default send supports "index.html" files, to disable this
@@ -114,7 +125,7 @@ meaning `start: 2` will include the 3rd byte in the stream.
 The `SendStream` is an event emitter and will emit the following events:
 
   - `error` an error occurred `(err)`
-  - `directory` a directory was requested
+  - `directory` a directory was requested `(res, path)`
   - `file` a file was requested `(path, stat)`
   - `headers` the headers are about to be set on a file `(res, path, stat)`
   - `stream` file streaming has started `(stream)`
@@ -171,9 +182,11 @@ var http = require('http')
 var parseUrl = require('parseurl')
 var send = require('send')
 
-var app = http.createServer(function onRequest (req, res) {
+var server = http.createServer(function onRequest (req, res) {
   send(req, parseUrl(req).pathname).pipe(res)
-}).listen(3000)
+})
+
+server.listen(3000)
 ```
 
 ### Custom file types
@@ -191,9 +204,52 @@ send.mime.define({
   'application/x-my-type': ['x-mt', 'x-mtt']
 })
 
-var app = http.createServer(function onRequest (req, res) {
+var server = http.createServer(function onRequest (req, res) {
   send(req, parseUrl(req).pathname).pipe(res)
-}).listen(3000)
+})
+
+server.listen(3000)
+```
+
+### Custom directory index view
+
+This is a example of serving up a structure of directories with a
+custom function to render a listing of a directory.
+
+```js
+var http = require('http')
+var fs = require('fs')
+var parseUrl = require('parseurl')
+var send = require('send')
+
+// Transfer arbitrary files from within /www/example.com/public/*
+// with a custom handler for directory listing
+var server = http.createServer(function onRequest (req, res) {
+  send(req, parseUrl(req).pathname, {index: false, root: '/www/example.com/public'})
+  .once('directory', directory)
+  .pipe(res)
+})
+
+server.listen(3000)
+
+// Custom directory handler
+function directory (res, path) {
+  var stream = this
+
+  // redirect to trailing slash for consistent url
+  if (!stream.hasTrailingSlash()) {
+    return stream.redirect(path)
+  }
+
+  // get directory list
+  fs.readdir(path, function onReaddir (err, list) {
+    if (err) return stream.error(err)
+
+    // render an index for the directory
+    res.setHeader('Content-Type', 'text/plain; charset=UTF-8')
+    res.end(list.join('\n') + '\n')
+  })
+}
 ```
 
 ### Serving from a root directory with custom error-handling
@@ -203,7 +259,7 @@ var http = require('http')
 var parseUrl = require('parseurl')
 var send = require('send')
 
-var app = http.createServer(function onRequest (req, res) {
+var server = http.createServer(function onRequest (req, res) {
   // your custom error-handling logic:
   function error (err) {
     res.statusCode = err.status || 500
@@ -229,11 +285,13 @@ var app = http.createServer(function onRequest (req, res) {
   .on('error', error)
   .on('directory', redirect)
   .on('headers', headers)
-  .pipe(res);
-}).listen(3000)
+  .pipe(res)
+})
+
+server.listen(3000)
 ```
 
-## License 
+## License
 
 [MIT](LICENSE)
 
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/index.js
index 81ec0b3f1..c4c967739 100644
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/index.js
+++ b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/index.js
@@ -19,7 +19,6 @@ var destroy = require('destroy')
 var encodeUrl = require('encodeurl')
 var escapeHtml = require('escape-html')
 var etag = require('etag')
-var EventEmitter = require('events').EventEmitter
 var fresh = require('fresh')
 var fs = require('fs')
 var mime = require('mime')
@@ -61,7 +60,7 @@ var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000 // 1 year
  * @private
  */
 
-var UP_PATH_REGEXP = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/
+var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/
 
 /**
  * Module exports.
@@ -71,14 +70,6 @@ var UP_PATH_REGEXP = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/
 module.exports = send
 module.exports.mime = mime
 
-/**
- * Shim EventEmitter.listenerCount for node.js < 0.10
- */
-
-/* istanbul ignore next */
-var listenerCount = EventEmitter.listenerCount ||
-  function (emitter, type) { return emitter.listeners(type).length }
-
 /**
  * Return a `SendStream` for `req` and `path`.
  *
@@ -146,6 +137,10 @@ function SendStream (req, path, options) {
     ? normalizeList(opts.extensions, 'extensions option')
     : []
 
+  this._immutable = opts.immutable !== undefined
+    ? Boolean(opts.immutable)
+    : false
+
   this._index = opts.index !== undefined
     ? normalizeList(opts.index, 'index option')
     : ['index.html']
@@ -265,42 +260,44 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) {
  * Emit error with `status`.
  *
  * @param {number} status
- * @param {Error} [error]
+ * @param {Error} [err]
  * @private
  */
 
-SendStream.prototype.error = function error (status, error) {
+SendStream.prototype.error = function error (status, err) {
   // emit if listeners instead of responding
-  if (listenerCount(this, 'error') !== 0) {
-    return this.emit('error', createError(error, status, {
+  if (hasListeners(this, 'error')) {
+    return this.emit('error', createError(status, err, {
       expose: false
     }))
   }
 
   var res = this.res
-  var msg = statuses[status]
+  var msg = statuses[status] || String(status)
+  var doc = createHtmlDocument('Error', escapeHtml(msg))
 
   // clear existing headers
   clearHeaders(res)
 
   // add error headers
-  if (error && error.headers) {
-    setHeaders(res, error.headers)
+  if (err && err.headers) {
+    setHeaders(res, err.headers)
   }
 
   // send basic response
   res.statusCode = status
-  res.setHeader('Content-Type', 'text/plain; charset=UTF-8')
-  res.setHeader('Content-Length', Buffer.byteLength(msg))
+  res.setHeader('Content-Type', 'text/html; charset=UTF-8')
+  res.setHeader('Content-Length', Buffer.byteLength(doc))
+  res.setHeader('Content-Security-Policy', "default-src 'self'")
   res.setHeader('X-Content-Type-Options', 'nosniff')
-  res.end(msg)
+  res.end(doc)
 }
 
 /**
  * Check if the pathname ends with "/".
  *
- * @return {Boolean}
- * @api private
+ * @return {boolean}
+ * @private
  */
 
 SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () {
@@ -315,10 +312,42 @@ SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () {
  */
 
 SendStream.prototype.isConditionalGET = function isConditionalGET () {
-  return this.req.headers['if-none-match'] ||
+  return this.req.headers['if-match'] ||
+    this.req.headers['if-unmodified-since'] ||
+    this.req.headers['if-none-match'] ||
     this.req.headers['if-modified-since']
 }
 
+/**
+ * Check if the request preconditions failed.
+ *
+ * @return {boolean}
+ * @private
+ */
+
+SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () {
+  var req = this.req
+  var res = this.res
+
+  // if-match
+  var match = req.headers['if-match']
+  if (match) {
+    var etag = res.getHeader('ETag')
+    return !etag || (match !== '*' && parseTokenList(match).every(function (match) {
+      return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag
+    }))
+  }
+
+  // if-unmodified-since
+  var unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since'])
+  if (!isNaN(unmodifiedSince)) {
+    var lastModified = parseHttpDate(res.getHeader('Last-Modified'))
+    return isNaN(lastModified) || lastModified > unmodifiedSince
+  }
+
+  return false
+}
+
 /**
  * Strip content-* header fields.
  *
@@ -327,7 +356,7 @@ SendStream.prototype.isConditionalGET = function isConditionalGET () {
 
 SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () {
   var res = this.res
-  var headers = Object.keys(res._headers || {})
+  var headers = getHeaderNames(res)
 
   for (var i = 0; i < headers.length; i++) {
     var header = headers[i]
@@ -405,7 +434,10 @@ SendStream.prototype.onStatError = function onStatError (error) {
  */
 
 SendStream.prototype.isFresh = function isFresh () {
-  return fresh(this.req.headers, this.res._headers)
+  return fresh(this.req.headers, {
+    'etag': this.res.getHeader('ETag'),
+    'last-modified': this.res.getHeader('Last-Modified')
+  })
 }
 
 /**
@@ -422,9 +454,15 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () {
     return true
   }
 
-  return ~ifRange.indexOf('"')
-    ? ~ifRange.indexOf(this.res._headers['etag'])
-    : Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange)
+  // if-range as etag
+  if (ifRange.indexOf('"') !== -1) {
+    var etag = this.res.getHeader('ETag')
+    return Boolean(etag && ifRange.indexOf(etag) !== -1)
+  }
+
+  // if-range as modified date
+  var lastModified = this.res.getHeader('Last-Modified')
+  return parseHttpDate(lastModified) <= parseHttpDate(ifRange)
 }
 
 /**
@@ -435,8 +473,10 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () {
  */
 
 SendStream.prototype.redirect = function redirect (path) {
-  if (listenerCount(this, 'directory') !== 0) {
-    this.emit('directory')
+  var res = this.res
+
+  if (hasListeners(this, 'directory')) {
+    this.emit('directory', res, path)
     return
   }
 
@@ -445,17 +485,18 @@ SendStream.prototype.redirect = function redirect (path) {
     return
   }
 
-  var loc = encodeUrl(collapseLeadingSlashes(path + '/'))
-  var msg = 'Redirecting to <a href="' + escapeHtml(loc) + '">' + escapeHtml(loc) + '</a>\n'
-  var res = this.res
+  var loc = encodeUrl(collapseLeadingSlashes(this.path + '/'))
+  var doc = createHtmlDocument('Redirecting', 'Redirecting to <a href="' + escapeHtml(loc) + '">' +
+    escapeHtml(loc) + '</a>')
 
   // redirect
   res.statusCode = 301
   res.setHeader('Content-Type', 'text/html; charset=UTF-8')
-  res.setHeader('Content-Length', Buffer.byteLength(msg))
+  res.setHeader('Content-Length', Buffer.byteLength(doc))
+  res.setHeader('Content-Security-Policy', "default-src 'self'")
   res.setHeader('X-Content-Type-Options', 'nosniff')
   res.setHeader('Location', loc)
-  res.end(msg)
+  res.end(doc)
 }
 
 /**
@@ -488,19 +529,24 @@ SendStream.prototype.pipe = function pipe (res) {
 
   var parts
   if (root !== null) {
+    // normalize
+    if (path) {
+      path = normalize('.' + sep + path)
+    }
+
     // malicious path
-    if (UP_PATH_REGEXP.test(normalize('.' + sep + path))) {
+    if (UP_PATH_REGEXP.test(path)) {
       debug('malicious path "%s"', path)
       this.error(403)
       return res
     }
 
+    // explode path parts
+    parts = path.split(sep)
+
     // join / normalize from optional root dir
     path = normalize(join(root, path))
     root = normalize(root + sep)
-
-    // explode path parts
-    parts = path.substr(root.length).split(sep)
   } else {
     // ".." is malicious without "root"
     if (UP_PATH_REGEXP.test(path)) {
@@ -542,7 +588,7 @@ SendStream.prototype.pipe = function pipe (res) {
   }
 
   // index file support
-  if (this._index.length && this.path[this.path.length - 1] === '/') {
+  if (this._index.length && this.hasTrailingSlash()) {
     this.sendIndex(path)
     return res
   }
@@ -567,7 +613,7 @@ SendStream.prototype.send = function send (path, stat) {
   var ranges = req.headers.range
   var offset = options.start || 0
 
-  if (res._header) {
+  if (headersSent(res)) {
     // impossible to send now
     this.headersAlreadySent()
     return
@@ -582,9 +628,16 @@ SendStream.prototype.send = function send (path, stat) {
   this.type(path)
 
   // conditional GET support
-  if (this.isConditionalGET() && this.isCachable() && this.isFresh()) {
-    this.notModified()
-    return
+  if (this.isConditionalGET()) {
+    if (this.isPreconditionFailure()) {
+      this.error(412)
+      return
+    }
+
+    if (this.isCachable() && this.isFresh()) {
+      this.notModified()
+      return
+    }
   }
 
   // adjust len to start/end options
@@ -672,7 +725,7 @@ SendStream.prototype.sendFile = function sendFile (path) {
       return next(err)
     }
     if (err) return self.onStatError(err)
-    if (stat.isDirectory()) return self.redirect(self.path)
+    if (stat.isDirectory()) return self.redirect(path)
     self.emit('file', path, stat)
     self.send(path, stat)
   })
@@ -817,6 +870,11 @@ SendStream.prototype.setHeader = function setHeader (path, stat) {
 
   if (this._cacheControl && !res.getHeader('Cache-Control')) {
     var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000)
+
+    if (this._immutable) {
+      cacheControl += ', immutable'
+    }
+
     debug('cache-control %s', cacheControl)
     res.setHeader('Cache-Control', cacheControl)
   }
@@ -842,8 +900,11 @@ SendStream.prototype.setHeader = function setHeader (path, stat) {
  */
 
 function clearHeaders (res) {
-  res._headers = {}
-  res._headerNames = {}
+  var headers = getHeaderNames(res)
+
+  for (var i = 0; i < headers.length; i++) {
+    res.removeHeader(headers[i])
+  }
 }
 
 /**
@@ -872,7 +933,8 @@ function collapseLeadingSlashes (str) {
 
 function containsDotFile (parts) {
   for (var i = 0; i < parts.length; i++) {
-    if (parts[i][0] === '.') {
+    var part = parts[i]
+    if (part.length > 1 && part[0] === '.') {
       return true
     }
   }
@@ -892,6 +954,27 @@ function contentRange (type, size, range) {
   return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size
 }
 
+/**
+ * Create a minimal HTML document.
+ *
+ * @param {string} title
+ * @param {string} body
+ * @private
+ */
+
+function createHtmlDocument (title, body) {
+  return '<!DOCTYPE html>\n' +
+    '<html lang="en">\n' +
+    '<head>\n' +
+    '<meta charset="utf-8">\n' +
+    '<title>' + title + '</title>\n' +
+    '</head>\n' +
+    '<body>\n' +
+    '<pre>' + body + '</pre>\n' +
+    '</body>\n' +
+    '<html>\n'
+}
+
 /**
  * decodeURIComponent.
  *
@@ -910,6 +993,54 @@ function decode (path) {
   }
 }
 
+/**
+ * Get the header names on a respnse.
+ *
+ * @param {object} res
+ * @returns {array[string]}
+ * @private
+ */
+
+function getHeaderNames (res) {
+  return typeof res.getHeaderNames !== 'function'
+    ? Object.keys(res._headers || {})
+    : res.getHeaderNames()
+}
+
+/**
+ * Determine if emitter has listeners of a given type.
+ *
+ * The way to do this check is done three different ways in Node.js >= 0.8
+ * so this consolidates them into a minimal set using instance methods.
+ *
+ * @param {EventEmitter} emitter
+ * @param {string} type
+ * @returns {boolean}
+ * @private
+ */
+
+function hasListeners (emitter, type) {
+  var count = typeof emitter.listenerCount !== 'function'
+    ? emitter.listeners(type).length
+    : emitter.listenerCount(type)
+
+  return count > 0
+}
+
+/**
+ * Determine if the response headers have been sent.
+ *
+ * @param {object} res
+ * @returns {boolean}
+ * @private
+ */
+
+function headersSent (res) {
+  return typeof res.headersSent !== 'boolean'
+    ? Boolean(res._header)
+    : res.headersSent
+}
+
 /**
  * Normalize the index option into an array.
  *
@@ -930,6 +1061,57 @@ function normalizeList (val, name) {
   return list
 }
 
+/**
+ * Parse an HTTP Date into a number.
+ *
+ * @param {string} date
+ * @private
+ */
+
+function parseHttpDate (date) {
+  var timestamp = date && Date.parse(date)
+
+  return typeof timestamp === 'number'
+    ? timestamp
+    : NaN
+}
+
+/**
+ * Parse a HTTP token list.
+ *
+ * @param {string} str
+ * @private
+ */
+
+function parseTokenList (str) {
+  var end = 0
+  var list = []
+  var start = 0
+
+  // gather tokens
+  for (var i = 0, len = str.length; i < len; i++) {
+    switch (str.charCodeAt(i)) {
+      case 0x20: /*   */
+        if (start === end) {
+          start = end = i + 1
+        }
+        break
+      case 0x2c: /* , */
+        list.push(str.substring(start, end))
+        start = end = i + 1
+        break
+      default:
+        end = i + 1
+        break
+    }
+  }
+
+  // final token
+  list.push(str.substring(start, end))
+
+  return list
+}
+
 /**
  * Set an object of headers on a response.
  *
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/LICENSE.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/LICENSE.md
deleted file mode 100644
index 69b61253a..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Zeit, Inc.
-
-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/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/README.md b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/README.md
deleted file mode 100644
index 5b475707d..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# ms
-
-[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)
-[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
-[![Slack Channel](https://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)
-
-Use this package to easily convert various time formats to milliseconds.
-
-## Examples
-
-```js
-ms('2 days')  // 172800000
-ms('1d')      // 86400000
-ms('10h')     // 36000000
-ms('2.5 hrs') // 9000000
-ms('2h')      // 7200000
-ms('1m')      // 60000
-ms('5s')      // 5000
-ms('1y')      // 31557600000
-ms('100')     // 100
-```
-
-### Convert from milliseconds
-
-```js
-ms(60000)             // "1m"
-ms(2 * 60000)         // "2m"
-ms(ms('10 hours'))    // "10h"
-```
-
-### Time format written-out
-
-```js
-ms(60000, { long: true })             // "1 minute"
-ms(2 * 60000, { long: true })         // "2 minutes"
-ms(ms('10 hours'), { long: true })    // "10 hours"
-```
-
-## Features
-
-- Works both in [node](https://nodejs.org) and in the browser.
-- If a number is supplied to `ms`, a string with a unit is returned.
-- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).
-- If you pass a string with a number and a valid unit, the number of equivalent ms is returned.
-
-## Caught a bug?
-
-1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
-2. Link the package to the global module directory: `npm link`
-3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!
-
-As always, you can run the tests using: `npm test`
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/index.js b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/index.js
deleted file mode 100644
index 824b37eba..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/index.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * Helpers.
- */
-
-var s = 1000
-var m = s * 60
-var h = m * 60
-var d = h * 24
-var y = d * 365.25
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- *  - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} options
- * @throws {Error} throw an error if val is not a non-empty string or a number
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function (val, options) {
-  options = options || {}
-  var type = typeof val
-  if (type === 'string' && val.length > 0) {
-    return parse(val)
-  } else if (type === 'number' && isNaN(val) === false) {
-    return options.long ?
-			fmtLong(val) :
-			fmtShort(val)
-  }
-  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
-}
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  str = String(str)
-  if (str.length > 10000) {
-    return
-  }
-  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
-  if (!match) {
-    return
-  }
-  var n = parseFloat(match[1])
-  var type = (match[2] || 'ms').toLowerCase()
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'yrs':
-    case 'yr':
-    case 'y':
-      return n * y
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * d
-    case 'hours':
-    case 'hour':
-    case 'hrs':
-    case 'hr':
-    case 'h':
-      return n * h
-    case 'minutes':
-    case 'minute':
-    case 'mins':
-    case 'min':
-    case 'm':
-      return n * m
-    case 'seconds':
-    case 'second':
-    case 'secs':
-    case 'sec':
-    case 's':
-      return n * s
-    case 'milliseconds':
-    case 'millisecond':
-    case 'msecs':
-    case 'msec':
-    case 'ms':
-      return n
-    default:
-      return undefined
-  }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtShort(ms) {
-  if (ms >= 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'
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtLong(ms) {
-  return plural(ms, d, 'day') ||
-    plural(ms, h, 'hour') ||
-    plural(ms, m, 'minute') ||
-    plural(ms, s, 'second') ||
-    ms + ' ms'
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
-  if (ms < n) {
-    return
-  }
-  if (ms < n * 1.5) {
-    return Math.floor(ms / n) + ' ' + name
-  }
-  return Math.ceil(ms / n) + ' ' + name + 's'
-}
diff --git a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/package.json b/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/package.json
deleted file mode 100644
index de75aca75..000000000
--- a/spec/cordova/fixtures/platforms/cordova-browser/node_modules/send/node_modules/ms/package.json
+++ /dev/null
@@ -1,108 +0,0 @@
-{
-  "_args": [
-    [
-      {
-        "raw": "ms@0.7.2",
-        "scope": null,
-        "escapedName": "ms",
-        "name": "ms",
-        "rawSpec": "0.7.2",
-        "spec": "0.7.2",
-        "type": "version"
-      },
-      "/Users/auso/cordova/cordova-lib/cordova-lib/spec-cordova/fixtures/platforms/cordova-browser/node_modules/send"
-    ]
-  ],
-  "_from": "ms@0.7.2",
-  "_id": "ms@0.7.2",
-  "_inCache": true,
-  "_location": "/send/ms",
-  "_nodeVersion": "6.8.0",
-  "_npmOperationalInternal": {
-    "host": "packages-18-east.internal.npmjs.com",
-    "tmp": "tmp/ms-0.7.2.tgz_1477383407940_0.4743474116548896"
-  },
-  "_npmUser": {
-    "name": "leo",
-    "email": "leo@zeit.co"
-  },
-  "_npmVersion": "3.10.8",
-  "_phantomChildren": {},
-  "_requested": {
-    "raw": "ms@0.7.2",
-    "scope": null,
-    "escapedName": "ms",
-    "name": "ms",
-    "rawSpec": "0.7.2",
-    "spec": "0.7.2",
-    "type": "version"
-  },
-  "_requiredBy": [
-    "/send"
-  ],
-  "_resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
-  "_shasum": "ae25cf2512b3885a1d95d7f0