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;