You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by za...@apache.org on 2015/04/01 16:23:15 UTC

[48/52] [abbrv] [partial] cordova-firefoxos git commit: CB-4548 Install new node-firefox-* dependencies in node_modules

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/promise/resolve.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/promise/resolve.js b/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/promise/resolve.js
new file mode 100644
index 0000000..1b3c533
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/promise/resolve.js
@@ -0,0 +1,49 @@
+import {
+  noop,
+  resolve as _resolve
+} from '../-internal';
+
+/**
+  `Promise.resolve` returns a promise that will become resolved with the
+  passed `value`. It is shorthand for the following:
+
+  ```javascript
+  var promise = new Promise(function(resolve, reject){
+    resolve(1);
+  });
+
+  promise.then(function(value){
+    // value === 1
+  });
+  ```
+
+  Instead of writing the above, your code now simply becomes the following:
+
+  ```javascript
+  var promise = Promise.resolve(1);
+
+  promise.then(function(value){
+    // value === 1
+  });
+  ```
+
+  @method resolve
+  @static
+  @param {Any} value value that the returned promise will be resolved with
+  @param {String} label optional string for identifying the returned promise.
+  Useful for tooling.
+  @return {Promise} a promise that will become fulfilled with the given
+  `value`
+*/
+export default function resolve(object, label) {
+  /*jshint validthis:true */
+  var Constructor = this;
+
+  if (object && typeof object === 'object' && object.constructor === Constructor) {
+    return object;
+  }
+
+  var promise = new Constructor(noop, label);
+  _resolve(promise, object);
+  return promise;
+}

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/utils.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/utils.js b/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/utils.js
new file mode 100644
index 0000000..6b49bbf
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/lib/es6-promise/utils.js
@@ -0,0 +1,39 @@
+export function objectOrFunction(x) {
+  return typeof x === 'function' || (typeof x === 'object' && x !== null);
+}
+
+export function isFunction(x) {
+  return typeof x === 'function';
+}
+
+export function isMaybeThenable(x) {
+  return typeof x === 'object' && x !== null;
+}
+
+var _isArray;
+if (!Array.isArray) {
+  _isArray = function (x) {
+    return Object.prototype.toString.call(x) === '[object Array]';
+  };
+} else {
+  _isArray = Array.isArray;
+}
+
+export var isArray = _isArray;
+
+// Date.now is not available in browsers < IE9
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
+export var now = Date.now || function() { return new Date().getTime(); };
+
+function F() { }
+
+export var o_create = (Object.create || function (o) {
+  if (arguments.length > 1) {
+    throw new Error('Second argument not supported');
+  }
+  if (typeof o !== 'object') {
+    throw new TypeError('Argument must be an object');
+  }
+  F.prototype = o;
+  return new F();
+});

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/package.json
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/package.json b/node_modules/node-firefox-connect/node_modules/es6-promise/package.json
new file mode 100644
index 0000000..28494ce
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/package.json
@@ -0,0 +1,81 @@
+{
+  "name": "es6-promise",
+  "namespace": "es6-promise",
+  "version": "2.0.1",
+  "description": "A lightweight library that provides tools for organizing asynchronous code",
+  "main": "dist/es6-promise.js",
+  "directories": {
+    "lib": "lib"
+  },
+  "devDependencies": {
+    "bower": "^1.3.9",
+    "brfs": "0.0.8",
+    "broccoli-closure-compiler": "^0.2.0",
+    "broccoli-compile-modules": "git+https://github.com/eventualbuddha/broccoli-compile-modules",
+    "broccoli-concat": "0.0.7",
+    "broccoli-es3-safe-recast": "0.0.8",
+    "broccoli-file-mover": "^0.4.0",
+    "broccoli-jshint": "^0.5.1",
+    "broccoli-merge-trees": "^0.1.4",
+    "broccoli-static-compiler": "^0.1.4",
+    "broccoli-string-replace": "0.0.1",
+    "browserify": "^4.2.0",
+    "ember-cli": "0.0.40",
+    "ember-publisher": "0.0.7",
+    "es6-module-transpiler-amd-formatter": "0.0.1",
+    "express": "^4.5.0",
+    "jshint": "~0.9.1",
+    "mkdirp": "^0.5.0",
+    "mocha": "^1.20.1",
+    "promises-aplus-tests": "git://github.com/stefanpenner/promises-tests.git",
+    "release-it": "0.0.10",
+    "testem": "^0.6.17",
+    "json3": "^3.3.2"
+  },
+  "scripts": {
+    "test": "testem ci -R dot",
+    "test-server": "testem",
+    "lint": "jshint lib",
+    "prepublish": "ember build --environment production",
+    "aplus": "browserify test/main.js",
+    "build-all": "ember build --environment production && browserify ./test/main.js -o tmp/test-bundle.js",
+    "dry-run-release": "ember build --environment production && release-it --dry-run --non-interactive"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/jakearchibald/ES6-Promises.git"
+  },
+  "bugs": {
+    "url": "https://github.com/jakearchibald/ES6-Promises/issues"
+  },
+  "keywords": [
+    "promises",
+    "futures"
+  ],
+  "author": {
+    "name": "Yehuda Katz, Tom Dale, Stefan Penner and contributors",
+    "url": "Conversion to ES6 API by Jake Archibald"
+  },
+  "license": "MIT",
+  "homepage": "https://github.com/jakearchibald/ES6-Promises",
+  "_id": "es6-promise@2.0.1",
+  "dist": {
+    "shasum": "ccc4963e679f0ca9fb187c777b9e583d3c7573c2",
+    "tarball": "http://registry.npmjs.org/es6-promise/-/es6-promise-2.0.1.tgz"
+  },
+  "_from": "es6-promise@^2.0.1",
+  "_npmVersion": "1.3.24",
+  "_npmUser": {
+    "name": "jaffathecake",
+    "email": "jaffathecake@gmail.com"
+  },
+  "maintainers": [
+    {
+      "name": "jaffathecake",
+      "email": "jaffathecake@gmail.com"
+    }
+  ],
+  "_shasum": "ccc4963e679f0ca9fb187c777b9e583d3c7573c2",
+  "_resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.0.1.tgz",
+  "readme": "ERROR: No README data found!"
+}

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/server/.jshintrc
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/server/.jshintrc b/node_modules/node-firefox-connect/node_modules/es6-promise/server/.jshintrc
new file mode 100644
index 0000000..c1f2978
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/server/.jshintrc
@@ -0,0 +1,3 @@
+{
+  "node": true
+}

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/server/index.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/server/index.js b/node_modules/node-firefox-connect/node_modules/es6-promise/server/index.js
new file mode 100644
index 0000000..8a54d36
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/server/index.js
@@ -0,0 +1,6 @@
+module.exports = function(app) {
+  app.use(require('express').static(__dirname + '/../'));
+  app.get('/', function(req, res) {
+    res.redirect('/test/');
+  })
+};

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/es6-promise/testem.json
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/es6-promise/testem.json b/node_modules/node-firefox-connect/node_modules/es6-promise/testem.json
new file mode 100644
index 0000000..7494912
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/es6-promise/testem.json
@@ -0,0 +1,11 @@
+{
+  "test_page": "test/index.html",
+  "parallel": 5,
+  "before_tests": "npm run build-all",
+  "launchers": {
+    "Mocha": {
+      "command": "./node_modules/.bin/mocha test/main.js"
+    }
+  },
+  "launch_in_ci":  ["PhantomJS", "Mocha"]
+}

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/README.md
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/README.md b/node_modules/node-firefox-connect/node_modules/firefox-client/README.md
new file mode 100644
index 0000000..c6aefea
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/README.md
@@ -0,0 +1,157 @@
+# firefox-client
+`firefox-client` is a [node](nodejs.org) library for remote debugging Firefox. You can use it to make things like [fxconsole](https://github.com/harthur/fxconsole), a remote JavaScript REPL.
+
+```javascript
+var FirefoxClient = require("firefox-client");
+
+var client = new FirefoxClient();
+
+client.connect(6000, function() {
+  client.listTabs(function(err, tabs) {
+    console.log("first tab:", tabs[0].url);
+  });
+});
+```
+
+## Install
+With [node.js](http://nodejs.org/) npm package manager:
+
+```bash
+npm install firefox-client
+```
+
+## Connecting
+
+### Desktop Firefox
+1. Enable remote debugging (You'll only have to do this once)
+ 1. Open the DevTools. **Web Developer** > **Toggle Tools**
+ 2. Visit the settings panel (gear icon)
+ 3. Check "Enable remote debugging" under Advanced Settings
+
+2. Listen for a connection
+ 1. Open the Firefox command line with **Tools** > **Web Developer** > **Developer Toolbar**.
+ 2. Start a server by entering this command: `listen 6000` (where `6000` is the port number)
+
+### Firefox for Android
+Follow the instructions in [this Hacks video](https://www.youtube.com/watch?v=Znj_8IFeTVs)
+
+### Firefox OS 1.1 Simulator
+A limited set of the API (`Console`, `StyleSheets`) is compatible with the [Simulator 4.0](https://addons.mozilla.org/en-US/firefox/addon/firefox-os-simulator/). See the [wiki instructions](https://github.com/harthur/firefox-client/wiki/Firefox-OS-Simulator-Instructions) for connecting.
+
+`client.listTabs()` will list the currently open apps in the Simulator.
+
+### Firefox OS 1.2+ Simulator and devices
+
+`client.getWebapps()` will expose the webapps in the Simulator, where each app implements the `Tab` API.
+
+```
+client.getWebapps(function(err, webapps) {
+  webapps.getApp("app://homescreen.gaiamobile.org/manifest.webapp", function (err, app) {
+    console.log("homescreen:", actor.url);
+    app.Console.evaluateJS("alert('foo')", function(err, resp) {
+      console.log("alert dismissed");
+    });
+  });
+});
+```
+
+## Compatibility
+
+This latest version of the library will stay compatible with [Firefox Nightly](http://nightly.mozilla.org/). Almost all of it will be compatible with [Firefox Aurora](http://www.mozilla.org/en-US/firefox/aurora/) as well.
+
+## API
+
+A `FirefoxClient` is the entry point to the API. After connecting, get a `Tab` object with `listTabs()` or `selectedTab()`. Once you have a `Tab`, you can call methods and listen to events from the tab's modules, `Console` or `Network`. There are also experimental `DOM` and `StyleSheets` tab modules, and an upcoming `Debugger` module.
+
+#### Methods
+Almost all API calls take a callback that will get called with an error as the first argument (or `null` if there is no error), and a return value as the second:
+
+```javascript
+tab.Console.evaluateJS("6 + 7", function(err, resp) {
+  if (err) throw err;
+
+  console.log(resp.result);
+});
+```
+
+#### Events
+
+The modules are `EventEmitter`s, listen for events with `on` or `once`, and stop listening with `off`:
+
+```javascript
+tab.Console.on("page-error", function(event) {
+  console.log("new error from tab:", event.errorMessage);
+});
+```
+
+Summary of the offerings of the modules and objects:
+
+#### [FirefoxClient](http://github.com/harthur/firefox-client/wiki/FirefoxClient)
+Methods: `connect()`, `disconnect()`, `listTabs()`, `selectedTab()`, `getWebapps()`, `getRoot()`
+
+Events: `"error"`, `"timeout"`, `"end"`
+
+#### [Tab](https://github.com/harthur/firefox-client/wiki/Tab)
+Properties: `url`, `title`
+
+Methods: `reload()`, `navigateTo()`, `attach()`, `detach()`
+
+Events: `"navigate"`, `"before-navigate"`
+
+#### [Tab.Console](https://github.com/harthur/firefox-client/wiki/Console)
+Methods: `evaluateJS()`, `startListening()`, `stopListening()`, `getCachedLogs()`
+
+Events: `"page-error"`, `"console-api-call"`
+
+#### [JSObject](https://github.com/harthur/firefox-client/wiki/JSObject)
+Properties: `class`, `name`, `displayName`
+
+Methods: `ownPropertyNames()`, `ownPropertyDescriptor()`, `ownProperties()`, `prototype()`
+
+#### [Tab.Network](https://github.com/harthur/firefox-client/wiki/Network)
+Methods: `startLogging()`, `stopLogging()`, `sendHTTPRequest()`
+
+Events: `"network-event"`
+
+#### [NetworkEvent](https://github.com/harthur/firefox-client/wiki/NetworkEvent)
+Properties: `url`, `method`, `isXHR`
+
+Methods: `getRequestHeaders()`, `getRequestCookies()`, `getRequestPostData()`, `getResponseHeaders()`, `getResponseCookies()`, `getResponseContent()`, `getEventTimings()`
+
+Events: `"request-headers"`, `"request-cookies"`, `"request-postdata"`, `"response-start"`, `"response-headers"`, `"response-cookies"`, `"event-timings"`
+
+#### [Tab.DOM](https://github.com/harthur/firefox-client/wiki/DOM)
+Methods: `document()`, `documentElement()`, `querySelector()`, `querySelectorAll()`
+
+#### [DOMNode](https://github.com/harthur/firefox-client/wiki/DOMNode)
+Properties: `nodeValue`, `nodeName`, `namespaceURI`
+
+Methods: `parentNode()`, `parents()`, `siblings()`, `nextSibling()`, `previousSibling()`, `querySelector()`, `querySelectorAll()`, `innerHTML()`, `outerHTML()`, `setAttribute()`, `remove()`, `release()`
+
+#### [Tab.StyleSheets](https://github.com/harthur/firefox-client/wiki/StyleSheets)
+Methods: `getStyleSheets()`, `addStyleSheet()`
+
+#### [StyleSheet](https://github.com/harthur/firefox-client/wiki/StyleSheet)
+Properties: `href`, `disabled`, `ruleCount`
+
+Methods: `getText()`, `update()`, `toggleDisabled()`, `getOriginalSources()`
+
+Events: `"disabled-changed"`, `"ruleCount-changed"`
+
+#### Tab.Memory
+Methods: `measure()`
+
+#### Webapps
+Methods: `listRunningApps()`, `getInstalledApps()`, `watchApps()`, `unwatchApps()`, `launch()`, `close()`, `getApp()`, `installHosted()`, `installPackaged()`, `installPackagedWithADB()`, `uninstall()`
+
+Events: `"appOpen"`, `"appClose"`, `"appInstall"`, `"appUninstall"`
+
+## Examples
+
+[fxconsole](https://github.com/harthur/fxconsole) - a remote JavaScript console for Firefox
+
+[webapps test script](https://pastebin.mozilla.org/5094843) - a sample usage of all webapps features
+
+## Feedback
+
+What do you need from the API? [File an issue](https://github.com/harthur/firefox-client/issues/new).

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/index.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/index.js b/node_modules/node-firefox-connect/node_modules/firefox-client/index.js
new file mode 100644
index 0000000..cbf7a39
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/index.js
@@ -0,0 +1 @@
+module.exports = require("./lib/browser");
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/browser.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/browser.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/browser.js
new file mode 100644
index 0000000..2e52220
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/browser.js
@@ -0,0 +1,123 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    Client = require("./client"),
+    Tab = require("./tab"),
+    Webapps = require("./webapps"),
+    Device = require("./device"),
+    SimulatorApps = require("./simulator");
+
+const DEFAULT_PORT = 6000;
+const DEFAULT_HOST = "localhost";
+
+module.exports = FirefoxClient;
+
+function FirefoxClient(options) {
+  var client = new Client(options);
+  var actor = 'root';
+
+  client.on("error", this.onError.bind(this));
+  client.on("end", this.onEnd.bind(this));
+  client.on("timeout", this.onTimeout.bind(this));
+
+  this.initialize(client, actor);
+}
+
+FirefoxClient.prototype = extend(ClientMethods, {
+  connect: function(port, host, cb) {
+    if (typeof port == "function") {
+      // (cb)
+      cb = port;
+      port = DEFAULT_PORT;
+      host = DEFAULT_HOST;
+
+    }
+    if (typeof host == "function") {
+      // (port, cb)
+      cb = host;
+      host = DEFAULT_HOST;
+    }
+    // (port, host, cb)
+
+    this.client.connect(port, host, cb);
+
+    this.client.expectReply(this.actor, function(packet) {
+      // root message
+    });
+  },
+
+  disconnect: function() {
+    this.client.disconnect();
+  },
+
+  onError: function(error) {
+    this.emit("error", error);
+  },
+
+  onEnd: function() {
+    this.emit("end");
+  },
+
+  onTimeout: function() {
+    this.emit("timeout");
+  },
+
+  selectedTab: function(cb) {
+    this.request("listTabs", function(resp) {
+      var tab = resp.tabs[resp.selected];
+      return new Tab(this.client, tab);
+    }.bind(this), cb);
+  },
+
+  listTabs: function(cb) {
+    this.request("listTabs", function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+
+      if (resp.simulatorWebappsActor) {
+        // the server is the Firefox OS Simulator, return apps as "tabs"
+        var apps = new SimulatorApps(this.client, resp.simulatorWebappsActor);
+        apps.listApps(cb);
+      }
+      else {
+        var tabs = resp.tabs.map(function(tab) {
+          return new Tab(this.client, tab);
+        }.bind(this));
+        cb(null, tabs);
+      }
+    }.bind(this));
+  },
+
+  getWebapps: function(cb) {
+    this.request("listTabs", (function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+      var webapps = new Webapps(this.client, resp);
+      cb(null, webapps);
+    }).bind(this));
+  },
+
+  getDevice: function(cb) {
+    this.request("listTabs", (function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+      var device = new Device(this.client, resp);
+      cb(null, device);
+    }).bind(this));
+  },
+
+  getRoot: function(cb) {
+    this.request("listTabs", (function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+      if (!resp.consoleActor) {
+        return cb("No root actor being available.");
+      }
+      var root = new Tab(this.client, resp);
+      cb(null, root);
+    }).bind(this));
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client-methods.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client-methods.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client-methods.js
new file mode 100644
index 0000000..c92c44c
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client-methods.js
@@ -0,0 +1,115 @@
+var events = require("events"),
+    extend = require("./extend");
+
+// to be instantiated later - to avoid circular dep resolution
+var JSObject;
+
+var ClientMethods = extend(events.EventEmitter.prototype, {
+  /**
+   * Intialize this client object.
+   *
+   * @param  {object} client
+   *         Client to send requests on.
+   * @param  {string} actor
+   *         Actor id to set as 'from' field on requests
+   */
+  initialize: function(client, actor) {
+    this.client = client;
+    this.actor = actor;
+
+    this.client.on('message', function(message) {
+      if (message.from == this.actor) {
+        this.emit(message.type, message);
+      }
+    }.bind(this));
+  },
+
+  /**
+   * Make request to our actor on the server.
+   *
+   * @param  {string}   type
+   *         Method name of the request
+   * @param  {object}   message
+   *         Optional extra properties (arguments to method)
+   * @param  {Function}   transform
+   *         Optional tranform for response object. Takes response object
+   *         and returns object to send on.
+   * @param  {Function} callback
+   *         Callback to call with (maybe transformed) response
+   */
+  request: function(type, message, transform, callback) {
+    if (typeof message == "function") {
+      if (typeof transform == "function") {
+        // (type, trans, cb)
+        callback = transform;
+        transform = message;
+      }
+      else {
+        // (type, cb)
+        callback = message;
+      }
+      message = {};
+    }
+    else if (!callback) {
+      if (!message) {
+        // (type)
+        message = {};
+      }
+      // (type, message, cb)
+      callback = transform;
+      transform = null;
+    }
+
+    message.to = this.actor;
+    message.type = type;
+
+    this.client.makeRequest(message, function(resp) {
+      delete resp.from;
+
+      if (resp.error) {
+        var err = new Error(resp.message);
+        err.name = resp.error;
+
+        callback(err);
+        return;
+      }
+
+      if (transform) {
+        resp = transform(resp);
+      }
+
+      if (callback) {
+        callback(null, resp);
+      }
+    });
+  },
+
+  /*
+   * Transform obj response into a JSObject
+   */
+  createJSObject: function(obj) {
+    if (obj == null) {
+      return;
+    }
+    if (!JSObject) {
+      // circular dependencies
+      JSObject = require("./jsobject");
+    }
+    if (obj.type == "object") {
+      return new JSObject(this.client, obj);
+    }
+    return obj;
+  },
+
+  /**
+   * Create function that plucks out only one value from an object.
+   * Used as the transform function for some responses.
+   */
+  pluck: function(prop) {
+    return function(obj) {
+      return obj[prop];
+    }
+  }
+})
+
+module.exports = ClientMethods;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client.js
new file mode 100644
index 0000000..22b3179
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/client.js
@@ -0,0 +1,246 @@
+var net = require("net"),
+    events = require("events"),
+    extend = require("./extend");
+
+var colors = require("colors");
+
+module.exports = Client;
+
+// this is very unfortunate! and temporary. we can't
+// rely on 'type' property to signify an event, and we
+// need to write clients for each actor to handle differences
+// in actor protocols
+var unsolicitedEvents = {
+  "tabNavigated": "tabNavigated",
+  "styleApplied": "styleApplied",
+  "propertyChange": "propertyChange",
+  "networkEventUpdate": "networkEventUpdate",
+  "networkEvent": "networkEvent",
+  "propertyChange": "propertyChange",
+  "newMutations": "newMutations",
+  "appOpen": "appOpen",
+  "appClose": "appClose",
+  "appInstall": "appInstall",
+  "appUninstall": "appUninstall",
+  "frameUpdate": "frameUpdate"
+};
+
+/**
+ * a Client object handles connecting with a Firefox remote debugging
+ * server instance (e.g. a Firefox instance), plus sending and receiving
+ * packets on that conection using the Firefox remote debugging protocol.
+ *
+ * Important methods:
+ * connect - Create the connection to the server.
+ * makeRequest - Make a request to the server with a JSON message,
+ *   and a callback to call with the response.
+ *
+ * Important events:
+ * 'message' - An unsolicited (e.g. not a response to a prior request)
+ *    packet has been received. These packets usually describe events.
+ */
+function Client(options) {
+  this.options = options || {};
+
+  this.incoming = new Buffer("");
+
+  this._pendingRequests = [];
+  this._activeRequests = {};
+}
+
+Client.prototype = extend(events.EventEmitter.prototype, {
+  connect: function(port, host, cb) {
+    this.client = net.createConnection({
+      port: port,
+      host: host
+    });
+
+    this.client.on("connect", cb);
+    this.client.on("data", this.onData.bind(this));
+    this.client.on("error", this.onError.bind(this));
+    this.client.on("end", this.onEnd.bind(this));
+    this.client.on("timeout", this.onTimeout.bind(this));
+  },
+
+  disconnect: function() {
+    if (this.client) {
+      this.client.end();
+    }
+  },
+
+  /**
+   * Set a request to be sent to an actor on the server. If the actor
+   * is already handling a request, queue this request until the actor
+   * has responded to the previous request.
+   *
+   * @param {object} request
+   *        Message to be JSON-ified and sent to server.
+   * @param {function} callback
+   *        Function that's called with the response from the server.
+   */
+  makeRequest: function(request, callback) {
+    this.log("request: " + JSON.stringify(request).green);
+
+    if (!request.to) {
+      var type = request.type || "";
+      throw new Error(type + " request packet has no destination.");
+    }
+    this._pendingRequests.push({ to: request.to,
+                                 message: request,
+                                 callback: callback });
+    this._flushRequests();
+  },
+
+  /**
+   * Activate (send) any pending requests to actors that don't have an
+   * active request.
+   */
+  _flushRequests: function() {
+    this._pendingRequests = this._pendingRequests.filter(function(request) {
+      // only one active request per actor at a time
+      if (this._activeRequests[request.to]) {
+        return true;
+      }
+
+      // no active requests for this actor, so activate this one
+      this.sendMessage(request.message);
+      this.expectReply(request.to, request.callback);
+
+      // remove from pending requests
+      return false;
+    }.bind(this));
+  },
+
+  /**
+   * Send a JSON message over the connection to the server.
+   */
+  sendMessage: function(message) {
+    if (!message.to) {
+      throw new Error("No actor specified in request");
+    }
+    if (!this.client) {
+      throw new Error("Not connected, connect() before sending requests");
+    }
+    var str = JSON.stringify(message);
+
+    // message is preceded by byteLength(message):
+    str = (new Buffer(str).length) + ":" + str;
+
+    this.client.write(str);
+  },
+
+  /**
+   * Arrange to hand the next reply from |actor| to |handler|.
+   */
+  expectReply: function(actor, handler) {
+    if (this._activeRequests[actor]) {
+      throw Error("clashing handlers for next reply from " + uneval(actor));
+    }
+    this._activeRequests[actor] = handler;
+  },
+
+  /**
+   * Handler for a new message coming in. It's either an unsolicited event
+   * from the server, or a response to a previous request from the client.
+   */
+  handleMessage: function(message) {
+    if (!message.from) {
+      if (message.error) {
+        throw new Error(message.message);
+      }
+      throw new Error("Server didn't specify an actor: " + JSON.stringify(message));
+    }
+
+    if (!(message.type in unsolicitedEvents)
+        && this._activeRequests[message.from]) {
+      this.log("response: " + JSON.stringify(message).yellow);
+
+      var callback = this._activeRequests[message.from];
+      delete this._activeRequests[message.from];
+
+      callback(message);
+
+      this._flushRequests();
+    }
+    else if (message.type) {
+      // this is an unsolicited event from the server
+      this.log("unsolicited event: ".grey + JSON.stringify(message).grey);
+
+      this.emit('message', message);
+      return;
+    }
+    else {
+      throw new Error("Unexpected packet from actor " +  message.from
+      +  JSON.stringify(message));
+    }
+  },
+
+  /**
+   * Called when a new data chunk is received on the connection.
+   * Parse data into message(s) and call message handler for any full
+   * messages that are read in.
+   */
+  onData: function(data) {
+    this.incoming = Buffer.concat([this.incoming, data]);
+
+    while(this.readMessage()) {};
+  },
+
+  /**
+   * Parse out and process the next message from the data read from
+   * the connection. Returns true if a full meassage was parsed, false
+   * otherwise.
+   */
+  readMessage: function() {
+    var sep = this.incoming.toString().indexOf(':');
+    if (sep < 0) {
+      return false;
+    }
+
+    // beginning of a message is preceded by byteLength(message) + ":"
+    var count = parseInt(this.incoming.slice(0, sep));
+
+    if (this.incoming.length - (sep + 1) < count) {
+      this.log("no complete response yet".grey);
+      return false;
+    }
+    this.incoming = this.incoming.slice(sep + 1);
+
+    var packet = this.incoming.slice(0, count);
+
+    this.incoming = this.incoming.slice(count);
+
+    var message;
+    try {
+      message = JSON.parse(packet.toString());
+    } catch(e) {
+      throw new Error("Couldn't parse packet from server as JSON " + e
+        + ", message:\n" + packet);
+    }
+    this.handleMessage(message);
+
+    return true;
+  },
+
+  onError: function(error) {
+    var code = error.code ? error.code : error;
+    this.log("connection error: ".red + code.red);
+    this.emit("error", error);
+  },
+
+  onEnd: function() {
+    this.log("connection closed by server".red);
+    this.emit("end");
+  },
+
+  onTimeout: function() {
+    this.log("connection timeout".red);
+    this.emit("timeout");
+  },
+
+  log: function(str) {
+    if (this.options.log) {
+      console.log(str);
+    }
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/console.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/console.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/console.js
new file mode 100644
index 0000000..3f3dcff
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/console.js
@@ -0,0 +1,107 @@
+var select = require("js-select"),
+    extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    JSObject = require("./jsobject");
+
+module.exports = Console;
+
+function Console(client, actor) {
+  this.initialize(client, actor);
+
+  this.on("consoleAPICall", this.onConsoleAPI.bind(this));
+  this.on("pageError", this.onPageError.bind(this));
+}
+
+Console.prototype = extend(ClientMethods, {
+  types: ["PageError", "ConsoleAPI"],
+
+  /**
+   * Response object:
+   *   -empty-
+   */
+  startListening: function(cb) {
+    this.request('startListeners', { listeners: this.types }, cb);
+  },
+
+  /**
+   * Response object:
+   *   -empty-
+   */
+  stopListening: function(cb) {
+    this.request('stopListeners', { listeners: this.types }, cb);
+  },
+
+  /**
+   * Event object:
+   *   level - "log", etc.
+   *   filename - file with call
+   *   lineNumber - line number of call
+   *   functionName - function log called from
+   *   timeStamp - ms timestamp of call
+   *   arguments - array of the arguments to log call
+   *   private -
+   */
+  onConsoleAPI: function(event) {
+    var message = this.transformConsoleCall(event.message);
+
+    this.emit("console-api-call", message);
+  },
+
+  /**
+   * Event object:
+   *   errorMessage - string error message
+   *   sourceName - file error
+   *   lineText
+   *   lineNumber - line number of error
+   *   columnNumber - column number of error
+   *   category - usually "content javascript",
+   *   timeStamp - time in ms of error occurance
+   *   warning - whether it's a warning
+   *   error - whether it's an error
+   *   exception - whether it's an exception
+   *   strict -
+   *   private -
+   */
+  onPageError: function(event) {
+    this.emit("page-error", event.pageError);
+  },
+
+  /**
+   * Response object: array of page error or console call objects.
+   */
+  getCachedLogs: function(cb) {
+    var message = {
+      messageTypes: this.types
+    };
+    this.request('getCachedMessages', message, function(resp) {
+      select(resp, ".messages > *").update(this.transformConsoleCall.bind(this));
+      return resp.messages;
+    }.bind(this), cb);
+  },
+
+  /**
+   * Response object:
+   *   -empty-
+   */
+  clearCachedLogs: function(cb) {
+    this.request('clearMessagesCache', cb);
+  },
+
+  /**
+   * Response object:
+   *   input - original input
+   *   result - result of the evaluation, a value or JSObject
+   *   timestamp - timestamp in ms of the evaluation
+   *   exception - any exception as a result of the evaluation
+   */
+  evaluateJS: function(text, cb) {
+    this.request('evaluateJS', { text: text }, function(resp) {
+      return select(resp, ".result, .exception")
+             .update(this.createJSObject.bind(this));
+    }.bind(this), cb)
+  },
+
+  transformConsoleCall: function(message) {
+    return select(message, ".arguments > *").update(this.createJSObject.bind(this));
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/device.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/device.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/device.js
new file mode 100644
index 0000000..6c5da84
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/device.js
@@ -0,0 +1,29 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods");
+
+module.exports = Device;
+
+function Device(client, tab) {
+  this.initialize(client, tab.deviceActor);
+}
+
+Device.prototype = extend(ClientMethods, {
+  getDescription: function(cb) {
+    this.request("getDescription", function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+
+      cb(null, resp.value);
+    });
+  },
+  getRawPermissionsTable: function(cb) {
+    this.request("getRawPermissionsTable", function(err, resp) {
+      if (err) {
+        return cb(err);
+      }
+
+      cb(null, resp.value.rawPermissionsTable);
+    });
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/dom.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/dom.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/dom.js
new file mode 100644
index 0000000..a00018c
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/dom.js
@@ -0,0 +1,68 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    Node = require("./domnode");
+
+module.exports = DOM;
+
+function DOM(client, actor) {
+  this.initialize(client, actor);
+  this.walker = null;
+}
+
+DOM.prototype = extend(ClientMethods, {
+  document: function(cb) {
+    this.walkerRequest("document", function(err, resp) {
+      if (err) return cb(err);
+
+      var node = new Node(this.client, this.walker, resp.node);
+      cb(null, node);
+    }.bind(this))
+  },
+
+  documentElement: function(cb) {
+    this.walkerRequest("documentElement", function(err, resp) {
+      var node = new Node(this.client, this.walker, resp.node);
+      cb(err, node);
+    }.bind(this))
+  },
+
+  querySelector: function(selector, cb) {
+    this.document(function(err, node) {
+      if (err) return cb(err);
+
+      node.querySelector(selector, cb);
+    })
+  },
+
+  querySelectorAll: function(selector, cb) {
+    this.document(function(err, node) {
+      if (err) return cb(err);
+
+      node.querySelectorAll(selector, cb);
+    })
+  },
+
+  walkerRequest: function(type, message, cb) {
+    this.getWalker(function(err, walker) {
+      walker.request(type, message, cb);
+    });
+  },
+
+  getWalker: function(cb) {
+    if (this.walker) {
+      return cb(null, this.walker);
+    }
+    this.request('getWalker', function(err, resp) {
+      this.walker = new Walker(this.client, resp.walker);
+      cb(err, this.walker);
+    }.bind(this))
+  }
+})
+
+function Walker(client, walker) {
+  this.initialize(client, walker.actor);
+
+  this.root = new Node(client, this, walker.root);
+}
+
+Walker.prototype = extend(ClientMethods, {});

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/domnode.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/domnode.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/domnode.js
new file mode 100644
index 0000000..e0a55b8
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/domnode.js
@@ -0,0 +1,169 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods");
+
+module.exports = Node;
+
+function Node(client, walker, node) {
+  this.initialize(client, node.actor);
+  this.walker = walker;
+
+  this.getNode = this.getNode.bind(this);
+  this.getNodeArray = this.getNodeArray.bind(this);
+  this.getNodeList = this.getNodeList.bind(this);
+
+  walker.on('newMutations', function(event) {
+    //console.log("on new mutations! ", JSON.stringify(event));
+  });
+
+  ['nodeType', 'nodeName', 'namespaceURI', 'attrs']
+  .forEach(function(attr) {
+    this[attr] = node[attr];
+  }.bind(this));
+}
+
+Node.prototype = extend(ClientMethods, {
+  getAttribute: function(name) {
+    for (var i in this.attrs) {
+      var attr = this.attrs[i];
+      if (attr.name == name) {
+        return attr.value;
+      }
+    }
+  },
+
+  setAttribute: function(name, value, cb) {
+    var mods = [{
+      attributeName: name,
+      newValue: value
+    }];
+    this.request('modifyAttributes', { modifications: mods }, cb);
+  },
+
+  parentNode: function(cb) {
+    this.parents(function(err, nodes) {
+      if (err) {
+        return cb(err);
+      }
+      var node = null;
+      if (nodes.length) {
+        node = nodes[0];
+      }
+      cb(null, node);
+    })
+  },
+
+  parents: function(cb) {
+    this.nodeRequest('parents', this.getNodeArray, cb);
+  },
+
+  children: function(cb) {
+    this.nodeRequest('children', this.getNodeArray, cb);
+  },
+
+  siblings: function(cb) {
+    this.nodeRequest('siblings', this.getNodeArray, cb);
+  },
+
+  nextSibling: function(cb) {
+    this.nodeRequest('nextSibling', this.getNode, cb);
+  },
+
+  previousSibling: function(cb) {
+    this.nodeRequest('previousSibling', this.getNode, cb);
+  },
+
+  querySelector: function(selector, cb) {
+    this.nodeRequest('querySelector', { selector: selector },
+                     this.getNode, cb);
+  },
+
+  querySelectorAll: function(selector, cb) {
+    this.nodeRequest('querySelectorAll', { selector: selector },
+                     this.getNodeList, cb);
+  },
+
+  innerHTML: function(cb) {
+    this.nodeRequest('innerHTML', function(resp) {
+      return resp.value;
+    }, cb)
+  },
+
+  outerHTML: function(cb) {
+    this.nodeRequest('outerHTML', function(resp) {
+      return resp.value;
+    }, cb)
+  },
+
+  remove: function(cb) {
+    this.nodeRequest('removeNode', function(resp) {
+      return new Node(this.client, this.walker, resp.nextSibling);
+    }.bind(this), cb);
+  },
+
+  highlight: function(cb) {
+    this.nodeRequest('highlight', cb);
+  },
+
+  release: function(cb) {
+    this.nodeRequest('releaseNode', cb);
+  },
+
+  getNode: function(resp) {
+    if (resp.node) {
+      return new Node(this.client, this.walker, resp.node);
+    }
+    return null;
+  },
+
+  getNodeArray: function(resp) {
+    return resp.nodes.map(function(form) {
+      return new Node(this.client, this.walker, form);
+    }.bind(this));
+  },
+
+  getNodeList: function(resp) {
+    return new NodeList(this.client, this.walker, resp.list);
+  },
+
+  nodeRequest: function(type, message, transform, cb) {
+    if (!cb) {
+      cb = transform;
+      transform = message;
+      message = {};
+    }
+    message.node = this.actor;
+
+    this.walker.request(type, message, transform, cb);
+  }
+});
+
+function NodeList(client, walker, list) {
+  this.client = client;
+  this.walker = walker;
+  this.actor = list.actor;
+
+  this.length = list.length;
+}
+
+NodeList.prototype = extend(ClientMethods, {
+  items: function(start, end, cb) {
+    if (typeof start == "function") {
+      cb = start;
+      start = 0;
+      end = this.length;
+    }
+    else if (typeof end == "function") {
+      cb = end;
+      end = this.length;
+    }
+    this.request('items', { start: start, end: end },
+      this.getNodeArray.bind(this), cb);
+  },
+
+  // TODO: add this function to ClientMethods
+  getNodeArray: function(resp) {
+    return resp.nodes.map(function(form) {
+      return new Node(this.client, this.walker, form);
+    }.bind(this));
+  }
+});

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/extend.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/extend.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/extend.js
new file mode 100644
index 0000000..8624103
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/extend.js
@@ -0,0 +1,12 @@
+module.exports = function extend(prototype, properties) {
+  return Object.create(prototype, getOwnPropertyDescriptors(properties));
+}
+
+function getOwnPropertyDescriptors(object) {
+  var names = Object.getOwnPropertyNames(object);
+
+  return names.reduce(function(descriptor, name) {
+    descriptor[name] = Object.getOwnPropertyDescriptor(object, name);
+    return descriptor;
+  }, {});
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/jsobject.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/jsobject.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/jsobject.js
new file mode 100644
index 0000000..907999f
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/jsobject.js
@@ -0,0 +1,91 @@
+var select = require("js-select"),
+    extend = require("./extend"),
+    ClientMethods = require("./client-methods");
+
+module.exports = JSObject;
+
+function JSObject(client, obj) {
+  this.initialize(client, obj.actor);
+  this.obj = obj;
+}
+
+JSObject.prototype = extend(ClientMethods, {
+  type: "object",
+
+  get class() {
+    return this.obj.class;
+  },
+
+  get name() {
+    return this.obj.name;
+  },
+
+  get displayName() {
+    return this.obj.displayName;
+  },
+
+  ownPropertyNames: function(cb) {
+    this.request('ownPropertyNames', function(resp) {
+      return resp.ownPropertyNames;
+    }, cb);
+  },
+
+  ownPropertyDescriptor: function(name, cb) {
+    this.request('property', { name: name }, function(resp) {
+      return this.transformDescriptor(resp.descriptor);
+    }.bind(this), cb);
+  },
+
+  ownProperties: function(cb) {
+    this.request('prototypeAndProperties', function(resp) {
+      return this.transformProperties(resp.ownProperties);
+    }.bind(this), cb);
+  },
+
+  prototype: function(cb) {
+    this.request('prototype', function(resp) {
+      return this.createJSObject(resp.prototype);
+    }.bind(this), cb);
+  },
+
+  ownPropertiesAndPrototype: function(cb) {
+    this.request('prototypeAndProperties', function(resp) {
+      resp.ownProperties = this.transformProperties(resp.ownProperties);
+      resp.safeGetterValues = this.transformGetters(resp.safeGetterValues);
+      resp.prototype = this.createJSObject(resp.prototype);
+
+      return resp;
+    }.bind(this), cb);
+  },
+
+  /* helpers */
+  transformProperties: function(props) {
+    var transformed = {};
+    for (var prop in props) {
+      transformed[prop] = this.transformDescriptor(props[prop]);
+    }
+    return transformed;
+  },
+
+  transformGetters: function(getters) {
+    var transformed = {};
+    for (var prop in getters) {
+      transformed[prop] = this.transformGetter(getters[prop]);
+    }
+    return transformed;
+  },
+
+  transformDescriptor: function(descriptor) {
+    descriptor.value = this.createJSObject(descriptor.value);
+    return descriptor;
+  },
+
+  transformGetter: function(getter) {
+    return {
+      value: this.createJSObject(getter.getterValue),
+      prototypeLevel: getter.getterPrototypeLevel,
+      enumerable: getter.enumerable,
+      writable: getter.writable
+    }
+  }
+})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/memory.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/memory.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/memory.js
new file mode 100644
index 0000000..8468539
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/memory.js
@@ -0,0 +1,16 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods");
+
+module.exports = Memory;
+
+function Memory(client, actor) {
+  this.initialize(client, actor);
+}
+
+Memory.prototype = extend(ClientMethods, {
+  measure: function(cb) {
+    this.request('measure', function (err, resp) {
+      cb(err, resp);
+    });
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/network.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/network.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/network.js
new file mode 100644
index 0000000..5c1afdb
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/network.js
@@ -0,0 +1,105 @@
+var extend = require("./extend");
+var ClientMethods = require("./client-methods");
+
+module.exports = Network;
+
+function Network(client, actor) {
+  this.initialize(client, actor);
+
+  this.on("networkEvent", this.onNetworkEvent.bind(this));
+}
+
+Network.prototype = extend(ClientMethods, {
+  types: ["NetworkActivity"],
+
+  startLogging: function(cb) {
+    this.request('startListeners', { listeners: this.types }, cb);
+  },
+
+  stopLogging: function(cb) {
+    this.request('stopListeners', { listeners: this.types }, cb);
+  },
+
+  onNetworkEvent: function(event) {
+    var networkEvent = new NetworkEvent(this.client, event.eventActor);
+
+    this.emit("network-event", networkEvent);
+  },
+
+  sendHTTPRequest: function(request, cb) {
+    this.request('sendHTTPRequest', { request: request }, function(resp) {
+      return new NetworkEvent(this.client, resp.eventActor);
+    }.bind(this), cb);
+  }
+})
+
+function NetworkEvent(client, event) {
+  this.initialize(client, event.actor);
+  this.event = event;
+
+  this.on("networkEventUpdate", this.onUpdate.bind(this));
+}
+
+NetworkEvent.prototype = extend(ClientMethods, {
+  get url() {
+   return this.event.url;
+  },
+
+  get method() {
+    return this.event.method;
+  },
+
+  get isXHR() {
+    return this.event.isXHR;
+  },
+
+  getRequestHeaders: function(cb) {
+    this.request('getRequestHeaders', cb);
+  },
+
+  getRequestCookies: function(cb) {
+    this.request('getRequestCookies', this.pluck('cookies'), cb);
+  },
+
+  getRequestPostData: function(cb) {
+    this.request('getRequestPostData', cb);
+  },
+
+  getResponseHeaders: function(cb) {
+    this.request('getResponseHeaders', cb);
+  },
+
+  getResponseCookies: function(cb) {
+    this.request('getResponseCookies', this.pluck('cookies'), cb);
+  },
+
+  getResponseContent: function(cb) {
+    this.request('getResponseContent', cb);
+  },
+
+  getEventTimings: function(cb) {
+    this.request('getEventTimings', cb);
+  },
+
+  onUpdate: function(event) {
+    var types = {
+      "requestHeaders": "request-headers",
+      "requestCookies": "request-cookies",
+      "requestPostData": "request-postdata",
+      "responseStart": "response-start",
+      "responseHeaders": "response-headers",
+      "responseCookies": "response-cookies",
+      "responseContent": "response-content",
+      "eventTimings": "event-timings"
+    }
+
+    var type = types[event.updateType];
+    delete event.updateType;
+
+    this.emit(type, event);
+  }
+})
+
+
+
+

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/simulator.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/simulator.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/simulator.js
new file mode 100644
index 0000000..4df6a2b
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/simulator.js
@@ -0,0 +1,22 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    Tab = require("./tab");
+
+module.exports = SimulatorApps;
+
+function SimulatorApps(client, actor) {
+  this.initialize(client, actor);
+}
+
+SimulatorApps.prototype = extend(ClientMethods, {
+  listApps: function(cb) {
+    this.request('listApps', function(resp) {
+      var apps = [];
+      for (var url in resp.apps) {
+        var app = resp.apps[url];
+        apps.push(new Tab(this.client, app));
+      }
+      return apps;
+    }.bind(this), cb);
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/stylesheets.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/stylesheets.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/stylesheets.js
new file mode 100644
index 0000000..0677c02
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/stylesheets.js
@@ -0,0 +1,96 @@
+var extend = require("./extend");
+var ClientMethods = require("./client-methods");
+
+module.exports = StyleSheets;
+
+function StyleSheets(client, actor) {
+  this.initialize(client, actor);
+}
+
+StyleSheets.prototype = extend(ClientMethods, {
+  getStyleSheets: function(cb) {
+    this.request('getStyleSheets', function(resp) {
+      return resp.styleSheets.map(function(sheet) {
+        return new StyleSheet(this.client, sheet);
+      }.bind(this));
+    }.bind(this), cb);
+  },
+
+  addStyleSheet: function(text, cb) {
+    this.request('addStyleSheet', { text: text }, function(resp) {
+      return new StyleSheet(this.client, resp.styleSheet);
+    }.bind(this), cb);
+  }
+})
+
+function StyleSheet(client, sheet) {
+  this.initialize(client, sheet.actor);
+  this.sheet = sheet;
+
+  this.on("propertyChange", this.onPropertyChange.bind(this));
+}
+
+StyleSheet.prototype = extend(ClientMethods, {
+  get href() {
+    return this.sheet.href;
+  },
+
+  get disabled() {
+    return this.sheet.disabled;
+  },
+
+  get ruleCount() {
+    return this.sheet.ruleCount;
+  },
+
+  onPropertyChange: function(event) {
+    this.sheet[event.property] = event.value;
+    this.emit(event.property + "-changed", event.value);
+  },
+
+  toggleDisabled: function(cb) {
+    this.request('toggleDisabled', function(err, resp) {
+      if (err) return cb(err);
+
+      this.sheet.disabled = resp.disabled;
+      cb(null, resp.disabled);
+    }.bind(this));
+  },
+
+  getOriginalSources: function(cb) {
+    this.request('getOriginalSources', function(resp) {
+      if (resp.originalSources === null) {
+        return [];
+      }
+      return resp.originalSources.map(function(form) {
+        return new OriginalSource(this.client, form);
+      }.bind(this));
+    }.bind(this), cb);
+  },
+
+  update: function(text, cb) {
+    this.request('update', { text: text, transition: true }, cb);
+  },
+
+  getText: function(cb) {
+    this.request('getText', this.pluck('text'), cb);
+  }
+});
+
+
+function OriginalSource(client, source) {
+  console.log("source", source);
+  this.initialize(client, source.actor);
+
+  this.source = source;
+}
+
+OriginalSource.prototype = extend(ClientMethods, {
+  get url()  {
+    return this.source.url
+  },
+
+  getText: function(cb) {
+    this.request('getText', this.pluck('text'), cb);
+  }
+});

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/tab.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/tab.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/tab.js
new file mode 100644
index 0000000..5e19e1c
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/tab.js
@@ -0,0 +1,87 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    Console = require("./console"),
+    Memory = require("./memory"),
+    DOM = require("./dom"),
+    Network = require("./network"),
+    StyleSheets = require("./stylesheets");
+
+module.exports = Tab;
+
+function Tab(client, tab) {
+  this.initialize(client, tab.actor);
+
+  this.tab = tab;
+  this.updateInfo(tab);
+
+  this.on("tabNavigated", this.onTabNavigated.bind(this));
+}
+
+Tab.prototype = extend(ClientMethods, {
+  updateInfo: function(form) {
+    this.url = form.url;
+    this.title = form.title;
+  },
+
+  get StyleSheets() {
+    if (!this._StyleSheets) {
+      this._StyleSheets = new StyleSheets(this.client, this.tab.styleSheetsActor);
+    }
+    return this._StyleSheets;
+  },
+
+  get DOM() {
+    if (!this._DOM) {
+      this._DOM = new DOM(this.client, this.tab.inspectorActor);
+    }
+    return this._DOM;
+  },
+
+  get Network() {
+    if (!this._Network) {
+      this._Network = new Network(this.client, this.tab.consoleActor);
+    }
+    return this._Network;
+  },
+
+  get Console() {
+    if (!this._Console) {
+      this._Console = new Console(this.client, this.tab.consoleActor);
+    }
+    return this._Console;
+  },
+
+  get Memory() {
+    if (!this._Memory) {
+      this._Memory = new Memory(this.client, this.tab.memoryActor);
+    }
+    return this._Memory;
+  },
+
+  onTabNavigated: function(event) {
+    if (event.state == "start") {
+      this.emit("before-navigate", { url: event.url });
+    }
+    else if (event.state == "stop") {
+      this.updateInfo(event);
+
+      this.emit("navigate", { url: event.url, title: event.title });
+    }
+  },
+
+  attach: function(cb) {
+    this.request("attach", cb);
+  },
+
+  detach: function(cb) {
+    this.request("detach", cb);
+  },
+
+  reload: function(cb) {
+    this.request("reload", cb);
+  },
+
+  navigateTo: function(url, cb) {
+    this.request("navigateTo", { url: url }, cb);
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/lib/webapps.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/lib/webapps.js b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/webapps.js
new file mode 100644
index 0000000..5ede808
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/lib/webapps.js
@@ -0,0 +1,170 @@
+var extend = require("./extend"),
+    ClientMethods = require("./client-methods"),
+    Tab = require("./tab"),
+    fs = require("fs"),
+    spawn = require("child_process").spawn;
+
+module.exports = Webapps;
+
+var CHUNK_SIZE = 20480;
+
+// Also dispatch appOpen/appClose, appInstall/appUninstall events
+function Webapps(client, tab) {
+  this.initialize(client, tab.webappsActor);
+}
+
+Webapps.prototype = extend(ClientMethods, {
+  watchApps: function(cb) {
+    this.request("watchApps", cb);
+  },
+  unwatchApps: function(cb) {
+    this.request("unwatchApps", cb);
+  },
+  launch: function(manifestURL, cb) {
+    this.request("launch", {manifestURL: manifestURL}, cb);
+  },
+  close: function(manifestURL, cb) {
+    this.request("close", {manifestURL: manifestURL}, cb);
+  },
+  getInstalledApps: function(cb) {
+    this.request("getAll", function (err, resp) {
+      if (err) {
+        cb(err);
+        return;
+      }
+      cb(null, resp.apps);
+    });
+  },
+  listRunningApps: function(cb) {
+    this.request("listRunningApps", function (err, resp) {
+      if (err) {
+        cb(err);
+        return;
+      }
+      cb(null, resp.apps);
+    });
+  },
+  getApp: function(manifestURL, cb) {
+    this.request("getAppActor", {manifestURL: manifestURL}, (function (err, resp) {
+      if (err) {
+        cb(err);
+        return;
+      }
+      var actor = new Tab(this.client, resp.actor);
+      cb(null, actor);
+    }).bind(this));
+  },
+  installHosted: function(options, cb) {
+    this.request(
+      "install",
+      { appId: options.appId,
+        metadata: options.metadata,
+        manifest: options.manifest },
+      function (err, resp) {
+        if (err || resp.error) {
+          cb(err || resp.error);
+          return;
+        }
+        cb(null, resp.appId);
+      });
+  },
+  _upload: function (path, cb) {
+    // First create an upload actor
+    this.request("uploadPackage", function (err, resp) {
+      var actor = resp.actor;
+      fs.readFile(path, function(err, data) {
+        chunk(actor, data);
+      });
+    });
+    // Send push the file chunk by chunk
+    var self = this;
+    var step = 0;
+    function chunk(actor, data) {
+      var i = step++ * CHUNK_SIZE;
+      var m = Math.min(i + CHUNK_SIZE, data.length);
+      var c = "";
+      for(; i < m; i++)
+        c += String.fromCharCode(data[i]);
+      var message = {
+        to: actor,
+        type: "chunk",
+        chunk: c
+      };
+      self.client.makeRequest(message, function(resp) {
+        if (resp.error) {
+          cb(resp);
+          return;
+        }
+        if (i < data.length) {
+          setTimeout(chunk, 0, actor, data);
+        } else {
+          done(actor);
+        }
+      });
+    }
+    // Finally close the upload
+    function done(actor) {
+      var message = {
+        to: actor,
+        type: "done"
+      };
+      self.client.makeRequest(message, function(resp) {
+        if (resp.error) {
+          cb(resp);
+        } else {
+          cb(null, actor, cleanup.bind(null, actor));
+        }
+      });
+    }
+
+    // Remove the temporary uploaded file from the server:
+    function cleanup(actor) {
+      var message = {
+        to: actor,
+        type: "remove"
+      };
+      self.client.makeRequest(message, function () {});
+    }
+  },
+  installPackaged: function(path, appId, cb) {
+    this._upload(path, (function (err, actor, cleanup) {
+      this.request("install", {appId: appId, upload: actor},
+        function (err, resp) {
+          if (err) {
+            cb(err);
+            return;
+          }
+          cb(null, resp.appId);
+          cleanup();
+        });
+    }).bind(this));
+  },
+  installPackagedWithADB: function(path, appId, cb) {
+    var self = this;
+    // First ensure the temporary folder exists
+    function createTemporaryFolder() {
+      var c = spawn("adb", ["shell", "mkdir -p /data/local/tmp/b2g/" + appId], {stdio:"inherit"});
+      c.on("close", uploadPackage);
+    }
+    // then upload the package to the temporary directory
+    function uploadPackage() {
+      var child = spawn("adb", ["push", path, "/data/local/tmp/b2g/" + appId + "/application.zip"], {stdio:"inherit"});
+      child.on("close", installApp);
+    }
+    // finally order the webapps actor to install the app
+    function installApp() {
+      self.request("install", {appId: appId},
+        function (err, resp) {
+          if (err) {
+            cb(err);
+            return;
+          }
+          cb(null, resp.appId);
+        });
+    }
+    createTemporaryFolder();
+  },
+  uninstall: function(manifestURL, cb) {
+    this.request("uninstall", {manifestURL: manifestURL}, cb);
+  }
+})

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/MIT-LICENSE.txt
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/MIT-LICENSE.txt b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/MIT-LICENSE.txt
new file mode 100644
index 0000000..7df0d5e
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/MIT-LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Alexis Sellier (cloudhead) , Marak Squires
+
+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.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/ReadMe.md
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/ReadMe.md b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/ReadMe.md
new file mode 100644
index 0000000..74acead
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/ReadMe.md
@@ -0,0 +1,30 @@
+<h1>colors.js - get color and style in your node.js console like what</h1>
+
+<img src="http://i.imgur.com/goJdO.png" border = "0"/>
+
+       var sys = require('sys');
+       var colors = require('./colors');
+
+       sys.puts('hello'.green); // outputs green text
+       sys.puts('i like cake and pies'.underline.red) // outputs red underlined text
+       sys.puts('inverse the color'.inverse); // inverses the color
+       sys.puts('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)
+       
+<h2>colors and styles!</h2>
+- bold
+- italic
+- underline
+- inverse
+- yellow
+- cyan
+- white
+- magenta
+- green
+- red
+- grey
+- blue
+
+
+### Authors 
+
+#### Alexis Sellier (cloudhead) , Marak Squires , Justin Campbell, Dustin Diaz (@ded)

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/colors.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/colors.js b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/colors.js
new file mode 100644
index 0000000..8c1d706
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/colors.js
@@ -0,0 +1,230 @@
+/*
+colors.js
+
+Copyright (c) 2010 Alexis Sellier (cloudhead) , Marak Squires
+
+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.
+
+*/
+
+exports.mode = "console";
+
+// prototypes the string object to have additional method calls that add terminal colors
+
+var addProperty = function (color, func) {
+  exports[color] = function(str) {
+    return func.apply(str);
+  };
+  String.prototype.__defineGetter__(color, func);
+}
+
+var isHeadless = (typeof module !== 'undefined');
+['bold', 'underline', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'].forEach(function (style) {
+
+  // __defineGetter__ at the least works in more browsers
+  // http://robertnyman.com/javascript/javascript-getters-setters.html
+  // Object.defineProperty only works in Chrome
+  addProperty(style, function () {
+    return isHeadless ?
+             stylize(this, style) : // for those running in node (headless environments)
+             this.replace(/( )/, '$1'); // and for those running in browsers:
+             // re: ^ you'd think 'return this' works (but doesn't) so replace coerces the string to be a real string
+  });
+});
+
+// prototypes string with method "rainbow"
+// rainbow will apply a the color spectrum to a string, changing colors every letter
+addProperty('rainbow', function () {
+  if (!isHeadless) {
+    return this.replace(/( )/, '$1');
+  }
+  var rainbowcolors = ['red','yellow','green','blue','magenta']; //RoY G BiV
+  var exploded = this.split("");
+  var i=0;
+  exploded = exploded.map(function(letter) {
+    if (letter==" ") {
+      return letter;
+    }
+    else {
+      return stylize(letter,rainbowcolors[i++ % rainbowcolors.length]);
+    }
+  });
+  return exploded.join("");
+});
+
+function stylize(str, style) {
+  if (exports.mode == 'console') {
+    var styles = {
+      //styles
+      'bold'      : ['\033[1m',  '\033[22m'],
+      'italic'    : ['\033[3m',  '\033[23m'],
+      'underline' : ['\033[4m',  '\033[24m'],
+      'inverse'   : ['\033[7m',  '\033[27m'],
+      //grayscale
+      'white'     : ['\033[37m', '\033[39m'],
+      'grey'      : ['\033[90m', '\033[39m'],
+      'black'     : ['\033[30m', '\033[39m'],
+      //colors
+      'blue'      : ['\033[34m', '\033[39m'],
+      'cyan'      : ['\033[36m', '\033[39m'],
+      'green'     : ['\033[32m', '\033[39m'],
+      'magenta'   : ['\033[35m', '\033[39m'],
+      'red'       : ['\033[31m', '\033[39m'],
+      'yellow'    : ['\033[33m', '\033[39m']
+    };
+  } else if (exports.mode == 'browser') {
+    var styles = {
+      //styles
+      'bold'      : ['<b>',  '</b>'],
+      'italic'    : ['<i>',  '</i>'],
+      'underline' : ['<u>',  '</u>'],
+      'inverse'   : ['<span style="background-color:black;color:white;">',  '</span>'],
+      //grayscale
+      'white'     : ['<span style="color:white;">',   '</span>'],
+      'grey'      : ['<span style="color:grey;">',    '</span>'],
+      'black'     : ['<span style="color:black;">',   '</span>'],
+      //colors
+      'blue'      : ['<span style="color:blue;">',    '</span>'],
+      'cyan'      : ['<span style="color:cyan;">',    '</span>'],
+      'green'     : ['<span style="color:green;">',   '</span>'],
+      'magenta'   : ['<span style="color:magenta;">', '</span>'],
+      'red'       : ['<span style="color:red;">',     '</span>'],
+      'yellow'    : ['<span style="color:yellow;">',  '</span>']
+    };
+  } else if (exports.mode == 'none') {
+      return str;
+  } else {
+    console.log('unsupported mode, try "browser", "console" or "none"');
+  }
+
+  return styles[style][0] + str + styles[style][1];
+};
+
+// don't summon zalgo
+addProperty('zalgo', function () {
+  return zalgo(this);
+});
+
+// please no
+function zalgo(text, options) {
+  var soul = {
+    "up" : [
+      '̍','̎','̄','̅',
+      '̿','̑','̆','̐',
+      '͒','͗','͑','̇',
+      '̈','̊','͂','̓',
+      '̈','͊','͋','͌',
+      '̃','̂','̌','͐',
+      '̀','́','̋','̏',
+      '̒','̓','̔','̽',
+      '̉','ͣ','ͤ','ͥ',
+      'ͦ','ͧ','ͨ','ͩ',
+      'ͪ','ͫ','ͬ','ͭ',
+      'ͮ','ͯ','̾','͛',
+      '͆','̚'
+      ],
+    "down" : [
+      '̖','̗','̘','̙',
+      '̜','̝','̞','̟',
+      '̠','̤','̥','̦',
+      '̩','̪','̫','̬',
+      '̭','̮','̯','̰',
+      '̱','̲','̳','̹',
+      '̺','̻','̼','ͅ',
+      '͇','͈','͉','͍',
+      '͎','͓','͔','͕',
+      '͖','͙','͚','̣'
+      ],
+    "mid" : [
+      '̕','̛','̀','́',
+      '͘','̡','̢','̧',
+      '̨','̴','̵','̶',
+      '͜','͝','͞',
+      '͟','͠','͢','̸',
+      '̷','͡',' ҉'
+      ]
+  },
+  all = [].concat(soul.up, soul.down, soul.mid),
+  zalgo = {};
+
+  function randomNumber(range) {
+    r = Math.floor(Math.random()*range);
+    return r;
+  };
+
+  function is_char(character) {
+    var bool = false;
+    all.filter(function(i){
+     bool = (i == character);
+    });
+    return bool;
+  }
+
+  function heComes(text, options){
+      result = '';
+      options = options || {};
+      options["up"] = options["up"] || true;
+      options["mid"] = options["mid"] || true;
+      options["down"] = options["down"] || true;
+      options["size"] = options["size"] || "maxi";
+      var counts;
+      text = text.split('');
+       for(var l in text){
+         if(is_char(l)) { continue; }
+         result = result + text[l];
+
+        counts = {"up" : 0, "down" : 0, "mid" : 0};
+
+        switch(options.size) {
+          case 'mini':
+            counts.up = randomNumber(8);
+            counts.min= randomNumber(2);
+            counts.down = randomNumber(8);
+          break;
+          case 'maxi':
+            counts.up = randomNumber(16) + 3;
+            counts.min = randomNumber(4) + 1;
+            counts.down = randomNumber(64) + 3;
+          break;
+          default:
+            counts.up = randomNumber(8) + 1;
+            counts.mid = randomNumber(6) / 2;
+            counts.down= randomNumber(8) + 1;
+          break;
+        }
+
+        var arr = ["up", "mid", "down"];
+        for(var d in arr){
+          var index = arr[d];
+          for (var i = 0 ; i <= counts[index]; i++)
+          {
+            if(options[index]) {
+                result = result + soul[index][randomNumber(soul[index].length)];
+              }
+            }
+          }
+        }
+      return result;
+  };
+  return heComes(text);
+}
+
+addProperty('stripColors', function() {
+  return ("" + this).replace(/\u001b\[\d+m/g,'');
+});

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.html
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.html b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.html
new file mode 100644
index 0000000..c9cd68c
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html lang="en-us">
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Colors Example</title>
+    <script src="colors.js"></script>
+    <script type="text/javascript">
+      console.log('Rainbows are fun!'.rainbow);
+      console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse);
+      console.log('Chains are also cool.'.bold.italic.underline.red);
+    </script>
+  </head>
+  <body>
+    <script>
+      document.write('Rainbows are fun!'.rainbow + '<br>');
+      document.write('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse + '<br>');
+      document.write('Chains are also cool.'.bold.italic.underline.red);
+    </script>
+  </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.js b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.js
new file mode 100644
index 0000000..12d8b1a
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/example.js
@@ -0,0 +1,20 @@
+var util = require('util');
+var colors = require('./colors');
+
+//colors.mode = "browser";
+
+var test = colors.red("hopefully colorless output");
+util.puts('Rainbows are fun!'.rainbow);
+util.puts('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
+util.puts('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
+//util.puts('zalgo time!'.zalgo);
+util.puts(test.stripColors);
+util.puts("a".grey + " b".black);
+
+util.puts(colors.rainbow('Rainbows are fun!'));
+util.puts(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
+util.puts(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
+//util.puts(colors.zalgo('zalgo time!'));
+util.puts(colors.stripColors(test));
+util.puts(colors.grey("a") + colors.black(" b"));
+

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/package.json
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/package.json b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/package.json
new file mode 100644
index 0000000..b0b4f79
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/colors/package.json
@@ -0,0 +1,49 @@
+{
+  "name": "colors",
+  "description": "get colors in your node.js console like what",
+  "version": "0.5.1",
+  "author": {
+    "name": "Marak Squires"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/Marak/colors.js.git"
+  },
+  "engines": {
+    "node": ">=0.1.90"
+  },
+  "main": "colors",
+  "_npmJsonOpts": {
+    "file": "/Users/maraksquires/.npm/colors/0.5.1/package/package.json",
+    "wscript": false,
+    "contributors": false,
+    "serverjs": false
+  },
+  "_id": "colors@0.5.1",
+  "dependencies": {},
+  "devDependencies": {},
+  "_engineSupported": true,
+  "_npmVersion": "1.0.30",
+  "_nodeVersion": "v0.4.10",
+  "_defaultsLoaded": true,
+  "dist": {
+    "shasum": "7d0023eaeb154e8ee9fce75dcb923d0ed1667774",
+    "tarball": "http://registry.npmjs.org/colors/-/colors-0.5.1.tgz"
+  },
+  "maintainers": [
+    {
+      "name": "marak",
+      "email": "marak.squires@gmail.com"
+    }
+  ],
+  "directories": {},
+  "_shasum": "7d0023eaeb154e8ee9fce75dcb923d0ed1667774",
+  "_from": "colors@0.5.x",
+  "_resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
+  "bugs": {
+    "url": "https://github.com/Marak/colors.js/issues"
+  },
+  "readme": "ERROR: No README data found!",
+  "homepage": "https://github.com/Marak/colors.js",
+  "scripts": {}
+}

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/LICENSE
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/LICENSE b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/LICENSE
new file mode 100644
index 0000000..2983774
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2011 Heather Arthur
+
+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.
+

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/README.md
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/README.md b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/README.md
new file mode 100644
index 0000000..6c218a4
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/README.md
@@ -0,0 +1,118 @@
+# js-select
+
+js-select uses [js-traverse](https://github.com/substack/js-traverse) to traverse and modify JavaScript object nodes that match [JSONSelect](http://jsonselect.org/) selectors.
+
+```javascript
+var people = {
+   george: {
+      age : 35,
+      movie: "Repo Man"
+   },
+   mary: {
+      age: 15,
+      movie: "Twilight"
+   }
+};
+```
+
+### .forEach(fn)
+
+Iterates over all matching nodes in the object. The callback gets a special `this` context. See [js-traverse](https://github.com/substack/js-traverse) for all the things you can do to modify and inspect the node with this context. In addition, js-select adds a `this.matches()` which will test if the node matches a selector:
+
+```javascript
+select(people).forEach(function(node) {
+   if (this.matches(".mary > .movie")) {
+      this.remove();
+   }
+});
+```
+
+### .nodes()
+
+Returns all matching nodes from the object.
+
+```javascript
+select(people, ".age").nodes(); // [35, 15]
+```
+
+### .remove()
+
+Removes matching elements from the original object.
+
+```javascript
+select(people, ".age").remove();
+```
+
+### .update(fn)
+
+Updates all matching nodes using the given callback.
+
+```javascript
+select(people, ".age").update(function(age) {
+   return age - 5;
+});
+```
+
+### .condense()
+
+Reduces the original object down to only the matching elements (the hierarchy is maintained).
+
+```javascript
+select(people, ".age").condense();
+```
+
+```javascript
+{
+    george: { age: 35 },
+    mary: { age: 15 }
+}
+```
+
+## Selectors
+
+js-select supports the following [JSONSelect](http://jsonselect.org/) selectors:
+
+```
+*
+type
+.key
+ancestor selector
+parent > selector
+sibling ~ selector
+selector1, selector2
+:root
+:nth-child(n)
+:nth-child(even)
+:nth-child(odd)
+:nth-last-child(n)
+:first-child
+:last-child
+:only-child
+:has(selector)
+:val("string")
+:contains("substring")
+```
+
+See [details](http://jsonselect.org/#docs/overview) on each selector, and [try them](http://jsonselect.org/#tryit) out on the JSONSelect website.
+
+## Install
+
+For [node](http://nodejs.org), install with [npm](http://npmjs.org):
+
+```bash
+npm install js-select
+```
+
+For the browser, download the select.js file or fetch the latest version from [npm](http://npmjs.org) and build a browser file using [browserify](https://github.com/substack/node-browserify):
+
+```bash
+npm install browserify -g
+npm install js-select
+
+browserify --require js-select --outfile select.js
+```
+this will build a browser file with `require('js-select')` available.
+
+## Propers
+
+Huge thanks to [@substack](http://github.com/substack) for the ingenious [js-traverse](https://github.com/substack/js-traverse) and [@lloyd](https://github.com/lloyd) for the ingenious [JSONSelect spec](http://http://jsonselect.org/) and [selector parser](http://search.npmjs.org/#/JSONSelect).
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-firefoxos/blob/b2b43200/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/index.js
----------------------------------------------------------------------
diff --git a/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/index.js b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/index.js
new file mode 100644
index 0000000..1489b8e
--- /dev/null
+++ b/node_modules/node-firefox-connect/node_modules/firefox-client/node_modules/js-select/index.js
@@ -0,0 +1,197 @@
+var traverse = require("traverse"),
+    JSONSelect = require("JSONSelect");
+
+module.exports = function(obj, string) {
+   var sels = parseSelectors(string);
+
+   return {
+      nodes: function() {
+         var nodes = [];
+         this.forEach(function(node) {
+            nodes.push(node);
+         });
+         return nodes;
+      },
+
+      update: function(cb) {
+         this.forEach(function(node) {
+            this.update(typeof cb == "function" ? cb(node) : cb);
+         });
+         return obj;
+      },
+
+      remove: function() {
+         this.forEach(function(node) {
+            this.remove();
+         })
+         return obj;
+      },
+
+      condense: function() {
+         traverse(obj).forEach(function(node) {
+            if (!this.parent) return;
+
+            if (this.parent.keep) {
+               this.keep = true;
+            } else {
+               var match = matchesAny(sels, this);
+               this.keep = match;
+               if (!match) {
+                  if (this.isLeaf) {
+                     this.remove();
+                  } else {
+                     this.after(function() {
+                        if (this.keep_child) {
+                           this.parent.keep_child = true;
+                        }
+                        if (!this.keep && !this.keep_child) {
+                           this.remove();
+                        }
+                     });
+                  }
+               } else {
+                  this.parent.keep_child = true;
+               }
+            }
+         });
+         return obj;
+      },
+
+      forEach: function(cb) {
+         traverse(obj).forEach(function(node) {
+            if (matchesAny(sels, this)) {
+               this.matches = function(string) {
+                  return matchesAny(parseSelectors(string), this);
+               };
+               // inherit context from js-traverse
+               cb.call(this, node);
+            }
+         });
+         return obj;
+      }
+   };
+}
+
+function parseSelectors(string) {
+   var parsed = JSONSelect._parse(string || "*")[1];
+   return getSelectors(parsed);
+}
+
+function getSelectors(parsed) {
+   if (parsed[0] == ",") {  // "selector1, selector2"
+      return parsed.slice(1);
+   }
+   return [parsed];
+}
+
+function matchesAny(sels, context) {
+   for (var i = 0; i < sels.length; i++) {
+      if (matches(sels[i], context)) {
+         return true;
+      }
+   }
+   return false;
+}
+
+function matches(sel, context) {
+   var path = context.parents.concat([context]),
+       i = path.length - 1,
+       j = sel.length - 1;
+
+   // walk up the ancestors
+   var must = true;
+   while(j >= 0 && i >= 0) {
+      var part = sel[j],
+          context = path[i];
+
+      if (part == ">") {
+         j--;
+         must = true;
+         continue;
+      }
+
+      if (matchesKey(part, context)) {
+         j--;
+      }
+      else if (must) {
+         return false;
+      }
+
+      i--;
+      must = false;
+   }
+   return j == -1;
+}
+
+function matchesKey(part, context) {
+   var key = context.key,
+       node = context.node,
+       parent = context.parent;
+
+   if (part.id && key != part.id) {
+      return false;
+   }
+   if (part.type) {
+      var type = part.type;
+
+      if (type == "null" && node !== null) {
+         return false;
+      }
+      else if (type == "array" && !isArray(node)) {
+         return false;
+      }
+      else if (type == "object" && (typeof node != "object"
+                 || node === null || isArray(node))) {
+         return false;
+      }
+      else if ((type == "boolean" || type == "string" || type == "number")
+               && type != typeof node) {
+         return false;
+      }
+   }
+   if (part.pf == ":nth-child") {
+      var index = parseInt(key) + 1;
+      if ((part.a == 0 && index !== part.b)         // :nth-child(i)
+        || (part.a == 1 && !(index >= -part.b))     // :nth-child(n)
+        || (part.a == -1 && !(index <= part.b))     // :nth-child(-n + 1)
+        || (part.a == 2 && index % 2 != part.b)) {  // :nth-child(even)
+         return false;
+      }
+   }
+   if (part.pf == ":nth-last-child"
+      && (!parent || key != parent.node.length - part.b)) {
+         return false;
+   }
+   if (part.pc == ":only-child"
+      && (!parent || parent.node.length != 1)) {
+         return false;
+   }
+   if (part.pc == ":root" && key !== undefined) {
+      return false;
+   }
+   if (part.has) {
+      var sels = getSelectors(part.has[0]),
+          match = false;
+      traverse(node).forEach(function(child) {
+         if (matchesAny(sels, this)) {
+            match = true;
+         }
+      });
+      if (!match) {
+         return false;
+      }
+   }
+   if (part.expr) {
+      var expr = part.expr, lhs = expr[0], op = expr[1], rhs = expr[2];
+      if (typeof node != "string"
+          || (!lhs && op == "=" && node != rhs)   // :val("str")
+          || (!lhs && op == "*=" && node.indexOf(rhs) == -1)) { // :contains("substr")
+         return false;
+      }
+   }
+   return true;
+}
+
+var isArray = Array.isArray || function(obj) {
+    return toString.call(obj) === '[object Array]';
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org