UNPKG

allex_browsercore

Version:
1,641 lines (1,499 loc) 1.48 MB
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ function createArrayHelpers (extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError) { 'use strict'; function equaler (item, propval, scalarpropname, index) { return item[scalarpropname] == propval[index]; } function propnamevalequal (item, propname, propval) { var ret = propname.every(equaler.bind(null, item, propval)); item = null; propval = null; return ret; } function propvals (item, propname) { var ret = propname.map(function (scalarpropname) { return item[scalarpropname]; }); item = null; return ret; } function finderwithindex(findobj, propname, propval, item, index){ if (item && propnamevalequal(item, propname, propval)) { findobj.element = item; findobj.index = index; return true; } } function plaincompare (a, b) { if (a == b) {return 0;} if (a > b) {return 1;} return -1; } function scalarcompare(ret, item, index) { if (ret.ret != 0) { return ret; } var pcres = plaincompare(item, ret.other[index]); ret.ret = pcres; return ret; } function compare (a, b) { return a.reduce(scalarcompare, {other: b, ret: 0}).ret; } function finderwithindexandinsertindex(findobj, propname, propval, item, index){ var val, cmpval; val = propvals(item, propname); cmpval = compare(val, propval); if (cmpval == 0) { findobj.element = item; findobj.index = index; return true; } if (cmpval<0) { findobj.insertafter = index; } } return { finderwithindex: finderwithindex, finderwithindexandinsertindex: finderwithindexandinsertindex }; } module.exports = createArrayHelpers; },{}],2:[function(require,module,exports){ function createHelpers (extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError) { 'use strict'; return { scalar: require('./scalarcreator')(extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError), array: require('./arraycreator')(extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError) }; } module.exports = createHelpers; },{"./arraycreator":1,"./scalarcreator":3}],3:[function(require,module,exports){ function createScalarHelpers (extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError) { 'use strict'; function finderwithindex(findobj, propname, propval, item, index){ if (item && item[propname] === propval) { findobj.element = item; findobj.index = index; return true; } } function compare (a, b) { if (a == b) {return 0;} if (a > b) {return 1;} return -1; } function finderwithindexandinsertindex(findobj, propname, propval, item, index){ var val, cmpval; val = item[propname]; if (val === propval) { findobj.element = item; findobj.index = index; return true; } cmpval = compare(val, propval); if (cmpval<0) { findobj.insertafter = index; } } return { finderwithindex: finderwithindex, finderwithindexandinsertindex: finderwithindexandinsertindex }; } module.exports = createScalarHelpers; },{}],4:[function(require,module,exports){ module.exports = function createArryOperations(extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError) { var helpers = require('./helpers')(extend, readPropertyFromDotDelimitedString, isFunction, Map, AllexJSONizingError); function isArray (val) {return 'object' === typeof(val) && val instanceof Array;} function helperselector (propname, propval, helpername) { if (isArray(propname)) { if (!isArray(propval)) { throw new Error('propname-propval type mismatch'); } if (propname.length != propval.length) { throw new Error('propname-propval length mismatch'); } return helpers.array[helpername]; } return helpers.scalar[helpername]; } function union(a1, a2) { var ret = a1.slice(); appendNonExistingItems(ret, a2); return ret; } function appendNonExistingItems(a1, a2) { a2.forEach(function (a2e) { if (a1.indexOf(a2e)<0) { a1.push(a2e); } }); a1 = null; } function finder(findobj, propname, propval, item){ var und; //if (item[propname] === propval) { if (propval !== und && readPropertyFromDotDelimitedString(item, propname) === propval) { findobj.found = item; return true; } } function findElementWithProperty(a, propname, propval) { if (!(a && a.some)) { return; } var und, findobj = {found: und}, ret; a.some(finder.bind(null, findobj, propname, propval)); ret = findobj.found; findobj.found = null; findobj = null; return ret; } function lastfinder (propname, propval, result, item) { var und; if (propval !== und && readPropertyFromDotDelimitedString(item, propname) === propval) { return item; } return result; } function findLastElementWithProperty(a, propname, propval) { var ret; if (!(a && a.reduce)) { return; } ret = a.reduce(lastfinder.bind(null, propname, propval), void 0); propname = null; propval = null; return ret; } function findElementAndIndexWithProperty(a, propname, propval) { if (!(a && a.some)) { return; } var und, findobj = {element: und, index: und}; a.some(helperselector(propname, propval, 'finderwithindex').bind(null, findobj, propname, propval)); return findobj; } function findElementIndexAndInsertIndexWithProperty(a, propname, propval) { if (!(a && a.some)) { return; } var und, findobj = {element: und, index: und, insertafter: und}, _fo = findobj; a.some(helperselector(propname, propval, 'finderwithindexandinsertindex').bind(null, _fo, propname, propval)); _fo = null; propname = null; propval = null; return findobj; } function findToMatchFilter (a, filter) { var ret = []; for (var i = 0; i < a.length; i++) { if (filter.isOK(a[i])) ret.push (a[i]); } return ret; } function findFirstToMatchFilter (a, filter) { for (var i = 0; i < a.length; i++) { if (filter.isOK(a[i])) return a[i]; } } function findWithProperty (arr, propname, propval) { return arr.filter (finder.bind(null, {}, propname, propval)); } function checkerForPropertyName(propertyname, propertyprocessor, arry, object, index) { if (!object.hasOwnProperty(propertyname)) { throw(new AllexJSONizingError('NO_PROPERTY', object, 'No propertyname')); return; } var prop = object[propertyname], existing; if (propertyprocessor) { prop = propertyprocessor(prop); } existing = findElementAndIndexWithProperty(arry, propertyname, prop); if (existing.element) { arry[existing.index] = extend(existing.element, object); } else { arry.push(object); } } function appendNonExistingObjects(a1, a2, propertyname, propertyprocessor) { a2.forEach(checkerForPropertyName.bind(null, propertyname, propertyprocessor, a1)); } function unionObjects(a1, a2, propertyname, propertyprocessor) { var ret = a1.slice(); appendNonExistingObjects(ret, a2, propertyname, propertyprocessor); return ret; } function execute_eqf (what, eqf, item){ if (eqf(item, what)) { return true; } } function contains (arr, what, eqf) { if (!isFunction (eqf)) { return arr.indexOf(what) > -1; } return arr.some(execute_eqf.bind(null, what, eqf)); } function notcontains (arr, what, eqf){ return !contains(arr, what, eqf); } function _filter_notcontains (arr, eqf, what){ return notcontains(arr, what, eqf); }; function difference (arr1, arr2, eqf) { return arr1.filter(_filter_notcontains.bind(null, arr2, eqf)); } function isConsistent (arr1, arr2) { ///means arr2 has to have starting elements equal to elements of arr1 if (arr2.length < arr1.length) return false; for (var i = 0 ; i < arr1.length; i++) { if (arr2[i] !== arr1[i]) return false; } return true; } function _intersect_check (ret, arr2, eqf, item) { if (notcontains(arr2, item, eqf)) { return; } if (contains(ret, item, eqf)) { return; } ret.push (item); } function intersect (arr1, arr2, eqf) { if (!(arr1 && arr1.length)) return []; if (!(arr2 && arr2.length)) return []; var ret = []; arr1.forEach(_intersect_check.bind(null, ret, arr2, eqf)); return ret; } function pivot (source, options) { var p = new Pivoter(options); return p.pivot(source); } function unpivot (source, options) { var p = new Pivoter(options); return p.unpivot(source); } /* options: x_field : this field is used for x axis ... y_field : this field is used for y axis ... value_field : this field is used for value ... x_fields_list : list of fields accross x axis ... init_empty_rows : should empty rows be inited, to_y : converting function to y ... from_y : convert back y value to original value ... pivot_init_value : what should we put as initial value ... */ function Pivoter (options) { this.options = extend ({}, Pivoter.DEFAULT_OPTIONS, options); if (!this.options.x_field) throw new Error('No x_field config'); if (!this.options.y_field) throw new Error('No y_field config'); if (!this.options.value_field) throw new Error('No value_field config'); if (!this.options.x_fields_list) throw new Error('No x_fields_list config'); } Pivoter.prototype.pivot = function (source) { var ret = []; source.forEach (this._processPivotSourceItem.bind(this, ret)); if (!this.options.init_empty_rows) return ret; for (var i = 0; i < ret.length; i++) { if (ret[i]) continue; ret[i] = this.initializeEmptyPivotRecord(); } return ret; }; Pivoter.prototype._processPivotSourceItem = function (ret, item) { var y = this.options.to_y(item[this.options.y_field], item); if (!ret[y]) { ret[y] = this.initializeEmptyPivotRecord(); } var x = item[this.options.x_field]; if (!(x in ret[y])) throw new Error(x+' is not in filed list ...'); //console.log('PROCESSING PIVOT SOURCE ITEM', y, ret[y], item); ret[y][x] = item[this.options.value_field]; }; Pivoter.prototype.initializeEmptyPivotRecord = function () { var ret = {}; this.options.x_fields_list.forEach (this._createEmptyPivotField.bind(this, ret)); return ret; }; Pivoter.prototype._createEmptyPivotField = function (ret, name) { return ret[name] = 'pivot_init_value' in this.options ? this.options.pivot_init_value : null; }; Pivoter.prototype.unpivot = function (source, removeNonExistingValueFromUnpivot) { var ret = []; source.forEach (this._processPivotedItem.bind(this, removeNonExistingValueFromUnpivot, ret)); return ret; }; Pivoter.prototype._processPivotedItem = function (removeNonExistingValueFromUnpivot, ret, item, index) { this.options.x_fields_list.forEach (this._fromPivoted.bind(this, removeNonExistingValueFromUnpivot, ret, index, item)); }; Pivoter.prototype._fromPivoted = function (removeNonExistingValueFromUnpivot, ret, y, item, field){ var o = {}; o[this.options.value_field] = item[field]; o[this.options.y_field] = this.options.from_y(y, item); o[this.options.x_field] = field; if (this._shouldAccountUnpivot(o, removeNonExistingValueFromUnpivot)) { ret.push (this._processUnpivotRecord(o)); } }; Pivoter.prototype._shouldAccountUnpivot = function (o, removeNonExistingValueFromUnpivot) { if (removeNonExistingValueFromUnpivot) { if (o[this.options.value_field] === this.options.nonexisting_value) { return false; } } var f = this.options.shouldAccountUnpivot; return isFunction(f) ? f(o) : true; }; Pivoter.prototype._processUnpivotRecord = function (rec) { var f = this.options.processUnpivotRecord; return isFunction(f) ? f(rec) : rec; }; Pivoter.DEFAULT_OPTIONS = { nonexisting_value : null, init_empty_rows : false, to_y: function (s) {return parseInt(s);}, from_y : function (s) {return s+'';} }; function toRet (ret, val, name) { ret.push (name); } function unique (arr) { var map = new Map (); for (var i = 0; i < arr.length; i++) { if (!map.get(arr[i])) map.add(arr[i], true); } var ret = []; map.traverse (toRet.bind(null, ret)); return ret; } function randomizeArray(array) { var length = array.length; var last = length - 1; for (var index = 0; index < length; index++) { var rand = Math.floor ((index+1)*Math.random()); var temp = array[index]; array[index] = array[rand]; array[rand] = temp; } return array; } var ret = { intersect : intersect, isConsistent : isConsistent, contains : contains, notcontains : notcontains, difference : difference, union: union, appendNonExistingItems: appendNonExistingItems, findElementWithProperty: findElementWithProperty, findLastElementWithProperty: findLastElementWithProperty, findElementAndIndexWithProperty: findElementAndIndexWithProperty, findElementIndexAndInsertIndexWithProperty: findElementIndexAndInsertIndexWithProperty, pivot : pivot, unpivot : unpivot, Pivoter : Pivoter, findToMatchFilter : findToMatchFilter, findFirstToMatchFilter : findFirstToMatchFilter, unique : unique, randomizeArray : randomizeArray, findWithProperty : findWithProperty, appendNonExistingObjects: appendNonExistingObjects, unionObjects: unionObjects }; return ret; }; },{"./helpers":2}],5:[function(require,module,exports){ function Node(content){ this.left = null; this.right = null; this.leftCount = 0; this.rightCount = 0; this.content = content; } Node.prototype.destroy = function(){ this.content = null; this.leftCount = null; this.rightCount = null; this.right = null; this.left = null; }; Node.prototype.returnOnRemove = function(){ return this.content; }; Node.prototype.apply = function(func,depth){ return func(this.content,this,depth); }; Node.prototype.advance = function(val){ if (val === -1){ return this.left; } if (val === 1){ return this.right; } throw new Error('Invalid value' + val + '. -1 for left, 1 for right.'); }; Node.prototype.higherSubtreeRootLeft = function(){ return (this.leftCount >= this.rightCount) ? this.left : this.right; /* if (this.leftCount >= this.rightCount){ return this.left; }else{ return this.right; } */ } Node.prototype.higherSubtreeRootRight = function(){ return (this.rightCount >= this.leftCount) ? this.right : this.left; /* if (this.rightCount >= this.leftCount){ return this.right; }else{ return this.left; } */ } Node.prototype.higherSubtree = function(){ return (this.leftCount >= this.rightCount ? this.leftCount : this.rightCount) + 1; }; Node.prototype.findMax = function(stack){ var curr = this; stack.addToFront(curr); while (curr.right){ curr = curr.right; stack.addToFront(curr); } return curr; }; Node.prototype.findMin = function(stack){ var curr = this; stack.addToFront(curr); while (curr.left){ curr = curr.left; stack.addToFront(curr); } return curr; }; Node.prototype.absHeightDiff = function(){ return Math.abs(this.leftCount - this.rightCount); }; Node.prototype.rotateLeftLeft = function(prnt,leaf){ this.left = leaf.right; if (this.left !== null){ this.leftCount = this.left.higherSubtree(); }else{ this.leftCount = 0; } if (leaf.right !== null){ //leaf.right.up = this; } leaf.right = this; //leaf.up = prnt; //this.up = leaf; leaf.rightCount = leaf.right.higherSubtree(); if (prnt !== null){ if (prnt.left === this){ prnt.left = leaf; prnt.leftCount = prnt.left.higherSubtree(); }else{ prnt.right = leaf; prnt.rightCount = prnt.right.higherSubtree(); } } }; Node.prototype.rotateLeftRight = function(prnt,leaf,bottom){ leaf.right = bottom.left; if (leaf.right !== null){ leaf.rightCount = leaf.right.higherSubtree(); }else{ leaf.rightCount = 0; } if (bottom.left !== null){ //bottom.left.up = leaf; } bottom.left = leaf; bottom.leftCount = bottom.left.higherSubtree(); this.left = bottom; this.leftCount = this.left.higherSubtree(); //bottom.up = this; //leaf.up = bottom; this.rotateLeftLeft(prnt,bottom); }; Node.prototype.rotateRightRight = function(prnt,leaf){ this.right = leaf.left; if (this.right !== null){ this.rightCount = this.right.higherSubtree(); }else{ this.rightCount = 0; } if (leaf.left !== null){ //leaf.left.up = this; } leaf.left = this; //leaf.up = prnt; //this.up = leaf; leaf.leftCount = leaf.left.higherSubtree(); if (prnt !== null){ if (prnt.left === this){ prnt.left = leaf; prnt.leftCount = prnt.left.higherSubtree(); }else{ prnt.right = leaf; prnt.rightCount = prnt.right.higherSubtree(); } } }; Node.prototype.rotateRightLeft = function(prnt,leaf,bottom){ leaf.left = bottom.right; if (leaf.left !== null){ leaf.leftCount = leaf.left.higherSubtree(); }else{ leaf.leftCount = 0; } if (bottom.right !== null){ //bottom.right.up = leaf; } bottom.right = leaf; bottom.rightCount = bottom.right.higherSubtree(); this.right = bottom; this.rightCount = this.right.higherSubtree(); //bottom.up = this; //leaf.up = bottom; this.rotateRightRight(prnt,bottom); }; Node.prototype.contentToString = function(){ return this.content.toString(); }; module.exports = Node; },{}],6:[function(require,module,exports){ function createStack(doublelinkedlistbase, inherit) { 'use strict'; var ListItemCtor = doublelinkedlistbase.Item, ListMixin = doublelinkedlistbase.Mixin; function TreeBranchItem (content) { ListItemCtor.call(this, content); } inherit(TreeBranchItem, ListItemCtor); function TreeBranchStack(){ ListMixin.call(this); } ListMixin.addMethods(TreeBranchStack); TreeBranchStack.prototype.addToFront = function(content){ if (!checkForTreeNode(content)) { return; } var newItem = new TreeBranchItem(content); this.assureForController(); this.controller.addToFront(newItem); }; TreeBranchStack.prototype.addToBack = function(content){ var newItem; if (!checkForTreeNode(content)) { return; } if (!this.assureForController()) { return; } newItem = new TreeBranchItem(content); this.controller.addToBack(newItem); }; TreeBranchStack.prototype.push = TreeBranchStack.prototype.addToBack; TreeBranchStack.prototype.shift = function(){ var ret, head; if (!this.head) { return; } if (!this.assureForController()) { return; } ret = this.head.content; if (!checkForTreeNode(ret)) { return; } head = this.head; this.controller.remove(this.head); head.destroy(); return ret; }; TreeBranchStack.prototype.addAsPrevTo = function (content, prevtarget) { if (!this.assureForController()) { return; } this.controller.addAsPrevTo(new TreeBranchItem(content), prevtarget); }; TreeBranchStack.prototype.findOne = function(criterionfunction){ var item = this.firstItemToSatisfy(criterionfunction); if(item){ return item.content; }else{ return; } }; function checkForTreeNode(ret) { if (!(ret && ret.hasOwnProperty('left'))) { console.trace(); console.error(ret); return false; } return true; } return TreeBranchStack; } module.exports = createStack; },{}],7:[function(require,module,exports){ (function (process){(function (){ function createAvlTreeControllerFactory(Stack) { 'use strict'; return function createAvlTreeController(compare){ //TODO check if compare is a function?? function AvlTreeController(myTree){ this.tree = myTree; } AvlTreeController.prototype.destroy = function(){ this.tree = null; }; AvlTreeController.prototype.remove = function(content){ if (typeof content !== 'number' && !content){ return false; } var prevStack = this.prevStackToEqual(content); if(!prevStack){ return false; } var leaf = prevStack.shift()||null; var oldHeight = 0; var higher = null; var newHeight = 0; var high,middle,low; var balanceInd = false; var ret; //1. case - No children if (leaf.left === null && leaf.right === null){ higher = prevStack.shift()||null; if (higher === null){ this.tree.root = null; this.tree.decCount(); ret = leaf.returnOnRemove(); leaf.destroy(); prevStack.destroy(); return ret; }else{ oldHeight = higher.higherSubtree(); if (higher.left === leaf){ higher.left = null; higher.leftCount--; high = higher; middle = higher.right; if (!!middle){ low = middle.higherSubtreeRootLeft(); }else{ low = null; } }else{ higher.right = null; higher.rightCount--; high = higher; middle = higher.left; if (!!middle){ low = middle.higherSubtreeRootRight(); }else{ low = null; } } newHeight = higher.higherSubtree(); balanceInd = balanceInd || (higher.absHeightDiff() === 2); } }else{ if (leaf.left === null || leaf.right === null){ higher = prevStack.shift()||null; if (higher !== null){ oldHeight = higher.higherSubtree(); } //2.1 case - 1 child - Left if (leaf.left !== null && leaf.right === null){ if (higher !== null){ if (higher.left === leaf){ higher.left = leaf.left; higher.leftCount--; high = higher; middle = higher.right; if (!!middle){ low = middle.higherSubtreeRootLeft(); }else{ low = null; } }else{ higher.right = leaf.left; higher.rightCount--; high = higher; middle = higher.left; if (!!middle){ low = middle.higherSubtreeRootRight(); }else{ low = null; } } newHeight = higher.higherSubtree(); balanceInd = balanceInd || (higher.absHeightDiff() === 2); }else{ this.tree.root = leaf.left; newHeight = 0; } }else{ //2.2 case - 1 child - Right if (leaf.left === null && leaf.right !== null){ if (higher !== null){ if (higher.left === leaf){ higher.left = leaf.right; higher.leftCount--; high = higher; middle = higher.right; if (!!middle){ low = middle.higherSubtreeRootLeft(); }else{ low = null; } }else{ higher.right = leaf.right; higher.rightCount--; high = higher; middle = higher.left; if (!!middle){ low = middle.higherSubtreeRootRight(); }else{ low = null; } } newHeight = higher.higherSubtree(); balanceInd = balanceInd || (higher.absHeightDiff() === 2); }else{ this.tree.root = leaf.right; newHeight = 0; } } } }else{ //3 case - 2 children var leafParent = prevStack.head; leaf.right.findMin(prevStack); var max = prevStack.shift()||null; var maxParent = prevStack.shift()||null; if (maxParent === null){ oldHeight = leaf.higherSubtree(); max.left = leaf.left; max.leftCount = max.left.higherSubtree(); high = max; middle = max.left; low = middle.higherSubtreeRootRight(); balanceInd = balanceInd || (max.absHeightDiff() === 2); newHeight = leaf.higherSubtree(); }else{ oldHeight = maxParent.higherSubtree(); if (maxParent.left === max){ maxParent.left = max.right; maxParent.leftCount--; max.left = leaf.left; max.leftCount = max.left.higherSubtree(); if (leaf.right !== max){ max.right = leaf.right; max.rightCount = max.right.higherSubtree(); } high = maxParent; middle = maxParent.right; if (!!middle){ low = middle.higherSubtreeRootLeft(); }else{ low = null; } if (leafParent !== null){ prevStack.addAsPrevTo(max, leafParent); //leafParent.insertBefore(max,prevStack); higher = leafParent.content; if (higher.left === leaf){ higher.left = max; }else{ higher.right = max; } }else{ prevStack.addToBack(max); } balanceInd = balanceInd || (maxParent.absHeightDiff() === 2); }else{ max.left = leaf.left; max.leftCount = max.left.higherSubtree(); if (leaf.right !== max){ max.right = leaf.right; max.rightCount = max.right.higherSubtree(); } if (maxParent.left === leaf){ maxParent.left = max; maxParent.leftCount = maxParent.left.higherSubtree(); }else{ maxParent.right = max; maxParent.rightCount = maxParent.right.higherSubtree(); } high = max; middle = max.left; if (!!middle){ low = middle.higherSubtreeRootRight(); }else{ low = null; } prevStack.addToFront(maxParent); balanceInd = balanceInd || (max.absHeightDiff() === 2) || (maxParent.absHeightDiff() === 2); } newHeight = maxParent.higherSubtree(); } if (leaf === this.tree.root){ this.tree.root = max; } } } this.tree.decCount(); if (oldHeight !== newHeight || !!balanceInd){ this.doBalanceRemove(high,middle,low,prevStack); } ret = leaf.returnOnRemove(); leaf.destroy(); prevStack.destroy(); return ret; }; AvlTreeController.prototype.add = function(newItem){ if (!newItem){ return; } var prevStack = this.prevStackToLeaf(newItem.content); var leaf = prevStack.shift()||null; if (leaf === null){ this.tree.root = newItem; prevStack.destroy(); return; }else{ var res = compare(leaf.content,newItem.content); //newItem.up = leaf; if (res===0){ console.trace(); prevStack.destroy(); console.error(leaf.content, 'is not unique'); throw new Error('Items must have unique content'); } if (res===-1){ leaf.left = newItem; leaf.leftCount++; }else{ leaf.right = newItem; leaf.rightCount++; } } var higher = prevStack.shift()||null; var bottom = newItem; if (leaf.leftCount !== leaf.rightCount){ this.doBalanceAdd(higher,leaf,bottom,prevStack); } prevStack.destroy(); }; AvlTreeController.prototype.doBalanceAdd = function(higher,leaf,bottom,prevStack){ var tmp; while (higher){ var prnt = prevStack.shift()||null; if (higher.left === leaf){ higher.leftCount = leaf.higherSubtree(); if (higher.leftCount === higher.rightCount){ break; } if (higher.leftCount - higher.rightCount === 2){ if (leaf.leftCount - leaf.rightCount >= 0){ higher.rotateLeftLeft(prnt,leaf); if (prnt === null){ this.tree.root = leaf; } tmp = higher; higher = leaf; leaf = bottom; bottom = tmp; }else{ higher.rotateLeftRight(prnt,leaf,bottom); if (prnt === null){ this.tree.root = bottom; } tmp = higher; higher = bottom; leaf = bottom; bottom = tmp; } } }else{ higher.rightCount = leaf.higherSubtree(); if (higher.leftCount === higher.rightCount){ break; } if (higher.leftCount - higher.rightCount === -2){ if (leaf.leftCount - leaf.rightCount <= 0){ higher.rotateRightRight(prnt,leaf); if (prnt === null){ this.tree.root = leaf; } tmp = higher; higher = leaf; leaf = bottom; bottom = tmp; }else{ higher.rotateRightLeft(prnt,leaf,bottom); if (prnt === null){ this.tree.root = bottom; } tmp = higher; higher = bottom; leaf = bottom; bottom = tmp; } } } bottom = leaf; leaf = higher; higher = prnt; } }; AvlTreeController.prototype.doBalanceRemove = function(higher,leaf,bottom,prevStack){ var tmp; while (higher){ var prnt = prevStack.shift()||null; if (!!leaf){ if (higher.right === leaf){ higher.leftCount = !!higher.left ? higher.left.higherSubtree() : 0; if (higher.leftCount + 1 === higher.rightCount){ break; } if (higher.leftCount - higher.rightCount === -2){ if (leaf.leftCount - leaf.rightCount <= 0){ higher.rotateRightRight(prnt,leaf); if (prnt === null){ this.tree.root = leaf; } tmp = higher; higher = leaf; leaf = bottom; bottom = tmp; }else{ higher.rotateRightLeft(prnt,leaf,bottom); if (prnt === null){ this.tree.root = bottom; } tmp = higher; higher = bottom; leaf = bottom; bottom = tmp; } } }else{ higher.rightCount = !!higher.right ? higher.right.higherSubtree() : 0; if (higher.leftCount === higher.rightCount + 1){ break; } if (higher.leftCount - higher.rightCount === 2){ if (leaf.leftCount - leaf.rightCount >= 0){ higher.rotateLeftLeft(prnt,leaf); if (prnt === null){ this.tree.root = leaf; } tmp = higher; higher = leaf; leaf = bottom; bottom = tmp; }else{ higher.rotateLeftRight(prnt,leaf,bottom); if (prnt === null){ this.tree.root = bottom; } tmp = higher; higher = bottom; leaf = bottom; bottom = tmp; } } } } if (!!prnt){ if (prnt.left === higher){ leaf = prnt.right; bottom = leaf.higherSubtreeRootLeft(); }else{ leaf = prnt.left; if (!(leaf && leaf.higherSubtreeRootRight)) { console.trace(); console.log(prnt); process.exit(0); } bottom = leaf.higherSubtreeRootRight(); } } higher = prnt; } }; AvlTreeController.prototype.prevStackToLeaf = function(content){ var curr = this.tree.root; var prevStack = new Stack(); var res; while (curr !== null){ res = compare(curr.content,content); if (res === 0){ console.trace(); prevStack.destroy(); console.error(content, 'is not unique'); throw new Error('Items must have unique content'); } prevStack.addToFront(curr); curr = curr.advance(res); } return prevStack; }; AvlTreeController.prototype.prevStackToEqual = function(content){ var curr = this.tree.root; var prevStack = new Stack(); var res; while (curr !== null){ prevStack.addToFront(curr); res = compare(curr.content,content); if (res === 0){ return prevStack; } curr = curr.advance(res); } prevStack.destroy(); /* console.trace(); throw Error('Item with content ' + JSON.stringify(content) + ' does not exist.'); */ return; } AvlTreeController.prototype.find = function(content){ var curr = this.tree.root; var res; while (curr){ res = compare(curr.content,content); if (res === 0){ return curr; } curr = curr.advance(res); } return null; }; function nodeApplier (node, thingy, errorcaption) { if (!errorcaption) { return node.apply(thingy); } if (!(typeof errorcaption == 'string')) { console.error('what is errorcaption?', errorcaption); process.exit(1); } try { return node.apply(thingy); } catch (e) { console.log(errorcaption+' :', e); return; } } function nodeApplier2 (node, thingy1, thingy2, errorcaption) { if (!errorcaption) { return node.apply(thingy1, thingy2); } try { return node.apply(thingy1, thingy2); } catch (e) { console.log(errorcaption+' :', e); return; } } AvlTreeController.prototype.firstItemToSatisfyPreOrder = function(func, node, errorcaption){ if (!node) return null; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!!check){ return node.content; } var ret = this.firstItemToSatisfyPreOrder(func,node.left, errorcaption); if (!!ret) return ret; ret = this.firstItemToSatisfyPreOrder(func,node.right, errorcaption); if (!!ret) return ret; }; AvlTreeController.prototype.firstItemToSatisfyInOrder = function(func, node, errorcaption){ if (!node) return null; ret = this.firstItemToSatisfyInOrder(func,node.left, errorcaption); if (!!ret) return ret; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!!check){ return node.content; } ret = this.firstItemToSatisfyInOrder(func,node.right, errorcaption); if (!!ret) return ret; }; AvlTreeController.prototype.firstItemToSatisfyPostOrder = function(func, node, errorcaption){ if (!node) return null; var ret = this.firstItemToSatisfyPostOrder(func,node.left, errorcaption); if (!!ret) return ret; ret = this.firstItemToSatisfyPostOrder(func,node.right, errorcaption); if (!!ret) return ret; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!!check){ return node.content; } }; AvlTreeController.prototype.lastItemToSatisfyPreOrder = function(func,node,prev, errorcaption){ if (!node) return null; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!check){ return !!prev ? prev.content : null; } var ret = this.lastItemToSatisfyPreOrder(func,node.left,node, errorcaption); if (!!ret) return ret; ret = this.lastItemToSatisfyPreOrder(func,node.right,node, errorcaption); if (!!ret) return ret; return null; }; AvlTreeController.prototype.lastItemToSatisfyInOrder = function(func,node,prev, errorcaption){ if (!node) return null; var ret = this.lastItemToSatisfyInOrder(func,node.left,node, errorcaption); if (!!ret) return ret; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!check){ return !!prev ? prev.content : null; } ret = this.lastItemToSatisfyInOrder(func,node.right,node, errorcaption); if (!!ret) return ret; return null; }; AvlTreeController.prototype.lastItemToSatisfyPostOrder = function(func,node,prev, errorcaption){ if (!node) return null; var ret = this.lastItemToSatisfyPostOrder(func,node.left,node, errorcaption); if (!!ret) return ret; ret = this.lastItemToSatisfyPostOrder(func,node.right,node, errorcaption); if (!!ret) return ret; var check = nodeApplier(node, func, errorcaption); if ('boolean' !== typeof check){ throw Error('func needs to return a boolean value'); } if (!check){ return !!prev ? prev.content : null; } return null; }; AvlTreeController.prototype.traversePreOrder = function(func, node, depth, errorcaption){ if (!node) return; nodeApplier2(node,func,depth, errorcaption); this.traversePreOrder(func,node.left,depth+1, errorcaption); this.traversePreOrder(func,node.right,depth+1, errorcaption); }; AvlTreeController.prototype.traversePreOrderConditionally = function(func, node, depth, errorcaption){ if (!node) return; var ret = nodeApplier2(node,func,depth, errorcaption); if(typeof ret !== 'undefined'){ return ret; } ret = this.traversePreOrderConditionally(func,node.left,depth+1, errorcaption); if(typeof ret !== 'undefined'){ return ret; } return this.traversePreOrderConditionally(func,node.right,depth+1, errorcaption); }; AvlTreeController.prototype.traverseInOrder = function(func, node, depth, errorcaption){ if (!node) return; this.traverseInOrder(func,node.left,depth+1, errorcaption); nodeApplier2(node,func,depth, errorcaption); this.traverseInOrder(func,node.right,depth+1, errorcaption); }; AvlTreeController.prototype.traverseInOrderConditionally = function(func, node, depth, errorcaption){ if (!node) return; var ret = this.traverseInOrderConditionally(func,node.left,depth+1, errorcaption); if(typeof ret !== 'undefined'){ return ret; } ret = nodeApplier2(node,func,depth, errorcaption); if(typeof ret !== 'undefined'){ return ret; } return this.traverseInOrderConditionally(func,node.right,depth+1, errorcaption); }; AvlTreeController.prototype.traversePostOrder = function(func, node, depth, errorcaption){ if (!node) return; this.traversePostOrder(func,node.left,depth+1, errorcaption); this.traversePostOrder(func,node.right,depth+1, errorcaption); nodeApplier2(node,func,depth, errorcaption); }; AvlTreeController.prototype.traversePostOrderConditionally = function(func, node, depth, errorcaption){ if (!node) return; var ret = this.traversePostOrderConditionally(func,node.left,depth+1, errorcaption); if(typeof ret !== 'undefined'){ return ret; } ret = this.traversePostOrderConditionally(func,node.right,depth+1, errorcaption); if(typeof ret !== 'undefined'){ return ret; } return nodeApplier2(node,func,depth, errorcaption); }; return AvlTreeController; } } module.exports = createAvlTreeControllerFactory; }).call(this)}).call(this,require('_process')) },{"_process":378}],8:[function(require,module,exports){ function createAvlTree (dlistbase, inherit) { return { treeFactory: require('./treefactorycreator')(dlistbase, inherit), Node: require('./Node') } } module.exports = createAvlTree; },{"./Node":5,"./treefactorycreator":9}],9:[function(require,module,exports){ function createTreeFactory(dlistbase, inherit) { var controllerFactory = require('./controllerfactorycreator')(require('./Stack.js')(dlistbase, inherit)); return function createTreeKlass(compare,nodefactory){ var controllerctor = controllerFactory(compare); function AvlTree(){ this.root = null; this.count = 0; this.controller = new controllerctor(this); } AvlTree.prototype.destroy = function(){ this.purge(); this.count = null; this.root = null; if (this.controller) { this.controller.destroy(); } this.controller = null; }; function contentGetter(content,node){ return content; } function destroyer (node) { node.destroy(); } AvlTree.prototype.purge = function(){ var nodes = [], _ns = nodes; this.controller.traverseInOrder(function (n) {_ns.push(n);}); _ns = null; nodes.forEach(destroyer); nodes = null; this.root = null; this.count = 0; }; AvlTree.prototype.count = function(){ return this.count; } AvlTree.prototype.empty = function(){ return this.count === 0; }; AvlTree.prototype.add = function(){ //arguments are to be fed into nodefactory if (!this.controller) { return null; } var newItem = nodefactory.apply(null,arguments);//new nodector(content); this.controller.add(newItem); this.count++; return newItem; }; //TODO private? AvlTree.prototype.decCount = function(){ this.count--; }; AvlTree.prototype.remove = function(content){ if (!this.controller) { return null; } return this.controller.remove(content); }; AvlTree.prototype.find = function(content){ if (!this.controller) { return null; } return this.controller.find(content); }; AvlTree.prototype.findOne = function(criterionfunction){ if ('function' !== typeof criterionfunction){ throw new Error('First parameter \'criterionfunction\' is not a function'); } return this.firstItemToSatisfy(criterionfunction); }; AvlTree.prototype.firstItemToSatisfyPreOrder = function(func){ if (!this.controller) { return null; } return this.controller.firstItemToSatisfyPreOrder(func,this.root); }; AvlTree.prototype.firstItemToSatisfy = function(func){ if (!this.controller) { return null; } return this.controller.firstItemToSatisfyInOrder(func,this.root); }; AvlTree.prototype.firstItemToSatisfyPostOrder = function(func){ if (!this.controller) { return null; } return this.controller.firstItemToSatisfyPostOrder(func,this.root); }; AvlTree.prototype.lastItemToSatisfyPreOrder = function(func){ if (!this.controller) { return null; } return this.controller.lastItemToSatisfyPreOrder(func,this.root,null); }; AvlTree.prototype.lastItemToSatisfy = function(func){ if (!this.controller) { return null; } return this.controller.lastItemToSatisfyInOrder(func,this.root,null); }; AvlTree.prototype.lastItemToSatisfyPostOrder = function(func){ if (!this.controller) { return null; } return this.controller.lastItemToSatisfyPostOrder(func,this.root,null); }; AvlTree.prototype.traverseInOrder = function(func){ if (!this.controller) { return; } this.controller.traverseInOrder(func,this.root,0); }; AvlTree.prototype.traversePreOrder= function(func){ if (!this.controller) { return; } this.controller.traversePreOrder(func,this.root,0); } AvlTree.prototype.traversePostOrder= function(func){ if (!this.controller) { return; } this.controller.traversePostOrder(func,this.root,0); } AvlTree.prototype.traverseInOrderConditionally = function(func){ if (!this.controller) { return; } return this.controller.traverseInOrderConditionally(func,this.root,0); } AvlTree.prototype.traversePreOrderConditionally= function(func){ if (!this.controller) { return; } return this.controller.traversePreOrderConditionally(func,this.root,0); } AvlTree.prototype.traversePostOrderConditionally= function(func){ if (!this.controller) { return; } return this.controller.traversePostOrderConditionally(func,this.root,0); } AvlTree.prototype.dumpToConsole = function(func){ console.log('\n-----------------------------------------------------------------\n'); this.traverseInOrder(func||consoleTree); }; function consoleTree(content,item,level){ var s = ''; for(var i=0; i<level; i++){ s += '\t'; } console.log(s+item.contentToString()+' ('+level+')'); } /* function drainer(arry,countobj,content){ arry[countobj.count] = content; countobj.count++; } AvlTree.prototype.drain = function(){ var ret = new Array(this.length),countobj={count:0},_ret = ret; this.traverse(drainer.bind(null,_ret,countobj)); _ret = null; this.purge(); return ret; }; */ return AvlTree; } } module.exports = createTreeFactory; },{"./Stack.js":6,"./controllerfactorycreator":7}],10:[function(require,module,exports){ (function (process){(function (){ module.exports = function (lib) { 'use strict'; var q = lib.q, jsonschema = lib.jsonschema, validator = new (jsonschema.Validator)(); //TODO: load some prefefined schemas into validator for common data types like email and so on ... function extractValidationMessages(title, error) { return (title ? (title + ': ') : '') + error.path.join('.') + ' ' + error.message; } function validateSingleParam(errors, complete_schema, param_value, param_index) { var schema = complete_schema[param_index], ret, result; if( lib.isUndef(schema) ){ console.error('no schema for',param_index,'in',complete_schema); return undefined; } //if schema === true just let it pass ... if (schema === true) { return undefined; } if ((null === param_value || lib.isUndef(param_value)) && schema.required===false) { ret = schema.required ? 'Missing param: ' + schema.title : undefined; //console.log('Param value is', param_value, 'and ', schema.required, ret); return ret; } result = validator.validate(param_value, schema); if (!result.errors.length) { return; } Array.prototype.push.apply(errors, result.errors.map(extractValidationMessages.bind(null, schema.title))); } var __id=0; function Callable() { //this.__id = ++__id; this._activeDefers = new lib.DeferMap(); } Callable.prototype.destroy = function () { //console.trace(); //console.log(this.__id, 'destroying'); var ad = this._activeDefers; this._activeDefers = null; if (ad) { ad.destroy(); } }; Callable.prototype.executeStep = function (stepspec) { //console.log('stepspec', stepspec); var ret = this._activeDefers.defer(lib.uid()), methodname = stepspec[0], method = this[methodname], ml, params, trailing, vp, cleaner; if (!ret.resolve) { console.trace(); console.error('this has to be a defer:', ret); process.exit(0); } if ('function' !== typeof method) { console.trace(); console.log('In', this.__methodDescriptors, 'Method ' + methodname + ' does not exist'); ret.reject(new lib.Error('METHOD_DOES_NOT_EXIST', 'Method ' + methodname + ' does not exist')); return ret.promise; } if (this.__methodDescriptors && !this.__methodDescriptors[methodname]) { console.log(this.__methodDescriptors, methodname, '?'); ret.reject(new lib.Error('METHOD_NOT_EXECUTABLE