elife
Version:
Express life // jump start your web application with express
1,421 lines (1,275 loc) • 69.8 kB
JavaScript
Type = require('type-of-is');
//https://github.com/kvz/phpjs/tree/master/functions
pathinfo = function(path, options) {
// discuss at: http://phpjs.org/functions/pathinfo/
// original by: Nate
// revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: Timo
// note: Inspired by actual PHP source: php5-5.2.6/ext/standard/string.c line #1559
// note: The way the bitwise arguments are handled allows for greater flexibility
// note: & compatability. We might even standardize this code and use a similar approach for
// note: other bitwise PHP functions
// note: php.js tries very hard to stay away from a core.js file with global dependencies, because we like
// note: that you can just take a couple of functions and be on your way.
// note: But by way we implemented this function, if you want you can still declare the PATHINFO_*
// note: yourself, and then you can use: pathinfo('/www/index.html', PATHINFO_BASENAME | PATHINFO_EXTENSION);
// note: which makes it fully compliant with PHP syntax.
// depends on: basename
// example 1: pathinfo('/www/htdocs/index.html', 1);
// returns 1: '/www/htdocs'
// example 2: pathinfo('/www/htdocs/index.html', 'PATHINFO_BASENAME');
// returns 2: 'index.html'
// example 3: pathinfo('/www/htdocs/index.html', 'PATHINFO_EXTENSION');
// returns 3: 'html'
// example 4: pathinfo('/www/htdocs/index.html', 'PATHINFO_FILENAME');
// returns 4: 'index'
// example 5: pathinfo('/www/htdocs/index.html', 2 | 4);
// returns 5: {basename: 'index.html', extension: 'html'}
// example 6: pathinfo('/www/htdocs/index.html', 'PATHINFO_ALL');
// returns 6: {dirname: '/www/htdocs', basename: 'index.html', extension: 'html', filename: 'index'}
// example 7: pathinfo('/www/htdocs/index.html');
// returns 7: {dirname: '/www/htdocs', basename: 'index.html', extension: 'html', filename: 'index'}
var opt = '',
optName = '',
optTemp = 0,
tmp_arr = {},
cnt = 0,
i = 0;
var have_basename = false,
have_extension = false,
have_filename = false;
// Input defaulting & sanitation
if (!path) {
return false;
}
if (!options) {
options = 'PATHINFO_ALL';
}
// Initialize binary arguments. Both the string & integer (constant) input is
// allowed
var OPTS = {
'PATHINFO_DIRNAME': 1,
'PATHINFO_BASENAME': 2,
'PATHINFO_EXTENSION': 4,
'PATHINFO_FILENAME': 8,
'PATHINFO_ALL': 0
};
// PATHINFO_ALL sums up all previously defined PATHINFOs (could just pre-calculate)
for (optName in OPTS) {
OPTS.PATHINFO_ALL = OPTS.PATHINFO_ALL | OPTS[optName];
}
if (typeof options !== 'number') { // Allow for a single string or an array of string flags
options = [].concat(options);
for (i = 0; i < options.length; i++) {
// Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
if (OPTS[options[i]]) {
optTemp = optTemp | OPTS[options[i]];
}
}
options = optTemp;
}
// Internal Functions
var __getExt = function(path) {
var str = path + '';
var dotP = str.lastIndexOf('.') + 1;
return !dotP ? false : dotP !== str.length ? str.substr(dotP) : '';
};
// Gather path infos
if (options & OPTS.PATHINFO_DIRNAME) {
var dirName = path.replace(/\\/g, '/')
.replace(/\/[^\/]*\/?$/, ''); // dirname
tmp_arr.dirname = dirName === path ? '.' : dirName;
}
if (options & OPTS.PATHINFO_BASENAME) {
if (false === have_basename) {
have_basename = this.basename(path);
}
tmp_arr.basename = have_basename;
}
if (options & OPTS.PATHINFO_EXTENSION) {
if (false === have_basename) {
have_basename = this.basename(path);
}
if (false === have_extension) {
have_extension = __getExt(have_basename);
}
if (false !== have_extension) {
tmp_arr.extension = have_extension;
}
}
if (options & OPTS.PATHINFO_FILENAME) {
if (false === have_basename) {
have_basename = this.basename(path);
}
if (false === have_extension) {
have_extension = __getExt(have_basename);
}
if (false === have_filename) {
have_filename = have_basename.slice(0, have_basename.length - (have_extension ? have_extension.length + 1 :
have_extension === false ? 0 : 1));
}
tmp_arr.filename = have_filename;
}
// If array contains only 1 element: return string
cnt = 0;
for (opt in tmp_arr) {
cnt++;
}
if (cnt == 1) {
return tmp_arr[opt];
}
// Return full-blown array
return tmp_arr;
};
var_dump = function() {
// discuss at: http://phpjs.org/functions/var_dump/
// original by: Brett Zamir (http://brett-zamir.me)
// improved by: Zahlii
// improved by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// note: For returning a string, use var_export() with the second argument set to true
// test: skip
// example 1: var_dump(1);
// returns 1: 'int(1)'
var output = '',
pad_char = ' ',
pad_val = 4,
lgth = 0,
i = 0;
var _getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
var _repeat_char = function(len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
};
var _getInnerVal = function(val, thick_pad) {
var ret = '';
if (val === null) {
ret = 'NULL';
} else if (typeof val === 'boolean') {
ret = 'bool(' + val + ')';
} else if (typeof val === 'string') {
ret = 'string(' + val.length + ') "' + val + '"';
} else if (typeof val === 'number') {
if (parseFloat(val) == parseInt(val, 10)) {
ret = 'int(' + val + ')';
} else {
ret = 'float(' + val + ')';
}
}
// The remaining are not PHP behavior because these values only exist in this exact form in JavaScript
else if (typeof val === 'undefined') {
ret = 'undefined';
} else if (typeof val === 'function') {
var funcLines = val.toString()
.split('\n');
ret = '';
for (var i = 0, fll = funcLines.length; i < fll; i++) {
ret += (i !== 0 ? '\n' + thick_pad : '') + funcLines[i];
}
} else if (val instanceof Date) {
ret = 'Date(' + val + ')';
} else if (val instanceof RegExp) {
ret = 'RegExp(' + val + ')';
} else if (val.nodeName) { // Different than PHP's DOMElement
switch (val.nodeType) {
case 1:
if (typeof val.namespaceURI === 'undefined' || val.namespaceURI === 'http://www.w3.org/1999/xhtml') { // Undefined namespace could be plain XML, but namespaceURI not widely supported
ret = 'HTMLElement("' + val.nodeName + '")';
} else {
ret = 'XML Element("' + val.nodeName + '")';
}
break;
case 2:
ret = 'ATTRIBUTE_NODE(' + val.nodeName + ')';
break;
case 3:
ret = 'TEXT_NODE(' + val.nodeValue + ')';
break;
case 4:
ret = 'CDATA_SECTION_NODE(' + val.nodeValue + ')';
break;
case 5:
ret = 'ENTITY_REFERENCE_NODE';
break;
case 6:
ret = 'ENTITY_NODE';
break;
case 7:
ret = 'PROCESSING_INSTRUCTION_NODE(' + val.nodeName + ':' + val.nodeValue + ')';
break;
case 8:
ret = 'COMMENT_NODE(' + val.nodeValue + ')';
break;
case 9:
ret = 'DOCUMENT_NODE';
break;
case 10:
ret = 'DOCUMENT_TYPE_NODE';
break;
case 11:
ret = 'DOCUMENT_FRAGMENT_NODE';
break;
case 12:
ret = 'NOTATION_NODE';
break;
}
}
return ret;
};
var _formatArray = function(obj, cur_depth, pad_val, pad_char) {
var someProp = '';
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = _repeat_char(pad_val * (cur_depth - 1), pad_char);
var thick_pad = _repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
var val = '';
if (typeof obj === 'object' && obj !== null) {
if (obj.constructor && _getFuncName(obj.constructor) === 'PHPJS_Resource') {
return obj.var_dump();
}
lgth = 0;
for (someProp in obj) {
lgth++;
}
str += 'array(' + lgth + ') {\n';
for (var key in obj) {
var objVal = obj[key];
if (typeof objVal === 'object' && objVal !== null && !(objVal instanceof Date) && !(objVal instanceof RegExp) && !
objVal.nodeName) {
str += thick_pad + '[' + key + '] =>\n' + thick_pad + _formatArray(objVal, cur_depth + 1, pad_val,
pad_char);
} else {
val = _getInnerVal(objVal, thick_pad);
str += thick_pad + '[' + key + '] =>\n' + thick_pad + val + '\n';
}
}
str += base_pad + '}\n';
} else {
str = _getInnerVal(obj, thick_pad);
}
return str;
};
output = _formatArray(arguments[0], 0, pad_val, pad_char);
for (i = 1; i < arguments.length; i++) {
output += '\n' + _formatArray(arguments[i], 0, pad_val, pad_char);
}
var isNode = typeof module !== 'undefined' && module.exports;
if (isNode) {
return '<pre >'+output+'</pre>';
}
var d = this.window.document;
if (d.body) {
this.echo(output);
} else {
try {
d = XULDocument; // We're in XUL, so appending as plain text won't work
this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">' + output + '</pre>');
} catch (e) {
this.echo(output); // Outputting as plain text may work in some plain XML
}
}
}
//EQUIVALENT OF PHP is_string
count = function(v){
if(is_array(v)) return v.length;
else if(is_number(v)) return (''+v).length;
var c = 0;
for(var i in v) c++;
return c;
};
/*
* FROM http://stackoverflow.com/questions/10645994/node-js-how-to-format-a-date-string-in-utc
*/
dateFormat = function(date, fstr, utc) {
utc = utc ? 'getUTC' : 'get';
return fstr.replace (/%[YmdHMS]/g, function (m) {
switch (m) {
case '%Y': return date[utc + 'FullYear'] (); // no leading zeros required
case '%m': m = 1 + date[utc + 'Month'] (); break;
case '%d': m = date[utc + 'Date'] (); break;
case '%H': m = date[utc + 'Hours'] (); break;
case '%M': m = date[utc + 'Minutes'] (); break;
case '%S': m = date[utc + 'Seconds'] (); break;
default: return m.slice (1); // unknown code, remove %
}
// add leading zero if required
return ('0' + m).slice (-2);
});
};
empty = function(mixed_var){
var undef, key, i, len;
var emptyValues = [undef, null, false, 0, '', '0'];
for (i = 0, len = emptyValues.length; i < len; i++) {
if (mixed_var === emptyValues[i]) {
return true;
}
}
if (typeof mixed_var === 'object') {
for (key in mixed_var) {
// TODO: should we check for own properties only?
//if (mixed_var.hasOwnProperty(key)) {
return false;
//}
}
return true;
}
return false;
};
array_int = function(a){
var v = true;
for(var i in a){
if(!is_number(a[i])){
v = false;
break;
}
}
return v;
};
object_merge = function(target, source){
/*
*
* Merges two (or more) objects,
* giving the last one precedence
*
*/
if ( typeof target !== 'object' ) {
target = {};
}
for (var property in source) {
if ( source.hasOwnProperty(property) ) {
var sourceProperty = source[ property ];
if ( typeof sourceProperty === 'object' ) {
target[ property ] = object_merge( target[ property ], sourceProperty );
continue;
}
target[ property ] = sourceProperty;
}
}
for (var a = 2, l = arguments.length; a < l; a++) {
merge(target, arguments[a]);
}
return target;
};
is_string = function(variable){
return Type.string(variable) == 'String';
};
is_bool = function(variable){
return Type.string(variable) == 'Boolean';
};
is_number = function(variable){
return Type.string(variable) == 'Number';
};
is_object = function(variable){
return Type.string(variable) == 'Object';
};
is_null = function(variable){
return Type.string(variable) == 'Null';
};
is_undefined = function(variable){
return Type.string(variable) == 'Undefined';
};
is_regexp = function(variable){
return Type.string(variable) == 'RegExp';
};
is_array = function(variable){
return Type.string(variable) == 'Array';
};
is_function = function(variable){
return Type.string(variable) == 'Function';
};
is_date = function(variable){
return Type.string(variable) == 'Date';
};
is_error = function(variable){
return Type.string(variable) == 'Error';
};
array_map = function(callback) {
// discuss at: http://phpjs.org/functions/array_map/
// original by: Andrea Giammarchi (http://webreflection.blogspot.com)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: thekid
// note: If the callback is a string (or object, if an array is supplied), it can only work if the function name is in the global context
// example 1: array_map( function (a){return (a * a * a)}, [1, 2, 3, 4, 5] );
// returns 1: [ 1, 8, 27, 64, 125 ]
var argc = arguments.length,
argv = arguments,
glbl = this.window,
obj = null,
cb = callback,
j = argv[1].length,
i = 0,
k = 1,
m = 0,
tmp = [],
tmp_ar = [];
while (i < j) {
while (k < argc) {
tmp[m++] = argv[k++][i];
}
m = 0;
k = 1;
if (callback) {
if (typeof callback === 'string') {
cb = glbl[callback];
} else if (typeof callback === 'object' && callback.length) {
obj = typeof callback[0] === 'string' ? glbl[callback[0]] : callback[0];
if (typeof obj === 'undefined') {
throw 'Object not found: ' + callback[0];
}
cb = typeof callback[1] === 'string' ? obj[callback[1]] : callback[1];
}
tmp_ar[i++] = cb.apply(obj, tmp);
} else {
tmp_ar[i++] = tmp;
}
tmp = [];
}
return tmp_ar;
}
array_merge = function() {
// discuss at: http://phpjs.org/functions/array_merge/
// original by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Nate
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// input by: josh
// example 1: arr1 = {"color": "red", 0: 2, 1: 4}
// example 1: arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4}
// example 1: array_merge(arr1, arr2)
// returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4}
// example 2: arr1 = []
// example 2: arr2 = {1: "data"}
// example 2: array_merge(arr1, arr2)
// returns 2: {0: "data"}
var args = Array.prototype.slice.call(arguments),
argl = args.length,
arg,
retObj = {},
k = '',
argil = 0,
j = 0,
i = 0,
ct = 0,
toStr = Object.prototype.toString,
retArr = true;
for (i = 0; i < argl; i++) {
if (toStr.call(args[i]) !== '[object Array]') {
retArr = false;
break;
}
}
if (retArr) {
retArr = [];
for (i = 0; i < argl; i++) {
retArr = retArr.concat(args[i]);
}
return retArr;
}
for (i = 0, ct = 0; i < argl; i++) {
arg = args[i];
if (toStr.call(arg) === '[object Array]') {
for (j = 0, argil = arg.length; j < argil; j++) {
retObj[ct++] = arg[j];
}
} else {
for (k in arg) {
if (arg.hasOwnProperty(k)) {
if (parseInt(k, 10) + '' === k) {
retObj[ct++] = arg[k];
} else {
retObj[k] = arg[k];
}
}
}
}
}
return retObj;
}
array_keys = function(input, search_value, argStrict) {
// discuss at: http://phpjs.org/functions/array_keys/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Brett Zamir (http://brett-zamir.me)
// input by: P
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// improved by: jd
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
// returns 1: {0: 'firstname', 1: 'surname'}
var search = typeof search_value !== 'undefined',
tmp_arr = [],
strict = !! argStrict,
include = true,
key = '';
if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array
return input.keys(search_value, argStrict);
}
for (key in input) {
if (input.hasOwnProperty(key)) {
include = true;
if (search) {
if (strict && input[key] !== search_value) {
include = false;
} else if (input[key] != search_value) {
include = false;
}
}
if (include) {
tmp_arr[tmp_arr.length] = key;
}
}
}
return tmp_arr;
}
array_sum = function(array) {
// discuss at: http://phpjs.org/functions/array_sum/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Nate
// bugfixed by: Gilbert
// improved by: David Pilia (http://www.beteck.it/)
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: array_sum([4, 9, 182.6]);
// returns 1: 195.6
// example 2: total = []; index = 0.1; for (y=0; y < 12; y++){total[y] = y + index;}
// example 2: array_sum(total);
// returns 2: 67.2
var key, sum = 0;
if (array && typeof array === 'object' && array.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array
return array.sum.apply(array, Array.prototype.slice.call(arguments, 0));
}
// input sanitation
if (typeof array !== 'object') {
return null;
}
for (key in array) {
if (!isNaN(parseFloat(array[key]))) {
sum += parseFloat(array[key]);
}
}
return sum;
}
count = function(mixed_var, mode) {
// discuss at: http://phpjs.org/functions/count/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Waldo Malqui Silva
// input by: merabi
// bugfixed by: Soren Hansen
// bugfixed by: Olivier Louvignes (http://mg-crea.com/)
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE');
// returns 1: 6
// example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
// returns 2: 6
var key, cnt = 0;
if (mixed_var === null || typeof mixed_var === 'undefined') {
return 0;
} else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object) {
return 1;
}
if (mode === 'COUNT_RECURSIVE') {
mode = 1;
}
if (mode != 1) {
mode = 0;
}
for (key in mixed_var) {
if (mixed_var.hasOwnProperty(key)) {
cnt++;
if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor ===
Object)) {
cnt += this.count(mixed_var[key], 1);
}
}
}
return cnt;
}
in_array = function(needle, haystack, argStrict) {
// discuss at: http://phpjs.org/functions/in_array/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: vlado houba
// improved by: Jonas Sciangula Street (Joni2Back)
// input by: Billy
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);
// returns 1: true
// example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
// returns 2: false
// example 3: in_array(1, ['1', '2', '3']);
// example 3: in_array(1, ['1', '2', '3'], false);
// returns 3: true
// returns 3: true
// example 4: in_array(1, ['1', '2', '3'], true);
// returns 4: false
var key = '',
strict = !! argStrict;
//we prevent the double check (strict && arr[key] === ndl) || (!strict && arr[key] == ndl)
//in just one for, in order to improve the performance
//deciding wich type of comparation will do before walk array
if (strict) {
for (key in haystack) {
if (haystack[key] === needle) {
return true;
}
}
} else {
for (key in haystack) {
if (haystack[key] == needle) {
return true;
}
}
}
return false;
}
range = function(low, high, step) {
// discuss at: http://phpjs.org/functions/range/
// original by: Waldo Malqui Silva
// example 1: range ( 0, 12 );
// returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// example 2: range( 0, 100, 10 );
// returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
// example 3: range( 'a', 'i' );
// returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
// example 4: range( 'c', 'a' );
// returns 4: ['c', 'b', 'a']
var matrix = [];
var inival, endval, plus;
var walker = step || 1;
var chars = false;
if (!isNaN(low) && !isNaN(high)) {
inival = low;
endval = high;
} else if (isNaN(low) && isNaN(high)) {
chars = true;
inival = low.charCodeAt(0);
endval = high.charCodeAt(0);
} else {
inival = (isNaN(low) ? 0 : low);
endval = (isNaN(high) ? 0 : high);
}
plus = ((inival > endval) ? false : true);
if (plus) {
while (inival <= endval) {
matrix.push(((chars) ? String.fromCharCode(inival) : inival));
inival += walker;
}
} else {
while (inival >= endval) {
matrix.push(((chars) ? String.fromCharCode(inival) : inival));
inival -= walker;
}
}
return matrix;
}
time = function() {
// discuss at: http://phpjs.org/functions/time/
// original by: GeekFG (http://geekfg.blogspot.com)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: metjay
// improved by: HKM
// example 1: timeStamp = time();
// example 1: timeStamp > 1000000000 && timeStamp < 2000000000
// returns 1: true
return Math.floor(new Date()
.getTime() / 1000);
}
strtotime = function(text, now) {
// discuss at: http://phpjs.org/functions/strtotime/
// version: 1109.2016
// original by: Caio Ariede (http://caioariede.com)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Caio Ariede (http://caioariede.com)
// improved by: A. Matías Quezada (http://amatiasq.com)
// improved by: preuter
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Mirko Faber
// input by: David
// bugfixed by: Wagner B. Soares
// bugfixed by: Artur Tchernychev
// note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
// example 1: strtotime('+1 day', 1129633200);
// returns 1: 1129719600
// example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
// returns 2: 1130425202
// example 3: strtotime('last month', 1129633200);
// returns 3: 1127041200
// example 4: strtotime('2009-05-04 08:30:00 GMT');
// returns 4: 1241425800
var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false;
if (!text) {
return fail;
}
// Unecessary spaces
text = text.replace(/^\s+|\s+$/g, '')
.replace(/\s{2,}/g, ' ')
.replace(/[\t\r\n]/g, '')
.toLowerCase();
// in contrast to php, js Date.parse function interprets:
// dates given as yyyy-mm-dd as in timezone: UTC,
// dates with "." or "-" as MDY instead of DMY
// dates with two-digit years differently
// etc...etc...
// ...therefore we manually parse lots of common date formats
match = text.match(
/^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/);
if (match && match[2] === match[4]) {
if (match[1] > 1901) {
switch (match[2]) {
case '-':
{ // YYYY-M-D
if (match[3] > 12 || match[5] > 31) {
return fail;
}
return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
case '.':
{ // YYYY.M.D is not parsed by strtotime()
return fail;
}
case '/':
{ // YYYY/M/D
if (match[3] > 12 || match[5] > 31) {
return fail;
}
return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
}
} else if (match[5] > 1901) {
switch (match[2]) {
case '-':
{ // D-M-YYYY
if (match[3] > 12 || match[1] > 31) {
return fail;
}
return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
case '.':
{ // D.M.YYYY
if (match[3] > 12 || match[1] > 31) {
return fail;
}
return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
case '/':
{ // M/D/YYYY
if (match[1] > 12 || match[3] > 31) {
return fail;
}
return new Date(match[5], parseInt(match[1], 10) - 1, match[3],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
}
} else {
switch (match[2]) {
case '-':
{ // YY-M-D
if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) {
return fail;
}
year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1];
return new Date(year, parseInt(match[3], 10) - 1, match[5],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
case '.':
{ // D.M.YY or H.MM.SS
if (match[5] >= 70) { // D.M.YY
if (match[3] > 12 || match[1] > 31) {
return fail;
}
return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
if (match[5] < 60 && !match[6]) { // H.MM.SS
if (match[1] > 23 || match[3] > 59) {
return fail;
}
today = new Date();
return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000;
}
return fail; // invalid format, cannot be parsed
}
case '/':
{ // M/D/YY
if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) {
return fail;
}
year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5];
return new Date(year, parseInt(match[1], 10) - 1, match[3],
match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
}
case ':':
{ // HH:MM:SS
if (match[1] > 23 || match[3] > 59 || match[5] > 59) {
return fail;
}
today = new Date();
return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
match[1] || 0, match[3] || 0, match[5] || 0) / 1000;
}
}
}
}
// other formats and "now" should be parsed by Date.parse()
if (text === 'now') {
return now === null || isNaN(now) ? new Date()
.getTime() / 1000 | 0 : now | 0;
}
if (!isNaN(parsed = Date.parse(text))) {
return parsed / 1000 | 0;
}
date = now ? new Date(now * 1000) : new Date();
days = {
'sun': 0,
'mon': 1,
'tue': 2,
'wed': 3,
'thu': 4,
'fri': 5,
'sat': 6
};
ranges = {
'yea': 'FullYear',
'mon': 'Month',
'day': 'Date',
'hou': 'Hours',
'min': 'Minutes',
'sec': 'Seconds'
};
function lastNext(type, range, modifier) {
var diff, day = days[range];
if (typeof day !== 'undefined') {
diff = day - date.getDay();
if (diff === 0) {
diff = 7 * modifier;
} else if (diff > 0 && type === 'last') {
diff -= 7;
} else if (diff < 0 && type === 'next') {
diff += 7;
}
date.setDate(date.getDate() + diff);
}
}
function process(val) {
var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes
type = splt[0],
range = splt[1].substring(0, 3),
typeIsNumber = /\d+/.test(type),
ago = splt[2] === 'ago',
num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1);
if (typeIsNumber) {
num *= parseInt(type, 10);
}
if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) {
return date['set' + ranges[range]](date['get' + ranges[range]]() + num);
}
if (range === 'wee') {
return date.setDate(date.getDate() + (num * 7));
}
if (type === 'next' || type === 'last') {
lastNext(type, range, num);
} else if (!typeIsNumber) {
return false;
}
return true;
}
times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' +
'|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' +
'|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)';
regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?';
match = text.match(new RegExp(regex, 'gi'));
if (!match) {
return fail;
}
for (i = 0, len = match.length; i < len; i++) {
if (!process(match[i])) {
return fail;
}
}
// ECMAScript 5 only
// if (!match.every(process))
// return false;
return (date.getTime() / 1000);
}
microtime = function(get_as_float) {
// discuss at: http://phpjs.org/functions/microtime/
// original by: Paulo Freitas
// example 1: timeStamp = microtime(true);
// example 1: timeStamp > 1000000000 && timeStamp < 2000000000
// returns 1: true
var now = new Date()
.getTime() / 1000;
var s = parseInt(now, 10);
return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
}
date = function(format, timestamp) {
// discuss at: http://phpjs.org/functions/date/
// original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
// original by: gettimeofday
// parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: MeEtc (http://yass.meetcweb.com)
// improved by: Brad Touesnard
// improved by: Tim Wiel
// improved by: Bryan Elliott
// improved by: David Randall
// improved by: Theriault
// improved by: Theriault
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Theriault
// improved by: Thomas Beaucourt (http://www.webapp.fr)
// improved by: JT
// improved by: Theriault
// improved by: Rafał Kukawski (http://blog.kukawski.pl)
// improved by: Theriault
// input by: Brett Zamir (http://brett-zamir.me)
// input by: majak
// input by: Alex
// input by: Martin
// input by: Alex Wilson
// input by: Haravikk
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: majak
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
// bugfixed by: Chris (http://www.devotis.nl/)
// note: Uses global: php_js to store the default timezone
// note: Although the function potentially allows timezone info (see notes), it currently does not set
// note: per a timezone specified by date_default_timezone_set(). Implementers might use
// note: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
// note: in order to adjust the dates in this function (or our other date functions!) accordingly
// example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
// returns 1: '09:09:40 m is month'
// example 2: date('F j, Y, g:i a', 1062462400);
// returns 2: 'September 2, 2003, 2:26 am'
// example 3: date('Y W o', 1062462400);
// returns 3: '2003 36 2003'
// example 4: x = date('Y m d', (new Date()).getTime()/1000);
// example 4: (x+'').length == 10 // 2009 01 09
// returns 4: true
// example 5: date('W', 1104534000);
// returns 5: '53'
// example 6: date('B t', 1104534000);
// returns 6: '999 31'
// example 7: date('W U', 1293750000.82); // 2010-12-31
// returns 7: '52 1293750000'
// example 8: date('W', 1293836400); // 2011-01-01
// returns 8: '52'
// example 9: date('W Y-m-d', 1293974054); // 2011-01-02
// returns 9: '52 2011-01-02'
var that = this;
var jsdate, f;
// Keep this here (works, but for code commented-out below for file size reasons)
// var tal= [];
var txt_words = [
'Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur',
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
// trailing backslash -> (dropped)
// a backslash followed by any character (including backslash) -> the character
// empty string -> empty string
var formatChr = /\\?(.?)/gi;
var formatChrCb = function(t, s) {
return f[t] ? f[t]() : s;
};
var _pad = function(n, c) {
n = String(n);
while (n.length < c) {
n = '0' + n;
}
return n;
};
f = {
// Day
d: function() { // Day of month w/leading 0; 01..31
return _pad(f.j(), 2);
},
D: function() { // Shorthand day name; Mon...Sun
return f.l()
.slice(0, 3);
},
j: function() { // Day of month; 1..31
return jsdate.getDate();
},
l: function() { // Full day name; Monday...Sunday
return txt_words[f.w()] + 'day';
},
N: function() { // ISO-8601 day of week; 1[Mon]..7[Sun]
return f.w() || 7;
},
S: function() { // Ordinal suffix for day of month; st, nd, rd, th
var j = f.j();
var i = j % 10;
if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) {
i = 0;
}
return ['st', 'nd', 'rd'][i - 1] || 'th';
},
w: function() { // Day of week; 0[Sun]..6[Sat]
return jsdate.getDay();
},
z: function() { // Day of year; 0..365
var a = new Date(f.Y(), f.n() - 1, f.j());
var b = new Date(f.Y(), 0, 1);
return Math.round((a - b) / 864e5);
},
// Week
W: function() { // ISO-8601 week number
var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3);
var b = new Date(a.getFullYear(), 0, 4);
return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
},
// Month
F: function() { // Full month name; January...December
return txt_words[6 + f.n()];
},
m: function() { // Month w/leading 0; 01...12
return _pad(f.n(), 2);
},
M: function() { // Shorthand month name; Jan...Dec
return f.F()
.slice(0, 3);
},
n: function() { // Month; 1...12
return jsdate.getMonth() + 1;
},
t: function() { // Days in month; 28...31
return (new Date(f.Y(), f.n(), 0))
.getDate();
},
// Year
L: function() { // Is leap year?; 0 or 1
var j = f.Y();
return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0;
},
o: function() { // ISO-8601 year
var n = f.n();
var W = f.W();
var Y = f.Y();
return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
},
Y: function() { // Full year; e.g. 1980...2010
return jsdate.getFullYear();
},
y: function() { // Last two digits of year; 00...99
return f.Y()
.toString()
.slice(-2);
},
// Time
a: function() { // am or pm
return jsdate.getHours() > 11 ? 'pm' : 'am';
},
A: function() { // AM or PM
return f.a()
.toUpperCase();
},
B: function() { // Swatch Internet time; 000..999
var H = jsdate.getUTCHours() * 36e2;
// Hours
var i = jsdate.getUTCMinutes() * 60;
// Minutes
var s = jsdate.getUTCSeconds(); // Seconds
return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
},
g: function() { // 12-Hours; 1..12
return f.G() % 12 || 12;
},
G: function() { // 24-Hours; 0..23
return jsdate.getHours();
},
h: function() { // 12-Hours w/leading 0; 01..12
return _pad(f.g(), 2);
},
H: function() { // 24-Hours w/leading 0; 00..23
return _pad(f.G(), 2);
},
i: function() { // Minutes w/leading 0; 00..59
return _pad(jsdate.getMinutes(), 2);
},
s: function() { // Seconds w/leading 0; 00..59
return _pad(jsdate.getSeconds(), 2);
},
u: function() { // Microseconds; 000000-999000
return _pad(jsdate.getMilliseconds() * 1000, 6);
},
// Timezone
e: function() { // Timezone identifier; e.g. Atlantic/Azores, ...
// The following works, but requires inclusion of the very large
// timezone_abbreviations_list() function.
/* return that.date_default_timezone_get();
*/
throw 'Not supported (see source code of date() for timezone on how to add support)';
},
I: function() { // DST observed?; 0 or 1
// Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
// If they are not equal, then DST is observed.
var a = new Date(f.Y(), 0);
// Jan 1
var c = Date.UTC(f.Y(), 0);
// Jan 1 UTC
var b = new Date(f.Y(), 6);
// Jul 1
var d = Date.UTC(f.Y(), 6); // Jul 1 UTC
return ((a - c) !== (b - d)) ? 1 : 0;
},
O: function() { // Difference to GMT in hour format; e.g. +0200
var tzo = jsdate.getTimezoneOffset();
var a = Math.abs(tzo);
return (tzo > 0 ? '-' : '+') + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
},
P: function() { // Difference to GMT w/colon; e.g. +02:00
var O = f.O();
return (O.substr(0, 3) + ':' + O.substr(3, 2));
},
T: function() { // Timezone abbreviation; e.g. EST, MDT, ...
// The following works, but requires inclusion of the very
// large timezone_abbreviations_list() function.
/* var abbr, i, os, _default;
if (!tal.length) {
tal = that.timezone_abbreviations_list();
}
if (that.php_js && that.php_js.default_timezone) {
_default = that.php_js.default_timezone;
for (abbr in tal) {
for (i = 0; i < tal[abbr].length; i++) {
if (tal[abbr][i].timezone_id === _default) {
return abbr.toUpperCase();
}
}
}
}
for (abbr in tal) {
for (i = 0; i < tal[abbr].length; i++) {
os = -jsdate.getTimezoneOffset() * 60;
if (tal[abbr][i].offset === os) {
return abbr.toUpperCase();
}
}
}
*/
return 'UTC';
},
Z: function() { // Timezone offset in seconds (-43200...50400)
return -jsdate.getTimezoneOffset() * 60;
},
// Full Date/Time
c: function() { // ISO-8601 date.
return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
},
r: function() { // RFC 2822
return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
},
U: function() { // Seconds since UNIX epoch
return jsdate / 1000 | 0;
}
};
this.date = function(format, timestamp) {
that = this;
jsdate = (timestamp === undefined ? new Date() : // Not provided
(timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
);
return format.replace(formatChr, formatChrCb);
};
return this.date(format, timestamp);
}
function_exists = function(func_name) {
// discuss at: http://phpjs.org/functions/function_exists/
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Steve Clay
// improved by: Legaev Andrey
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: function_exists('isFinite');
// returns 1: true
if (typeof func_name === 'string') {
try {
func_name = this.window[func_name];
}catch(e){}
}
return typeof func_name === 'function';
}
rand = function(min, max) {
// discuss at: http://phpjs.org/functions/rand/
// original by: Leslie Hoare
// bugfixed by: Onno Marsman
// note: See the commented out code below for a version which will work with our experimental (though probably unnecessary) srand() function)
// example 1: rand(1, 1);
// returns 1: 1
var argc = arguments.length;
if (argc === 0) {
min = 0;
max = 2147483647;
} else if (argc === 1) {
throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
}
return Math.floor(Math.random() * (max - min + 1)) + min;
/*
// See note above for an explanation of the following alternative code
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// - depends on: srand
// % note 1: This is a very possibly imperfect adaptation from the PHP source code
var rand_seed, ctx, PHP_RAND_MAX=2147483647; // 0x7fffffff
if (!this.php_js || this.php_js.rand_seed === undefined) {
this.srand();
}
rand_seed = this.php_js.rand_seed;
var argc = arguments.length;
if (argc === 1) {
throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
}
var do_rand = function (ctx) {
return ((ctx * 1103515245 + 12345) % (PHP_RAND_MAX + 1));
};
var php_rand = function (ctxArg) { // php_rand_r
this.php_js.rand_seed = do_rand(ctxArg);
return parseInt(this.php_js.rand_seed, 10);
};
var number = php_rand(rand_seed);
if (argc === 2) {
number = min + parseInt(parseFloat(parseFloat(max) - min + 1.0) * (number/(PHP_RAND_MAX + 1.0)), 10);
}
return number;
*/
}
md5 = function(str) {
// discuss at: http://phpjs.org/functions/md5/
// original by: Webtoolkit.info (http://www.webtoolkit.info/)
// improved by: Michael White (http://getsprink.com)
// improved by: Jack
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// depends on: utf8_encode
// example 1: md5('Kevin van Zonneveld');
// returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
var xl;
var rotateLeft = function(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
};
var addUnsigned = function(lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) {