You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by lo...@apache.org on 2013/05/07 17:24:13 UTC

[08/51] [partial] [BlackBerry10] Added support for new platform

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/date.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/date.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/date.js
new file mode 100644
index 0000000..7232ce0
--- /dev/null
+++ b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/date.js
@@ -0,0 +1,903 @@
+/*
+ * 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 string = require('./string')
+  , date
+  , log = require('./log');
+
+/**
+  @name date
+  @namespace date
+*/
+
+date = new (function () {
+  var _this = this
+    , _date = new Date();
+
+  var _US_DATE_PAT = /^(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{4})/;
+  var _DATETIME_PAT = /^(\d{4})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:T| )?(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?(?: *)?(Z|[+-]\d{4}|[+-]\d{2}:\d{2}|[+-]\d{2})?/;
+  // TODO Add am/pm parsing instead of dumb, 24-hour clock.
+  var _TIME_PAT = /^(\d{1,2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?$/;
+
+  var _dateMethods = [
+      'FullYear'
+    , 'Month'
+    , 'Date'
+    , 'Hours'
+    , 'Minutes'
+    , 'Seconds'
+    , 'Milliseconds'
+  ];
+
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  this.weekdayLong = ['Sunday', 'Monday', 'Tuesday',
+    'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+  this.weekdayShort = ['Sun', 'Mon', 'Tue', 'Wed',
+    'Thu', 'Fri', 'Sat'];
+  this.monthLong = ['January', 'February', 'March',
+    'April', 'May', 'June', 'July', 'August', 'September',
+    'October', 'November', 'December'];
+  this.monthShort = ['Jan', 'Feb', 'Mar', 'Apr',
+    'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+  this.meridiem = {
+    'AM': 'AM',
+    'PM': 'PM'
+  }
+  // compat
+  this.meridian = this.meridiem
+
+  /**
+    @name date#supportedFormats
+    @public
+    @object
+    @description List of supported strftime formats
+  */
+  this.supportedFormats = {
+    // abbreviated weekday name according to the current locale
+    'a': function (dt) { return _this.weekdayShort[dt.getDay()]; },
+    // full weekday name according to the current locale
+    'A': function (dt) { return _this.weekdayLong[dt.getDay()]; },
+    //  abbreviated month name according to the current locale
+    'b': function (dt) { return _this.monthShort[dt.getMonth()]; },
+    'h': function (dt) { return _this.strftime(dt, '%b'); },
+    // full month name according to the current locale
+    'B': function (dt) { return _this.monthLong[dt.getMonth()]; },
+    // preferred date and time representation for the current locale
+    'c': function (dt) { return _this.strftime(dt, '%a %b %d %T %Y'); },
+    // century number (the year divided by 100 and truncated
+    // to an integer, range 00 to 99)
+    'C': function (dt) { return _this.calcCentury(dt.getFullYear());; },
+    // day of the month as a decimal number (range 01 to 31)
+    'd': function (dt) { return string.lpad(dt.getDate(), '0', 2); },
+    // same as %m/%d/%y
+    'D': function (dt) { return _this.strftime(dt, '%m/%d/%y') },
+    // day of the month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '31')
+    'e': function (dt) { return string.lpad(dt.getDate(), ' ', 2); },
+    // month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '12')
+    'f': function () { return _this.strftimeNotImplemented('f'); },
+    // same as %Y-%m-%d
+    'F': function (dt) { return _this.strftime(dt, '%Y-%m-%d');  },
+    // like %G, but without the century.
+    'g': function () { return _this.strftimeNotImplemented('g'); },
+    // The 4-digit year corresponding to the ISO week number
+    // (see %V).  This has the same format and value as %Y,
+    // except that if the ISO week number belongs to the
+    // previous or next year, that year is used instead.
+    'G': function () { return _this.strftimeNotImplemented('G'); },
+    // hour as a decimal number using a 24-hour clock (range
+    // 00 to 23)
+    'H': function (dt) { return string.lpad(dt.getHours(), '0', 2); },
+    // hour as a decimal number using a 12-hour clock (range
+    // 01 to 12)
+    'I': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), '0', 2); },
+    // day of the year as a decimal number (range 001 to 366)
+    'j': function (dt) { return string.lpad(
+      _this.calcDays(dt), '0', 3); },
+    // Hour as a decimal number using a 24-hour clock (range
+    // 0 to 23 (space-padded))
+    'k': function (dt) { return string.lpad(dt.getHours(), ' ', 2); },
+    // Hour as a decimal number using a 12-hour clock (range
+    // 1 to 12 (space-padded))
+    'l': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), ' ', 2); },
+    // month as a decimal number (range 01 to 12)
+    'm': function (dt) { return string.lpad((dt.getMonth()+1), '0', 2); },
+    // minute as a decimal number
+    'M': function (dt) { return string.lpad(dt.getMinutes(), '0', 2); },
+    // Linebreak
+    'n': function () { return '\n'; },
+    // either `am' or `pm' according to the given time value,
+    // or the corresponding strings for the current locale
+    'p': function (dt) { return _this.getMeridian(dt.getHours()); },
+    // time in a.m. and p.m. notation
+    'r': function (dt) { return _this.strftime(dt, '%I:%M:%S %p'); },
+    // time in 24 hour notation
+    'R': function (dt) { return _this.strftime(dt, '%H:%M'); },
+    // second as a decimal number
+    'S': function (dt) { return string.lpad(dt.getSeconds(), '0', 2); },
+    // Tab char
+    't': function () { return '\t'; },
+    // current time, equal to %H:%M:%S
+    'T': function (dt) { return _this.strftime(dt, '%H:%M:%S'); },
+    // weekday as a decimal number [1,7], with 1 representing
+    // Monday
+    'u': function (dt) { return _this.convertOneBase(dt.getDay()); },
+    // week number of the current year as a decimal number,
+    // starting with the first Sunday as the first day of the
+    // first week
+    'U': function () { return _this.strftimeNotImplemented('U'); },
+    // week number of the year (Monday as the first day of the
+    // week) as a decimal number [01,53]. If the week containing
+    // 1 January has four or more days in the new year, then it
+    // is considered week 1. Otherwise, it is the last week of
+    // the previous year, and the next week is week 1.
+    'V': function () { return _this.strftimeNotImplemented('V'); },
+    // week number of the current year as a decimal number,
+    // starting with the first Monday as the first day of the
+    // first week
+    'W': function () { return _this.strftimeNotImplemented('W'); },
+    // day of the week as a decimal, Sunday being 0
+    'w': function (dt) { return dt.getDay(); },
+    // preferred date representation for the current locale
+    // without the time
+    'x': function (dt) { return _this.strftime(dt, '%D'); },
+    // preferred time representation for the current locale
+    // without the date
+    'X': function (dt) { return _this.strftime(dt, '%T'); },
+    // year as a decimal number without a century (range 00 to
+    // 99)
+    'y': function (dt) { return _this.getTwoDigitYear(dt.getFullYear()); },
+    // year as a decimal number including the century
+    'Y': function (dt) { return string.lpad(dt.getFullYear(), '0', 4); },
+    // time zone or name or abbreviation
+    'z': function () { return _this.strftimeNotImplemented('z'); },
+    'Z': function () { return _this.strftimeNotImplemented('Z'); },
+    // Literal percent char
+    '%': function (dt) { return '%'; }
+  };
+
+  /**
+    @name date#getSupportedFormats
+    @public
+    @function
+    @description return the list of formats in a string
+    @return {String} The list of supported formats
+  */
+  this.getSupportedFormats = function () {
+    var str = '';
+    for (var i in this.supportedFormats) { str += i; }
+    return str;
+  }
+
+  this.supportedFormatsPat = new RegExp('%[' +
+      this.getSupportedFormats() + ']{1}', 'g');
+
+  /**
+    @name date#strftime
+    @public
+    @function
+    @return {String} The `dt` formated with the given `format`
+    @description Formats the given date with the strftime formated
+    @param {Date} dt the date object to format
+    @param {String} format the format to convert the date to
+  */
+  this.strftime = function (dt, format) {
+    if (!dt) { return '' }
+
+    var d = dt;
+    var pats = [];
+    var dts = [];
+    var str = format;
+
+    // Allow either Date obj or UTC stamp
+    d = typeof dt == 'number' ? new Date(dt) : dt;
+
+    // Grab all instances of expected formats into array
+    while (pats = this.supportedFormatsPat.exec(format)) {
+      dts.push(pats[0]);
+    }
+
+    // Process any hits
+    for (var i = 0; i < dts.length; i++) {
+      key = dts[i].replace(/%/, '');
+      str = str.replace('%' + key,
+        this.supportedFormats[key](d));
+    }
+    return str;
+
+  };
+
+  this.strftimeNotImplemented = function (s) {
+    throw('this.strftime format "' + s + '" not implemented.');
+  };
+
+  /**
+    @name date#calcCentury
+    @public
+    @function
+    @return {String} The century for the given date
+    @description Find the century for the given `year`
+    @param {Number} year The year to find the century for
+  */
+  this.calcCentury = function (year) {
+    if(!year) {
+      year = _date.getFullYear();
+    }
+
+    var ret = parseInt((year / 100) + 1);
+    year = year.toString();
+
+    // If year ends in 00 subtract one, because it's still the century before the one
+    // it divides to
+    if (year.substring(year.length - 2) === '00') {
+      ret--;
+    }
+
+    return ret.toString();
+  };
+
+  /**
+    @name date#calcDays
+    @public
+    @function
+    @return {Number} The number of days so far for the given date
+    @description Calculate the day number in the year a particular date is on
+    @param {Date} dt The date to use
+  */
+  this.calcDays = function (dt) {
+    var first = new Date(dt.getFullYear(), 0, 1);
+    var diff = 0;
+    var ret = 0;
+    first = first.getTime();
+    diff = (dt.getTime() - first);
+    ret = parseInt(((((diff/1000)/60)/60)/24))+1;
+    return ret;
+  };
+
+  /**
+   * Adjust from 0-6 base week to 1-7 base week
+   * @param d integer for day of week
+   * @return Integer day number for 1-7 base week
+   */
+  this.convertOneBase = function (d) {
+    return d == 0 ? 7 : d;
+  };
+
+  this.getTwoDigitYear = function (yr) {
+    // Add a millenium to take care of years before the year 1000,
+    // (e.g, the year 7) since we're only taking the last two digits
+    // If we overshoot, it doesn't matter
+    var millenYear = yr + 1000;
+    var str = millenYear.toString();
+    str = str.substr(2); // Get the last two digits
+    return str
+  };
+
+  /**
+    @name date#getMeridiem
+    @public
+    @function
+    @return {String} Return 'AM' or 'PM' based on hour in 24-hour format
+    @description Return 'AM' or 'PM' based on hour in 24-hour format
+    @param {Number} h The hour to check
+  */
+  this.getMeridiem = function (h) {
+    return h > 11 ? this.meridiem.PM :
+      this.meridiem.AM;
+  };
+  // Compat
+  this.getMeridian = this.getMeridiem;
+
+  /**
+    @name date#hrMil2Std
+    @public
+    @function
+    @return {String} Return a 12 hour version of the given time
+    @description Convert a 24-hour formatted hour to 12-hour format
+    @param {String} hour The hour to convert
+  */
+  this.hrMil2Std = function (hour) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = h > 12 ? h - 12 : h;
+    str = str == 0 ? 12 : str;
+    return str;
+  };
+
+  /**
+    @name date#hrStd2Mil
+    @public
+    @function
+    @return {String} Return a 24 hour version of the given time
+    @description Convert a 12-hour formatted hour with meridian flag to 24-hour format
+    @param {String} hour The hour to convert
+    @param {Boolean} pm hour is PM then this should be true
+  */
+  this.hrStd2Mil = function  (hour, pm) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = '';
+    // PM
+    if (pm) {
+      str = h < 12 ? (h+12) : h;
+    }
+    // AM
+    else {
+      str = h == 12 ? 0 : h;
+    }
+    return str;
+  };
+
+  // Constants for use in this.add
+  var dateParts = {
+    YEAR: 'year'
+    , MONTH: 'month'
+    , DAY: 'day'
+    , HOUR: 'hour'
+    , MINUTE: 'minute'
+    , SECOND: 'second'
+    , MILLISECOND: 'millisecond'
+    , QUARTER: 'quarter'
+    , WEEK: 'week'
+    , WEEKDAY: 'weekday'
+  };
+  // Create a map for singular/plural lookup, e.g., day/days
+  var datePartsMap = {};
+  for (var p in dateParts) {
+    datePartsMap[dateParts[p]] = dateParts[p];
+    datePartsMap[dateParts[p] + 's'] = dateParts[p];
+  }
+  this.dateParts = dateParts;
+
+  /**
+    @name date#add
+    @public
+    @function
+    @return {Date} Incremented date
+    @description Add to a Date in intervals of different size, from
+                 milliseconds to years
+    @param {Date} dt Date (or timestamp Number), date to increment
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+    @param {Number} incr how much to add to the date
+  */
+  this.add = function (dt, interv, incr) {
+    if (typeof dt == 'number') { dt = new Date(dt); }
+    function fixOvershoot() {
+      if (sum.getDate() < dt.getDate()) {
+        sum.setDate(0);
+      }
+    }
+    var key = datePartsMap[interv];
+    var sum = new Date(dt);
+    switch (key) {
+      case dateParts.YEAR:
+        sum.setFullYear(dt.getFullYear()+incr);
+        // Keep increment/decrement from 2/29 out of March
+        fixOvershoot();
+        break;
+      case dateParts.QUARTER:
+        // Naive quarter is just three months
+        incr*=3;
+        // fallthrough...
+      case dateParts.MONTH:
+        sum.setMonth(dt.getMonth()+incr);
+        // Reset to last day of month if you overshoot
+        fixOvershoot();
+        break;
+      case dateParts.WEEK:
+        incr*=7;
+        // fallthrough...
+      case dateParts.DAY:
+        sum.setDate(dt.getDate() + incr);
+        break;
+      case dateParts.WEEKDAY:
+        //FIXME: assumes Saturday/Sunday weekend, but even this is not fixed.
+        // There are CLDR entries to localize this.
+        var dat = dt.getDate();
+        var weeks = 0;
+        var days = 0;
+        var strt = 0;
+        var trgt = 0;
+        var adj = 0;
+        // Divide the increment time span into weekspans plus leftover days
+        // e.g., 8 days is one 5-day weekspan / and two leftover days
+        // Can't have zero leftover days, so numbers divisible by 5 get
+        // a days value of 5, and the remaining days make up the number of weeks
+        var mod = incr % 5;
+        if (mod == 0) {
+          days = (incr > 0) ? 5 : -5;
+          weeks = (incr > 0) ? ((incr-5)/5) : ((incr+5)/5);
+        }
+        else {
+          days = mod;
+          weeks = parseInt(incr/5);
+        }
+        // Get weekday value for orig date param
+        strt = dt.getDay();
+        // Orig date is Sat / positive incrementer
+        // Jump over Sun
+        if (strt == 6 && incr > 0) {
+          adj = 1;
+        }
+        // Orig date is Sun / negative incrementer
+        // Jump back over Sat
+        else if (strt == 0 && incr < 0) {
+          adj = -1;
+        }
+        // Get weekday val for the new date
+        trgt = strt + days;
+        // New date is on Sat or Sun
+        if (trgt == 0 || trgt == 6) {
+          adj = (incr > 0) ? 2 : -2;
+        }
+        // Increment by number of weeks plus leftover days plus
+        // weekend adjustments
+        sum.setDate(dat + (7*weeks) + days + adj);
+        break;
+      case dateParts.HOUR:
+        sum.setHours(sum.getHours()+incr);
+        break;
+      case dateParts.MINUTE:
+        sum.setMinutes(sum.getMinutes()+incr);
+        break;
+      case dateParts.SECOND:
+        sum.setSeconds(sum.getSeconds()+incr);
+        break;
+      case dateParts.MILLISECOND:
+        sum.setMilliseconds(sum.getMilliseconds()+incr);
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    return sum; // Date
+  };
+
+  /**
+    @name date#diff
+    @public
+    @function
+    @return {Number} number of (interv) units apart that
+    the two dates are
+    @description Get the difference in a specific unit of time (e.g., number
+                 of months, weeks, days, etc.) between two dates.
+    @param {Date} date1 First date to check
+    @param {Date} date2 Date to compate `date1` with
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+  */
+  this.diff = function (date1, date2, interv) {
+    //  date1
+    //    Date object or Number equivalent
+    //
+    //  date2
+    //    Date object or Number equivalent
+    //
+    //  interval
+    //    A constant representing the interval, e.g. YEAR, MONTH, DAY.  See this.dateParts.
+
+    // Accept timestamp input
+    if (typeof date1 == 'number') { date1 = new Date(date1); }
+    if (typeof date2 == 'number') { date2 = new Date(date2); }
+    var yeaDiff = date2.getFullYear() - date1.getFullYear();
+    var monDiff = (date2.getMonth() - date1.getMonth()) + (yeaDiff * 12);
+    var msDiff = date2.getTime() - date1.getTime(); // Millisecs
+    var secDiff = msDiff/1000;
+    var minDiff = secDiff/60;
+    var houDiff = minDiff/60;
+    var dayDiff = houDiff/24;
+    var weeDiff = dayDiff/7;
+    var delta = 0; // Integer return value
+
+    var key = datePartsMap[interv];
+    switch (key) {
+      case dateParts.YEAR:
+        delta = yeaDiff;
+        break;
+      case dateParts.QUARTER:
+        var m1 = date1.getMonth();
+        var m2 = date2.getMonth();
+        // Figure out which quarter the months are in
+        var q1 = Math.floor(m1/3) + 1;
+        var q2 = Math.floor(m2/3) + 1;
+        // Add quarters for any year difference between the dates
+        q2 += (yeaDiff * 4);
+        delta = q2 - q1;
+        break;
+      case dateParts.MONTH:
+        delta = monDiff;
+        break;
+      case dateParts.WEEK:
+        // Truncate instead of rounding
+        // Don't use Math.floor -- value may be negative
+        delta = parseInt(weeDiff);
+        break;
+      case dateParts.DAY:
+        delta = dayDiff;
+        break;
+      case dateParts.WEEKDAY:
+        var days = Math.round(dayDiff);
+        var weeks = parseInt(days/7);
+        var mod = days % 7;
+
+        // Even number of weeks
+        if (mod == 0) {
+          days = weeks*5;
+        }
+        else {
+          // Weeks plus spare change (< 7 days)
+          var adj = 0;
+          var aDay = date1.getDay();
+          var bDay = date2.getDay();
+
+          weeks = parseInt(days/7);
+          mod = days % 7;
+          // Mark the date advanced by the number of
+          // round weeks (may be zero)
+          var dtMark = new Date(date1);
+          dtMark.setDate(dtMark.getDate()+(weeks*7));
+          var dayMark = dtMark.getDay();
+
+          // Spare change days -- 6 or less
+          if (dayDiff > 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = -1;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 0;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = -1;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = -2;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) > 5:
+                adj = -2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          else if (dayDiff < 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = 0;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 1;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = 2;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = 1;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) < 0:
+                adj = 2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          days += adj;
+          days -= (weeks*2);
+        }
+        delta = days;
+
+        break;
+      case dateParts.HOUR:
+        delta = houDiff;
+        break;
+      case dateParts.MINUTE:
+        delta = minDiff;
+        break;
+      case dateParts.SECOND:
+        delta = secDiff;
+        break;
+      case dateParts.MILLISECOND:
+        delta = msDiff;
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    // Round for fractional values and DST leaps
+    return Math.round(delta); // Number (integer)
+  };
+
+  /**
+    @name date#parse
+    @public
+    @function
+    @return {Date} a JavaScript Date object
+    @description Convert various sorts of strings to JavaScript
+                 Date objects
+    @param {String} val The string to convert to a Date
+  */
+  this.parse = function (val) {
+    var dt
+      , matches
+      , reordered
+      , off
+      , posOff
+      , offHours
+      , offMinutes
+      , curr
+      , stamp
+      , utc;
+
+    // Yay, we have a date, use it as-is
+    if (val instanceof Date || typeof val.getFullYear == 'function') {
+      dt = val;
+    }
+
+    // Timestamp?
+    else if (typeof val == 'number') {
+      dt = new Date(val);
+    }
+
+    // String or Array
+    else {
+      // Value preparsed, looks like [yyyy, mo, dd, hh, mi, ss, ms, (offset?)]
+      if (_isArray(val)) {
+        matches = val;
+        matches.unshift(null);
+        matches[8] = null;
+      }
+
+      // Oh, crap, it's a string -- parse this bitch
+      else if (typeof val == 'string') {
+        matches = val.match(_DATETIME_PAT);
+
+        // Stupid US-only format?
+        if (!matches) {
+          matches = val.match(_US_DATE_PAT);
+          if (matches) {
+            reordered = [matches[0], matches[3], matches[1], matches[2]];
+            // Pad the results to the same length as ISO8601
+            reordered[8] = null;
+            matches = reordered;
+          }
+        }
+
+        // Time-stored-in-Date hack?
+        if (!matches) {
+          matches = val.match(_TIME_PAT);
+          if (matches) {
+            reordered = [matches[0], 0, 1, 0, matches[1],
+                matches[2], matches[3], matches[4], null];
+            matches = reordered;
+          }
+        }
+
+      }
+
+      // Sweet, the regex actually parsed it into something useful
+      if (matches) {
+        matches.shift(); // First match is entire match, DO NOT WANT
+
+        off = matches.pop();
+        // If there's an offset (or the 'Z' non-offset offset), use UTC
+        // methods to set everything
+        if (off) {
+          if (off == 'Z') {
+            utc = true;
+            offMinutes = 0;
+          }
+          else {
+            utc = false;
+            off = off.replace(/\+|-|:/g, '');
+            if (parseInt(off, 10) === 0) {
+              utc = true;
+            }
+            else {
+              posOff = off.indexOf('+') === 0;
+              off = off.substr(1);
+              off = off.split(':');
+              offHours = parseInt(off[0], 10);
+              offMinutes = parseInt(off[1], 10) || 0;
+              offMinutes += (offHours * 60);
+              if (!posOff) {
+                offMinutes = 0 - offMinutes;
+              }
+            }
+          }
+        }
+
+        dt = new Date(0);
+
+        // Stupid zero-based months
+        matches[1] = parseInt(matches[1], 10) - 1;
+
+        // Specific offset, iterate the array and set each date property
+        // using UTC setters, then adjust time using offset
+        if (off) {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['setUTC' + _dateMethods[i]](curr);
+          }
+          // Add any offset
+          dt.setMinutes(dt.getMinutes() - offMinutes);
+        }
+        // Otherwise we know nothing about the offset, just iterate the
+        // array and set each date property using regular setters
+        else {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['set' + _dateMethods[i]](curr);
+          }
+        }
+      }
+
+      // Shit, last-ditch effort using Date.parse
+      else {
+        stamp = Date.parse(val);
+        // Failures to parse yield NaN
+        if (!isNaN(stamp)) {
+          dt = new Date(stamp);
+        }
+      }
+
+    }
+
+    return dt || null;
+  };
+
+  /**
+    @name date#relativeTime
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    the passed-in Date is
+    @description Convert a Date to an English sentence representing
+    how long ago the Date was
+    @param {Date} dt The Date to to convert to a relative time string
+    @param {Object} [opts]
+      @param {Boolean} [opts.abbreviated=false] Use short strings
+      (e.g., '<1m') for the relative-time string
+  */
+  this.relativeTime = function (dt, options) {
+    var opts = options || {}
+      , now = opts.now || new Date()
+      , abbr = opts.abbreviated || false
+      , format = opts.format || '%F %T'
+    // Diff in seconds
+      , diff = (now.getTime() - dt.getTime()) / 1000
+      , ret
+      , num
+      , hour = 60*60
+      , day = 24*hour
+      , week = 7*day
+      , month = 30*day;
+    switch (true) {
+      case diff < 60:
+        ret = abbr ? '<1m' : 'less than a minute ago';
+        break;
+      case diff < 120:
+        ret = abbr ? '1m' : 'about a minute ago';
+        break;
+      case diff < (45*60):
+        num = parseInt((diff / 60), 10);
+        ret = abbr ? num + 'm' : num + ' minutes ago';
+        break;
+      case diff < (2*hour):
+        ret = abbr ? '1h' : 'about an hour ago';
+        break;
+      case diff < (1*day):
+        num = parseInt((diff / hour), 10);
+        ret = abbr ? num + 'h' : 'about ' + num + ' hours ago';
+        break;
+      case diff < (2*day):
+        ret = abbr ? '1d' : 'one day ago';
+        break;
+      case diff < (7*day):
+        num = parseInt((diff / day), 10);
+        ret = abbr ? num + 'd' : 'about ' + num + ' days ago';
+        break;
+      case diff < (11*day):
+        ret = abbr ? '1w': 'one week ago';
+        break;
+      case diff < (1*month):
+        num = Math.round(diff / week);
+        ret = abbr ? num + 'w' : 'about ' + num + ' weeks ago';
+        break;
+      default:
+        ret = date.strftime(dt, format);
+        break;
+    }
+    return ret;
+  };
+
+  /**
+    @name date#toISO8601
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    @description Convert a Date to an ISO8601-formatted string
+    @param {Date} dt The Date to to convert to an ISO8601 string
+  */
+  var _pad = function (n) {
+    return n < 10 ? '0' + n : n;
+  };
+  this.toISO8601 = function (dt, options) {
+    var opts = options || {}
+      , off = dt.getTimezoneOffset()
+      , offHours
+      , offMinutes
+      , str = this.strftime(dt, '%F') + 'T'
+          + this.strftime(dt, '%T') + '.'
+          + string.lpad(dt.getMilliseconds(), '0', 3);
+    // Pos and neg numbers are both truthy; only
+    // zero is falsy
+    if (off && !opts.utc) {
+      str += off > 0 ? '-' : '+';
+      offHours = parseInt(off / 60, 10);
+      str += string.lpad(offHours, '0', 2);
+      offMinutes = off % 60;
+      if (offMinutes) {
+        str += string.lpad(offMinutes, '0', 2);
+      }
+    }
+    else {
+      str += 'Z';
+    }
+    return str;
+  };
+
+  // Alias
+  this.toIso8601 = this.toISO8601;
+
+  this.toUTC = function (dt) {
+    return new Date(
+        dt.getUTCFullYear()
+      , dt.getUTCMonth()
+      , dt.getUTCDate()
+      , dt.getUTCHours()
+      , dt.getUTCMinutes()
+      , dt.getUTCSeconds()
+      , dt.getUTCMilliseconds());
+  };
+
+})();
+
+module.exports = date;
+
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/event_buffer.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/event_buffer.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/event_buffer.js
new file mode 100644
index 0000000..3e224c8
--- /dev/null
+++ b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/event_buffer.js
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ *
+*/
+
+/*
+This is a very simple buffer for a predetermined set of events. It is unbounded.
+It forwards all arguments to any outlet emitter attached with sync().
+
+Example:
+    var source = new Stream()
+      , dest = new EventEmitter()
+      , buff = new EventBuffer(source)
+      , data = '';
+    dest.on('data', function (d) { data += d; });
+    source.writeable = true;
+    source.readable = true;
+    source.emit('data', 'abcdef');
+    source.emit('data', '123456');
+    buff.sync(dest);
+*/
+
+/**
+  @name EventBuffer
+  @namespace EventBuffer
+  @constructor
+*/
+
+var EventBuffer = function (src, events) {
+  // By default, we service the default stream events
+  var self = this
+    , streamEvents = ['data', 'end', 'error', 'close', 'fd', 'drain', 'pipe'];
+  this.events = events || streamEvents;
+  this.emitter = src;
+  this.eventBuffer = [];
+  this.outlet = null;
+  this.events.forEach(function (name) {
+    self.emitter.addListener(name, function () {
+      self.proxyEmit(name, arguments);
+    });
+  });
+};
+
+EventBuffer.prototype = new (function () {
+  /**
+    @name EventBuffer#proxyEmit
+    @public
+    @function
+    @description Emit an event by name and arguments or add it to the buffer if
+                 no outlet is set
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.proxyEmit = function (name, args) {
+    if (this.outlet) {
+      this.emit(name, args);
+    }
+    else {
+      this.eventBuffer.push({name: name, args: args});
+    }
+  };
+
+  /**
+    @name EventBuffer#emit
+    @public
+    @function
+    @description Emit an event by name and arguments
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.emit = function (name, args) {
+    // Prepend name to args
+    var outlet = this.outlet;
+    Array.prototype.splice.call(args, 0, 0, name);
+    outlet.emit.apply(outlet, args);
+  };
+
+  /**
+    @name EventBuffer#sync
+    @public
+    @function
+    @description Flush the buffer and continue piping new events to the outlet
+    @param {Object} outlet The emitter to send events to
+  */
+  this.sync = function (outlet) {
+    var buffer = this.eventBuffer
+      , bufferItem;
+    this.outlet = outlet;
+    while ((bufferItem = buffer.shift())) {
+      this.emit(bufferItem.name, bufferItem.args);
+    }
+  };
+})();
+EventBuffer.prototype.constructor = EventBuffer;
+
+module.exports.EventBuffer = EventBuffer;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/file.js
new file mode 100644
index 0000000..a4bd2e7
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/i18n.js
new file mode 100644
index 0000000..aa00950
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/index.js
new file mode 100644
index 0000000..97e1118
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/inflection.js
new file mode 100644
index 0000000..2d89839
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/log.js
new file mode 100644
index 0000000..d26557b
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/network.js
new file mode 100644
index 0000000..c90324d
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/object.js
new file mode 100644
index 0000000..dd92e7d
--- /dev/null
+++ b/lib/cordova-blackberry/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-cli/blob/6831bed4/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js b/lib/cordova-blackberry/blackberry10/node_modules/jake/node_modules/utilities/lib/request.js
new file mode 100644
index 0000000..0984db1
--- /dev/null
+++ b/lib/cordova-blackberry/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;