Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/utils/lib/util.js
diff options
context:
space:
mode:
Diffstat (limited to 'utils/lib/util.js')
-rwxr-xr-xutils/lib/util.js864
1 files changed, 0 insertions, 864 deletions
diff --git a/utils/lib/util.js b/utils/lib/util.js
deleted file mode 100755
index 510e322..0000000
--- a/utils/lib/util.js
+++ /dev/null
@@ -1,864 +0,0 @@
-
-// a decorator for functions that curry "polymorphically",
-// that is, that return a function that can be tested
-// against various objects if they're only "partially
-// completed", or fewer arguments than needed are used.
-//
-// this enables the idioms:
-// [1, 2, 3].every(lt(4)) eq true
-// [1, 2, 3].map(add(1)) eq [2, 3, 4]
-// [{}, {}, {}].forEach(set('a', 10))
-//
-exports.operator = function (name, length, block) {
- var operator = function () {
- var args = exports.array(arguments);
- var completion = function (object) {
- if (
- typeof object == "object" &&
- object !== null && // seriously? typeof null == "object"
- name in object && // would throw if object === null
- // not interested in literal objects:
- !Object.prototype.hasOwnProperty.call(object, name)
- )
- return object[name].apply(object, args);
- return block.apply(
- this,
- [object].concat(args)
- );
- };
- if (arguments.length < length) {
- // polymoprhic curry, delayed completion
- return completion;
- } else {
- // immediate completion
- return completion.call(this, args.shift());
- }
- };
- operator.name = name;
- operator.displayName = name;
- operator.length = length;
- operator.operator = block;
- return operator;
-};
-
-exports.no = function (value) {
- return value === null || value === undefined;
-};
-
-// object
-
-exports.object = exports.operator('object', 1, function (object) {
- var items = object;
- if (!items.length)
- items = exports.items(object);
- var copy = {};
- for (var i = 0; i < items.length; i++) {
- var item = items[i];
- var key = item[0];
- var value = item[1];
- copy[key] = value;
- }
- return copy;
-});
-
-exports.object.copy = function (object) {
- var copy = {};
- exports.object.keys(object).forEach(function (key) {
- copy[key] = object[key];
- });
- return copy;
-};
-
-exports.object.deepCopy = function (object) {
- var copy = {};
- exports.object.keys(object).forEach(function (key) {
- copy[key] = exports.deepCopy(object[key]);
- });
- return copy;
-};
-
-exports.object.eq = function (a, b, stack) {
- return (
- !exports.no(a) && !exports.no(b) &&
- exports.array.eq(
- exports.sort(exports.object.keys(a)),
- exports.sort(exports.object.keys(b))
- ) &&
- exports.object.keys(a).every(function (key) {
- return exports.eq(a[key], b[key], stack);
- })
- );
-};
-
-exports.object.len = function (object) {
- return exports.object.keys(object).length;
-};
-
-exports.object.has = function (object, key) {
- return Object.prototype.hasOwnProperty.call(object, key);
-};
-
-exports.object.keys = function (object) {
- var keys = [];
- for (var key in object) {
- if (exports.object.has(object, key))
- keys.push(key);
- }
- return keys;
-};
-
-exports.object.values = function (object) {
- var values = [];
- exports.object.keys(object).forEach(function (key) {
- values.push(object[key]);
- });
- return values;
-};
-
-exports.object.items = function (object) {
- var items = [];
- exports.object.keys(object).forEach(function (key) {
- items.push([key, object[key]]);
- });
- return items;
-};
-
-exports.object.update = function (target, source) {
- for (var key in source) {
- if (exports.object.has(source, key)) {
- target[key] = source[key];
- }
- }
-};
-
-exports.object.complete = function (target, source) {
- for (var key in source) {
- if (
- exports.object.has(source, key) &&
- !exports.object.has(target, key)
- ) {
- target[key] = source[key];
- }
- }
-};
-
-exports.object.repr = function (object) {
- return "{" +
- exports.object.keys(object)
- .map(function (key) {
- return exports.enquote(key) + ": " +
- exports.repr(object[key]);
- }).join(", ") +
- "}";
-};
-
-// array
-
-exports.array = function (array) {
- if (!exports.isArrayLike(array))
- return exports.items(array);
- return Array.prototype.slice.call(array);
-};
-
-exports.isArrayLike = function(object) {
- return object &&
- typeof object === "object" &&
- (
- object.constructor === Array ||
- typeof object.callee !== "undefined"
- );
-};
-
-exports.array.copy = exports.array;
-
-exports.array.deepCopy = function (array) {
- return array.map(exports.deepCopy);
-};
-
-exports.array.len = function (array) {
- return array.length;
-};
-
-exports.array.has = function (array, value) {
- return Array.prototype.indexOf.call(array, value) >= 0;
-};
-
-exports.array.put = function (array, key, value) {
- array.splice(key, 0, value);
- return array;
-};
-
-exports.array.del = function (array, begin, end) {
- array.splice(begin, end === undefined ? 1 : (end - begin));
- return array;
-};
-
-exports.array.eq = function (a, b, stack) {
- return exports.isArrayLike(b) &&
- a.length == b.length &&
- exports.zip(a, b).every(exports.apply(function (a, b) {
- return exports.eq(a, b, stack);
- }));
-};
-
-exports.array.lt = function (a, b) {
- var length = Math.max(a.length, b.length);
- for (var i = 0; i < length; i++)
- if (!exports.eq(a[i], b[i]))
- return exports.lt(a[i], b[i]);
- return false;
-};
-
-exports.array.repr = function (array) {
- return "[" + exports.map(array, exports.repr).join(', ') + "]";
-};
-
-exports.apply = exports.operator('apply', 2, function (args, block) {
- return block.apply(this, args);
-});
-
-exports.copy = exports.operator('copy', 1, function (object) {
- if (exports.no(object))
- return object;
- if (exports.isArrayLike(object))
- return exports.array.copy(object);
- if (typeof object == 'object')
- return exports.object.copy(object);
- return object;
-});
-
-exports.deepCopy = exports.operator('deepCopy', 1, function (object) {
- if (exports.no(object))
- return object;
- if (exports.isArrayLike(object))
- return exports.array.deepCopy(object);
- if (typeof object == 'object')
- return exports.object.deepCopy(object);
- return object;
-});
-
-exports.repr = exports.operator('repr', 1, function (object) {
- if (exports.no(object))
- return String(object);
- if (exports.isArrayLike(object))
- return exports.array.repr(object);
- if (typeof object == 'object')
- return exports.object.repr(object);
- if (typeof object == 'string')
- return exports.enquote(object);
- return object.toString();
-});
-
-exports.keys = exports.operator('keys', 1, function (object) {
- if (exports.isArrayLike(object))
- return exports.range(object.length);
- else if (typeof object == 'object')
- return exports.object.keys(object);
- return [];
-});
-
-exports.values = exports.operator('values', 1, function (object) {
- if (exports.isArrayLike(object))
- return exports.array(object);
- else if (typeof object == 'object')
- return exports.object.values(object);
- return [];
-});
-
-exports.items = exports.operator('items', 1, function (object) {
- if (exports.isArrayLike(object) || typeof object == "string")
- return exports.enumerate(object);
- else if (typeof object == 'object')
- return exports.object.items(object);
- return [];
-});
-
-exports.len = exports.operator('len', 1, function (object) {
- if (exports.isArrayLike(object))
- return exports.array.len(object);
- else if (typeof object == 'object')
- return exports.object.len(object);
-});
-
-exports.has = exports.operator('has', 2, function (object, value) {
- if (exports.isArrayLike(object))
- return exports.array.has(object, value);
- else if (typeof object == 'object')
- return exports.object.has(object, value);
- return false;
-});
-
-exports.get = exports.operator('get', 2, function (object, key, value) {
- if (typeof object == "string") {
- if (!typeof key == "number")
- throw new Error("TypeError: String keys must be numbers");
- if (!exports.has(exports.range(object.length), key)) {
- if (arguments.length == 3)
- return value;
- throw new Error("KeyError: " + exports.repr(key));
- }
- return items.charAt(object);
- }
- if (typeof object == "object") {
- if (!exports.object.has(object, key)) {
- if (arguments.length == 3)
- return value;
- throw new Error("KeyError: " + exports.repr(key));
- }
- return object[key];
- }
- throw new Error("Object does not have keys: " + exports.repr(object));
-});
-
-exports.set = exports.operator('set', 3, function (object, key, value) {
- object[key] = value;
- return object;
-});
-
-exports.getset = exports.operator('getset', 3, function (object, key, value) {
- if (!exports.has(object, key))
- exports.set(object, key, value);
- return exports.get(object, key);
-});
-
-exports.del = exports.operator('del', 2, function (object, begin, end) {
- if (exports.isArrayLike(object))
- return exports.array.del(object, begin, end);
- delete object[begin];
- return object;
-});
-
-exports.cut = exports.operator('cut', 2, function (object, key) {
- var result = exports.get(object, key);
- exports.del(object, key);
- return result;
-});
-
-exports.put = exports.operator('put', 2, function (object, key, value) {
- if (exports.isArrayLike(object))
- return exports.array.put(object, key, value);
- return exports.set(object, key, value);
-});
-
-exports.update = exports.operator('update', 2, function (target, source) {
- exports.object.update(target, source);
-});
-
-exports.complete = exports.operator('complete', 2, function (target, source) {
- exports.object.complete(target, source);
-});
-
-// TODO insert
-// TODO remove
-// TODO discard
-
-exports.range = function () {
- var start = 0, stop = 0, step = 1;
- if (arguments.length == 1) {
- stop = arguments[0];
- } else if (arguments.length == 2) {
- start = arguments[0];
- stop = arguments[1];
- } else if (arguments.length == 3) {
- start = arguments[0];
- stop = arguments[1];
- step = arguments[2];
- }
- var range = [];
- for (var i = start; i < stop; i += step)
- range.push(i);
- return range;
-};
-
-exports.forEach = function (array, block) {
- Array.prototype.forEach.call(array, block);
-};
-
-exports.forEachApply = function (array, block) {
- Array.prototype.forEach.call(array, exports.apply(block));
-};
-
-exports.map = function (array, block, context) {
- return Array.prototype.map.call(array, block, context);
-};
-
-exports.mapApply = function (array, block) {
- return Array.prototype.map.call(array, exports.apply(block));
-};
-
-exports.every = exports.operator('every', 2, function (array, block, context) {
- return exports.all(exports.map(array, block, context));
-});
-
-exports.some = exports.operator('some', 2, function (array, block, context) {
- return exports.any(exports.map(array, block, context));
-});
-
-exports.all = exports.operator('all', 1, function (array) {
- for (var i = 0; i < array.length; i++)
- if (!array[i])
- return false;
- return true;
-});
-
-exports.any = exports.operator('all', 1, function (array) {
- for (var i = 0; i < array.length; i++)
- if (array[i])
- return true;
- return false;
-});
-
-exports.reduce = exports.operator('reduce', 2, function (array, block, basis) {
- return array.reduce.apply(array, arguments);
-});
-
-exports.reduceRight = exports.operator('reduceRight', 2, function (array, block, basis) {
- return array.reduceRight.apply(array, arguments);
-});
-
-exports.zip = function () {
- return exports.transpose(arguments);
-};
-
-exports.transpose = function (array) {
- var transpose = [];
- for (var i = 0; i < array.length; i++) {
- var row = array[i];
- for (var j = 0; j < row.length; j++) {
- var cell = row[j];
- if (!transpose[j])
- transpose[j] = [];
- transpose[j][i] = cell;
- }
- }
- return transpose;
-};
-
-exports.enumerate = function (array, start) {
- if (exports.no(start))
- start = 0;
- return exports.zip(
- exports.range(start, start + array.length),
- array
- );
-};
-
-// arithmetic, transitive, and logical operators
-
-exports.is = function (a, b) {
- return a === b;
-};
-
-exports.eq = exports.operator('eq', 2, function (a, b, stack) {
- if (!stack)
- stack = [];
- if (a === b)
- return true;
- if (typeof a !== typeof b)
- return false;
- if (exports.no(a))
- return exports.no(b);
- if (typeof a == "date")
- return a.valueOf() == b.valueOf();
- if (typeof a == "regexp")
- return a.source == b.source &&
- a.global == b.global &&
- a.ignoreCase == b.ignoreCase &&
- a.multiline == b.multiline;
- if (typeof a == "function") {
- var caller = stack[stack.length - 1];
- return caller !== Object &&
- typeof caller != "undefined";
- }
- if (exports.isArrayLike(a))
- return exports.array.eq(
- a, b,
- stack.concat([a.constructor])
- );
- if (typeof a == 'object')
- return exports.object.eq(
- a, b,
- stack.concat([a.constructor])
- );
- return a == b;
-});
-
-exports.ne = exports.operator('ne', 2, function (a, b) {
- return !exports.eq(a, b);
-});
-
-exports.lt = exports.operator('lt', 2, function (a, b) {
- if (exports.no(a) != exports.no(b))
- return exports.no(a) > exports.no(b);
- if (exports.isArrayLike(a) && exports.isArrayLike(b))
- return exports.array.lt(a, b);
- return a < b;
-});
-
-exports.gt = exports.operator('gt', 2, function (a, b) {
- return !(exports.lt(a, b) || exports.eq(a, b));
-});
-
-exports.le = exports.operator(2, 'le', function (a, b) {
- return exports.lt(a, b) || exports.eq(a, b);
-});
-
-exports.ge = exports.operator(2, 'ge', function (a, b) {
- return !exports.lt(a, b);
-});
-
-/*** by
- returns a `comparator` that compares
- values based on the values resultant from
- a given `relation`.
- accepts a `relation` and an optional comparator.
-
- To sort a list of objects based on their
- "a" key::
-
- objects.sort(by(get("a")))
-
- To get those in descending order::
-
- objects.sort(by(get("a")), desc)
-
- `by` returns a comparison function that also tracks
- the arguments you used to construct it. This permits
- `sort` and `sorted` to perform a Schwartzian transform
- which can increase the performance of the sort
- by a factor of 2.
-*/
-exports.by = function (relation) {
- var compare = arguments[1];
- if (exports.no(compare))
- compare = exports.compare;
- var comparator = function (a, b) {
- a = relation(a);
- b = relation(b);
- return compare(a, b);
- };
- comparator.by = relation;
- comparator.compare = compare;
- return comparator;
-};
-
-exports.compare = exports.operator(2, 'compare', function (a, b) {
- if (exports.no(a) != exports.no(b))
- return exports.no(b) - exports.no(a);
- if (typeof a == "number" && typeof b == "number")
- return a - b;
- return exports.eq(a, b) ? 0 : exports.lt(a, b) ? -1 : 1;
-});
-
-/*** sort
- an in-place array sorter that uses a deep comparison
- function by default (compare), and improves performance if
- you provide a comparator returned by "by", using a
- Schwartzian transform.
-*/
-exports.sort = function (array, compare) {
- if (exports.no(compare))
- compare = exports.compare;
- if (compare.by) {
- /* schwartzian transform */
- array.splice.apply(
- array,
- [0, array.length].concat(
- array.map(function (value) {
- return [compare.by(value), value];
- }).sort(function (a, b) {
- return exports.compare(a[0], b[0]);
- }).map(function (pair) {
- return pair[1];
- })
- )
- );
- } else {
- array.sort(compare);
- }
- return array;
-};
-
-/*** sorted
- returns a sorted copy of an array using a deep
- comparison function by default (compare), and
- improves performance if you provide a comparator
- returned by "by", using a Schwartzian transform.
-*/
-exports.sorted = function (array, compare) {
- return exports.sort(exports.array.copy(array), compare);
-};
-
-// string
-
-/*** escape
- escapes all characters of a string that are
- special to JavaScript and many other languages.
- Recognizes all of the relevant
- control characters and formats all other
- non-printable characters as Hex byte escape
- sequences or Unicode escape sequences depending
- on their size.
-
- Pass ``true`` as an optional second argument and
- ``escape`` produces valid contents for escaped
- JSON strings, wherein non-printable-characters are
- all escaped with the Unicode ``\u`` notation.
-*/
-/* more Steve Levithan flagrence */
-var escapeExpression = /[^ !#-[\]-~]/g;
-/* from Doug Crockford's JSON library */
-var escapePatterns = {
- '\b': '\\b', '\t': '\\t',
- '\n': '\\n', '\f': '\\f', '\r': '\\r',
- '"' : '\\"', '\\': '\\\\'
-};
-exports.escape = function (value, strictJson) {
- if (typeof value != "string")
- throw new Error(
- module.path +
- "#escape: requires a string. got " +
- exports.repr(value)
- );
- return value.replace(
- escapeExpression,
- function (match) {
- if (escapePatterns[match])
- return escapePatterns[match];
- match = match.charCodeAt();
- if (!strictJson && match < 256)
- return "\\x" + exports.padBegin(match.toString(16), 2);
- return '\\u' + exports.padBegin(match.toString(16), 4);
- }
- );
-};
-
-/*** enquote
- transforms a string into a string literal, escaping
- all characters of a string that are special to
- JavaScript and and some other languages.
-
- ``enquote`` uses double quotes to be JSON compatible.
-
- Pass ``true`` as an optional second argument to
- be strictly JSON compliant, wherein all
- non-printable-characters are represented with
- Unicode escape sequences.
-*/
-exports.enquote = function (value, strictJson) {
- return '"' + exports.escape(value, strictJson) + '"';
-};
-
-/*** expand
- transforms tabs to an equivalent number of spaces.
-*/
-// TODO special case for \r if it ever matters
-exports.expand = function (str, tabLength) {
- str = String(str);
- tabLength = tabLength || 4;
- var output = [],
- tabLf = /[\t\n]/g,
- lastLastIndex = 0,
- lastLfIndex = 0,
- charsAddedThisLine = 0,
- tabOffset, match;
- while (match = tabLf.exec(str)) {
- if (match[0] == "\t") {
- tabOffset = (
- tabLength - 1 -
- (
- (match.index - lastLfIndex) +
- charsAddedThisLine
- ) % tabLength
- );
- charsAddedThisLine += tabOffset;
- output.push(
- str.slice(lastLastIndex, match.index) +
- operator.mul(" ", tabOffset + 1)
- );
- } else if (match[0] === "\n") {
- output.push(str.slice(lastLastIndex, tabLf.lastIndex));
- lastLfIndex = tabLf.lastIndex;
- charsAddedThisLine = 0;
- }
- lastLastIndex = tabLf.lastIndex;
- }
- return output.join("") + str.slice(lastLastIndex);
-};
-
-var trimBeginExpression = /^\s\s*/g;
-exports.trimBegin = function (value) {
- return String(value).replace(trimBeginExpression, "");
-};
-
-var trimEndExpression = /\s\s*$/g;
-exports.trimEnd = function (value) {
- return String(value).replace(trimEndExpression, "");
-};
-
-exports.trim = function (value) {
- return String(value).replace(trimBeginExpression, "").replace(trimEndExpression, "");
-};
-
-/* generates padBegin and padEnd */
-var augmentor = function (augment) {
- return function (value, length, pad) {
- if (exports.no(pad)) pad = '0';
- if (exports.no(length)) length = 2;
- value = String(value);
- while (value.length < length) {
- value = augment(value, pad);
- }
- return value;
- };
-};
-
-/*** padBegin
-
- accepts:
- - a `String` or `Number` value
- - a minimum length of the resultant `String`:
- by default, 2
- - a pad string: by default, ``'0'``.
-
- returns a `String` of the value padded up to at least
- the minimum length. adds the padding to the begining
- side of the `String`.
-
-*/
-exports.padBegin = augmentor(function (value, pad) {
- return pad + value;
-});
-
-/*** padEnd
-
- accepts:
- - a `String` or `Number` value
- - a minimum length of the resultant `String`:
- by default, 2
- - a pad string: by default, ``'0'``.
-
- returns a `String` of the value padded up to at least
- the minimum length. adds the padding to the end
- side of the `String`.
-
-*/
-exports.padEnd = augmentor(function (value, pad) {
- return value + pad;
-});
-
-/*** splitName
- splits a string into a `List` of words from an origin
- string.
-*/
-var splitNameExpression = /[a-z]+|[A-Z](?:[a-z]+|[A-Z]*(?![a-z]))|[.\d]+/g;
-exports.splitName = function (value) {
- return String(value).match(splitNameExpression);
-};
-
-/*** joinName
- joins a list of words with a given delimiter
- between alphanumeric words.
-*/
-exports.joinName = function (delimiter, parts) {
- if (exports.no(delimiter)) delimiter = '_';
- parts.unshift([]);
- return parts.reduce(function (parts, part) {
- if (
- part.match(/\d/) &&
- exports.len(parts) && parts[parts.length-1].match(/\d/)
- ) {
- return parts.concat([delimiter + part]);
- } else {
- return parts.concat([part]);
- }
- }).join('');
-};
-
-/*** upper
- converts a name to ``UPPER CASE`` using
- a given delimiter between numeric words.
-
- see:
- - `lower`
- - `camel`
- - `title`
-
-*/
-exports.upper = function (value, delimiter) {
- if (exports.no(delimiter))
- return value.toUpperCase();
- return exports.splitName(value).map(function (part) {
- return part.toUpperCase();
- }).join(delimiter);
-};
-
-/*** lower
- converts a name to a ``lower case`` using
- a given delimiter between numeric words.
-
- see:
- - `upper`
- - `camel`
- - `title`
-
-*/
-exports.lower = function (value, delimiter) {
- if (exports.no(delimiter))
- return String(value).toLowerCase();
- return exports.splitName(value).map(function (part) {
- return part.toLowerCase();
- }).join(delimiter);
-};
-
-/*** camel
- converts a name to ``camel Case`` using
- a given delimiter between numeric words.
-
- see:
- - `lower`
- - `upper`
- - `title`
-
-*/
-exports.camel = function (value, delimiter) {
- return exports.joinName(
- delimiter,
- exports.mapApply(
- exports.enumerate(exports.splitName(value)),
- function (n, part) {
- if (n) {
- return (
- part.substring(0, 1).toUpperCase() +
- part.substring(1).toLowerCase()
- );
- } else {
- return part.toLowerCase();
- }
- }
- )
- );
-};
-
-/*** title
- converts a name to ``Title Case`` using
- a given delimiter between numeric words.
-
- see:
- - `lower`
- - `upper`
- - `camel`
-
-*/
-exports.title = function (value, delimiter) {
- return exports.joinName(
- delimiter,
- exports.splitName(value).map(function (part) {
- return (
- part.substring(0, 1).toUpperCase() +
- part.substring(1).toLowerCase()
- );
- })
- );
-};
-