mirror of https://github.com/masayuki0812/c3.git
Quite good looking graph derived from d3.js
http://c3js.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1505 lines
40 KiB
1505 lines
40 KiB
11 years ago
|
var Q = function () {
|
||
|
};
|
||
|
|
||
|
Q.copy = function (src, target, options, depth) {
|
||
|
if(depth==null)
|
||
|
depth = 0;
|
||
|
if(depth==100){
|
||
|
console.warn("Q.copy is in depth of 100 - possible circular reference")
|
||
|
}
|
||
|
///<summary>Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists</summary>
|
||
|
///<param name="src" />
|
||
|
///<param name="target" />
|
||
|
///<param name="options" type="Object">{ overwrite:false }</param>
|
||
|
///<returns type="Object">The copied object</returns>
|
||
|
options = options || { overwrite: false };
|
||
|
if (src == target || src == null)
|
||
|
return target;
|
||
|
if (typeof (src) != "object") {
|
||
|
if (options.overwrite || target == null)
|
||
|
return src;
|
||
|
return target;
|
||
|
}
|
||
|
if (typeof(src.clone)=="function") {
|
||
|
if (options.overwrite || target == null)
|
||
|
return src.clone();
|
||
|
return target;
|
||
|
}
|
||
|
if (target == null) {
|
||
|
if (src instanceof Array)
|
||
|
target = [];
|
||
|
else
|
||
|
target = {};
|
||
|
}
|
||
|
|
||
|
if (src instanceof Array) {
|
||
|
for (var i = 0; i < src.length; i++) {
|
||
|
var item = src[i];
|
||
|
var item2 = target[i];
|
||
|
item2 = Q.copy(item, item2, options, depth+1);
|
||
|
target[i] = item2;
|
||
|
}
|
||
|
target.splice(src.length, target.length - src.length);
|
||
|
return target;
|
||
|
}
|
||
|
for (var p in src) {
|
||
|
var value = src[p];
|
||
|
var value2 = target[p];
|
||
|
value2 = Q.copy(value, value2, options, depth+1);
|
||
|
target[p] = value2;
|
||
|
}
|
||
|
return target;
|
||
|
}
|
||
|
|
||
|
Object.reversePairs = function (obj) {
|
||
|
var list = [];
|
||
|
for (var i = 0; i < obj.length; i++) {
|
||
|
list.push([obj[i][1],obj[i][0]]);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Q.objectToNameValueArray = function () {
|
||
|
var list = [];
|
||
|
for (var p in this.obj) {
|
||
|
list.push({ name: p, value: this.obj[p] });
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
|
||
|
Array.prototype.forEachJoin = function (action, actionBetweenItems) {
|
||
|
var first = true;
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
if (first)
|
||
|
first = false;
|
||
|
else
|
||
|
actionBetweenItems();
|
||
|
action(this[i]);
|
||
|
}
|
||
|
}
|
||
|
Array.prototype.first = function (predicate) {
|
||
|
if (predicate == null)
|
||
|
return this[0];
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
if (predicate(this[i]))
|
||
|
return this[i];
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
Array.prototype.toArray = function () {
|
||
|
return this.slice(0, this.length);
|
||
|
}
|
||
|
|
||
|
Array.prototype.insert = function (index, item) {
|
||
|
this.splice(index, 0, item);
|
||
|
}
|
||
|
Array.prototype.last = function (predicate) {
|
||
|
if (this.length == 0)
|
||
|
return null;
|
||
|
if (predicate == null)
|
||
|
return this[this.length - 1];
|
||
|
for (var i = this.length; i >= 0; i--) {
|
||
|
if (predicate(this[i]))
|
||
|
return this[i];
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
Q.objectValuesToArray = function (obj) {
|
||
|
var list = [];
|
||
|
for (var p in obj) {
|
||
|
list.push(obj[p]);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Object.values = Q.objectValuesToArray;
|
||
|
Object.toArray = function (obj) {
|
||
|
var list = [];
|
||
|
for (var p in obj) {
|
||
|
list.push(p, obj[p]);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Object.allKeys = function (obj) {
|
||
|
var list = [];
|
||
|
for (var p in obj) {
|
||
|
list.push(p);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Object.keysValues = function (obj) {
|
||
|
var list = [];
|
||
|
for (var p in obj) {
|
||
|
list.push({ key: p, value: obj[p] });
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Object.pairs = function (obj) {
|
||
|
var list = [];
|
||
|
list.isArrayOfPairs = true;
|
||
|
for (var p in obj) {
|
||
|
list.push([p, obj[p]]);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Object.fromPairs = function (keysValues) {
|
||
|
var obj = {};
|
||
|
keysValues.forEach(function (pair) {
|
||
|
obj[pair[0]] = pair[1];
|
||
|
});
|
||
|
return obj;
|
||
|
}
|
||
|
Q.cloneJson = function (obj) {
|
||
|
if (obj == null)
|
||
|
return null;
|
||
|
return JSON.parse(JSON.stringify(obj));
|
||
|
};
|
||
|
Q.forEachValueInObject = function (obj, func, thisArg) {
|
||
|
for (var p in obj) {
|
||
|
func.call(thisArg, obj[p]);
|
||
|
}
|
||
|
};
|
||
|
Array.prototype.toObject = function (selector) {
|
||
|
if (selector == null) {
|
||
|
return this.copyPairsToObject();
|
||
|
}
|
||
|
var obj = {};
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
var obj2 = selector(this[i]);
|
||
|
if (obj2 instanceof Array)
|
||
|
obj2.copyPairsToObject(obj);
|
||
|
else {
|
||
|
for (var p in obj2)
|
||
|
obj[p] = obj2[p];
|
||
|
}
|
||
|
}
|
||
|
return obj;
|
||
|
};
|
||
|
Array.prototype.copyPairsToObject = function (obj) {
|
||
|
if (obj == null)
|
||
|
obj = {};
|
||
|
for (var i = 0; i < this.length; i += 2) {
|
||
|
obj[this[i]] = this[i + 1];
|
||
|
}
|
||
|
return obj;
|
||
|
};
|
||
|
//Object.keys = Q.keys;
|
||
|
Object.toSortedByKey = function (obj) {
|
||
|
var sortedKeys = Object.keys(obj).sort();
|
||
|
return sortedKeys.toObject(function (key) { return [key, obj[key]]; })
|
||
|
}
|
||
|
Q.mapKeyValueInArrayOrObject = function (objOrList, func, thisArg) {
|
||
|
var list = [];
|
||
|
if (objOrList instanceof Array) {
|
||
|
for (var i = 0; i < objOrList.length; i++) {
|
||
|
list.push(func.call(thisArg, i, objOrList[i]));
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for (var p in objOrList) {
|
||
|
list.push(func.call(thisArg, p, objOrList[p]));
|
||
|
}
|
||
|
}
|
||
|
return list;
|
||
|
};
|
||
|
//Alternative to $.map of jquery - which has array reducers overhead, and sometimes causes stackOverflow
|
||
|
Q.jMap = function (objOrList, func, thisArg) {
|
||
|
var list = [];
|
||
|
if (objOrList instanceof Array) {
|
||
|
for (var i = 0; i < objOrList.length; i++) {
|
||
|
list.push(func.call(thisArg, objOrList[i], i));
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for (var p in objOrList) {
|
||
|
list.push(func.call(thisArg, objOrList[p], p));
|
||
|
}
|
||
|
}
|
||
|
return list;
|
||
|
};
|
||
|
///Returns if the parameter is null, or an empty json object
|
||
|
Q.isEmptyObject = function (obj) {
|
||
|
if (obj == null)
|
||
|
return true;
|
||
|
if (typeof (obj) != "object")
|
||
|
return false;
|
||
|
for (var p in obj)
|
||
|
return false;
|
||
|
return true;
|
||
|
};
|
||
|
|
||
|
Q.min = function (list) {
|
||
|
return Math.min.apply(null, list);
|
||
|
};
|
||
|
Q.max = function (list) {
|
||
|
return Math.max.apply(null, list);
|
||
|
};
|
||
|
|
||
|
function toStringOrEmpty(val) {
|
||
|
return val == null ? "" : val.toString();
|
||
|
}
|
||
|
|
||
|
Object.getCreateArray = function (obj, p) {
|
||
|
var value = obj[p];
|
||
|
if (value == null) {
|
||
|
value = [];
|
||
|
obj[p] = value;
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
Array.prototype.removeLast = Array.prototype.pop;
|
||
|
Array.prototype.removeFirst = function () {
|
||
|
return this.splice(0, 1)[0];
|
||
|
}
|
||
|
|
||
|
Array.prototype.remove = function (item) {
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
if (this[i] === item) {
|
||
|
this.removeAt(i);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
Array.prototype.removeRange = function (items) {
|
||
|
items.forEach(function (t) { this.remove(t); });
|
||
|
}
|
||
|
String.prototype.contains = function (s) {
|
||
|
return this.indexOf(s) >= 0;
|
||
|
}
|
||
|
Array.prototype.contains = function (s) {
|
||
|
return this.indexOf(s) >= 0;
|
||
|
}
|
||
|
Array.prototype.containsAny = function (items) {
|
||
|
return items.any(function (t) { return this.contains(t); }.bind(this));
|
||
|
}
|
||
|
Array.prototype.any = function (predicate) {
|
||
|
return this.some(Q.createSelectorFunction(predicate));
|
||
|
}
|
||
|
Array.prototype.distinct = function (keyGen) {
|
||
|
if (keyGen == null)
|
||
|
keyGen = Object.getHashKey;
|
||
|
var list = [];
|
||
|
var set = {};
|
||
|
this.forEach(function (t) {
|
||
|
var key = keyGen(t);
|
||
|
if (set[key])
|
||
|
return;
|
||
|
set[key] = true;
|
||
|
list.push(t);
|
||
|
});
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
|
||
|
Array.prototype.removeAll = function (predicate) {
|
||
|
var toRemove = [];
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
if (predicate(this[i])) {
|
||
|
toRemove.push(i);
|
||
|
}
|
||
|
}
|
||
|
while (toRemove.length > 0) {
|
||
|
var index = toRemove.pop();
|
||
|
this.removeAt(index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
Array.prototype.removeAt = function (index) {
|
||
|
this.splice(index, 1);
|
||
|
}
|
||
|
|
||
|
Q.stringifyFormatted = function (obj) {
|
||
|
var sb = [];
|
||
|
sb.indent = "";
|
||
|
sb.indentSize = " ";
|
||
|
sb.startBlock = function (s) {
|
||
|
this.indent += sb.indentSize;
|
||
|
this.push(s);
|
||
|
this.newLine();
|
||
|
};
|
||
|
sb.endBlock = function (s) {
|
||
|
this.indent = this.indent.substr(0, this.indent.length - this.indentSize.length);
|
||
|
this.newLine();
|
||
|
this.push(s);
|
||
|
};
|
||
|
sb.newLine = function (s) {
|
||
|
this.push("\n");
|
||
|
this.push(this.indent);
|
||
|
};
|
||
|
Q.stringifyFormatted2(obj, sb);
|
||
|
return sb.join("");
|
||
|
}
|
||
|
Q.stringifyFormatted2 = function (obj, sb) {
|
||
|
var type = typeof (obj);
|
||
|
if (type == "object") {
|
||
|
if (obj instanceof Array) {
|
||
|
var list = obj;
|
||
|
if (list.length == 0 || ["string", "number"].contains(typeof (list[0]))) {
|
||
|
sb.push("[");
|
||
|
list.forEach(function (t, i) {
|
||
|
Q.stringifyFormatted2(t, sb);
|
||
|
if (i < list.length - 1)
|
||
|
sb.push(",");
|
||
|
});
|
||
|
sb.push("]");
|
||
|
}
|
||
|
else {
|
||
|
sb.startBlock("[");
|
||
|
for (var i = 0; i < list.length; i++) {
|
||
|
Q.stringifyFormatted2(list[i], sb);
|
||
|
if (i < list.length - 1) {
|
||
|
sb.push(",");
|
||
|
sb.newLine();
|
||
|
}
|
||
|
}
|
||
|
sb.endBlock("]");
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
sb.startBlock("{");
|
||
|
var first = true;
|
||
|
for (var p in obj) {
|
||
|
if (first)
|
||
|
first = false;
|
||
|
else {
|
||
|
sb.push(",");
|
||
|
sb.newLine();
|
||
|
}
|
||
|
sb.push(p + ": ");
|
||
|
Q.stringifyFormatted2(obj[p], sb);
|
||
|
}
|
||
|
sb.endBlock("}");
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
sb.push(JSON.stringify(obj));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///<summary>Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback)</summary>
|
||
|
Array.prototype.forEachAsyncProgressive = function (actionWithCallback, finalCallback) {
|
||
|
this._forEachAsyncProgressive(actionWithCallback, finalCallback, 0);
|
||
|
}
|
||
|
|
||
|
Array.prototype.where = function (predicate) {
|
||
|
return this.filter(Q.createSelectorFunction(predicate));
|
||
|
}
|
||
|
Array.prototype.addRange = function (items) {
|
||
|
this.push.apply(this, items);
|
||
|
}
|
||
|
|
||
|
Array.prototype.add = Array.prototype.push;
|
||
|
Array.prototype.diff = function (target) {
|
||
|
var source = this;
|
||
|
var res = {
|
||
|
added: source.where(function (t) { return !target.contains(t); }),
|
||
|
removed: target.where(function (t) { return !source.contains(t); }),
|
||
|
};
|
||
|
return res;
|
||
|
}
|
||
|
Array.prototype.hasDiff = function (target) {
|
||
|
var diff = this.diff(target);
|
||
|
return diff.added.length > 0 || diff.removed.length > 0;
|
||
|
}
|
||
|
|
||
|
Array.prototype._forEachAsyncProgressive = function (actionWithCallback, finalCallback, index) {
|
||
|
if (index == null)
|
||
|
index = 0;
|
||
|
if (index >= this.length) {
|
||
|
if (finalCallback != null)
|
||
|
finalCallback();
|
||
|
return;
|
||
|
}
|
||
|
var item = this[index];
|
||
|
actionWithCallback(item, function () { this._forEachAsyncProgressive(actionWithCallback, finalCallback, index + 1); }.bind(this));
|
||
|
}
|
||
|
|
||
|
|
||
|
/// Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback)
|
||
|
Array.prototype.mapAsyncProgressive = function (actionWithCallback, finalCallback) {
|
||
|
this._mapAsyncProgressive(actionWithCallback, finalCallback, 0, []);
|
||
|
}
|
||
|
|
||
|
Array.prototype._mapAsyncProgressive = function (actionWithCallbackWithResult, finalCallback, index, results) {
|
||
|
if (index == null)
|
||
|
index = 0;
|
||
|
if (index >= this.length) {
|
||
|
if (finalCallback != null)
|
||
|
finalCallback(results);
|
||
|
return;
|
||
|
}
|
||
|
var item = this[index];
|
||
|
actionWithCallbackWithResult(item, function (res) {
|
||
|
results.push(res);
|
||
|
this._mapAsyncProgressive(actionWithCallbackWithResult, finalCallback, index + 1, results);
|
||
|
}.bind(this));
|
||
|
}
|
||
|
|
||
|
Array.prototype.mapWith = function (anotherList, funcForTwoItems) {
|
||
|
if (funcForTwoItems == null)
|
||
|
funcForTwoItems = function (x, y) { return [x, y]; };
|
||
|
var list = [];
|
||
|
var maxLength = Math.max(this.length, anotherList.length);
|
||
|
for (var i = 0; i < maxLength; i++)
|
||
|
list.push(funcForTwoItems(this[i], anotherList[i]));
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Array.prototype.min = function () {
|
||
|
var min = null;
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
var value = this[i];
|
||
|
if (min==null || value < min)
|
||
|
min = value;
|
||
|
}
|
||
|
return min;
|
||
|
}
|
||
|
|
||
|
Array.prototype.max = function () {
|
||
|
var max = null;
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
var value = this[i];
|
||
|
if (max == null || value > max)
|
||
|
max = value;
|
||
|
}
|
||
|
return max;
|
||
|
}
|
||
|
|
||
|
Array.prototype.getEnumerator = function () {
|
||
|
return new ArrayEnumerator(this);
|
||
|
}
|
||
|
|
||
|
var ArrayEnumerator = function (list) {
|
||
|
this.index = -1;
|
||
|
this.list = list;
|
||
|
}
|
||
|
|
||
|
ArrayEnumerator.prototype.moveNext = function () {
|
||
|
if (this.index == -2)
|
||
|
throw new Error("End of array");
|
||
|
this.index++;
|
||
|
if (this.index >= this.list.length) {
|
||
|
this.index = -2;
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
ArrayEnumerator.prototype.getCurrent = function () {
|
||
|
if (this.index < 0)
|
||
|
throw new Error("Invalid array position");
|
||
|
return this.list[this.index];
|
||
|
}
|
||
|
|
||
|
String.prototype.endsWith = function (suffix) {
|
||
|
return this.indexOf(suffix, this.length - suffix.length) !== -1;
|
||
|
};
|
||
|
|
||
|
var Comparer = function () {
|
||
|
|
||
|
}
|
||
|
Comparer.prototype.compare = function (x, y) {
|
||
|
if (x > y)
|
||
|
return 1;
|
||
|
if (x < y)
|
||
|
return -1;
|
||
|
return 0;
|
||
|
}
|
||
|
Comparer.default = new Comparer();
|
||
|
|
||
|
function combineCompareFuncs(compareFuncs) {
|
||
|
return function (a, b) {
|
||
|
var count = compareFuncs.length;
|
||
|
for (var i = 0; i < count; i++) {
|
||
|
var compare = compareFuncs[i];
|
||
|
var x = compare(a, b);
|
||
|
if (x != 0)
|
||
|
return x;
|
||
|
}
|
||
|
return 0;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function createCompareFuncFromSelector(selector, desc) {
|
||
|
desc = desc ? -1 : 1;
|
||
|
var compare = Comparer.default.compare;
|
||
|
var type = typeof (selector);
|
||
|
if (type == "string" || type == "number") {
|
||
|
return function (x, y) {
|
||
|
return compare(x[selector], y[selector]) * desc;
|
||
|
};
|
||
|
}
|
||
|
return function (x, y) {
|
||
|
return compare(selector(x), selector(y)) * desc;
|
||
|
};
|
||
|
}
|
||
|
Array.prototype.sortBy = function (selector, desc) {
|
||
|
var compareFunc;
|
||
|
if (selector instanceof Array) {
|
||
|
var pairs = selector;
|
||
|
var funcs = pairs.map(function (pair) {
|
||
|
if (pair instanceof Array)
|
||
|
return createSortFuncFromCompareFunc(pair[0], pair[1]);
|
||
|
return createCompareFuncFromSelector(pair);
|
||
|
});
|
||
|
compareFunc = combineCompareFuncs(funcs);
|
||
|
}
|
||
|
else {
|
||
|
compareFunc = createCompareFuncFromSelector(selector, desc);
|
||
|
}
|
||
|
this.sort(compareFunc);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
Array.prototype.sortByDescending = function (selector) {
|
||
|
return this.sortBy(selector, true);
|
||
|
}
|
||
|
String.prototype.startsWith = function (s) {
|
||
|
return this.indexOf(s) == 0;
|
||
|
}
|
||
|
|
||
|
//Performs an async function on each item in the array, invoking a finalCallback when all are completed
|
||
|
//asyncFunc -> function(item, callback -> function(result))
|
||
|
//finalCallback -> function(results);
|
||
|
Array.prototype.mapAsyncParallel = function (asyncFunc, finalCallback) {
|
||
|
var results = [];
|
||
|
var length = this.length;
|
||
|
if (length == 0) {
|
||
|
finalCallback(results);
|
||
|
return;
|
||
|
}
|
||
|
var cb = function (res) {
|
||
|
results.push(res);
|
||
|
if (results.length == length)
|
||
|
finalCallback(results);
|
||
|
};
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
var item = this[i];
|
||
|
asyncFunc(item, cb);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
Array.prototype.clear = function () {
|
||
|
this.splice(0, this.length);
|
||
|
}
|
||
|
|
||
|
|
||
|
var Timer = function (action, ms) {
|
||
|
this.action = action;
|
||
|
if(ms!=null)
|
||
|
this.set(ms);
|
||
|
}
|
||
|
|
||
|
Timer.prototype.set = function (ms) {
|
||
|
if(ms==null)
|
||
|
ms = this._ms;
|
||
|
else
|
||
|
this._ms = ms;
|
||
|
this.clear();
|
||
|
if(ms==null)
|
||
|
return;
|
||
|
this.timeout = window.setTimeout(this.onTick.bind(this), ms);
|
||
|
}
|
||
|
|
||
|
Timer.prototype.onTick = function () {
|
||
|
this.clear();
|
||
|
this.action();
|
||
|
}
|
||
|
|
||
|
Timer.prototype.clear = function (ms) {
|
||
|
if (this.timeout == null)
|
||
|
return;
|
||
|
window.clearTimeout(this.timeout);
|
||
|
this.timeout = null;
|
||
|
}
|
||
|
|
||
|
Array.prototype.itemsEqual = function (list) {
|
||
|
if (list == this)
|
||
|
return true;
|
||
|
if (list.length != this.length)
|
||
|
return false;
|
||
|
for (var i = 0; i < this.length; i++)
|
||
|
if (this[i] != list[i])
|
||
|
return false;
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
Number.prototype.format = function (format) {
|
||
|
var s = this.toString();
|
||
|
for (var i = 0; i < format.length; i++) {
|
||
|
var ch = format.charAt(i);
|
||
|
if (ch == "0") {
|
||
|
if (s.length < i + 1)
|
||
|
s = "0" + s;
|
||
|
}
|
||
|
else
|
||
|
throw new Error("not implemented");
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* ReplaceAll by Fagner Brack (MIT Licensed)
|
||
|
* Replaces all occurrences of a substring in a string
|
||
|
*/
|
||
|
String.prototype.replaceAll = function (token, newToken, ignoreCase) {
|
||
|
var _token;
|
||
|
var str = this + "";
|
||
|
var i = -1;
|
||
|
|
||
|
if (typeof token === "string") {
|
||
|
|
||
|
if (ignoreCase) {
|
||
|
|
||
|
_token = token.toLowerCase();
|
||
|
|
||
|
while ((
|
||
|
i = str.toLowerCase().indexOf(
|
||
|
token, i >= 0 ? i + newToken.length : 0
|
||
|
)) !== -1
|
||
|
) {
|
||
|
str = str.substring(0, i) +
|
||
|
newToken +
|
||
|
str.substring(i + token.length);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
return this.split(token).join(newToken);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
return str;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* Date extensions, taken from jsclr framework */
|
||
|
Date.new = function (y, m, d, h, mm, s, ms) {
|
||
|
if (ms != null)
|
||
|
return new Date(y, m - 1, d, h, mm, s, ms);
|
||
|
if (s != null)
|
||
|
return new Date(y, m - 1, d, h, mm, s);
|
||
|
if (mm != null)
|
||
|
return new Date(y, m - 1, d, h, mm);
|
||
|
if (h != null)
|
||
|
return new Date(y, m - 1, d, h);
|
||
|
if (d != null)
|
||
|
return new Date(y, m - 1, d);
|
||
|
if (m != null)
|
||
|
return new Date(y, m - 1);
|
||
|
if (y != null)
|
||
|
return new Date(y);
|
||
|
var x = new Date(0);
|
||
|
x.setHours(0, 0, 0, 0);
|
||
|
return x;
|
||
|
}
|
||
|
Date.prototype.compareTo = function (value) {
|
||
|
return this.valueOf() - value.valueOf();
|
||
|
};
|
||
|
Date.prototype.year = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCFullYear();
|
||
|
return this.getFullYear();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCFullYear(value);
|
||
|
else
|
||
|
this.setFullYear(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.totalDays = function () {
|
||
|
return this.valueOf() / (24 * 60 * 60 * 1000);
|
||
|
};
|
||
|
Date.prototype.totalHours = function () {
|
||
|
return this.valueOf() / (60 * 60 * 1000);
|
||
|
};
|
||
|
|
||
|
Date.prototype.month = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCMonth() + 1;
|
||
|
return this.getMonth() + 1;
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCMonth(value - 1);
|
||
|
else
|
||
|
this.setMonth(value - 1);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.day = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCDate();
|
||
|
return this.getDate();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCDate(value);
|
||
|
else
|
||
|
this.setDate(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.hour = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCHours();
|
||
|
return this.getHours();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCHours(value);
|
||
|
else
|
||
|
this.setHours(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.minute = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCMinutes();
|
||
|
return this.getMinutes();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCMinutes(value);
|
||
|
else
|
||
|
this.setMinutes(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.second = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCSeconds();
|
||
|
return this.getSeconds();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCSeconds(value);
|
||
|
else
|
||
|
this.setSeconds(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.ms = function (value) {
|
||
|
if (value == null) {
|
||
|
if (this._Kind == 1)
|
||
|
return this.getUTCMilliseconds();
|
||
|
return this.getMilliseconds();
|
||
|
}
|
||
|
if (this._Kind == 1)
|
||
|
this.setUTCMilliseconds(value);
|
||
|
else
|
||
|
this.setMilliseconds(value);
|
||
|
return this;
|
||
|
};
|
||
|
Date.prototype.toUnix = function () {
|
||
|
if (this._Kind == 1)
|
||
|
throw new Error();
|
||
|
return Math.round(this.getTime() / 1000);
|
||
|
};
|
||
|
Date.fromUnix = function (value) {
|
||
|
return new Date(value * 1000);
|
||
|
};
|
||
|
|
||
|
Date.prototype.dayOfWeek = function () {
|
||
|
return this.getDay()+1;
|
||
|
};
|
||
|
Date.prototype.toLocalTime = function () {
|
||
|
if (this._Kind != 1)
|
||
|
return this;
|
||
|
var x = this.clone();
|
||
|
x._Kind = 2;
|
||
|
return x;
|
||
|
};
|
||
|
Date.prototype.toUniversalTime = function () {
|
||
|
if (this._Kind == 1)
|
||
|
return this;
|
||
|
var x = this.clone();
|
||
|
x._Kind = 1;
|
||
|
return x;
|
||
|
};
|
||
|
Date.today = function () {
|
||
|
return new Date().removeTime();
|
||
|
};
|
||
|
//Date.now = function () {
|
||
|
// return new Date();
|
||
|
//};
|
||
|
Date.prototype.subtract = function (date) {
|
||
|
var diff = this.valueOf() - date.valueOf();
|
||
|
return new Date(diff);
|
||
|
};
|
||
|
Date.prototype.Subtract$$DateTime = function (value) {
|
||
|
var diff = this.valueOf() - value.valueOf();
|
||
|
return new System.TimeSpan.ctor$$Int64(diff * 10000);
|
||
|
};
|
||
|
Date.prototype.Subtract$$TimeSpan = function (value) {
|
||
|
var newDate = this.clone();
|
||
|
newDate.setMilliseconds(this.getMilliseconds() + value.getTotalMilliseconds());
|
||
|
return newDate;
|
||
|
};
|
||
|
Date.prototype.format = function (format) {
|
||
|
if (typeof (format) == "object") {
|
||
|
var options = format;
|
||
|
if (options.noTime!=null && !this.hasTime())
|
||
|
return this.format(options.noTime);
|
||
|
else if (options.noDate!=null && !this.hasDate())
|
||
|
return this.format(options.noDate);
|
||
|
else if (options.fallback!=null)
|
||
|
return this.format(options.fallback);
|
||
|
return this.toString();
|
||
|
}
|
||
|
var s = format;
|
||
|
s = s.replaceAll("yyyy", this.year().format("0000"));
|
||
|
s = s.replaceAll("yy", this.year().format("00").truncateStart(2));
|
||
|
s = s.replaceAll("y", this.year().toString());
|
||
|
s = s.replaceAll("MM", this.month().format("00"));
|
||
|
s = s.replaceAll("M", this.month().toString());
|
||
|
s = s.replaceAll("dd", this.day().format("00"));
|
||
|
s = s.replaceAll("d", this.day().toString());
|
||
|
s = s.replaceAll("HH", this.hour().format("00"));
|
||
|
s = s.replaceAll("H", this.hour().toString());
|
||
|
s = s.replaceAll("mm", this.minute().format("00"));
|
||
|
s = s.replaceAll("m", this.minute().toString());
|
||
|
s = s.replaceAll("ss", this.second().format("00"));
|
||
|
s = s.replaceAll("s", this.second().toString());
|
||
|
return s.toString();
|
||
|
};
|
||
|
String.prototype.truncateEnd = function (finalLength) {
|
||
|
if (this.length > finalLength)
|
||
|
return this.substr(0, finalLength);
|
||
|
return this;
|
||
|
}
|
||
|
String.prototype.truncateStart = function (finalLength) {
|
||
|
if (this.length > finalLength)
|
||
|
return this.substr(this.length-finalLength);
|
||
|
return this;
|
||
|
}
|
||
|
String.prototype.remove = function (index, length) {
|
||
|
var s = this.substr(0, index);
|
||
|
s += this.substr(index + length);
|
||
|
return s;
|
||
|
}
|
||
|
String.prototype.insert = function (index, text) {
|
||
|
var s = this.substr(0, index);
|
||
|
s += text;
|
||
|
s += this.substr(index);
|
||
|
return s;
|
||
|
}
|
||
|
String.prototype.replaceAt = function (index, length, text) {
|
||
|
return this.remove(index, length).insert(index, text);
|
||
|
}
|
||
|
String.prototype.padRight = function (totalWidth, paddingChar) {
|
||
|
if (paddingChar == null || paddingChar == "")
|
||
|
paddingChar = " ";
|
||
|
var s = this;
|
||
|
while (s.length < totalWidth)
|
||
|
s += paddingChar;
|
||
|
return s;
|
||
|
}
|
||
|
String.prototype.padLeft = function (totalWidth, paddingChar) {
|
||
|
if (paddingChar == null || paddingChar == "")
|
||
|
paddingChar = " ";
|
||
|
var s = this;
|
||
|
while (s.length < totalWidth)
|
||
|
s = paddingChar + s;
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
Date._parsePart = function (ctx, part, setter) {
|
||
|
if (ctx.failed)
|
||
|
return;
|
||
|
var index = ctx.format.indexOf(part);
|
||
|
if (index < 0)
|
||
|
return;
|
||
|
var token = ctx.s.substr(index, part.length);
|
||
|
if (token.length == 0) {
|
||
|
ctx.failed = true;
|
||
|
return;
|
||
|
}
|
||
|
var value = Q.parseInt(token);
|
||
|
if (value == null) {
|
||
|
ctx.failed = true;
|
||
|
return;
|
||
|
}
|
||
|
setter.call(ctx.date, value);
|
||
|
ctx.format = ctx.format.replaceAt(index, part.length, "".padRight(part.length));
|
||
|
ctx.s = ctx.s.replaceAt(index, part.length, "".padRight(part.length));
|
||
|
}
|
||
|
Date.tryParseExact = function (s, formats) {
|
||
|
if (typeof (formats) == "string")
|
||
|
formats = [formats];
|
||
|
for (var i = 0; i < formats.length; i++) {
|
||
|
var x = Date._tryParseExact(s, formats[i]);
|
||
|
if (x != null)
|
||
|
return x;
|
||
|
}
|
||
|
return null;
|
||
|
};
|
||
|
Date._tryParseExact = function (s, format) {
|
||
|
if (s.length != format.length)
|
||
|
return null;
|
||
|
var date = Date.new();
|
||
|
var ctx = { date: date, s: s, format: format };
|
||
|
Date._parsePart(ctx, "yyyy", date.year);
|
||
|
Date._parsePart(ctx, "yy", date.year);
|
||
|
Date._parsePart(ctx, "MM", date.month);
|
||
|
Date._parsePart(ctx, "dd", date.day);
|
||
|
Date._parsePart(ctx, "HH", date.hour);
|
||
|
Date._parsePart(ctx, "mm", date.minute);
|
||
|
Date._parsePart(ctx, "ss", date.second);
|
||
|
if (ctx.failed)
|
||
|
return null;
|
||
|
if (ctx.s != ctx.format)
|
||
|
return null;
|
||
|
return ctx.date;
|
||
|
};
|
||
|
Date.prototype.clone = function () {
|
||
|
var x = new Date(this.valueOf());
|
||
|
x._Kind = this._Kind;
|
||
|
return x;
|
||
|
};
|
||
|
Date.prototype.addMs = function (miliseconds) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setMilliseconds(date2.getMilliseconds() + miliseconds);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addSeconds = function (seconds) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setSeconds(date2.getSeconds() + seconds);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addMinutes = function (minutes) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setMinutes(date2.getMinutes() + minutes);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addHours = function (hours) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setHours(date2.getHours() + hours);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addDays = function (days) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setDate(date2.getDate() + days);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addMonths = function (months) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setMonth(date2.getMonth() + months);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.addYears = function (years) {
|
||
|
var date2 = this.clone();
|
||
|
date2.setMonth(date2.getFullYear() + years);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.removeTime = function () {
|
||
|
var date2 = this.clone();
|
||
|
date2.setHours(0, 0, 0, 0);
|
||
|
return date2;
|
||
|
};
|
||
|
Date.prototype.hasTime = function () {
|
||
|
return this.hour() != 0 && this.second() != 0 && this.ms() != 0;
|
||
|
};
|
||
|
Date.prototype.hasDate = function () {
|
||
|
var date2 = new Date(0);
|
||
|
return this.year() != date2.year() && this.month() != date2.month() && this.day() != date2.day();
|
||
|
};
|
||
|
Date.prototype.removeDate = function () {
|
||
|
var time = this.clone();
|
||
|
time.setHours(this.hour(), this.minute(), this.second(), this.ms());
|
||
|
return time;
|
||
|
};
|
||
|
Date.prototype.extractTime = function () {
|
||
|
return this.removeDate();
|
||
|
};
|
||
|
Date.prototype.extractDate = function () {
|
||
|
return this.removeTime();
|
||
|
};
|
||
|
Date.prototype.equals = function (obj) {
|
||
|
if (obj == null)
|
||
|
return false;
|
||
|
return obj.valueOf() == this.valueOf();
|
||
|
};
|
||
|
Date.prototype.GetHashCode = function () {
|
||
|
return this.valueOf();
|
||
|
};
|
||
|
Date.prototype.getKind = function () {
|
||
|
if (this._Kind == null)
|
||
|
return 2;
|
||
|
return this._Kind;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/* Binds all function on an object to the object, so the 'this' context will be reserved even if referencing the function alone */
|
||
|
Q.bindFunctions = function (obj) {
|
||
|
for (var p in obj) {
|
||
|
var func = obj[p];
|
||
|
if (typeof (func) != "function")
|
||
|
continue;
|
||
|
if (func.boundTo == obj)
|
||
|
continue;
|
||
|
func = func.bind(obj);
|
||
|
func.boundTo = obj;
|
||
|
if (func.name == null)
|
||
|
func.name = p;
|
||
|
obj[p] = func;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Similar to func.apply(thisContext, args), but creates a new object instead of just calling the function - new func(args[0], args[1], args[2]...)
|
||
|
Function.prototype.applyNew = function (args) {
|
||
|
var args2 = args.toArray();
|
||
|
args2.insert(0, null);
|
||
|
var ctor2 = this.bind.apply(this, args2);
|
||
|
var obj = new ctor2();
|
||
|
return obj;
|
||
|
}
|
||
|
// Similar to func.call(thisContext, args), but creates a new object instead of just calling the function - new func(arguments[0], arguments[1], arguments[2]...)
|
||
|
Function.prototype.callNew = function (varargs) {
|
||
|
var args2 = Array.prototype.slice.call(arguments);
|
||
|
args2.insert(0, null);
|
||
|
var ctor2 = this.bind.apply(this, args2);
|
||
|
var obj = new ctor2();
|
||
|
return obj;
|
||
|
}
|
||
|
|
||
|
Error.prototype.wrap = function (e) {
|
||
|
e.innerError = this;
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
Error.prototype.causedBy = function (e) {
|
||
|
this.innerError = e;
|
||
|
}
|
||
|
|
||
|
Q.parseInt = function(s){
|
||
|
var intRegex = /^[+-]?[0-9]+$/;
|
||
|
if (!intRegex.test(s))
|
||
|
return null;
|
||
|
var x = parseInt(s);
|
||
|
if (isNaN(x))
|
||
|
return null;
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
Q.parseFloat = function (s) {
|
||
|
var floatRegex = /^[+-]?[0-9]*[\.]?[0-9]*$/;
|
||
|
if (!floatRegex.test(s))
|
||
|
return null;
|
||
|
var x = parseFloat(s);
|
||
|
if (isNaN(x))
|
||
|
return null;
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
Number.prototype.round = function (decimals) {
|
||
|
if (decimals) {
|
||
|
var x = Math.pow(10, decimals);
|
||
|
return Math.round(this * x) / x;
|
||
|
}
|
||
|
return Math.round(this);
|
||
|
}
|
||
|
Q.createSelectorFunction = function(selector){
|
||
|
if (selector == null)
|
||
|
return function (t) { return t; };
|
||
|
if (typeof (selector) == "function")
|
||
|
return selector;
|
||
|
return function (t) { return t[selector]; };
|
||
|
}
|
||
|
Array.prototype.select = function (selector) {
|
||
|
var func = Q.createSelectorFunction(selector);
|
||
|
return this.map(func);
|
||
|
}
|
||
|
|
||
|
Array.prototype.selectInvoke = function (name) {
|
||
|
return this.map(function (t) { return t[name](); });
|
||
|
}
|
||
|
|
||
|
Array.prototype.joinWith = function (list2, keySelector1, keySelector2, resultSelector) {
|
||
|
keySelector1 = Q.createSelectorFunction(keySelector1);
|
||
|
keySelector2 = Q.createSelectorFunction(keySelector2);
|
||
|
resultSelector = Q.createSelectorFunction(resultSelector);
|
||
|
|
||
|
var list1 = this;
|
||
|
|
||
|
var groups1 = list1.groupByToObject(keySelector1);
|
||
|
var groups2 = list2.groupByToObject(keySelector2);
|
||
|
|
||
|
var list = [];
|
||
|
var group = {};
|
||
|
for (var p in groups1) {
|
||
|
if(groups2[p]!=null)
|
||
|
list.push(resultSelector(groups1[p], groups2[p]));
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
Array.prototype.all = function (predicate) {
|
||
|
return this.every(Q.createSelectorFunction(predicate));
|
||
|
}
|
||
|
|
||
|
String.prototype.all = Array.prototype.all;
|
||
|
String.prototype.every = Array.prototype.every;
|
||
|
Array.prototype.flatten = function () {
|
||
|
var list = [];
|
||
|
this.forEach(function (t) {
|
||
|
list.addRange(t);
|
||
|
});
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Array.joinAll = function (lists, keySelector, resultSelector) {
|
||
|
keySelector = Q.createSelectorFunction(keySelector);
|
||
|
resultSelector = Q.createSelectorFunction(resultSelector);
|
||
|
|
||
|
var groupMaps = lists.map(function (list) {
|
||
|
return list.groupByToObject(keySelector);
|
||
|
});
|
||
|
|
||
|
var groupMap1 = groupMaps[0];
|
||
|
|
||
|
var list = [];
|
||
|
for (var p in groupMap1) {
|
||
|
if (groupMaps.all(p))
|
||
|
list.push(resultSelector(groupMaps.select(p)));
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Q.isNullOrEmpty = function (stringOrArray) {
|
||
|
return stringOrArray == null || stringOrArray.length == 0;
|
||
|
}
|
||
|
Q.isNotNullOrEmpty = function (stringOrArray) {
|
||
|
return stringOrArray != null && stringOrArray.length > 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
Array.prototype.selectToObject = function (keySelector, valueSelector) {
|
||
|
var obj = {};
|
||
|
if (valueSelector == null) {
|
||
|
var list = this.select(keySelector);
|
||
|
for (var i = 0; i < list.length; i++) {
|
||
|
var obj2 = this[i];
|
||
|
if (obj2 != null) {
|
||
|
if (obj2 instanceof Array) {
|
||
|
for (var i = 0; i < obj2.length; i++) {
|
||
|
obj[obj2[0]] = obj2[1];
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
Q.copy(obj2, obj, { overwrite: true });
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
var item = this[i];
|
||
|
obj[keySelector(item)] = valueSelector(item);
|
||
|
}
|
||
|
}
|
||
|
return obj;
|
||
|
}
|
||
|
Array.prototype.groupByToObject = function (keySelector, itemSelector) {
|
||
|
keySelector = Q.createSelectorFunction(keySelector);
|
||
|
itemSelector = Q.createSelectorFunction(itemSelector);
|
||
|
var obj = {};
|
||
|
for (var i = 0; i < this.length; i++) {
|
||
|
var item = this[i];
|
||
|
var key = keySelector(item);
|
||
|
if (obj[key] == null) {
|
||
|
obj[key] = [];
|
||
|
obj[key].key = key;
|
||
|
}
|
||
|
var value = itemSelector(item);
|
||
|
obj[key].push(value);
|
||
|
}
|
||
|
return obj;
|
||
|
}
|
||
|
Array.prototype.groupBy = function (keySelector, itemSelector) {
|
||
|
var groupsMap = this.groupByToObject(keySelector, itemSelector);
|
||
|
return Object.values(groupsMap);
|
||
|
}
|
||
|
|
||
|
Array.prototype.splitIntoChunksOf = function (countInEachChunk) {
|
||
|
var chunks = Math.ceil(this.length / countInEachChunk);
|
||
|
var list = [];
|
||
|
for(var i=0;i<this.length;i+=countInEachChunk){
|
||
|
list.push(this.slice(i, i+countInEachChunk));
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Array.prototype.avg = function () {
|
||
|
return this.sum() / this.length;
|
||
|
}
|
||
|
Array.prototype.selectMany = function (selector) {
|
||
|
var list = [];
|
||
|
this.select(selector).forEach(function (t) { t.forEach(function (x) { list.push(x); }); });
|
||
|
return list;
|
||
|
}
|
||
|
Array.prototype.sum = function () {
|
||
|
var sum = this[0];
|
||
|
for (var i = 1; i < this.length; i++)
|
||
|
sum += this[i];
|
||
|
return sum;
|
||
|
}
|
||
|
Array.prototype.skip = function (count) {
|
||
|
return this.slice(count);
|
||
|
}
|
||
|
Array.prototype.take = function (count) {
|
||
|
return this.slice(0, count);
|
||
|
}
|
||
|
|
||
|
Date.tryParseJsonDate = function (s) {
|
||
|
if (s.length == 26 && s[0] == "\"" && s[value.length - 1] == "\"") {
|
||
|
s = s.substr(1, 24);
|
||
|
}
|
||
|
if (s.length == 24 && /[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+:[0-9]+\.[0-9]+Z/.test(s)) {
|
||
|
var d = new Date(s);
|
||
|
if (!isNaN(d.valueOf()))
|
||
|
return d;
|
||
|
}
|
||
|
return null;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
var QueryString = function () {
|
||
|
|
||
|
}
|
||
|
|
||
|
QueryString.parse = function (url, obj, defaults) {
|
||
|
if(url==null)
|
||
|
url = window.location.href;
|
||
|
if (obj == null)
|
||
|
obj = {};
|
||
|
if (defaults == null)
|
||
|
defaults = {};
|
||
|
var index = url.indexOf("?");
|
||
|
if (index < 0)
|
||
|
return obj;
|
||
|
var parts = url.slice(url.indexOf('?') + 1).split('&');
|
||
|
$.map(parts, function (part) {
|
||
|
var keyval = part.split('=');
|
||
|
var key = keyval[0];
|
||
|
var eValue = keyval[1];
|
||
|
var value;
|
||
|
var currentValue = obj[key];
|
||
|
if (currentValue == null || currentValue == defaults[key]) {
|
||
|
value = decodeURIComponent(eValue);
|
||
|
obj[key] = value;
|
||
|
}
|
||
|
else if (currentValue instanceof Array || defaults[key] instanceof Array) {
|
||
|
if (currentValue == null) {
|
||
|
currentValue = [];
|
||
|
obj[key] = currentValue;
|
||
|
}
|
||
|
if (eValue != "") {
|
||
|
var items = eValue.split(",").select(function (item) { return decodeURIComponent(item); });
|
||
|
items.forEach(function (item) {
|
||
|
if (!currentValue.contains(item))
|
||
|
currentValue.add(item);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
else if (currentValue != null) {
|
||
|
value = decodeURIComponent(eValue);
|
||
|
obj[key] = value;
|
||
|
//value = decodeURIComponent(eValue);
|
||
|
//obj[key] = [currentValue, value];
|
||
|
}
|
||
|
});
|
||
|
return obj;
|
||
|
}
|
||
|
|
||
|
QueryString.stringify = function (obj) {
|
||
|
var sb = [];
|
||
|
QueryString.write(obj, sb);
|
||
|
return sb.join("&");
|
||
|
}
|
||
|
|
||
|
QueryString.write = function (obj, sb) {
|
||
|
for (var p in obj) {
|
||
|
var value = obj[p];
|
||
|
if (value instanceof Array) {
|
||
|
sb.push(p + "=" + value.select(function (item) { return encodeURIComponent(item); }).join(","));
|
||
|
}
|
||
|
else {
|
||
|
sb.push(p + "=" + encodeURIComponent(value));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var __hashKeyIndex = 0;
|
||
|
Object.getHashKey = function (obj) {
|
||
|
if (obj == null)
|
||
|
return null;
|
||
|
var x = obj.valueOf();
|
||
|
var type = typeof (x);
|
||
|
if (type == "number")
|
||
|
return x.toString();
|
||
|
if (type == "string")
|
||
|
return x;
|
||
|
if (x.__hashKey == null) {
|
||
|
x.__hashKey = "\0" + "_"+x.constructor.name+"_"+__hashKeyIndex++;
|
||
|
}
|
||
|
return x.__hashKey
|
||
|
}
|
||
|
var ValueOfEqualityComparer = function () {
|
||
|
|
||
|
}
|
||
|
|
||
|
ValueOfEqualityComparer.prototype.equals = function (x, y) {
|
||
|
if (x == y)
|
||
|
return true;
|
||
|
if (x == null || y == null)
|
||
|
return false;
|
||
|
return x.valueOf() == y.valueOf();
|
||
|
}
|
||
|
|
||
|
ValueOfEqualityComparer.prototype.getHashKey = function (x) {
|
||
|
return Object.getHashKey(x);
|
||
|
}
|
||
|
|
||
|
Number.prototype.isInt = function () {
|
||
|
return this | 0 === this;
|
||
|
}
|
||
|
Number.prototype.isFloat = function () {
|
||
|
return this | 0 !== this;
|
||
|
}
|
||
|
Number.generate = function (min, max, step) {
|
||
|
var list = [];
|
||
|
if(step==null)
|
||
|
step = 1;
|
||
|
for (var i = min; i <= max; i += step) {
|
||
|
list.push(i);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Object.jsonStringifyEquals = function (x, y) {
|
||
|
return JSON.stringify(x) == JSON.stringify(y);
|
||
|
}
|
||
|
|
||
|
Object.tryGet = function (obj, indexers) {
|
||
|
if (typeof (indexers) == "string")
|
||
|
indexers = indexers.split(".");
|
||
|
var value = obj;
|
||
|
for (var i = 0; i < indexers.length; i++) {
|
||
|
if (value == null)
|
||
|
return null;
|
||
|
value = value[indexers[i]];
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
JSON.iterateRecursively = function (obj, action) {
|
||
|
if (obj == null || typeof(obj)!="object" || obj instanceof Date)
|
||
|
return;
|
||
|
|
||
|
if (obj instanceof Array) {
|
||
|
var list = obj;
|
||
|
list.forEach(function (item, index) {
|
||
|
action(obj, index, item);
|
||
|
JSON.iterateRecursively(item, action);
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
Object.keys(obj).forEach(function (key) {
|
||
|
var value = obj[key];
|
||
|
action(obj, key, value);
|
||
|
JSON.iterateRecursively(value, action);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Function._lambda_cache = {};
|
||
|
Function.lambda = function (exp) {
|
||
|
var cache = Function._lambda_cache;
|
||
|
var func = cache[exp];
|
||
|
if (func == null) {
|
||
|
func = Function._lambda(exp);
|
||
|
cache[exp] = func;
|
||
|
}
|
||
|
return func;
|
||
|
}
|
||
|
Function._lambda = function (exp) {
|
||
|
var arrow = exp.indexOf("=>");
|
||
|
var prms;
|
||
|
var body;
|
||
|
if (arrow > 0) {
|
||
|
var tPrms = exp.substring(0, arrow).replace("(", "").replace(")", "");
|
||
|
prms = tPrms.split(",").map(function (t) { return t.trim(); });
|
||
|
body = exp.substring(arrow + 2);
|
||
|
}
|
||
|
else {
|
||
|
prms = [];
|
||
|
body = exp;
|
||
|
}
|
||
|
if (!body.contains("return"))
|
||
|
body = "return " + body+";";
|
||
|
prms.push(body);
|
||
|
return Function.applyNew(prms);
|
||
|
}
|
||
|
String.prototype.toLambda = function () {
|
||
|
return Function.lambda(this);
|
||
|
}
|
||
|
Array.generateNumbers = function (from, until) {
|
||
|
if (arguments.length == 1) {
|
||
|
until = from;
|
||
|
from = 0;
|
||
|
}
|
||
|
var length = until - from;
|
||
|
var list = new Array(length);
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
list[i] = i + from;
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
Array.prototype.removeNulls = function () {
|
||
|
return this.removeAll(function (t) { return t != null; });
|
||
|
}
|
||
|
|
||
|
Array.prototype.exceptNulls = function () {
|
||
|
return this.where(function (t) { return t != null; });
|
||
|
}
|
||
|
|
||
|
Number.prototype.inRangeInclusive = function (min, max) {
|
||
|
return this >= min && this <= max;
|
||
|
}
|
||
|
Array.generate = function (length, generator) {
|
||
|
var list = new Array(length);
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
list[i] = generator(i);
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
Math.randomInt = function(min, max){
|
||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||
|
}
|
||
|
Array.prototype.random = function(){
|
||
|
return this[Math.randomInt(0, this.length-1)];
|
||
|
}
|
||
|
|
||
|
String.prototype.substringBetween = function(start, end){
|
||
|
var s = this;
|
||
|
var i1 = s.indexOf(start);
|
||
|
if(i1<0)
|
||
|
return null;
|
||
|
var i2 = s.indexOf(end, i1+1);
|
||
|
if(i2<0)
|
||
|
return null;
|
||
|
return s.substring(i1+start.length, i2);
|
||
|
}
|
||
|
|