UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

1,202 lines (1,155 loc) 441 kB
/*/---------------------------------------------------------/*/ /*/ Craydent LLC v1.8.0 /*/ /*/ Copyright 2011 (http://craydent.com/about) /*/ /*/ Dual licensed under the MIT or GPL Version 2 licenses. /*/ /*/ (http://craydent.com/license) /*/ /*/---------------------------------------------------------/*/ /*---------------------------------------------------------------------------------------------------------------- /- Global CONSTANTS and variables /---------------------------------------------------------------------------------------------------------------*/ var __version = "1.8.0", __thisIsNewer = true, $w = typeof window != "undefined" ? window : {location:(typeof location != "undefined"?location:{href:''}),console:(typeof console != "undefined"?console:{})}, $g = $w, $d = typeof document != "undefined" ? document : {}, $l = $w.location; if ($w.__craydentLoaded || typeof($c) != "undefined") { var __current = ($w.__craydentVersion||$c.VERSION||"").split("."), __thisVersion = __version.split("."); if(__thisIsNewer = __isNewer(__current,__thisVersion)) { $c.VERSION = __version; } } function __isNewer(loadedVersion, thisVersion){ if (loadedVersion[0] == thisVersion[0]) { loadedVersion.splice(0,1); thisVersion.splice(0,1); if (!thisVersion.length || !loadedVersion.length) { return false; } return __isNewer(loadedVersion, thisVersion); } return parseInt(loadedVersion[0]) < parseInt(thisVersion[0]); } function __cleanUp() { try { delete $w.__current; delete $w.__thisVersion; delete $w.__thisIsNewer; delete $w.__isNewer; delete $w.__version; delete $w._ie; delete $w._droid; delete $w._amay; delete $w._browser; delete $w._os; delete $w._device; delete $w._engine; } catch(e) { $w.__current = undefined; $w.__thisVersion = undefined; $w.__thisIsNewer = undefined; $w.__isNewer = undefined; $w.__version = undefined; $w._ie = undefined; $w._droid = undefined; $w._amay = undefined; $w._browser = undefined; $w._os = undefined; $w._device = undefined; $w._engine = undefined; } } $w.__craydentVersion = __version; if (__thisIsNewer) { var _ao,_ah, _df, _irregularNouns = { "addendum":"addenda", "alga":"algae", "alumna":"alumnae", "apparatus":"apparatuses", "appendix":"appendices", "bacillus":"bacilli", "bacterium":"bacteria", "beau":"beaux", "bison":"bison", "bureau":"bureaus", "child":"children", "corps":"corps", "corpus":"corpora", "curriculum":"curricula", "datum":"data", "deer":"deer", "die":"dice", "diagnosis":"diagnoses", "erratum":"errata", "fireman":"firemen", "focus":"focuses", "foot":"feet", "genus":"genera", "goose":"geese", "index":"indices", "louse":"lice", "man":"men", "matrix":"matrices", "means":"means", "medium":"media", "memo":"memos", "memorandum":"memoranda", "moose":"moose", "mouse":"mice", "nebula":"nebulae", "ovum":"ova", "ox":"oxen", "person":"people", "radius":"radii", "series":"series", "sheep":"sheep", "scissors":"scissors", "species":"species", "stratum":"strata", "syllabus":"syllabi", "tableau":"tableaux", "that":"those", "this":"these", "tooth":"teeth", "vertebra":"vertebrae", "vita":"vitae", "woman":"women", "zero":"zeros" }; /*---------------------------------------------------------------------------------------------------------------- /- define functions preventing overwriting other framework functions /---------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------- /- private methods /---------------------------------------------------------------------------------------------------------------*/ function __add_fillTemplate_ref (obj){ try { var uid = suid(); fillTemplate.refs["ref_" + fillTemplate.refs.length] = uid; fillTemplate.refs[uid] = obj; fillTemplate.refs.push(obj); return uid; } catch (e) { error('fillTemplate.__add_fillTemplate_ref', e); } } function __and (){ try { var len = arguments.length; for(var a = 0; a<len; a++){ if(!arguments[a]){ return arguments[a - 1] || ""; } } return arguments[len - 1]; } catch (e) { error('fillTemplate.__and', e); } } function __andNotHelper (record, query, operands, index) { try { for (var i = 0, len = query.length; i < len; i++) { for (var prop in query[i]) { if (!query[i].hasOwnProperty(prop)) { continue; } if (!(prop in operands && _subQuery(record, query[i][prop], prop, index) || _subQuery(record, query[i][prop], "$equals", prop, index) )) { return false; } } } return true; } catch (e) { error('where.__andNotHelper', e); } } function __clean_micro_templates () { var _micro_templates = fillTemplate._micro_templates; for (var id in _micro_templates) { if (!_micro_templates.hasOwnProperty(id)) { continue; } if (!$CSS("[data-craydent-bind*='"+id+"']").length) { delete _micro_templates[id]; } } } function __convert_regex_safe(reg_str) { try { return reg_str.replace(/\\/gi,"\\\\") .replace(/\$/gi, "\\$") .replace(/\//gi, "\\/") .replace(/\^/gi, "\\^") .replace(/\./gi, "\\.") .replace(/\|/gi, "\\|") .replace(/\*/gi, "\\*") .replace(/\+/gi, "\\+") .replace(/\?/gi, "\\?") .replace(/\!/gi, "\\!") .replace(/\{/gi, "\\{") .replace(/\}/gi, "\\}") .replace(/\[/gi, "\\[") .replace(/\]/gi, "\\]") .replace(/\(/gi, "\\(") .replace(/\)/gi, "\\)") .replace('\n','\\n'); } catch (e) { error('__convert_regex_safe', e); } } function __count(arr){ try { return arr.length; } catch (e) { error('fillTemplate.count', e); } } function __dup (old) { try { for (var prop in old){ if (!old.hasOwnProperty(prop)) { continue; } this[prop] = old[prop]; } } catch (e) { error('__dup', e); } } function __enum(obj, delimiter, prePost){ try { delimiter = delimiter || ", "; prePost = prePost || ["",""]; var props = [], str = ""; if ($c.isArray(obj)) { props = obj.slice(0); } if ($c.isObject(obj)) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { props.push(prop); } } } for (var i = 0, len = props.length; i < len; i++) { var pre = prePost[0].replace_all(['{ENUM_VAR}','{ENUM_VAL}'],[props[i],obj[props[i]]]), post = prePost[1].replace_all(['{ENUM_VAR}','{ENUM_VAL}'],[props[i],obj[props[i]]]); str += pre + props[i] + post + delimiter; } return str.slice(0,-1*delimiter.length); } catch (e) { error('fillTemplate.enum', e); } } function __interpreter (template, obj) { try { var codeBlock = /\$\{if .*?\}([\s\S]*)\$\{end_if\}/g.exec(template), ifb = "${if(", efb = "${end_if}"; // if (!codeBlock) { // return template; // } // codeBlock = codeBlock[0]; template = template.replace_all(['${if (',') }'],['${if(',')}']); var ifcount = 0; var efcount = 0; var ifindex = template.indexOf(ifb), efindex = template.indexOf(efb); if (ifindex == -1) { return template; } //noinspection CommaExpressionJS ifcount++, efcount++; var before = template.substring(0,ifindex); template = template.substring(ifindex); ifindex = 0; var blockstart = template.indexOf(')}'), cond = template.substring(5, blockstart).strip(); while (ifcount == 1 || ifcount != efcount) { ifindex = template.indexOf(ifb,ifindex+1); if (ifindex > -1) { if (ifindex < efindex) { ifcount++; } else { efcount++; efindex = template.indexOf(efb,efindex+1); } } else { efindex++; break; } } if (ifcount == 1) { efindex = template.indexOf(efb); } var block = template.substring(blockstart + 2, efindex), statement = template.substring(0,efindex + efb.length); if (cond.contains('${')) { cond = fillTemplate(cond.replace_all(['${','}'],['"${','}"']), obj); } if(!tryEval(cond)) { template = before + template.replace(statement, ''); } else { // template = before + template.replace(block, __interpreter(block,obj)); template = before + template.replace(statement, __interpreter(block,obj)); } return __interpreter(template,obj); } catch (e) { error('fillTemplate.interpreter', e); } } function __logic_parser (code, obj, bind) { if (!code) { return ""; } var ttc = $c.TEMPLATE_TAG_CONFIG, indexes = [], logic = {}; code = code.replace_all(ttc.IGNORE_CHARS,['']); $c.eachProperty(ttc, function (value) { if (!value.begin) { return; } var index = code.indexOfAlt(value.begin); indexes.push(index); logic[index] = value; }); var index = Math.min.apply(Math,indexes.condense([-1])); if (!logic[index]) { return code; } return code.substring(0,index) + logic[index].parser(code.substring(index),obj, bind); } function __observe_helper (obj, callback, acceptList, parent) { try { if ($c.isObject(obj)) { return observe(obj, callback, acceptList, parent); } if (!$c.isArray(obj)) { return; } for (var i = 0, len = obj.length; i < len; i++) { if (!$c.isObject(obj[i])) { continue; } observe(obj[i], callback, acceptList, parent); } } catch(e) { error('observe.observe_helper', e); } } function __on_observable_change (changes) { try { var change = changes[0], obj = change.object, prop = change.name, value = change.oldValue; var _observing = fillTemplate._observing, _micro_templates = fillTemplate._micro_templates; // change values if (obj[prop] != value) { var id_index = _observing.indexOf(obj); var hash = _observing["hash_"+id_index], pattern = new RegExp(hash+"[a-zA-Z0-9,]*\."+prop+";?|$"), //nodes = $CSS("[data-craydent-bind*='"+hash+"."+prop+"']"); nodes = Array.prototype.slice.call($CSS("[data-craydent-bind*='"+hash+"']")||[]).filter(function(node){ return pattern.test(node.getAttribute("data-craydent-bind")); }); if (!$CSS("[data-craydent-bind*='"+hash+"']").length) { delete _observing["hash_" + id_index]; return; } for (var i = 0, len = nodes.length; i < len; i++) { if (nodes[i].isOrphan()) { continue; } var id = nodes[i].getAttribute("data-craydent-bind").split(":")[0], tobj = $c.getProperty(_observing,"parents_"+id_index + ".0") || obj; nodes[i].replace(fillTemplate(_micro_templates[id].template.replace_all("${craydent_bind}",hash),tobj).toDomElement()); } } } catch(e) { error('observe.on_observable_change', e); } } function __or (){ try { for(var a = 0, len = arguments.length; a<len; a++){ if(arguments[a]){ return arguments[a]; } } return ""; } catch (e) { error('fillTemplate.__or', e); } } function __processBlocks (start, end, code, lookups) { lookups = lookups || {}; var blocks = [], sindexes = [], sindex = 0, eindexes = [], eindex = 0; while ((sindex = code.indexOfAlt(start, sindex)) != -1 && (eindex = code.indexOfAlt(end, eindex)) != -1) { sindex != -1 && (sindexes.push(sindex), sindex++); eindex != -1 && (eindexes.push(eindex), eindex++); } // if true syntax error, start end missmatch if (sindexes.length != eindexes.length) { blocks.push({id: uid, block: "", body:"", code: code}); return blocks; } var j, pairs = OrderedList([], function (a, b) { if (a.end < b.end) { return -1; } if (a.end > b.end) { return 1; } return 0; }); j = 0; while (j < sindexes.length) { var e = 0; while (eindexes[0] > sindexes[e]) { e++; } e--; pairs.add({begin: sindexes[e], end: eindexes[0]}); sindexes.removeAt(e); eindexes.removeAt(0); } var endlength = code.match(end)[0].length; for (var k = 0, len = pairs.size(); k < len; k++) { var uid = "##" + suid() + "##", block = code.slice(pairs[k].begin, pairs[k].end + endlength), beginLength = block.match(start)[0].length, body = code.slice(pairs[k].begin + beginLength, pairs[k].end); code = code.replace(block, uid); blocks.push({id: uid, block: block, body: body, code: code}); lookups[uid] = block; for (var i = k + 1; i < len; i++) { var offset = block.length - uid.length; pairs[i].end -= offset; if (pairs[i].begin > pairs[k].end) { pairs[i].begin -= offset; } } } return blocks.reverse(); } function __parseArithmeticExpr (doc,expr,field) { try { var value; switch (field) { case "$add": value = 0; for (var i = 0, len = expr["$add"].length; i < len; i++) { value += __processExpression(doc, expr["$add"][i]); } return value; case "$subtract": return __processExpression(doc, expr["$subtract"][0]) - __processExpression(doc, expr["$subtract"][1]); case "$multiply": value = 1; for (var i = 0, len = expr["$multiply"].length; i < len; i++) { value *= __processExpression(doc, expr["$multiply"][i]); } return value; case "$divide": return __processExpression(doc, expr["$divide"][0]) / __processExpression(doc, expr["$divide"][1]); case "$mod": return __processExpression(doc, expr["$mod"][0]) % __processExpression(doc, expr["$mod"][1]); } } catch (e) { error('aggregate.__parseArithmeticExpr', e); } } function __parseArrayExpr (doc,expr,field) { try { switch (field) { case "$size": return (__processExpression(doc, expr, field) || []).length; } } catch (e) { error('aggregate.__parseArrayExpr', e); } } function __parseBooleanExpr (doc,expr,field) { try { var arr = []; switch (field) { case "$and": arr = expr["$and"]; for (var i = 0, len = arr.length; i < len; i++) { if (!__processExpression(doc, expr[i])) { return false; } } return true; case "$or": arr = expr["$or"]; for (var i = 0, len = arr.length; i < len; i++) { if (__processExpression(doc, expr[i])) { return true; } } return false; case "$not": arr = expr["$not"]; return !__processExpression(doc, expr[0]); } } catch (e) { error('aggregate.__parseBooleanExpr', e); } } function __parseComparisonExpr (doc,expr,field) { try { var sortOrder = [ undefined, null, Number, typeof Symbol != "undefined" ? Symbol : "Symbol", String, Object, Array, typeof BinData != "undefined" ? BinData : "BinData", typeof ObjectId != "undefined" ? ObjectId : "ObjectId", Boolean, Date, typeof Timestamp != "undefined" ? Timestamp : "Timestamp", RegExp], value1 = __processExpression(doc, expr[field][0]), value2 = __processExpression(doc, expr[field][1]), cmp = null; if (value1 == value2) { cmp = 0; } if (value1 < value2) { cmp = -1; } if (value1 > value2) { cmp = 1; } if (isNull(cmp)) { value1 = sortOrder.indexOf([null, undefined].contains(value1) ? value1 : value1.constructor); value2 = sortOrder.indexOf([null, undefined].contains(value2) ? value2 : value2.constructor); if (value1 < value2) { cmp = -1; } if (value1 > value2) { cmp = 1; } } switch (field) { case "$cmp": return cmp; case "$eq": return cmp === 0; case "$gt": return cmp === 1; case "$gte": return cmp === 1 || cmp === 0; case "$lt": return cmp === -1; case "$lte": return cmp === -1 || cmp === 0; case "$ne": return cmp !== 0; } } catch (e) { error('aggregate.__parse', e); } } function __parseCond(doc,expr){ try { if (!$c.isObject(expr) || !expr['$cond']) { return expr; } // parse $cond var condition = expr['$cond'], boolExpression, thenStatement, elseStatement; if ($c.isArray(condition)) { boolExpression = condition[0]; thenStatement = condition[1]; elseStatement = condition[2]; } else { boolExpression = condition["if"]; thenStatement = condition["then"]; elseStatement = condition["else"]; } //return [doc].where(boolExpression).length ? thenStatement : elseStatement; return __processExpression(doc, boolExpression) ? thenStatement : elseStatement; } catch (e) { error('aggregate.__parseCond', e); } } function __parseConditionalExpr (doc,expr,field) { try { switch (field) { case "$cond": return __parseCond(doc, expr); case "$ifNull": var value = __processExpression(doc, expr["$ifNull"][0]); return isNull(value) ? __processExpression(doc, expr["$ifNull"][1]) : value; } } catch (e) { error('aggregate.__parseConditionExpr', e); } } function __parseDateExpr (doc,expr,field) { var dt = __processExpression(doc, expr[field]); try { switch (field) { case "$dayOfYear": return dt.getDayOfYear(); case "$dayOfMonth": return dt.getDate(); case "$dayOfWeek": return dt.getDay() + 1; case "$year": return dt.getFullYear(); case "$month": return dt.getMonth() + 1; case "$week": return dt.getWeek(); case "$hour": return dt.getHours(); case "$minute": return dt.getMinutes(); case "$second": return dt.getSeconds(); case "$millisecond": return dt.getMilliseconds(); case "$dateToString": dt = __processExpression(doc, expr[field].date); return dt.format(expr[field].format) } } catch (e) { error('aggregate.__parseDateExpr', e); } } function __parseSetExpr (doc,expr,field) { try { switch (field) { case "$setEquals": for (var i = 1, len = expr[field].length; i < len; i++) { var set1 = $c.duplicate(__processExpression(doc, expr[field][i - 1])), set2 = $c.duplicate(__processExpression(doc, expr[field][i])); if (!$c.isArray(set1) || !$c.isArray(set2)){ //noinspection ExceptionCaughtLocallyJS throw "Exception: All operands of $setEquals must be arrays. One argument is of type: " + (typeof (!$c.isArray(set1) ? set1 : set2)).captialize(); } set1.toSet(); set2.toSet(); if (set1.length != set2.length) { return false; } for (var j = 0, jlen = set1.length; j < jlen; j++) { if (!set2.contains(set1[j])) { return false; } } } return true; case "$setIntersection": var rtnSet = $c.duplicate(__processExpression(doc, expr[field][0])), errorMessage = "Exception: All operands of $setIntersection must be arrays. One argument is of type: "; if(!$c.isArray(rtnSet)) { //noinspection ExceptionCaughtLocallyJS throw errorMessage + (typeof rtnSet).captialize(); } rtnSet.toSet(); for (var i = 1, len = expr[field].length; i < len; i++) { var set1 = $c.duplicate(__processExpression(doc, expr[field][i])); if (!$c.isArray(set1)){ //noinspection ExceptionCaughtLocallyJS throw errorMessage + + (typeof set1).captialize(); } set1.toSet(); if (set1.length < rtnSet.length) { var settmp = set1; set1 = rtnSet; rtnSet = settmp; } for (var j = 0; j < rtnSet.length; j++) { if (!set1.contains(rtnSet[j])) { rtnSet.removeAt(j); j--; } } if (!rtnSet.length) { return rtnSet; } } return rtnSet; case "$setUnion": var rtnSet = $c.duplicate(__processExpression(doc, expr[field][0])), errorMessage = "Exception: All operands of $setUnion must be arrays. One argument is of type: "; if(!$c.isArray(rtnSet)) { //noinspection ExceptionCaughtLocallyJS throw errorMessage + (typeof rtnSet).captialize(); } //rtnSet.toSet(); for (var i = 1, len = expr[field].length; i < len; i++) { var arr = $c.duplicate(__processExpression(doc, expr[field][i])); if (!$c.isArray(arr)){ //noinspection ExceptionCaughtLocallyJS throw errorMessage + + (typeof arr).captialize(); } rtnSet = rtnSet.concat(arr); } return rtnSet.toSet(); case "$setDifference": var arr1 = $c.duplicate(__processExpression(doc, expr[field][0])), arr2 = $c.duplicate(__processExpression(doc, expr[field][1])), rtnSet = []; if (!$c.isArray(arr1) || !$c.isArray(arr2)){ //noinspection ExceptionCaughtLocallyJS throw "Exception: All operands of $setEquals must be arrays. One argument is of type: " + (typeof (!$c.isArray(arr1) ? arr1 : arr2)).captialize(); } for (var i = 0, len = arr1.length; i < len; i++) { var item = arr1[i]; if (!arr2.contains(item) && !rtnSet.contains(item)) { rtnSet.push(item); } } return rtnSet; case "$setIsSubset": var arr1 = $c.duplicate(__processExpression(doc, expr[field][0])), arr2 = $c.duplicate(__processExpression(doc, expr[field][1])), rtnSet = []; if (!$c.isArray(arr1) || !$c.isArray(arr2)){ //noinspection ExceptionCaughtLocallyJS throw "Exception: All operands of $setEquals must be arrays. One argument is of type: " + (typeof (!$c.isArray(arr1) ? arr1 : arr2)).captialize(); } return $c.isSubset(arr1,arr2); case "$anyElementTrue": var arr1 = $c.duplicate(__processExpression(doc, expr[field][0])), falseCondition = [undefined,null,0,false]; for (var i = 0, len = arr1.length; i < len; i++) { var item = arr1[i]; if (!falseCondition.contains(item)) { return true; } } return false; case "$allElementsTrue": var arr1 = $c.duplicate(__processExpression(doc, expr[field][0])), falseCondition = [undefined,null,0,false]; for (var i = 0, len = arr1.length; i < len; i++) { var item = arr1[i]; if (falseCondition.contains(item)) { return false; } } return true; } } catch (e) { error('aggregate.__parseSetExpr', e); } } function __parseStringExpr (doc,expr,field) { try { switch (field) { case "$concat": var value = ""; for (var i = 0, len = expr["$concat"].length; i < len; i++) { value += __processExpression(doc, expr["$concat"][i]); } return value; case "$substr": var index = expr["$substr"][1], length = expr["$substr"][2] < 0 ? undefined : expr["$substr"][2]; return __processExpression(doc, expr["$substr"][0]).substr(index, length); case "$toLower": return (__processExpression(doc, expr["$toLower"]) || "").toLowerCase(); case "$toUpper": return (__processExpression(doc, expr["$toLower"]) || "").toUpperCase(); case "$strcasecmp": var value1 = (__processExpression(doc, expr["$strcasecmp"][0]) || "").toString(), value2 = (__processExpression(doc, expr["$strcasecmp"][1]) || "").toString(); if (value1 == value2) { return 0; } if (value1 < value2) { return -1; } if (value1 > value2) { return 1; } } } catch (e) { error('aggregate.__parseStringExpr', e); } } function __parseVariableExpr (doc,expr,field) { try { switch (field) { case "$map": var input = __processExpression(doc, expr[field].input), v_as = "$" + expr[field].as, v_in = expr[field]["in"]; for (var i = 0, len = input.length; i < len; i++) { doc[v_as] = input[i]; input[i] = __processExpression(doc, v_in); delete doc[v_as]; } return input; case "$let": var vars = expr[field].vars, rmProps = [], rtn = null; for (var prop in vars) { if (!vars.hasOwnProperty(prop)) { continue; } doc["$" + prop] = __processExpression(doc, vars[prop]); rmProps.push(prop); } rtn = __processExpression(doc, expr[field]["in"]); for (var i = 0, len = rmProps.length; i < len; i++) { delete doc[rmProps[i]]; } return rtn; } } catch (e) { error('aggregate.__parseVariableExpr', e); } } function __processAccumulator (doc,accumulator,previousValue,meta) { try { var value = __processExpression(doc, accumulator["$sum"] || accumulator["$avg"] || accumulator["$first"] || accumulator["$last"] || accumulator["$max"] || accumulator["$min"] || accumulator["$push"] || accumulator["$addToSet"]); switch (true) { case !!accumulator["$sum"]: return value + (previousValue || 0); case !!accumulator["$avg"]: previousValue = previousValue || {n:0,avg:0}; //if (isNull(previousValue)) { // (previousValue = 0).n = 0; //} previousValue.avg = ((previousValue.avg / (previousValue.n || 1)) + value) / previousValue.n; if (meta.length == meta.index + 1) { previousValue = previousValue.avg; } return previousValue; case !!accumulator["$first"]: if(isNull(previousValue)) { previousValue = value; } return previousValue; case !!accumulator["$last"]: return value; case !!accumulator["$max"]: return Math.max(value, (previousValue || -9007199254740991)); case !!accumulator["$min"]: return Math.min(value, (previousValue || 9007199254740991)); case !!accumulator["$push"]: return (previousValue || []).push(value); case !!accumulator["$addToSet"]: previousValue = previousValue || []; if (!previousValue.contains(value)) { previousValue.push(value); } return previousValue; } } catch (e) { error('aggregate.__processAccumulator', e); } } function __processExpression (doc,expr) { try { if ($c.isString(expr)) { if (expr[0] == "$") { expr = expr.substr(1); } return $c.getProperty(doc, expr.replace("$CURRENT.", "")); } else if (!$c.isObject(expr)) { return expr; } //var exprKeys = { // //}; for (var field in expr) { if (!expr.hasOwnProperty(field)) { continue; } var value = expr[field], literalKeys = ["$literal"], boolKeys = ["$and", "$or", "$not"], setKeys = ["$setEquals", "$setIntersection", "$setUnion", "$setDifference", "$setIsSubset", "$anyElementTrue", "$allElementsTrue"], compareKeys = ["$cmp", "$eq", "$gt", "$gte", "$lt", "$lte", "$ne"], arithmeticKeys = ["$add", "$subtract", "$multiply", "$divide", "$mod"], stringKeys = ["$concat", "$substr", "$toLower", "$toUpper", "$strcasecmp"], //searchKeys = ["meta"], arrayKeys = ["$size"], variableKeys = ["$map", "$let"], dateKeys = ["$dayOfYear", "$dayOfMonth", "$dayOfWeek", "$year", "$month", "$week", "$hour", "$minute", "$second", "$millisecond", "$dateToString"], conditionalKeys = ["$cond", "$ifNull"]; //accumulatorKeys = ["$sum", "$avg", "$first", "$last", "$max", "$min", "$push", "$addToSet"]; switch (true) { case literalKeys.contains(field): return expr; case boolKeys.contains(field): return __parseBooleanExpr(doc, expr, field); case setKeys.contains(field): return __parseSetExpr(doc, expr, field); case compareKeys.contains(field): return __parseComparisonExpr(doc, expr, field); case arithmeticKeys.contains(field): return __parseArithmeticExpr(doc, expr, field); case stringKeys.contains(field): return __parseStringExpr(doc, expr, field); //case searchKeys.contains(field): // return __parseTextSearchExpr (doc,expr); case arrayKeys.contains(field): return __parseArrayExpr(doc, expr, field); case variableKeys.contains(field): return __parseVariableExpr(doc, expr, field); case dateKeys.contains(field): return __parseDateExpr(doc, expr, field); case conditionalKeys.contains(field): return __parseConditionalExpr(doc, expr, field); //case accumulatorKeys.contains(field): // return __parseAccumulatorExpr(doc, expr, field); default: __processExpression (doc,value); break; } } } catch (e) { error('aggregate.__parseExpression', e); } } function __processGroup (docs, expr) { try { var _ids = expr._id, doc, i = 0, groupings = {}, results = [], meta = {index:0,length:docs.length/*,stop:false*/}; //while(doc = docs[i++]) { for (var i = 0, len = docs.length; i < len; i++,meta.index = i) { var doc = docs[i],result, key = "null", keys; if (_ids) { keys = {}; for (var prop in _ids) { if (!_ids.hasOwnProperty(prop)) { continue; } keys[prop] = __processExpression(doc, _ids[prop]); } key = JSON.stringify(keys); } if (!groupings[key]) { result = groupings[key] = {_id:keys}; results.push(result); } else { result = groupings[key]; } for (var prop in expr) { if (!expr.hasOwnProperty(prop) || prop == "_id") { continue; } result[prop] = __processAccumulator(doc, expr[prop],result[prop], meta); //if (meta.stop) { break; } } } return results; } catch (e) { error('aggregate.__processGroup', e); } } function __processStage(docs, stage) { try { var operator = "", value = {}; for (var opts in stage) { if (!stage.hasOwnProperty(opts)) { continue; } if (operator) { //noinspection ExceptionCaughtLocallyJS throw "Exception: A pipeline stage specification object must contain exactly one field."; } operator = opts; value = stage[opts]; } switch (opts) { case "$project": for (var i = 0, len = docs.length; i < len; i++) { var doc = {}; for (var prop in value) { if (!value.hasOwnProperty(prop)) { continue; } if ($c.parseBoolean(value[prop])) { doc[prop] = docs[i]; } else { doc[prop] = __processExpression(docs[i], value[prop]); } } docs.replaceAt(i, doc); } return docs.where({}, value); case "$match": return docs.where(value); case "$redact": return _redact(docs, value); case "$limit": return docs.slice(0, value); case "$skip": return docs.slice(value); case "$unwind": return _unwind(docs, value); case "$group": return __processGroup(docs, value); case "$sort": var sorter = []; for (var prop in value) { if (!value.hasOwnProperty(prop)) { continue; } var pre = ""; if (value[prop] == -1) { pre = "!"; } sorter.push(pre+prop); } return docs.sortBy(sorter); //case "$geoNear": // break; case "$out": var rtnDocs = $c.duplicate(docs,true); if ($c.isString(value)) { $w[value] = rtnDocs; } else if ($c.isArray(value)) { value.removeAll(); $c.merge(value,rtnDocs); } return rtnDocs; } return docs; } catch (e) { error('aggregate.__processStage', e); } } function __run_replace (reg, template, use_run, obj) { try { var pre = "", post = "", split_param = "|", match; //noinspection CommaExpressionJS use_run && (pre="RUN[",post="]", split_param=/;(?!\\)/); while ((match = reg.exec(template)) && match[1]) { var funcValue = [], func = ""; funcValue = match[1].replace_all(['\\[','\\]'],['[',']']).split(split_param); while (funcValue[0].count("{") != funcValue[0].count("}")) { funcValue[0]+= funcValue[1]+($c.isString(split_param)?split_param:";"); funcValue.splice(1,1); } func = funcValue.splice(0,1)[0].strip(";"); for (var i = 0, len = funcValue.length; i < len; i++) { if (funcValue[i].contains("${")) { funcValue[i] = fillTemplate(funcValue[i], obj); } try { //funcValue[i] = eval("(" + funcValue[i].replace_all([';\\','\\[','\\]'], [';','[',']']) + ")"); funcValue[i] = eval("(" + funcValue[i].replace_all([';\\'], [';']) + ")"); } catch (e) {} } template = template.contains(match[1]) ? template.replace(match[1], (match[1] = match[1].replace_all(['\\[', '\\]'], ['[', ']']))) : template; template = template.replace_all("${" + pre + match[1] + post +"}", $w.getProperty(func) ? $w.getProperty(func).apply(obj, funcValue) : (tryEval("("+func+")")||foo)() || ""); } return template; } catch (e) { error('fillTemplate.__run_replace', e); } } function _ajaxServerResponse(response) { try { if (response.readyState == 4 && response.status==200) { var objResponse = {}; try { objResponse = eval(response.responseText.trim()); } catch (e) { objResponse = eval("(" + response.responseText.trim() + ")"); } if (!objResponse || objResponse.hasErrors) { return false; } return objResponse; } return false; } catch (e) { error("ajax._ajaxServerResponse", e); return false; } } function _condense (obj, check_values) { try { var skip = [], arr = [], without = false; if (check_values && check_values.constructor == Array) { without = true; } for (var i = 0, len = obj.length; i < len; i++) { if (check_values) { var index = i; if (without && check_values.contains(obj[i])) { skip.push(i); continue; } if (skip.indexOf(i) != -1) { continue; } while ((index = obj.indexOf(obj[i],index+1)) != -1) { skip.push(index); } } (skip.indexOf && skip.indexOf(i) || _indexOf(skip, i)) == -1 && !isNull(obj[i]) && arr.push(obj[i]); } return arr; } catch (e) { error("_condence", e); return false; } } function _copyWithProjection(projection, record) { var copy = {}, len = 0; projection = projection || "*"; if ($c.isString(projection)) { projection = projection.split(','); } if ($c.isArray(projection)) { if (!(len = projection.length)) { // _copyWithProjectionHelper(record,copy); copy = $c.duplicate(record); return copy; } var arr = projection; projection = {}; for (var i = 0; i < len; i++) { projection[arr[i]] = 1; } } for (var prop in projection) { if (projection.has(prop)) { if (prop == "*") { // _copyWithProjectionHelper(record,copy); copy = $c.duplicate(record); } else if (record[prop] && !$c.isArray(record[prop])) { copy[prop] = record[prop]; } else if (record[prop]) { var del = true; if (prop.slice(-2) == ".$") { prop = prop.slice(0,-2); copy[prop] = record[prop].slice(0,1); } else if (projection[prop]['$elemMatch']) { copy[prop] = record[prop].where(projection[prop]['$elemMatch']).slice(0,1); } else if (projection[prop]['$slice']) { var start = 0, length = $c.isInt(projection[prop]['$slice']) ? projection[prop]['$slice'] : 0; if ($c.isArray(projection[prop]['$slice'])) { start = projection[prop]['$slice'][0]; length = projection[prop]['$slice'][1]; } copy[prop] = record[prop].slice(start, length); } else if (projection[prop]) { del = false; copy[prop] = record[prop]; } if (del && !copy[prop].length) { delete copy[prop]; } } else { copy[prop] = projection[prop]; } } } return copy; } function _copyWithProjectionHelper(record,copy) { for (var prop in record) { if (record.has(prop)) { copy[prop] = record[prop]; } } } function _craydentSelector (by, overwrite, object, single) { try { if (!object || object === true) { return undefined; } var elem = $d[by](object); if (single) { return ((elem && ((elem.length && elem[0]) || elem)) || $w[overwrite](object)[0]); } return (elem || $w[overwrite](object)); } catch (e) { error('_craydentSelector', e); } } function _dataset (){ try { var attributes = this.attributes, ds = {}; for (var i in attributes) { if (!attributes.hasOwnProperty(i)) { continue; } var attribute = attributes[i]; if (attribute.name.indexOf("data-") == 0) { ds[attribute.name.substring(5)] = attribute.value; } } return ds; } catch (e) { error("DOM._dataset", e); } } function _defineFunction (name, func, override) { try { var args = _getFuncArgs(func), fstr = func.toString().replace(/this/g