+18
-19
| { | ||
| "name": "js-select", | ||
| "description": "Traverse and modify objects with JSONSelect selectors", | ||
| "version": "0.6.0", | ||
| "author": "Heather Arthur <fayearthur@gmail.com>", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "http://github.com/harthur/js-select.git" | ||
| }, | ||
| "main": "./index", | ||
| "dependencies": { | ||
| "traverse": "0.4.x", | ||
| "JSONSelect": "0.2.1" | ||
| }, | ||
| "devDependencies": { | ||
| "nomnom": "0.6.x", | ||
| "color": "0.3.x" | ||
| }, | ||
| "keywords": ["json"] | ||
| } | ||
| "name": "js-select", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/npm/deprecate-holder.git" | ||
| }, | ||
| "author": "", | ||
| "license": "ISC", | ||
| "bugs": { | ||
| "url": "https://github.com/npm/deprecate-holder/issues" | ||
| }, | ||
| "homepage": "https://github.com/npm/deprecate-holder#readme" | ||
| } |
+3
-116
@@ -1,118 +0,5 @@ | ||
| # js-select | ||
| # Deprecated Package | ||
| js-select uses [js-traverse](https://github.com/substack/js-traverse) to traverse and modify JavaScript object nodes that match [JSONSelect](http://jsonselect.org/) selectors. | ||
| This package is no longer supported and has been deprecated. To avoid malicious use, npm is hanging on to the package name. | ||
| ```javascript | ||
| var people = { | ||
| george: { | ||
| age : 35, | ||
| movie: "Repo Man" | ||
| }, | ||
| mary: { | ||
| age: 15, | ||
| movie: "Twilight" | ||
| } | ||
| }; | ||
| ``` | ||
| ### .forEach(fn) | ||
| Iterates over all matching nodes in the object. The callback gets a special `this` context. See [js-traverse](https://github.com/substack/js-traverse) for all the things you can do to modify and inspect the node with this context. In addition, js-select adds a `this.matches()` which will test if the node matches a selector: | ||
| ```javascript | ||
| select(people).forEach(function(node) { | ||
| if (this.matches(".mary > .movie")) { | ||
| this.remove(); | ||
| } | ||
| }); | ||
| ``` | ||
| ### .nodes() | ||
| Returns all matching nodes from the object. | ||
| ```javascript | ||
| select(people, ".age").nodes(); // [35, 15] | ||
| ``` | ||
| ### .remove() | ||
| Removes matching elements from the original object. | ||
| ```javascript | ||
| select(people, ".age").remove(); | ||
| ``` | ||
| ### .update(fn) | ||
| Updates all matching nodes using the given callback. | ||
| ```javascript | ||
| select(people, ".age").update(function(age) { | ||
| return age - 5; | ||
| }); | ||
| ``` | ||
| ### .condense() | ||
| Reduces the original object down to only the matching elements (the hierarchy is maintained). | ||
| ```javascript | ||
| select(people, ".age").condense(); | ||
| ``` | ||
| ```javascript | ||
| { | ||
| george: { age: 35 }, | ||
| mary: { age: 15 } | ||
| } | ||
| ``` | ||
| ## Selectors | ||
| js-select supports the following [JSONSelect](http://jsonselect.org/) selectors: | ||
| ``` | ||
| * | ||
| type | ||
| .key | ||
| ancestor selector | ||
| parent > selector | ||
| sibling ~ selector | ||
| selector1, selector2 | ||
| :root | ||
| :nth-child(n) | ||
| :nth-child(even) | ||
| :nth-child(odd) | ||
| :nth-last-child(n) | ||
| :first-child | ||
| :last-child | ||
| :only-child | ||
| :has(selector) | ||
| :val("string") | ||
| :contains("substring") | ||
| ``` | ||
| See [details](http://jsonselect.org/#docs/overview) on each selector, and [try them](http://jsonselect.org/#tryit) out on the JSONSelect website. | ||
| ## Install | ||
| For [node](http://nodejs.org), install with [npm](http://npmjs.org): | ||
| ```bash | ||
| npm install js-select | ||
| ``` | ||
| For the browser, download the select.js file or fetch the latest version from [npm](http://npmjs.org) and build a browser file using [browserify](https://github.com/substack/node-browserify): | ||
| ```bash | ||
| npm install browserify -g | ||
| npm install js-select | ||
| browserify --require js-select --outfile select.js | ||
| ``` | ||
| this will build a browser file with `require('js-select')` available. | ||
| ## Propers | ||
| Huge thanks to [@substack](http://github.com/substack) for the ingenious [js-traverse](https://github.com/substack/js-traverse) and [@lloyd](https://github.com/lloyd) for the ingenious [JSONSelect spec](http://http://jsonselect.org/) and [selector parser](http://search.npmjs.org/#/JSONSelect). | ||
| Please contact support@npmjs.com if you have questions about this package. |
-197
| var traverse = require("traverse"), | ||
| JSONSelect = require("JSONSelect"); | ||
| module.exports = function(obj, string) { | ||
| var sels = parseSelectors(string); | ||
| return { | ||
| nodes: function() { | ||
| var nodes = []; | ||
| this.forEach(function(node) { | ||
| nodes.push(node); | ||
| }); | ||
| return nodes; | ||
| }, | ||
| update: function(cb) { | ||
| this.forEach(function(node) { | ||
| this.update(typeof cb == "function" ? cb(node) : cb); | ||
| }); | ||
| return obj; | ||
| }, | ||
| remove: function() { | ||
| this.forEach(function(node) { | ||
| this.remove(); | ||
| }) | ||
| return obj; | ||
| }, | ||
| condense: function() { | ||
| traverse(obj).forEach(function(node) { | ||
| if (!this.parent) return; | ||
| if (this.parent.keep) { | ||
| this.keep = true; | ||
| } else { | ||
| var match = matchesAny(sels, this); | ||
| this.keep = match; | ||
| if (!match) { | ||
| if (this.isLeaf) { | ||
| this.remove(); | ||
| } else { | ||
| this.after(function() { | ||
| if (this.keep_child) { | ||
| this.parent.keep_child = true; | ||
| } | ||
| if (!this.keep && !this.keep_child) { | ||
| this.remove(); | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| this.parent.keep_child = true; | ||
| } | ||
| } | ||
| }); | ||
| return obj; | ||
| }, | ||
| forEach: function(cb) { | ||
| traverse(obj).forEach(function(node) { | ||
| if (matchesAny(sels, this)) { | ||
| this.matches = function(string) { | ||
| return matchesAny(parseSelectors(string), this); | ||
| }; | ||
| // inherit context from js-traverse | ||
| cb.call(this, node); | ||
| } | ||
| }); | ||
| return obj; | ||
| } | ||
| }; | ||
| } | ||
| function parseSelectors(string) { | ||
| var parsed = JSONSelect._parse(string || "*")[1]; | ||
| return getSelectors(parsed); | ||
| } | ||
| function getSelectors(parsed) { | ||
| if (parsed[0] == ",") { // "selector1, selector2" | ||
| return parsed.slice(1); | ||
| } | ||
| return [parsed]; | ||
| } | ||
| function matchesAny(sels, context) { | ||
| for (var i = 0; i < sels.length; i++) { | ||
| if (matches(sels[i], context)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function matches(sel, context) { | ||
| var path = context.parents.concat([context]), | ||
| i = path.length - 1, | ||
| j = sel.length - 1; | ||
| // walk up the ancestors | ||
| var must = true; | ||
| while(j >= 0 && i >= 0) { | ||
| var part = sel[j], | ||
| context = path[i]; | ||
| if (part == ">") { | ||
| j--; | ||
| must = true; | ||
| continue; | ||
| } | ||
| if (matchesKey(part, context)) { | ||
| j--; | ||
| } | ||
| else if (must) { | ||
| return false; | ||
| } | ||
| i--; | ||
| must = false; | ||
| } | ||
| return j == -1; | ||
| } | ||
| function matchesKey(part, context) { | ||
| var key = context.key, | ||
| node = context.node, | ||
| parent = context.parent; | ||
| if (part.id && key != part.id) { | ||
| return false; | ||
| } | ||
| if (part.type) { | ||
| var type = part.type; | ||
| if (type == "null" && node !== null) { | ||
| return false; | ||
| } | ||
| else if (type == "array" && !isArray(node)) { | ||
| return false; | ||
| } | ||
| else if (type == "object" && (typeof node != "object" | ||
| || node === null || isArray(node))) { | ||
| return false; | ||
| } | ||
| else if ((type == "boolean" || type == "string" || type == "number") | ||
| && type != typeof node) { | ||
| return false; | ||
| } | ||
| } | ||
| if (part.pf == ":nth-child") { | ||
| var index = parseInt(key) + 1; | ||
| if ((part.a == 0 && index !== part.b) // :nth-child(i) | ||
| || (part.a == 1 && !(index >= -part.b)) // :nth-child(n) | ||
| || (part.a == -1 && !(index <= part.b)) // :nth-child(-n + 1) | ||
| || (part.a == 2 && index % 2 != part.b)) { // :nth-child(even) | ||
| return false; | ||
| } | ||
| } | ||
| if (part.pf == ":nth-last-child" | ||
| && (!parent || key != parent.node.length - part.b)) { | ||
| return false; | ||
| } | ||
| if (part.pc == ":only-child" | ||
| && (!parent || parent.node.length != 1)) { | ||
| return false; | ||
| } | ||
| if (part.pc == ":root" && key !== undefined) { | ||
| return false; | ||
| } | ||
| if (part.has) { | ||
| var sels = getSelectors(part.has[0]), | ||
| match = false; | ||
| traverse(node).forEach(function(child) { | ||
| if (matchesAny(sels, this)) { | ||
| match = true; | ||
| } | ||
| }); | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| } | ||
| if (part.expr) { | ||
| var expr = part.expr, lhs = expr[0], op = expr[1], rhs = expr[2]; | ||
| if (typeof node != "string" | ||
| || (!lhs && op == "=" && node != rhs) // :val("str") | ||
| || (!lhs && op == "*=" && node.indexOf(rhs) == -1)) { // :contains("substr") | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| var isArray = Array.isArray || function(obj) { | ||
| return toString.call(obj) === '[object Array]'; | ||
| } |
-21
| Copyright (c) 2011 Heather Arthur | ||
| Permission is hereby granted, free of charge, to any person obtaining | ||
| a copy of this software and associated documentation files (the | ||
| "Software"), to deal in the Software without restriction, including | ||
| without limitation the rights to use, copy, modify, merge, publish, | ||
| distribute, sublicense, and/or sell copies of the Software, and to | ||
| permit persons to whom the Software is furnished to do so, subject to | ||
| the following conditions: | ||
| The above copyright notice and this permission notice shall be | ||
| included in all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| var select=function(){var c=function(j,f){var d=c.resolve(j,f||"/"),l=c.modules[d];if(!l)throw Error("Failed to resolve module "+j+", tried "+d);return(d=c.cache[d])?d.exports:l()};c.paths=[];c.modules={};c.cache={};c.extensions=[".js",".coffee"];c._core={assert:!0,events:!0,fs:!0,path:!0,vm:!0};c.resolve=function(j,f){function d(b){b=h.normalize(b);if(c.modules[b])return b;for(var a=0;a<c.extensions.length;a++){var e=c.extensions[a];if(c.modules[b+e])return b+e}}function l(b){var b=b.replace(/\/+$/, | ||
| ""),a=h.normalize(b+"/package.json");if(c.modules[a]){var a=c.modules[a](),e=a.browserify;if("object"===typeof e&&e.main){if(a=d(h.resolve(b,e.main)))return a}else if("string"===typeof e){if(a=d(h.resolve(b,e)))return a}else if(a.main&&(a=d(h.resolve(b,a.main))))return a}return d(b+"/index")}f||(f="/");if(c._core[j])return j;var h=c.modules.path(),a=(f=h.resolve("/",f))||"/";if(j.match(/^(?:\.\.?\/|\/)/)){var e=d(h.resolve(a,j))||l(h.resolve(a,j));if(e)return e}a:{for(var e="/"===a?[""]:h.normalize(a).split("/"), | ||
| a=[],g=e.length-1;0<=g;g--)if("node_modules"!==e[g]){var b=e.slice(0,g+1).join("/")+"/node_modules";a.push(b)}for(e=0;e<a.length;e++){g=a[e];if(b=d(g+"/"+j)){a=b;break a}if(g=l(g+"/"+j)){a=g;break a}}a=(b=d(j))?b:void 0}if(a)return a;throw Error("Cannot find module '"+j+"'");};c.alias=function(j,f){var d=c.modules.path(),l=null;try{l=c.resolve(j+"/package.json","/")}catch(h){l=c.resolve(j,"/")}for(var d=d.dirname(l),l=(Object.keys||function(a){var b=[],e;for(e in a)b.push(e);return b})(c.modules), | ||
| a=0;a<l.length;a++){var e=l[a];e.slice(0,d.length+1)===d+"/"?(e=e.slice(d.length),c.modules[f+e]=c.modules[d+e]):e===d&&(c.modules[f]=c.modules[d])}};var u={};c.define=function(j,f){c.modules.__browserify_process&&(u=c.modules.__browserify_process());var d=c._core[j]?"":c.modules.path().dirname(j),l=function(a){var e=c(a,d);if((a=c.cache[c.resolve(a,d)])&&null===a.parent)a.parent=h;return e};l.resolve=function(a){return c.resolve(a,d)};l.modules=c.modules;l.define=c.define;l.cache=c.cache;var h={id:j, | ||
| filename:j,exports:{},loaded:!1,parent:null};c.modules[j]=function(){c.cache[j]=h;f.call(h.exports,l,h,h.exports,d,j,u);h.loaded=!0;return h.exports}};c.define("path",function(c,f,d,l,h,a){function e(a,b){for(var e=[],g=0;g<a.length;g++)b(a[g],g,a)&&e.push(a[g]);return e}function g(a,b){for(var e=0,g=a.length;0<=g;g--){var d=a[g];"."==d?a.splice(g,1):".."===d?(a.splice(g,1),e++):e&&(a.splice(g,1),e--)}if(b)for(;e--;e)a.unshift("..");return a}var b=/^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;d.resolve= | ||
| function(){for(var b="",o=!1,d=arguments.length;-1<=d&&!o;d--){var c=0<=d?arguments[d]:a.cwd();"string"===typeof c&&c&&(b=c+"/"+b,o="/"===c.charAt(0))}b=g(e(b.split("/"),function(a){return!!a}),!o).join("/");return(o?"/":"")+b||"."};d.normalize=function(a){var b="/"===a.charAt(0),d="/"===a.slice(-1),a=g(e(a.split("/"),function(a){return!!a}),!b).join("/");!a&&!b&&(a=".");a&&d&&(a+="/");return(b?"/":"")+a};d.join=function(){var a=Array.prototype.slice.call(arguments,0);return d.normalize(e(a,function(a){return a&& | ||
| "string"===typeof a}).join("/"))};d.dirname=function(a){return(a=b.exec(a)[1]||"")?1===a.length?a:a.substring(0,a.length-1):"."};d.basename=function(a,e){var g=b.exec(a)[2]||"";e&&g.substr(-1*e.length)===e&&(g=g.substr(0,g.length-e.length));return g};d.extname=function(a){return b.exec(a)[3]||""}});c.define("__browserify_process",function(c,f,d,l,h,a){var f=a=f.exports={},e=[],g="undefined"!==typeof window&&window.postMessage&&window.addEventListener;g&&window.addEventListener("message",function(a){a.source=== | ||
| window&&"browserify-tick"===a.data&&(a.stopPropagation(),0<e.length&&e.shift()())},!0);f.nextTick=function(a){g?(e.push(a),window.postMessage("browserify-tick","*")):setTimeout(a,0)};a.title="browser";a.browser=!0;a.env={};a.argv=[];a.binding=function(a){if("evals"===a)return c("vm");throw Error("No such module. (Possibly not yet loaded)");};var b="/",t;a.cwd=function(){return b};a.chdir=function(a){t||(t=c("path"));b=t.resolve(a,b)}});c.define("vm",function(c,f){f.exports=c("vm-browserify")});c.define("/node_modules/vm-browserify/package.json", | ||
| function(c,f){f.exports={main:"index.js"}});c.define("/node_modules/vm-browserify/index.js",function(c,f,d){var l=function(a){if(Object.keys)return Object.keys(a);var g=[],b;for(b in a)g.push(b);return g},h=function(a,g){if(a.forEach)return a.forEach(g);for(var b=0;b<a.length;b++)g(a[b],b,a)},a=d.Script=function(e){if(!(this instanceof a))return new a(e);this.code=e};a.prototype.runInNewContext=function(a){a||(a={});var g=document.createElement("iframe");g.style||(g.style={});g.style.display="none"; | ||
| document.body.appendChild(g);var b=g.contentWindow;h(l(a),function(g){b[g]=a[g]});!b.eval&&b.execScript&&b.execScript("null");var d=b.eval(this.code);h(l(b),function(g){a[g]=b[g]});document.body.removeChild(g);return d};a.prototype.runInThisContext=function(){return eval(this.code)};a.prototype.runInContext=function(a){return this.runInNewContext(a)};h(l(a.prototype),function(e){d[e]=a[e]=function(g){var b=a(g);return b[e].apply(b,[].slice.call(arguments,1))}});d.createScript=function(a){return d.Script(a)}; | ||
| d.createContext=a.createContext=function(a){var g={};"object"===typeof a&&h(l(a),function(b){g[b]=a[b]});return g}});c.define("/package.json",function(c,f){f.exports={main:"./index"}});c.define("js-select",function(c,f){function d(a){a=e._parse(a||"*")[1];return","==a[0]?a.slice(1):[a]}function l(a,e){for(var g=0;g<a.length;g++){var d;a:{d=a[g];for(var c=e,l=c.parents.concat([c]),j=l.length-1,f=d.length-1,r=!0;0<=f&&0<=j;){var q=d[f],c=l[j];if(">"==q)f--,r=!0;else{if(h(q,c))f--;else if(r){d=!1;break a}j--; | ||
| r=!1}}d=-1==f}if(d)return!0}return!1}function h(b,e){var d=e.key,c=e.node,h=e.parent;if(b.id&&d!=b.id)return!1;if(b.type){var f=b.type;if("null"==f&&null!==c||"array"==f&&!g(c)||"object"==f&&("object"!=typeof c||null===c||g(c))||("boolean"==f||"string"==f||"number"==f)&&f!=typeof c)return!1}if(":nth-child"==b.pf&&(f=parseInt(d)+1,0==b.a&&f!==b.b||1==b.a&&!(f>=-b.b)||-1==b.a&&!(f<=b.b)||2==b.a&&f%2!=b.b)||":nth-last-child"==b.pf&&(!h||d!=h.node.length-b.b)||":only-child"==b.pc&&(!h||1!=h.node.length)|| | ||
| ":root"==b.pc&&void 0!==d)return!1;if(b.has){var j=","==b.has[0][0]?b.has[0].slice(1):[b.has[0]],p=!1;a(c).forEach(function(){l(j,this)&&(p=!0)});if(!p)return!1}return b.expr&&(f=b.expr,d=f[0],h=f[1],f=f[2],"string"!=typeof c||!d&&"="==h&&c!=f||!d&&"*="==h&&-1==c.indexOf(f))?!1:!0}var a=c("traverse"),e=c("JSONSelect");f.exports=function(b,e){var g=d(e);return{nodes:function(){var a=[];this.forEach(function(b){a.push(b)});return a},update:function(a){this.forEach(function(b){this.update("function"== | ||
| typeof a?a(b):a)})},remove:function(){this.forEach(function(){this.remove()})},condense:function(){a(b).forEach(function(){if(this.parent)if(this.parent.keep)this.keep=!0;else{var a=l(g,this);(this.keep=a)?this.parent.keep_child=!0:this.isLeaf?this.remove():this.after(function(){this.keep_child&&(this.parent.keep_child=!0);!this.keep&&!this.keep_child&&this.remove()})}})},forEach:function(e){a(b).forEach(function(a){l(g,this)&&(this.matches=function(a){return l(d(a),this)},e.call(this,a))})}}};var g= | ||
| Array.isArray||function(a){return"[object Array]"===toString.call(a)}});c.define("/node_modules/traverse/package.json",function(c,f){f.exports={main:"./index"}});c.define("/node_modules/traverse/index.js",function(c,f){function d(a){if(!(this instanceof d))return new d(a);this.value=a}function l(a,e,g){var b=[],d=[],c=!0;return function x(a){var f=g?h(a):a,l,j,q,v,n=!0,i={node:f,node_:a,path:[].concat(b),parent:d[d.length-1],parents:d,key:b.slice(-1)[0],isRoot:0===b.length,level:b.length,circular:null, | ||
| update:function(a,b){i.isRoot||(i.parent.node[i.key]=a);i.node=a;b&&(n=!1)},"delete":function(){delete i.parent.node[i.key]},remove:function(){Array.isArray(i.parent.node)?i.parent.node.splice(i.key,1):delete i.parent.node[i.key]},keys:null,before:function(a){l=a},after:function(a){j=a},pre:function(a){q=a},post:function(a){v=a},stop:function(){c=!1},block:function(){n=!1}};if(!c)return i;if("object"===typeof f&&null!==f){i.keys=Object.keys(f);i.isLeaf=0==i.keys.length;for(f=0;f<d.length;f++)if(d[f].node_=== | ||
| a){i.circular=d[f];break}}else i.isLeaf=!0;i.notLeaf=!i.isLeaf;i.notRoot=!i.isRoot;a=e.call(i,i.node);void 0!==a&&i.update&&i.update(a);l&&l.call(i,i.node);if(!n)return i;"object"==typeof i.node&&(null!==i.node&&!i.circular)&&(d.push(i),i.keys.forEach(function(a,e){b.push(a);q&&q.call(i,i.node[a],a);var d=x(i.node[a]);g&&Object.hasOwnProperty.call(i.node,a)&&(i.node[a]=d.node);d.isLast=e==i.keys.length-1;d.isFirst=0==e;v&&v.call(i,d);b.pop()}),d.pop());j&&j.call(i,i.node);return i}(a).node}function h(a){if("object"=== | ||
| typeof a&&null!==a){var e;e=Array.isArray(a)?[]:a instanceof Date?new Date(a):a instanceof Boolean?new Boolean(a):a instanceof Number?new Number(a):a instanceof String?new String(a):Object.create(Object.getPrototypeOf(a));Object.keys(a).forEach(function(d){e[d]=a[d]});return e}return a}f.exports=d;d.prototype.get=function(a){for(var e=this.value,d=0;d<a.length;d++){var b=a[d];if(!Object.hasOwnProperty.call(e,b)){e=void 0;break}e=e[b]}return e};d.prototype.set=function(a,e){for(var d=this.value,b= | ||
| 0;b<a.length-1;b++){var c=a[b];Object.hasOwnProperty.call(d,c)||(d[c]={});d=d[c]}return d[a[b]]=e};d.prototype.map=function(a){return l(this.value,a,!0)};d.prototype.forEach=function(a){return this.value=l(this.value,a,!1)};d.prototype.reduce=function(a,d){var c=1===arguments.length,b=c?this.value:d;this.forEach(function(d){if(!this.isRoot||!c)b=a.call(this,b,d)});return b};d.prototype.deepEqual=function(a){if(1!==arguments.length)throw Error("deepEqual requires exactly one object to compare against"); | ||
| var e=!0,c=a;this.forEach(function(b){var f=function(){e=!1}.bind(this);if(!this.isRoot){if("object"!==typeof c)return f();c=c[this.key]}var h=c;this.post(function(){c=h});if(this.circular)d(a).get(this.circular.path)!==h&&f();else if(typeof h!==typeof b)f();else if(null===h||null===b||void 0===h||void 0===b)h!==b&&f();else if(h.__proto__!==b.__proto__)f();else if(h!==b)if("function"===typeof h)h instanceof RegExp?h.toString()!=b.toString()&&f():h!==b&&f();else if("object"===typeof h)if("[object Arguments]"=== | ||
| Object.prototype.toString.call(b)||"[object Arguments]"===Object.prototype.toString.call(h))Object.prototype.toString.call(h)!==Object.prototype.toString.call(b)&&f();else if(h instanceof Date||b instanceof Date)(!(h instanceof Date)||!(b instanceof Date)||h.getTime()!==b.getTime())&&f();else{var l=Object.keys(h),j=Object.keys(b);if(l.length!==j.length)return f();for(j=0;j<l.length;j++)Object.hasOwnProperty.call(b,l[j])||f()}});return e};d.prototype.paths=function(){var a=[];this.forEach(function(){a.push(this.path)}); | ||
| return a};d.prototype.nodes=function(){var a=[];this.forEach(function(){a.push(this.node)});return a};d.prototype.clone=function(){var a=[],d=[];return function b(c){for(var f=0;f<a.length;f++)if(a[f]===c)return d[f];if("object"===typeof c&&null!==c){var j=h(c);a.push(c);d.push(j);Object.keys(c).forEach(function(a){j[a]=b(c[a])});a.pop();d.pop();return j}return c}(this.value)};Object.keys(d.prototype).forEach(function(a){d[a]=function(c){var f=[].slice.call(arguments,1),b=d(c);return b[a].apply(b, | ||
| f)}})});c.define("/node_modules/JSONSelect/package.json",function(c,f){f.exports={main:"src/jsonselect"}});c.define("/node_modules/JSONSelect/src/jsonselect.js",function(c,f,d){var c="undefined"===typeof d?window.JSONSelect={}:d,l=function(a){try{return JSON&&JSON.parse?JSON.parse(a):(new Function("return "+a))()}catch(b){h("ijs",b.message)}},h=function(a,b){throw Error(v[a]+(b&&" in '"+b+"'"));},a=function(a,b){b||(b=0);var d=i.exec(a.substr(b));if(d){var b=b+d[0].length,c;d[1]?c=[b," "]:d[2]?c= | ||
| [b,d[0]]:d[3]?c=[b,n.typ,d[0]]:d[4]?c=[b,n.psc,d[0]]:d[5]?c=[b,n.psf,d[0]]:d[6]?h("upc",a):d[8]?c=[b,d[7]?n.ide:n.str,l(d[8])]:d[9]?h("ujs",a):d[10]&&(c=[b,n.ide,d[10].replace(/\\([^\r\n\f0-9a-fA-F])/g,"$1")]);return c}},e=function(a,b){return typeof a===b},g=function(a,b){var d,c=B.exec(a.substr(b));if(c)return b+=c[0].length,d=c[1]||c[2]||c[3]||c[5]||c[6],c[1]||c[2]||c[3]?[b,0,l(d)]:c[4]?[b,0,void 0]:[b,d]},b=function(a,d){d||(d=0);var c=g(a,d),e;c&&"("===c[1]?(e=b(a,c[0]),c=g(a,e[0]),(!c||")"!== | ||
| c[1])&&h("epex",a),d=c[0],e=["(",e[1]]):!c||c[1]&&"x"!=c[1]?h("ee",a+" - "+(c[1]&&c[1])):(e="x"===c[1]?void 0:c[2],d=c[0]);c=g(a,d);if(!c||")"==c[1])return[d,e];("x"==c[1]||!c[1])&&h("bop",a+" - "+(c[1]&&c[1]));var f=b(a,c[0]),d=f[0],f=f[1],l;if("object"!==typeof f||"("===f[0]||w[c[1]][0]<w[f[1]][0])l=[e,c[1],f];else{for(l=f;"object"===typeof f[0]&&"("!=f[0][0]&&w[c[1]][0]>=w[f[0][1]][0];)f=f[0];f[0]=[e,c[1],f[0]]}return[d,l]},t=function(a,c){function d(a){return"object"!==typeof a||null===a?a:"("=== | ||
| a[0]?d(a[1]):[d(a[0]),a[1],d(a[2])]}var e=b(a,c?c:0);return[e[0],d(e[1])]},o=function(a,c){if(void 0===a)return c;if(null===a||"object"!==typeof a)return a;var b=o(a[0],c),d=o(a[2],c);return w[a[1]][1](b,d)},y=function(c,b,d,e){d||(e={});var f=[],g,l;for(b||(b=0);;){var m;m=c;var i=b,b=i,j={},k=a(m,i);k&&" "===k[1]&&(b=i=k[0],k=a(m,i));k&&k[1]===n.typ?(j.type=k[2],k=a(m,i=k[0])):k&&"*"===k[1]&&(k=a(m,i=k[0]));for(;void 0!==k;){if(k[1]===n.ide)j.id&&h("nmi",k[1]),j.id=k[2];else if(k[1]===n.psc)(j.pc|| | ||
| j.pf)&&h("mpc",k[1]),":first-child"===k[2]?(j.pf=":nth-child",j.a=0,j.b=1):":last-child"===k[2]?(j.pf=":nth-last-child",j.a=0,j.b=1):j.pc=k[2];else if(k[1]===n.psf)":val"===k[2]||":contains"===k[2]?(j.expr=[void 0,":val"===k[2]?"=":"*=",void 0],(k=a(m,k[0]))&&" "===k[1]&&(k=a(m,k[0])),(!k||"("!==k[1])&&h("pex",m),(k=a(m,k[0]))&&" "===k[1]&&(k=a(m,k[0])),(!k||k[1]!==n.str)&&h("sex",m),j.expr[2]=k[2],(k=a(m,k[0]))&&" "===k[1]&&(k=a(m,k[0])),(!k||")"!==k[1])&&h("epex",m)):":has"===k[2]?((k=a(m,k[0]))&& | ||
| " "===k[1]&&(k=a(m,k[0])),(!k||"("!==k[1])&&h("pex",m),i=y(m,k[0],!0),k[0]=i[0],j.has||(j.has=[]),j.has.push(i[1])):":expr"===k[2]?(j.expr&&h("mexp",m),i=t(m,k[0]),k[0]=i[0],j.expr=i[1]):((j.pc||j.pf)&&h("mpc",m),j.pf=k[2],(i=A.exec(m.substr(k[0])))||h("mepf",m),i[5]?(j.a=2,j.b="odd"===i[5]?1:0):i[6]?(j.a=0,j.b=parseInt(i[6],10)):(j.a=parseInt((i[1]?i[1]:"+")+(i[2]?i[2]:"1"),10),j.b=i[3]?parseInt(i[3]+i[4],10):0),k[0]+=i[0].length);else break;k=a(m,i=k[0])}b===i&&h("se",m);m=[i,j];f.push(m[1]);(m= | ||
| a(c,b=m[0]))&&" "===m[1]&&(m=a(c,b=m[0]));if(!m)break;if(">"===m[1]||"~"===m[1])"~"===m[1]&&(e.usesSiblingOp=!0),f.push(m[1]),b=m[0];else if(","===m[1])void 0===g?g=[",",f]:g.push(f),f=[],b=m[0];else if(")"===m[1]){d||h("ucp",m[1]);l=1;b=m[0];break}}d&&!l&&h("mcp",c);g&&g.push(f);var s;if(!d&&e.usesSiblingOp)if(c=g?g:f,","===c[0]){for(d=[","];s<c.length;s++)var o=x(o[s]),d=d.concat(","===o[0]?o.slice(1):o);s=d}else s=x(c);else s=g?g:f;return[b,s]},x=function(a){for(var c=[],b,d=0;d<a.length;d++)if("~"=== | ||
| a[d]){if(2>d||">"!=a[d-2])b=a.slice(0,d-1),b=b.concat([{has:[[{pc:":root"},">",a[d-1]]]},">"]),b=b.concat(a.slice(d+1)),c.push(b);if(1<d){var e=">"===a[d-2]?d-3:d-2;b=a.slice(0,e);var f={},g;for(g in a[e])a[e].hasOwnProperty(g)&&(f[g]=a[e][g]);f.has||(f.has=[]);f.has.push([{pc:":root"},">",a[d-1]]);b=b.concat(f,">",a.slice(d+1));c.push(b)}break}return d==a.length?a:1<c.length?[","].concat(c):c[0]},u=function(a){return Array.isArray?Array.isArray(a):"[object Array]"===q.call(a)},z=function(a,b,c,d, | ||
| e){var f=[],g=">"===b[0]?b[1]:b[0],h=!0;if(g.type&&h){var h=g.type,i;null===a?i="null":(i=typeof a,"object"===i&&u(a)&&(i="array"));h=h===i}g.id&&(h=h&&g.id===c);h&&g.pf&&(":nth-last-child"===g.pf?d=e-d:d++,0===g.a?h=g.b===d:(c=(d-g.b)%g.a,h=!c&&0<=d*g.a+g.b));if(h&&g.has){d=function(){throw 42;};for(c=0;c<g.has.length;c++){try{p(g.has[c],a,d)}catch(j){if(42===j)continue}h=!1;break}}h&&g.expr&&(h=o(g.expr,a));">"!==b[0]&&":root"!==b[0].pc&&f.push(b);h&&(">"===b[0]?2<b.length&&(h=!1,f.push(b.slice(2))): | ||
| 1<b.length&&(h=!1,f.push(b.slice(1))));return[h,f]},p=function(a,b,c,d,e,f){for(var a=","===a[0]?a.slice(1):[a],g=[],h=!1,i=0,j=0,k,l,i=0;i<a.length;i++){l=z(b,a[i],d,e,f);l[0]&&(h=!0);for(j=0;j<l[1].length;j++)g.push(l[1][j])}if(g.length&&"object"===typeof b)if(1<=g.length&&g.unshift(","),u(b))for(i=0;i<b.length;i++)p(g,b[i],c,void 0,i,b.length);else for(k in b)b.hasOwnProperty(k)&&p(g,b[k],c,k);h&&c&&c(b)},r=function(a){return{sel:y(a)[1],match:function(a){var b=[];p(this.sel,a,function(a){b.push(a)}); | ||
| return b},forEach:function(a,b){return p(this.sel,a,b)}}},q=Object.prototype.toString,v={bop:"binary operator expected",ee:"expression expected",epex:"closing paren expected ')'",ijs:"invalid json string",mcp:"missing closing paren",mepf:"malformed expression in pseudo-function",mexp:"multiple expressions not allowed",mpc:"multiple pseudo classes (:xxx) not allowed",nmi:"multiple ids not allowed",pex:"opening paren expected '('",se:"selector expected",sex:"string expected",sra:"string required after '.'", | ||
| uc:"unrecognized char",ucp:"unexpected closing paren",ujs:"unclosed json string",upc:"unrecognized pseudo class"},n={psc:1,psf:2,typ:3,str:4,ide:5},i=RegExp('^(?:([\\r\\n\\t\\ ]+)|([~*,>\\)\\(])|(string|boolean|null|array|object|number)|(:(?:root|first-child|last-child|only-child))|(:(?:nth-child|nth-last-child|has|expr|val|contains))|(:\\w+)|(?:(\\.)?(\\"(?:[^\\\\\\"]|\\\\[^\\"])*\\"))|(\\")|\\.((?:[_a-zA-Z]|[^\\0-\\0177]|\\\\[^\\r\\n\\f0-9a-fA-F])(?:[_a-zA-Z0-9\\-]|[^\\u0000-\\u0177]|(?:\\\\[^\\r\\n\\f0-9a-fA-F]))*))'), | ||
| A=/^\s*\(\s*(?:([+\-]?)([0-9]*)n\s*(?:([+\-])\s*([0-9]))?|(odd|even)|([+\-]?[0-9]+))\s*\)/,B=RegExp('^\\s*(?:(true|false|null)|(-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)|("(?:[^\\]|\\[^"])*")|(x)|(&&|\\|\\||[\\$\\^<>!\\*]=|[=+\\-*/%<>])|([\\(\\)]))'),w={"*":[9,function(a,b){return a*b}],"/":[9,function(a,b){return a/b}],"%":[9,function(a,b){return a%b}],"+":[7,function(a,b){return a+b}],"-":[7,function(a,b){return a-b}],"<=":[5,function(a,b){return e(a,"number")&&e(b,"number")&&a<=b}],">=":[5,function(a, | ||
| b){return e(a,"number")&&e(b,"number")&&a>=b}],"$=":[5,function(a,b){return e(a,"string")&&e(b,"string")&&a.lastIndexOf(b)===a.length-b.length}],"^=":[5,function(a,b){return e(a,"string")&&e(b,"string")&&0===a.indexOf(b)}],"*=":[5,function(a,b){return e(a,"string")&&e(b,"string")&&-1!==a.indexOf(b)}],">":[5,function(a,b){return e(a,"number")&&e(b,"number")&&a>b}],"<":[5,function(a,b){return e(a,"number")&&e(b,"number")&&a<b}],"=":[3,function(a,b){return a===b}],"!=":[3,function(a,b){return a!==b}], | ||
| "&&":[2,function(a,b){return a&&b}],"||":[1,function(a,b){return a||b}]};c._lex=a;c._parse=y;c.match=function(a,b){return r(a).match(b)};c.forEach=function(a,b,c){return r(a).forEach(b,c)};c.compile=r});return c("js-select")}(); |
-1533
| var select = (function() { | ||
| var require = function (file, cwd) { | ||
| var resolved = require.resolve(file, cwd || '/'); | ||
| var mod = require.modules[resolved]; | ||
| if (!mod) throw new Error( | ||
| 'Failed to resolve module ' + file + ', tried ' + resolved | ||
| ); | ||
| var cached = require.cache[resolved]; | ||
| var res = cached? cached.exports : mod(); | ||
| return res; | ||
| }; | ||
| require.paths = []; | ||
| require.modules = {}; | ||
| require.cache = {}; | ||
| require.extensions = [".js",".coffee"]; | ||
| require._core = { | ||
| 'assert': true, | ||
| 'events': true, | ||
| 'fs': true, | ||
| 'path': true, | ||
| 'vm': true | ||
| }; | ||
| require.resolve = (function () { | ||
| return function (x, cwd) { | ||
| if (!cwd) cwd = '/'; | ||
| if (require._core[x]) return x; | ||
| var path = require.modules.path(); | ||
| cwd = path.resolve('/', cwd); | ||
| var y = cwd || '/'; | ||
| if (x.match(/^(?:\.\.?\/|\/)/)) { | ||
| var m = loadAsFileSync(path.resolve(y, x)) | ||
| || loadAsDirectorySync(path.resolve(y, x)); | ||
| if (m) return m; | ||
| } | ||
| var n = loadNodeModulesSync(x, y); | ||
| if (n) return n; | ||
| throw new Error("Cannot find module '" + x + "'"); | ||
| function loadAsFileSync (x) { | ||
| x = path.normalize(x); | ||
| if (require.modules[x]) { | ||
| return x; | ||
| } | ||
| for (var i = 0; i < require.extensions.length; i++) { | ||
| var ext = require.extensions[i]; | ||
| if (require.modules[x + ext]) return x + ext; | ||
| } | ||
| } | ||
| function loadAsDirectorySync (x) { | ||
| x = x.replace(/\/+$/, ''); | ||
| var pkgfile = path.normalize(x + '/package.json'); | ||
| if (require.modules[pkgfile]) { | ||
| var pkg = require.modules[pkgfile](); | ||
| var b = pkg.browserify; | ||
| if (typeof b === 'object' && b.main) { | ||
| var m = loadAsFileSync(path.resolve(x, b.main)); | ||
| if (m) return m; | ||
| } | ||
| else if (typeof b === 'string') { | ||
| var m = loadAsFileSync(path.resolve(x, b)); | ||
| if (m) return m; | ||
| } | ||
| else if (pkg.main) { | ||
| var m = loadAsFileSync(path.resolve(x, pkg.main)); | ||
| if (m) return m; | ||
| } | ||
| } | ||
| return loadAsFileSync(x + '/index'); | ||
| } | ||
| function loadNodeModulesSync (x, start) { | ||
| var dirs = nodeModulesPathsSync(start); | ||
| for (var i = 0; i < dirs.length; i++) { | ||
| var dir = dirs[i]; | ||
| var m = loadAsFileSync(dir + '/' + x); | ||
| if (m) return m; | ||
| var n = loadAsDirectorySync(dir + '/' + x); | ||
| if (n) return n; | ||
| } | ||
| var m = loadAsFileSync(x); | ||
| if (m) return m; | ||
| } | ||
| function nodeModulesPathsSync (start) { | ||
| var parts; | ||
| if (start === '/') parts = [ '' ]; | ||
| else parts = path.normalize(start).split('/'); | ||
| var dirs = []; | ||
| for (var i = parts.length - 1; i >= 0; i--) { | ||
| if (parts[i] === 'node_modules') continue; | ||
| var dir = parts.slice(0, i + 1).join('/') + '/node_modules'; | ||
| dirs.push(dir); | ||
| } | ||
| return dirs; | ||
| } | ||
| }; | ||
| })(); | ||
| require.alias = function (from, to) { | ||
| var path = require.modules.path(); | ||
| var res = null; | ||
| try { | ||
| res = require.resolve(from + '/package.json', '/'); | ||
| } | ||
| catch (err) { | ||
| res = require.resolve(from, '/'); | ||
| } | ||
| var basedir = path.dirname(res); | ||
| var keys = (Object.keys || function (obj) { | ||
| var res = []; | ||
| for (var key in obj) res.push(key); | ||
| return res; | ||
| })(require.modules); | ||
| for (var i = 0; i < keys.length; i++) { | ||
| var key = keys[i]; | ||
| if (key.slice(0, basedir.length + 1) === basedir + '/') { | ||
| var f = key.slice(basedir.length); | ||
| require.modules[to + f] = require.modules[basedir + f]; | ||
| } | ||
| else if (key === basedir) { | ||
| require.modules[to] = require.modules[basedir]; | ||
| } | ||
| } | ||
| }; | ||
| (function () { | ||
| var process = {}; | ||
| require.define = function (filename, fn) { | ||
| if (require.modules.__browserify_process) { | ||
| process = require.modules.__browserify_process(); | ||
| } | ||
| var dirname = require._core[filename] | ||
| ? '' | ||
| : require.modules.path().dirname(filename) | ||
| ; | ||
| var require_ = function (file) { | ||
| var requiredModule = require(file, dirname); | ||
| var cached = require.cache[require.resolve(file, dirname)]; | ||
| if (cached && cached.parent === null) { | ||
| cached.parent = module_; | ||
| } | ||
| return requiredModule; | ||
| }; | ||
| require_.resolve = function (name) { | ||
| return require.resolve(name, dirname); | ||
| }; | ||
| require_.modules = require.modules; | ||
| require_.define = require.define; | ||
| require_.cache = require.cache; | ||
| var module_ = { | ||
| id : filename, | ||
| filename: filename, | ||
| exports : {}, | ||
| loaded : false, | ||
| parent: null | ||
| }; | ||
| require.modules[filename] = function () { | ||
| require.cache[filename] = module_; | ||
| fn.call( | ||
| module_.exports, | ||
| require_, | ||
| module_, | ||
| module_.exports, | ||
| dirname, | ||
| filename, | ||
| process | ||
| ); | ||
| module_.loaded = true; | ||
| return module_.exports; | ||
| }; | ||
| }; | ||
| })(); | ||
| require.define("path",function(require,module,exports,__dirname,__filename,process){function filter (xs, fn) { | ||
| var res = []; | ||
| for (var i = 0; i < xs.length; i++) { | ||
| if (fn(xs[i], i, xs)) res.push(xs[i]); | ||
| } | ||
| return res; | ||
| } | ||
| // resolves . and .. elements in a path array with directory names there | ||
| // must be no slashes, empty elements, or device names (c:\) in the array | ||
| // (so also no leading and trailing slashes - it does not distinguish | ||
| // relative and absolute paths) | ||
| function normalizeArray(parts, allowAboveRoot) { | ||
| // if the path tries to go above the root, `up` ends up > 0 | ||
| var up = 0; | ||
| for (var i = parts.length; i >= 0; i--) { | ||
| var last = parts[i]; | ||
| if (last == '.') { | ||
| parts.splice(i, 1); | ||
| } else if (last === '..') { | ||
| parts.splice(i, 1); | ||
| up++; | ||
| } else if (up) { | ||
| parts.splice(i, 1); | ||
| up--; | ||
| } | ||
| } | ||
| // if the path is allowed to go above the root, restore leading ..s | ||
| if (allowAboveRoot) { | ||
| for (; up--; up) { | ||
| parts.unshift('..'); | ||
| } | ||
| } | ||
| return parts; | ||
| } | ||
| // Regex to split a filename into [*, dir, basename, ext] | ||
| // posix version | ||
| var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/; | ||
| // path.resolve([from ...], to) | ||
| // posix version | ||
| exports.resolve = function() { | ||
| var resolvedPath = '', | ||
| resolvedAbsolute = false; | ||
| for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) { | ||
| var path = (i >= 0) | ||
| ? arguments[i] | ||
| : process.cwd(); | ||
| // Skip empty and invalid entries | ||
| if (typeof path !== 'string' || !path) { | ||
| continue; | ||
| } | ||
| resolvedPath = path + '/' + resolvedPath; | ||
| resolvedAbsolute = path.charAt(0) === '/'; | ||
| } | ||
| // At this point the path should be resolved to a full absolute path, but | ||
| // handle relative paths to be safe (might happen when process.cwd() fails) | ||
| // Normalize the path | ||
| resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { | ||
| return !!p; | ||
| }), !resolvedAbsolute).join('/'); | ||
| return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | ||
| }; | ||
| // path.normalize(path) | ||
| // posix version | ||
| exports.normalize = function(path) { | ||
| var isAbsolute = path.charAt(0) === '/', | ||
| trailingSlash = path.slice(-1) === '/'; | ||
| // Normalize the path | ||
| path = normalizeArray(filter(path.split('/'), function(p) { | ||
| return !!p; | ||
| }), !isAbsolute).join('/'); | ||
| if (!path && !isAbsolute) { | ||
| path = '.'; | ||
| } | ||
| if (path && trailingSlash) { | ||
| path += '/'; | ||
| } | ||
| return (isAbsolute ? '/' : '') + path; | ||
| }; | ||
| // posix version | ||
| exports.join = function() { | ||
| var paths = Array.prototype.slice.call(arguments, 0); | ||
| return exports.normalize(filter(paths, function(p, index) { | ||
| return p && typeof p === 'string'; | ||
| }).join('/')); | ||
| }; | ||
| exports.dirname = function(path) { | ||
| var dir = splitPathRe.exec(path)[1] || ''; | ||
| var isWindows = false; | ||
| if (!dir) { | ||
| // No dirname | ||
| return '.'; | ||
| } else if (dir.length === 1 || | ||
| (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) { | ||
| // It is just a slash or a drive letter with a slash | ||
| return dir; | ||
| } else { | ||
| // It is a full dirname, strip trailing slash | ||
| return dir.substring(0, dir.length - 1); | ||
| } | ||
| }; | ||
| exports.basename = function(path, ext) { | ||
| var f = splitPathRe.exec(path)[2] || ''; | ||
| // TODO: make this comparison case-insensitive on windows? | ||
| if (ext && f.substr(-1 * ext.length) === ext) { | ||
| f = f.substr(0, f.length - ext.length); | ||
| } | ||
| return f; | ||
| }; | ||
| exports.extname = function(path) { | ||
| return splitPathRe.exec(path)[3] || ''; | ||
| }; | ||
| }); | ||
| require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process){var process = module.exports = {}; | ||
| process.nextTick = (function () { | ||
| var queue = []; | ||
| var canPost = typeof window !== 'undefined' | ||
| && window.postMessage && window.addEventListener | ||
| ; | ||
| if (canPost) { | ||
| window.addEventListener('message', function (ev) { | ||
| if (ev.source === window && ev.data === 'browserify-tick') { | ||
| ev.stopPropagation(); | ||
| if (queue.length > 0) { | ||
| var fn = queue.shift(); | ||
| fn(); | ||
| } | ||
| } | ||
| }, true); | ||
| } | ||
| return function (fn) { | ||
| if (canPost) { | ||
| queue.push(fn); | ||
| window.postMessage('browserify-tick', '*'); | ||
| } | ||
| else setTimeout(fn, 0); | ||
| }; | ||
| })(); | ||
| process.title = 'browser'; | ||
| process.browser = true; | ||
| process.env = {}; | ||
| process.argv = []; | ||
| process.binding = function (name) { | ||
| if (name === 'evals') return (require)('vm') | ||
| else throw new Error('No such module. (Possibly not yet loaded)') | ||
| }; | ||
| (function () { | ||
| var cwd = '/'; | ||
| var path; | ||
| process.cwd = function () { return cwd }; | ||
| process.chdir = function (dir) { | ||
| if (!path) path = require('path'); | ||
| cwd = path.resolve(dir, cwd); | ||
| }; | ||
| })(); | ||
| }); | ||
| require.define("vm",function(require,module,exports,__dirname,__filename,process){module.exports = require("vm-browserify")}); | ||
| require.define("/node_modules/vm-browserify/package.json",function(require,module,exports,__dirname,__filename,process){module.exports = {"main":"index.js"}}); | ||
| require.define("/node_modules/vm-browserify/index.js",function(require,module,exports,__dirname,__filename,process){var Object_keys = function (obj) { | ||
| if (Object.keys) return Object.keys(obj) | ||
| else { | ||
| var res = []; | ||
| for (var key in obj) res.push(key) | ||
| return res; | ||
| } | ||
| }; | ||
| var forEach = function (xs, fn) { | ||
| if (xs.forEach) return xs.forEach(fn) | ||
| else for (var i = 0; i < xs.length; i++) { | ||
| fn(xs[i], i, xs); | ||
| } | ||
| }; | ||
| var Script = exports.Script = function NodeScript (code) { | ||
| if (!(this instanceof Script)) return new Script(code); | ||
| this.code = code; | ||
| }; | ||
| Script.prototype.runInNewContext = function (context) { | ||
| if (!context) context = {}; | ||
| var iframe = document.createElement('iframe'); | ||
| if (!iframe.style) iframe.style = {}; | ||
| iframe.style.display = 'none'; | ||
| document.body.appendChild(iframe); | ||
| var win = iframe.contentWindow; | ||
| forEach(Object_keys(context), function (key) { | ||
| win[key] = context[key]; | ||
| }); | ||
| if (!win.eval && win.execScript) { | ||
| // win.eval() magically appears when this is called in IE: | ||
| win.execScript('null'); | ||
| } | ||
| var res = win.eval(this.code); | ||
| forEach(Object_keys(win), function (key) { | ||
| context[key] = win[key]; | ||
| }); | ||
| document.body.removeChild(iframe); | ||
| return res; | ||
| }; | ||
| Script.prototype.runInThisContext = function () { | ||
| return eval(this.code); // maybe... | ||
| }; | ||
| Script.prototype.runInContext = function (context) { | ||
| // seems to be just runInNewContext on magical context objects which are | ||
| // otherwise indistinguishable from objects except plain old objects | ||
| // for the parameter segfaults node | ||
| return this.runInNewContext(context); | ||
| }; | ||
| forEach(Object_keys(Script.prototype), function (name) { | ||
| exports[name] = Script[name] = function (code) { | ||
| var s = Script(code); | ||
| return s[name].apply(s, [].slice.call(arguments, 1)); | ||
| }; | ||
| }); | ||
| exports.createScript = function (code) { | ||
| return exports.Script(code); | ||
| }; | ||
| exports.createContext = Script.createContext = function (context) { | ||
| // not really sure what this one does | ||
| // seems to just make a shallow copy | ||
| var copy = {}; | ||
| if(typeof context === 'object') { | ||
| forEach(Object_keys(context), function (key) { | ||
| copy[key] = context[key]; | ||
| }); | ||
| } | ||
| return copy; | ||
| }; | ||
| }); | ||
| require.define("/package.json",function(require,module,exports,__dirname,__filename,process){module.exports = {"main":"./index"}}); | ||
| require.define("js-select",function(require,module,exports,__dirname,__filename,process){var traverse = require("traverse"), | ||
| JSONSelect = require("JSONSelect"); | ||
| module.exports = function(obj, string) { | ||
| var sels = parseSelectors(string); | ||
| return { | ||
| nodes: function() { | ||
| var nodes = []; | ||
| this.forEach(function(node) { | ||
| nodes.push(node); | ||
| }); | ||
| return nodes; | ||
| }, | ||
| update: function(cb) { | ||
| this.forEach(function(node) { | ||
| this.update(typeof cb == "function" ? cb(node) : cb); | ||
| }); | ||
| }, | ||
| remove: function() { | ||
| this.forEach(function(node) { | ||
| this.remove(); | ||
| }) | ||
| }, | ||
| condense: function() { | ||
| traverse(obj).forEach(function(node) { | ||
| if (!this.parent) return; | ||
| if (this.parent.keep) { | ||
| this.keep = true; | ||
| } else { | ||
| var match = matchesAny(sels, this); | ||
| this.keep = match; | ||
| if (!match) { | ||
| if (this.isLeaf) { | ||
| this.remove(); | ||
| } else { | ||
| this.after(function() { | ||
| if (this.keep_child) { | ||
| this.parent.keep_child = true; | ||
| } | ||
| if (!this.keep && !this.keep_child) { | ||
| this.remove(); | ||
| } | ||
| }); | ||
| } | ||
| } else { | ||
| this.parent.keep_child = true; | ||
| } | ||
| } | ||
| }); | ||
| }, | ||
| forEach: function(cb) { | ||
| traverse(obj).forEach(function(node) { | ||
| if (matchesAny(sels, this)) { | ||
| this.matches = function(string) { | ||
| return matchesAny(parseSelectors(string), this); | ||
| }; | ||
| // inherit context from js-traverse | ||
| cb.call(this, node); | ||
| } | ||
| }); | ||
| } | ||
| }; | ||
| } | ||
| function parseSelectors(string) { | ||
| var parsed = JSONSelect._parse(string || "*")[1]; | ||
| return getSelectors(parsed); | ||
| } | ||
| function getSelectors(parsed) { | ||
| if (parsed[0] == ",") { // "selector1, selector2" | ||
| return parsed.slice(1); | ||
| } | ||
| return [parsed]; | ||
| } | ||
| function matchesAny(sels, context) { | ||
| for (var i = 0; i < sels.length; i++) { | ||
| if (matches(sels[i], context)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function matches(sel, context) { | ||
| var path = context.parents.concat([context]), | ||
| i = path.length - 1, | ||
| j = sel.length - 1; | ||
| // walk up the ancestors | ||
| var must = true; | ||
| while(j >= 0 && i >= 0) { | ||
| var part = sel[j], | ||
| context = path[i]; | ||
| if (part == ">") { | ||
| j--; | ||
| must = true; | ||
| continue; | ||
| } | ||
| if (matchesKey(part, context)) { | ||
| j--; | ||
| } | ||
| else if (must) { | ||
| return false; | ||
| } | ||
| i--; | ||
| must = false; | ||
| } | ||
| return j == -1; | ||
| } | ||
| function matchesKey(part, context) { | ||
| var key = context.key, | ||
| node = context.node, | ||
| parent = context.parent; | ||
| if (part.id && key != part.id) { | ||
| return false; | ||
| } | ||
| if (part.type) { | ||
| var type = part.type; | ||
| if (type == "null" && node !== null) { | ||
| return false; | ||
| } | ||
| else if (type == "array" && !isArray(node)) { | ||
| return false; | ||
| } | ||
| else if (type == "object" && (typeof node != "object" | ||
| || node === null || isArray(node))) { | ||
| return false; | ||
| } | ||
| else if ((type == "boolean" || type == "string" || type == "number") | ||
| && type != typeof node) { | ||
| return false; | ||
| } | ||
| } | ||
| if (part.pf == ":nth-child") { | ||
| var index = parseInt(key) + 1; | ||
| if ((part.a == 0 && index !== part.b) // :nth-child(i) | ||
| || (part.a == 1 && !(index >= -part.b)) // :nth-child(n) | ||
| || (part.a == -1 && !(index <= part.b)) // :nth-child(-n + 1) | ||
| || (part.a == 2 && index % 2 != part.b)) { // :nth-child(even) | ||
| return false; | ||
| } | ||
| } | ||
| if (part.pf == ":nth-last-child" | ||
| && (!parent || key != parent.node.length - part.b)) { | ||
| return false; | ||
| } | ||
| if (part.pc == ":only-child" | ||
| && (!parent || parent.node.length != 1)) { | ||
| return false; | ||
| } | ||
| if (part.pc == ":root" && key !== undefined) { | ||
| return false; | ||
| } | ||
| if (part.has) { | ||
| var sels = getSelectors(part.has[0]), | ||
| match = false; | ||
| traverse(node).forEach(function(child) { | ||
| if (matchesAny(sels, this)) { | ||
| match = true; | ||
| } | ||
| }); | ||
| if (!match) { | ||
| return false; | ||
| } | ||
| } | ||
| if (part.expr) { | ||
| var expr = part.expr, lhs = expr[0], op = expr[1], rhs = expr[2]; | ||
| if (typeof node != "string" | ||
| || (!lhs && op == "=" && node != rhs) // :val("str") | ||
| || (!lhs && op == "*=" && node.indexOf(rhs) == -1)) { // :contains("substr") | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| var isArray = Array.isArray || function(obj) { | ||
| return toString.call(obj) === '[object Array]'; | ||
| } | ||
| }); | ||
| require.define("/node_modules/traverse/package.json",function(require,module,exports,__dirname,__filename,process){module.exports = {"main":"./index"}}); | ||
| require.define("/node_modules/traverse/index.js",function(require,module,exports,__dirname,__filename,process){module.exports = Traverse; | ||
| function Traverse (obj) { | ||
| if (!(this instanceof Traverse)) return new Traverse(obj); | ||
| this.value = obj; | ||
| } | ||
| Traverse.prototype.get = function (ps) { | ||
| var node = this.value; | ||
| for (var i = 0; i < ps.length; i ++) { | ||
| var key = ps[i]; | ||
| if (!Object.hasOwnProperty.call(node, key)) { | ||
| node = undefined; | ||
| break; | ||
| } | ||
| node = node[key]; | ||
| } | ||
| return node; | ||
| }; | ||
| Traverse.prototype.set = function (ps, value) { | ||
| var node = this.value; | ||
| for (var i = 0; i < ps.length - 1; i ++) { | ||
| var key = ps[i]; | ||
| if (!Object.hasOwnProperty.call(node, key)) node[key] = {}; | ||
| node = node[key]; | ||
| } | ||
| node[ps[i]] = value; | ||
| return value; | ||
| }; | ||
| Traverse.prototype.map = function (cb) { | ||
| return walk(this.value, cb, true); | ||
| }; | ||
| Traverse.prototype.forEach = function (cb) { | ||
| this.value = walk(this.value, cb, false); | ||
| return this.value; | ||
| }; | ||
| Traverse.prototype.reduce = function (cb, init) { | ||
| var skip = arguments.length === 1; | ||
| var acc = skip ? this.value : init; | ||
| this.forEach(function (x) { | ||
| if (!this.isRoot || !skip) { | ||
| acc = cb.call(this, acc, x); | ||
| } | ||
| }); | ||
| return acc; | ||
| }; | ||
| Traverse.prototype.deepEqual = function (obj) { | ||
| if (arguments.length !== 1) { | ||
| throw new Error( | ||
| 'deepEqual requires exactly one object to compare against' | ||
| ); | ||
| } | ||
| var equal = true; | ||
| var node = obj; | ||
| this.forEach(function (y) { | ||
| var notEqual = (function () { | ||
| equal = false; | ||
| //this.stop(); | ||
| return undefined; | ||
| }).bind(this); | ||
| //if (node === undefined || node === null) return notEqual(); | ||
| if (!this.isRoot) { | ||
| /* | ||
| if (!Object.hasOwnProperty.call(node, this.key)) { | ||
| return notEqual(); | ||
| } | ||
| */ | ||
| if (typeof node !== 'object') return notEqual(); | ||
| node = node[this.key]; | ||
| } | ||
| var x = node; | ||
| this.post(function () { | ||
| node = x; | ||
| }); | ||
| var toS = function (o) { | ||
| return Object.prototype.toString.call(o); | ||
| }; | ||
| if (this.circular) { | ||
| if (Traverse(obj).get(this.circular.path) !== x) notEqual(); | ||
| } | ||
| else if (typeof x !== typeof y) { | ||
| notEqual(); | ||
| } | ||
| else if (x === null || y === null || x === undefined || y === undefined) { | ||
| if (x !== y) notEqual(); | ||
| } | ||
| else if (x.__proto__ !== y.__proto__) { | ||
| notEqual(); | ||
| } | ||
| else if (x === y) { | ||
| // nop | ||
| } | ||
| else if (typeof x === 'function') { | ||
| if (x instanceof RegExp) { | ||
| // both regexps on account of the __proto__ check | ||
| if (x.toString() != y.toString()) notEqual(); | ||
| } | ||
| else if (x !== y) notEqual(); | ||
| } | ||
| else if (typeof x === 'object') { | ||
| if (toS(y) === '[object Arguments]' | ||
| || toS(x) === '[object Arguments]') { | ||
| if (toS(x) !== toS(y)) { | ||
| notEqual(); | ||
| } | ||
| } | ||
| else if (x instanceof Date || y instanceof Date) { | ||
| if (!(x instanceof Date) || !(y instanceof Date) | ||
| || x.getTime() !== y.getTime()) { | ||
| notEqual(); | ||
| } | ||
| } | ||
| else { | ||
| var kx = Object.keys(x); | ||
| var ky = Object.keys(y); | ||
| if (kx.length !== ky.length) return notEqual(); | ||
| for (var i = 0; i < kx.length; i++) { | ||
| var k = kx[i]; | ||
| if (!Object.hasOwnProperty.call(y, k)) { | ||
| notEqual(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| return equal; | ||
| }; | ||
| Traverse.prototype.paths = function () { | ||
| var acc = []; | ||
| this.forEach(function (x) { | ||
| acc.push(this.path); | ||
| }); | ||
| return acc; | ||
| }; | ||
| Traverse.prototype.nodes = function () { | ||
| var acc = []; | ||
| this.forEach(function (x) { | ||
| acc.push(this.node); | ||
| }); | ||
| return acc; | ||
| }; | ||
| Traverse.prototype.clone = function () { | ||
| var parents = [], nodes = []; | ||
| return (function clone (src) { | ||
| for (var i = 0; i < parents.length; i++) { | ||
| if (parents[i] === src) { | ||
| return nodes[i]; | ||
| } | ||
| } | ||
| if (typeof src === 'object' && src !== null) { | ||
| var dst = copy(src); | ||
| parents.push(src); | ||
| nodes.push(dst); | ||
| Object.keys(src).forEach(function (key) { | ||
| dst[key] = clone(src[key]); | ||
| }); | ||
| parents.pop(); | ||
| nodes.pop(); | ||
| return dst; | ||
| } | ||
| else { | ||
| return src; | ||
| } | ||
| })(this.value); | ||
| }; | ||
| function walk (root, cb, immutable) { | ||
| var path = []; | ||
| var parents = []; | ||
| var alive = true; | ||
| return (function walker (node_) { | ||
| var node = immutable ? copy(node_) : node_; | ||
| var modifiers = {}; | ||
| var keepGoing = true; | ||
| var state = { | ||
| node : node, | ||
| node_ : node_, | ||
| path : [].concat(path), | ||
| parent : parents[parents.length - 1], | ||
| parents : parents, | ||
| key : path.slice(-1)[0], | ||
| isRoot : path.length === 0, | ||
| level : path.length, | ||
| circular : null, | ||
| update : function (x, stopHere) { | ||
| if (!state.isRoot) { | ||
| state.parent.node[state.key] = x; | ||
| } | ||
| state.node = x; | ||
| if (stopHere) keepGoing = false; | ||
| }, | ||
| 'delete' : function () { | ||
| delete state.parent.node[state.key]; | ||
| }, | ||
| remove : function () { | ||
| if (Array.isArray(state.parent.node)) { | ||
| state.parent.node.splice(state.key, 1); | ||
| } | ||
| else { | ||
| delete state.parent.node[state.key]; | ||
| } | ||
| }, | ||
| keys : null, | ||
| before : function (f) { modifiers.before = f }, | ||
| after : function (f) { modifiers.after = f }, | ||
| pre : function (f) { modifiers.pre = f }, | ||
| post : function (f) { modifiers.post = f }, | ||
| stop : function () { alive = false }, | ||
| block : function () { keepGoing = false } | ||
| }; | ||
| if (!alive) return state; | ||
| if (typeof node === 'object' && node !== null) { | ||
| state.keys = Object.keys(node); | ||
| state.isLeaf = state.keys.length == 0; | ||
| for (var i = 0; i < parents.length; i++) { | ||
| if (parents[i].node_ === node_) { | ||
| state.circular = parents[i]; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| state.isLeaf = true; | ||
| } | ||
| state.notLeaf = !state.isLeaf; | ||
| state.notRoot = !state.isRoot; | ||
| // use return values to update if defined | ||
| var ret = cb.call(state, state.node); | ||
| if (ret !== undefined && state.update) state.update(ret); | ||
| if (modifiers.before) modifiers.before.call(state, state.node); | ||
| if (!keepGoing) return state; | ||
| if (typeof state.node == 'object' | ||
| && state.node !== null && !state.circular) { | ||
| parents.push(state); | ||
| state.keys.forEach(function (key, i) { | ||
| path.push(key); | ||
| if (modifiers.pre) modifiers.pre.call(state, state.node[key], key); | ||
| var child = walker(state.node[key]); | ||
| if (immutable && Object.hasOwnProperty.call(state.node, key)) { | ||
| state.node[key] = child.node; | ||
| } | ||
| child.isLast = i == state.keys.length - 1; | ||
| child.isFirst = i == 0; | ||
| if (modifiers.post) modifiers.post.call(state, child); | ||
| path.pop(); | ||
| }); | ||
| parents.pop(); | ||
| } | ||
| if (modifiers.after) modifiers.after.call(state, state.node); | ||
| return state; | ||
| })(root).node; | ||
| } | ||
| Object.keys(Traverse.prototype).forEach(function (key) { | ||
| Traverse[key] = function (obj) { | ||
| var args = [].slice.call(arguments, 1); | ||
| var t = Traverse(obj); | ||
| return t[key].apply(t, args); | ||
| }; | ||
| }); | ||
| function copy (src) { | ||
| if (typeof src === 'object' && src !== null) { | ||
| var dst; | ||
| if (Array.isArray(src)) { | ||
| dst = []; | ||
| } | ||
| else if (src instanceof Date) { | ||
| dst = new Date(src); | ||
| } | ||
| else if (src instanceof Boolean) { | ||
| dst = new Boolean(src); | ||
| } | ||
| else if (src instanceof Number) { | ||
| dst = new Number(src); | ||
| } | ||
| else if (src instanceof String) { | ||
| dst = new String(src); | ||
| } | ||
| else { | ||
| dst = Object.create(Object.getPrototypeOf(src)); | ||
| } | ||
| Object.keys(src).forEach(function (key) { | ||
| dst[key] = src[key]; | ||
| }); | ||
| return dst; | ||
| } | ||
| else return src; | ||
| } | ||
| }); | ||
| require.define("/node_modules/JSONSelect/package.json",function(require,module,exports,__dirname,__filename,process){module.exports = {"main":"src/jsonselect"}}); | ||
| require.define("/node_modules/JSONSelect/src/jsonselect.js",function(require,module,exports,__dirname,__filename,process){/*! Copyright (c) 2011, Lloyd Hilaiel, ISC License */ | ||
| /* | ||
| * This is the JSONSelect reference implementation, in javascript. | ||
| */ | ||
| (function(exports) { | ||
| var // localize references | ||
| toString = Object.prototype.toString; | ||
| function jsonParse(str) { | ||
| try { | ||
| if(JSON && JSON.parse){ | ||
| return JSON.parse(str); | ||
| } | ||
| return (new Function("return " + str))(); | ||
| } catch(e) { | ||
| te("ijs", e.message); | ||
| } | ||
| } | ||
| // emitted error codes. | ||
| var errorCodes = { | ||
| "bop": "binary operator expected", | ||
| "ee": "expression expected", | ||
| "epex": "closing paren expected ')'", | ||
| "ijs": "invalid json string", | ||
| "mcp": "missing closing paren", | ||
| "mepf": "malformed expression in pseudo-function", | ||
| "mexp": "multiple expressions not allowed", | ||
| "mpc": "multiple pseudo classes (:xxx) not allowed", | ||
| "nmi": "multiple ids not allowed", | ||
| "pex": "opening paren expected '('", | ||
| "se": "selector expected", | ||
| "sex": "string expected", | ||
| "sra": "string required after '.'", | ||
| "uc": "unrecognized char", | ||
| "ucp": "unexpected closing paren", | ||
| "ujs": "unclosed json string", | ||
| "upc": "unrecognized pseudo class" | ||
| }; | ||
| // throw an error message | ||
| function te(ec, context) { | ||
| throw new Error(errorCodes[ec] + ( context && " in '" + context + "'")); | ||
| } | ||
| // THE LEXER | ||
| var toks = { | ||
| psc: 1, // pseudo class | ||
| psf: 2, // pseudo class function | ||
| typ: 3, // type | ||
| str: 4, // string | ||
| ide: 5 // identifiers (or "classes", stuff after a dot) | ||
| }; | ||
| // The primary lexing regular expression in jsonselect | ||
| var pat = new RegExp( | ||
| "^(?:" + | ||
| // (1) whitespace | ||
| "([\\r\\n\\t\\ ]+)|" + | ||
| // (2) one-char ops | ||
| "([~*,>\\)\\(])|" + | ||
| // (3) types names | ||
| "(string|boolean|null|array|object|number)|" + | ||
| // (4) pseudo classes | ||
| "(:(?:root|first-child|last-child|only-child))|" + | ||
| // (5) pseudo functions | ||
| "(:(?:nth-child|nth-last-child|has|expr|val|contains))|" + | ||
| // (6) bogusly named pseudo something or others | ||
| "(:\\w+)|" + | ||
| // (7 & 8) identifiers and JSON strings | ||
| "(?:(\\.)?(\\\"(?:[^\\\\\\\"]|\\\\[^\\\"])*\\\"))|" + | ||
| // (8) bogus JSON strings missing a trailing quote | ||
| "(\\\")|" + | ||
| // (9) identifiers (unquoted) | ||
| "\\.((?:[_a-zA-Z]|[^\\0-\\0177]|\\\\[^\\r\\n\\f0-9a-fA-F])(?:[_a-zA-Z0-9\\-]|[^\\u0000-\\u0177]|(?:\\\\[^\\r\\n\\f0-9a-fA-F]))*)" + | ||
| ")" | ||
| ); | ||
| // A regular expression for matching "nth expressions" (see grammar, what :nth-child() eats) | ||
| var nthPat = /^\s*\(\s*(?:([+\-]?)([0-9]*)n\s*(?:([+\-])\s*([0-9]))?|(odd|even)|([+\-]?[0-9]+))\s*\)/; | ||
| function lex(str, off) { | ||
| if (!off) off = 0; | ||
| var m = pat.exec(str.substr(off)); | ||
| if (!m) return undefined; | ||
| off+=m[0].length; | ||
| var a; | ||
| if (m[1]) a = [off, " "]; | ||
| else if (m[2]) a = [off, m[0]]; | ||
| else if (m[3]) a = [off, toks.typ, m[0]]; | ||
| else if (m[4]) a = [off, toks.psc, m[0]]; | ||
| else if (m[5]) a = [off, toks.psf, m[0]]; | ||
| else if (m[6]) te("upc", str); | ||
| else if (m[8]) a = [off, m[7] ? toks.ide : toks.str, jsonParse(m[8])]; | ||
| else if (m[9]) te("ujs", str); | ||
| else if (m[10]) a = [off, toks.ide, m[10].replace(/\\([^\r\n\f0-9a-fA-F])/g,"$1")]; | ||
| return a; | ||
| } | ||
| // THE EXPRESSION SUBSYSTEM | ||
| var exprPat = new RegExp( | ||
| // skip and don't capture leading whitespace | ||
| "^\\s*(?:" + | ||
| // (1) simple vals | ||
| "(true|false|null)|" + | ||
| // (2) numbers | ||
| "(-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)|" + | ||
| // (3) strings | ||
| "(\"(?:[^\\]|\\[^\"])*\")|" + | ||
| // (4) the 'x' value placeholder | ||
| "(x)|" + | ||
| // (5) binops | ||
| "(&&|\\|\\||[\\$\\^<>!\\*]=|[=+\\-*/%<>])|" + | ||
| // (6) parens | ||
| "([\\(\\)])" + | ||
| ")" | ||
| ); | ||
| function is(o, t) { return typeof o === t; } | ||
| var operators = { | ||
| '*': [ 9, function(lhs, rhs) { return lhs * rhs; } ], | ||
| '/': [ 9, function(lhs, rhs) { return lhs / rhs; } ], | ||
| '%': [ 9, function(lhs, rhs) { return lhs % rhs; } ], | ||
| '+': [ 7, function(lhs, rhs) { return lhs + rhs; } ], | ||
| '-': [ 7, function(lhs, rhs) { return lhs - rhs; } ], | ||
| '<=': [ 5, function(lhs, rhs) { return is(lhs, 'number') && is(rhs, 'number') && lhs <= rhs; } ], | ||
| '>=': [ 5, function(lhs, rhs) { return is(lhs, 'number') && is(rhs, 'number') && lhs >= rhs; } ], | ||
| '$=': [ 5, function(lhs, rhs) { return is(lhs, 'string') && is(rhs, 'string') && lhs.lastIndexOf(rhs) === lhs.length - rhs.length; } ], | ||
| '^=': [ 5, function(lhs, rhs) { return is(lhs, 'string') && is(rhs, 'string') && lhs.indexOf(rhs) === 0; } ], | ||
| '*=': [ 5, function(lhs, rhs) { return is(lhs, 'string') && is(rhs, 'string') && lhs.indexOf(rhs) !== -1; } ], | ||
| '>': [ 5, function(lhs, rhs) { return is(lhs, 'number') && is(rhs, 'number') && lhs > rhs; } ], | ||
| '<': [ 5, function(lhs, rhs) { return is(lhs, 'number') && is(rhs, 'number') && lhs < rhs; } ], | ||
| '=': [ 3, function(lhs, rhs) { return lhs === rhs; } ], | ||
| '!=': [ 3, function(lhs, rhs) { return lhs !== rhs; } ], | ||
| '&&': [ 2, function(lhs, rhs) { return lhs && rhs; } ], | ||
| '||': [ 1, function(lhs, rhs) { return lhs || rhs; } ] | ||
| }; | ||
| function exprLex(str, off) { | ||
| var v, m = exprPat.exec(str.substr(off)); | ||
| if (m) { | ||
| off += m[0].length; | ||
| v = m[1] || m[2] || m[3] || m[5] || m[6]; | ||
| if (m[1] || m[2] || m[3]) return [off, 0, jsonParse(v)]; | ||
| else if (m[4]) return [off, 0, undefined]; | ||
| return [off, v]; | ||
| } | ||
| } | ||
| function exprParse2(str, off) { | ||
| if (!off) off = 0; | ||
| // first we expect a value or a '(' | ||
| var l = exprLex(str, off), | ||
| lhs; | ||
| if (l && l[1] === '(') { | ||
| lhs = exprParse2(str, l[0]); | ||
| var p = exprLex(str, lhs[0]); | ||
| if (!p || p[1] !== ')') te('epex', str); | ||
| off = p[0]; | ||
| lhs = [ '(', lhs[1] ]; | ||
| } else if (!l || (l[1] && l[1] != 'x')) { | ||
| te("ee", str + " - " + ( l[1] && l[1] )); | ||
| } else { | ||
| lhs = ((l[1] === 'x') ? undefined : l[2]); | ||
| off = l[0]; | ||
| } | ||
| // now we expect a binary operator or a ')' | ||
| var op = exprLex(str, off); | ||
| if (!op || op[1] == ')') return [off, lhs]; | ||
| else if (op[1] == 'x' || !op[1]) { | ||
| te('bop', str + " - " + ( op[1] && op[1] )); | ||
| } | ||
| // tail recursion to fetch the rhs expression | ||
| var rhs = exprParse2(str, op[0]); | ||
| off = rhs[0]; | ||
| rhs = rhs[1]; | ||
| // and now precedence! how shall we put everything together? | ||
| var v; | ||
| if (typeof rhs !== 'object' || rhs[0] === '(' || operators[op[1]][0] < operators[rhs[1]][0] ) { | ||
| v = [lhs, op[1], rhs]; | ||
| } | ||
| else { | ||
| v = rhs; | ||
| while (typeof rhs[0] === 'object' && rhs[0][0] != '(' && operators[op[1]][0] >= operators[rhs[0][1]][0]) { | ||
| rhs = rhs[0]; | ||
| } | ||
| rhs[0] = [lhs, op[1], rhs[0]]; | ||
| } | ||
| return [off, v]; | ||
| } | ||
| function exprParse(str, off) { | ||
| function deparen(v) { | ||
| if (typeof v !== 'object' || v === null) return v; | ||
| else if (v[0] === '(') return deparen(v[1]); | ||
| else return [deparen(v[0]), v[1], deparen(v[2])]; | ||
| } | ||
| var e = exprParse2(str, off ? off : 0); | ||
| return [e[0], deparen(e[1])]; | ||
| } | ||
| function exprEval(expr, x) { | ||
| if (expr === undefined) return x; | ||
| else if (expr === null || typeof expr !== 'object') { | ||
| return expr; | ||
| } | ||
| var lhs = exprEval(expr[0], x), | ||
| rhs = exprEval(expr[2], x); | ||
| return operators[expr[1]][1](lhs, rhs); | ||
| } | ||
| // THE PARSER | ||
| function parse(str, off, nested, hints) { | ||
| if (!nested) hints = {}; | ||
| var a = [], am, readParen; | ||
| if (!off) off = 0; | ||
| while (true) { | ||
| var s = parse_selector(str, off, hints); | ||
| a.push(s[1]); | ||
| s = lex(str, off = s[0]); | ||
| if (s && s[1] === " ") s = lex(str, off = s[0]); | ||
| if (!s) break; | ||
| // now we've parsed a selector, and have something else... | ||
| if (s[1] === ">" || s[1] === "~") { | ||
| if (s[1] === "~") hints.usesSiblingOp = true; | ||
| a.push(s[1]); | ||
| off = s[0]; | ||
| } else if (s[1] === ",") { | ||
| if (am === undefined) am = [ ",", a ]; | ||
| else am.push(a); | ||
| a = []; | ||
| off = s[0]; | ||
| } else if (s[1] === ")") { | ||
| if (!nested) te("ucp", s[1]); | ||
| readParen = 1; | ||
| off = s[0]; | ||
| break; | ||
| } | ||
| } | ||
| if (nested && !readParen) te("mcp", str); | ||
| if (am) am.push(a); | ||
| var rv; | ||
| if (!nested && hints.usesSiblingOp) { | ||
| rv = normalize(am ? am : a); | ||
| } else { | ||
| rv = am ? am : a; | ||
| } | ||
| return [off, rv]; | ||
| } | ||
| function normalizeOne(sel) { | ||
| var sels = [], s; | ||
| for (var i = 0; i < sel.length; i++) { | ||
| if (sel[i] === '~') { | ||
| // `A ~ B` maps to `:has(:root > A) > B` | ||
| // `Z A ~ B` maps to `Z :has(:root > A) > B, Z:has(:root > A) > B` | ||
| // This first clause, takes care of the first case, and the first half of the latter case. | ||
| if (i < 2 || sel[i-2] != '>') { | ||
| s = sel.slice(0,i-1); | ||
| s = s.concat([{has:[[{pc: ":root"}, ">", sel[i-1]]]}, ">"]); | ||
| s = s.concat(sel.slice(i+1)); | ||
| sels.push(s); | ||
| } | ||
| // here we take care of the second half of above: | ||
| // (`Z A ~ B` maps to `Z :has(:root > A) > B, Z :has(:root > A) > B`) | ||
| // and a new case: | ||
| // Z > A ~ B maps to Z:has(:root > A) > B | ||
| if (i > 1) { | ||
| var at = sel[i-2] === '>' ? i-3 : i-2; | ||
| s = sel.slice(0,at); | ||
| var z = {}; | ||
| for (var k in sel[at]) if (sel[at].hasOwnProperty(k)) z[k] = sel[at][k]; | ||
| if (!z.has) z.has = []; | ||
| z.has.push([{pc: ":root"}, ">", sel[i-1]]); | ||
| s = s.concat(z, '>', sel.slice(i+1)); | ||
| sels.push(s); | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| if (i == sel.length) return sel; | ||
| return sels.length > 1 ? [','].concat(sels) : sels[0]; | ||
| } | ||
| function normalize(sels) { | ||
| if (sels[0] === ',') { | ||
| var r = [","]; | ||
| for (var i = i; i < sels.length; i++) { | ||
| var s = normalizeOne(s[i]); | ||
| r = r.concat(s[0] === "," ? s.slice(1) : s); | ||
| } | ||
| return r; | ||
| } else { | ||
| return normalizeOne(sels); | ||
| } | ||
| } | ||
| function parse_selector(str, off, hints) { | ||
| var soff = off; | ||
| var s = { }; | ||
| var l = lex(str, off); | ||
| // skip space | ||
| if (l && l[1] === " ") { soff = off = l[0]; l = lex(str, off); } | ||
| if (l && l[1] === toks.typ) { | ||
| s.type = l[2]; | ||
| l = lex(str, (off = l[0])); | ||
| } else if (l && l[1] === "*") { | ||
| // don't bother representing the universal sel, '*' in the | ||
| // parse tree, cause it's the default | ||
| l = lex(str, (off = l[0])); | ||
| } | ||
| // now support either an id or a pc | ||
| while (true) { | ||
| if (l === undefined) { | ||
| break; | ||
| } else if (l[1] === toks.ide) { | ||
| if (s.id) te("nmi", l[1]); | ||
| s.id = l[2]; | ||
| } else if (l[1] === toks.psc) { | ||
| if (s.pc || s.pf) te("mpc", l[1]); | ||
| // collapse first-child and last-child into nth-child expressions | ||
| if (l[2] === ":first-child") { | ||
| s.pf = ":nth-child"; | ||
| s.a = 0; | ||
| s.b = 1; | ||
| } else if (l[2] === ":last-child") { | ||
| s.pf = ":nth-last-child"; | ||
| s.a = 0; | ||
| s.b = 1; | ||
| } else { | ||
| s.pc = l[2]; | ||
| } | ||
| } else if (l[1] === toks.psf) { | ||
| if (l[2] === ":val" || l[2] === ":contains") { | ||
| s.expr = [ undefined, l[2] === ":val" ? "=" : "*=", undefined]; | ||
| // any amount of whitespace, followed by paren, string, paren | ||
| l = lex(str, (off = l[0])); | ||
| if (l && l[1] === " ") l = lex(str, off = l[0]); | ||
| if (!l || l[1] !== "(") te("pex", str); | ||
| l = lex(str, (off = l[0])); | ||
| if (l && l[1] === " ") l = lex(str, off = l[0]); | ||
| if (!l || l[1] !== toks.str) te("sex", str); | ||
| s.expr[2] = l[2]; | ||
| l = lex(str, (off = l[0])); | ||
| if (l && l[1] === " ") l = lex(str, off = l[0]); | ||
| if (!l || l[1] !== ")") te("epex", str); | ||
| } else if (l[2] === ":has") { | ||
| // any amount of whitespace, followed by paren | ||
| l = lex(str, (off = l[0])); | ||
| if (l && l[1] === " ") l = lex(str, off = l[0]); | ||
| if (!l || l[1] !== "(") te("pex", str); | ||
| var h = parse(str, l[0], true); | ||
| l[0] = h[0]; | ||
| if (!s.has) s.has = []; | ||
| s.has.push(h[1]); | ||
| } else if (l[2] === ":expr") { | ||
| if (s.expr) te("mexp", str); | ||
| var e = exprParse(str, l[0]); | ||
| l[0] = e[0]; | ||
| s.expr = e[1]; | ||
| } else { | ||
| if (s.pc || s.pf ) te("mpc", str); | ||
| s.pf = l[2]; | ||
| var m = nthPat.exec(str.substr(l[0])); | ||
| if (!m) te("mepf", str); | ||
| if (m[5]) { | ||
| s.a = 2; | ||
| s.b = (m[5] === "odd") ? 1 : 0; | ||
| } else if (m[6]) { | ||
| s.a = 0; | ||
| s.b = parseInt(m[6], 10); | ||
| } else { | ||
| s.a = parseInt((m[1] ? m[1] : "+") + (m[2] ? m[2] : "1"),10); | ||
| s.b = m[3] ? parseInt(m[3] + m[4],10) : 0; | ||
| } | ||
| l[0] += m[0].length; | ||
| } | ||
| } else { | ||
| break; | ||
| } | ||
| l = lex(str, (off = l[0])); | ||
| } | ||
| // now if we didn't actually parse anything it's an error | ||
| if (soff === off) te("se", str); | ||
| return [off, s]; | ||
| } | ||
| // THE EVALUATOR | ||
| function isArray(o) { | ||
| return Array.isArray ? Array.isArray(o) : | ||
| toString.call(o) === "[object Array]"; | ||
| } | ||
| function mytypeof(o) { | ||
| if (o === null) return "null"; | ||
| var to = typeof o; | ||
| if (to === "object" && isArray(o)) to = "array"; | ||
| return to; | ||
| } | ||
| function mn(node, sel, id, num, tot) { | ||
| var sels = []; | ||
| var cs = (sel[0] === ">") ? sel[1] : sel[0]; | ||
| var m = true, mod; | ||
| if (cs.type) m = m && (cs.type === mytypeof(node)); | ||
| if (cs.id) m = m && (cs.id === id); | ||
| if (m && cs.pf) { | ||
| if (cs.pf === ":nth-last-child") num = tot - num; | ||
| else num++; | ||
| if (cs.a === 0) { | ||
| m = cs.b === num; | ||
| } else { | ||
| mod = ((num - cs.b) % cs.a); | ||
| m = (!mod && ((num*cs.a + cs.b) >= 0)); | ||
| } | ||
| } | ||
| if (m && cs.has) { | ||
| // perhaps we should augment forEach to handle a return value | ||
| // that indicates "client cancels traversal"? | ||
| var bail = function() { throw 42; }; | ||
| for (var i = 0; i < cs.has.length; i++) { | ||
| try { | ||
| forEach(cs.has[i], node, bail); | ||
| } catch (e) { | ||
| if (e === 42) continue; | ||
| } | ||
| m = false; | ||
| break; | ||
| } | ||
| } | ||
| if (m && cs.expr) { | ||
| m = exprEval(cs.expr, node); | ||
| } | ||
| // should we repeat this selector for descendants? | ||
| if (sel[0] !== ">" && sel[0].pc !== ":root") sels.push(sel); | ||
| if (m) { | ||
| // is there a fragment that we should pass down? | ||
| if (sel[0] === ">") { if (sel.length > 2) { m = false; sels.push(sel.slice(2)); } } | ||
| else if (sel.length > 1) { m = false; sels.push(sel.slice(1)); } | ||
| } | ||
| return [m, sels]; | ||
| } | ||
| function forEach(sel, obj, fun, id, num, tot) { | ||
| var a = (sel[0] === ",") ? sel.slice(1) : [sel], | ||
| a0 = [], | ||
| call = false, | ||
| i = 0, j = 0, k, x; | ||
| for (i = 0; i < a.length; i++) { | ||
| x = mn(obj, a[i], id, num, tot); | ||
| if (x[0]) { | ||
| call = true; | ||
| } | ||
| for (j = 0; j < x[1].length; j++) { | ||
| a0.push(x[1][j]); | ||
| } | ||
| } | ||
| if (a0.length && typeof obj === "object") { | ||
| if (a0.length >= 1) { | ||
| a0.unshift(","); | ||
| } | ||
| if (isArray(obj)) { | ||
| for (i = 0; i < obj.length; i++) { | ||
| forEach(a0, obj[i], fun, undefined, i, obj.length); | ||
| } | ||
| } else { | ||
| for (k in obj) { | ||
| if (obj.hasOwnProperty(k)) { | ||
| forEach(a0, obj[k], fun, k); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (call && fun) { | ||
| fun(obj); | ||
| } | ||
| } | ||
| function match(sel, obj) { | ||
| var a = []; | ||
| forEach(sel, obj, function(x) { | ||
| a.push(x); | ||
| }); | ||
| return a; | ||
| } | ||
| function compile(sel) { | ||
| return { | ||
| sel: parse(sel)[1], | ||
| match: function(obj){ | ||
| return match(this.sel, obj); | ||
| }, | ||
| forEach: function(obj, fun) { | ||
| return forEach(this.sel, obj, fun); | ||
| } | ||
| }; | ||
| } | ||
| exports._lex = lex; | ||
| exports._parse = parse; | ||
| exports.match = function (sel, obj) { | ||
| return compile(sel).match(obj); | ||
| }; | ||
| exports.forEach = function(sel, obj, fun) { | ||
| return compile(sel).forEach(obj, fun); | ||
| }; | ||
| exports.compile = compile; | ||
| })(typeof exports === "undefined" ? (window.JSONSelect = {}) : exports); | ||
| }); | ||
| return require('js-select'); | ||
| })(); |
| /* node runner for the JSONSelect conformance tests | ||
| https://github.com/lloyd/JSONSelectTests */ | ||
| var assert = require("assert"), | ||
| fs = require("fs"), | ||
| path = require("path"), | ||
| colors = require("colors"), | ||
| traverse = require("traverse") | ||
| select = require("../index"); | ||
| var options = require("nomnom").opts({ | ||
| directory: { | ||
| abbr: 'd', | ||
| help: 'directory of tests to run', | ||
| metavar: 'PATH', | ||
| default: __dirname + "/level_1" | ||
| } | ||
| }).parseArgs(); | ||
| var directory = options.directory, | ||
| files = fs.readdirSync(directory); | ||
| var jsonFiles = files.filter(function(file) { | ||
| return path.extname(file) == ".json"; | ||
| }); | ||
| jsonFiles.forEach(function(file) { | ||
| var jsonName = file.replace(/\..*$/, ""), | ||
| json = JSON.parse(fs.readFileSync(path.join(directory, file), "utf-8")); | ||
| var selFiles = files.filter(function(file) { | ||
| return file.indexOf(jsonName) == 0 && path.extname(file) == ".selector" | ||
| }) | ||
| selFiles.forEach(function(file) { | ||
| var test = file.replace(/\..*$/, ""); | ||
| var selector = fs.readFileSync(path.join(directory, file), "utf-8"); | ||
| var output = fs.readFileSync(path.join(directory, test + ".output"), "utf-8"); | ||
| var expected = JSON.parse(output).sort(sort); | ||
| var got = select(json, selector).nodes().sort(sort); | ||
| try { | ||
| assert.deepEqual(got, expected); | ||
| } | ||
| catch(AssertionError) { | ||
| console.log("\nfail".red + " " + test + "\ngot: ".blue + JSON.stringify(got) | ||
| + "\n\expected: ".blue + JSON.stringify(expected) + "\n") | ||
| }; | ||
| console.log("pass".green + " " + test); | ||
| }); | ||
| }); | ||
| function sort(a, b) { | ||
| if (JSON.stringify(a) < JSON.stringify(b)) { | ||
| return -1; | ||
| } | ||
| return 1; | ||
| } |
-161
| var assert = require("assert"), | ||
| fs = require("fs"), | ||
| traverse = require("traverse") | ||
| select = require("../index"); | ||
| var people = { | ||
| "george": { | ||
| age : 35, | ||
| movies: [{ | ||
| name: "Repo Man", | ||
| stars: 5 | ||
| }] | ||
| }, | ||
| "mary": { | ||
| age: 15, | ||
| movies: [{ | ||
| name: "Twilight", | ||
| stars: 3 | ||
| }, | ||
| { | ||
| name: "Trudy", | ||
| stars: 2 | ||
| }, | ||
| { | ||
| name: "The Fighter", | ||
| stars: 4 | ||
| }] | ||
| }, | ||
| "chris" : { | ||
| car: null, | ||
| male: true | ||
| } | ||
| }; | ||
| var people2, obj; | ||
| assert.deepEqual(select(people, "*").nodes(), [{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},"chris":{"car":null,"male":true}},{"age":35,"movies":[{"name":"Repo Man","stars":5}]},35,[{"name":"Repo Man","stars":5}],{"name":"Repo Man","stars":5},"Repo Man",5,{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},15,[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}],{"name":"Twilight","stars":3},"Twilight",3,{"name":"Trudy","stars":2},"Trudy",2,{"name":"The Fighter","stars":4},"The Fighter",4,{"car":null,"male":true},null,true]); | ||
| assert.deepEqual(select(people, ".george").nodes(), [{"age":35,"movies":[{"name":"Repo Man","stars":5}]}]); | ||
| assert.deepEqual(select(people, ".george .age").nodes(), [35]); | ||
| assert.deepEqual(select(people, ".george .name").nodes(), ["Repo Man"]); | ||
| assert.deepEqual(select(people, ".george *").nodes(), [35,[{"name":"Repo Man","stars":5}],{"name":"Repo Man","stars":5},"Repo Man",5]) | ||
| assert.deepEqual(select(people, ".george > *").nodes(), [35,[{"name":"Repo Man","stars":5}]]); | ||
| assert.deepEqual(select(people, ".george > .name").nodes(), []); | ||
| assert.deepEqual(select(people, ":first-child").nodes(), [{"name":"Repo Man","stars":5},{"name":"Twilight","stars":3}]); | ||
| assert.deepEqual(select(people, ":nth-child(1)").nodes(), select(people, ":first-child").nodes()); | ||
| assert.deepEqual(select(people, ":nth-child(2)").nodes(), [{"name":"Trudy","stars":2}]); | ||
| assert.deepEqual(select(people, ":nth-child(odd)").nodes(), [{"name":"Repo Man","stars":5},{"name":"Twilight","stars":3},{"name":"The Fighter","stars":4}]); | ||
| assert.deepEqual(select(people, ":nth-child(even)").nodes(), [{"name":"Trudy","stars":2}]); | ||
| assert.deepEqual(select(people, ":nth-child(-n+1)").nodes(), select(people, ":first-child").nodes()); | ||
| assert.deepEqual(select(people, ":nth-child(-n+2)").nodes(), [{"name":"Repo Man","stars":5},{"name":"Twilight","stars":3},{"name":"Trudy","stars":2}]); | ||
| assert.deepEqual(select(people, ":nth-child(n)").nodes(), [{"name":"Repo Man","stars":5},{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]); | ||
| assert.deepEqual(select(people, ":nth-child(n-1)").nodes(), select(people, ":nth-child(n)").nodes()); | ||
| assert.deepEqual(select(people, ":nth-child(n-2)").nodes(), [{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]); | ||
| assert.deepEqual(select(people, ":last-child").nodes(), [{"name":"Repo Man","stars":5},{"name":"The Fighter","stars":4}]); | ||
| assert.deepEqual(select(people, ":nth-last-child(1)").nodes(), select(people, ":last-child").nodes()); | ||
| assert.deepEqual(select(people, ":nth-last-child(2)").nodes(), [{"name":"Trudy","stars":2}]); | ||
| assert.deepEqual(select(people, ":only-child").nodes(), [{"name":"Repo Man","stars":5}]); | ||
| assert.deepEqual(select(people, ":root").nodes(),[{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},"chris":{"car":null,"male":true}}]) | ||
| assert.deepEqual(select(people, "string").nodes(),["Repo Man","Twilight","Trudy","The Fighter"]); | ||
| assert.deepEqual(select(people, "number").nodes(),[35,5,15,3,2,4]); | ||
| assert.deepEqual(select(people, "boolean").nodes(),[true]); | ||
| assert.deepEqual(select(people, "object").nodes(),[{"george":{"age":35,"movies":[{"name":"Repo Man","stars":5}]},"mary":{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},"chris":{"car":null,"male":true}},{"age":35,"movies":[{"name":"Repo Man","stars":5}]},{"name":"Repo Man","stars":5},{"age":15,"movies":[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]},{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4},{"car":null,"male":true}]); | ||
| assert.deepEqual(select(people, "array").nodes(),[[{"name":"Repo Man","stars":5}],[{"name":"Twilight","stars":3},{"name":"Trudy","stars":2},{"name":"The Fighter","stars":4}]]); | ||
| assert.deepEqual(select(people, "null").nodes(),[null]); | ||
| assert.deepEqual(select(people, "number, string, boolean").nodes(), [35,"Repo Man",5,15,"Twilight",3,"Trudy",2,"The Fighter",4,true]) | ||
| assert.deepEqual(select(people, ":has(.car) > .male").nodes(), [true]); | ||
| assert.deepEqual(select(people, ".male ~ .car").nodes(), [null]) | ||
| assert.deepEqual(select(people, ':val("Twilight")').nodes(), ["Twilight"]) | ||
| assert.deepEqual(select(people, ':val("Twi")').nodes(), []) | ||
| assert.deepEqual(select(people, ':contains("Twi")').nodes(), ["Twilight"]) | ||
| assert.deepEqual(select(people, ':contains("weif")').nodes(), []) | ||
| // invalid | ||
| assert.deepEqual(select(people, ".hmmm").nodes(), []); | ||
| assert.throws(function() { | ||
| select(people, "afcjwiojwe9q28*C@!(# (!#R($R)))").nodes(); | ||
| }); | ||
| // update() | ||
| people2 = traverse.clone(people); | ||
| select(people2, ".age").update(function(age) { | ||
| return age - 5; | ||
| }) | ||
| assert.deepEqual(select(people2, ".age").nodes(), [30, 10]); | ||
| obj = select(people2, ".age").update(3) | ||
| assert.deepEqual(select(people2, ".age").nodes(), [3, 3]); | ||
| assert.deepEqual(obj, people2); | ||
| // remove() | ||
| people2 = traverse.clone(people); | ||
| obj = select(people2, ".age").remove(); | ||
| assert.deepEqual(select(people2, ".age").nodes(), []); | ||
| assert.deepEqual(obj, people2); | ||
| // condense() | ||
| people2 = traverse.clone(people); | ||
| select(people2, ".george").condense(); | ||
| assert.deepEqual(people2, {"george": {age: 35, movies: [{name: "Repo Man", stars: 5}]}}); | ||
| people2 = traverse.clone(people); | ||
| select(people2, ".hmmm").condense(); | ||
| assert.deepEqual(people2, {}); | ||
| people2 = traverse.clone(people); | ||
| obj = select(people2, ".stars").condense(); | ||
| assert.deepEqual(people2, {"george": {movies: [{stars: 5}]}, "mary": {movies: [{stars: 3},{stars: 2},{stars: 4}]}}); | ||
| assert.deepEqual(obj, people2); | ||
| // forEach() | ||
| people2 = traverse.clone(people); | ||
| obj = select(people2, ".age").forEach(function(age) { | ||
| this.update(age - 5); | ||
| }) | ||
| assert.deepEqual(select(people2, ".age").nodes(), [30, 10]); | ||
| assert.deepEqual(obj, people2); | ||
| // this.matches() | ||
| people2 = traverse.clone(people); | ||
| select(people2).forEach(function(node) { | ||
| if (this.matches(".age")) { | ||
| this.update(node + 10); | ||
| } | ||
| }); | ||
| assert.deepEqual(select(people2, ".age").nodes(), [45, 25]) | ||
| // bigger stuff | ||
| var timeline = require("./timeline.js"); | ||
| console.time("select time"); | ||
| assert.equal(select(timeline, ".bug .id").nodes().length, 126); | ||
| assert.equal(select(timeline, ".id").nodes().length, 141); | ||
| assert.equal(select(timeline, ".comments .id").nodes().length, 115); | ||
| assert.equal(select(timeline, ":nth-child(n-2)").nodes().length, 335); | ||
| assert.equal(select(timeline, "object").nodes().length, 927); | ||
| assert.equal(select(timeline, "*").nodes().length, 3281); | ||
| console.timeEnd("select time") | ||
| var sel = require("JSONSelect"); | ||
| console.time("JSONSelect time") | ||
| assert.equal(sel.match(".bug .id", timeline).length, 126); | ||
| assert.equal(sel.match(".id", timeline).length, 141); | ||
| assert.equal(sel.match(".comments .id", timeline).length, 115); | ||
| assert.equal(sel.match(":nth-child(n-2)", timeline).length, 335); | ||
| assert.equal(sel.match("object", timeline).length, 927); | ||
| assert.equal(sel.match("*", timeline).length, 3281); | ||
| console.timeEnd("JSONSelect time") |
Sorry, the diff of this file is too big to display
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
AI-detected possible typosquat
Supply chain riskAI has identified this package as a potential typosquat of a more popular package. This suggests that the package may be intentionally mimicking another package's name, description, or other metadata.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 3 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
0
-100%0
-100%1
-75%0
-100%3
-72.73%671
-99.58%2
-77.78%0
-100%6
-94.92%- Removed
- Removed
- Removed
- Removed