You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by bh...@apache.org on 2014/03/27 16:08:49 UTC

[35/51] [partial] CB-6346 - Add node_modules to source control

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js
new file mode 100644
index 0000000..a4bd2e7
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js
@@ -0,0 +1,520 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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')
+  , path = require('path')
+  , JS_PAT = /\.(js|coffee)$/
+  , logger;
+
+var logger = new (function () {
+  var out;
+  try {
+    out = require('./logger');
+  }
+  catch (e) {
+    out = console;
+  }
+
+  this.log = function (o) {
+    out.log(o);
+  };
+})();
+
+/**
+  @name file
+  @namespace file
+*/
+
+var fileUtils = new (function () {
+  var _copyFile
+    , _copyDir
+    , _readDir
+    , _rmDir
+    , _watch;
+
+
+  // Recursively copy files and directories
+  _copyFile = function (fromPath, toPath, opts) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , options = opts || {}
+      , fromStat
+      , toStat
+      , destExists
+      , destDoesNotExistErr
+      , content
+      , filename
+      , dirContents
+      , targetDir;
+
+    fromStat = fs.statSync(from);
+
+    try {
+      //console.dir(to + ' destExists');
+      toStat = fs.statSync(to);
+      destExists = true;
+    }
+    catch(e) {
+      //console.dir(to + ' does not exist');
+      destDoesNotExistErr = e;
+      destExists = false;
+    }
+    // Destination dir or file exists, copy into (directory)
+    // or overwrite (file)
+    if (destExists) {
+
+      // If there's a rename-via-copy file/dir name passed, use it.
+      // Otherwise use the actual file/dir name
+      filename = options.rename || path.basename(from);
+
+      // Copying a directory
+      if (fromStat.isDirectory()) {
+        dirContents = fs.readdirSync(from);
+        targetDir = path.join(to, filename);
+        // We don't care if the target dir already exists
+        try {
+          fs.mkdirSync(targetDir, options.mode || 0755);
+        }
+        catch(e) {
+          if (e.code != 'EEXIST') {
+            throw e;
+          }
+        }
+        for (var i = 0, ii = dirContents.length; i < ii; i++) {
+          //console.log(dirContents[i]);
+          _copyFile(path.join(from, dirContents[i]), targetDir);
+        }
+      }
+      // Copying a file
+      else {
+        content = fs.readFileSync(from);
+        // Copy into dir
+        if (toStat.isDirectory()) {
+          //console.log('copy into dir ' + to);
+          fs.writeFileSync(path.join(to, filename), content);
+        }
+        // Overwrite file
+        else {
+          //console.log('overwriting ' + to);
+          fs.writeFileSync(to, content);
+        }
+      }
+    }
+    // Dest doesn't exist, can't create it
+    else {
+      throw destDoesNotExistErr;
+    }
+  };
+
+  _copyDir = function (from, to, opts) {
+    var createDir = opts.createDir;
+  };
+
+  // Return the contents of a given directory
+  _readDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = []
+      , ret = [dir]
+      , msg;
+
+    try {
+      paths = fs.readdirSync(dir);
+    }
+    catch (e) {
+      msg = 'Could not read path ' + dir + '\n';
+      if (e.stack) {
+        msg += e.stack;
+      }
+      throw new Error(msg);
+    }
+
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        ret = ret.concat(_readDir(curr));
+      }
+      else {
+        ret.push(curr);
+      }
+    });
+
+    return ret;
+  };
+
+  // Remove the given directory
+  _rmDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = [];
+    paths = fs.readdirSync(dir);
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        _rmDir(curr);
+      }
+      else {
+        fs.unlinkSync(curr);
+      }
+    });
+    fs.rmdirSync(dir);
+  };
+
+  // Recursively watch files with a callback
+  _watch = function (path, callback) {
+    fs.stat(path, function (err, stats) {
+      if (err) {
+        return false;
+      }
+      if (stats.isFile() && JS_PAT.test(path)) {
+        fs.watchFile(path, callback);
+      }
+      else if (stats.isDirectory()) {
+        fs.readdir(path, function (err, files) {
+          if (err) {
+            return log.fatal(err);
+          }
+          for (var f in files) {
+            _watch(path + '/' + files[f], callback);
+          }
+        });
+      }
+    });
+  };
+
+  /**
+    @name file#cpR
+    @public
+    @function
+    @description Copies a directory/file to a destination
+    @param {String} fromPath The source path to copy from
+    @param {String} toPath The destination path to copy to
+    @param {Object} opts Options to use
+      @param {Boolean} [opts.silent] If false then will log the command
+  */
+  this.cpR = function (fromPath, toPath, options) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , toStat
+      , doesNotExistErr
+      , paths
+      , filename
+      , opts = options || {};
+
+    if (!opts.silent) {
+      logger.log('cp -r ' + fromPath + ' ' + toPath);
+    }
+
+    opts = {}; // Reset
+
+    if (from == to) {
+      throw new Error('Cannot copy ' + from + ' to itself.');
+    }
+
+    // Handle rename-via-copy
+    try {
+      toStat = fs.statSync(to);
+    }
+    catch(e) {
+      doesNotExistErr = e;
+
+      // Get abs path so it's possible to check parent dir
+      if (!this.isAbsolute(to)) {
+        to = path.join(process.cwd() , to);
+      }
+
+      // Save the file/dir name
+      filename = path.basename(to);
+      // See if a parent dir exists, so there's a place to put the
+      /// renamed file/dir (resets the destination for the copy)
+      to = path.dirname(to);
+      try {
+        toStat = fs.statSync(to);
+      }
+      catch(e) {}
+      if (toStat && toStat.isDirectory()) {
+        // Set the rename opt to pass to the copy func, will be used
+        // as the new file/dir name
+        opts.rename = filename;
+        //console.log('filename ' + filename);
+      }
+      else {
+        throw doesNotExistErr;
+      }
+    }
+
+    _copyFile(from, to, opts);
+  };
+
+  /**
+    @name file#mkdirP
+    @public
+    @function
+    @description Create the given directory(ies) using the given mode permissions
+    @param {String} dir The directory to create
+    @param {Number} mode The mode to give the created directory(ies)(Default: 0755)
+  */
+  this.mkdirP = function (dir, mode) {
+    var dirPath = path.normalize(dir)
+      , paths = dirPath.split(/\/|\\/)
+      , currPath = ''
+      , next;
+
+    if (paths[0] == '' || /^[A-Za-z]+:/.test(paths[0])) {
+      currPath = paths.shift() || '/';
+      currPath = path.join(currPath, paths.shift());
+      //console.log('basedir');
+    }
+    while ((next = paths.shift())) {
+      if (next == '..') {
+        currPath = path.join(currPath, next);
+        continue;
+      }
+      currPath = path.join(currPath, next);
+      try {
+        //console.log('making ' + currPath);
+        fs.mkdirSync(currPath, mode || 0755);
+      }
+      catch(e) {
+        if (e.code != 'EEXIST') {
+          throw e;
+        }
+      }
+    }
+  };
+
+  /**
+    @name file#readdirR
+    @public
+    @function
+    @return {Array} Returns the contents as an Array, can be configured via opts.format
+    @description Reads the given directory returning it's contents
+    @param {String} dir The directory to read
+    @param {Object} opts Options to use
+      @param {String} [opts.format] Set the format to return(Default: Array)
+  */
+  this.readdirR = function (dir, opts) {
+    var options = opts || {}
+      , format = options.format || 'array'
+      , ret;
+    ret = _readDir(dir);
+    return format == 'string' ? ret.join('\n') : ret;
+  };
+
+  /**
+    @name file#rmRf
+    @public
+    @function
+    @description Deletes the given directory/file
+    @param {String} p The path to delete, can be a directory or file
+    @param {Object} opts Options to use
+      @param {String} [opts.silent] If false then logs the command
+  */
+  this.rmRf = function (p, options) {
+    var stat
+      , opts = options || {};
+    if (!opts.silent) {
+      logger.log('rm -rf ' + p);
+    }
+    try {
+      stat = fs.statSync(p);
+      if (stat.isDirectory()) {
+        _rmDir(p);
+      }
+      else {
+        fs.unlinkSync(p);
+      }
+    }
+    catch (e) {}
+  };
+
+  /**
+    @name file#isAbsolute
+    @public
+    @function
+    @return {Boolean/String} If it's absolute the first char is returned otherwise false
+    @description Checks if a given path is absolute or relative
+    @param {String} p Path to check
+  */
+  this.isAbsolute = function (p) {
+    var match = /^[A-Za-z]+:\\|^\//.exec(p);
+    if (match && match.length) {
+      return match[0];
+    }
+    return false;
+  };
+
+  /**
+    @name file#absolutize
+    @public
+    @function
+    @return {String} Returns the absolute path for the given path
+    @description Returns the absolute path for the given path
+    @param {String} p The path to get the absolute path for
+  */
+  this.absolutize = function (p) {
+    if (this.isAbsolute(p)) {
+      return p;
+    }
+    else {
+      return path.join(process.cwd(), p);
+    }
+  };
+
+  /**
+    Given a patern, return the base directory of it (ie. the folder
+    that will contain all the files matching the path).
+    eg. file.basedir('/test/**') => '/test/'
+    Path ending by '/' are considerd as folder while other are considerd
+    as files, eg.:
+        file.basedir('/test/a/') => '/test/a'
+        file.basedir('/test/a') => '/test'
+    The returned path always end with a '/' so we have:
+        file.basedir(file.basedir(x)) == file.basedir(x)
+  */
+  this.basedir = function (pathParam) {
+    var basedir = ''
+      , parts
+      , part
+      , pos = 0
+      , p = pathParam || '';
+
+    // If the path has a leading asterisk, basedir is the current dir
+    if (p.indexOf('*') == 0 || p.indexOf('**') == 0) {
+      return '.';
+    }
+
+    // always consider .. at the end as a folder and not a filename
+    if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) {
+      p += '/';
+    }
+
+    parts = p.split(/\\|\//);
+    for (var i = 0, l = parts.length - 1; i < l; i++) {
+      part = parts[i];
+      if (part.indexOf('*') > -1 || part.indexOf('**') > -1) {
+        break;
+      }
+      pos += part.length + 1;
+      basedir += part + p[pos - 1];
+    }
+    if (!basedir) {
+      basedir = '.';
+    }
+    // Strip trailing slashes
+    if (!(basedir == '\\' || basedir == '/')) {
+      basedir = basedir.replace(/\\$|\/$/, '');
+    }
+    return basedir;
+
+  };
+
+  /**
+    @name file#searchParentPath
+    @public
+    @function
+    @description Search for a directory/file in the current directory and parent directories
+    @param {String} p The path to search for
+    @param {Function} callback The function to call once the path is found
+  */
+  this.searchParentPath = function (location, beginPath, callback) {
+    if (typeof beginPath === 'function' && !callback) {
+      callback = beginPath;
+      beginPath = process.cwd();
+    }
+    var cwd = beginPath || process.cwd();
+
+    if (!location) {
+      // Return if no path is given
+      return;
+    }
+    var relPath = ''
+      , i = 5 // Only search up to 5 directories
+      , pathLoc
+      , pathExists;
+
+    while (--i >= 0) {
+      pathLoc = path.join(cwd, relPath, location);
+      pathExists = this.existsSync(pathLoc);
+
+      if (pathExists) {
+        callback && callback(undefined, pathLoc);
+        break;
+      } else {
+        // Dir could not be found
+        if (i === 0) {
+          callback && callback(new Error("Path \"" + pathLoc + "\" not found"), undefined);
+          break;
+        }
+
+        // Add a relative parent directory
+        relPath += '../';
+        // Switch to relative parent directory
+        process.chdir(path.join(cwd, relPath));
+      }
+    }
+  };
+
+  /**
+    @name file#watch
+    @public
+    @function
+    @description Watch a given path then calls the callback once a change occurs
+    @param {String} path The path to watch
+    @param {Function} callback The function to call when a change occurs
+  */
+  this.watch = function () {
+    _watch.apply(this, arguments);
+  };
+
+  // Compatibility for fs.exists(0.8) and path.exists(0.6)
+  this.exists = (typeof fs.exists === 'function') ? fs.exists : path.exists;
+
+  // Compatibility for fs.existsSync(0.8) and path.existsSync(0.6)
+  this.existsSync = (typeof fs.existsSync === 'function') ? fs.existsSync : path.existsSync;
+
+  /**
+    @name file#requireLocal
+    @public
+    @function
+    @return {Object} The given module is returned
+    @description Require a local module from the node_modules in the current directory
+    @param {String} module The module to require
+    @param {String} message An option message to throw if the module doesn't exist
+  */
+  this.requireLocal = function (module, message) {
+    // Try to require in the application directory
+    try {
+      dep = require(path.join(process.cwd(), 'node_modules', module));
+    }
+    catch(err) {
+      if (message) {
+        throw new Error(message);
+      }
+      throw new Error('Module "' + module + '" could not be found as a ' +
+          'local module.\n Please make sure there is a node_modules directory in the ' +
+          'current directory,\n and install it by doing "npm install ' +
+          module + '"');
+    }
+    return dep;
+  };
+
+})();
+
+module.exports = fileUtils;
+

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js
new file mode 100644
index 0000000..aa00950
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js
@@ -0,0 +1,60 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 core = require('./core')
+  , i18n;
+
+i18n = new (function () {
+  var _defaultLocale = 'en-us'
+    , _strings = {};
+
+  this.getText = function (key, opts, locale) {
+    var currentLocale = locale || _defaultLocale
+      , currentLocaleStrings = _strings[currentLocale] || {}
+      , defaultLocaleStrings = _strings[_defaultLocale] || {}
+      , str = currentLocaleStrings[key]
+            || defaultLocaleStrings[key] || "[[" + key + "]]";
+    for (p in opts) {
+      str = str.replace(new RegExp('\\{' + p + '\\}', 'g'), opts[p]);
+    }
+    return str;
+  };
+
+  this.getDefaultLocale = function (locale) {
+    return _defaultLocale;
+  };
+
+  this.setDefaultLocale = function (locale) {
+    _defaultLocale = locale;
+  };
+
+  this.loadLocale = function (locale, strings) {
+    _strings[locale] = _strings[locale] || {};
+    core.mixin(_strings[locale], strings);
+  };
+
+})();
+
+i18n.I18n = function (locale) {
+  this.getText = function (key, opts) {
+    return i18n.getText(key, opts || {}, locale);
+  };
+  this.t = this.getText;
+};
+
+module.exports = i18n;
+

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js
new file mode 100644
index 0000000..97e1118
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js
@@ -0,0 +1,59 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 utils = {}
+// Core methods
+  , core = require('./core')
+// Namespaces with methods
+  , string = require('./string')
+  , file = require('./file')
+  , async = require('./async')
+  , i18n = require('./i18n')
+  , uri = require('./uri')
+  , array = require('./array')
+  , object = require('./object')
+  , date = require('./date')
+  , request = require('./request')
+  , log = require('./log')
+  , network = require('./network')
+// Third-party -- remove this if possible
+  , inflection = require('./inflection')
+// Constructors
+  , EventBuffer = require('./event_buffer').EventBuffer
+  , XML = require('./xml').XML
+  , SortedCollection = require('./sorted_collection').SortedCollection;
+
+core.mixin(utils, core);
+
+utils.string = string;
+utils.file = file;
+utils.async = async;
+utils.i18n = i18n;
+utils.uri = uri;
+utils.array = array;
+utils.object = object;
+utils.date = date;
+utils.request = request;
+utils.log = log;
+utils.network = network;
+utils.inflection = inflection;
+utils.SortedCollection = SortedCollection;
+utils.EventBuffer = EventBuffer;
+utils.XML = XML;
+
+module.exports = utils;
+

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js
new file mode 100644
index 0000000..2d89839
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2010 George Moschovitis, http://www.gmosx.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 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.
+ *
+ * A port of the Rails/ActiveSupport Inflector class
+ * http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html
+*/
+
+/**
+  @name inflection
+  @namespace inflection
+*/
+
+var inflection = new (function () {
+
+  /**
+    @name inflection#inflections
+    @public
+    @object
+    @description A list of rules and replacements for different inflection types
+  */
+  this.inflections = {
+      plurals: []
+    , singulars: []
+    , uncountables: []
+  };
+
+  var self = this
+    , setInflection
+    , setPlural
+    , setSingular
+    , setUncountable
+    , setIrregular;
+
+  // Add a new inflection rule/replacement to the beginning of the array for the
+  // inflection type
+  setInflection = function (type, rule, replacement) {
+    self.inflections[type].unshift([rule, replacement]);
+  };
+
+  // Add a new plural inflection rule
+  setPlural = function (rule, replacement) {
+    setInflection('plurals', rule, replacement);
+  };
+
+  // Add a new singular inflection rule
+  setSingular = function (rule, replacement) {
+    setInflection('singulars', rule, replacement);
+  };
+
+  // Add a new irregular word to the inflection list, by a given singular and plural inflection
+  setIrregular = function (singular, plural) {
+    if (singular.substr(0, 1).toUpperCase() == plural.substr(0, 1).toUpperCase()) {
+      setPlural(new RegExp("(" + singular.substr(0, 1) + ")" + singular.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setPlural(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setSingular(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + singular.substr(1));
+    } else {
+      setPlural(new RegExp(singular.substr(0, 1).toUpperCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(singular.substr(0, 1).toLowerCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toUpperCase() + singular.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toLowerCase() + singular.substr(1));
+    }
+  };
+
+  // Add a new word to the uncountable inflection list
+  setUncountable = function (word) {
+    self.inflections.uncountables[word] = true;
+  };
+
+  // Create inflections
+  (function () {
+    setPlural(/$/, "s");
+    setPlural(/s$/i, "s");
+    setPlural(/(ax|test)is$/i, "$1es");
+    setPlural(/(octop|vir)us$/i, "$1i");
+    setPlural(/(alias|status)$/i, "$1es");
+    setPlural(/(bu)s$/i, "$1ses");
+    setPlural(/(buffal|tomat)o$/i, "$1oes");
+    setPlural(/([ti])um$/i, "$1a");
+    setPlural(/sis$/i, "ses");
+    setPlural(/(?:([^f])fe|([lr])f)$/i, "$1$2ves");
+    setPlural(/(hive)$/i, "$1s");
+    setPlural(/([^aeiouy]|qu)y$/i, "$1ies");
+    setPlural(/(x|ch|ss|sh)$/i, "$1es");
+    setPlural(/(matr|vert|ind)(?:ix|ex)$/i, "$1ices");
+    setPlural(/([m|l])ouse$/i, "$1ice");
+    setPlural(/^(ox)$/i, "$1en");
+    setPlural(/(quiz)$/i, "$1zes");
+
+    setSingular(/s$/i, "")
+		setSingular(/ss$/i, "ss")
+    setSingular(/(n)ews$/i, "$1ews")
+    setSingular(/([ti])a$/i, "$1um")
+    setSingular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis")
+    setSingular(/(^analy)ses$/i, "$1sis")
+    setSingular(/([^f])ves$/i, "$1fe")
+    setSingular(/(hive)s$/i, "$1")
+    setSingular(/(tive)s$/i, "$1")
+    setSingular(/([lr])ves$/i, "$1f")
+    setSingular(/([^aeiouy]|qu)ies$/i, "$1y")
+    setSingular(/(s)eries$/i, "$1eries")
+    setSingular(/(m)ovies$/i, "$1ovie")
+    setSingular(/(x|ch|ss|sh)es$/i, "$1")
+    setSingular(/([m|l])ice$/i, "$1ouse")
+    setSingular(/(bus)es$/i, "$1")
+    setSingular(/(o)es$/i, "$1")
+    setSingular(/(shoe)s$/i, "$1")
+    setSingular(/(cris|ax|test)es$/i, "$1is")
+    setSingular(/(octop|vir)i$/i, "$1us")
+    setSingular(/(alias|status)es$/i, "$1")
+    setSingular(/^(ox)en/i, "$1")
+    setSingular(/(vert|ind)ices$/i, "$1ex")
+    setSingular(/(matr)ices$/i, "$1ix")
+    setSingular(/(quiz)zes$/i, "$1")
+    setSingular(/(database)s$/i, "$1")
+
+    setIrregular("person", "people");
+    setIrregular("man", "men");
+    setIrregular("child", "children");
+    setIrregular("sex", "sexes");
+    setIrregular("move", "moves");
+    setIrregular("cow", "kine");
+
+    setUncountable("equipment");
+    setUncountable("information");
+    setUncountable("rice");
+    setUncountable("money");
+    setUncountable("species");
+    setUncountable("series");
+    setUncountable("fish");
+    setUncountable("sheep");
+    setUncountable("jeans");
+  })();
+
+  /**
+    @name inflection#parse
+    @public
+    @function
+    @return {String} The inflection of the word from the type given
+    @description Parse a word from the given inflection type
+    @param {String} type A type of the inflection to use
+    @param {String} word the word to parse
+  */
+  this.parse = function (type, word) {
+    var lowWord = word.toLowerCase()
+      , inflections = this.inflections[type];
+
+    if (this.inflections.uncountables[lowWord]) {
+      return word;
+    }
+
+    var i = -1;
+    while (++i < inflections.length) {
+      var rule = inflections[i][0]
+        , replacement = inflections[i][1];
+
+      if (rule.test(word)) {
+        return word.replace(rule, replacement)
+      }
+    }
+
+    return word;
+  };
+
+  /**
+    @name inflection#pluralize
+    @public
+    @function
+    @return {String} The plural inflection for the given word
+    @description Create a plural inflection for a word
+    @param {String} word the word to create a plural version for
+  */
+  this.pluralize = function (word) {
+    return this.parse('plurals', word);
+  };
+
+  /**
+    @name inflection#singularize
+    @public
+    @function
+    @return {String} The singular inflection for the given word
+    @description Create a singular inflection for a word
+    @param {String} word the word to create a singular version for
+  */
+  this.singularize = function (word) {
+    return this.parse('singulars', word);
+  };
+
+})();
+
+module.exports = inflection;

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js
new file mode 100644
index 0000000..d26557b
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js
@@ -0,0 +1,67 @@
+var util = require('util')
+  , log
+  , _logger
+  , _levels
+  , _serialize
+  , _output;
+
+_levels = {
+  'debug': 'log'
+, 'info': 'log'
+, 'notice': 'log'
+, 'warning': 'error'
+, 'error': 'error'
+, 'critical': 'error'
+, 'alert': 'error'
+, 'emergency': 'error'
+};
+
+_serialize = function (obj) {
+  var out;
+  if (typeof obj == 'string') {
+    out = obj;
+  }
+  else {
+    out = util.inspect(obj);
+  }
+  return out;
+};
+
+_output = function (obj, level) {
+  var out = _serialize(obj);
+  if (_logger) {
+    _logger[level](out);
+  }
+  else {
+    console[_levels[level]](out);
+  }
+};
+
+
+log = function (obj) {
+  _output(obj, 'info');
+};
+
+log.registerLogger = function (logger) {
+  // Malkovitch, Malkovitch
+  if (logger === log) {
+    return;
+  }
+  _logger = logger;
+};
+
+(function () {
+  var level;
+  for (var p in _levels) {
+    (function (p) {
+      level = _levels[p];
+      log[p] = function (obj) {
+        _output(obj, p);
+      };
+    })(p);
+  }
+  // Also handle 'access', not an actual level
+  log.access = log.info;
+})();
+
+module.exports = log;

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js
new file mode 100644
index 0000000..c90324d
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js
@@ -0,0 +1,72 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 network
+	, net = require('net');
+
+/**
+  @name network
+  @namespace network
+*/
+
+network = new (function () {
+	/**
+		@name network#isPortOpen
+		@public
+		@function
+		@description Checks if the given port in the given host is open
+		@param {Number} port number
+		@param {String} host
+		@param {Function} callback Callback function -- should be in the format
+			of function(err, result) {}
+	*/
+	this.isPortOpen = function (port, host, callback) {
+		if (typeof host === 'function' && !callback) {
+			callback = host;
+			host = 'localhost';
+		}
+
+		var isOpen = false
+			, connection
+			, error;
+
+		connection = net.createConnection(port, host, function () {
+			isOpen = true;
+			connection.end();
+		});
+
+		connection.on('error', function (err) {
+			// We ignore 'ECONNREFUSED' as it simply indicates the port isn't open.
+			// Anything else is reported
+			if(err.code !== 'ECONNREFUSED') {
+				error = err;
+			}
+		});
+
+		connection.setTimeout(400, function () {
+			connection.end();
+		});
+
+		connection.on('close', function () {
+			callback && callback(error, isOpen);
+		});
+	};
+
+})();
+
+module.exports = network;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js
new file mode 100644
index 0000000..dd92e7d
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js
@@ -0,0 +1,108 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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.
+ *
+*/
+
+/**
+  @name object
+  @namespace object
+*/
+
+var object = new (function () {
+
+  /**
+    @name object#merge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description Merge merges `otherObject` into `object` and takes care of deep
+                 merging of objects
+    @param {Object} object Object to merge into
+    @param {Object} otherObject Object to read from
+  */
+  this.merge = function (object, otherObject) {
+    var obj = object || {}
+      , otherObj = otherObject || {}
+      , key, value;
+
+    for (key in otherObj) {
+      value = otherObj[key];
+
+      // Check if a value is an Object, if so recursively add it's key/values
+      if (typeof value === 'object' && !(value instanceof Array)) {
+        // Update value of object to the one from otherObj
+        obj[key] = this.merge(obj[key], value);
+      }
+      // Value is anything other than an Object, so just add it
+      else {
+        obj[key] = value;
+      }
+    }
+
+    return obj;
+  };
+
+  /**
+    @name object#reverseMerge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description ReverseMerge merges `object` into `defaultObject`
+    @param {Object} object Object to read from
+    @param {Object} defaultObject Object to merge into
+  */
+  this.reverseMerge = function (object, defaultObject) {
+    // Same as `merge` except `defaultObject` is the object being changed
+    // - this is useful if we want to easily deal with default object values
+    return this.merge(defaultObject, object);
+  };
+
+  /**
+    @name object#isEmpty
+    @public
+    @function
+    @return {Boolean} Returns true if empty false otherwise
+    @description isEmpty checks if an Object is empty
+    @param {Object} object Object to check if empty
+  */
+  this.isEmpty = function (object) {
+    // Returns true if a object is empty false if not
+    for (var i in object) { return false; }
+    return true;
+  };
+
+  /**
+    @name object#toArray
+    @public
+    @function
+    @return {Array} Returns an array of objects each including the original key and value
+    @description Converts an object to an array of objects each including the original key/value
+    @param {Object} object Object to convert
+  */
+  this.toArray = function (object) {
+    // Converts an object into an array of objects with the original key, values
+    array = [];
+
+    for (var i in object) {
+      array.push({ key: i, value: object[i] });
+    }
+
+    return array;
+  };
+
+})();
+
+module.exports = object;

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js
new file mode 100644
index 0000000..0984db1
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js
@@ -0,0 +1,143 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 http = require('http')
+  , https = require('https')
+  , url = require('url')
+  , uri = require('./uri')
+  , log = require('./log')
+  , core = require('./core');
+
+var formatters = {
+  xml: function (data) {
+    return data;
+  }
+, html: function (data) {
+    return data;
+  }
+, txt: function (data) {
+    return data;
+  }
+, json: function (data) {
+    return JSON.parse(data);
+  }
+}
+
+/**
+  @name request
+  @namespace request
+  @public
+  @function
+  @description Sends requests to the given url sending any data if the method is POST or PUT
+  @param {Object} opts The options to use for the request
+    @param {String} [opts.url] The URL to send the request to
+    @param {String} [opts.method=GET] The method to use for the request
+    @param {Object} [opts.headers] Headers to send on requests
+    @param {String} [opts.data] Data to send on POST and PUT requests
+    @param {String} [opts.dataType] The type of data to send
+  @param {Function} callback the function to call after, args are `error, data`
+*/
+var request = function (opts, callback) {
+  var client
+    , options = opts || {}
+    , parsed = url.parse(options.url)
+    , path
+    , requester = parsed.protocol == 'http:' ? http : https
+    , method = (options.method && options.method.toUpperCase()) || 'GET'
+    , headers = core.mixin({}, options.headers || {})
+    , contentLength
+    , port
+    , clientOpts;
+
+  if (parsed.port) {
+    port = parsed.port;
+  }
+  else {
+    port = parsed.protocol == 'http:' ? '80' : '443';
+  }
+
+  path = parsed.pathname;
+  if (parsed.search) {
+    path += parsed.search;
+  }
+
+  if (method == 'POST' || method == 'PUT') {
+    if (options.data) {
+      contentLength = options.data.length;
+    }
+    else {
+      contentLength = 0
+    }
+    headers['Content-Length'] = contentLength;
+  }
+
+  clientOpts = {
+    host: parsed.hostname
+  , port: port
+  , method: method
+  , agent: false
+  , path: path
+  , headers: headers
+  };
+  client = requester.request(clientOpts);
+
+  client.addListener('response', function (resp) {
+    var data = ''
+      , dataType;
+    resp.addListener('data', function (chunk) {
+      data += chunk.toString();
+    });
+    resp.addListener('end', function () {
+      var stat = resp.statusCode
+        , err;
+      // Successful response
+      if ((stat > 199 && stat < 300) || stat == 304) {
+        dataType = options.dataType || uri.getFileExtension(parsed.pathname);
+        if (formatters[dataType]) {
+          try {
+            if (data) {
+              data = formatters[dataType](data);
+            }
+          }
+          catch (e) {
+            callback(e, null);
+          }
+        }
+        callback(null, data);
+      }
+      // Something failed
+      else {
+        err = new Error(data);
+        err.statusCode = resp.statusCode;
+        callback(err, null);
+      }
+
+    });
+  });
+
+  client.addListener('error', function (e) {
+    callback(e, null);
+  });
+
+  if ((method == 'POST' || method == 'PUT') && options.data) {
+    client.write(options.data);
+  }
+
+  client.end();
+};
+
+module.exports = request;

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/sorted_collection.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/sorted_collection.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/sorted_collection.js
new file mode 100644
index 0000000..bdeca90
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/sorted_collection.js
@@ -0,0 +1,558 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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.
+ *
+*/
+
+/**
+  @name SortedCollection
+  @namespace SortedCollection
+  @constructor
+*/
+
+var SortedCollection = function (d) {
+  this.count = 0;
+  this.items = {}; // Hash keys and their values
+  this.order = []; // Array for sort order
+  if (d) {
+    this.defaultValue = d;
+  };
+};
+
+SortedCollection.prototype = new (function () {
+  /**
+    @name SortedCollection#addItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Adds a new key/value to the collection
+    @param {String} key The key for the collection item
+    @param {Any} val The value for the collection item
+  */
+  this.addItem = function (key, val) {
+    if (typeof key != 'string') {
+      throw('Hash only allows string keys.');
+    }
+    return this.setByKey(key, val);
+  };
+
+  /**
+    @name SortedCollection#getItem
+    @public
+    @function
+    @return {Any} The value for the given identifier is returned
+    @description Retrieves the value for the given identifier that being a key or index
+    @param {String/Number} p The identifier to look in the collection for, being a key or index
+  */
+  this.getItem = function (p) {
+    if (typeof p == 'string') {
+      return this.getByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.getByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#setItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets the item in the collection with the given val, overwriting the existsing item
+      if identifier is an index
+    @param {String/Number} p The identifier set in the collection, being either a key or index
+    @param {Any} val The value for the collection item
+  */
+  this.setItem = function (p, val) {
+    if (typeof p == 'string') {
+      return this.setByKey(p, val);
+    }
+    else if (typeof p == 'number') {
+      return this.setByIndex(p, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#removeItem
+    @public
+    @function
+    @return {Boolean} Returns true if the item has been removed, false otherwise
+    @description Removes the item for the given identifier
+    @param {String/Number} p The identifier to delete the item for, being a key or index
+  */
+  this.removeItem = function (p) {
+    if (typeof p == 'string') {
+      return this.removeByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.removeByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#getByKey
+    @public
+    @function
+    @return {Any} The value for the given key item is returned
+    @description Retrieves the value for the given key
+    @param {String} key The key for the item to lookup
+  */
+  this.getByKey = function (key) {
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#setByKey
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by key assigning the given val
+    @param {String} key The key for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByKey = function (key, val) {
+    var v = null;
+    if (typeof val == 'undefined') {
+      v = this.defaultValue;
+    }
+    else { v = val; }
+    if (typeof this.items[key] == 'undefined') {
+      this.order[this.count] = key;
+      this.count++;
+    }
+    this.items[key] = v;
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#removeByKey
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by key
+    @param {String} key The key for the item to remove
+  */
+  this.removeByKey = function (key) {
+    if (typeof this.items[key] != 'undefined') {
+      var pos = null;
+      delete this.items[key]; // Remove the value
+      // Find the key in the order list
+      for (var i = 0; i < this.order.length; i++) {
+        if (this.order[i] == key) {
+          pos = i;
+        }
+      }
+      this.order.splice(pos, 1); // Remove the key
+      this.count--; // Decrement the length
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#getByIndex
+    @public
+    @function
+    @return {Any} The value for the given index item is returned
+    @description Retrieves the value for the given index
+    @param {Number} ind The index to lookup for the item
+  */
+  this.getByIndex = function (ind) {
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#setByIndex
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by index assigning the given val
+    @param {Number} ind The index for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByIndex = function (ind, val) {
+    if (ind < 0 || ind >= this.count) {
+      throw('Index out of bounds. Hash length is ' + this.count);
+    }
+    this.items[this.order[ind]] = val;
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#removeByIndex
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by index
+    @param {Number} ind The index for the item to remove
+  */
+  this.removeByIndex = function (ind) {
+    var ret = this.items[this.order[ind]];
+    if (typeof ret != 'undefined') {
+      delete this.items[this.order[ind]]
+      this.order.splice(ind, 1);
+      this.count--;
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#hasKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item exists, false otherwise
+    @description Checks if a key item exists in the collection
+    @param {String} key The key to look for in the collection
+  */
+  this.hasKey = function (key) {
+    return typeof this.items[key] != 'undefined';
+  };
+
+  /**
+    @name SortedCollection#hasValue
+    @public
+    @function
+    @return {Boolean} Returns true if a key with the given value exists, false otherwise
+    @description Checks if a key item in the collection has a given val
+    @param {Any} val The value to check for in the collection
+  */
+  this.hasValue = function (val) {
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.items[this.order[i]] == val) {
+        return true;
+      }
+    }
+    return false;
+  };
+
+  /**
+    @name SortedCollection#allKeys
+    @public
+    @function
+    @return {String} Returns all the keys in a string
+    @description Joins all the keys into a string
+    @param {String} str The string to use between each key
+  */
+  this.allKeys = function (str) {
+    return this.order.join(str);
+  };
+
+  /**
+    @name SortedCollection#replaceKey
+    @public
+    @function
+    @description Joins all the keys into a string
+    @param {String} oldKey The key item to change
+    @param {String} newKey The key item to change the name to
+  */
+  this.replaceKey = function (oldKey, newKey) {
+    // If item for newKey exists, nuke it
+    if (this.hasKey(newKey)) {
+      this.removeItem(newKey);
+    }
+    this.items[newKey] = this.items[oldKey];
+    delete this.items[oldKey];
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.order[i] == oldKey) {
+        this.order[i] = newKey;
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#insertAtIndex
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set at the given index
+    @description Inserts a key/value at a specific index in the collection
+    @param {Number} ind The index to set the item at
+    @param {String} key The key to use at the item index
+    @param {Any} val The value to set for the item
+  */
+  this.insertAtIndex = function (ind, key, val) {
+    this.order.splice(ind, 0, key);
+    this.items[key] = val;
+    this.count++;
+    return true;
+  };
+
+  /**
+    @name SortedCollection#insertAfterKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set for the given key
+    @description Inserts a key/value item after the given reference key in the collection
+    @param {String} refKey The key to insert the new item after
+    @param {String} key The key for the new item
+    @param {Any} val The value to set for the item
+  */
+  this.insertAfterKey = function (refKey, key, val) {
+    var pos = this.getPosition(refKey);
+    return this.insertAtIndex(pos, key, val);
+  };
+
+  /**
+    @name SortedCollection#getPosition
+    @public
+    @function
+    @return {Number} Returns the index for the item of the given key
+    @description Retrieves the index of the key item
+    @param {String} key The key to get the index for
+  */
+  this.getPosition = function (key) {
+    var order = this.order;
+    if (typeof order.indexOf == 'function') {
+      return order.indexOf(key);
+    }
+    else {
+      for (var i = 0; i < order.length; i++) {
+        if (order[i] == key) { return i;}
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#each
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, the arguments
+      are the key and value for the current item
+    @param {Object} opts The options to use
+      @param {Boolean} [opts.keyOnly] Only give the function the key
+      @param {Boolean} [opts.valueOnly] Only give the function the value
+  */
+  this.each = function (func, opts) {
+    var options = opts || {}
+      , order = this.order;
+    for (var i = 0, ii = order.length; i < ii; i++) {
+      var key = order[i];
+      var val = this.items[key];
+      if (options.keyOnly) {
+        func(key);
+      }
+      else if (options.valueOnly) {
+        func(val);
+      }
+      else {
+        func(val, key);
+      }
+    }
+    return true;
+  };
+
+  /**
+    @name SortedCollection#eachKey
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      key to the function
+  */
+  this.eachKey = function (func) {
+    return this.each(func, { keyOnly: true });
+  };
+
+  /**
+    @name SortedCollection#eachValue
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      value to the function
+  */
+  this.eachValue = function (func) {
+    return this.each(func, { valueOnly: true });
+  };
+
+  /**
+    @name SortedCollection#clone
+    @public
+    @function
+    @return {Object} Returns a new SortedCollection with the data of the current one
+    @description Creates a cloned version of the current collection and returns it
+  */
+  this.clone = function () {
+    var coll = new SortedCollection()
+      , key
+      , val;
+    for (var i = 0; i < this.order.length; i++) {
+      key = this.order[i];
+      val = this.items[key];
+      coll.setItem(key, val);
+    }
+    return coll;
+  };
+
+  /**
+    @name SortedCollection#concat
+    @public
+    @function
+    @description Join a given collection with the current one
+    @param {Object} hNew A SortedCollection to join from
+  */
+  this.concat = function (hNew) {
+    for (var i = 0; i < hNew.order.length; i++) {
+      var key = hNew.order[i];
+      var val = hNew.items[key];
+      this.setItem(key, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#push
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Appends a new item to the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.push = function (key, val) {
+    this.insertAtIndex(this.count, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#pop
+    @public
+    @function
+    @return {Any} Returns the value for the last item in the collection
+    @description Pops off the last item in the collection and returns it's value
+  */
+  this.pop = function () {
+    var pos = this.count-1;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#unshift
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Prepends a new item to the beginning of the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.unshift = function (key, val) {
+    this.insertAtIndex(0, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#shift
+    @public
+    @function
+    @return {Number} Returns the removed items value
+    @description Removes the first item in the list and returns it's value
+  */
+  this.shift = function () {
+    var pos = 0;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#splice
+    @public
+    @function
+    @description Removes items from index to the given max and then adds the given
+      collections items
+    @param {Number} index The index to start at when removing items
+    @param {Number} numToRemove The number of items to remove before adding the new items
+    @param {Object} hash the collection of items to add
+  */
+  this.splice = function (index, numToRemove, hash) {
+    var _this = this;
+    // Removal
+    if (numToRemove > 0) {
+      // Items
+      var limit = index + numToRemove;
+      for (var i = index; i < limit; i++) {
+        delete this.items[this.order[i]];
+      }
+      // Order
+      this.order.splice(index, numToRemove);
+    }
+    // Adding
+    if (hash) {
+      // Items
+      for (var i in hash.items) {
+        this.items[i] = hash.items[i];
+      }
+      // Order
+      var args = hash.order;
+      args.unshift(0);
+      args.unshift(index);
+      this.order.splice.apply(this.order, args);
+    }
+    this.count = this.order.length;
+  };
+
+  this.sort = function (c) {
+    var arr = [];
+    // Assumes vals are comparable scalars
+    var comp = function (a, b) {
+      return c(a.val, b.val);
+    }
+    for (var i = 0; i < this.order.length; i++) {
+      var key = this.order[i];
+      arr[i] = { key: key, val: this.items[key] };
+    }
+    arr.sort(comp);
+    this.order = [];
+    for (var i = 0; i < arr.length; i++) {
+      this.order.push(arr[i].key);
+    }
+  };
+
+  this.sortByKey = function (comp) {
+    this.order.sort(comp);
+  };
+
+  /**
+    @name SortedCollection#reverse
+    @public
+    @function
+    @description Reverse the collection item list
+  */
+  this.reverse = function () {
+    this.order.reverse();
+  };
+
+})();
+
+module.exports.SortedCollection = SortedCollection;

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/string.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/string.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/string.js
new file mode 100644
index 0000000..9c35a08
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/string.js
@@ -0,0 +1,791 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 core = require('./core')
+  , inflection = require('./inflection')
+  , string;
+
+
+/**
+  @name string
+  @namespace string
+*/
+
+string = new (function () {
+
+  // Regexes for trimming, and character maps for escaping
+  var _LTR = /^\s+/
+    , _RTR = /\s+$/
+    , _TR = /^\s+|\s+$/g
+    , _NL = /\n|\r|\r\n/g
+    , _CHARS = {
+          '&': '&amp;'
+        , '<': '&lt;'
+        , '>': '&gt;'
+        , '"': '&quot;'
+        , '\'': '&#39;'
+      }
+    , _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+    , _buildEscape
+    , _buildEscapeTest;
+
+  // Builds the escape/unescape methods using a
+  // map of characters
+  _buildEscape = function (direction) {
+    return function (str) {
+      var string = str;
+
+      // If string is NaN, null or undefined then provide an empty default
+      if((typeof string === 'undefined') ||
+          string === null ||
+          (!string && isNaN(string))) {
+        string = '';
+      }
+      string = string.toString();
+
+      var from, to, p;
+      for (p in _CHARS) {
+        from = direction == 'to' ? p : _CHARS[p];
+        to = direction == 'to' ? _CHARS[p] : p;
+
+        string = string.replace(new RegExp(from, 'gm'), to);
+      }
+
+      return string;
+    }
+  };
+
+  // Builds a method that tests for any escapable
+  // characters, useful for avoiding double-scaping if
+  // you're not sure if a string has already been escaped
+  _buildEscapeTest = function (direction) {
+    return function (string) {
+      var pat = ''
+        , p;
+
+      for (p in _CHARS) {
+        pat += direction == 'to' ? p : _CHARS[p];
+        pat += '|';
+      }
+
+      pat = pat.substr(0, pat.length - 1);
+      pat = new RegExp(pat, "gm");
+      return pat.test(string)
+    }
+  };
+
+  // Escape special XMl chars
+  this.escapeXML = _buildEscape('to');
+
+  // Unescape XML chars to literal representation
+  this.unescapeXML = _buildEscape('from');
+
+  // Test if a string includes special chars
+  // that need escaping
+  this.needsEscape = _buildEscapeTest('to');
+
+  // Test if a string includes escaped chars
+  // that need unescaping
+  this.needsUnescape = _buildEscapeTest('from');
+
+  /**
+    @name string#escapeRegExpChars
+    @public
+    @function
+    @return {String} A string of escaped characters
+    @description Escapes regex control-characters in strings
+                 used to build regexes dynamically
+    @param {String} string The string of chars to escape
+  */
+  this.escapeRegExpChars = (function () {
+    var specials = [ '^', '$', '/', '.', '*', '+', '?', '|', '(', ')',
+        '[', ']', '{', '}', '\\' ];
+    sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
+    return function (string) {
+      var str = string || '';
+      str = String(str);
+      return str.replace(sRE, '\\$1');
+    };
+  }).call(this);
+
+  /**
+    @name string#toArray
+    @public
+    @function
+    @return {Array} Returns an array of characters
+    @description Converts a string to an array
+    @param {String} string The string to convert
+  */
+  this.toArray = function (string) {
+    var str = string || ''
+      , arr = []
+      , i = -1;
+    str = String(str);
+
+    while (++i < str.length) {
+      arr.push(str.substr(i, 1));
+    }
+
+    return arr;
+  };
+
+  /**
+    @name string#reverse
+    @public
+    @function
+    @return {String} Returns the `string` reversed
+    @description Reverses a string
+    @param {String} string The string to reverse
+  */
+  this.reverse = function (string) {
+    var str = string || '';
+    str = String(str);
+    return this.toArray(str).reverse().join('');
+  };
+
+  /**
+    @name string#ltrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Ltrim trims `char` from the left of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} char The character to trim
+  */
+  this.ltrim = function (string, char) {
+    var str = string || ''
+      , pat = char ? new RegExp('^' + char + '+') : _LTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#rtrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Rtrim trims `char` from the right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} char The character to trim
+  */
+  this.rtrim = function (string, char) {
+    var str = string || ''
+      , pat = char ? new RegExp(char + '+$') : _RTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  // Alias
+  this.chomp = this.rtrim;
+
+  /**
+    @name string#trim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Trim trims `char` from the left and right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} char The character to trim
+  */
+  this.trim = function (string, char) {
+    var str = string || ''
+      , pat = char ? new RegExp('^' + char + '+|' + char + '+$', 'g') : _TR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#chop
+    @public
+    @function
+    @description Returns a new String with the last character removed. If the
+                 string ends with \r\n, both characters are removed. Applying chop to an
+                 empty string returns an empty string.
+    @param {String} string to return with the last character removed.
+  */
+  this.chop = function (string) {
+    var index
+      , str = string || '';
+    str = String(str);
+
+    if (str.length) {
+      // Special-case for \r\n
+      index = str.indexOf('\r\n');
+      if (index == str.length - 2) {
+        return str.substring(0, index);
+      }
+      return str.substring(0, str.length - 1);
+    }
+    else {
+      return '';
+    }
+  };
+
+  /**
+    @name string#lpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Lpad adds `char` to the left of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} char The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.lpad = function (string, char, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    char = char || ' ';
+
+    while (str.length < width) {
+      str = char + str;
+    }
+    return str;
+  };
+
+  /**
+    @name string#rpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Rpad adds `char` to the right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} char The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.rpad = function (string, char, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    char = char || ' ';
+
+    while (str.length < width) {
+      str += char;
+    }
+    return str;
+  };
+
+  /**
+    @name string#pad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Pad adds `char` to the left and right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} char The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.pad = function (string, char, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    char = char || ' ';
+
+    while (str.length < width) {
+      str = char + str + char;
+    }
+    return str;
+  };
+
+  /**
+    @name string#truncate
+    @public
+    @function
+    @return {String} Returns the truncated string
+    @description Truncates a given `string` after a specified `length` if `string` is longer than
+                 `length`. The last characters will be replaced with an `omission` for a total length
+                 not exceeding `length`. If `callback` is given it will fire if `string` is truncated.
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+      @param {Integer} [options.length=string.length] Length the output string will be
+      @param {Integer} [options.len] Alias for `length`
+      @param {String} [options.omission='...'] Replace last characters with an omission
+      @param {String} [options.ellipsis='...'] Alias for `omission`
+      @param {String/RegExp} [options.seperator] Break the truncated test at the nearest `seperator`
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncate = function (string, options, callback) {
+    var str = string || ''
+      , stringLen
+      , opts
+      , stringLenWithOmission
+      , last
+      , ignoreCase
+      , multiLine
+      , stringToWorkWith
+      , lastIndexOf
+      , nextStop
+      , result
+      , returnString;
+
+    str = String(str);
+    stringLen = str.length
+
+    // If `options` is a number, assume it's the length and
+    // create a options object with length
+    if (typeof options === 'number') {
+      opts = {
+        length: options
+      };
+    }
+    else {
+      opts = options || {};
+    }
+
+    // Set `opts` defaults
+    opts.length = opts.length || stringLen;
+    opts.omission = opts.omission || opts.ellipsis || '...';
+
+    stringLenWithOmission = opts.length - opts.omission.length;
+
+    // Set the index to stop at for `string`
+    if (opts.seperator) {
+      if (opts.seperator instanceof RegExp) {
+        // If `seperator` is a regex
+        if (opts.seperator.global) {
+          opts.seperator = opts.seperator;
+        } else {
+          ignoreCase = opts.seperator.ignoreCase ? 'i' : ''
+          multiLine = opts.seperator.multiLine ? 'm' : '';
+          opts.seperator = new RegExp(opts.seperator.source,
+              'g' + ignoreCase + multiLine);
+        }
+        stringToWorkWith = str.substring(0, stringLenWithOmission + 1)
+        lastIndexOf = -1
+        nextStop = 0
+
+        while ((result = opts.seperator.exec(stringToWorkWith))) {
+          lastIndexOf = result.index;
+          opts.seperator.lastIndex = ++nextStop;
+        }
+        last = lastIndexOf;
+      }
+      else {
+        // Seperator is a String
+        last = str.lastIndexOf(opts.seperator, stringLenWithOmission);
+      }
+
+      // If the above couldn't be found, they'll default to -1 so,
+      // we need to just set it as `stringLenWithOmission`
+      if (last === -1) {
+        last = stringLenWithOmission;
+      }
+    }
+    else {
+      last = stringLenWithOmission;
+    }
+
+    if (stringLen < opts.length) {
+      return str;
+    }
+    else {
+      returnString = str.substring(0, last) + opts.omission;
+      returnString += callback && typeof callback === 'function' ? callback() : '';
+      return returnString;
+    }
+  };
+
+  /**
+    @name string#truncateHTML
+    @public
+    @function
+    @return {String} Returns the HTML safe truncated string
+    @description Truncates a given `string` inside HTML tags after a specified `length` if string`
+                 is longer than `length`. The last characters will be replaced with an `omission`
+                 for a total length not exceeding `length`. If `callback` is given it will fire if
+                 `string` is truncated. If `once` is true only the first string in the first HTML
+                 tags will be truncated leaving the others as they were
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+                            all Object options are the same as `truncate`
+      @param {Boolean} [options.once=false] If true, it will only be truncated once, otherwise the
+                                            truncation will loop through all text inside HTML tags
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncateHTML = function (string, options, callback) {
+    var str = string || ''
+      , returnString = ''
+      , opts = options;
+
+    str = String(str);
+
+    // If `options` is a number assume it's the length and create a options object with length
+    if (typeof opts === 'number') {
+      var num = opts;
+
+      opts = {};
+      opts.length = num;
+    } else opts = opts || {};
+
+    // Set `default` options for HTML specifics
+    opts.once = opts.once || false;
+
+    var pat = /(<[^>]*>)/ // Patter for matching HTML tags
+      , arr = [] // Holds the HTML tags and content seperately
+      , truncated = false
+      , result = pat.exec(str)
+      , item
+      , firstPos
+      , lastPos
+      , i;
+
+    // Gather the HTML tags and content into the array
+    while (result) {
+      firstPos = result.index;
+      lastPos = pat.lastIndex;
+
+      if (firstPos !== 0) {
+        // Should be content not HTML tags
+        arr.push(str.substring(0, firstPos));
+        // Slice content from string
+        str = str.slice(firstPos);
+      }
+
+      arr.push(result[0]); // Push HTML tags
+      str = str.slice(result[0].length);
+
+      // Re-run the pattern on the new string
+      result = pat.exec(str);
+    }
+    if (str !== '') {
+      arr.push(str);
+    }
+
+    // Loop through array items appending the tags to the string,
+    // - and truncating the text then appending it to content
+    i = -1;
+    while (++i < arr.length) {
+      item = arr[i];
+      switch (true) {
+        // Closing tag
+        case item.indexOf('</') == 0:
+          returnString += item;
+          openTag = null;
+          break;
+        // Opening tag
+        case item.indexOf('<') == 0:
+          returnString += item;
+          openTag = item;
+          break;
+        // Normal text
+        default:
+          if (opts.once && truncated) {
+            returnString += item;
+          } else {
+            returnString += this.truncate(item, opts, callback);
+            truncated = true;
+          }
+          break;
+      }
+    }
+
+    return returnString;
+  };
+
+  /**
+    @name string#nl2br
+    @public
+    @function
+    @return {String} The string with converted newlines chars to br tags
+    @description Nl2br returns a string where all newline chars are turned
+                 into line break HTML tags
+    @param {String} string The string to convert
+  */
+  this.nl2br = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.replace(_NL,'<br />');
+  };
+
+  /**
+    @name string#snakeize
+    @public
+    @function
+    @return {String} The string in a snake_case version
+    @description Snakeize converts camelCase and CamelCase strings to snake_case strings
+    @param {String} string The string to convert to snake_case
+    @param {String} separ='_' The seperator to use
+  */
+  this.snakeize = (function () {
+    // Only create regexes once on initial load
+    var repl = /([A-Z]+)/g
+      , lead = /^_/g;
+    return function (string, separ) {
+      var str = string || ''
+        , sep = separ || '_'
+        , leading = separ ? new RegExp('^' + sep, 'g') : lead;
+      str = String(str);
+      return str.replace(repl, sep + '$1').toLowerCase().
+        replace(leading, '');
+    };
+  }).call(this);
+
+  // Aliases
+  /**
+    @name string#underscorize
+    @public
+    @function
+    @return {String} The string in a underscorized version
+    @description Underscorize returns the given `string` converting camelCase and snakeCase to underscores
+    @param {String} string The string to underscorize
+  */
+  this.underscorize = this.snakeize;
+  this.underscoreize = this.snakeize;
+  this.decamelize = this.snakeize;
+
+  /**
+    @name string#camelize
+    @public
+    @function
+    @return {String} The string in a camelCase version
+    @description Camelize takes a string and optional options and
+                 returns a camelCase version of the given `string`
+    @param {String} string The string to convert to camelCase
+    @param {Object} options
+      @param {Boolean} [options.initialCap] If initialCap is true the returned
+                                            string will have a capitalized first letter
+      @param {Boolean} [options.leadingUnderscore] If leadingUnderscore os true then if
+                                                   an underscore exists at the beggining
+                                                   of the string, it will stay there.
+                                                   Otherwise it'll be removed.
+  */
+  this.camelize = (function () {
+    // Only create regex once on initial load
+    var repl = /[-_](\w)/g;
+    return function (string, options) {
+      var str = string || ''
+        , ret
+        , config = {
+            initialCap: false
+          , leadingUnderscore: false
+          }
+        , opts = options || {};
+
+      str = String(str);
+
+      // Backward-compat
+      if (typeof opts == 'boolean') {
+        config = {
+          initialCap: true
+        };
+      }
+      else {
+        core.mixin(config, opts);
+      }
+
+      ret = str.replace(repl, function (m, m1) {
+        return m1.toUpperCase();
+      });
+
+      if (config.leadingUnderscore & str.indexOf('_') === 0) {
+        ret = '_' + this.decapitalize(ret);
+      }
+      // If initialCap is true capitalize it
+      ret = config.initialCap ? this.capitalize(ret) : this.decapitalize(ret);
+
+      return ret;
+    };
+  }).call(this);
+
+  /**
+    @name string#decapitalize
+    @public
+    @function
+    @return {String} The string with the first letter decapitalized
+    @description Decapitalize returns the given string with the first letter uncapitalized.
+    @param {String} string The string to decapitalize
+  */
+  this.decapitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toLowerCase() + str.substr(1);
+  };
+
+  /**
+    @name string#capitalize
+    @public
+    @function
+    @return {String} The string with the first letter capitalized
+    @description capitalize returns the given string with the first letter capitalized.
+    @param {String} string The string to capitalize
+  */
+  this.capitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toUpperCase() + str.substr(1);
+  };
+
+  /**
+    @name string#dasherize
+    @public
+    @function
+    @return {String} The string in a dashed version
+    @description Dasherize returns the given `string` converting camelCase and snakeCase
+                 to dashes or replace them with the `replace` character.
+    @param {String} string The string to dasherize
+    @param {String} replace='-' The character to replace with
+  */
+  this.dasherize = function (string, replace) {
+    var repl = replace || '-'
+    return this.snakeize(string, repl);
+  };
+
+  /**
+    @name string#include
+    @public
+    @function
+    @return {Boolean} Returns true if the string is found in the string to search
+    @description Searches for a particular string in another string
+    @param {String} searchIn The string to search for the other string in
+    @param {String} searchFor The string to search for
+  */
+  this.include = function (searchIn, searchFor) {
+    var str = searchFor;
+    if (!str && typeof string != 'string') {
+      return false;
+    }
+    str = String(str);
+    return (searchIn.indexOf(str) > -1);
+  };
+
+  /*
+   * getInflections(name<String>, initialCap<String>)
+   *
+   * Inflection returns an object that contains different inflections
+   * created from the given `name`
+  */
+
+  /**
+    @name string#getInflections
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflections = function (name) {
+    if (!name) {
+      return;
+    }
+
+    var self = this
+        // Use plural version to fix possible mistakes(e,g,. thingie instead of thingy)
+      , normalizedName = this.snakeize(inflection.pluralize(name))
+      , nameSingular = inflection.singularize(normalizedName)
+      , namePlural = inflection.pluralize(normalizedName);
+
+    return {
+      // For filepaths or URLs
+      filename: {
+        // neil_peart
+        singular: nameSingular
+        // neil_pearts
+      , plural: namePlural
+      }
+      // Constructor names
+    , constructor: {
+        // NeilPeart
+        singular: self.camelize(nameSingular, {initialCap: true})
+        // NeilPearts
+      , plural: self.camelize(namePlural, {initialCap: true})
+      }
+    , property: {
+        // neilPeart
+        singular: self.camelize(nameSingular)
+        // neilPearts
+      , plural: self.camelize(namePlural)
+      }
+    };
+  };
+
+  /**
+    @name string#getInflection
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflection = function (name, key, pluralization) {
+    var infl = this.getInflections(name);
+    return infl[key][pluralization];
+  };
+
+  // From Math.uuid.js, https://github.com/broofa/node-uuid
+  // Robert Kieffer (robert@broofa.com), MIT license
+  this.uuid = function (length, radix) {
+    var chars = _UUID_CHARS
+      , uuid = []
+      , r
+      , i;
+
+    radix = radix || chars.length;
+
+    if (length) {
+      // Compact form
+      i = -1;
+      while (++i < length) {
+        uuid[i] = chars[0 | Math.random()*radix];
+      }
+    } else {
+      // rfc4122, version 4 form
+
+      // rfc4122 requires these characters
+      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+      uuid[14] = '4';
+
+      // Fill in random data.  At i==19 set the high bits of clock sequence as
+      // per rfc4122, sec. 4.1.5
+      i = -1;
+      while (++i < 36) {
+        if (!uuid[i]) {
+          r = 0 | Math.random()*16;
+          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+        }
+      }
+    }
+
+    return uuid.join('');
+  };
+
+})();
+
+module.exports = string;
+

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/1139813c/blackberry10/node_modules/jake/node_modules/utilities/lib/uri.js
----------------------------------------------------------------------
diff --git a/blackberry10/node_modules/jake/node_modules/utilities/lib/uri.js b/blackberry10/node_modules/jake/node_modules/utilities/lib/uri.js
new file mode 100644
index 0000000..92f086f
--- /dev/null
+++ b/blackberry10/node_modules/jake/node_modules/utilities/lib/uri.js
@@ -0,0 +1,177 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed 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 uri
+  , string = require('./string');
+
+/**
+  @name uri
+  @namespace uri
+*/
+
+uri = new (function () {
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  /**
+    @name uri#getFileExtension
+    @public
+    @function
+    @return {String} Returns the file extension for a given path
+    @description Gets the file extension for a path and returns it
+    @param {String} path The path to get the extension for
+  */
+  this.getFileExtension = function (path) {
+    var match;
+    if (path) {
+      match = /.+\.(\w{2,4}$)/.exec(path);
+    }
+    return (match && match[1]) || '';
+  };
+
+  /**
+    @name uri#paramify
+    @public
+    @function
+    @return {String} Returns a querystring contains the given values
+    @description Convert a JS Object to a querystring (key=val&key=val). Values in arrays
+      will be added as multiple parameters
+    @param {Object} obj An Object containing only scalars and arrays
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=false] take values from elements that can return
+        multiple values (multi-select, checkbox groups) and collapse into a single,
+        comman-delimited value.
+      @param {Boolean} [o.includeEmpty=false] include keys in the string for all elements, even
+        they have no value set (e.g., even if elemB has no value: elemA=foo&elemB=&elemC=bar).
+        Note that some false-y values are always valid even without this option, [0, ''].
+        This option extends coverage to [null, undefined, NaN]
+      @param {Boolean} [o.snakeize=false] change param names from camelCase to snake_case.
+      @param {Boolean} [o.escapeVals=false] escape the values for XML entities.
+  */
+  this.paramify = function (obj, o) {
+    var opts = o || {},
+        str = '',
+        key,
+        val,
+        isValid,
+        itemArray,
+        arr = [],
+        arrVal;
+
+    for (var p in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, p)) {
+        val = obj[p];
+
+        // This keeps valid falsy values like false and 0
+        // It's duplicated in the array block below. Could
+        // put it in a function but don't want the overhead
+        isValid = !( val === null || val === undefined ||
+                    (typeof val === 'number' && isNaN(val)) );
+
+        key = opts.snakeize ? string.snakeize(p) : p;
+        if (isValid) {
+          // Multiple vals -- array
+          if (_isArray(val) && val.length) {
+            itemArray = [];
+            for (var i = 0, ii = val.length; i < ii; i++) {
+              arrVal = val[i];
+              // This keeps valid falsy values like false and 0
+              isValid = !( arrVal === null || arrVal === undefined ||
+                           (typeof arrVal === 'number' && isNaN(arrVal)) );
+
+              itemArray[i] = isValid ? encodeURIComponent(arrVal) : '';
+              if (opts.escapeVals) {
+                itemArray[i] = string.escapeXML(itemArray[i]);
+              }
+            }
+            // Consolidation mode -- single value joined on comma
+            if (opts.consolidate) {
+              arr.push(key + '=' + itemArray.join(','));
+            }
+            // Normal mode -- multiple, same-named params with each val
+            else {
+              // {foo: [1, 2, 3]} => 'foo=1&foo=2&foo=3'
+              // Add into results array, as this just ends up getting
+              // joined on ampersand at the end anyhow
+              arr.push(key + '=' + itemArray.join('&' + key + '='));
+            }
+          }
+          // Single val -- string
+          else {
+            if (opts.escapeVals) {
+              val = string.escapeXML(val);
+            }
+            arr.push(key + '=' + encodeURIComponent(val));
+          }
+          str += '&';
+        }
+        else {
+          if (opts.includeEmpty) { arr.push(key + '='); }
+        }
+      }
+    }
+    return arr.join('&');
+  };
+
+  /**
+    @name uri#objectify
+    @public
+    @function
+    @return {Object} JavaScript key/val object with the values from the querystring
+    @description Convert the values in a query string (key=val&key=val) to an Object
+    @param {String} str The querystring to convert to an object
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=true] Convert multiple instances of the same
+        key into an array of values instead of overwriting
+  */
+  this.objectify = function (str, o) {
+    var opts = o || {};
+    var d = {};
+    var consolidate = typeof opts.consolidate == 'undefined' ?
+        true : opts.consolidate;
+    if (str) {
+      var arr = str.split('&');
+      for (var i = 0; i < arr.length; i++) {
+        var pair = arr[i].split('=');
+        var name = pair[0];
+        var val = decodeURIComponent(pair[1] || '');
+        // "We've already got one!" -- arrayize if the flag
+        // is set
+        if (typeof d[name] != 'undefined' && consolidate) {
+          if (typeof d[name] == 'string') {
+            d[name] = [d[name]];
+          }
+          d[name].push(val);
+        }
+        // Otherwise just set the value
+        else {
+          d[name] = val;
+        }
+      }
+    }
+    return d;
+  };
+
+})();
+
+module.exports = uri;
+