diff --git a/Makefile b/Makefile index d2ba8fc..98f130d 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,12 @@ PACKAGE_VERSION = $(shell node -e 'console.log(require("./package.json").version all: $(LIB_DIR) @cp $(SRC_DIR)/sql_keywords.txt $(LIB_DIR)/ +standalone_bundle: clean all + node_modules/.bin/browserify -s gesundheit lib/index.js > gesundheit-standalone.js + +doc_bundle: clean all + node_modules/.bin/browserify -s gesundheit lib/index.js > doc/_static/bundle.js + .PHONY: test test: unit integration @@ -31,12 +37,10 @@ clean: $(LIB_DIR): $(SRC_DIR) @node_modules/.bin/coffee -o $@ -bc $< -pages: bundle +pages: doc_bundle make -C doc clean html - cp bundle.js doc/_build/html/_static - cp tryit.html doc/_build/html/_static -release: clean test pages +release: clean test pages standalone_bundle git checkout gh-pages cp -R doc/_build/html/ ./ [[ -z `git status -suno` ]] || git commit -a -m v$(PACKAGE_VERSION) diff --git a/README.rst b/README.rst index 4e3d5b9..da67c09 100644 --- a/README.rst +++ b/README.rst @@ -32,10 +32,10 @@ Install ------- In addition to the usual ``npm install gesundheit``, you will need to install -the driver for your database. Driver support is provided by `any-db -`_, which currently works with the ``pg``, -``mysql``, and ``sqlite3`` database drivers. So for example, if you use -PostgreSQL as your database backend you would do ``npm install pg gesundheit``. +the driver for your database. Driver support is provided by `Any-DB +`_, which currently supports MySQL, Postgres +and SQLite3. So for example, if you use PostgreSQL as your database backend you +would do ``npm install --save any-db-postgres``. License ------- diff --git a/doc/_static/bsm.css_t b/doc/_static/bsm.css_t deleted file mode 100644 index 6151549..0000000 --- a/doc/_static/bsm.css_t +++ /dev/null @@ -1,303 +0,0 @@ -/* - * nature.css_t - * ~~~~~~~~~~~~ - * - * Sphinx stylesheet -- nature theme. - * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -#laser, #pony { float: right; clear: right; } - -body { - font-family: Arial, sans-serif; - font-size: 100%; - background-color: #eee; - color: #555; - margin: 0; - padding: 0; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 260px; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 30px 30px; - font-size: 0.9em; -} - -div.footer { - color: #555; - margin: 0 0 0 260px; - padding: 13px 0; - text-align: center; - font-size: 75%; - background-color: #111; -} - -div.footer a { - color: #444; - text-decoration: underline; -} - -div.related { - background-color: #102023; - line-height: 32px; - color: #fff; - text-shadow: 0px 1px 0 #444; - font-size: 0.9em; -} - -div.related a { - color: #E33725; -} - -div.sphinxsidebar { - float: none; - border-right: 1px solid #ddd; - margin-left: 0; - width: 260px; - position: fixed; - font-size: 0.75em; - line-height: 1.5em; - z-index: 20; - height: 100%; - overflow-y: auto; -} - -div.sphinxsidebarwrapper{ - padding: 20px 0; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: Arial, sans-serif; - color: #222; - font-size: 1.2em; - font-weight: normal; - margin: 0; - padding: 5px 10px; - background-color: #ddd; -} - -div.sphinxsidebar h4{ - font-size: 1.1em; -} - -div.sphinxsidebar h3 a { - color: #444; -} - - -div.sphinxsidebar p { - color: #888; - padding: 5px 20px; -} - -div.sphinxsidebar p.topless { -} - -div.sphinxsidebar ul { - margin: 10px 0px 10px 16px; - padding: 0; - color: #000; -} - -div.sphinxsidebar a { - color: #444; -} - -/* Invisible borders to prevent jitters when highlighting sections */ -div.sphinxsidebar ul li > a { - border-bottom: 1px solid #eee; - border-top: 1px solid #eee; - display: block; - padding: 1px 0 0 4px; -} - -div.sphinxsidebar li.currentsection > a { - margin-right: -1px; - color: #8B1A02; - background-color: #fff; - font-weight: bold; - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; - border-radius: 6px 0px 0px 6px; -} - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar input[type=text]{ - margin-left: 20px; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #005B81; - text-decoration: none; -} - -a:hover { - color: #E32E00; - text-decoration: underline; -} - -div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { - color: #8B1A02; - font-family: Arial,sans-serif; - font-weight: normal; - text-shadow: 0 1px 0 #CBA39C; -} - -div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } -div.body h2 { border-bottom: 1px solid #CAC8C6; padding: 5px 0; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -/* Add some vertical whitespace in autodoc blocks */ -dl.class dl.attribute, dl.class dl.method { - margin-top: 22px; -} - -dl.class dl.attribute ~ dl.attribute, dl.class dl.method ~ dl.method { - margin-top: 15px; -} - -div.body p, div.body dd, div.body li { - line-height: 1.5em; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.highlight{ - background-color: white; -} - -.highlight { - display: block; - position: relative; -} -.highlight .expand, .highlight .collapse { - display: block; - position: absolute; - width: 100%; - padding: 2px 0px; - border-bottom: 1px solid #333; - background-color: #ddd; - opacity: .7; - text-align: center; - cursor: pointer; -} -.highlight .expand { - bottom: 0px; -} -.highlight .collapse { - width: 2em; - right: 1px; - top: 1px; - border-left: 1px solid #333; -} -.highlight .expand:hover { - background-color: #bbb; -} -.highlight pre { - padding: 10px; - margin: 1.5em 0 1.5em 0; - overflow: auto; - overflow-y: hidden; - line-height: 1.2em; - font-size: 1.1em; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 10px; - background-color: White; - color: #222; - line-height: 1.2em; - border: 1px solid #C6C9CB; - font-size: 1.1em; - margin: 1.5em 0 1.5em 0; - -webkit-box-shadow: 2px 3px 10px #d8d8d8; - -moz-box-shadow: 2px 3px 10px #d8d8d8; -} - -tt { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ - font-size: 1.1em; - font-family: monospace; -} - -.viewcode-back { - font-family: Arial, sans-serif; -} - -div.viewcode-block:target { - background-color: #dedede; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} diff --git a/doc/_static/bundle.js b/doc/_static/bundle.js new file mode 100644 index 0000000..28f477b --- /dev/null +++ b/doc/_static/bundle.js @@ -0,0 +1,6657 @@ +(function(e){if("function"==typeof bootstrap)bootstrap("gesundheit",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeGesundheit=e}else"undefined"!=typeof window?window.gesundheit=e():global.gesundheit=e()})(function(){var define,ses,bootstrap,module,exports; +return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o`_ that will delegate compiling to it's dialect +instance. +*/ + +var BaseDialect, Delete, Field, Insert, MySQLDialect, PostgresDialect, PrettyDialect, Relation, SQLite3Dialect, Select, Update, keywords, _ref, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +_ref = require('./nodes'), Select = _ref.Select, Update = _ref.Update, Delete = _ref.Delete, Insert = _ref.Insert, Relation = _ref.Relation, Field = _ref.Field; + +if (process.browser) { + keywords = []; +} else { + keywords = require('fs').readFileSync(__dirname + '/sql_keywords.txt').toString().split('\n').filter(Boolean); +} + +BaseDialect = (function() { + var Visitor, doubleQuote, needsQuote; + + function BaseDialect() {} + + BaseDialect.prototype.reset = function() {}; + + BaseDialect.prototype.compile = function(root) { + var text, visitor; + visitor = new Visitor(this); + text = visitor.compile(root); + return [text, visitor.params]; + }; + + BaseDialect.prototype.renderString = function(s) { + var path; + path = this.path.map(function(p) { + var _ref1; + return (_ref1 = p.constructor) != null ? _ref1.name : void 0; + }).join(' > '); + this.path = []; + throw new Error("raw string compiled! " + path); + }; + + needsQuote = /\s|"|\./; + + doubleQuote = /"/g; + + BaseDialect.prototype.quote = function(s) { + if ((s != null ? s.match(needsQuote) : void 0) || this.isKeyword(s)) { + return '"' + s.replace(doubleQuote, '\\"') + '"'; + } else { + return s; + } + }; + + BaseDialect.prototype.isKeyword = function(word) { + return keywords.indexOf(word.toUpperCase()) !== -1; + }; + + BaseDialect.prototype.operator = function(op) { + switch ((op = op.toUpperCase())) { + case 'NE': + case '!=': + case '<>': + return '!='; + case 'EQ': + case '=': + return '='; + case 'LT': + case '<': + return '<'; + case 'GT': + case '>': + return '>'; + case 'LTE': + case '<=': + return '<='; + case 'GTE': + case '>=': + return '>='; + case 'LIKE': + case 'ILIKE': + case 'IN': + case 'NOT IN': + case 'IS': + case 'IS NOT': + return op; + default: + throw new Error("Unsupported comparison operator: " + op); + } + }; + + BaseDialect.prototype.placeholder = function(position) { + return "$" + position; + }; + + Visitor = (function() { + + function Visitor(dialect) { + this.dialect = dialect; + this.path = []; + this.params = []; + } + + Visitor.prototype.compile = function(node, allowOverride) { + var custom, name, string, _ref1, _ref2; + if (allowOverride == null) { + allowOverride = true; + } + this.path.push(node); + name = node != null ? (_ref1 = node.__proto__) != null ? (_ref2 = _ref1.constructor) != null ? _ref2.name : void 0 : void 0 : void 0; + if (allowOverride && name && (custom = this.dialect['render' + name])) { + string = custom.call(this, node); + } else { + if (!(node != null ? node.compile : void 0)) { + debugger; + } + string = node.compile(this, this.path); + } + this.path.pop(node); + return string; + }; + + Visitor.prototype.maybeParens = function(it) { + if (/\s/.exec(it)) { + return "(" + it + ")"; + } else { + return it; + } + }; + + Visitor.prototype.operator = function(string) { + return this.dialect.operator(string); + }; + + Visitor.prototype.parameter = function(val) { + this.params.push(val); + return this.dialect.placeholder(this.params.length); + }; + + Visitor.prototype.quote = function(string) { + return this.dialect.quote(string, this.path); + }; + + return Visitor; + + })(); + + return BaseDialect; + +})(); + +PrettyDialect = (function(_super) { + + __extends(PrettyDialect, _super); + + function PrettyDialect() { + return PrettyDialect.__super__.constructor.apply(this, arguments); + } + + PrettyDialect.prototype.renderJoin = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderWhere = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderHaving = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderOrderBy = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderGroupBy = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderRelationSet = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderSelectColumnSet = function(node) { + var glue, last, lines, size, text, thisLine, thisLineLength, _i, _len, _ref1; + glue = node.glue; + last = node.nodes.length; + lines = []; + thisLine = []; + thisLineLength = 81; + _ref1 = node.nodes; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + node = _ref1[_i]; + text = this.compile(node); + size = text.length + glue.length; + if (thisLineLength + size > 50) { + lines.push(thisLine.join(glue)); + thisLine = []; + thisLineLength = 0; + } + thisLineLength += size; + thisLine.push(text); + } + lines.shift(); + lines.push(thisLine.join(glue)); + return lines.join("\n "); + }; + + return PrettyDialect; + +})(BaseDialect); + +PostgresDialect = (function(_super) { + + __extends(PostgresDialect, _super); + + function PostgresDialect() { + return PostgresDialect.__super__.constructor.apply(this, arguments); + } + + PostgresDialect.prototype.operator = function(op) { + switch (op.toLowerCase()) { + case 'hasKey': + case '?': + return '?'; + case 'contains': + case '@>': + return '@>'; + case '->': + return '->'; + default: + return PostgresDialect.__super__.operator.call(this, op); + } + }; + + PostgresDialect.prototype.isKeyword = function(s) { + return (s != null) && s !== '*'; + }; + + return PostgresDialect; + +})(BaseDialect); + +MySQLDialect = (function(_super) { + + __extends(MySQLDialect, _super); + + function MySQLDialect() { + return MySQLDialect.__super__.constructor.apply(this, arguments); + } + + MySQLDialect.prototype.placeholder = function() { + return '?'; + }; + + MySQLDialect.prototype.quote = function(s, path) { + /* + MySQL has two special cases for quoting: + - The column names in an insert column list are not quoted + - table and field names are quoted with backticks. + */ + + var node; + node = path[path.length - 1]; + if (s === '*' || path.some(function(node) { + return node instanceof Insert.ColumnList; + })) { + return s; + } else if (node instanceof Field || node instanceof Relation) { + return "`" + s + "`"; + } else { + return MySQLDialect.__super__.quote.apply(this, arguments); + } + }; + + return MySQLDialect; + +})(BaseDialect); + +SQLite3Dialect = (function(_super) { + + __extends(SQLite3Dialect, _super); + + function SQLite3Dialect() { + return SQLite3Dialect.__super__.constructor.apply(this, arguments); + } + + SQLite3Dialect.prototype.placeholder = function() { + return '?'; + }; + + SQLite3Dialect.prototype.renderInsertData = function(node) { + var string; + if (node.nodes.length < 2) { + return node.compile(this, this.path); + } else { + node.glue = ' UNION ALL SELECT '; + string = node.compile(this, this.path).replace('VALUES', 'SELECT').replace(/[()]/g, ''); + node.glue = ', '; + return string; + } + }; + + return SQLite3Dialect; + +})(BaseDialect); + +module.exports = { + base: BaseDialect, + pretty: PrettyDialect, + postgres: PostgresDialect, + mysql: MySQLDialect, + sqlite3: SQLite3Dialect +}; + +},{"./nodes":7,"__browserify_process":27,"fs":19}],5:[function(require,module,exports){ +var process=require("__browserify_process");// Generated by CoffeeScript 1.4.0 +var Engine, anyDB, dialects, fakePool, queries, url; + +url = require('url'); + +anyDB = require('any-db'); + +queries = require('./queries/index'); + +dialects = require('./dialects'); + +module.exports = function() { + return Engine.create.apply(Engine, arguments); +}; + +Engine = (function() { + /* + ``Engine`` is gesundheits interface to an actual database. + + Engines have all of the :ref:`query factory functions ` + attached to them as instance methods that automatically bind created queries + to the engine. They also have these additionaly methods + */ + + Engine.create = function(dbUrl, poolOptions) { + /* + Create an :class:`engine::Engine` instance from an Any-DB_ connect string + and extra connection pool options, this is exported by gesundheit as + ``gesundheit.engine(...)``. + + :ref:`This example ` shows the most common way to set up + a single default database engine for an application. + + .. _Any-DB: https://github.com/grncdr/node-any-db + .. _Any-DB ConnectionPool: https://github.com/grncdr/node-any-db/blob/master/API.md#connectionpool + */ + + var dialectType, driverName, parsed, pool; + parsed = url.parse(dbUrl); + driverName = parsed.protocol.replace(':', '').split('+').shift(); + if (driverName === 'fake') { + pool = fakePool(); + if (parsed.protocol.match('pretty')) { + dialectType = dialects.pretty; + } else { + dialectType = dialects.base; + } + } else { + pool = anyDB.createPool(dbUrl, poolOptions); + dialectType = dialects[driverName]; + } + if (!(dialectType != null)) { + throw new Error('no such dialect: ' + driverName); + } + return new Engine(driverName, dbUrl, pool, new dialectType()); + }; + + function Engine(driver, url, pool, dialect) { + this.driver = driver; + this.url = url; + this.pool = pool; + this.dialect = dialect; + queries.mixinFactoryMethods(this); + } + + Engine.prototype.query = function(statement, params, callback) { + /* + Passes arguments directly to the query method of the underlying `Any-DB + ConnectionPool`_ + */ + + var _ref; + return (_ref = this.pool).query.apply(_ref, arguments); + }; + + Engine.prototype.begin = function(callback) { + /* + Start a new transaction and return it. + + The returned object behaves exactly like a new engine, but has ``commit`` + and ``rollback`` methods instead of ``close``. (In fact it's an `Any-DB + Transaction`_ that has had the query factory functions mixed in to it). + + .. _Any-DB Transaction: https://github.com/grncdr/node-any-db/blob/master/API.md#transaction + */ + + var tx; + tx = queries.mixinFactoryMethods(this.pool.begin(callback)); + tx.engine = this; + tx.compile = this.dialect.compile.bind(this.dialect); + return tx; + }; + + Engine.prototype.compile = function(root) { + /* + Render an AST to a SQL string and collect parameters + */ + return this.dialect.compile(root); + }; + + Engine.prototype.close = function() { + /* + Closes the internal connection pool. + */ + return this.pool.close(); + }; + + return Engine; + +})(); + +fakePool = function() { + /* + Create a fake database connection pool that throws errors if you try to + execute a query. + */ + return { + begin: function(cb) { + if (cb) { + process.nextTick(cb.bind(null, engine)); + } + return engine; + }, + query: function(sql, params, cb) { + throw new Error("Cannot query with fakeEngine. Do `gesundheit.defaultEngine = gesundheit.engine(url)` before querying"); + }, + close: function() {} + }; +}; + +},{"./dialects":4,"./queries/index":10,"__browserify_process":27,"any-db":26,"url":21}],6:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +There are a few subsystems that make up gesundheit, but the majority of use +cases will be covered by using the following properties of the main module: + + **gesundheit.{Select, SELECT, select}** + Function for creating new :class:`queries/select::SelectQuery` instances. + + **gesundheit.{Update, UPDATE, update}** + Function for creating new :class:`queries/update::UpdateQuery` instances. + + **gesundheit.{Delete, DELETE, delete}** + Function for creating new :class:`queries/delete::DeleteQuery` instances. + + **gesundheit.{Insert, INSERT, insert}** + Function for creating new :class:`queries/insert::InsertQuery` instances. + + **gesundheit.engine** + Function for creating new :mod:`engines`. + + **gesundheit.defaultEngine** + The engine that will be used for queries that aren't explicitly bound. This + is set to a no-op engine that you will want to replace with either an object + returned by the ``gesundheit.engine`` function or by implementing the engine + interface yourself. + + **Join types** + Constant nodes for use with :meth:`queries/sud::SUDQuery.join`. + 'LEFT', 'RIGHT', 'INNER', 'LEFT_OUTER', 'RIGHT_OUTER', 'FULL_OUTER' + 'NATURAL', 'CROSS' + + **AST helper functions** + These come from the `nodes <#module-nodes::>`_ module and are often useful + when constructing complicated queries: + + :func:`nodes::toParam` + Convert any object to a parameter placeholder. + :func:`nodes::toRelation` + Convert various inputs to :class:`nodes::Relation` nodes. + :func:`nodes::binaryOp` + Create a binary comparison node manually. (e.g. for postgres' custom + operators). + :func:`nodes::sqlFunction` + Create SQL function calls (e.g. ``MAX(last_update)``) + :func:`nodes::text` + Include raw SQL in a query, with parameter placeholders. + +If you are implementing support for a different database engine or constructing +particularly unusual SQL statements, you might also want to make use of these: + + **gesundheit.nodes** + The `nodes ` module. + + **gesundheit.dialects** + The `dialects ` module. +*/ + +var helper, name, node, _ref, _ref1, _ref2, + __slice = [].slice; + +exports.dialects = require('./dialects'); + +exports.engine = require('./engine'); + +exports.nodes = require('./nodes'); + +exports.queries = require('./queries/index'); + +exports.defaultEngine = exports.engine('fake://localhost/'); + +exports.queries.mixinFactoryMethods(exports, function() { + return exports.defaultEngine; +}); + +_ref = exports.nodes.CONST_NODES; +for (name in _ref) { + node = _ref[name]; + exports[name] = exports.nodes.CONST_NODES[name]; +} + +_ref1 = exports.nodes.JOIN_TYPES; +for (name in _ref1) { + node = _ref1[name]; + exports[name] = exports.nodes.JOIN_TYPES[name]; +} + +_ref2 = exports.nodes; +for (name in _ref2) { + helper = _ref2[name]; + if (name[0] === name[0].toLowerCase()) { + exports[name] = helper; + } +} + +exports.begin = function() { + var args, _ref3; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return (_ref3 = exports.defaultEngine).begin.apply(_ref3, args); +}; + +exports.query = function() { + var args, _ref3; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return (_ref3 = exports.defaultEngine).query.apply(_ref3, args); +}; + +exports.unmarshaller = require('./unmarshal'); + +},{"./dialects":4,"./engine":5,"./nodes":7,"./queries/index":10,"./unmarshal":16}],7:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +These are the classes that represent nodes in the AST for a SQL statement. +Application code should very rarely have to deal with these classes directly; +Instead, the APIs exposed by the various query manager classes are intended to +cover the majority of use-cases. + +However, in the spirit of "making hard things possible", all of AST nodes are +exported from this module so you can constructed and assemble them manually if +you need to. +*/ + +var AbstractAlias, And, Binary, CONST_NODES, Column, ColumnSet, ComparableMixin, Delete, Distinct, Field, FixedNodeSet, FunctionAlias, GroupBy, Having, Identifier, Insert, IntegerNode, JOIN_TYPES, Join, JoinType, Limit, Node, NodeSet, Offset, Or, OrderBy, Ordering, Parameter, ParenthesizedNodeSet, Prefixed, Relation, RelationAlias, RelationSet, Returning, Select, SelectColumnSet, SqlFunction, Statement, TextAlias, TextNode, Tuple, Update, ValueNode, Where, binaryOp, copy, ctor, exists, func, getAlias, merge, name, notExists, sqlFunction, text, toColumn, toField, toParam, toProjection, toRelation, tuple, unmarshal, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + +Node = (function() { + + function Node() {} + + /* (Empty) base Node class + */ + + + Node.prototype.compile = function(dialect) { + var message; + message = "" + this.constructor + " has no compile method. Parents: " + dialect.path; + throw new Error(message); + }; + + Node.prototype.toJSON = function() { + return { + _type: this.constructor.name + }; + }; + + Node.prototype.copy = function() { + return unmarshal(this.toJSON()); + }; + + return Node; + +})(); + +ValueNode = (function(_super) { + + __extends(ValueNode, _super); + + /* A ValueNode is a literal string that should be printed unescaped. + */ + + + ValueNode.unmarshal = function(data, recur) { + return new this(data.value); + }; + + function ValueNode(value) { + this.value = value; + if (this.value != null) { + if (!this.valid()) { + throw new Error("Invalid " + this.constructor.name + ": " + this.value); + } + } + } + + ValueNode.prototype.valid = function() { + return true; + }; + + ValueNode.prototype.compile = function() { + return this.value; + }; + + ValueNode.prototype.toJSON = function() { + return merge(ValueNode.__super__.toJSON.apply(this, arguments), { + value: this.value + }); + }; + + return ValueNode; + +})(Node); + +IntegerNode = (function(_super) { + + __extends(IntegerNode, _super); + + function IntegerNode() { + return IntegerNode.__super__.constructor.apply(this, arguments); + } + + /* A :class:`nodes::ValueNode` that validates it's input is an integer. + */ + + + IntegerNode.prototype.valid = function() { + return !isNaN(this.value = parseInt(this.value)); + }; + + return IntegerNode; + +})(ValueNode); + +Identifier = (function(_super) { + + __extends(Identifier, _super); + + function Identifier() { + return Identifier.__super__.constructor.apply(this, arguments); + } + + /* + An identifier is a column or relation name that may need to be quoted. + */ + + + Identifier.prototype.compile = function(dialect) { + return dialect.quote(this.value); + }; + + return Identifier; + +})(ValueNode); + +CONST_NODES = {}; + +_ref = ['DEFAULT', 'NULL', 'IS_NULL', 'IS_NOT_NULL']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + CONST_NODES[name] = new ValueNode(name.replace('_', ' ')); +} + +JoinType = (function(_super) { + + __extends(JoinType, _super); + + function JoinType() { + return JoinType.__super__.constructor.apply(this, arguments); + } + + return JoinType; + +})(ValueNode); + +JOIN_TYPES = {}; + +_ref1 = ['LEFT', 'RIGHT', 'INNER', 'LEFT_OUTER', 'RIGHT_OUTER', 'FULL_OUTER', 'NATURAL', 'CROSS']; +for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + name = _ref1[_j]; + JOIN_TYPES[name] = new JoinType(name.replace('_', ' ')); +} + +NodeSet = (function(_super) { + + __extends(NodeSet, _super); + + /* A set of nodes joined together by ``@glue`` + */ + + + NodeSet.unmarshal = function(data, recur) { + return new this(recur(data.nodes), data.glue); + }; + + function NodeSet(nodes, glue) { + var node, _k, _len2, _ref2; + if (glue == null) { + glue = ' '; + } + /* + :param @nodes: A list of child nodes. + :param glue: A string that will be used to join the nodes when compileing + */ + + this.nodes = []; + if (nodes) { + for (_k = 0, _len2 = nodes.length; _k < _len2; _k++) { + node = nodes[_k]; + this.addNode(node); + } + } + if ((_ref2 = this.glue) == null) { + this.glue = glue; + } + } + + NodeSet.prototype.addNode = function(node) { + /* Add a new Node to the end of this set + */ + return this.nodes.push(node); + }; + + NodeSet.prototype.compile = function(dialect) { + var compile; + compile = dialect.compile.bind(dialect); + return this.nodes.map(compile).filter(Boolean).join(this.glue); + }; + + NodeSet.prototype.toJSON = function() { + return merge(NodeSet.__super__.toJSON.apply(this, arguments), { + glue: this.glue, + nodes: this.nodes.map(function(n) { + return n.toJSON(); + }) + }); + }; + + return NodeSet; + +})(Node); + +FixedNodeSet = (function(_super) { + + __extends(FixedNodeSet, _super); + + function FixedNodeSet() { + FixedNodeSet.__super__.constructor.apply(this, arguments); + this.addNode = null; + } + + return FixedNodeSet; + +})(NodeSet); + +Statement = (function(_super) { + + __extends(Statement, _super); + + Statement.prefix = ''; + + Statement.structure = function(structure) { + var _this = this; + this._nodeOrder = []; + return structure.forEach(function(_arg) { + var k, type; + k = _arg[0], type = _arg[1]; + _this._nodeOrder.push(k); + _this.prototype.__defineGetter__(k, function() { + var _base; + return (_base = this._private)[k] || (_base[k] = new type); + }); + return _this.prototype.__defineSetter__(k, function(v) { + return this._private[k] = v; + }); + }); + }; + + Statement.unmarshal = function(data, recur) { + var it; + it = new this; + delete data._type; + it._private = recur(data); + return it; + }; + + function Statement(opts) { + this._private = {}; + if (opts) { + this.initialize(opts); + } + } + + Statement.prototype.initialize = function(opts) { + return this.initialize = null; + }; + + Statement.prototype.compile = function(dialect) { + var k, node, parts; + parts = (function() { + var _k, _len2, _ref2, _results; + _ref2 = this.constructor._nodeOrder; + _results = []; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + k = _ref2[_k]; + if (node = this._private[k]) { + _results.push(dialect.compile(node)); + } + } + return _results; + }).call(this); + if (parts.length) { + return this.constructor.prefix + parts.join(' '); + } else { + return ""; + } + }; + + Statement.prototype.toJSON = function() { + var k, parent, v, _ref2; + parent = Statement.__super__.toJSON.apply(this, arguments); + _ref2 = this._private; + for (k in _ref2) { + v = _ref2[k]; + parent[k] = v.toJSON(); + } + return parent; + }; + + return Statement; + +})(Node); + +ParenthesizedNodeSet = (function(_super) { + + __extends(ParenthesizedNodeSet, _super); + + function ParenthesizedNodeSet() { + return ParenthesizedNodeSet.__super__.constructor.apply(this, arguments); + } + + /* A NodeSet wrapped in parenthesis. + */ + + + ParenthesizedNodeSet.prototype.compile = function() { + return "(" + ParenthesizedNodeSet.__super__.compile.apply(this, arguments) + ")"; + }; + + return ParenthesizedNodeSet; + +})(NodeSet); + +AbstractAlias = (function(_super) { + + __extends(AbstractAlias, _super); + + AbstractAlias.patch = function(klazz) { + klazz.Alias = this; + return klazz.prototype.as = function(name) { + return new this.constructor.Alias(this, name); + }; + }; + + AbstractAlias.unmarshal = function(data, recur) { + return new this(recur(data.obj), data.alias); + }; + + function AbstractAlias(obj, alias) { + this.obj = obj; + this.alias = alias; + } + + AbstractAlias.prototype.ref = function() { + return this.alias; + }; + + AbstractAlias.prototype.compile = function(dialect) { + return dialect.maybeParens(dialect.compile(this.obj)) + " AS " + dialect.quote(this.alias); + }; + + AbstractAlias.prototype.toJSON = function() { + return merge(AbstractAlias.__super__.toJSON.apply(this, arguments), { + obj: this.obj.toJSON(), + alias: this.alias + }); + }; + + return AbstractAlias; + +})(Node); + +TextNode = (function(_super) { + var paramRegexp; + + __extends(TextNode, _super); + + TextNode.unmarshal = function(data, recur) { + return new this(data.text, data.bindVals); + }; + + function TextNode(text, bindVals) { + this.text = text; + this.bindVals = bindVals != null ? bindVals : []; + } + + paramRegexp = /\$([\w]+)\b/g; + + TextNode.prototype.compile = function(dialect) { + var _this = this; + return this.text.replace(paramRegexp, function(_, name) { + if (name in _this.bindVals) { + return dialect.parameter(_this.bindVals[name]); + } else { + throw new Error("Parameter " + name + " not present in " + (JSON.stringify(_this.bindVals))); + } + }); + }; + + TextNode.prototype.toJSON = function() { + return merge(TextNode.__super__.toJSON.apply(this, arguments), { + text: this.text, + bindVals: this.bindVals + }); + }; + + return TextNode; + +})(Node); + +TextAlias = (function(_super) { + + __extends(TextAlias, _super); + + function TextAlias() { + return TextAlias.__super__.constructor.apply(this, arguments); + } + + TextAlias.patch(TextNode); + + return TextAlias; + +})(AbstractAlias); + +SqlFunction = (function(_super) { + + __extends(SqlFunction, _super); + + /* Includes :class:`nodes::ComparableMixin` + */ + + + SqlFunction.unmarshal = function(data, recur) { + return new this(data.name, data.arglist); + }; + + function SqlFunction(name, arglist) { + this.name = name; + this.arglist = arglist; + } + + SqlFunction.prototype.ref = function() { + return this.name; + }; + + SqlFunction.prototype.compile = function(d) { + return "" + this.name + (d.compile(this.arglist)); + }; + + SqlFunction.prototype.toJSON = function() { + return merge(SqlFunction.__super__.toJSON.apply(this, arguments), { + name: this.name, + arglist: this.arglist + }); + }; + + return SqlFunction; + +})(Node); + +FunctionAlias = (function(_super) { + var shouldRenderFull; + + __extends(FunctionAlias, _super); + + function FunctionAlias() { + return FunctionAlias.__super__.constructor.apply(this, arguments); + } + + FunctionAlias.patch(SqlFunction); + + shouldRenderFull = function(parents) { + if (parents.some(function(it) { + return it instanceof Column; + })) { + return false; + } + return parents.some(function(node) { + return node instanceof ColumnSet || node instanceof RelationSet; + }); + }; + + FunctionAlias.prototype.compile = function(dialect, parents) { + if (shouldRenderFull(parents)) { + return dialect.compile(this.obj) + " AS " + dialect.quote(this.alias); + } else { + return dialect.quote(this.alias); + } + }; + + return FunctionAlias; + +})(AbstractAlias); + +Parameter = (function(_super) { + + __extends(Parameter, _super); + + function Parameter() { + return Parameter.__super__.constructor.apply(this, arguments); + } + + /* + Like a ValueNode, but will render as a bound parameter place-holder + (e.g. ``$1``) and it's value will be collected by the dialect when compiling. + */ + + + Parameter.prototype.compile = function(dialect) { + return dialect.parameter(this.value); + }; + + return Parameter; + +})(ValueNode); + +Relation = (function(_super) { + + __extends(Relation, _super); + + function Relation() { + return Relation.__super__.constructor.apply(this, arguments); + } + + /* + A relation node represents a table name or alias in a statement. + */ + + + Relation.prototype.ref = function() { + /* + Return the table name. Aliased tables return the alias name. + */ + return this.value; + }; + + Relation.prototype.project = function(field) { + /* Return a new :class:`nodes::Column` of `field` from this table. + */ + return new Column(this, toField(field)); + }; + + return Relation; + +})(Identifier); + +RelationAlias = (function(_super) { + + __extends(RelationAlias, _super); + + /* An aliased :class:`nodes::Relation` + */ + + + function RelationAlias() { + return RelationAlias.__super__.constructor.apply(this, arguments); + } + + RelationAlias.patch(Relation); + + RelationAlias.prototype.project = function(field) { + return Relation.prototype.project.call(this, field); + }; + + RelationAlias.prototype.compile = function(dialect, parents) { + if (parents.some(function(n) { + return n instanceof Column; + })) { + return dialect.quote(this.alias); + } else { + return RelationAlias.__super__.compile.apply(this, arguments); + } + }; + + return RelationAlias; + +})(AbstractAlias); + +Field = (function(_super) { + + __extends(Field, _super); + + /* A column name + */ + + + function Field() { + return Field.__super__.constructor.apply(this, arguments); + } + + return Field; + +})(Identifier); + +Column = (function(_super) { + var Alias; + + __extends(Column, _super); + + /* + Includes :class:`nodes::ComparableMixin` + */ + + + Column.unmarshal = function(data, recur) { + return new this(recur(data.nodes[0]), recur(data.nodes[1])); + }; + + function Column(source, field) { + this.source = source; + this.field = field; + Column.__super__.constructor.call(this, [this.source, this.field], '.'); + } + + Column.prototype.rel = function() { + return this.source; + }; + + Column.prototype.as = function(alias) { + /* Return an aliased version of this column. + */ + return new Alias(this, alias); + }; + + Column.Alias = Alias = (function(_super1) { + + __extends(Alias, _super1); + + function Alias() { + return Alias.__super__.constructor.apply(this, arguments); + } + + /* An aliased :class:`nodes::Column` + */ + + + Alias.prototype.rel = function() { + return this.obj.rel(); + }; + + Alias.prototype.compile = function(dialect, parents) { + var node, _k, _len2; + for (_k = 0, _len2 = parents.length; _k < _len2; _k++) { + node = parents[_k]; + if (node instanceof ColumnSet) { + return dialect.compile(this.obj) + " AS " + dialect.quote(this.alias); + } + } + return dialect.quote(this.alias); + }; + + return Alias; + + })(AbstractAlias); + + return Column; + +})(FixedNodeSet); + +Limit = (function(_super) { + + __extends(Limit, _super); + + function Limit() { + return Limit.__super__.constructor.apply(this, arguments); + } + + Limit.prototype.compile = function() { + if (this.value) { + return "LIMIT " + this.value; + } else { + return ""; + } + }; + + return Limit; + +})(IntegerNode); + +Offset = (function(_super) { + + __extends(Offset, _super); + + function Offset() { + return Offset.__super__.constructor.apply(this, arguments); + } + + Offset.prototype.compile = function() { + if (this.value) { + return "OFFSET " + this.value; + } else { + return ""; + } + }; + + return Offset; + +})(IntegerNode); + +Binary = (function(_super) { + + __extends(Binary, _super); + + Binary.unmarshal = function(data, recur) { + return new this(recur(data.left), recur(data.op), recur(data.right)); + }; + + function Binary(left, op, right) { + this.left = left; + this.op = op; + this.right = right; + Binary.__super__.constructor.call(this, [this.left, this.op, this.right], ' '); + } + + Binary.prototype.and = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new And([this].concat(__slice.call(args))); + }; + + Binary.prototype.or = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new Or([this].concat(__slice.call(args))); + }; + + Binary.prototype.compile = function(dialect) { + return [dialect.compile(this.left), dialect.operator(this.op), dialect.compile(this.right)].join(' '); + }; + + Binary.prototype.toJSON = function() { + return merge(Node.prototype.toJSON.call(this), { + left: this.left.toJSON(), + op: this.op, + right: this.right.toJSON() + }); + }; + + return Binary; + +})(FixedNodeSet); + +Tuple = (function(_super) { + + __extends(Tuple, _super); + + function Tuple() { + return Tuple.__super__.constructor.apply(this, arguments); + } + + Tuple.prototype.glue = ', '; + + return Tuple; + +})(ParenthesizedNodeSet); + +ColumnSet = (function(_super) { + + __extends(ColumnSet, _super); + + function ColumnSet() { + return ColumnSet.__super__.constructor.apply(this, arguments); + } + + /* The list of projected columns in a query + */ + + + ColumnSet.prototype.glue = ', '; + + return ColumnSet; + +})(NodeSet); + +Returning = (function(_super) { + + __extends(Returning, _super); + + function Returning() { + return Returning.__super__.constructor.apply(this, arguments); + } + + Returning.extend = function(klazz) { + return klazz.prototype.addReturning = function(cols) { + var col, _k, _len2; + for (_k = 0, _len2 = cols.length; _k < _len2; _k++) { + col = cols[_k]; + this.returning.addNode(toField(col)); + } + return null; + }; + }; + + Returning.prototype.compile = function() { + var string; + if (string = Returning.__super__.compile.apply(this, arguments)) { + return "RETURNING " + string; + } else { + return ""; + } + }; + + return Returning; + +})(ColumnSet); + +Distinct = (function(_super) { + + __extends(Distinct, _super); + + function Distinct(enable) { + this.enable = enable != null ? enable : false; + Distinct.__super__.constructor.apply(this, arguments); + } + + Distinct.prototype.compile = function(dialect) { + if (!this.enable) { + return ''; + } else if (this.nodes.length) { + return "DISTINCT(" + Distinct.__super__.compile.apply(this, arguments) + ")"; + } else { + return 'DISTINCT'; + } + }; + + return Distinct; + +})(ColumnSet); + +SelectColumnSet = (function(_super) { + + __extends(SelectColumnSet, _super); + + function SelectColumnSet() { + return SelectColumnSet.__super__.constructor.apply(this, arguments); + } + + SelectColumnSet.prototype.prune = function(predicate) { + /* + Recurse over child nodes, removing all Column nodes that match the + predicate. + */ + return this.nodes = this.nodes.filter(function(n) { + return !predicate(n); + }); + }; + + SelectColumnSet.prototype.compile = function(dialect) { + if (!this.nodes.length) { + return '*'; + } else { + return SelectColumnSet.__super__.compile.apply(this, arguments); + } + }; + + return SelectColumnSet; + +})(ColumnSet); + +RelationSet = (function(_super) { + + __extends(RelationSet, _super); + + function RelationSet() { + return RelationSet.__super__.constructor.apply(this, arguments); + } + + /* + Manages a set of relations and exposes methods to find them by alias. + */ + + + RelationSet.prototype.addNode = function(node) { + if (!this.first) { + this.relsByName = {}; + this.nodes.push(node); + return this.first = this.active = this.relsByName[node.ref()] = node; + } else { + RelationSet.__super__.addNode.apply(this, arguments); + return this.active = this.relsByName[node.ref()] = node.relation; + } + }; + + RelationSet.prototype.get = function(name, strict) { + var found; + if (strict == null) { + strict = true; + } + if ('string' !== typeof name) { + name = name.ref(); + } + found = this.relsByName[name]; + if (strict && !found) { + throw new Error("No such relation " + name + " in " + (Object.keys(this.relsByName))); + } + return found; + }; + + RelationSet.prototype["switch"] = function(name) { + return this.active = this.get(name); + }; + + RelationSet.prototype.compile = function(dialect) { + var string; + if (string = RelationSet.__super__.compile.apply(this, arguments)) { + return "FROM " + string; + } else { + return ""; + } + }; + + return RelationSet; + +})(NodeSet); + +Join = (function(_super) { + var JOIN, ON; + + __extends(Join, _super); + + JOIN = new ValueNode('JOIN'); + + ON = new ValueNode('ON'); + + Join.unmarshal = function(data, recur) { + var clause, join, nodes, _k, _len2, _ref2; + nodes = data.nodes; + join = new this(recur(nodes[0]), recur(nodes[2])); + _ref2 = nodes.slice(4); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + clause = _ref2[_k]; + join.on(clause); + } + return join; + }; + + function Join(type, relation) { + var nodes; + this.type = type; + this.relation = relation; + nodes = [this.type, JOIN, this.relation]; + Join.__super__.constructor.call(this, nodes); + } + + Join.prototype.on = function(clause) { + if (this.nodes.length < 4) { + this.nodes.push(ON); + } + return this.nodes.push(clause); + }; + + Join.prototype.ref = function() { + return this.relation.ref(); + }; + + return Join; + +})(FixedNodeSet); + +Where = (function(_super) { + + __extends(Where, _super); + + function Where() { + return Where.__super__.constructor.apply(this, arguments); + } + + Where.prototype.glue = ' AND '; + + Where.prototype.compile = function(dialect) { + var string; + if (string = Where.__super__.compile.apply(this, arguments)) { + return "WHERE " + string; + } else { + return ""; + } + }; + + return Where; + +})(NodeSet); + +Or = (function(_super) { + + __extends(Or, _super); + + function Or() { + return Or.__super__.constructor.apply(this, arguments); + } + + Or.prototype.glue = ' OR '; + + Or.prototype.and = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new And([this].concat(__slice.call(args))); + }; + + Or.prototype.or = function() { + var arg, args, ret, _k, _len2; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + ret = this.copy(); + for (_k = 0, _len2 = args.length; _k < _len2; _k++) { + arg = args[_k]; + ret.addNode(arg); + } + return ret; + }; + + return Or; + +})(ParenthesizedNodeSet); + +And = (function(_super) { + + __extends(And, _super); + + function And() { + return And.__super__.constructor.apply(this, arguments); + } + + And.prototype.glue = ' AND '; + + And.prototype.and = function() { + var arg, args, ret, _k, _len2; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + ret = this.copy(); + for (_k = 0, _len2 = args.length; _k < _len2; _k++) { + arg = args[_k]; + ret.addNode(arg); + } + return ret; + }; + + And.prototype.or = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new Or([this].concat(__slice.call(args))); + }; + + return And; + +})(ParenthesizedNodeSet); + +GroupBy = (function(_super) { + + __extends(GroupBy, _super); + + function GroupBy() { + return GroupBy.__super__.constructor.apply(this, arguments); + } + + GroupBy.prototype.glue = ', '; + + GroupBy.prototype.compile = function(dialect) { + var string; + if (string = GroupBy.__super__.compile.apply(this, arguments)) { + return "GROUP BY " + string; + } else { + return ""; + } + }; + + return GroupBy; + +})(NodeSet); + +Having = (function(_super) { + + __extends(Having, _super); + + function Having() { + return Having.__super__.constructor.apply(this, arguments); + } + + Having.prototype.glue = ' AND '; + + Having.prototype.compile = function(dialect) { + var string; + if (string = Having.__super__.compile.apply(this, arguments)) { + return "HAVING " + string; + } else { + return ""; + } + }; + + return Having; + +})(NodeSet); + +OrderBy = (function(_super) { + + __extends(OrderBy, _super); + + function OrderBy(orderings) { + OrderBy.__super__.constructor.call(this, orderings, ', '); + } + + OrderBy.prototype.compile = function(dialect) { + var string; + if (string = OrderBy.__super__.compile.apply(this, arguments)) { + return "ORDER BY " + string; + } else { + return ""; + } + }; + + return OrderBy; + +})(NodeSet); + +Ordering = (function(_super) { + + __extends(Ordering, _super); + + function Ordering(projection, direction) { + if (typeof direction === 'string') { + direction = new ValueNode(direction); + } + Ordering.__super__.constructor.call(this, [projection, direction]); + } + + return Ordering; + +})(FixedNodeSet); + +Select = (function(_super) { + + __extends(Select, _super); + + /* + The root node of a SELECT query + */ + + + function Select() { + return Select.__super__.constructor.apply(this, arguments); + } + + Select.prefix = 'SELECT '; + + Select.structure([['distinct', Distinct], ['projections', SelectColumnSet], ['relations', RelationSet], ['where', Where], ['groupBy', GroupBy], ['having', Having], ['orderBy', OrderBy], ['limit', Limit], ['offset', Offset]]); + + Select.prototype.initialize = function(opts) { + this.projections; + if (opts.table) { + return this.relations.addNode(toRelation(opts.table)); + } + }; + + return Select; + +})(Statement); + +Update = (function(_super) { + var UpdateSet; + + __extends(Update, _super); + + /* + The root node of an UPDATE query + */ + + + function Update() { + return Update.__super__.constructor.apply(this, arguments); + } + + Update.UpdateSet = UpdateSet = (function(_super1) { + + __extends(UpdateSet, _super1); + + function UpdateSet(nodes) { + UpdateSet.__super__.constructor.call(this, nodes, ', '); + } + + UpdateSet.prototype.compile = function(dialect) { + var string; + if (string = UpdateSet.__super__.compile.apply(this, arguments)) { + return "SET " + string; + } else { + return ""; + } + }; + + return UpdateSet; + + })(NodeSet); + + Update.prefix = 'UPDATE '; + + Update.structure([['relation', Relation], ['updates', UpdateSet], ['orderBy', OrderBy], ['limit', Limit], ['fromList', RelationSet], ['where', Where], ['returning', Returning]]); + + Returning.extend(Update); + + Update.prototype.initialize = function(opts) { + return this.relation = toRelation(opts.table); + }; + + return Update; + +})(Statement); + +Insert = (function(_super) { + var ColumnList, InsertData, valOrDefault; + + __extends(Insert, _super); + + /* + The root node of an INSERT query + */ + + + function Insert() { + return Insert.__super__.constructor.apply(this, arguments); + } + + Insert.InsertData = InsertData = (function(_super1) { + + __extends(InsertData, _super1); + + function InsertData() { + return InsertData.__super__.constructor.apply(this, arguments); + } + + InsertData.prototype.glue = ', '; + + InsertData.prototype.compile = function(dialect) { + var string; + if (string = InsertData.__super__.compile.apply(this, arguments)) { + return "VALUES " + string; + } else { + return ""; + } + }; + + return InsertData; + + })(NodeSet); + + Insert.ColumnList = ColumnList = (function(_super1) { + + __extends(ColumnList, _super1); + + function ColumnList() { + return ColumnList.__super__.constructor.apply(this, arguments); + } + + return ColumnList; + + })(Tuple); + + Insert.prefix = 'INSERT INTO '; + + Insert.structure([['relation', Relation], ['columns', ColumnList], ['data', InsertData], ['returning', Returning]]); + + Returning.extend(Insert); + + Insert.prototype.initialize = function(opts) { + var _ref2; + if (!((_ref2 = opts.fields) != null ? _ref2.length : void 0)) { + throw new Error("Column list is required when constructing an INSERT"); + } + this.columns = new ColumnList(opts.fields.map(toField)); + return this.relation = toRelation(opts.table); + }; + + Insert.prototype.addRow = function(row) { + if (this.data instanceof Select) { + throw new Error("Cannot add rows when inserting from a SELECT"); + } + if (Array.isArray(row)) { + return this.addRowArray(row); + } else { + return this.addRowObject(row); + } + }; + + Insert.prototype.addRowArray = function(row) { + var count, message, params, v; + if (!(count = this.columns.nodes.length)) { + throw new Error("Must set column list before inserting arrays"); + } + if (row.length !== count) { + message = "Wrong number of values in array, expected " + this.columns.nodes; + throw new Error(message); + } + params = (function() { + var _k, _len2, _results; + _results = []; + for (_k = 0, _len2 = row.length; _k < _len2; _k++) { + v = row[_k]; + if (v instanceof Node) { + _results.push(v); + } else { + _results.push(new Parameter(v)); + } + } + return _results; + })(); + return this.data.addNode(new Tuple(params)); + }; + + Insert.prototype.addRowObject = function(row) { + /* + Add a row from an object. This will set the column list of the query if it + isn't set yet. If it `is` set, then only keys matching the existing column + list will be inserted. + */ + return this.addRowArray(this.columns.nodes.map(valOrDefault.bind(row))); + }; + + valOrDefault = function(field) { + var key; + key = field.value; + if (this.hasOwnProperty(key)) { + return this[key]; + } else { + return CONST_NODES.DEFAULT; + } + }; + + Insert.prototype.from = function(query) { + if (!(query instanceof Select)) { + throw new Error("Can only insert from a SELECT"); + } + return this.data = query; + }; + + return Insert; + +})(Statement); + +Delete = (function(_super) { + + __extends(Delete, _super); + + /* + The root node of a DELETE query + */ + + + function Delete() { + return Delete.__super__.constructor.apply(this, arguments); + } + + Delete.prefix = 'DELETE '; + + Delete.structure([['relations', RelationSet], ['where', Where], ['orderBy', OrderBy], ['limit', Limit], ['returning', Returning]]); + + Returning.extend(Delete); + + Delete.prototype.initialize = function(opts) { + return this.relations.addNode(toRelation(opts.table)); + }; + + return Delete; + +})(Statement); + +ComparableMixin = (function() { + /* + A mixin that adds comparison methods to a class. Each of these comparison + methods will yield a new AST node comparing the invocant to the argument. + */ + + function ComparableMixin() {} + + ComparableMixin.patch = function(klazz) { + var k, v, _ref2, _results; + _ref2 = this.prototype; + _results = []; + for (k in _ref2) { + v = _ref2[k]; + _results.push(klazz.prototype[k] = v); + } + return _results; + }; + + ComparableMixin.prototype.eq = function(other) { + /* ``this = other`` + */ + return this.compare('=', other); + }; + + ComparableMixin.prototype.ne = function(other) { + /* ``this != other`` + */ + return this.compare('!=', other); + }; + + ComparableMixin.prototype.gt = function(other) { + /* ``this > other`` + */ + return this.compare('>', other); + }; + + ComparableMixin.prototype.lt = function(other) { + /* ``this < other`` + */ + return this.compare('<', other); + }; + + ComparableMixin.prototype.lte = function(other) { + /* ``this <= other`` + */ + return this.compare('<=', other); + }; + + ComparableMixin.prototype.gte = function(other) { + /* ``this >= other`` + */ + return this.compare('>=', other); + }; + + ComparableMixin.prototype.like = function(other) { + return this.compare('LIKE', other); + }; + + ComparableMixin.prototype.is = function(other) { + return this.compare('IS', other != null ? other : CONST_NODES.NULL); + }; + + ComparableMixin.prototype.isNot = function(other) { + return this.compare('IS NOT', other != null ? other : CONST_NODES.NULL); + }; + + ComparableMixin.prototype["in"] = function(other) { + return this.compare('IN', other); + }; + + ComparableMixin.prototype.notIn = function(other) { + return this.compare('NOT IN', other); + }; + + ComparableMixin.prototype.compare = function(op, other) { + /* ``this op other`` **DANGER** `op` is **NOT** escaped! + */ + return new Binary(this, op, toParam(other)); + }; + + return ComparableMixin; + +})(); + +_ref2 = [TextNode, SqlFunction, SqlFunction.Alias, Column, Column.Alias, Tuple]; +for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + ctor = _ref2[_k]; + ComparableMixin.patch(ctor); +} + +toParam = function(it) { + /* + Return a Node that can be used as a parameter. + + * :class:`queries/select::SelectQuery` instances will be treated as + un-named sub queries, + * Node instances will be returned unchanged. + * Arrays will be turned into a :class:`nodes::Tuple` instance. + + All other types will be wrapped in a :class:`nodes::Parameter` instance. + */ + + var SelectQuery; + SelectQuery = require('./queries/select'); + if ((it != null ? it.constructor : void 0) === SelectQuery) { + return new Tuple([it.q]); + } else if (it instanceof Node) { + return it; + } else if (Array.isArray(it)) { + return new Tuple(it.map(toParam)); + } else { + return new Parameter(it); + } +}; + +toRelation = function(it) { + /* + Transform ``it`` into a :class:`nodes::Relation` instance. + + This accepts `strings, ``Relation`` and ``Alias`` instances, and objects with + a single key-value pair, which will be turned into an ``Alias`` instance. + + Examples:: + + toRelation('table1') == new Relation('table1') + toRelation(t1: 'table1') == new Alias(new Relation('table1'), 't1') + + **Throws Errors** if the input is not valid. + */ + + var alias; + switch (it.constructor) { + case Relation: + case Relation.Alias: + case SqlFunction: + case SqlFunction.Alias: + return it; + case String: + return new Relation(it); + case Object: + if (alias = getAlias(it)) { + return toRelation(it[alias]).as(alias); + } else { + throw new Error("Can't make relation out of " + it); + } + break; + default: + throw new Error("Can't make relation out of " + it); + } +}; + +toField = function(it) { + if (typeof it === 'string') { + return new Field(it); + } else if (it instanceof Field) { + return it; + } else { + throw new Error("Can't make a field out of " + it); + } +}; + +toColumn = function(relation, field) { + /* + Create a new :class:`nodes::Column` instance. + + The first argument is optional and specifies a table (or alias) name. + Alternatively, you can specify the relation name and field with a single + dot-separated string:: + + toColumn('departments.name') == toColumn('departments', 'name') + + Either argument can be an pre-constructed node object (of the correct type). + */ + + var parts; + if (field != null) { + return new Column(toRelation(relation), toField(field)); + } else if (typeof relation === 'string') { + parts = relation.split('.'); + if (parts.length === 2) { + return new Column(toRelation(parts[0]), toField(parts[1])); + } + } + throw new Error("Can't make projection from object: " + relation); +}; + +toProjection = toColumn; + +sqlFunction = function(name, args) { + /* + Create a new SQL function call node. For example:: + + count = g.sqlFunction('count', [g.text('*')]) + */ + return new SqlFunction(name, new Tuple(args.map(toParam))); +}; + +func = function(name) { + /* + Create a factory for calling the given SQL function. Example:: + + count = g.func('count') + count(g.text('*')) + + The returned factory accepts any number of parameters:: + + substringIndex = g.func('SUBSTRING_INDEX') + substringIndex(g.text('mycol'), '-', 1) # SUBSTRING_INDEX(mycol, '-', 1) + */ + return function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return sqlFunction(name, args); + }; +}; + +getAlias = function(o) { + /* + Check if ``o`` is an object literal representing an alias, and return the + alias name if it is. + */ + + var keys; + if ('object' === typeof o) { + keys = Object.keys(o); + if (keys.length === 1) { + return keys[0]; + } + } + return null; +}; + +text = function(rawSQL, bindVals) { + /* + Construct a node with a raw SQL string and (optionally) parameters. Useful for + when you want to construct a query that is difficult or impossible with the + normal APIs. [#]_ + + To use bound parameters in the SQL string, use ``$`` prefixed names, and + pass a ``bindVals`` argument with corresponding property names. For example, + :meth:`~queries/sud::SUDQuery.where` doesn't (currently) support the SQL + ``BETWEEN`` operator, but if you needed it, you could use ``text``:: + + function peopleInWeightRange (min, max, callback) { + return select('people') + .where(text("weight BETWEEN $min AND $max", {min: min, max: max})) + .execute(callback) + } + + Because javascript doesn't distinguish between array indexing and property + access, it can be more clear to use numbered parameters for such short + snippets:: + + function peopleInWeightRange (min, max, callback) { + return select('people') + .where(text("weight BETWEEN $0 AND $1", [min, max])) + .execute(callback) + } + + .. [#] If you find yourself using this function often, please `open an issue`_ + on Github with details on your use case so `gesundheit` can support it + more elegantly. + + .. _open an issue: https://github.com/BetSmartMedia/gesundheit/issues/new?title=I%20use%20text()%20for%20blah + */ + return new TextNode(rawSQL, bindVals); +}; + +binaryOp = function(left, op, right) { + /* + Create a new :class:`nodes::Binary` node:: + + binaryOp('hstore_column', '->', toParam(y)) + # hstore_column -> ? + + This is for special cases, normally you want to use the methods from + :class:`nodes::ComparableMixin`. + */ + return new Binary(left, op, right); +}; + +Prefixed = (function(_super) { + + __extends(Prefixed, _super); + + function Prefixed(prefix, node) { + this.prefix = prefix; + this.node = node; + } + + Prefixed.prototype.compile = function() { + return this.prefix + this.node.compile.apply(this.node, arguments); + }; + + return Prefixed; + +})(ValueNode); + +exists = function(subquery) { + /* Create an ``EXISTS ()`` node for `where` + */ + return new Prefixed('EXISTS ', new Tuple([subquery.q || subquery])); +}; + +notExists = function(subquery) { + /* Create a ``NOT EXISTS ()`` node for `where` + */ + return new Prefixed('NOT EXISTS ', new Tuple([subquery.q || subquery])); +}; + +tuple = function(input) { + /* + Create a new Tuple from an array of nodes. Any item in the array that is + **not** an `instanceof Node` will be turned into a parameter with + :func:`nodes::toParam`. + */ + return new Tuple(input.map(toParam)); +}; + +module.exports = { + CONST_NODES: CONST_NODES, + JOIN_TYPES: JOIN_TYPES, + binaryOp: binaryOp, + exists: exists, + func: func, + getAlias: getAlias, + notExists: notExists, + sqlFunction: sqlFunction, + text: text, + toField: toField, + toParam: toParam, + toColumn: toColumn, + toProjection: toProjection, + toRelation: toRelation, + tuple: tuple, + Node: Node, + ValueNode: ValueNode, + IntegerNode: IntegerNode, + Identifier: Identifier, + JoinType: JoinType, + NodeSet: NodeSet, + FixedNodeSet: FixedNodeSet, + Statement: Statement, + ParenthesizedNodeSet: ParenthesizedNodeSet, + TextNode: TextNode, + TextAlias: TextAlias, + SqlFunction: SqlFunction, + FunctionAlias: FunctionAlias, + Parameter: Parameter, + Relation: Relation, + RelationAlias: Relation.Alias, + Field: Field, + Column: Column, + ColumnAlias: Column.Alias, + Limit: Limit, + Offset: Offset, + Binary: Binary, + Tuple: Tuple, + ColumnSet: ColumnSet, + Returning: Returning, + Distinct: Distinct, + SelectColumnSet: SelectColumnSet, + RelationSet: RelationSet, + Join: Join, + Where: Where, + Or: Or, + And: And, + GroupBy: GroupBy, + OrderBy: OrderBy, + Ordering: Ordering, + Select: Select, + Update: Update, + UpdateSet: Update.UpdateSet, + Insert: Insert, + ColumnList: Insert.ColumnList, + InsertData: Insert.InsertData, + Delete: Delete, + ComparableMixin: ComparableMixin +}; + +unmarshal = require('./unmarshal')(); + +copy = function(it) { + var c, k, v; + if (!it) { + return it; + } + switch (it.constructor) { + case String: + case Number: + case Boolean: + return it; + case Array: + return it.map(copy); + case Object: + c = {}; + for (k in it) { + v = it[k]; + c[k] = copy(v); + } + return c; + default: + if (it.copy != null) { + return it.copy(); + } else { + throw new Error("Don't know how to copy " + it); + } + } +}; + +merge = function(dest, src) { + var k, v; + for (k in src) { + v = src[k]; + dest[k] = v; + } + return dest; +}; + +},{"./queries/select":13,"./unmarshal":16}],8:[function(require,module,exports){ +var process=require("__browserify_process");// Generated by CoffeeScript 1.4.0 +var BaseQuery, EventEmitter, assert, fluid, inspect, method, toRelation, _i, _len, _ref, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +inspect = require('util').inspect; + +EventEmitter = require('events').EventEmitter; + +toRelation = require('../nodes').toRelation; + +assert = require('assert'); + +module.exports = BaseQuery = (function(_super) { + + __extends(BaseQuery, _super); + + /* + The base class for all queries. While this class itself is not part of + gesundheits public API, the methods defined on it are. + */ + + + BaseQuery.rootNode = null; + + BaseQuery.unmarshal = function(data, recur) { + var query; + query = new this; + query.q = recur(data.q); + return query; + }; + + function BaseQuery(engine, opts) { + if (opts == null) { + opts = {}; + } + /* + :param engine: The engine the query will be bound to. + + :param opts.table: + Any object that can be converted by :func:`nodes::toRelation`. + */ + + this.bind(engine); + this.q = opts.rootNode || new this.constructor.rootNode(opts); + } + + BaseQuery.prototype.copy = function(fn) { + /* Instantiate a new query with a deep copy of this ones AST + */ + + var query; + query = new this.constructor(this.engine, { + rootNode: this.q.copy() + }); + if (fn) { + return query.visit(fn); + } else { + return query; + } + }; + + BaseQuery.prototype.visit = function(fn) { + /* + Call the given function in the context of this query. This is useful with + query factory functions where you can use it as a sort-of-DSL:: + + SELECT('people', ['name'], function(q) { + // this === q + this.join('addresses', { + on: {person_id: q.project('people', 'id')}, + fields: ['city', 'region'] + }) + }) + */ + return fn.call(this, this); + }; + + BaseQuery.prototype.bind = function(engine) { + /* + Bind this query object to a new engine. + If no argument is given the query will be bound to the default engine. + */ + + var oldEngine, _base, _ref, _ref1; + oldEngine = this.engine; + this.engine = engine || require('../index').defaultEngine; + if (this.engine !== oldEngine) { + if (oldEngine != null) { + if (typeof oldEngine.unextendQuery === "function") { + oldEngine.unextendQuery(this); + } + } + if (typeof (_base = this.engine).extendQuery === "function") { + _base.extendQuery(this); + } + } + assert((_ref = this.engine) != null ? _ref.query : void 0, "Engine has no query method: " + (inspect(this.engine))); + return assert((_ref1 = this.engine) != null ? _ref1.compile : void 0, "Engine has no compile method: " + (inspect(this.engine))); + }; + + BaseQuery.prototype.render = function() { + /* + Render the query to a SQL string. + */ + return this.compile()[0]; + }; + + BaseQuery.prototype.compile = function() { + /* + Compile this query object, returning a SQL string and parameter array. + */ + return this.engine.compile(this.q); + }; + + BaseQuery.prototype.execute = function(cb) { + /* + Execute the query using ``@engine`` and return a `QueryAdapter`. + + :param cb: An (optional) node-style callback that will be called with any + errors and/or the query results. If no callback is given, an `AnyDB Query`_ + will be returned. + + .. _AnyDB Query: https://github.com/grncdr/node-any-db/blob/master/DESIGN.md#query-adapters + */ + + var args, emitter; + try { + args = this.compile(); + args.push(cb); + } catch (err) { + emitter = new EventEmitter; + process.nextTick(function() { + if (cb) { + return cb(err); + } else { + return emitter.emit('error', err); + } + }); + return emitter; + } + return this.engine.query.apply(this.engine, args); + }; + + BaseQuery.prototype.toString = function() { + return this.render(); + }; + + BaseQuery.prototype.toJSON = function() { + return { + _type: this.constructor.name, + q: this.q.toJSON() + }; + }; + + return BaseQuery; + +})(EventEmitter); + +fluid = require('../decorators/fluid'); + +_ref = ['bind', 'visit']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + method = _ref[_i]; + BaseQuery.prototype[method] = fluid(BaseQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../index":6,"../nodes":7,"__browserify_process":27,"assert":17,"events":18,"util":22}],9:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var Delete, DeleteQuery, SUDQuery, returnable, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +SUDQuery = require('./sud'); + +returnable = require('./returnable'); + +Delete = require('../nodes').Delete; + +module.exports = DeleteQuery = (function(_super) { + + __extends(DeleteQuery, _super); + + /* Delete queries only add a 'returning' method to ``SUDQuery`` + */ + + + function DeleteQuery() { + return DeleteQuery.__super__.constructor.apply(this, arguments); + } + + DeleteQuery.rootNode = Delete; + + returnable(DeleteQuery); + + return DeleteQuery; + +})(SUDQuery); + +},{"../nodes":7,"./returnable":12,"./sud":14}],10:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +The factory functions defined here create instances of the corresponding +`*Query` manager classes, which fit the following inheritance hierarchy: + + * BaseQuery + + * InsertQuery + + * SUDQuery + + * SelectQuery + + * UpdateQuery + + * DeleteQuery + +.. _query-factories: + +These functions are the same ones re-exported by the main gesundheit module +(where they bind queries to ``gesundheit.defaultEngine``), and attached to +engine/transaction objects (where they bind queries to the engine/transaction +they are called on). + +Each one accepts a table name or alias object (anything handled by +:func:`nodes::toRelation`), one or more extra parameters, and an optional +visitor callback as a final parameter that will be called with it's ``this`` +context set to the newly constructed query instance. +*/ + +var DELETE, DeleteQuery, INSERT, InsertQuery, SELECT, SelectQuery, UPDATE, UpdateQuery, maybeVisit; + +InsertQuery = require('./insert'); + +SelectQuery = require('./select'); + +UpdateQuery = require('./update'); + +DeleteQuery = require('./delete'); + +INSERT = function(table, fieldsOrRow) { + /* + Create a new :class:`queries/insert::InsertQuery` that will add rows to + ``table``. + + :param table: Name of the table that rows will be inserted into. + :param fieldsOrRow: Either an array of column names that will be inserted, or a + plain object representing a row of data to insert, in which case the keys + of the object will define the columns that are inserted. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + + .. warning:: + The column names passed in ``fields`` will be printed into the query + **unescaped** so do **not** use arbitrary input here. This is hopefully only temporary. + */ + + var fields, iq, row; + if (Array.isArray(fieldsOrRow)) { + fields = fieldsOrRow; + } else if (typeof fieldsOrRow === 'object') { + row = fieldsOrRow; + fields = Object.keys(row); + } + iq = new InsertQuery(this, { + table: table, + fields: fields + }); + if (row) { + iq.addRow(row); + } + return iq; +}; + +SELECT = function(table, fields) { + /* + Create a new :class:`queries/select::SelectQuery` selecting from ``table``. + + :param table: Name or alias object of the first table to select rows from. + More tables can be joined using :meth:`queries/select::SelectQuery.join`. + :param fields: (Optional) Fields to project from ``table``. If this is not + given, all fields (``*``) will be projected until + :meth:`queries/select::SelectQuery.fields` is called. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + + var query; + query = new SelectQuery(this, { + table: table + }); + if (fields != null) { + query.fields.apply(query, fields); + } + return query; +}; + +UPDATE = function(table) { + /* + Create a new :class:`queries/update::UpdateQuery` that will update ``table``. + + :param table: Name or alias of the table to update. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + return new UpdateQuery(this, { + table: table + }); +}; + +DELETE = function(table) { + /* + Create a new :class:`queries/delete::DeleteQuery` that will delete rows from + ``table``. + + :param table: Name or alias of the table to delete rows from. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + return new DeleteQuery(this, { + table: table + }); +}; + +exports.mixinFactoryMethods = function(invocant, getEngine) { + /* + Add wrappers methods for each of the query factory functions to ``invocant`` + using lower, UPPER, and Camel cases. The new methods will retrieve an engine + using ``getEngine`` and then create the query bound to that engine. + + If ``getEngine`` is not given, queries will be bound to ``invocant`` instead. + */ + + var factory, type, _fn, _ref; + if (getEngine == null) { + getEngine = function() { + return invocant; + }; + } + _ref = { + INSERT: INSERT, + SELECT: SELECT, + UPDATE: UPDATE, + DELETE: DELETE + }; + _fn = function(type, factory) { + var wrapper; + factory = maybeVisit(factory); + wrapper = function() { + return factory.apply(getEngine(), arguments); + }; + invocant[type] = wrapper; + invocant[type.toLowerCase()] = wrapper; + return invocant[type[0] + type.toLowerCase().substring(1)] = wrapper; + }; + for (type in _ref) { + factory = _ref[type]; + _fn(type, factory); + } + return invocant; +}; + +maybeVisit = function(func) { + return function() { + var a, cb; + a = [].slice.call(arguments); + if (typeof a[a.length - 1] === 'function') { + cb = a.pop(); + return func.apply(this, a).visit(cb); + } else { + return func.apply(this, a); + } + }; +}; + +},{"./delete":9,"./insert":11,"./select":13,"./update":15}],11:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var BaseQuery, Insert, InsertQuery, SelectQuery, fluid, method, returnable, toField, _i, _len, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +returnable = require('./returnable'); + +BaseQuery = require('./base'); + +SelectQuery = require('./select'); + +_ref = require('../nodes'), Insert = _ref.Insert, toField = _ref.toField; + +module.exports = InsertQuery = (function(_super) { + + __extends(InsertQuery, _super); + + /* + Insert queries are much simpler than most query types: they cannot join + multiple tables. + */ + + + function InsertQuery() { + return InsertQuery.__super__.constructor.apply(this, arguments); + } + + InsertQuery.rootNode = Insert; + + returnable(InsertQuery); + + InsertQuery.prototype.addRows = function(rows, variadic) { + /* Add multiple rows of data to the insert statement. + */ + + var row, _i, _len, _results; + if (variadic != null) { + console.warn("DEPRECATED: InsertQuery::addRows will not be variadic in a future release.", new Error().stack.split('\n').slice(1).join('\n')); + rows = Array.prototype.slice.call(arguments); + } + _results = []; + for (_i = 0, _len = rows.length; _i < _len; _i++) { + row = rows[_i]; + _results.push(this.q.addRow(row)); + } + return _results; + }; + + InsertQuery.prototype.addRow = function(row) { + /* Add a single row + */ + return this.q.addRow(row); + }; + + InsertQuery.prototype.from = function(query) { + /* Insert from a select query. + */ + return this.q.from(query.q || query); + }; + + return InsertQuery; + +})(BaseQuery); + +fluid = require('../decorators/fluid'); + +_ref1 = ['addRow', 'addRows', 'from', 'returning']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + InsertQuery.prototype[method] = fluid(InsertQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../nodes":7,"./base":8,"./returnable":12,"./select":13}],12:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var fluid, variadic; + +variadic = require('../decorators/variadic'); + +fluid = require('../decorators/fluid'); + +module.exports = function(klazz) { + return klazz.prototype.returning = fluid(variadic(function(cols) { + this.q.addReturning(cols); + return this; + })); +}; + +},{"../decorators/fluid":2,"../decorators/variadic":3}],13:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var And, JOIN_TYPES, Join, Node, SUDQuery, Select, SelectQuery, deprecate, fluid, getAlias, method, sqlFunction, toColumn, toRelation, variadic, _i, _j, _len, _len1, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +SUDQuery = require('./sud'); + +_ref = require('../nodes'), Node = _ref.Node, getAlias = _ref.getAlias, Select = _ref.Select, And = _ref.And, Join = _ref.Join, toRelation = _ref.toRelation, toColumn = _ref.toColumn, sqlFunction = _ref.sqlFunction, JOIN_TYPES = _ref.JOIN_TYPES; + +module.exports = SelectQuery = (function(_super) { + + __extends(SelectQuery, _super); + + /* + Adds a number of SELECT-specific methods to :class:`queries/sud::SUDQuery`, + such as `fields` and `groupBy` + */ + + + function SelectQuery() { + return SelectQuery.__super__.constructor.apply(this, arguments); + } + + SelectQuery.rootNode = Select; + + SelectQuery.prototype.fields = function(fields) { + /* + Adds one or more fields to the query. Fields can be strings (in which case + they will be passed to :meth:`queries/sud::SUDQuery.column`) or pre- + constructed nodes. (Such as those returned by ``column``). + + If no fields are given, clears all fields from the currently focused table. + + To alias a field, use an object with a single key where the key is the alias + name and the value is a string or node:: + + q.fields({employee_name: 'employees.name'}) + */ + + var alias, col, f, rel, _i, _len, + _this = this; + if (fields.length === 0) { + rel = this.q.relations.active; + this.q.projections.prune(function(p) { + return p.rel() === rel; + }); + return; + } + col = function(o) { + if (o instanceof Node) { + return o; + } else { + return _this.column(o); + } + }; + for (_i = 0, _len = fields.length; _i < _len; _i++) { + f = fields[_i]; + if (alias = getAlias(f)) { + f = f[alias]; + this.q.projections.addNode(col(f).as(alias)); + } else { + this.q.projections.addNode(col(f)); + } + } + return null; + }; + + SelectQuery.prototype.func = function(fun, args) { + /* + Adds a SQL function to the column list for the query. This can be an + aggregate function if you also use :meth:`queries/select::groupBy`. + + :param fun: name of SQL function. + :param args: arguments that will be passed to the function. Any argument + that is not a `Node` object will be converted into a bound parameter. + + Example:: + + # SELECT count(id) FROM t1 + select('t1', function (q) { q.func('count', q.c('id')) }) + + # SELECT count(id) AS "counter" FROM t1 + select('t1', function (q) { q.func({counter: 'count'}, q.c('id')) }) + */ + + var alias; + if (alias = getAlias(fun)) { + return this.q.projections.addNode(sqlFunction(fun[alias], args).as(alias)); + } else { + return this.q.projections.addNode(sqlFunction(fun, args)); + } + }; + + SelectQuery.prototype.distinct = function(bool) { + /* + Make this query DISTINCT on *all* fields. + */ + return this.q.distinct.enable = bool; + }; + + SelectQuery.prototype.join = function(table, opts) { + var fieldList, join, prefix, relation, type; + if (opts == null) { + opts = {}; + } + /* + Join another table to the query. + + :param table: A table name, or alias literal. An error will be thrown if + the table/alias name is not unique. See :func:`nodes::toRelation` for + more information on the many things ``table`` could be. + :param opts.on: + An object literal expressing join conditions. See + :meth:`queries/select::SelectQuery::where` for more. + :param opts.type: A join type constant (e.g. INNER, OUTER) + :param opts.fields: Columns to be selected from the newly joined table. + :param opts.prefixFields: If this is a string, it will be used to prefix + the field names given in ``opts.fields``. If this is a boolean ``true`` + then the joined table (or alias) name plus an underscore will be used + as the prefix. For example:: + + query.join({p: 'people'}, { + on: query.c('people.dep_id').eq(query.c('dep.id')), + fields: ['first_name', 'last_name'], + prefixFields: true + }) + + Will alias ``people.first_name AS p_first_name``. + */ + + relation = toRelation(table); + if (this.q.relations.get(relation, false)) { + throw new Error("Table/alias " + (relation.ref()) + " is not unique!"); + } + type = opts.type || JOIN_TYPES.INNER; + if (!(type instanceof JOIN_TYPES.INNER.constructor)) { + throw new Error("Invalid join type " + type + ", try the constant types exported in the base module (e.g. INNER)."); + } + join = new Join(type, relation); + this.q.relations.addNode(join); + if (opts.on) { + join.on(new And(this._makeClauses(opts.on))); + } + if ((fieldList = opts.fields) != null) { + if (opts.prefixFields) { + if (opts.prefixFields === true) { + prefix = relation.ref() + '_'; + } else { + prefix = opts.prefixFields; + } + fieldList = fieldList.map(function(f) { + return toColumn(relation, f).as(prefix + f); + }); + } + return this.fields(fieldList); + } + }; + + SelectQuery.prototype.ensureJoin = function(table, opts) { + var rel; + if (opts == null) { + opts = {}; + } + /* + The same as :meth:`join`, but will only join ``tbl`` if it is **not** + joined already. + */ + + rel = toRelation(table); + if (!this.q.relations.get(rel.ref(), false)) { + return this.join(rel, opts); + } + }; + + SelectQuery.prototype.focus = function(alias) { + /* + Make a different table "focused", this will use that table as the default + for the ``fields``, ``order`` and ``where`` methods. + + :param alias: The table/alias name to focus. If the table or alias is not + already part of the query an error will be thrown. + */ + return this.q.relations["switch"](alias); + }; + + SelectQuery.prototype.groupBy = function(fields) { + /* Add a GROUP BY to the query. + */ + + var field, _i, _len; + for (_i = 0, _len = fields.length; _i < _len; _i++) { + field = fields[_i]; + this.q.groupBy.addNode(this.column(field)); + } + return null; + }; + + SelectQuery.prototype.having = function(constraint) { + /* + This method works similarly to :meth:`queries/sud::SUDQuery.where`, but the + constraints are added the `HAVING` portion of a SQL clause. + */ + + var node, _i, _len, _ref1, _results; + _ref1 = this._makeClauses(constraint); + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + node = _ref1[_i]; + _results.push(this.q.having.addNode(node)); + } + return _results; + }; + + return SelectQuery; + +})(SUDQuery); + +fluid = require('../decorators/fluid'); + +variadic = require('../decorators/variadic'); + +deprecate = require('../decorators/deprecate'); + +_ref1 = ['fields', 'groupBy']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + SelectQuery.prototype[method] = variadic(SelectQuery.prototype[method]); +} + +_ref2 = ['distinct', 'fields', 'func', 'join', 'ensureJoin', 'focus', 'groupBy', 'having']; +for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + method = _ref2[_j]; + SelectQuery.prototype[method] = fluid(SelectQuery.prototype[method]); +} + +SelectQuery.prototype.field = SelectQuery.prototype.fields; + +SelectQuery.prototype.agg = deprecate.rename(SelectQuery.prototype.func, ".agg", ".func"); + +},{"../decorators/deprecate":1,"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./sud":14}],14:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var And, BaseQuery, CONST_NODES, Column, Node, Or, Ordering, SUDQuery, deprecate, fluid, method, nodes, toField, variadic, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +BaseQuery = require('./base'); + +nodes = require('../nodes'); + +Node = nodes.Node, And = nodes.And, Or = nodes.Or, Ordering = nodes.Ordering, Column = nodes.Column, CONST_NODES = nodes.CONST_NODES, toField = nodes.toField; + +module.exports = SUDQuery = (function(_super) { + + __extends(SUDQuery, _super); + + function SUDQuery() { + return SUDQuery.__super__.constructor.apply(this, arguments); + } + + /* + SUDQuery is the base class for SELECT, UPDATE, and DELETE queries. It adds + logic to :class:`queries/base::BaseQuery` for adding WHERE clauses, projecting + columns, ordering, limits, and offsets. + */ + + + SUDQuery.prototype.where = function(constraint) { + /* + Adds a WHERE clause to the query. This method accepts wide range of input + that can express very complex constraints. The examples below assume we are + starting with this simple select query: ``q = select('t1')`` + + The first kind of constraint is a comparison node as produced by the + :class:`nodes::ComparableMixin` methods on projected fields:: + + q.where(q.c('field1').eq(42)) + q.where(q.c('field2').gt(42)) + # WHERE t1.field1 = 42 AND t1.field2 > 42 + + We used an implied table name above, which is always the last table added to + the query or focused with :meth:`queries/sud::SUDQuery.focus`. If you want + to specify constraints on multiple tables at once (or just be more explicit) + you can also specify the relation for a field by prepending it to the field + name (e.g. ``q.c('t1.field1')``. See :meth:`queries/sud::SUDQuery.project` + for details. + + The second kind of constraint is an object literal where each key is a field + name and each value is a constraint. The last example expressed as a literal + object looks like this:: + + q.where({field1: 42, field2: {gt: 42}}) + # WHERE t1.field1 = 42 AND t1.field2 > 42 + + Internally this constructs the comparison nodes for you using a simple + transformation: each key is passed to :meth:`project` (meaning you can + specify the relation name as part of the key if you so desire) and each + value is either used as the argument to :meth:`nodes::ComparableMixin.eq` + or (in the case of object literals) converted into one or more calls to + the corresponding comparison methods. + + To compare two fields, use a projection as the value to be compared:: + + p = q.project.bind(q, 't1') + q.where({field1: {gt: p('field2')}}) + # WHERE t1.field1 > t1.field2 + + If you use either of the special keys ``'and'`` or ``'or'`` in an object, + the value will be treated as a nested set of constraints to be joined with + the corresponding SQL operator. This process is recursive so you can nest + constraints arbitrarily deep:: + + q.where({or: {a: 1, and: {b: 2, c: 3}}}) + # WHERE (t1.a = 1 OR (t1.b = 2 AND t1.c = 3)) + + You can also acheive the same effect by chaining method calls on comparison + nodes:: + + a = q.c('a') + b = q.c('b') + c = q.c('c') + q.where(a.eq(1).or(b.eq(2).and(c.eq(3)))) + # WHERE (t1.a = 1 OR (t1.b = 2 AND t1.c = 3)) + + If you have the need to mix both styles (or simply find it more readable, + You can use an array of constraints as the value for ``'or'`` or ``'and'``:: + + q.where({or: [{a: 1}, b.eq(2).and(c.eq(3))]}) + + Note that currently you **cannot** pass an object literal to the ``.and`` + and ``.or`` methods:: + + # Will not work!! + q.where(a.eq(1).or({b: 2, c: 3})) + + Finally, there are also shortcut methods :meth:`queries/sud::SUDQuery.and` + and :meth:`queries/sud::SUDQuery.or` that treat multiple arguments like an + array of constraints. + */ + + var node, _i, _len, _ref, _results; + _ref = this._makeClauses(constraint); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + _results.push(this.q.where.addNode(node)); + } + return _results; + }; + + SUDQuery.prototype._makeClauses = function(constraint) { + /* + Return an array of Binary, And, and Or nodes for this constraint object + */ + + var clauses, column, field, item, op, predicate, val, _i, _len; + clauses = []; + if (Array.isArray(constraint)) { + for (_i = 0, _len = constraint.length; _i < _len; _i++) { + item = constraint[_i]; + if (item instanceof Node) { + clauses.push(item); + } else { + clauses = clauses.concat(this._makeClauses(item)); + } + } + return clauses; + } + if (constraint instanceof Node) { + return [constraint]; + } + for (field in constraint) { + predicate = constraint[field]; + if (field === 'and') { + clauses.push(new And(this._makeClauses(predicate))); + } else if (field === 'or') { + clauses.push(new Or(this._makeClauses(predicate))); + } else { + column = this.column(field); + if (predicate === null) { + clauses.push(column.compare('IS', CONST_NODES.NULL)); + } else if (predicate.constructor === Object) { + for (op in predicate) { + val = predicate[op]; + clauses.push(column.compare(op, val)); + } + } else { + clauses.push(column.eq(predicate)); + } + } + } + return clauses; + }; + + SUDQuery.prototype.or = function(clauses) { + /* Shortcut for ``.where({or: clauses})`` + */ + return this.where({ + or: clauses + }); + }; + + SUDQuery.prototype.and = function(clauses) { + /* Shortcut for ``.where({and: clauses})`` + */ + return this.where({ + and: clauses + }); + }; + + SUDQuery.prototype.order = function(args) { + /* + Add one or more ORDER BY clauses to the query. + + Each ordering can either be a string, in which case it must be a valid-ish + SQL snippet like 'some_table.some_field DESC', (the field name and direction + will still be converted to AST nodes) or an object, in which case each key + will be treated as a field and each value as a direction. + */ + + var dir, direction, field, name, orderBy, orderings, rel, _i, _j, _len, _len1, _ref, _results; + rel = this.defaultRel(); + orderings = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + orderBy = args[_i]; + switch (orderBy.constructor) { + case String: + orderings.push(orderBy.split(' ')); + break; + case Object: + for (name in orderBy) { + dir = orderBy[name]; + orderings.push([name, dir]); + } + break; + default: + if (orderBy instanceof Node) { + this.q.orderBy.addNode(orderBy); + } else { + throw new Error("Can't turn " + orderBy + " into an ordering"); + } + } + } + _results = []; + for (_j = 0, _len1 = orderings.length; _j < _len1; _j++) { + _ref = orderings[_j], field = _ref[0], direction = _ref[1]; + direction = (function() { + switch ((direction || '').toLowerCase()) { + case 'asc': + case 'ascending': + return 'ASC'; + case 'desc': + case 'descending': + return 'DESC'; + case '': + return ''; + default: + throw new Error("Unsupported ordering direction " + direction); + } + })(); + _results.push(this.q.orderBy.addNode(new Ordering(this.column(field), direction))); + } + return _results; + }; + + SUDQuery.prototype.limit = function(l) { + /* Set the LIMIT on this query + */ + return this.q.limit.value = l; + }; + + SUDQuery.prototype.offset = function(l) { + /* Set the OFFSET of this query + */ + return this.q.offset.value = l; + }; + + SUDQuery.prototype.defaultRel = function() { + return this.q.relations.active; + }; + + SUDQuery.prototype.project = function() { + /* Backwards compatible alias for :meth:`queries/sud::SUDQuery.column` + */ + return this.column.apply(this, arguments); + }; + + SUDQuery.prototype.column = function(relation, field) { + /* + Return a :class:`nodes::Column` node representing ``.``. + + The first argument is optional and specifies a table or alias name referring + to a relation already joined to this query. If you don't specify a relation, + the table added or focused last will be used. Alternatively, you can specify + the relation name and field with a single dot-separated string:: + + q.column('departments.name') == q.column('departments', 'name') + + The returned object has a methods from :class:`nodes::ComparableMixin` that + create new comparison nodes usable in join conditions and where clauses:: + + # Find developers over the age of 45 + s = select('people', ['name']) + s.join('departments', on: {id: s.column('people', 'department_id')}) + s.where(s.column('departments', 'name').eq('development')) + s.where(s.column('people', 'age').gte(45)) + + ``project`` is also aliased as ``p`` for those who value brevity:: + + q.where(q.c('departments.name').eq('development')) + + .. note:: this means you *must* specify a relation name if you have a field + name with a dot in it, if you have dots in your column names, sorry. + */ + + var parts, proj, _ref; + if (field != null) { + field = toField(field); + if (typeof relation === 'string') { + return new Column(this.q.relations.get(relation), field); + } else { + relation = this.q.relations.get(toRelation(relation).ref()); + return new Column(relation, field); + } + } else if (typeof relation === 'string') { + parts = relation.split('.'); + if (parts.length === 2) { + return new Column(this.q.relations.get(parts[0]), toField(parts[1])); + } else { + return new Column(this.defaultRel(), toField(relation)); + } + } else if (relation instanceof Column) { + proj = relation; + this.q.relations.get((_ref = proj.source) != null ? _ref.ref() : void 0); + return proj; + } else { + throw new Error("Can't make a projection from object: " + relation); + } + }; + + SUDQuery.prototype.rel = function(alias) { + /* A shorthand way to get a relation by (alias) name + */ + return this.q.relations.get(alias); + }; + + return SUDQuery; + +})(BaseQuery); + +deprecate = require('../decorators/deprecate'); + +variadic = require('../decorators/variadic'); + +fluid = require('../decorators/fluid'); + +_ref = ['and', 'or', 'order']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + method = _ref[_i]; + SUDQuery.prototype[method] = variadic(SUDQuery.prototype[method]); +} + +_ref1 = ['where', 'or', 'and', 'limit', 'offset', 'order']; +for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + method = _ref1[_j]; + SUDQuery.prototype[method] = fluid(SUDQuery.prototype[method]); +} + +_ref2 = ['p', 'project']; +for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + method = _ref2[_k]; + SUDQuery.prototype[method] = deprecate.rename(SUDQuery.prototype.column, method, ".column or .c"); +} + +SUDQuery.prototype.c = SUDQuery.prototype.column; + +},{"../decorators/deprecate":1,"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./base":8}],15:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var SUDQuery, Update, UpdateQuery, binaryOp, fluid, method, returnable, toField, toParam, variadic, _i, _len, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +returnable = require('./returnable'); + +SUDQuery = require('./sud'); + +_ref = require('../nodes'), Update = _ref.Update, binaryOp = _ref.binaryOp, toField = _ref.toField, toParam = _ref.toParam; + +module.exports = UpdateQuery = (function(_super) { + + __extends(UpdateQuery, _super); + + /* + The update query is a little underpowered right now, and can only handle + simple updates of a single table. + */ + + + function UpdateQuery() { + return UpdateQuery.__super__.constructor.apply(this, arguments); + } + + UpdateQuery.rootNode = Update; + + returnable(UpdateQuery); + + UpdateQuery.prototype.set = function(data) { + /* + Add fields to the SET portion of this query. + + :param data: An object mapping fields to values. The values will be passed + to :func:`nodes::toParam` to be converted into bound paramaeters. + */ + + var field, value, _results; + _results = []; + for (field in data) { + value = data[field]; + _results.push(this.q.updates.addNode(binaryOp(toField(field), '=', toParam(value)))); + } + return _results; + }; + + UpdateQuery.prototype.setNodes = function(nodes) { + /* Directly push one or more nodes into the SET portion of this query + */ + + var _ref1; + return (_ref1 = this.q.updates).push.apply(_ref1, nodes); + }; + + UpdateQuery.prototype.defaultRel = function() { + return this.q.relation; + }; + + return UpdateQuery; + +})(SUDQuery); + +fluid = require('../decorators/fluid'); + +variadic = require('../decorators/variadic'); + +UpdateQuery.prototype.setNodes = variadic(UpdateQuery.prototype.setNodes); + +_ref1 = ['set', 'setNodes', 'returning']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + UpdateQuery.prototype[method] = fluid(UpdateQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./returnable":12,"./sud":14}],16:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var unmarshal, unmarshallable; + +unmarshallable = Object.create(require('./nodes'), { + InsertQuery: { + value: require('./queries/insert') + }, + SelectQuery: { + value: require('./queries/select') + }, + UpdateQuery: { + value: require('./queries/update') + }, + DeleteQuery: { + value: require('./queries/delete') + } +}); + +unmarshal = null; + +module.exports = function(visitor, object) { + var path, recur; + path = []; + recur = function(object, k) { + var ctor, err, result, type, v, _ref; + if (k == null) { + k = ""; + } + if (typeof object !== 'object') { + return object; + } + path.push(k); + if (Array.isArray(object)) { + result = object.map(recur); + } else { + if (!(type = object._type)) { + result = {}; + for (k in object) { + v = object[k]; + result[k] = recur(v, k); + } + result; + + } else if (((_ref = (ctor = unmarshallable[type])) != null ? _ref.unmarshal : void 0) != null) { + if (visitor != null) { + if (typeof visitor.before === "function") { + visitor.before(object, path); + } + } + result = ctor.unmarshal(object, recur); + if (visitor != null) { + if (typeof visitor.after === "function") { + visitor.after(result, path); + } + } + } else { + err = new Error("Cannot unmarshall " + type + " @ " + (path.join('/'))); + err.path = path.slice(); + path = []; + throw err; + } + } + path.pop(k); + return result; + }; + if (arguments.length > 1) { + return recur(object); + } else { + return recur; + } +}; + +module.exports.allow = unmarshallable; + +},{"./nodes":7,"./queries/delete":9,"./queries/insert":11,"./queries/select":13,"./queries/update":15}],17:[function(require,module,exports){ +// UTILITY +var util = require('util'); +var Buffer = require("buffer").Buffer; +var pSlice = Array.prototype.slice; + +function objectKeys(object) { + if (Object.keys) return Object.keys(object); + var result = []; + for (var name in object) { + if (Object.prototype.hasOwnProperty.call(object, name)) { + result.push(name); + } + } + return result; +} + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (value === undefined) { + return '' + value; + } + if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (typeof value === 'function' || value instanceof RegExp) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (typeof s == 'string') { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name + ':', this.message].join(' '); + } else { + return [ + this.name + ':', + truncate(JSON.stringify(this.actual, replacer), 128), + this.operator, + truncate(JSON.stringify(this.expected, replacer), 128) + ].join(' '); + } +}; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!!!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (expected instanceof RegExp) { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail('Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail('Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +},{"buffer":24,"util":22}],18:[function(require,module,exports){ +var process=require("__browserify_process");if (!process.EventEmitter) process.EventEmitter = function () {}; + +var EventEmitter = exports.EventEmitter = process.EventEmitter; +var isArray = typeof Array.isArray === 'function' + ? Array.isArray + : function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]' + } +; +function indexOf (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; + } + return -1; +} + +// By default EventEmitters will print a warning if more than +// 10 listeners are added to it. This is a useful default which +// helps finding memory leaks. +// +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +var defaultMaxListeners = 10; +EventEmitter.prototype.setMaxListeners = function(n) { + if (!this._events) this._events = {}; + this._events.maxListeners = n; +}; + + +EventEmitter.prototype.emit = function(type) { + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events || !this._events.error || + (isArray(this._events.error) && !this._events.error.length)) + { + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + if (!this._events) return false; + var handler = this._events[type]; + if (!handler) return false; + + if (typeof handler == 'function') { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + return true; + + } else if (isArray(handler)) { + var args = Array.prototype.slice.call(arguments, 1); + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + listeners[i].apply(this, args); + } + return true; + + } else { + return false; + } +}; + +// EventEmitter is defined in src/node_events.cc +// EventEmitter.prototype.emit() is also defined there. +EventEmitter.prototype.addListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('addListener only takes instances of Function'); + } + + if (!this._events) this._events = {}; + + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); + + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } else if (isArray(this._events[type])) { + + // Check for listener leak + if (!this._events[type].warned) { + var m; + if (this._events.maxListeners !== undefined) { + m = this._events.maxListeners; + } else { + m = defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + + // If we've already got an array, just append. + this._events[type].push(listener); + } else { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + var self = this; + self.on(type, function g() { + self.removeListener(type, g); + listener.apply(this, arguments); + }); + + return this; +}; + +EventEmitter.prototype.removeListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('removeListener only takes instances of Function'); + } + + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events || !this._events[type]) return this; + + var list = this._events[type]; + + if (isArray(list)) { + var i = indexOf(list, listener); + if (i < 0) return this; + list.splice(i, 1); + if (list.length == 0) + delete this._events[type]; + } else if (this._events[type] === listener) { + delete this._events[type]; + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + this._events = {}; + return this; + } + + // does not use listeners(), so no side effect of creating _events[type] + if (type && this._events && this._events[type]) this._events[type] = null; + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + if (!this._events) this._events = {}; + if (!this._events[type]) this._events[type] = []; + if (!isArray(this._events[type])) { + this._events[type] = [this._events[type]]; + } + return this._events[type]; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (typeof emitter._events[type] === 'function') + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +},{"__browserify_process":27}],19:[function(require,module,exports){ +// nothing to see here... no file methods for the browser + +},{}],20:[function(require,module,exports){ + +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Array#indexOf shim. + */ + +var indexOf = typeof Array.prototype.indexOf === 'function' + ? function(arr, el) { return arr.indexOf(el); } + : function(arr, el) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === el) return i; + } + return -1; + }; + +/** + * Array.isArray shim. + */ + +var isArray = Array.isArray || function(arr) { + return toString.call(arr) == '[object Array]'; +}; + +/** + * Object.keys shim. + */ + +var objectKeys = Object.keys || function(obj) { + var ret = []; + for (var key in obj) ret.push(key); + return ret; +}; + +/** + * Array#forEach shim. + */ + +var forEach = typeof Array.prototype.forEach === 'function' + ? function(arr, fn) { return arr.forEach(fn); } + : function(arr, fn) { + for (var i = 0; i < arr.length; i++) fn(arr[i]); + }; + +/** + * Array#reduce shim. + */ + +var reduce = function(arr, fn, initial) { + if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); + var res = initial; + for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); + return res; +}; + +/** + * Cache non-integer test regexp. + */ + +var isint = /^[0-9]+$/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {}; + var t = {}; + for (var i in parent[key]) t[i] = parent[key][i]; + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + // end + if (!part) { + if (isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[objectKeys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~indexOf(part, ']')) { + part = part.substr(0, part.length - 1); + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~indexOf(key, ']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (!isint.test(key) && isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + forEach(objectKeys(obj), function(name){ + merge(ret, name, obj[name]); + }); + return ret.base; +} + +/** + * Parse the given str. + */ + +function parseString(str){ + return reduce(String(str).split('&'), function(ret, pair){ + var eql = indexOf(pair, '=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(indexOf(val, '=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + if ('' == key) return ret; + + return merge(ret, decode(key), decode(val)); + }, { base: {} }).base; +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix + '=' + encodeURIComponent(String(obj)); + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[' + i + ']')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = objectKeys(obj) + , key; + + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + if (null == obj[key]) { + ret.push(encodeURIComponent(key) + '='); + } else { + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + } + + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (undefined === v) { + obj[key] = val; + } else if (isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} + +/** + * Decode `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function decode(str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (err) { + return str; + } +} + +},{}],21:[function(require,module,exports){ +var punycode = { encode : function (s) { return s } }; + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +function arrayIndexOf(array, subject) { + for (var i = 0, j = array.length; i < j; i++) { + if(array[i] == subject) return i; + } + return -1; +} + +var objectKeys = Object.keys || function objectKeys(object) { + if (object !== Object(object)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in object) if (object.hasOwnProperty(key)) keys[keys.length] = key; + return keys; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]+$/, + // RFC 2396: characters reserved for delimiting URLs. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '~', '[', ']', '`'].concat(delims), + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''], + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'] + .concat(unwise).concat(autoEscape), + nonAuthChars = ['/', '@', '?', '#'].concat(delims), + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z_-]{0,62}$/, + hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z_-]{0,62})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always have a path component. + pathedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && typeof(url) === 'object' && url.href) return url; + + if (typeof url !== 'string') { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var out = {}, + rest = url; + + // cut off any delimiters. + // This is to support parse stuff like "" + for (var i = 0, l = rest.length; i < l; i++) { + if (arrayIndexOf(delims, rest.charAt(i)) === -1) break; + } + if (i !== 0) rest = rest.substr(i); + + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + out.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + out.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // don't enforce full RFC correctness, just be unstupid about it. + + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the first @ sign, unless some non-auth character + // comes *before* the @-sign. + // URLs are obnoxious. + var atSign = arrayIndexOf(rest, '@'); + if (atSign !== -1) { + // there *may be* an auth + var hasAuth = true; + for (var i = 0, l = nonAuthChars.length; i < l; i++) { + var index = arrayIndexOf(rest, nonAuthChars[i]); + if (index !== -1 && index < atSign) { + // not a valid auth. Something like http://foo.com/bar@baz/ + hasAuth = false; + break; + } + } + if (hasAuth) { + // pluck off the auth portion. + out.auth = rest.substr(0, atSign); + rest = rest.substr(atSign + 1); + } + } + + var firstNonHost = -1; + for (var i = 0, l = nonHostChars.length; i < l; i++) { + var index = arrayIndexOf(rest, nonHostChars[i]); + if (index !== -1 && + (firstNonHost < 0 || index < firstNonHost)) firstNonHost = index; + } + + if (firstNonHost !== -1) { + out.host = rest.substr(0, firstNonHost); + rest = rest.substr(firstNonHost); + } else { + out.host = rest; + rest = ''; + } + + // pull out port. + var p = parseHost(out.host); + var keys = objectKeys(p); + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + out[key] = p[key]; + } + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + out.hostname = out.hostname || ''; + + // validate a little. + if (out.hostname.length > hostnameMaxLen) { + out.hostname = ''; + } else { + var hostparts = out.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + out.hostname = validParts.join('.'); + break; + } + } + } + } + + // hostnames are always lower case. + out.hostname = out.hostname.toLowerCase(); + + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = out.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + out.hostname = newOut.join('.'); + + out.host = (out.hostname || '') + + ((out.port) ? ':' + out.port : ''); + out.href += out.host; + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + + // Now make sure that delims never appear in a url. + var chop = rest.length; + for (var i = 0, l = delims.length; i < l; i++) { + var c = arrayIndexOf(rest, delims[i]); + if (c !== -1) { + chop = Math.min(c, chop); + } + } + rest = rest.substr(0, chop); + } + + + // chop off from the tail first. + var hash = arrayIndexOf(rest, '#'); + if (hash !== -1) { + // got a fragment string. + out.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = arrayIndexOf(rest, '?'); + if (qm !== -1) { + out.search = rest.substr(qm); + out.query = rest.substr(qm + 1); + if (parseQueryString) { + out.query = querystring.parse(out.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + out.search = ''; + out.query = {}; + } + if (rest) out.pathname = rest; + if (slashedProtocol[proto] && + out.hostname && !out.pathname) { + out.pathname = '/'; + } + + //to support http.request + if (out.pathname || out.search) { + out.path = (out.pathname ? out.pathname : '') + + (out.search ? out.search : ''); + } + + // finally, reconstruct the href based on what has been validated. + out.href = urlFormat(out); + return out; +} + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (typeof(obj) === 'string') obj = urlParse(obj); + + var auth = obj.auth || ''; + if (auth) { + auth = auth.split('@').join('%40'); + for (var i = 0, l = nonAuthChars.length; i < l; i++) { + var nAC = nonAuthChars[i]; + auth = auth.split(nAC).join(encodeURIComponent(nAC)); + } + auth += '@'; + } + + var protocol = obj.protocol || '', + host = (obj.host !== undefined) ? auth + obj.host : + obj.hostname !== undefined ? ( + auth + obj.hostname + + (obj.port ? ':' + obj.port : '') + ) : + false, + pathname = obj.pathname || '', + query = obj.query && + ((typeof obj.query === 'object' && + objectKeys(obj.query).length) ? + querystring.stringify(obj.query) : + '') || '', + search = obj.search || (query && ('?' + query)) || '', + hash = obj.hash || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (obj.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + return protocol + host + pathname + search + hash; +} + +function urlResolve(source, relative) { + return urlFormat(urlResolveObject(source, relative)); +} + +function urlResolveObject(source, relative) { + if (!source) return relative; + + source = urlParse(urlFormat(source), false, true); + relative = urlParse(urlFormat(relative), false, true); + + // hash is always overridden, no matter what. + source.hash = relative.hash; + + if (relative.href === '') { + source.href = urlFormat(source); + return source; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + relative.protocol = source.protocol; + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[relative.protocol] && + relative.hostname && !relative.pathname) { + relative.path = relative.pathname = '/'; + } + relative.href = urlFormat(relative); + return relative; + } + + if (relative.protocol && relative.protocol !== source.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + relative.href = urlFormat(relative); + return relative; + } + source.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + relative.pathname = relPath.join('/'); + } + source.pathname = relative.pathname; + source.search = relative.search; + source.query = relative.query; + source.host = relative.host || ''; + source.auth = relative.auth; + source.hostname = relative.hostname || relative.host; + source.port = relative.port; + //to support http.request + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.slashes = source.slashes || relative.slashes; + source.href = urlFormat(source); + return source; + } + + var isSourceAbs = (source.pathname && source.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host !== undefined || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (source.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = source.pathname && source.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = source.protocol && + !slashedProtocol[source.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // source.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + + delete source.hostname; + delete source.port; + if (source.host) { + if (srcPath[0] === '') srcPath[0] = source.host; + else srcPath.unshift(source.host); + } + delete source.host; + if (relative.protocol) { + delete relative.hostname; + delete relative.port; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + delete relative.host; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + source.host = (relative.host || relative.host === '') ? + relative.host : source.host; + source.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : source.hostname; + source.search = relative.search; + source.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + source.search = relative.search; + source.query = relative.query; + } else if ('search' in relative) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + source.hostname = source.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = source.host && arrayIndexOf(source.host, '@') > 0 ? + source.host.split('@') : false; + if (authInHost) { + source.auth = authInHost.shift(); + source.host = source.hostname = authInHost.shift(); + } + } + source.search = relative.search; + source.query = relative.query; + //to support http.request + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.href = urlFormat(source); + return source; + } + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + delete source.pathname; + //to support http.request + if (!source.search) { + source.path = '/' + source.search; + } else { + delete source.path; + } + source.href = urlFormat(source); + return source; + } + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (source.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + source.hostname = source.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = source.host && arrayIndexOf(source.host, '@') > 0 ? + source.host.split('@') : false; + if (authInHost) { + source.auth = authInHost.shift(); + source.host = source.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (source.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + source.pathname = srcPath.join('/'); + //to support request.http + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.auth = relative.auth || source.auth; + source.slashes = source.slashes || relative.slashes; + source.href = urlFormat(source); + return source; +} + +function parseHost(host) { + var out = {}; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + out.port = port.substr(1); + host = host.substr(0, host.length - port.length); + } + if (host) out.hostname = host; + return out; +} + +},{"querystring":20}],22:[function(require,module,exports){ +var events = require('events'); + +exports.isArray = isArray; +exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'}; +exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'}; + + +exports.print = function () {}; +exports.puts = function () {}; +exports.debug = function() {}; + +exports.inspect = function(obj, showHidden, depth, colors) { + var seen = []; + + var stylize = function(str, styleType) { + // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + var styles = + { 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] }; + + var style = + { 'special': 'cyan', + 'number': 'blue', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' }[styleType]; + + if (style) { + return '\u001b[' + styles[style][0] + 'm' + str + + '\u001b[' + styles[style][1] + 'm'; + } else { + return str; + } + }; + if (! colors) { + stylize = function(str, styleType) { return str; }; + } + + function format(value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value !== exports && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + return value.inspect(recurseTimes); + } + + // Primitive types cannot have properties + switch (typeof value) { + case 'undefined': + return stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return stylize(simple, 'string'); + + case 'number': + return stylize('' + value, 'number'); + + case 'boolean': + return stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return stylize('null', 'null'); + } + + // Look up the keys of the object. + var visible_keys = Object_keys(value); + var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys; + + // Functions without properties can be shortcutted. + if (typeof value === 'function' && keys.length === 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + var name = value.name ? ': ' + value.name : ''; + return stylize('[Function' + name + ']', 'special'); + } + } + + // Dates without properties can be shortcutted + if (isDate(value) && keys.length === 0) { + return stylize(value.toUTCString(), 'date'); + } + + var base, type, braces; + // Determine the object type + if (isArray(value)) { + type = 'Array'; + braces = ['[', ']']; + } else { + type = 'Object'; + braces = ['{', '}']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var n = value.name ? ': ' + value.name : ''; + base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; + } else { + base = ''; + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + value.toUTCString(); + } + + if (keys.length === 0) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + return stylize('[Object]', 'special'); + } + } + + seen.push(value); + + var output = keys.map(function(key) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = stylize('[Getter/Setter]', 'special'); + } else { + str = stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = stylize('[Setter]', 'special'); + } + } + } + if (visible_keys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = format(value[key]); + } else { + str = format(value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (isArray(value)) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (type === 'Array' && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = stylize(name, 'string'); + } + } + + return name + ': ' + str; + }); + + seen.pop(); + + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 50) { + output = braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + + } else { + output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + return output; + } + return format(obj, (typeof depth === 'undefined' ? 2 : depth)); +}; + + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && Object.prototype.toString.call(ar) === '[object Array]'); +} + + +function isRegExp(re) { + typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]'; +} + + +function isDate(d) { + return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; +} + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + +exports.log = function (msg) {}; + +exports.pump = null; + +var Object_keys = Object.keys || function (obj) { + var res = []; + for (var key in obj) res.push(key); + return res; +}; + +var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) { + var res = []; + for (var key in obj) { + if (Object.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +var Object_create = Object.create || function (prototype, properties) { + // from es5-shim + var object; + if (prototype === null) { + object = { '__proto__' : null }; + } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); + } + return object; +}; + +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object_create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (typeof f !== 'string') { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(exports.inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': return JSON.stringify(args[i++]); + default: + return x; + } + }); + for(var x = args[i]; i < len; x = args[++i]){ + if (x === null || typeof x !== 'object') { + str += ' ' + x; + } else { + str += ' ' + exports.inspect(x); + } + } + return str; +}; + +},{"events":18}],23:[function(require,module,exports){ +exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; + +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; + +},{}],24:[function(require,module,exports){ +var assert = require('assert'); +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; + +function Buffer(subject, encoding, offset) { + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; + + var type; + + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + this.offset = offset; + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; + + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; + + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; + + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } + + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; + } + } + } +} + +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; +}; + +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; + +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; + + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; + + case 'ascii': + case 'binary': + return str.length; + + case 'base64': + return base64ToBytes(str).length; + + default: + throw new Error('Unknown encoding'); + } +}; + +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; + +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; + +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; + +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; + +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; + +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); + + i++; + } + + return res + decodeUtf8Char(tmp); +} + +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} + +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; + +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; + } + } + return ''; +}; + + +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); + } + return out; +}; + + +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; + + // Fastpath empty strings + if (+end == start) { + return ''; + } + + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); + + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); + + case 'ascii': + return this.asciiSlice(start, end); + + case 'binary': + return this.binarySlice(start, end); + + case 'base64': + return this.base64Slice(start, end); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); + + default: + throw new Error('Unknown encoding'); + } +}; + + +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); + } + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; +}; + + +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; + } + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || 'utf8').toLowerCase(); + + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); + + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); + + case 'ascii': + return this.asciiWrite(string, offset, length); + + case 'binary': + return this.binaryWrite(string, offset, length); + + case 'base64': + return this.base64Write(string, offset, length); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); + + default: + throw new Error('Unknown encoding'); + } +}; + + +// slice(start, end) +Buffer.prototype.slice = function(start, end) { + if (end === undefined) end = this.length; + + if (end > this.length) { + throw new Error('oob'); + } + if (start > end) { + throw new Error('oob'); + } + + return new Buffer(this, end - start, +start); +}; + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; + } + target_start || (target_start = 0); + + if (end < start) throw new Error('sourceEnd < sourceStart'); + + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; + + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); + } + + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); + } + + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); + } + + // Are we oob? + if (end > this.length) { + end = this.length; + } + + if (target.length - target_start < end - start) { + end = target.length - target_start + start; + } + + var temp = []; + for (var i=start; i= this.length) { + throw new Error('start out of bounds'); + } + + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); + } + + for (var i = start; i < end; i++) { + this[i] = value; + } +} + +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; +}; + +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); + } + + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; + } + + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; + } + } + + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer; +}; + +// helpers + +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; +} + +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) +} + +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; +} + +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); +} + +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); + } + + return byteArray; +} + +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); + + return byteArray; +} + +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} + +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; + + dst[i + offset] = src[i]; + i++; + } + return i; +} + +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char + } +} + +// read/write bit-twiddling + +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + return buffer[offset]; +}; + +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; + } + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; + } + } + + return val; +} + +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; + +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); + } + + return val; +} + +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; + + +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); + } + + return ((0xff - buffer[offset] + 1) * -1); +}; + +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } + + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; + } + + return (0xffff - val + 1) * -1; +} + +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; + +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); +}; + +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); + } + + return (0xffffffff - val + 1) * -1; +} + +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); +}; + +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); +}; + +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; + +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); +}; + +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); +}; + + +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); + + assert.ok(value <= max, 'value is larger than maximum value for type'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} + +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xff); + } + + if (offset < buffer.length) { + buffer[offset] = value; + } +}; + +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffff); + } + + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; + } + +} + +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); +}; + +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); + } + + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; + } +} + +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; + + +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: + * + * > -32 & 0xff + * 224 + * + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. + * + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: + * + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: + * + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. + */ + +/* + * A series of checks to make sure we actually have a signed 32-bit number + */ +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} + +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} + +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7f, -0x80); + } + + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); + } +}; + +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); + } + + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; + +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fffffff, -0x80000000); + } + + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; + +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); +}; + +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; + +},{"./buffer_ieee754":23,"assert":17,"base64-js":25}],25:[function(require,module,exports){ +(function (exports) { + 'use strict'; + + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } + + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } + + return arr; + } + + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } + + return output; + } + + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); + +},{}],26:[function(require,module,exports){ + +},{}],27:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + if (ev.source === window && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +},{}]},{},[6]) +(6) +}); +; \ No newline at end of file diff --git a/doc/_static/jquery-1.7.1.min.js b/doc/_static/jquery-1.7.1.min.js deleted file mode 100644 index 198b3ff..0000000 --- a/doc/_static/jquery-1.7.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/doc/_static/jquery.js b/doc/_static/jquery.js deleted file mode 100644 index 198b3ff..0000000 --- a/doc/_static/jquery.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/doc/_static/local-overrides.css b/doc/_static/local-overrides.css new file mode 100644 index 0000000..4f19403 --- /dev/null +++ b/doc/_static/local-overrides.css @@ -0,0 +1,3 @@ +#try-it-modal .modal-body { + max-height: 800px; +} diff --git a/doc/_static/logo.png b/doc/_static/logo.png deleted file mode 100644 index a4ebee3..0000000 Binary files a/doc/_static/logo.png and /dev/null differ diff --git a/doc/_static/try-it-now.js b/doc/_static/try-it-now.js new file mode 100644 index 0000000..0fb535e --- /dev/null +++ b/doc/_static/try-it-now.js @@ -0,0 +1,35 @@ +$(function ($) { + var queryInput = $("#try-it-modal textarea.code"); + var dialect = new gesundheit.dialects.pretty() + + queryInput.change(evaluateQuery); + queryInput.keyup(evaluateQuery); + evaluateQuery(); + + function evaluateQuery () { + var result; + try { + eval([ + 'var result = (function (g) {', + ' with (g) {', + ' ' + queryInput.val(), + ' }', + '})(gesundheit)' + ].join('\n')); + if (result && result.compile) { + if (result.q) result = result.q; + var sp = dialect.compile(result); + $('#try-it-modal .sql').text(sp[0]) + $('#try-it-modal .params').text(JSON.stringify(sp[1])) + } else { + $('#try-it-modal .sql').text(result + ' has no "compile" method') + $('#try-it-modal .params').text(''); + } + } catch (err) { + if (!(err instanceof SyntaxError)) { + $('#try-it-modal .sql').text('' + err) + $('#try-it-modal .params').text(''); + } + } + } +}) diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html index 72c1a46..8c49c00 100644 --- a/doc/_templates/layout.html +++ b/doc/_templates/layout.html @@ -1,8 +1,13 @@ {% extends "!layout.html" %} -{% set script_files = script_files %} -{% set sidebars = ['localtoc.html', 'projectlinks.html', 'logo.html'] %} +{% set css_files = css_files + ['_static/local-overrides.css'] %} -{% block sidebar1 %} {{ sidebar() }} {% endblock %} -{% block sidebar2 %} {% endblock %} -{% block relbar1 %} {% endblock %} -{% block relbar2 %} {% endblock %} +{% block navbarextra %} +
  • + Try it now! +
  • +{% endblock %} + +{% block footer %} + {% include "try_it_modal.html" %} + {{ super() }} +{% endblock %} diff --git a/doc/_templates/try_it_modal.html b/doc/_templates/try_it_modal.html new file mode 100644 index 0000000..2cbc1cf --- /dev/null +++ b/doc/_templates/try_it_modal.html @@ -0,0 +1,28 @@ + + + + diff --git a/doc/client_side_usage.rst b/doc/client_side_usage.rst new file mode 100644 index 0000000..bb04876 --- /dev/null +++ b/doc/client_side_usage.rst @@ -0,0 +1,74 @@ +Client-side usage - Experimental +================================ + +Starting with version 0.9, Gesundheit can be used in the browser with +`Browserify `_. There are also +precompiled standalone bundles (available on Github) that declare a +``gesundheit`` global variable. + +Because it is not possible to connect directly to a database server over a +socket from the browser, queries created in the browser will need to be sent to +some sort of server-side component for execution. + +Securely executing queries from untrusted sources +------------------------------------------------- + +The idea of executing arbitrary SQL statements sent to your web-app should be +setting off all kinds of alarm bells. Luckily, Gesundheit provides a better +alternative. Instead of sending queries as an opaque string, a browser-based +client instead sends a serialized AST. On the server side this datastructure +is unmarshalled back into a Gesundheit query object. + +This is an improvement over arbitrary text, but it's still not really providing +any `security`; A user can construct an awful lot of malicious queries using +Gesundheit. + +The next layer of security is pluggable via the ``visitor`` argument to +``gesundheit.unmarshaller(visitor, data)``. This ``visitor`` object can +interact with and/or abort the unmarshalling process. For example:: + + var allowedTables = ['free_for_all', 'delete_my_records']; + var checkTableName = { + before: function (nodeData, path) { + if (nodeData._type == 'Relation' + && allowedTables.indexOf(nodeData.value) == -1) + { + throw new Error("Access denied"); + } + } + } + + var userInput = JSON.parse(arbitraryString); + var query = gesundheit.unmarshaller(checkTableNames, userInput); + +If a query attempts to access any table that is not listed in ``allowedTables`` +an error will be thrown. The above could also be written using the ``after`` +hook:: + + var allowedTables = ['free_for_all', 'delete_my_records']; + var checkTableName = { + after: function (node, path) { + if (node instanceof gesundheit.nodes.Relation) + && allowedTables.indexOf(node.value) == -1) + { + throw new Error("Access denied"); + } + } + } + +Missing Batteries +----------------- + +This approach currently leaves most of the hard work up to the end user. Several +additional projects are envisaged that will make this much easier to use. + + 1. A "compiler" of sorts that creates a visitor object using a declarative + access policy description. + + 2. An engine implementation sends queries over HTTP. + + 3. A server-side "bridge" component that can handle HTTP requests from #2 + and enforce an access policy using #1. + +Each of these could be published separately from Gesundheit itself, which is +already quite large. diff --git a/doc/conf.py b/doc/conf.py index 0128508..2ae9ea0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -108,7 +108,12 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +html_theme_options = { + 'navbar_site_name': 'Contents', + 'navbar_sidebarrel': False, + 'source_link_position': False, + #'bootswatch_theme': 'readable', +} # Add any paths that contain custom themes here, relative to this directory. html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() diff --git a/doc/getting_started.rst b/doc/getting_started.rst index 03d8872..24b07a4 100644 --- a/doc/getting_started.rst +++ b/doc/getting_started.rst @@ -11,8 +11,7 @@ Installation In addition to `gesundheit` itself, you will need to install any database drivers you plan on using:: - npm install --save pg mysql - npm install --save-dev sqlite3 + npm install --save any-db-{mysql,postgres,sqlite3} Creating a Query object diff --git a/doc/index.rst b/doc/index.rst index b96fa4d..9d78ac9 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -22,5 +22,6 @@ Contents engines_and_binding dialects nodes + client_side_usage * :ref:`genindex` diff --git a/gesundheit-standalone.js b/gesundheit-standalone.js new file mode 100644 index 0000000..28f477b --- /dev/null +++ b/gesundheit-standalone.js @@ -0,0 +1,6657 @@ +(function(e){if("function"==typeof bootstrap)bootstrap("gesundheit",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeGesundheit=e}else"undefined"!=typeof window?window.gesundheit=e():global.gesundheit=e()})(function(){var define,ses,bootstrap,module,exports; +return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o`_ that will delegate compiling to it's dialect +instance. +*/ + +var BaseDialect, Delete, Field, Insert, MySQLDialect, PostgresDialect, PrettyDialect, Relation, SQLite3Dialect, Select, Update, keywords, _ref, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +_ref = require('./nodes'), Select = _ref.Select, Update = _ref.Update, Delete = _ref.Delete, Insert = _ref.Insert, Relation = _ref.Relation, Field = _ref.Field; + +if (process.browser) { + keywords = []; +} else { + keywords = require('fs').readFileSync(__dirname + '/sql_keywords.txt').toString().split('\n').filter(Boolean); +} + +BaseDialect = (function() { + var Visitor, doubleQuote, needsQuote; + + function BaseDialect() {} + + BaseDialect.prototype.reset = function() {}; + + BaseDialect.prototype.compile = function(root) { + var text, visitor; + visitor = new Visitor(this); + text = visitor.compile(root); + return [text, visitor.params]; + }; + + BaseDialect.prototype.renderString = function(s) { + var path; + path = this.path.map(function(p) { + var _ref1; + return (_ref1 = p.constructor) != null ? _ref1.name : void 0; + }).join(' > '); + this.path = []; + throw new Error("raw string compiled! " + path); + }; + + needsQuote = /\s|"|\./; + + doubleQuote = /"/g; + + BaseDialect.prototype.quote = function(s) { + if ((s != null ? s.match(needsQuote) : void 0) || this.isKeyword(s)) { + return '"' + s.replace(doubleQuote, '\\"') + '"'; + } else { + return s; + } + }; + + BaseDialect.prototype.isKeyword = function(word) { + return keywords.indexOf(word.toUpperCase()) !== -1; + }; + + BaseDialect.prototype.operator = function(op) { + switch ((op = op.toUpperCase())) { + case 'NE': + case '!=': + case '<>': + return '!='; + case 'EQ': + case '=': + return '='; + case 'LT': + case '<': + return '<'; + case 'GT': + case '>': + return '>'; + case 'LTE': + case '<=': + return '<='; + case 'GTE': + case '>=': + return '>='; + case 'LIKE': + case 'ILIKE': + case 'IN': + case 'NOT IN': + case 'IS': + case 'IS NOT': + return op; + default: + throw new Error("Unsupported comparison operator: " + op); + } + }; + + BaseDialect.prototype.placeholder = function(position) { + return "$" + position; + }; + + Visitor = (function() { + + function Visitor(dialect) { + this.dialect = dialect; + this.path = []; + this.params = []; + } + + Visitor.prototype.compile = function(node, allowOverride) { + var custom, name, string, _ref1, _ref2; + if (allowOverride == null) { + allowOverride = true; + } + this.path.push(node); + name = node != null ? (_ref1 = node.__proto__) != null ? (_ref2 = _ref1.constructor) != null ? _ref2.name : void 0 : void 0 : void 0; + if (allowOverride && name && (custom = this.dialect['render' + name])) { + string = custom.call(this, node); + } else { + if (!(node != null ? node.compile : void 0)) { + debugger; + } + string = node.compile(this, this.path); + } + this.path.pop(node); + return string; + }; + + Visitor.prototype.maybeParens = function(it) { + if (/\s/.exec(it)) { + return "(" + it + ")"; + } else { + return it; + } + }; + + Visitor.prototype.operator = function(string) { + return this.dialect.operator(string); + }; + + Visitor.prototype.parameter = function(val) { + this.params.push(val); + return this.dialect.placeholder(this.params.length); + }; + + Visitor.prototype.quote = function(string) { + return this.dialect.quote(string, this.path); + }; + + return Visitor; + + })(); + + return BaseDialect; + +})(); + +PrettyDialect = (function(_super) { + + __extends(PrettyDialect, _super); + + function PrettyDialect() { + return PrettyDialect.__super__.constructor.apply(this, arguments); + } + + PrettyDialect.prototype.renderJoin = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderWhere = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderHaving = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderOrderBy = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderGroupBy = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderRelationSet = function(node) { + return "\n" + this.compile(node, false); + }; + + PrettyDialect.prototype.renderSelectColumnSet = function(node) { + var glue, last, lines, size, text, thisLine, thisLineLength, _i, _len, _ref1; + glue = node.glue; + last = node.nodes.length; + lines = []; + thisLine = []; + thisLineLength = 81; + _ref1 = node.nodes; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + node = _ref1[_i]; + text = this.compile(node); + size = text.length + glue.length; + if (thisLineLength + size > 50) { + lines.push(thisLine.join(glue)); + thisLine = []; + thisLineLength = 0; + } + thisLineLength += size; + thisLine.push(text); + } + lines.shift(); + lines.push(thisLine.join(glue)); + return lines.join("\n "); + }; + + return PrettyDialect; + +})(BaseDialect); + +PostgresDialect = (function(_super) { + + __extends(PostgresDialect, _super); + + function PostgresDialect() { + return PostgresDialect.__super__.constructor.apply(this, arguments); + } + + PostgresDialect.prototype.operator = function(op) { + switch (op.toLowerCase()) { + case 'hasKey': + case '?': + return '?'; + case 'contains': + case '@>': + return '@>'; + case '->': + return '->'; + default: + return PostgresDialect.__super__.operator.call(this, op); + } + }; + + PostgresDialect.prototype.isKeyword = function(s) { + return (s != null) && s !== '*'; + }; + + return PostgresDialect; + +})(BaseDialect); + +MySQLDialect = (function(_super) { + + __extends(MySQLDialect, _super); + + function MySQLDialect() { + return MySQLDialect.__super__.constructor.apply(this, arguments); + } + + MySQLDialect.prototype.placeholder = function() { + return '?'; + }; + + MySQLDialect.prototype.quote = function(s, path) { + /* + MySQL has two special cases for quoting: + - The column names in an insert column list are not quoted + - table and field names are quoted with backticks. + */ + + var node; + node = path[path.length - 1]; + if (s === '*' || path.some(function(node) { + return node instanceof Insert.ColumnList; + })) { + return s; + } else if (node instanceof Field || node instanceof Relation) { + return "`" + s + "`"; + } else { + return MySQLDialect.__super__.quote.apply(this, arguments); + } + }; + + return MySQLDialect; + +})(BaseDialect); + +SQLite3Dialect = (function(_super) { + + __extends(SQLite3Dialect, _super); + + function SQLite3Dialect() { + return SQLite3Dialect.__super__.constructor.apply(this, arguments); + } + + SQLite3Dialect.prototype.placeholder = function() { + return '?'; + }; + + SQLite3Dialect.prototype.renderInsertData = function(node) { + var string; + if (node.nodes.length < 2) { + return node.compile(this, this.path); + } else { + node.glue = ' UNION ALL SELECT '; + string = node.compile(this, this.path).replace('VALUES', 'SELECT').replace(/[()]/g, ''); + node.glue = ', '; + return string; + } + }; + + return SQLite3Dialect; + +})(BaseDialect); + +module.exports = { + base: BaseDialect, + pretty: PrettyDialect, + postgres: PostgresDialect, + mysql: MySQLDialect, + sqlite3: SQLite3Dialect +}; + +},{"./nodes":7,"__browserify_process":27,"fs":19}],5:[function(require,module,exports){ +var process=require("__browserify_process");// Generated by CoffeeScript 1.4.0 +var Engine, anyDB, dialects, fakePool, queries, url; + +url = require('url'); + +anyDB = require('any-db'); + +queries = require('./queries/index'); + +dialects = require('./dialects'); + +module.exports = function() { + return Engine.create.apply(Engine, arguments); +}; + +Engine = (function() { + /* + ``Engine`` is gesundheits interface to an actual database. + + Engines have all of the :ref:`query factory functions ` + attached to them as instance methods that automatically bind created queries + to the engine. They also have these additionaly methods + */ + + Engine.create = function(dbUrl, poolOptions) { + /* + Create an :class:`engine::Engine` instance from an Any-DB_ connect string + and extra connection pool options, this is exported by gesundheit as + ``gesundheit.engine(...)``. + + :ref:`This example ` shows the most common way to set up + a single default database engine for an application. + + .. _Any-DB: https://github.com/grncdr/node-any-db + .. _Any-DB ConnectionPool: https://github.com/grncdr/node-any-db/blob/master/API.md#connectionpool + */ + + var dialectType, driverName, parsed, pool; + parsed = url.parse(dbUrl); + driverName = parsed.protocol.replace(':', '').split('+').shift(); + if (driverName === 'fake') { + pool = fakePool(); + if (parsed.protocol.match('pretty')) { + dialectType = dialects.pretty; + } else { + dialectType = dialects.base; + } + } else { + pool = anyDB.createPool(dbUrl, poolOptions); + dialectType = dialects[driverName]; + } + if (!(dialectType != null)) { + throw new Error('no such dialect: ' + driverName); + } + return new Engine(driverName, dbUrl, pool, new dialectType()); + }; + + function Engine(driver, url, pool, dialect) { + this.driver = driver; + this.url = url; + this.pool = pool; + this.dialect = dialect; + queries.mixinFactoryMethods(this); + } + + Engine.prototype.query = function(statement, params, callback) { + /* + Passes arguments directly to the query method of the underlying `Any-DB + ConnectionPool`_ + */ + + var _ref; + return (_ref = this.pool).query.apply(_ref, arguments); + }; + + Engine.prototype.begin = function(callback) { + /* + Start a new transaction and return it. + + The returned object behaves exactly like a new engine, but has ``commit`` + and ``rollback`` methods instead of ``close``. (In fact it's an `Any-DB + Transaction`_ that has had the query factory functions mixed in to it). + + .. _Any-DB Transaction: https://github.com/grncdr/node-any-db/blob/master/API.md#transaction + */ + + var tx; + tx = queries.mixinFactoryMethods(this.pool.begin(callback)); + tx.engine = this; + tx.compile = this.dialect.compile.bind(this.dialect); + return tx; + }; + + Engine.prototype.compile = function(root) { + /* + Render an AST to a SQL string and collect parameters + */ + return this.dialect.compile(root); + }; + + Engine.prototype.close = function() { + /* + Closes the internal connection pool. + */ + return this.pool.close(); + }; + + return Engine; + +})(); + +fakePool = function() { + /* + Create a fake database connection pool that throws errors if you try to + execute a query. + */ + return { + begin: function(cb) { + if (cb) { + process.nextTick(cb.bind(null, engine)); + } + return engine; + }, + query: function(sql, params, cb) { + throw new Error("Cannot query with fakeEngine. Do `gesundheit.defaultEngine = gesundheit.engine(url)` before querying"); + }, + close: function() {} + }; +}; + +},{"./dialects":4,"./queries/index":10,"__browserify_process":27,"any-db":26,"url":21}],6:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +There are a few subsystems that make up gesundheit, but the majority of use +cases will be covered by using the following properties of the main module: + + **gesundheit.{Select, SELECT, select}** + Function for creating new :class:`queries/select::SelectQuery` instances. + + **gesundheit.{Update, UPDATE, update}** + Function for creating new :class:`queries/update::UpdateQuery` instances. + + **gesundheit.{Delete, DELETE, delete}** + Function for creating new :class:`queries/delete::DeleteQuery` instances. + + **gesundheit.{Insert, INSERT, insert}** + Function for creating new :class:`queries/insert::InsertQuery` instances. + + **gesundheit.engine** + Function for creating new :mod:`engines`. + + **gesundheit.defaultEngine** + The engine that will be used for queries that aren't explicitly bound. This + is set to a no-op engine that you will want to replace with either an object + returned by the ``gesundheit.engine`` function or by implementing the engine + interface yourself. + + **Join types** + Constant nodes for use with :meth:`queries/sud::SUDQuery.join`. + 'LEFT', 'RIGHT', 'INNER', 'LEFT_OUTER', 'RIGHT_OUTER', 'FULL_OUTER' + 'NATURAL', 'CROSS' + + **AST helper functions** + These come from the `nodes <#module-nodes::>`_ module and are often useful + when constructing complicated queries: + + :func:`nodes::toParam` + Convert any object to a parameter placeholder. + :func:`nodes::toRelation` + Convert various inputs to :class:`nodes::Relation` nodes. + :func:`nodes::binaryOp` + Create a binary comparison node manually. (e.g. for postgres' custom + operators). + :func:`nodes::sqlFunction` + Create SQL function calls (e.g. ``MAX(last_update)``) + :func:`nodes::text` + Include raw SQL in a query, with parameter placeholders. + +If you are implementing support for a different database engine or constructing +particularly unusual SQL statements, you might also want to make use of these: + + **gesundheit.nodes** + The `nodes ` module. + + **gesundheit.dialects** + The `dialects ` module. +*/ + +var helper, name, node, _ref, _ref1, _ref2, + __slice = [].slice; + +exports.dialects = require('./dialects'); + +exports.engine = require('./engine'); + +exports.nodes = require('./nodes'); + +exports.queries = require('./queries/index'); + +exports.defaultEngine = exports.engine('fake://localhost/'); + +exports.queries.mixinFactoryMethods(exports, function() { + return exports.defaultEngine; +}); + +_ref = exports.nodes.CONST_NODES; +for (name in _ref) { + node = _ref[name]; + exports[name] = exports.nodes.CONST_NODES[name]; +} + +_ref1 = exports.nodes.JOIN_TYPES; +for (name in _ref1) { + node = _ref1[name]; + exports[name] = exports.nodes.JOIN_TYPES[name]; +} + +_ref2 = exports.nodes; +for (name in _ref2) { + helper = _ref2[name]; + if (name[0] === name[0].toLowerCase()) { + exports[name] = helper; + } +} + +exports.begin = function() { + var args, _ref3; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return (_ref3 = exports.defaultEngine).begin.apply(_ref3, args); +}; + +exports.query = function() { + var args, _ref3; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return (_ref3 = exports.defaultEngine).query.apply(_ref3, args); +}; + +exports.unmarshaller = require('./unmarshal'); + +},{"./dialects":4,"./engine":5,"./nodes":7,"./queries/index":10,"./unmarshal":16}],7:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +These are the classes that represent nodes in the AST for a SQL statement. +Application code should very rarely have to deal with these classes directly; +Instead, the APIs exposed by the various query manager classes are intended to +cover the majority of use-cases. + +However, in the spirit of "making hard things possible", all of AST nodes are +exported from this module so you can constructed and assemble them manually if +you need to. +*/ + +var AbstractAlias, And, Binary, CONST_NODES, Column, ColumnSet, ComparableMixin, Delete, Distinct, Field, FixedNodeSet, FunctionAlias, GroupBy, Having, Identifier, Insert, IntegerNode, JOIN_TYPES, Join, JoinType, Limit, Node, NodeSet, Offset, Or, OrderBy, Ordering, Parameter, ParenthesizedNodeSet, Prefixed, Relation, RelationAlias, RelationSet, Returning, Select, SelectColumnSet, SqlFunction, Statement, TextAlias, TextNode, Tuple, Update, ValueNode, Where, binaryOp, copy, ctor, exists, func, getAlias, merge, name, notExists, sqlFunction, text, toColumn, toField, toParam, toProjection, toRelation, tuple, unmarshal, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + +Node = (function() { + + function Node() {} + + /* (Empty) base Node class + */ + + + Node.prototype.compile = function(dialect) { + var message; + message = "" + this.constructor + " has no compile method. Parents: " + dialect.path; + throw new Error(message); + }; + + Node.prototype.toJSON = function() { + return { + _type: this.constructor.name + }; + }; + + Node.prototype.copy = function() { + return unmarshal(this.toJSON()); + }; + + return Node; + +})(); + +ValueNode = (function(_super) { + + __extends(ValueNode, _super); + + /* A ValueNode is a literal string that should be printed unescaped. + */ + + + ValueNode.unmarshal = function(data, recur) { + return new this(data.value); + }; + + function ValueNode(value) { + this.value = value; + if (this.value != null) { + if (!this.valid()) { + throw new Error("Invalid " + this.constructor.name + ": " + this.value); + } + } + } + + ValueNode.prototype.valid = function() { + return true; + }; + + ValueNode.prototype.compile = function() { + return this.value; + }; + + ValueNode.prototype.toJSON = function() { + return merge(ValueNode.__super__.toJSON.apply(this, arguments), { + value: this.value + }); + }; + + return ValueNode; + +})(Node); + +IntegerNode = (function(_super) { + + __extends(IntegerNode, _super); + + function IntegerNode() { + return IntegerNode.__super__.constructor.apply(this, arguments); + } + + /* A :class:`nodes::ValueNode` that validates it's input is an integer. + */ + + + IntegerNode.prototype.valid = function() { + return !isNaN(this.value = parseInt(this.value)); + }; + + return IntegerNode; + +})(ValueNode); + +Identifier = (function(_super) { + + __extends(Identifier, _super); + + function Identifier() { + return Identifier.__super__.constructor.apply(this, arguments); + } + + /* + An identifier is a column or relation name that may need to be quoted. + */ + + + Identifier.prototype.compile = function(dialect) { + return dialect.quote(this.value); + }; + + return Identifier; + +})(ValueNode); + +CONST_NODES = {}; + +_ref = ['DEFAULT', 'NULL', 'IS_NULL', 'IS_NOT_NULL']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + CONST_NODES[name] = new ValueNode(name.replace('_', ' ')); +} + +JoinType = (function(_super) { + + __extends(JoinType, _super); + + function JoinType() { + return JoinType.__super__.constructor.apply(this, arguments); + } + + return JoinType; + +})(ValueNode); + +JOIN_TYPES = {}; + +_ref1 = ['LEFT', 'RIGHT', 'INNER', 'LEFT_OUTER', 'RIGHT_OUTER', 'FULL_OUTER', 'NATURAL', 'CROSS']; +for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + name = _ref1[_j]; + JOIN_TYPES[name] = new JoinType(name.replace('_', ' ')); +} + +NodeSet = (function(_super) { + + __extends(NodeSet, _super); + + /* A set of nodes joined together by ``@glue`` + */ + + + NodeSet.unmarshal = function(data, recur) { + return new this(recur(data.nodes), data.glue); + }; + + function NodeSet(nodes, glue) { + var node, _k, _len2, _ref2; + if (glue == null) { + glue = ' '; + } + /* + :param @nodes: A list of child nodes. + :param glue: A string that will be used to join the nodes when compileing + */ + + this.nodes = []; + if (nodes) { + for (_k = 0, _len2 = nodes.length; _k < _len2; _k++) { + node = nodes[_k]; + this.addNode(node); + } + } + if ((_ref2 = this.glue) == null) { + this.glue = glue; + } + } + + NodeSet.prototype.addNode = function(node) { + /* Add a new Node to the end of this set + */ + return this.nodes.push(node); + }; + + NodeSet.prototype.compile = function(dialect) { + var compile; + compile = dialect.compile.bind(dialect); + return this.nodes.map(compile).filter(Boolean).join(this.glue); + }; + + NodeSet.prototype.toJSON = function() { + return merge(NodeSet.__super__.toJSON.apply(this, arguments), { + glue: this.glue, + nodes: this.nodes.map(function(n) { + return n.toJSON(); + }) + }); + }; + + return NodeSet; + +})(Node); + +FixedNodeSet = (function(_super) { + + __extends(FixedNodeSet, _super); + + function FixedNodeSet() { + FixedNodeSet.__super__.constructor.apply(this, arguments); + this.addNode = null; + } + + return FixedNodeSet; + +})(NodeSet); + +Statement = (function(_super) { + + __extends(Statement, _super); + + Statement.prefix = ''; + + Statement.structure = function(structure) { + var _this = this; + this._nodeOrder = []; + return structure.forEach(function(_arg) { + var k, type; + k = _arg[0], type = _arg[1]; + _this._nodeOrder.push(k); + _this.prototype.__defineGetter__(k, function() { + var _base; + return (_base = this._private)[k] || (_base[k] = new type); + }); + return _this.prototype.__defineSetter__(k, function(v) { + return this._private[k] = v; + }); + }); + }; + + Statement.unmarshal = function(data, recur) { + var it; + it = new this; + delete data._type; + it._private = recur(data); + return it; + }; + + function Statement(opts) { + this._private = {}; + if (opts) { + this.initialize(opts); + } + } + + Statement.prototype.initialize = function(opts) { + return this.initialize = null; + }; + + Statement.prototype.compile = function(dialect) { + var k, node, parts; + parts = (function() { + var _k, _len2, _ref2, _results; + _ref2 = this.constructor._nodeOrder; + _results = []; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + k = _ref2[_k]; + if (node = this._private[k]) { + _results.push(dialect.compile(node)); + } + } + return _results; + }).call(this); + if (parts.length) { + return this.constructor.prefix + parts.join(' '); + } else { + return ""; + } + }; + + Statement.prototype.toJSON = function() { + var k, parent, v, _ref2; + parent = Statement.__super__.toJSON.apply(this, arguments); + _ref2 = this._private; + for (k in _ref2) { + v = _ref2[k]; + parent[k] = v.toJSON(); + } + return parent; + }; + + return Statement; + +})(Node); + +ParenthesizedNodeSet = (function(_super) { + + __extends(ParenthesizedNodeSet, _super); + + function ParenthesizedNodeSet() { + return ParenthesizedNodeSet.__super__.constructor.apply(this, arguments); + } + + /* A NodeSet wrapped in parenthesis. + */ + + + ParenthesizedNodeSet.prototype.compile = function() { + return "(" + ParenthesizedNodeSet.__super__.compile.apply(this, arguments) + ")"; + }; + + return ParenthesizedNodeSet; + +})(NodeSet); + +AbstractAlias = (function(_super) { + + __extends(AbstractAlias, _super); + + AbstractAlias.patch = function(klazz) { + klazz.Alias = this; + return klazz.prototype.as = function(name) { + return new this.constructor.Alias(this, name); + }; + }; + + AbstractAlias.unmarshal = function(data, recur) { + return new this(recur(data.obj), data.alias); + }; + + function AbstractAlias(obj, alias) { + this.obj = obj; + this.alias = alias; + } + + AbstractAlias.prototype.ref = function() { + return this.alias; + }; + + AbstractAlias.prototype.compile = function(dialect) { + return dialect.maybeParens(dialect.compile(this.obj)) + " AS " + dialect.quote(this.alias); + }; + + AbstractAlias.prototype.toJSON = function() { + return merge(AbstractAlias.__super__.toJSON.apply(this, arguments), { + obj: this.obj.toJSON(), + alias: this.alias + }); + }; + + return AbstractAlias; + +})(Node); + +TextNode = (function(_super) { + var paramRegexp; + + __extends(TextNode, _super); + + TextNode.unmarshal = function(data, recur) { + return new this(data.text, data.bindVals); + }; + + function TextNode(text, bindVals) { + this.text = text; + this.bindVals = bindVals != null ? bindVals : []; + } + + paramRegexp = /\$([\w]+)\b/g; + + TextNode.prototype.compile = function(dialect) { + var _this = this; + return this.text.replace(paramRegexp, function(_, name) { + if (name in _this.bindVals) { + return dialect.parameter(_this.bindVals[name]); + } else { + throw new Error("Parameter " + name + " not present in " + (JSON.stringify(_this.bindVals))); + } + }); + }; + + TextNode.prototype.toJSON = function() { + return merge(TextNode.__super__.toJSON.apply(this, arguments), { + text: this.text, + bindVals: this.bindVals + }); + }; + + return TextNode; + +})(Node); + +TextAlias = (function(_super) { + + __extends(TextAlias, _super); + + function TextAlias() { + return TextAlias.__super__.constructor.apply(this, arguments); + } + + TextAlias.patch(TextNode); + + return TextAlias; + +})(AbstractAlias); + +SqlFunction = (function(_super) { + + __extends(SqlFunction, _super); + + /* Includes :class:`nodes::ComparableMixin` + */ + + + SqlFunction.unmarshal = function(data, recur) { + return new this(data.name, data.arglist); + }; + + function SqlFunction(name, arglist) { + this.name = name; + this.arglist = arglist; + } + + SqlFunction.prototype.ref = function() { + return this.name; + }; + + SqlFunction.prototype.compile = function(d) { + return "" + this.name + (d.compile(this.arglist)); + }; + + SqlFunction.prototype.toJSON = function() { + return merge(SqlFunction.__super__.toJSON.apply(this, arguments), { + name: this.name, + arglist: this.arglist + }); + }; + + return SqlFunction; + +})(Node); + +FunctionAlias = (function(_super) { + var shouldRenderFull; + + __extends(FunctionAlias, _super); + + function FunctionAlias() { + return FunctionAlias.__super__.constructor.apply(this, arguments); + } + + FunctionAlias.patch(SqlFunction); + + shouldRenderFull = function(parents) { + if (parents.some(function(it) { + return it instanceof Column; + })) { + return false; + } + return parents.some(function(node) { + return node instanceof ColumnSet || node instanceof RelationSet; + }); + }; + + FunctionAlias.prototype.compile = function(dialect, parents) { + if (shouldRenderFull(parents)) { + return dialect.compile(this.obj) + " AS " + dialect.quote(this.alias); + } else { + return dialect.quote(this.alias); + } + }; + + return FunctionAlias; + +})(AbstractAlias); + +Parameter = (function(_super) { + + __extends(Parameter, _super); + + function Parameter() { + return Parameter.__super__.constructor.apply(this, arguments); + } + + /* + Like a ValueNode, but will render as a bound parameter place-holder + (e.g. ``$1``) and it's value will be collected by the dialect when compiling. + */ + + + Parameter.prototype.compile = function(dialect) { + return dialect.parameter(this.value); + }; + + return Parameter; + +})(ValueNode); + +Relation = (function(_super) { + + __extends(Relation, _super); + + function Relation() { + return Relation.__super__.constructor.apply(this, arguments); + } + + /* + A relation node represents a table name or alias in a statement. + */ + + + Relation.prototype.ref = function() { + /* + Return the table name. Aliased tables return the alias name. + */ + return this.value; + }; + + Relation.prototype.project = function(field) { + /* Return a new :class:`nodes::Column` of `field` from this table. + */ + return new Column(this, toField(field)); + }; + + return Relation; + +})(Identifier); + +RelationAlias = (function(_super) { + + __extends(RelationAlias, _super); + + /* An aliased :class:`nodes::Relation` + */ + + + function RelationAlias() { + return RelationAlias.__super__.constructor.apply(this, arguments); + } + + RelationAlias.patch(Relation); + + RelationAlias.prototype.project = function(field) { + return Relation.prototype.project.call(this, field); + }; + + RelationAlias.prototype.compile = function(dialect, parents) { + if (parents.some(function(n) { + return n instanceof Column; + })) { + return dialect.quote(this.alias); + } else { + return RelationAlias.__super__.compile.apply(this, arguments); + } + }; + + return RelationAlias; + +})(AbstractAlias); + +Field = (function(_super) { + + __extends(Field, _super); + + /* A column name + */ + + + function Field() { + return Field.__super__.constructor.apply(this, arguments); + } + + return Field; + +})(Identifier); + +Column = (function(_super) { + var Alias; + + __extends(Column, _super); + + /* + Includes :class:`nodes::ComparableMixin` + */ + + + Column.unmarshal = function(data, recur) { + return new this(recur(data.nodes[0]), recur(data.nodes[1])); + }; + + function Column(source, field) { + this.source = source; + this.field = field; + Column.__super__.constructor.call(this, [this.source, this.field], '.'); + } + + Column.prototype.rel = function() { + return this.source; + }; + + Column.prototype.as = function(alias) { + /* Return an aliased version of this column. + */ + return new Alias(this, alias); + }; + + Column.Alias = Alias = (function(_super1) { + + __extends(Alias, _super1); + + function Alias() { + return Alias.__super__.constructor.apply(this, arguments); + } + + /* An aliased :class:`nodes::Column` + */ + + + Alias.prototype.rel = function() { + return this.obj.rel(); + }; + + Alias.prototype.compile = function(dialect, parents) { + var node, _k, _len2; + for (_k = 0, _len2 = parents.length; _k < _len2; _k++) { + node = parents[_k]; + if (node instanceof ColumnSet) { + return dialect.compile(this.obj) + " AS " + dialect.quote(this.alias); + } + } + return dialect.quote(this.alias); + }; + + return Alias; + + })(AbstractAlias); + + return Column; + +})(FixedNodeSet); + +Limit = (function(_super) { + + __extends(Limit, _super); + + function Limit() { + return Limit.__super__.constructor.apply(this, arguments); + } + + Limit.prototype.compile = function() { + if (this.value) { + return "LIMIT " + this.value; + } else { + return ""; + } + }; + + return Limit; + +})(IntegerNode); + +Offset = (function(_super) { + + __extends(Offset, _super); + + function Offset() { + return Offset.__super__.constructor.apply(this, arguments); + } + + Offset.prototype.compile = function() { + if (this.value) { + return "OFFSET " + this.value; + } else { + return ""; + } + }; + + return Offset; + +})(IntegerNode); + +Binary = (function(_super) { + + __extends(Binary, _super); + + Binary.unmarshal = function(data, recur) { + return new this(recur(data.left), recur(data.op), recur(data.right)); + }; + + function Binary(left, op, right) { + this.left = left; + this.op = op; + this.right = right; + Binary.__super__.constructor.call(this, [this.left, this.op, this.right], ' '); + } + + Binary.prototype.and = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new And([this].concat(__slice.call(args))); + }; + + Binary.prototype.or = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new Or([this].concat(__slice.call(args))); + }; + + Binary.prototype.compile = function(dialect) { + return [dialect.compile(this.left), dialect.operator(this.op), dialect.compile(this.right)].join(' '); + }; + + Binary.prototype.toJSON = function() { + return merge(Node.prototype.toJSON.call(this), { + left: this.left.toJSON(), + op: this.op, + right: this.right.toJSON() + }); + }; + + return Binary; + +})(FixedNodeSet); + +Tuple = (function(_super) { + + __extends(Tuple, _super); + + function Tuple() { + return Tuple.__super__.constructor.apply(this, arguments); + } + + Tuple.prototype.glue = ', '; + + return Tuple; + +})(ParenthesizedNodeSet); + +ColumnSet = (function(_super) { + + __extends(ColumnSet, _super); + + function ColumnSet() { + return ColumnSet.__super__.constructor.apply(this, arguments); + } + + /* The list of projected columns in a query + */ + + + ColumnSet.prototype.glue = ', '; + + return ColumnSet; + +})(NodeSet); + +Returning = (function(_super) { + + __extends(Returning, _super); + + function Returning() { + return Returning.__super__.constructor.apply(this, arguments); + } + + Returning.extend = function(klazz) { + return klazz.prototype.addReturning = function(cols) { + var col, _k, _len2; + for (_k = 0, _len2 = cols.length; _k < _len2; _k++) { + col = cols[_k]; + this.returning.addNode(toField(col)); + } + return null; + }; + }; + + Returning.prototype.compile = function() { + var string; + if (string = Returning.__super__.compile.apply(this, arguments)) { + return "RETURNING " + string; + } else { + return ""; + } + }; + + return Returning; + +})(ColumnSet); + +Distinct = (function(_super) { + + __extends(Distinct, _super); + + function Distinct(enable) { + this.enable = enable != null ? enable : false; + Distinct.__super__.constructor.apply(this, arguments); + } + + Distinct.prototype.compile = function(dialect) { + if (!this.enable) { + return ''; + } else if (this.nodes.length) { + return "DISTINCT(" + Distinct.__super__.compile.apply(this, arguments) + ")"; + } else { + return 'DISTINCT'; + } + }; + + return Distinct; + +})(ColumnSet); + +SelectColumnSet = (function(_super) { + + __extends(SelectColumnSet, _super); + + function SelectColumnSet() { + return SelectColumnSet.__super__.constructor.apply(this, arguments); + } + + SelectColumnSet.prototype.prune = function(predicate) { + /* + Recurse over child nodes, removing all Column nodes that match the + predicate. + */ + return this.nodes = this.nodes.filter(function(n) { + return !predicate(n); + }); + }; + + SelectColumnSet.prototype.compile = function(dialect) { + if (!this.nodes.length) { + return '*'; + } else { + return SelectColumnSet.__super__.compile.apply(this, arguments); + } + }; + + return SelectColumnSet; + +})(ColumnSet); + +RelationSet = (function(_super) { + + __extends(RelationSet, _super); + + function RelationSet() { + return RelationSet.__super__.constructor.apply(this, arguments); + } + + /* + Manages a set of relations and exposes methods to find them by alias. + */ + + + RelationSet.prototype.addNode = function(node) { + if (!this.first) { + this.relsByName = {}; + this.nodes.push(node); + return this.first = this.active = this.relsByName[node.ref()] = node; + } else { + RelationSet.__super__.addNode.apply(this, arguments); + return this.active = this.relsByName[node.ref()] = node.relation; + } + }; + + RelationSet.prototype.get = function(name, strict) { + var found; + if (strict == null) { + strict = true; + } + if ('string' !== typeof name) { + name = name.ref(); + } + found = this.relsByName[name]; + if (strict && !found) { + throw new Error("No such relation " + name + " in " + (Object.keys(this.relsByName))); + } + return found; + }; + + RelationSet.prototype["switch"] = function(name) { + return this.active = this.get(name); + }; + + RelationSet.prototype.compile = function(dialect) { + var string; + if (string = RelationSet.__super__.compile.apply(this, arguments)) { + return "FROM " + string; + } else { + return ""; + } + }; + + return RelationSet; + +})(NodeSet); + +Join = (function(_super) { + var JOIN, ON; + + __extends(Join, _super); + + JOIN = new ValueNode('JOIN'); + + ON = new ValueNode('ON'); + + Join.unmarshal = function(data, recur) { + var clause, join, nodes, _k, _len2, _ref2; + nodes = data.nodes; + join = new this(recur(nodes[0]), recur(nodes[2])); + _ref2 = nodes.slice(4); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + clause = _ref2[_k]; + join.on(clause); + } + return join; + }; + + function Join(type, relation) { + var nodes; + this.type = type; + this.relation = relation; + nodes = [this.type, JOIN, this.relation]; + Join.__super__.constructor.call(this, nodes); + } + + Join.prototype.on = function(clause) { + if (this.nodes.length < 4) { + this.nodes.push(ON); + } + return this.nodes.push(clause); + }; + + Join.prototype.ref = function() { + return this.relation.ref(); + }; + + return Join; + +})(FixedNodeSet); + +Where = (function(_super) { + + __extends(Where, _super); + + function Where() { + return Where.__super__.constructor.apply(this, arguments); + } + + Where.prototype.glue = ' AND '; + + Where.prototype.compile = function(dialect) { + var string; + if (string = Where.__super__.compile.apply(this, arguments)) { + return "WHERE " + string; + } else { + return ""; + } + }; + + return Where; + +})(NodeSet); + +Or = (function(_super) { + + __extends(Or, _super); + + function Or() { + return Or.__super__.constructor.apply(this, arguments); + } + + Or.prototype.glue = ' OR '; + + Or.prototype.and = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new And([this].concat(__slice.call(args))); + }; + + Or.prototype.or = function() { + var arg, args, ret, _k, _len2; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + ret = this.copy(); + for (_k = 0, _len2 = args.length; _k < _len2; _k++) { + arg = args[_k]; + ret.addNode(arg); + } + return ret; + }; + + return Or; + +})(ParenthesizedNodeSet); + +And = (function(_super) { + + __extends(And, _super); + + function And() { + return And.__super__.constructor.apply(this, arguments); + } + + And.prototype.glue = ' AND '; + + And.prototype.and = function() { + var arg, args, ret, _k, _len2; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + ret = this.copy(); + for (_k = 0, _len2 = args.length; _k < _len2; _k++) { + arg = args[_k]; + ret.addNode(arg); + } + return ret; + }; + + And.prototype.or = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return new Or([this].concat(__slice.call(args))); + }; + + return And; + +})(ParenthesizedNodeSet); + +GroupBy = (function(_super) { + + __extends(GroupBy, _super); + + function GroupBy() { + return GroupBy.__super__.constructor.apply(this, arguments); + } + + GroupBy.prototype.glue = ', '; + + GroupBy.prototype.compile = function(dialect) { + var string; + if (string = GroupBy.__super__.compile.apply(this, arguments)) { + return "GROUP BY " + string; + } else { + return ""; + } + }; + + return GroupBy; + +})(NodeSet); + +Having = (function(_super) { + + __extends(Having, _super); + + function Having() { + return Having.__super__.constructor.apply(this, arguments); + } + + Having.prototype.glue = ' AND '; + + Having.prototype.compile = function(dialect) { + var string; + if (string = Having.__super__.compile.apply(this, arguments)) { + return "HAVING " + string; + } else { + return ""; + } + }; + + return Having; + +})(NodeSet); + +OrderBy = (function(_super) { + + __extends(OrderBy, _super); + + function OrderBy(orderings) { + OrderBy.__super__.constructor.call(this, orderings, ', '); + } + + OrderBy.prototype.compile = function(dialect) { + var string; + if (string = OrderBy.__super__.compile.apply(this, arguments)) { + return "ORDER BY " + string; + } else { + return ""; + } + }; + + return OrderBy; + +})(NodeSet); + +Ordering = (function(_super) { + + __extends(Ordering, _super); + + function Ordering(projection, direction) { + if (typeof direction === 'string') { + direction = new ValueNode(direction); + } + Ordering.__super__.constructor.call(this, [projection, direction]); + } + + return Ordering; + +})(FixedNodeSet); + +Select = (function(_super) { + + __extends(Select, _super); + + /* + The root node of a SELECT query + */ + + + function Select() { + return Select.__super__.constructor.apply(this, arguments); + } + + Select.prefix = 'SELECT '; + + Select.structure([['distinct', Distinct], ['projections', SelectColumnSet], ['relations', RelationSet], ['where', Where], ['groupBy', GroupBy], ['having', Having], ['orderBy', OrderBy], ['limit', Limit], ['offset', Offset]]); + + Select.prototype.initialize = function(opts) { + this.projections; + if (opts.table) { + return this.relations.addNode(toRelation(opts.table)); + } + }; + + return Select; + +})(Statement); + +Update = (function(_super) { + var UpdateSet; + + __extends(Update, _super); + + /* + The root node of an UPDATE query + */ + + + function Update() { + return Update.__super__.constructor.apply(this, arguments); + } + + Update.UpdateSet = UpdateSet = (function(_super1) { + + __extends(UpdateSet, _super1); + + function UpdateSet(nodes) { + UpdateSet.__super__.constructor.call(this, nodes, ', '); + } + + UpdateSet.prototype.compile = function(dialect) { + var string; + if (string = UpdateSet.__super__.compile.apply(this, arguments)) { + return "SET " + string; + } else { + return ""; + } + }; + + return UpdateSet; + + })(NodeSet); + + Update.prefix = 'UPDATE '; + + Update.structure([['relation', Relation], ['updates', UpdateSet], ['orderBy', OrderBy], ['limit', Limit], ['fromList', RelationSet], ['where', Where], ['returning', Returning]]); + + Returning.extend(Update); + + Update.prototype.initialize = function(opts) { + return this.relation = toRelation(opts.table); + }; + + return Update; + +})(Statement); + +Insert = (function(_super) { + var ColumnList, InsertData, valOrDefault; + + __extends(Insert, _super); + + /* + The root node of an INSERT query + */ + + + function Insert() { + return Insert.__super__.constructor.apply(this, arguments); + } + + Insert.InsertData = InsertData = (function(_super1) { + + __extends(InsertData, _super1); + + function InsertData() { + return InsertData.__super__.constructor.apply(this, arguments); + } + + InsertData.prototype.glue = ', '; + + InsertData.prototype.compile = function(dialect) { + var string; + if (string = InsertData.__super__.compile.apply(this, arguments)) { + return "VALUES " + string; + } else { + return ""; + } + }; + + return InsertData; + + })(NodeSet); + + Insert.ColumnList = ColumnList = (function(_super1) { + + __extends(ColumnList, _super1); + + function ColumnList() { + return ColumnList.__super__.constructor.apply(this, arguments); + } + + return ColumnList; + + })(Tuple); + + Insert.prefix = 'INSERT INTO '; + + Insert.structure([['relation', Relation], ['columns', ColumnList], ['data', InsertData], ['returning', Returning]]); + + Returning.extend(Insert); + + Insert.prototype.initialize = function(opts) { + var _ref2; + if (!((_ref2 = opts.fields) != null ? _ref2.length : void 0)) { + throw new Error("Column list is required when constructing an INSERT"); + } + this.columns = new ColumnList(opts.fields.map(toField)); + return this.relation = toRelation(opts.table); + }; + + Insert.prototype.addRow = function(row) { + if (this.data instanceof Select) { + throw new Error("Cannot add rows when inserting from a SELECT"); + } + if (Array.isArray(row)) { + return this.addRowArray(row); + } else { + return this.addRowObject(row); + } + }; + + Insert.prototype.addRowArray = function(row) { + var count, message, params, v; + if (!(count = this.columns.nodes.length)) { + throw new Error("Must set column list before inserting arrays"); + } + if (row.length !== count) { + message = "Wrong number of values in array, expected " + this.columns.nodes; + throw new Error(message); + } + params = (function() { + var _k, _len2, _results; + _results = []; + for (_k = 0, _len2 = row.length; _k < _len2; _k++) { + v = row[_k]; + if (v instanceof Node) { + _results.push(v); + } else { + _results.push(new Parameter(v)); + } + } + return _results; + })(); + return this.data.addNode(new Tuple(params)); + }; + + Insert.prototype.addRowObject = function(row) { + /* + Add a row from an object. This will set the column list of the query if it + isn't set yet. If it `is` set, then only keys matching the existing column + list will be inserted. + */ + return this.addRowArray(this.columns.nodes.map(valOrDefault.bind(row))); + }; + + valOrDefault = function(field) { + var key; + key = field.value; + if (this.hasOwnProperty(key)) { + return this[key]; + } else { + return CONST_NODES.DEFAULT; + } + }; + + Insert.prototype.from = function(query) { + if (!(query instanceof Select)) { + throw new Error("Can only insert from a SELECT"); + } + return this.data = query; + }; + + return Insert; + +})(Statement); + +Delete = (function(_super) { + + __extends(Delete, _super); + + /* + The root node of a DELETE query + */ + + + function Delete() { + return Delete.__super__.constructor.apply(this, arguments); + } + + Delete.prefix = 'DELETE '; + + Delete.structure([['relations', RelationSet], ['where', Where], ['orderBy', OrderBy], ['limit', Limit], ['returning', Returning]]); + + Returning.extend(Delete); + + Delete.prototype.initialize = function(opts) { + return this.relations.addNode(toRelation(opts.table)); + }; + + return Delete; + +})(Statement); + +ComparableMixin = (function() { + /* + A mixin that adds comparison methods to a class. Each of these comparison + methods will yield a new AST node comparing the invocant to the argument. + */ + + function ComparableMixin() {} + + ComparableMixin.patch = function(klazz) { + var k, v, _ref2, _results; + _ref2 = this.prototype; + _results = []; + for (k in _ref2) { + v = _ref2[k]; + _results.push(klazz.prototype[k] = v); + } + return _results; + }; + + ComparableMixin.prototype.eq = function(other) { + /* ``this = other`` + */ + return this.compare('=', other); + }; + + ComparableMixin.prototype.ne = function(other) { + /* ``this != other`` + */ + return this.compare('!=', other); + }; + + ComparableMixin.prototype.gt = function(other) { + /* ``this > other`` + */ + return this.compare('>', other); + }; + + ComparableMixin.prototype.lt = function(other) { + /* ``this < other`` + */ + return this.compare('<', other); + }; + + ComparableMixin.prototype.lte = function(other) { + /* ``this <= other`` + */ + return this.compare('<=', other); + }; + + ComparableMixin.prototype.gte = function(other) { + /* ``this >= other`` + */ + return this.compare('>=', other); + }; + + ComparableMixin.prototype.like = function(other) { + return this.compare('LIKE', other); + }; + + ComparableMixin.prototype.is = function(other) { + return this.compare('IS', other != null ? other : CONST_NODES.NULL); + }; + + ComparableMixin.prototype.isNot = function(other) { + return this.compare('IS NOT', other != null ? other : CONST_NODES.NULL); + }; + + ComparableMixin.prototype["in"] = function(other) { + return this.compare('IN', other); + }; + + ComparableMixin.prototype.notIn = function(other) { + return this.compare('NOT IN', other); + }; + + ComparableMixin.prototype.compare = function(op, other) { + /* ``this op other`` **DANGER** `op` is **NOT** escaped! + */ + return new Binary(this, op, toParam(other)); + }; + + return ComparableMixin; + +})(); + +_ref2 = [TextNode, SqlFunction, SqlFunction.Alias, Column, Column.Alias, Tuple]; +for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + ctor = _ref2[_k]; + ComparableMixin.patch(ctor); +} + +toParam = function(it) { + /* + Return a Node that can be used as a parameter. + + * :class:`queries/select::SelectQuery` instances will be treated as + un-named sub queries, + * Node instances will be returned unchanged. + * Arrays will be turned into a :class:`nodes::Tuple` instance. + + All other types will be wrapped in a :class:`nodes::Parameter` instance. + */ + + var SelectQuery; + SelectQuery = require('./queries/select'); + if ((it != null ? it.constructor : void 0) === SelectQuery) { + return new Tuple([it.q]); + } else if (it instanceof Node) { + return it; + } else if (Array.isArray(it)) { + return new Tuple(it.map(toParam)); + } else { + return new Parameter(it); + } +}; + +toRelation = function(it) { + /* + Transform ``it`` into a :class:`nodes::Relation` instance. + + This accepts `strings, ``Relation`` and ``Alias`` instances, and objects with + a single key-value pair, which will be turned into an ``Alias`` instance. + + Examples:: + + toRelation('table1') == new Relation('table1') + toRelation(t1: 'table1') == new Alias(new Relation('table1'), 't1') + + **Throws Errors** if the input is not valid. + */ + + var alias; + switch (it.constructor) { + case Relation: + case Relation.Alias: + case SqlFunction: + case SqlFunction.Alias: + return it; + case String: + return new Relation(it); + case Object: + if (alias = getAlias(it)) { + return toRelation(it[alias]).as(alias); + } else { + throw new Error("Can't make relation out of " + it); + } + break; + default: + throw new Error("Can't make relation out of " + it); + } +}; + +toField = function(it) { + if (typeof it === 'string') { + return new Field(it); + } else if (it instanceof Field) { + return it; + } else { + throw new Error("Can't make a field out of " + it); + } +}; + +toColumn = function(relation, field) { + /* + Create a new :class:`nodes::Column` instance. + + The first argument is optional and specifies a table (or alias) name. + Alternatively, you can specify the relation name and field with a single + dot-separated string:: + + toColumn('departments.name') == toColumn('departments', 'name') + + Either argument can be an pre-constructed node object (of the correct type). + */ + + var parts; + if (field != null) { + return new Column(toRelation(relation), toField(field)); + } else if (typeof relation === 'string') { + parts = relation.split('.'); + if (parts.length === 2) { + return new Column(toRelation(parts[0]), toField(parts[1])); + } + } + throw new Error("Can't make projection from object: " + relation); +}; + +toProjection = toColumn; + +sqlFunction = function(name, args) { + /* + Create a new SQL function call node. For example:: + + count = g.sqlFunction('count', [g.text('*')]) + */ + return new SqlFunction(name, new Tuple(args.map(toParam))); +}; + +func = function(name) { + /* + Create a factory for calling the given SQL function. Example:: + + count = g.func('count') + count(g.text('*')) + + The returned factory accepts any number of parameters:: + + substringIndex = g.func('SUBSTRING_INDEX') + substringIndex(g.text('mycol'), '-', 1) # SUBSTRING_INDEX(mycol, '-', 1) + */ + return function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return sqlFunction(name, args); + }; +}; + +getAlias = function(o) { + /* + Check if ``o`` is an object literal representing an alias, and return the + alias name if it is. + */ + + var keys; + if ('object' === typeof o) { + keys = Object.keys(o); + if (keys.length === 1) { + return keys[0]; + } + } + return null; +}; + +text = function(rawSQL, bindVals) { + /* + Construct a node with a raw SQL string and (optionally) parameters. Useful for + when you want to construct a query that is difficult or impossible with the + normal APIs. [#]_ + + To use bound parameters in the SQL string, use ``$`` prefixed names, and + pass a ``bindVals`` argument with corresponding property names. For example, + :meth:`~queries/sud::SUDQuery.where` doesn't (currently) support the SQL + ``BETWEEN`` operator, but if you needed it, you could use ``text``:: + + function peopleInWeightRange (min, max, callback) { + return select('people') + .where(text("weight BETWEEN $min AND $max", {min: min, max: max})) + .execute(callback) + } + + Because javascript doesn't distinguish between array indexing and property + access, it can be more clear to use numbered parameters for such short + snippets:: + + function peopleInWeightRange (min, max, callback) { + return select('people') + .where(text("weight BETWEEN $0 AND $1", [min, max])) + .execute(callback) + } + + .. [#] If you find yourself using this function often, please `open an issue`_ + on Github with details on your use case so `gesundheit` can support it + more elegantly. + + .. _open an issue: https://github.com/BetSmartMedia/gesundheit/issues/new?title=I%20use%20text()%20for%20blah + */ + return new TextNode(rawSQL, bindVals); +}; + +binaryOp = function(left, op, right) { + /* + Create a new :class:`nodes::Binary` node:: + + binaryOp('hstore_column', '->', toParam(y)) + # hstore_column -> ? + + This is for special cases, normally you want to use the methods from + :class:`nodes::ComparableMixin`. + */ + return new Binary(left, op, right); +}; + +Prefixed = (function(_super) { + + __extends(Prefixed, _super); + + function Prefixed(prefix, node) { + this.prefix = prefix; + this.node = node; + } + + Prefixed.prototype.compile = function() { + return this.prefix + this.node.compile.apply(this.node, arguments); + }; + + return Prefixed; + +})(ValueNode); + +exists = function(subquery) { + /* Create an ``EXISTS ()`` node for `where` + */ + return new Prefixed('EXISTS ', new Tuple([subquery.q || subquery])); +}; + +notExists = function(subquery) { + /* Create a ``NOT EXISTS ()`` node for `where` + */ + return new Prefixed('NOT EXISTS ', new Tuple([subquery.q || subquery])); +}; + +tuple = function(input) { + /* + Create a new Tuple from an array of nodes. Any item in the array that is + **not** an `instanceof Node` will be turned into a parameter with + :func:`nodes::toParam`. + */ + return new Tuple(input.map(toParam)); +}; + +module.exports = { + CONST_NODES: CONST_NODES, + JOIN_TYPES: JOIN_TYPES, + binaryOp: binaryOp, + exists: exists, + func: func, + getAlias: getAlias, + notExists: notExists, + sqlFunction: sqlFunction, + text: text, + toField: toField, + toParam: toParam, + toColumn: toColumn, + toProjection: toProjection, + toRelation: toRelation, + tuple: tuple, + Node: Node, + ValueNode: ValueNode, + IntegerNode: IntegerNode, + Identifier: Identifier, + JoinType: JoinType, + NodeSet: NodeSet, + FixedNodeSet: FixedNodeSet, + Statement: Statement, + ParenthesizedNodeSet: ParenthesizedNodeSet, + TextNode: TextNode, + TextAlias: TextAlias, + SqlFunction: SqlFunction, + FunctionAlias: FunctionAlias, + Parameter: Parameter, + Relation: Relation, + RelationAlias: Relation.Alias, + Field: Field, + Column: Column, + ColumnAlias: Column.Alias, + Limit: Limit, + Offset: Offset, + Binary: Binary, + Tuple: Tuple, + ColumnSet: ColumnSet, + Returning: Returning, + Distinct: Distinct, + SelectColumnSet: SelectColumnSet, + RelationSet: RelationSet, + Join: Join, + Where: Where, + Or: Or, + And: And, + GroupBy: GroupBy, + OrderBy: OrderBy, + Ordering: Ordering, + Select: Select, + Update: Update, + UpdateSet: Update.UpdateSet, + Insert: Insert, + ColumnList: Insert.ColumnList, + InsertData: Insert.InsertData, + Delete: Delete, + ComparableMixin: ComparableMixin +}; + +unmarshal = require('./unmarshal')(); + +copy = function(it) { + var c, k, v; + if (!it) { + return it; + } + switch (it.constructor) { + case String: + case Number: + case Boolean: + return it; + case Array: + return it.map(copy); + case Object: + c = {}; + for (k in it) { + v = it[k]; + c[k] = copy(v); + } + return c; + default: + if (it.copy != null) { + return it.copy(); + } else { + throw new Error("Don't know how to copy " + it); + } + } +}; + +merge = function(dest, src) { + var k, v; + for (k in src) { + v = src[k]; + dest[k] = v; + } + return dest; +}; + +},{"./queries/select":13,"./unmarshal":16}],8:[function(require,module,exports){ +var process=require("__browserify_process");// Generated by CoffeeScript 1.4.0 +var BaseQuery, EventEmitter, assert, fluid, inspect, method, toRelation, _i, _len, _ref, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +inspect = require('util').inspect; + +EventEmitter = require('events').EventEmitter; + +toRelation = require('../nodes').toRelation; + +assert = require('assert'); + +module.exports = BaseQuery = (function(_super) { + + __extends(BaseQuery, _super); + + /* + The base class for all queries. While this class itself is not part of + gesundheits public API, the methods defined on it are. + */ + + + BaseQuery.rootNode = null; + + BaseQuery.unmarshal = function(data, recur) { + var query; + query = new this; + query.q = recur(data.q); + return query; + }; + + function BaseQuery(engine, opts) { + if (opts == null) { + opts = {}; + } + /* + :param engine: The engine the query will be bound to. + + :param opts.table: + Any object that can be converted by :func:`nodes::toRelation`. + */ + + this.bind(engine); + this.q = opts.rootNode || new this.constructor.rootNode(opts); + } + + BaseQuery.prototype.copy = function(fn) { + /* Instantiate a new query with a deep copy of this ones AST + */ + + var query; + query = new this.constructor(this.engine, { + rootNode: this.q.copy() + }); + if (fn) { + return query.visit(fn); + } else { + return query; + } + }; + + BaseQuery.prototype.visit = function(fn) { + /* + Call the given function in the context of this query. This is useful with + query factory functions where you can use it as a sort-of-DSL:: + + SELECT('people', ['name'], function(q) { + // this === q + this.join('addresses', { + on: {person_id: q.project('people', 'id')}, + fields: ['city', 'region'] + }) + }) + */ + return fn.call(this, this); + }; + + BaseQuery.prototype.bind = function(engine) { + /* + Bind this query object to a new engine. + If no argument is given the query will be bound to the default engine. + */ + + var oldEngine, _base, _ref, _ref1; + oldEngine = this.engine; + this.engine = engine || require('../index').defaultEngine; + if (this.engine !== oldEngine) { + if (oldEngine != null) { + if (typeof oldEngine.unextendQuery === "function") { + oldEngine.unextendQuery(this); + } + } + if (typeof (_base = this.engine).extendQuery === "function") { + _base.extendQuery(this); + } + } + assert((_ref = this.engine) != null ? _ref.query : void 0, "Engine has no query method: " + (inspect(this.engine))); + return assert((_ref1 = this.engine) != null ? _ref1.compile : void 0, "Engine has no compile method: " + (inspect(this.engine))); + }; + + BaseQuery.prototype.render = function() { + /* + Render the query to a SQL string. + */ + return this.compile()[0]; + }; + + BaseQuery.prototype.compile = function() { + /* + Compile this query object, returning a SQL string and parameter array. + */ + return this.engine.compile(this.q); + }; + + BaseQuery.prototype.execute = function(cb) { + /* + Execute the query using ``@engine`` and return a `QueryAdapter`. + + :param cb: An (optional) node-style callback that will be called with any + errors and/or the query results. If no callback is given, an `AnyDB Query`_ + will be returned. + + .. _AnyDB Query: https://github.com/grncdr/node-any-db/blob/master/DESIGN.md#query-adapters + */ + + var args, emitter; + try { + args = this.compile(); + args.push(cb); + } catch (err) { + emitter = new EventEmitter; + process.nextTick(function() { + if (cb) { + return cb(err); + } else { + return emitter.emit('error', err); + } + }); + return emitter; + } + return this.engine.query.apply(this.engine, args); + }; + + BaseQuery.prototype.toString = function() { + return this.render(); + }; + + BaseQuery.prototype.toJSON = function() { + return { + _type: this.constructor.name, + q: this.q.toJSON() + }; + }; + + return BaseQuery; + +})(EventEmitter); + +fluid = require('../decorators/fluid'); + +_ref = ['bind', 'visit']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + method = _ref[_i]; + BaseQuery.prototype[method] = fluid(BaseQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../index":6,"../nodes":7,"__browserify_process":27,"assert":17,"events":18,"util":22}],9:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var Delete, DeleteQuery, SUDQuery, returnable, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +SUDQuery = require('./sud'); + +returnable = require('./returnable'); + +Delete = require('../nodes').Delete; + +module.exports = DeleteQuery = (function(_super) { + + __extends(DeleteQuery, _super); + + /* Delete queries only add a 'returning' method to ``SUDQuery`` + */ + + + function DeleteQuery() { + return DeleteQuery.__super__.constructor.apply(this, arguments); + } + + DeleteQuery.rootNode = Delete; + + returnable(DeleteQuery); + + return DeleteQuery; + +})(SUDQuery); + +},{"../nodes":7,"./returnable":12,"./sud":14}],10:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +/* +The factory functions defined here create instances of the corresponding +`*Query` manager classes, which fit the following inheritance hierarchy: + + * BaseQuery + + * InsertQuery + + * SUDQuery + + * SelectQuery + + * UpdateQuery + + * DeleteQuery + +.. _query-factories: + +These functions are the same ones re-exported by the main gesundheit module +(where they bind queries to ``gesundheit.defaultEngine``), and attached to +engine/transaction objects (where they bind queries to the engine/transaction +they are called on). + +Each one accepts a table name or alias object (anything handled by +:func:`nodes::toRelation`), one or more extra parameters, and an optional +visitor callback as a final parameter that will be called with it's ``this`` +context set to the newly constructed query instance. +*/ + +var DELETE, DeleteQuery, INSERT, InsertQuery, SELECT, SelectQuery, UPDATE, UpdateQuery, maybeVisit; + +InsertQuery = require('./insert'); + +SelectQuery = require('./select'); + +UpdateQuery = require('./update'); + +DeleteQuery = require('./delete'); + +INSERT = function(table, fieldsOrRow) { + /* + Create a new :class:`queries/insert::InsertQuery` that will add rows to + ``table``. + + :param table: Name of the table that rows will be inserted into. + :param fieldsOrRow: Either an array of column names that will be inserted, or a + plain object representing a row of data to insert, in which case the keys + of the object will define the columns that are inserted. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + + .. warning:: + The column names passed in ``fields`` will be printed into the query + **unescaped** so do **not** use arbitrary input here. This is hopefully only temporary. + */ + + var fields, iq, row; + if (Array.isArray(fieldsOrRow)) { + fields = fieldsOrRow; + } else if (typeof fieldsOrRow === 'object') { + row = fieldsOrRow; + fields = Object.keys(row); + } + iq = new InsertQuery(this, { + table: table, + fields: fields + }); + if (row) { + iq.addRow(row); + } + return iq; +}; + +SELECT = function(table, fields) { + /* + Create a new :class:`queries/select::SelectQuery` selecting from ``table``. + + :param table: Name or alias object of the first table to select rows from. + More tables can be joined using :meth:`queries/select::SelectQuery.join`. + :param fields: (Optional) Fields to project from ``table``. If this is not + given, all fields (``*``) will be projected until + :meth:`queries/select::SelectQuery.fields` is called. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + + var query; + query = new SelectQuery(this, { + table: table + }); + if (fields != null) { + query.fields.apply(query, fields); + } + return query; +}; + +UPDATE = function(table) { + /* + Create a new :class:`queries/update::UpdateQuery` that will update ``table``. + + :param table: Name or alias of the table to update. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + return new UpdateQuery(this, { + table: table + }); +}; + +DELETE = function(table) { + /* + Create a new :class:`queries/delete::DeleteQuery` that will delete rows from + ``table``. + + :param table: Name or alias of the table to delete rows from. + :param visitor: (Optional) a function that will be called with it's context + set to the newly constructed query object. + */ + return new DeleteQuery(this, { + table: table + }); +}; + +exports.mixinFactoryMethods = function(invocant, getEngine) { + /* + Add wrappers methods for each of the query factory functions to ``invocant`` + using lower, UPPER, and Camel cases. The new methods will retrieve an engine + using ``getEngine`` and then create the query bound to that engine. + + If ``getEngine`` is not given, queries will be bound to ``invocant`` instead. + */ + + var factory, type, _fn, _ref; + if (getEngine == null) { + getEngine = function() { + return invocant; + }; + } + _ref = { + INSERT: INSERT, + SELECT: SELECT, + UPDATE: UPDATE, + DELETE: DELETE + }; + _fn = function(type, factory) { + var wrapper; + factory = maybeVisit(factory); + wrapper = function() { + return factory.apply(getEngine(), arguments); + }; + invocant[type] = wrapper; + invocant[type.toLowerCase()] = wrapper; + return invocant[type[0] + type.toLowerCase().substring(1)] = wrapper; + }; + for (type in _ref) { + factory = _ref[type]; + _fn(type, factory); + } + return invocant; +}; + +maybeVisit = function(func) { + return function() { + var a, cb; + a = [].slice.call(arguments); + if (typeof a[a.length - 1] === 'function') { + cb = a.pop(); + return func.apply(this, a).visit(cb); + } else { + return func.apply(this, a); + } + }; +}; + +},{"./delete":9,"./insert":11,"./select":13,"./update":15}],11:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var BaseQuery, Insert, InsertQuery, SelectQuery, fluid, method, returnable, toField, _i, _len, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +returnable = require('./returnable'); + +BaseQuery = require('./base'); + +SelectQuery = require('./select'); + +_ref = require('../nodes'), Insert = _ref.Insert, toField = _ref.toField; + +module.exports = InsertQuery = (function(_super) { + + __extends(InsertQuery, _super); + + /* + Insert queries are much simpler than most query types: they cannot join + multiple tables. + */ + + + function InsertQuery() { + return InsertQuery.__super__.constructor.apply(this, arguments); + } + + InsertQuery.rootNode = Insert; + + returnable(InsertQuery); + + InsertQuery.prototype.addRows = function(rows, variadic) { + /* Add multiple rows of data to the insert statement. + */ + + var row, _i, _len, _results; + if (variadic != null) { + console.warn("DEPRECATED: InsertQuery::addRows will not be variadic in a future release.", new Error().stack.split('\n').slice(1).join('\n')); + rows = Array.prototype.slice.call(arguments); + } + _results = []; + for (_i = 0, _len = rows.length; _i < _len; _i++) { + row = rows[_i]; + _results.push(this.q.addRow(row)); + } + return _results; + }; + + InsertQuery.prototype.addRow = function(row) { + /* Add a single row + */ + return this.q.addRow(row); + }; + + InsertQuery.prototype.from = function(query) { + /* Insert from a select query. + */ + return this.q.from(query.q || query); + }; + + return InsertQuery; + +})(BaseQuery); + +fluid = require('../decorators/fluid'); + +_ref1 = ['addRow', 'addRows', 'from', 'returning']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + InsertQuery.prototype[method] = fluid(InsertQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../nodes":7,"./base":8,"./returnable":12,"./select":13}],12:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var fluid, variadic; + +variadic = require('../decorators/variadic'); + +fluid = require('../decorators/fluid'); + +module.exports = function(klazz) { + return klazz.prototype.returning = fluid(variadic(function(cols) { + this.q.addReturning(cols); + return this; + })); +}; + +},{"../decorators/fluid":2,"../decorators/variadic":3}],13:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var And, JOIN_TYPES, Join, Node, SUDQuery, Select, SelectQuery, deprecate, fluid, getAlias, method, sqlFunction, toColumn, toRelation, variadic, _i, _j, _len, _len1, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +SUDQuery = require('./sud'); + +_ref = require('../nodes'), Node = _ref.Node, getAlias = _ref.getAlias, Select = _ref.Select, And = _ref.And, Join = _ref.Join, toRelation = _ref.toRelation, toColumn = _ref.toColumn, sqlFunction = _ref.sqlFunction, JOIN_TYPES = _ref.JOIN_TYPES; + +module.exports = SelectQuery = (function(_super) { + + __extends(SelectQuery, _super); + + /* + Adds a number of SELECT-specific methods to :class:`queries/sud::SUDQuery`, + such as `fields` and `groupBy` + */ + + + function SelectQuery() { + return SelectQuery.__super__.constructor.apply(this, arguments); + } + + SelectQuery.rootNode = Select; + + SelectQuery.prototype.fields = function(fields) { + /* + Adds one or more fields to the query. Fields can be strings (in which case + they will be passed to :meth:`queries/sud::SUDQuery.column`) or pre- + constructed nodes. (Such as those returned by ``column``). + + If no fields are given, clears all fields from the currently focused table. + + To alias a field, use an object with a single key where the key is the alias + name and the value is a string or node:: + + q.fields({employee_name: 'employees.name'}) + */ + + var alias, col, f, rel, _i, _len, + _this = this; + if (fields.length === 0) { + rel = this.q.relations.active; + this.q.projections.prune(function(p) { + return p.rel() === rel; + }); + return; + } + col = function(o) { + if (o instanceof Node) { + return o; + } else { + return _this.column(o); + } + }; + for (_i = 0, _len = fields.length; _i < _len; _i++) { + f = fields[_i]; + if (alias = getAlias(f)) { + f = f[alias]; + this.q.projections.addNode(col(f).as(alias)); + } else { + this.q.projections.addNode(col(f)); + } + } + return null; + }; + + SelectQuery.prototype.func = function(fun, args) { + /* + Adds a SQL function to the column list for the query. This can be an + aggregate function if you also use :meth:`queries/select::groupBy`. + + :param fun: name of SQL function. + :param args: arguments that will be passed to the function. Any argument + that is not a `Node` object will be converted into a bound parameter. + + Example:: + + # SELECT count(id) FROM t1 + select('t1', function (q) { q.func('count', q.c('id')) }) + + # SELECT count(id) AS "counter" FROM t1 + select('t1', function (q) { q.func({counter: 'count'}, q.c('id')) }) + */ + + var alias; + if (alias = getAlias(fun)) { + return this.q.projections.addNode(sqlFunction(fun[alias], args).as(alias)); + } else { + return this.q.projections.addNode(sqlFunction(fun, args)); + } + }; + + SelectQuery.prototype.distinct = function(bool) { + /* + Make this query DISTINCT on *all* fields. + */ + return this.q.distinct.enable = bool; + }; + + SelectQuery.prototype.join = function(table, opts) { + var fieldList, join, prefix, relation, type; + if (opts == null) { + opts = {}; + } + /* + Join another table to the query. + + :param table: A table name, or alias literal. An error will be thrown if + the table/alias name is not unique. See :func:`nodes::toRelation` for + more information on the many things ``table`` could be. + :param opts.on: + An object literal expressing join conditions. See + :meth:`queries/select::SelectQuery::where` for more. + :param opts.type: A join type constant (e.g. INNER, OUTER) + :param opts.fields: Columns to be selected from the newly joined table. + :param opts.prefixFields: If this is a string, it will be used to prefix + the field names given in ``opts.fields``. If this is a boolean ``true`` + then the joined table (or alias) name plus an underscore will be used + as the prefix. For example:: + + query.join({p: 'people'}, { + on: query.c('people.dep_id').eq(query.c('dep.id')), + fields: ['first_name', 'last_name'], + prefixFields: true + }) + + Will alias ``people.first_name AS p_first_name``. + */ + + relation = toRelation(table); + if (this.q.relations.get(relation, false)) { + throw new Error("Table/alias " + (relation.ref()) + " is not unique!"); + } + type = opts.type || JOIN_TYPES.INNER; + if (!(type instanceof JOIN_TYPES.INNER.constructor)) { + throw new Error("Invalid join type " + type + ", try the constant types exported in the base module (e.g. INNER)."); + } + join = new Join(type, relation); + this.q.relations.addNode(join); + if (opts.on) { + join.on(new And(this._makeClauses(opts.on))); + } + if ((fieldList = opts.fields) != null) { + if (opts.prefixFields) { + if (opts.prefixFields === true) { + prefix = relation.ref() + '_'; + } else { + prefix = opts.prefixFields; + } + fieldList = fieldList.map(function(f) { + return toColumn(relation, f).as(prefix + f); + }); + } + return this.fields(fieldList); + } + }; + + SelectQuery.prototype.ensureJoin = function(table, opts) { + var rel; + if (opts == null) { + opts = {}; + } + /* + The same as :meth:`join`, but will only join ``tbl`` if it is **not** + joined already. + */ + + rel = toRelation(table); + if (!this.q.relations.get(rel.ref(), false)) { + return this.join(rel, opts); + } + }; + + SelectQuery.prototype.focus = function(alias) { + /* + Make a different table "focused", this will use that table as the default + for the ``fields``, ``order`` and ``where`` methods. + + :param alias: The table/alias name to focus. If the table or alias is not + already part of the query an error will be thrown. + */ + return this.q.relations["switch"](alias); + }; + + SelectQuery.prototype.groupBy = function(fields) { + /* Add a GROUP BY to the query. + */ + + var field, _i, _len; + for (_i = 0, _len = fields.length; _i < _len; _i++) { + field = fields[_i]; + this.q.groupBy.addNode(this.column(field)); + } + return null; + }; + + SelectQuery.prototype.having = function(constraint) { + /* + This method works similarly to :meth:`queries/sud::SUDQuery.where`, but the + constraints are added the `HAVING` portion of a SQL clause. + */ + + var node, _i, _len, _ref1, _results; + _ref1 = this._makeClauses(constraint); + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + node = _ref1[_i]; + _results.push(this.q.having.addNode(node)); + } + return _results; + }; + + return SelectQuery; + +})(SUDQuery); + +fluid = require('../decorators/fluid'); + +variadic = require('../decorators/variadic'); + +deprecate = require('../decorators/deprecate'); + +_ref1 = ['fields', 'groupBy']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + SelectQuery.prototype[method] = variadic(SelectQuery.prototype[method]); +} + +_ref2 = ['distinct', 'fields', 'func', 'join', 'ensureJoin', 'focus', 'groupBy', 'having']; +for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + method = _ref2[_j]; + SelectQuery.prototype[method] = fluid(SelectQuery.prototype[method]); +} + +SelectQuery.prototype.field = SelectQuery.prototype.fields; + +SelectQuery.prototype.agg = deprecate.rename(SelectQuery.prototype.func, ".agg", ".func"); + +},{"../decorators/deprecate":1,"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./sud":14}],14:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var And, BaseQuery, CONST_NODES, Column, Node, Or, Ordering, SUDQuery, deprecate, fluid, method, nodes, toField, variadic, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +BaseQuery = require('./base'); + +nodes = require('../nodes'); + +Node = nodes.Node, And = nodes.And, Or = nodes.Or, Ordering = nodes.Ordering, Column = nodes.Column, CONST_NODES = nodes.CONST_NODES, toField = nodes.toField; + +module.exports = SUDQuery = (function(_super) { + + __extends(SUDQuery, _super); + + function SUDQuery() { + return SUDQuery.__super__.constructor.apply(this, arguments); + } + + /* + SUDQuery is the base class for SELECT, UPDATE, and DELETE queries. It adds + logic to :class:`queries/base::BaseQuery` for adding WHERE clauses, projecting + columns, ordering, limits, and offsets. + */ + + + SUDQuery.prototype.where = function(constraint) { + /* + Adds a WHERE clause to the query. This method accepts wide range of input + that can express very complex constraints. The examples below assume we are + starting with this simple select query: ``q = select('t1')`` + + The first kind of constraint is a comparison node as produced by the + :class:`nodes::ComparableMixin` methods on projected fields:: + + q.where(q.c('field1').eq(42)) + q.where(q.c('field2').gt(42)) + # WHERE t1.field1 = 42 AND t1.field2 > 42 + + We used an implied table name above, which is always the last table added to + the query or focused with :meth:`queries/sud::SUDQuery.focus`. If you want + to specify constraints on multiple tables at once (or just be more explicit) + you can also specify the relation for a field by prepending it to the field + name (e.g. ``q.c('t1.field1')``. See :meth:`queries/sud::SUDQuery.project` + for details. + + The second kind of constraint is an object literal where each key is a field + name and each value is a constraint. The last example expressed as a literal + object looks like this:: + + q.where({field1: 42, field2: {gt: 42}}) + # WHERE t1.field1 = 42 AND t1.field2 > 42 + + Internally this constructs the comparison nodes for you using a simple + transformation: each key is passed to :meth:`project` (meaning you can + specify the relation name as part of the key if you so desire) and each + value is either used as the argument to :meth:`nodes::ComparableMixin.eq` + or (in the case of object literals) converted into one or more calls to + the corresponding comparison methods. + + To compare two fields, use a projection as the value to be compared:: + + p = q.project.bind(q, 't1') + q.where({field1: {gt: p('field2')}}) + # WHERE t1.field1 > t1.field2 + + If you use either of the special keys ``'and'`` or ``'or'`` in an object, + the value will be treated as a nested set of constraints to be joined with + the corresponding SQL operator. This process is recursive so you can nest + constraints arbitrarily deep:: + + q.where({or: {a: 1, and: {b: 2, c: 3}}}) + # WHERE (t1.a = 1 OR (t1.b = 2 AND t1.c = 3)) + + You can also acheive the same effect by chaining method calls on comparison + nodes:: + + a = q.c('a') + b = q.c('b') + c = q.c('c') + q.where(a.eq(1).or(b.eq(2).and(c.eq(3)))) + # WHERE (t1.a = 1 OR (t1.b = 2 AND t1.c = 3)) + + If you have the need to mix both styles (or simply find it more readable, + You can use an array of constraints as the value for ``'or'`` or ``'and'``:: + + q.where({or: [{a: 1}, b.eq(2).and(c.eq(3))]}) + + Note that currently you **cannot** pass an object literal to the ``.and`` + and ``.or`` methods:: + + # Will not work!! + q.where(a.eq(1).or({b: 2, c: 3})) + + Finally, there are also shortcut methods :meth:`queries/sud::SUDQuery.and` + and :meth:`queries/sud::SUDQuery.or` that treat multiple arguments like an + array of constraints. + */ + + var node, _i, _len, _ref, _results; + _ref = this._makeClauses(constraint); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + _results.push(this.q.where.addNode(node)); + } + return _results; + }; + + SUDQuery.prototype._makeClauses = function(constraint) { + /* + Return an array of Binary, And, and Or nodes for this constraint object + */ + + var clauses, column, field, item, op, predicate, val, _i, _len; + clauses = []; + if (Array.isArray(constraint)) { + for (_i = 0, _len = constraint.length; _i < _len; _i++) { + item = constraint[_i]; + if (item instanceof Node) { + clauses.push(item); + } else { + clauses = clauses.concat(this._makeClauses(item)); + } + } + return clauses; + } + if (constraint instanceof Node) { + return [constraint]; + } + for (field in constraint) { + predicate = constraint[field]; + if (field === 'and') { + clauses.push(new And(this._makeClauses(predicate))); + } else if (field === 'or') { + clauses.push(new Or(this._makeClauses(predicate))); + } else { + column = this.column(field); + if (predicate === null) { + clauses.push(column.compare('IS', CONST_NODES.NULL)); + } else if (predicate.constructor === Object) { + for (op in predicate) { + val = predicate[op]; + clauses.push(column.compare(op, val)); + } + } else { + clauses.push(column.eq(predicate)); + } + } + } + return clauses; + }; + + SUDQuery.prototype.or = function(clauses) { + /* Shortcut for ``.where({or: clauses})`` + */ + return this.where({ + or: clauses + }); + }; + + SUDQuery.prototype.and = function(clauses) { + /* Shortcut for ``.where({and: clauses})`` + */ + return this.where({ + and: clauses + }); + }; + + SUDQuery.prototype.order = function(args) { + /* + Add one or more ORDER BY clauses to the query. + + Each ordering can either be a string, in which case it must be a valid-ish + SQL snippet like 'some_table.some_field DESC', (the field name and direction + will still be converted to AST nodes) or an object, in which case each key + will be treated as a field and each value as a direction. + */ + + var dir, direction, field, name, orderBy, orderings, rel, _i, _j, _len, _len1, _ref, _results; + rel = this.defaultRel(); + orderings = []; + for (_i = 0, _len = args.length; _i < _len; _i++) { + orderBy = args[_i]; + switch (orderBy.constructor) { + case String: + orderings.push(orderBy.split(' ')); + break; + case Object: + for (name in orderBy) { + dir = orderBy[name]; + orderings.push([name, dir]); + } + break; + default: + if (orderBy instanceof Node) { + this.q.orderBy.addNode(orderBy); + } else { + throw new Error("Can't turn " + orderBy + " into an ordering"); + } + } + } + _results = []; + for (_j = 0, _len1 = orderings.length; _j < _len1; _j++) { + _ref = orderings[_j], field = _ref[0], direction = _ref[1]; + direction = (function() { + switch ((direction || '').toLowerCase()) { + case 'asc': + case 'ascending': + return 'ASC'; + case 'desc': + case 'descending': + return 'DESC'; + case '': + return ''; + default: + throw new Error("Unsupported ordering direction " + direction); + } + })(); + _results.push(this.q.orderBy.addNode(new Ordering(this.column(field), direction))); + } + return _results; + }; + + SUDQuery.prototype.limit = function(l) { + /* Set the LIMIT on this query + */ + return this.q.limit.value = l; + }; + + SUDQuery.prototype.offset = function(l) { + /* Set the OFFSET of this query + */ + return this.q.offset.value = l; + }; + + SUDQuery.prototype.defaultRel = function() { + return this.q.relations.active; + }; + + SUDQuery.prototype.project = function() { + /* Backwards compatible alias for :meth:`queries/sud::SUDQuery.column` + */ + return this.column.apply(this, arguments); + }; + + SUDQuery.prototype.column = function(relation, field) { + /* + Return a :class:`nodes::Column` node representing ``.``. + + The first argument is optional and specifies a table or alias name referring + to a relation already joined to this query. If you don't specify a relation, + the table added or focused last will be used. Alternatively, you can specify + the relation name and field with a single dot-separated string:: + + q.column('departments.name') == q.column('departments', 'name') + + The returned object has a methods from :class:`nodes::ComparableMixin` that + create new comparison nodes usable in join conditions and where clauses:: + + # Find developers over the age of 45 + s = select('people', ['name']) + s.join('departments', on: {id: s.column('people', 'department_id')}) + s.where(s.column('departments', 'name').eq('development')) + s.where(s.column('people', 'age').gte(45)) + + ``project`` is also aliased as ``p`` for those who value brevity:: + + q.where(q.c('departments.name').eq('development')) + + .. note:: this means you *must* specify a relation name if you have a field + name with a dot in it, if you have dots in your column names, sorry. + */ + + var parts, proj, _ref; + if (field != null) { + field = toField(field); + if (typeof relation === 'string') { + return new Column(this.q.relations.get(relation), field); + } else { + relation = this.q.relations.get(toRelation(relation).ref()); + return new Column(relation, field); + } + } else if (typeof relation === 'string') { + parts = relation.split('.'); + if (parts.length === 2) { + return new Column(this.q.relations.get(parts[0]), toField(parts[1])); + } else { + return new Column(this.defaultRel(), toField(relation)); + } + } else if (relation instanceof Column) { + proj = relation; + this.q.relations.get((_ref = proj.source) != null ? _ref.ref() : void 0); + return proj; + } else { + throw new Error("Can't make a projection from object: " + relation); + } + }; + + SUDQuery.prototype.rel = function(alias) { + /* A shorthand way to get a relation by (alias) name + */ + return this.q.relations.get(alias); + }; + + return SUDQuery; + +})(BaseQuery); + +deprecate = require('../decorators/deprecate'); + +variadic = require('../decorators/variadic'); + +fluid = require('../decorators/fluid'); + +_ref = ['and', 'or', 'order']; +for (_i = 0, _len = _ref.length; _i < _len; _i++) { + method = _ref[_i]; + SUDQuery.prototype[method] = variadic(SUDQuery.prototype[method]); +} + +_ref1 = ['where', 'or', 'and', 'limit', 'offset', 'order']; +for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + method = _ref1[_j]; + SUDQuery.prototype[method] = fluid(SUDQuery.prototype[method]); +} + +_ref2 = ['p', 'project']; +for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + method = _ref2[_k]; + SUDQuery.prototype[method] = deprecate.rename(SUDQuery.prototype.column, method, ".column or .c"); +} + +SUDQuery.prototype.c = SUDQuery.prototype.column; + +},{"../decorators/deprecate":1,"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./base":8}],15:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var SUDQuery, Update, UpdateQuery, binaryOp, fluid, method, returnable, toField, toParam, variadic, _i, _len, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +returnable = require('./returnable'); + +SUDQuery = require('./sud'); + +_ref = require('../nodes'), Update = _ref.Update, binaryOp = _ref.binaryOp, toField = _ref.toField, toParam = _ref.toParam; + +module.exports = UpdateQuery = (function(_super) { + + __extends(UpdateQuery, _super); + + /* + The update query is a little underpowered right now, and can only handle + simple updates of a single table. + */ + + + function UpdateQuery() { + return UpdateQuery.__super__.constructor.apply(this, arguments); + } + + UpdateQuery.rootNode = Update; + + returnable(UpdateQuery); + + UpdateQuery.prototype.set = function(data) { + /* + Add fields to the SET portion of this query. + + :param data: An object mapping fields to values. The values will be passed + to :func:`nodes::toParam` to be converted into bound paramaeters. + */ + + var field, value, _results; + _results = []; + for (field in data) { + value = data[field]; + _results.push(this.q.updates.addNode(binaryOp(toField(field), '=', toParam(value)))); + } + return _results; + }; + + UpdateQuery.prototype.setNodes = function(nodes) { + /* Directly push one or more nodes into the SET portion of this query + */ + + var _ref1; + return (_ref1 = this.q.updates).push.apply(_ref1, nodes); + }; + + UpdateQuery.prototype.defaultRel = function() { + return this.q.relation; + }; + + return UpdateQuery; + +})(SUDQuery); + +fluid = require('../decorators/fluid'); + +variadic = require('../decorators/variadic'); + +UpdateQuery.prototype.setNodes = variadic(UpdateQuery.prototype.setNodes); + +_ref1 = ['set', 'setNodes', 'returning']; +for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + method = _ref1[_i]; + UpdateQuery.prototype[method] = fluid(UpdateQuery.prototype[method]); +} + +},{"../decorators/fluid":2,"../decorators/variadic":3,"../nodes":7,"./returnable":12,"./sud":14}],16:[function(require,module,exports){ +// Generated by CoffeeScript 1.4.0 +var unmarshal, unmarshallable; + +unmarshallable = Object.create(require('./nodes'), { + InsertQuery: { + value: require('./queries/insert') + }, + SelectQuery: { + value: require('./queries/select') + }, + UpdateQuery: { + value: require('./queries/update') + }, + DeleteQuery: { + value: require('./queries/delete') + } +}); + +unmarshal = null; + +module.exports = function(visitor, object) { + var path, recur; + path = []; + recur = function(object, k) { + var ctor, err, result, type, v, _ref; + if (k == null) { + k = ""; + } + if (typeof object !== 'object') { + return object; + } + path.push(k); + if (Array.isArray(object)) { + result = object.map(recur); + } else { + if (!(type = object._type)) { + result = {}; + for (k in object) { + v = object[k]; + result[k] = recur(v, k); + } + result; + + } else if (((_ref = (ctor = unmarshallable[type])) != null ? _ref.unmarshal : void 0) != null) { + if (visitor != null) { + if (typeof visitor.before === "function") { + visitor.before(object, path); + } + } + result = ctor.unmarshal(object, recur); + if (visitor != null) { + if (typeof visitor.after === "function") { + visitor.after(result, path); + } + } + } else { + err = new Error("Cannot unmarshall " + type + " @ " + (path.join('/'))); + err.path = path.slice(); + path = []; + throw err; + } + } + path.pop(k); + return result; + }; + if (arguments.length > 1) { + return recur(object); + } else { + return recur; + } +}; + +module.exports.allow = unmarshallable; + +},{"./nodes":7,"./queries/delete":9,"./queries/insert":11,"./queries/select":13,"./queries/update":15}],17:[function(require,module,exports){ +// UTILITY +var util = require('util'); +var Buffer = require("buffer").Buffer; +var pSlice = Array.prototype.slice; + +function objectKeys(object) { + if (Object.keys) return Object.keys(object); + var result = []; + for (var name in object) { + if (Object.prototype.hasOwnProperty.call(object, name)) { + result.push(name); + } + } + return result; +} + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.message = options.message; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (value === undefined) { + return '' + value; + } + if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (typeof value === 'function' || value instanceof RegExp) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (typeof s == 'string') { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +assert.AssertionError.prototype.toString = function() { + if (this.message) { + return [this.name + ':', this.message].join(' '); + } else { + return [ + this.name + ':', + truncate(JSON.stringify(this.actual, replacer), 128), + this.operator, + truncate(JSON.stringify(this.expected, replacer), 128) + ].join(' '); + } +}; + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!!!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (expected instanceof RegExp) { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail('Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail('Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +},{"buffer":24,"util":22}],18:[function(require,module,exports){ +var process=require("__browserify_process");if (!process.EventEmitter) process.EventEmitter = function () {}; + +var EventEmitter = exports.EventEmitter = process.EventEmitter; +var isArray = typeof Array.isArray === 'function' + ? Array.isArray + : function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]' + } +; +function indexOf (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; + } + return -1; +} + +// By default EventEmitters will print a warning if more than +// 10 listeners are added to it. This is a useful default which +// helps finding memory leaks. +// +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +var defaultMaxListeners = 10; +EventEmitter.prototype.setMaxListeners = function(n) { + if (!this._events) this._events = {}; + this._events.maxListeners = n; +}; + + +EventEmitter.prototype.emit = function(type) { + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events || !this._events.error || + (isArray(this._events.error) && !this._events.error.length)) + { + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + if (!this._events) return false; + var handler = this._events[type]; + if (!handler) return false; + + if (typeof handler == 'function') { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + return true; + + } else if (isArray(handler)) { + var args = Array.prototype.slice.call(arguments, 1); + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + listeners[i].apply(this, args); + } + return true; + + } else { + return false; + } +}; + +// EventEmitter is defined in src/node_events.cc +// EventEmitter.prototype.emit() is also defined there. +EventEmitter.prototype.addListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('addListener only takes instances of Function'); + } + + if (!this._events) this._events = {}; + + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); + + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } else if (isArray(this._events[type])) { + + // Check for listener leak + if (!this._events[type].warned) { + var m; + if (this._events.maxListeners !== undefined) { + m = this._events.maxListeners; + } else { + m = defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + + // If we've already got an array, just append. + this._events[type].push(listener); + } else { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + var self = this; + self.on(type, function g() { + self.removeListener(type, g); + listener.apply(this, arguments); + }); + + return this; +}; + +EventEmitter.prototype.removeListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('removeListener only takes instances of Function'); + } + + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events || !this._events[type]) return this; + + var list = this._events[type]; + + if (isArray(list)) { + var i = indexOf(list, listener); + if (i < 0) return this; + list.splice(i, 1); + if (list.length == 0) + delete this._events[type]; + } else if (this._events[type] === listener) { + delete this._events[type]; + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + this._events = {}; + return this; + } + + // does not use listeners(), so no side effect of creating _events[type] + if (type && this._events && this._events[type]) this._events[type] = null; + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + if (!this._events) this._events = {}; + if (!this._events[type]) this._events[type] = []; + if (!isArray(this._events[type])) { + this._events[type] = [this._events[type]]; + } + return this._events[type]; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (typeof emitter._events[type] === 'function') + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +},{"__browserify_process":27}],19:[function(require,module,exports){ +// nothing to see here... no file methods for the browser + +},{}],20:[function(require,module,exports){ + +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Array#indexOf shim. + */ + +var indexOf = typeof Array.prototype.indexOf === 'function' + ? function(arr, el) { return arr.indexOf(el); } + : function(arr, el) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === el) return i; + } + return -1; + }; + +/** + * Array.isArray shim. + */ + +var isArray = Array.isArray || function(arr) { + return toString.call(arr) == '[object Array]'; +}; + +/** + * Object.keys shim. + */ + +var objectKeys = Object.keys || function(obj) { + var ret = []; + for (var key in obj) ret.push(key); + return ret; +}; + +/** + * Array#forEach shim. + */ + +var forEach = typeof Array.prototype.forEach === 'function' + ? function(arr, fn) { return arr.forEach(fn); } + : function(arr, fn) { + for (var i = 0; i < arr.length; i++) fn(arr[i]); + }; + +/** + * Array#reduce shim. + */ + +var reduce = function(arr, fn, initial) { + if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); + var res = initial; + for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); + return res; +}; + +/** + * Cache non-integer test regexp. + */ + +var isint = /^[0-9]+$/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {}; + var t = {}; + for (var i in parent[key]) t[i] = parent[key][i]; + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + // end + if (!part) { + if (isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[objectKeys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~indexOf(part, ']')) { + part = part.substr(0, part.length - 1); + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~indexOf(key, ']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (!isint.test(key) && isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + forEach(objectKeys(obj), function(name){ + merge(ret, name, obj[name]); + }); + return ret.base; +} + +/** + * Parse the given str. + */ + +function parseString(str){ + return reduce(String(str).split('&'), function(ret, pair){ + var eql = indexOf(pair, '=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(indexOf(val, '=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + if ('' == key) return ret; + + return merge(ret, decode(key), decode(val)); + }, { base: {} }).base; +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix + '=' + encodeURIComponent(String(obj)); + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[' + i + ']')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = objectKeys(obj) + , key; + + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + if (null == obj[key]) { + ret.push(encodeURIComponent(key) + '='); + } else { + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + } + + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (undefined === v) { + obj[key] = val; + } else if (isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} + +/** + * Decode `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function decode(str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (err) { + return str; + } +} + +},{}],21:[function(require,module,exports){ +var punycode = { encode : function (s) { return s } }; + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +function arrayIndexOf(array, subject) { + for (var i = 0, j = array.length; i < j; i++) { + if(array[i] == subject) return i; + } + return -1; +} + +var objectKeys = Object.keys || function objectKeys(object) { + if (object !== Object(object)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in object) if (object.hasOwnProperty(key)) keys[keys.length] = key; + return keys; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]+$/, + // RFC 2396: characters reserved for delimiting URLs. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '~', '[', ']', '`'].concat(delims), + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''], + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'] + .concat(unwise).concat(autoEscape), + nonAuthChars = ['/', '@', '?', '#'].concat(delims), + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z_-]{0,62}$/, + hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z_-]{0,62})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always have a path component. + pathedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && typeof(url) === 'object' && url.href) return url; + + if (typeof url !== 'string') { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var out = {}, + rest = url; + + // cut off any delimiters. + // This is to support parse stuff like "" + for (var i = 0, l = rest.length; i < l; i++) { + if (arrayIndexOf(delims, rest.charAt(i)) === -1) break; + } + if (i !== 0) rest = rest.substr(i); + + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + out.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + out.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // don't enforce full RFC correctness, just be unstupid about it. + + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the first @ sign, unless some non-auth character + // comes *before* the @-sign. + // URLs are obnoxious. + var atSign = arrayIndexOf(rest, '@'); + if (atSign !== -1) { + // there *may be* an auth + var hasAuth = true; + for (var i = 0, l = nonAuthChars.length; i < l; i++) { + var index = arrayIndexOf(rest, nonAuthChars[i]); + if (index !== -1 && index < atSign) { + // not a valid auth. Something like http://foo.com/bar@baz/ + hasAuth = false; + break; + } + } + if (hasAuth) { + // pluck off the auth portion. + out.auth = rest.substr(0, atSign); + rest = rest.substr(atSign + 1); + } + } + + var firstNonHost = -1; + for (var i = 0, l = nonHostChars.length; i < l; i++) { + var index = arrayIndexOf(rest, nonHostChars[i]); + if (index !== -1 && + (firstNonHost < 0 || index < firstNonHost)) firstNonHost = index; + } + + if (firstNonHost !== -1) { + out.host = rest.substr(0, firstNonHost); + rest = rest.substr(firstNonHost); + } else { + out.host = rest; + rest = ''; + } + + // pull out port. + var p = parseHost(out.host); + var keys = objectKeys(p); + for (var i = 0, l = keys.length; i < l; i++) { + var key = keys[i]; + out[key] = p[key]; + } + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + out.hostname = out.hostname || ''; + + // validate a little. + if (out.hostname.length > hostnameMaxLen) { + out.hostname = ''; + } else { + var hostparts = out.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + out.hostname = validParts.join('.'); + break; + } + } + } + } + + // hostnames are always lower case. + out.hostname = out.hostname.toLowerCase(); + + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = out.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + out.hostname = newOut.join('.'); + + out.host = (out.hostname || '') + + ((out.port) ? ':' + out.port : ''); + out.href += out.host; + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + + // Now make sure that delims never appear in a url. + var chop = rest.length; + for (var i = 0, l = delims.length; i < l; i++) { + var c = arrayIndexOf(rest, delims[i]); + if (c !== -1) { + chop = Math.min(c, chop); + } + } + rest = rest.substr(0, chop); + } + + + // chop off from the tail first. + var hash = arrayIndexOf(rest, '#'); + if (hash !== -1) { + // got a fragment string. + out.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = arrayIndexOf(rest, '?'); + if (qm !== -1) { + out.search = rest.substr(qm); + out.query = rest.substr(qm + 1); + if (parseQueryString) { + out.query = querystring.parse(out.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + out.search = ''; + out.query = {}; + } + if (rest) out.pathname = rest; + if (slashedProtocol[proto] && + out.hostname && !out.pathname) { + out.pathname = '/'; + } + + //to support http.request + if (out.pathname || out.search) { + out.path = (out.pathname ? out.pathname : '') + + (out.search ? out.search : ''); + } + + // finally, reconstruct the href based on what has been validated. + out.href = urlFormat(out); + return out; +} + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (typeof(obj) === 'string') obj = urlParse(obj); + + var auth = obj.auth || ''; + if (auth) { + auth = auth.split('@').join('%40'); + for (var i = 0, l = nonAuthChars.length; i < l; i++) { + var nAC = nonAuthChars[i]; + auth = auth.split(nAC).join(encodeURIComponent(nAC)); + } + auth += '@'; + } + + var protocol = obj.protocol || '', + host = (obj.host !== undefined) ? auth + obj.host : + obj.hostname !== undefined ? ( + auth + obj.hostname + + (obj.port ? ':' + obj.port : '') + ) : + false, + pathname = obj.pathname || '', + query = obj.query && + ((typeof obj.query === 'object' && + objectKeys(obj.query).length) ? + querystring.stringify(obj.query) : + '') || '', + search = obj.search || (query && ('?' + query)) || '', + hash = obj.hash || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (obj.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + return protocol + host + pathname + search + hash; +} + +function urlResolve(source, relative) { + return urlFormat(urlResolveObject(source, relative)); +} + +function urlResolveObject(source, relative) { + if (!source) return relative; + + source = urlParse(urlFormat(source), false, true); + relative = urlParse(urlFormat(relative), false, true); + + // hash is always overridden, no matter what. + source.hash = relative.hash; + + if (relative.href === '') { + source.href = urlFormat(source); + return source; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + relative.protocol = source.protocol; + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[relative.protocol] && + relative.hostname && !relative.pathname) { + relative.path = relative.pathname = '/'; + } + relative.href = urlFormat(relative); + return relative; + } + + if (relative.protocol && relative.protocol !== source.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + relative.href = urlFormat(relative); + return relative; + } + source.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + relative.pathname = relPath.join('/'); + } + source.pathname = relative.pathname; + source.search = relative.search; + source.query = relative.query; + source.host = relative.host || ''; + source.auth = relative.auth; + source.hostname = relative.hostname || relative.host; + source.port = relative.port; + //to support http.request + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.slashes = source.slashes || relative.slashes; + source.href = urlFormat(source); + return source; + } + + var isSourceAbs = (source.pathname && source.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host !== undefined || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (source.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = source.pathname && source.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = source.protocol && + !slashedProtocol[source.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // source.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + + delete source.hostname; + delete source.port; + if (source.host) { + if (srcPath[0] === '') srcPath[0] = source.host; + else srcPath.unshift(source.host); + } + delete source.host; + if (relative.protocol) { + delete relative.hostname; + delete relative.port; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + delete relative.host; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + source.host = (relative.host || relative.host === '') ? + relative.host : source.host; + source.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : source.hostname; + source.search = relative.search; + source.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + source.search = relative.search; + source.query = relative.query; + } else if ('search' in relative) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + source.hostname = source.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = source.host && arrayIndexOf(source.host, '@') > 0 ? + source.host.split('@') : false; + if (authInHost) { + source.auth = authInHost.shift(); + source.host = source.hostname = authInHost.shift(); + } + } + source.search = relative.search; + source.query = relative.query; + //to support http.request + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.href = urlFormat(source); + return source; + } + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + delete source.pathname; + //to support http.request + if (!source.search) { + source.path = '/' + source.search; + } else { + delete source.path; + } + source.href = urlFormat(source); + return source; + } + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (source.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + source.hostname = source.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = source.host && arrayIndexOf(source.host, '@') > 0 ? + source.host.split('@') : false; + if (authInHost) { + source.auth = authInHost.shift(); + source.host = source.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (source.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + source.pathname = srcPath.join('/'); + //to support request.http + if (source.pathname !== undefined || source.search !== undefined) { + source.path = (source.pathname ? source.pathname : '') + + (source.search ? source.search : ''); + } + source.auth = relative.auth || source.auth; + source.slashes = source.slashes || relative.slashes; + source.href = urlFormat(source); + return source; +} + +function parseHost(host) { + var out = {}; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + out.port = port.substr(1); + host = host.substr(0, host.length - port.length); + } + if (host) out.hostname = host; + return out; +} + +},{"querystring":20}],22:[function(require,module,exports){ +var events = require('events'); + +exports.isArray = isArray; +exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'}; +exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'}; + + +exports.print = function () {}; +exports.puts = function () {}; +exports.debug = function() {}; + +exports.inspect = function(obj, showHidden, depth, colors) { + var seen = []; + + var stylize = function(str, styleType) { + // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + var styles = + { 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] }; + + var style = + { 'special': 'cyan', + 'number': 'blue', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' }[styleType]; + + if (style) { + return '\u001b[' + styles[style][0] + 'm' + str + + '\u001b[' + styles[style][1] + 'm'; + } else { + return str; + } + }; + if (! colors) { + stylize = function(str, styleType) { return str; }; + } + + function format(value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value !== exports && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + return value.inspect(recurseTimes); + } + + // Primitive types cannot have properties + switch (typeof value) { + case 'undefined': + return stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return stylize(simple, 'string'); + + case 'number': + return stylize('' + value, 'number'); + + case 'boolean': + return stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return stylize('null', 'null'); + } + + // Look up the keys of the object. + var visible_keys = Object_keys(value); + var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys; + + // Functions without properties can be shortcutted. + if (typeof value === 'function' && keys.length === 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + var name = value.name ? ': ' + value.name : ''; + return stylize('[Function' + name + ']', 'special'); + } + } + + // Dates without properties can be shortcutted + if (isDate(value) && keys.length === 0) { + return stylize(value.toUTCString(), 'date'); + } + + var base, type, braces; + // Determine the object type + if (isArray(value)) { + type = 'Array'; + braces = ['[', ']']; + } else { + type = 'Object'; + braces = ['{', '}']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var n = value.name ? ': ' + value.name : ''; + base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; + } else { + base = ''; + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + value.toUTCString(); + } + + if (keys.length === 0) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + return stylize('[Object]', 'special'); + } + } + + seen.push(value); + + var output = keys.map(function(key) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = stylize('[Getter/Setter]', 'special'); + } else { + str = stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = stylize('[Setter]', 'special'); + } + } + } + if (visible_keys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = format(value[key]); + } else { + str = format(value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (isArray(value)) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (type === 'Array' && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = stylize(name, 'string'); + } + } + + return name + ': ' + str; + }); + + seen.pop(); + + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 50) { + output = braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + + } else { + output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + return output; + } + return format(obj, (typeof depth === 'undefined' ? 2 : depth)); +}; + + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && Object.prototype.toString.call(ar) === '[object Array]'); +} + + +function isRegExp(re) { + typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]'; +} + + +function isDate(d) { + return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; +} + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + +exports.log = function (msg) {}; + +exports.pump = null; + +var Object_keys = Object.keys || function (obj) { + var res = []; + for (var key in obj) res.push(key); + return res; +}; + +var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) { + var res = []; + for (var key in obj) { + if (Object.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +var Object_create = Object.create || function (prototype, properties) { + // from es5-shim + var object; + if (prototype === null) { + object = { '__proto__' : null }; + } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); + } + return object; +}; + +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object_create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (typeof f !== 'string') { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(exports.inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': return JSON.stringify(args[i++]); + default: + return x; + } + }); + for(var x = args[i]; i < len; x = args[++i]){ + if (x === null || typeof x !== 'object') { + str += ' ' + x; + } else { + str += ' ' + exports.inspect(x); + } + } + return str; +}; + +},{"events":18}],23:[function(require,module,exports){ +exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; + +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; + +},{}],24:[function(require,module,exports){ +var assert = require('assert'); +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; + +function Buffer(subject, encoding, offset) { + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; + + var type; + + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + this.offset = offset; + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; + + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; + + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; + + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } + + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; + } + } + } +} + +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; +}; + +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; + +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; + + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; + + case 'ascii': + case 'binary': + return str.length; + + case 'base64': + return base64ToBytes(str).length; + + default: + throw new Error('Unknown encoding'); + } +}; + +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; + +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; + +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; + +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; + +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; + +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); + + i++; + } + + return res + decodeUtf8Char(tmp); +} + +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} + +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; + +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; + } + } + return ''; +}; + + +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); + } + return out; +}; + + +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; + + // Fastpath empty strings + if (+end == start) { + return ''; + } + + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); + + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); + + case 'ascii': + return this.asciiSlice(start, end); + + case 'binary': + return this.binarySlice(start, end); + + case 'base64': + return this.base64Slice(start, end); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); + + default: + throw new Error('Unknown encoding'); + } +}; + + +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); + } + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; +}; + + +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; + } + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || 'utf8').toLowerCase(); + + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); + + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); + + case 'ascii': + return this.asciiWrite(string, offset, length); + + case 'binary': + return this.binaryWrite(string, offset, length); + + case 'base64': + return this.base64Write(string, offset, length); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); + + default: + throw new Error('Unknown encoding'); + } +}; + + +// slice(start, end) +Buffer.prototype.slice = function(start, end) { + if (end === undefined) end = this.length; + + if (end > this.length) { + throw new Error('oob'); + } + if (start > end) { + throw new Error('oob'); + } + + return new Buffer(this, end - start, +start); +}; + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; + } + target_start || (target_start = 0); + + if (end < start) throw new Error('sourceEnd < sourceStart'); + + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; + + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); + } + + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); + } + + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); + } + + // Are we oob? + if (end > this.length) { + end = this.length; + } + + if (target.length - target_start < end - start) { + end = target.length - target_start + start; + } + + var temp = []; + for (var i=start; i= this.length) { + throw new Error('start out of bounds'); + } + + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); + } + + for (var i = start; i < end; i++) { + this[i] = value; + } +} + +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; +}; + +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); + } + + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; + } + + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; + } + } + + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer; +}; + +// helpers + +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; +} + +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) +} + +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; +} + +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); +} + +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); + } + + return byteArray; +} + +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); + + return byteArray; +} + +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} + +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; + + dst[i + offset] = src[i]; + i++; + } + return i; +} + +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char + } +} + +// read/write bit-twiddling + +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + return buffer[offset]; +}; + +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; + } + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; + } + } + + return val; +} + +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; + +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); + } + + return val; +} + +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; + + +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); + } + + return ((0xff - buffer[offset] + 1) * -1); +}; + +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } + + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; + } + + return (0xffff - val + 1) * -1; +} + +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; + +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); +}; + +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); + } + + return (0xffffffff - val + 1) * -1; +} + +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); +}; + +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); +}; + +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; + +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); +}; + +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); +}; + + +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); + + assert.ok(value <= max, 'value is larger than maximum value for type'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} + +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xff); + } + + if (offset < buffer.length) { + buffer[offset] = value; + } +}; + +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffff); + } + + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; + } + +} + +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); +}; + +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); + } + + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; + } +} + +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; + + +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: + * + * > -32 & 0xff + * 224 + * + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. + * + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: + * + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: + * + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. + */ + +/* + * A series of checks to make sure we actually have a signed 32-bit number + */ +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} + +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} + +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7f, -0x80); + } + + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); + } +}; + +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); + } + + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; + +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fffffff, -0x80000000); + } + + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; + +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); +}; + +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; + +},{"./buffer_ieee754":23,"assert":17,"base64-js":25}],25:[function(require,module,exports){ +(function (exports) { + 'use strict'; + + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } + + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } + + return arr; + } + + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } + + return output; + } + + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); + +},{}],26:[function(require,module,exports){ + +},{}],27:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + if (ev.source === window && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +},{}]},{},[6]) +(6) +}); +; \ No newline at end of file diff --git a/package.json b/package.json index 5acffc7..7c7c02b 100644 --- a/package.json +++ b/package.json @@ -29,15 +29,21 @@ "engines": { "node": ">=0.4.0" }, - "dependencies": { - "any-db": "< 0.9.9" + "peerDependencies": { + "any-db": "1.x" + }, + "browser": { + "any-db": false }, "devDependencies": { "coffee-script": "~1.4.0", - "pg": "*", - "mysql": "~2.0.0-alpha6", + "any-db": "1.x", + "any-db-postgres": "1.x", + "any-db-sqlite3": "1.x", + "any-db-mysql": "1.x", "tap": "~0.4.0", - "sqlite3": "~2.1.5" + "browserify": "2.x.x", + "coffeeify": "~0.5.1" }, "author": "Stephen Sugden (http://www.betsmartmedia.com)", "optionalDependencies": {}, diff --git a/src/dialects.coffee b/src/dialects.coffee index 2931e60..6c602a9 100644 --- a/src/dialects.coffee +++ b/src/dialects.coffee @@ -5,11 +5,16 @@ bound to an `engine `_ that will delegate compiling to it's dialect instance. ### -read = require('fs').readFileSync -kwFile = __dirname + '/sql_keywords.txt' -keywords = read(kwFile, 'ascii').split('\n').filter(Boolean) {Select, Update, Delete, Insert, Relation, Field} = require './nodes' +if process.browser + keywords = [] +else + keywords = require('fs') + .readFileSync(__dirname + '/sql_keywords.txt') + .toString() + .split('\n').filter(Boolean) + class BaseDialect reset: -> @@ -61,6 +66,7 @@ class BaseDialect if allowOverride and name and custom = @dialect['render' + name] string = custom.call(@, node) else + debugger unless node?.compile string = node.compile(@, @path) @path.pop(node) return string @@ -107,7 +113,8 @@ class PrettyDialect extends BaseDialect class PostgresDialect extends BaseDialect operator: (op) -> switch op.toLowerCase() - when 'hasKey' then '?' + when 'hasKey', '?' then '?' + when 'contains', '@>' then '@>' when '->' then '->' else super op diff --git a/src/engine.coffee b/src/engine.coffee index db4e1e5..481cbfd 100644 --- a/src/engine.coffee +++ b/src/engine.coffee @@ -1,6 +1,6 @@ url = require('url') anyDB = require('any-db') -queries = require('./queries') +queries = require('./queries/index') dialects = require('./dialects') module.exports = -> Engine.create.apply Engine, arguments diff --git a/src/index.coffee b/src/index.coffee index 7bdbcb2..602b61d 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -55,10 +55,14 @@ particularly unusual SQL statements, you might also want to make use of these: ### exports.dialects = require './dialects' -exports.engine = require './engine' +exports.engine = require './engine' +exports.nodes = require './nodes' + +exports.queries = require('./queries/index') + exports.defaultEngine = exports.engine 'fake://localhost/' -exports.nodes = require './nodes' +exports.queries.mixinFactoryMethods(exports, -> exports.defaultEngine) for name, node of exports.nodes.CONST_NODES exports[name] = exports.nodes.CONST_NODES[name] @@ -69,10 +73,10 @@ for name, node of exports.nodes.JOIN_TYPES for name, helper of exports.nodes when name[0] is name[0].toLowerCase() exports[name] = helper -require('./queries').mixinFactoryMethods(exports, -> exports.defaultEngine) - exports.begin = (args...) -> exports.defaultEngine.begin args... exports.query = (args...) -> exports.defaultEngine.query args... + +exports.unmarshaller = require('./unmarshal') diff --git a/src/nodes.coffee b/src/nodes.coffee index 35588d7..13a0b20 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -15,15 +15,24 @@ class Node message = "#{@constructor} has no compile method. Parents: #{dialect.path}" throw new Error message + toJSON: -> + {_type: @constructor.name} + + copy: -> + unmarshal @toJSON() class ValueNode extends Node ### A ValueNode is a literal string that should be printed unescaped. ### + @unmarshal = (data, recur) -> + new @(data.value) + constructor: (@value) -> if @value? throw new Error("Invalid #{@constructor.name}: #{@value}") unless @valid() - copy: -> new @constructor @value - valid: -> true + + valid: -> true compile: -> @value + toJSON: -> merge super, value: @value class IntegerNode extends ValueNode ### A :class:`nodes::ValueNode` that validates it's input is an integer. ### @@ -52,6 +61,10 @@ JOIN_TYPES[name] = new JoinType(name.replace('_', ' ')) for name in [ class NodeSet extends Node ### A set of nodes joined together by ``@glue`` ### + + @unmarshal = (data, recur) -> + new @(recur(data.nodes), data.glue) + constructor: (nodes, glue=' ') -> ### :param @nodes: A list of child nodes. @@ -61,13 +74,6 @@ class NodeSet extends Node @addNode(node) for node in nodes if nodes @glue ?= glue - copy: -> - ### - Make a deep copy of this node and it's children - ### - c = new @constructor @nodes.map(copy), @glue - return c - addNode: (node) -> ### Add a new Node to the end of this set ### @nodes.push node @@ -76,6 +82,9 @@ class NodeSet extends Node compile = dialect.compile.bind(dialect) @nodes.map(compile).filter(Boolean).join(@glue) + toJSON: -> + merge super, glue: @glue, nodes: @nodes.map (n) -> n.toJSON() + class FixedNodeSet extends NodeSet # A NodeSet that disables the ``addNode`` method after construction. @@ -95,6 +104,12 @@ class Statement extends Node @::__defineGetter__ k, -> @_private[k] or= new type @::__defineSetter__ k, (v) -> @_private[k] = v + @unmarshal = (data, recur) -> + it = new @ + delete data._type + it._private = recur(data) + return it + constructor: (opts) -> @_private = {} @initialize(opts) if opts @@ -102,13 +117,6 @@ class Statement extends Node initialize: (opts) -> @initialize = null - copy: -> - c = new @constructor - for k, node of @_private - c[k] = copy node - c.initialize = null - return c - compile: (dialect) -> parts = for k in @constructor._nodeOrder when node = @_private[k] dialect.compile(node) @@ -117,21 +125,40 @@ class Statement extends Node else return "" + toJSON: -> + parent = super + for k, v of @_private + parent[k] = v.toJSON() + parent + + class ParenthesizedNodeSet extends NodeSet ### A NodeSet wrapped in parenthesis. ### compile: -> "(" + super + ")" class AbstractAlias extends Node + @patch = (klazz) -> + klazz.Alias = @ + klazz::as = (name) -> + new @constructor.Alias @, name + + @unmarshal = (data, recur) -> + new @(recur(data.obj), data.alias) + constructor: (@obj, @alias) -> - copy: -> new @constructor copy(@obj), @alias ref: -> @alias compile: (dialect) -> dialect.maybeParens(dialect.compile(@obj)) + " AS " + dialect.quote(@alias) + toJSON: -> merge super, {obj: @obj.toJSON(), @alias} + # End of generic base classes class TextNode extends Node + @unmarshal = (data, recur) -> + new @(data.text, data.bindVals) + constructor: (@text, @bindVals=[]) -> paramRegexp = /\$([\w]+)\b/g @@ -143,34 +170,35 @@ class TextNode extends Node else throw new Error "Parameter #{name} not present in #{JSON.stringify(@bindVals)}" - as: (alias) -> - new Alias @, alias - - copy: -> new @constructor(@text, copy(@bindVals)) - - @Alias = class Alias extends AbstractAlias + toJSON: -> + merge super, {@text, @bindVals} +class TextAlias extends AbstractAlias + @patch(TextNode) class SqlFunction extends Node ### Includes :class:`nodes::ComparableMixin` ### + @unmarshal = (data, recur) -> + new @(data.name, data.arglist) + constructor: (@name, @arglist) -> - ref: -> @name - copy: -> new @constructor @name, copy(@arglist) - compile: (dialect) -> - "#{@name}#{dialect.compile @arglist}" - as: (alias) -> new Alias @, alias + ref: -> @name + compile: (d) -> "#{@name}#{d.compile @arglist}" + toJSON: -> merge super, {@name, @arglist} - @Alias = class Alias extends AbstractAlias - shouldRenderFull = (parents) -> - return false if parents.some((it) -> it instanceof Column) - parents.some (node) -> - node instanceof ColumnSet or node instanceof RelationSet +class FunctionAlias extends AbstractAlias + @patch(SqlFunction) - compile: (dialect, parents) -> - if shouldRenderFull(parents) - dialect.compile(@obj) + " AS " + dialect.quote(@alias) - else - dialect.quote(@alias) + shouldRenderFull = (parents) -> + return false if parents.some((it) -> it instanceof Column) + parents.some (node) -> + node instanceof ColumnSet or node instanceof RelationSet + + compile: (dialect, parents) -> + if shouldRenderFull(parents) + dialect.compile(@obj) + " AS " + dialect.quote(@alias) + else + dialect.quote(@alias) class Parameter extends ValueNode ### @@ -194,17 +222,15 @@ class Relation extends Identifier ### Return a new :class:`nodes::Column` of `field` from this table. ### new Column @, toField(field) - as: (alias) -> - new Alias @, alias - - @Alias = class Alias extends AbstractAlias - ### An aliased :class:`nodes::Relation` ### - project: (field) -> Relation::project.call @, field - compile: (dialect, parents) -> - if parents.some((n) -> n instanceof Column) - dialect.quote(@alias) - else - super +class RelationAlias extends AbstractAlias + ### An aliased :class:`nodes::Relation` ### + @patch(Relation) + project: (field) -> Relation::project.call @, field + compile: (dialect, parents) -> + if parents.some((n) -> n instanceof Column) + dialect.quote(@alias) + else + super class Field extends Identifier ### A column name ### @@ -213,9 +239,11 @@ class Column extends FixedNodeSet ### Includes :class:`nodes::ComparableMixin` ### + @unmarshal = (data, recur) -> + new @(recur(data.nodes[0]), recur(data.nodes[1])) + constructor: (@source, @field) -> super [@source, @field], '.' rel: -> @source - copy: -> new @constructor copy(@source), copy(@field) as: (alias) -> ### Return an aliased version of this column. ### new Alias @, alias @@ -237,8 +265,10 @@ class Offset extends IntegerNode if @value then "OFFSET #{@value}" else "" class Binary extends FixedNodeSet + @unmarshal = (data, recur) -> + new @(recur(data.left), recur(data.op), recur(data.right)) + constructor: (@left, @op, @right) -> super [@left, @op, @right], ' ' - copy: -> new @constructor copy(@left), @op, copy(@right) and: (args...) -> new And [@, args...] @@ -252,6 +282,12 @@ class Binary extends FixedNodeSet dialect.compile(@right) ].join(' ') + toJSON: -> + merge Node::toJSON.call(@), + left: @left.toJSON(), + op: @op, + right: @right.toJSON() + class Tuple extends ParenthesizedNodeSet glue: ', ' @@ -271,8 +307,6 @@ class Returning extends ColumnSet class Distinct extends ColumnSet constructor: (@enable=false) -> super - copy: -> new @constructor @enable, copy(@nodes) - compile: (dialect) -> if not @enable '' @@ -310,12 +344,6 @@ class RelationSet extends NodeSet super @active = @relsByName[node.ref()] = node.relation - copy: -> - c = super - if @active?.ref?() isnt c.active?.ref?() - c.switch(@active.ref()) - return c - get: (name, strict=true) -> name = name.ref() unless 'string' == typeof name found = @relsByName[name] @@ -331,7 +359,14 @@ class RelationSet extends NodeSet class Join extends FixedNodeSet JOIN = new ValueNode 'JOIN' - ON = new ValueNode 'ON' + ON = new ValueNode 'ON' + + @unmarshal = (data, recur) -> + {nodes} = data + join = new @(recur(nodes[0]), recur(nodes[2])) + for clause in nodes.slice(4) + join.on(clause) + join constructor: (@type, @relation) -> nodes = [@type, JOIN, @relation] @@ -345,13 +380,6 @@ class Join extends FixedNodeSet ref: -> @relation.ref() - copy: -> - c = new @constructor copy(@type), copy(@relation) - for clause in @nodes.slice(4) - c.on(clause) - return c - - class Where extends NodeSet glue: ' AND ' compile: (dialect) -> @@ -428,7 +456,7 @@ class Update extends Statement The root node of an UPDATE query ### - class UpdateSet extends NodeSet + @UpdateSet = class UpdateSet extends NodeSet # must be pre-defined for the call to @structure below constructor: (nodes) -> super nodes, ', ' compile: (dialect) -> @@ -457,7 +485,7 @@ class Insert extends Statement The root node of an INSERT query ### - class InsertData extends NodeSet + @InsertData = class InsertData extends NodeSet # must be pre-defined for the call to @structure below glue: ', ' compile: (dialect) -> @@ -541,6 +569,9 @@ class ComparableMixin A mixin that adds comparison methods to a class. Each of these comparison methods will yield a new AST node comparing the invocant to the argument. ### + @patch = (klazz) -> + klazz::[k] = v for k, v of @prototype + eq: (other) -> ### ``this = other`` ### @compare '=', other @@ -573,13 +604,14 @@ class ComparableMixin ### ``this op other`` **DANGER** `op` is **NOT** escaped! ### new Binary @, op, toParam other -for k, v of ComparableMixin:: - TextNode::[k] = v - SqlFunction::[k] = v - SqlFunction.Alias::[k] = v - Column::[k] = v - Column.Alias::[k] = v - Tuple::[k] = v +ComparableMixin.patch(ctor) for ctor in [ + TextNode + SqlFunction + SqlFunction.Alias + Column + Column.Alias + Tuple +] toParam = (it) -> ### @@ -602,7 +634,7 @@ toRelation = (it) -> ### Transform ``it`` into a :class:`nodes::Relation` instance. - This accepts `strings, `Relation`` and ``Alias`` instances, and objects with + This accepts `strings, ``Relation`` and ``Alias`` instances, and objects with a single key-value pair, which will be turned into an ``Alias`` instance. Examples:: @@ -716,9 +748,11 @@ text = (rawSQL, bindVals) -> .execute(callback) } - If you find yourself using this function often, please consider opening an - issue on `Github `_ with details - on your use case so gesundheit can support it more elegantly. + .. [#] If you find yourself using this function often, please `open an issue`_ + on Github with details on your use case so `gesundheit` can support it + more elegantly. + + .. _open an issue: https://github.com/BetSmartMedia/gesundheit/issues/new?title=I%20use%20text()%20for%20blah ### new TextNode(rawSQL, bindVals) @@ -782,11 +816,15 @@ module.exports = { Statement ParenthesizedNodeSet TextNode + TextAlias SqlFunction + FunctionAlias Parameter Relation + RelationAlias: Relation.Alias Field Column + ColumnAlias: Column.Alias Limit Offset Binary @@ -805,11 +843,17 @@ module.exports = { Ordering Select Update + UpdateSet: Update.UpdateSet Insert + ColumnList: Insert.ColumnList + InsertData: Insert.InsertData Delete ComparableMixin } +# default (no validation) unmarshaller +unmarshal = require('./unmarshal')() + copy = (it) -> # Return a deep copy of ``it``. if not it then return it @@ -820,6 +864,11 @@ copy = (it) -> c = {} for k, v of it c[k] = copy v + return c else if it.copy? then it.copy() else throw new Error "Don't know how to copy #{it}" + +merge = (dest, src) -> + dest[k] = v for k, v of src + dest diff --git a/src/queries/base.coffee b/src/queries/base.coffee index 244b765..ba2abcd 100644 --- a/src/queries/base.coffee +++ b/src/queries/base.coffee @@ -11,6 +11,11 @@ module.exports = class BaseQuery extends EventEmitter ### @rootNode = null + @unmarshal = (data, recur) -> + query = new @ + query.q = recur(data.q) + query + constructor: (engine, opts={}) -> ### :param engine: The engine the query will be bound to. @@ -40,7 +45,7 @@ module.exports = class BaseQuery extends EventEmitter }) ### - fn.call @ + fn.call @, @ bind: (engine) -> ### @@ -48,7 +53,7 @@ module.exports = class BaseQuery extends EventEmitter If no argument is given the query will be bound to the default engine. ### oldEngine = @engine - @engine = engine or require('../').defaultEngine + @engine = engine or require('../index').defaultEngine if @engine isnt oldEngine oldEngine?.unextendQuery?(@) @engine.extendQuery?(@) @@ -93,6 +98,9 @@ module.exports = class BaseQuery extends EventEmitter toString: -> @render() + toJSON: -> + {_type: @constructor.name, q: @q.toJSON()} + fluid = require '../decorators/fluid' diff --git a/src/queries/sud.coffee b/src/queries/sud.coffee index 81287e0..0b6ebf7 100644 --- a/src/queries/sud.coffee +++ b/src/queries/sud.coffee @@ -1,5 +1,5 @@ BaseQuery = require './base' -nodes = require '../nodes' +nodes = require '../nodes' {Node, And, Or, Ordering, Column, CONST_NODES, toField} = nodes module.exports = class SUDQuery extends BaseQuery diff --git a/src/unmarshal.coffee b/src/unmarshal.coffee new file mode 100644 index 0000000..4b7fecd --- /dev/null +++ b/src/unmarshal.coffee @@ -0,0 +1,44 @@ +unmarshallable = Object.create require('./nodes'), { + InsertQuery: value: require './queries/insert' + SelectQuery: value: require './queries/select' + UpdateQuery: value: require './queries/update' + DeleteQuery: value: require './queries/delete' +} + +# The current (global) unmarshal callback +unmarshal = null + +module.exports = (visitor, object) -> + path = [] + recur = (object, k="") -> + return object if typeof object != 'object' + + path.push(k) + + if Array.isArray(object) + result = object.map(recur) + else + if !(type = object._type) + result = {} + result[k] = recur(v, k) for k, v of object + result + else if (ctor = unmarshallable[type])?.unmarshal? + visitor?.before?(object, path) + result = ctor.unmarshal(object, recur) + visitor?.after?(result, path) + else + err = new Error "Cannot unmarshall #{type} @ #{path.join('/')}" + err.path = path.slice() + path = [] + throw err + + path.pop(k) + result + + # A little manual currying + if arguments.length > 1 + recur(object) + else + recur + +module.exports.allow = unmarshallable diff --git a/test/unit/marshalling.test.js b/test/unit/marshalling.test.js new file mode 100644 index 0000000..7ad65dd --- /dev/null +++ b/test/unit/marshalling.test.js @@ -0,0 +1,35 @@ +var g = require('../../lib') +var test = require('tap').test + +test("Marshalling", function (t) { + t.plan(1) + + t.test("Unmarshal visitor", function (t) { + t.plan(2); + + t.test('Unmarshal visitor `before`', function (t) { + t.plan(2) + var unmarshal = g.unmarshaller({ + before: function (data, path) { + if (data._type === 'Relation') { + t.ok(Array.isArray(path), 'path argument is an array') + t.equal(data.value, 'my_table'); + } + } + }) + unmarshal(g.select('my_table').toJSON()) + }) + + t.test('Unmarshal visitor `after`', function (t) { + t.plan(1) + var unmarshal = g.unmarshaller({ + after: function (object, path) { + if (object instanceof g.nodes.Relation) { + t.equal(object.value, 'my_table'); + } + } + }) + unmarshal(g.select('my_table').toJSON()) + }) + }) +})