diff --git a/.gitignore b/.gitignore
index 2b7141a4..81b7cea3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
bower_components
node_modules
-dist
doc
.sass-cache
.coverage-results
diff --git a/.whitesource b/.whitesource
new file mode 100644
index 00000000..55b922e8
--- /dev/null
+++ b/.whitesource
@@ -0,0 +1,12 @@
+{
+ "scanSettings": {
+ "baseBranches": []
+ },
+ "checkRunSettings": {
+ "vulnerableCheckRunConclusionLevel": "failure",
+ "displayMode": "diff"
+ },
+ "issueSettings": {
+ "minSeverityLevel": "LOW"
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index cb412ddb..1c3fffb4 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,5 @@
-# jQuery QueryBuilder
+# jQuery QueryBuilder Forked by FT Solutions
-[](https://www.npmjs.com/package/jQuery-QueryBuilder)
-[](https://www.jsdelivr.com/package/npm/jQuery-QueryBuilder)
-[](https://travis-ci.org/mistic100/jQuery-QueryBuilder)
-[](https://coveralls.io/r/mistic100/jQuery-QueryBuilder)
-[](https://david-dm.org/mistic100/jQuery-QueryBuilder)
jQuery plugin offering an simple interface to create complex queries.
@@ -32,7 +27,7 @@ $ bower install jQuery-QueryBuilder
#### With npm
```bash
-$ npm install jQuery-QueryBuilder
+$ npm install fasttrack-solutions/jQuery-QueryBuilder
```
#### Via CDN
diff --git a/composer.json b/composer.json
index 3d52b425..b4b0f37a 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "mistic100/jquery-querybuilder",
- "version": "2.4.0",
+ "version": "2.5.2",
"authors": [{
"name": "Damien \"Mistic\" Sorel",
"email": "contact@git.strangeplanet.fr",
diff --git a/dist/css/query-builder.dark.css b/dist/css/query-builder.dark.css
new file mode 100644
index 00000000..6cb3aef9
--- /dev/null
+++ b/dist/css/query-builder.dark.css
@@ -0,0 +1,173 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+.query-builder .rules-group-container, .query-builder .rule-container, .query-builder .rule-placeholder {
+ position: relative;
+ margin: 4px 0;
+ border-radius: 5px;
+ padding: 5px;
+ border: 1px solid #111;
+ background: rgba(40, 40, 40, 0.9);
+}
+
+.query-builder .rule-container .rule-filter-container,
+.query-builder .rule-container .rule-operator-container,
+.query-builder .rule-container .rule-value-container, .query-builder .error-container, .query-builder .drag-handle {
+ display: inline-block;
+ margin: 0 5px 0 0;
+ vertical-align: middle;
+}
+
+.query-builder .rules-group-container {
+ padding: 10px;
+ padding-bottom: 6px;
+ border: 1px solid #00164A;
+ background: rgba(50, 70, 80, 0.5);
+}
+
+.query-builder .rules-group-header {
+ margin-bottom: 10px;
+}
+
+.query-builder .rules-group-header .group-conditions .btn.readonly:not(.active),
+.query-builder .rules-group-header .group-conditions input[name$='_cond'] {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+ white-space: nowrap;
+}
+
+.query-builder .rules-group-header .group-conditions .btn.readonly {
+ border-radius: 3px;
+}
+
+.query-builder .rules-list {
+ list-style: none;
+ padding: 0 0 0 15px;
+ margin: 0;
+}
+
+.query-builder .rule-value-container {
+ border-left: 1px solid #DDD;
+ padding-left: 5px;
+}
+
+.query-builder .rule-value-container label {
+ margin-bottom: 0;
+ font-weight: normal;
+}
+
+.query-builder .rule-value-container label.block {
+ display: block;
+}
+
+.query-builder .rule-value-container select,
+.query-builder .rule-value-container input[type='text'],
+.query-builder .rule-value-container input[type='number'] {
+ padding: 1px;
+}
+
+.query-builder .error-container {
+ display: none;
+ cursor: help;
+ color: #F00;
+}
+
+.query-builder .has-error {
+ background-color: #322;
+ border-color: #800;
+}
+
+.query-builder .has-error .error-container {
+ display: inline-block !important;
+}
+
+.query-builder .rules-list > *::before, .query-builder .rules-list > *::after {
+ content: '';
+ position: absolute;
+ left: -10px;
+ width: 10px;
+ height: calc(50% + 4px);
+ border-color: #222;
+ border-style: solid;
+}
+
+.query-builder .rules-list > *::before {
+ top: -4px;
+ border-width: 0 0 2px 2px;
+}
+
+.query-builder .rules-list > *::after {
+ top: 50%;
+ border-width: 0 0 0 2px;
+}
+
+.query-builder .rules-list > *:first-child::before {
+ top: -12px;
+ height: calc(50% + 14px);
+}
+
+.query-builder .rules-list > *:last-child::before {
+ border-radius: 0 0 0 4px;
+}
+
+.query-builder .rules-list > *:last-child::after {
+ display: none;
+}
+
+.query-builder.bt-checkbox-glyphicons .checkbox input[type='checkbox']:checked + label::after {
+ font-family: 'Glyphicons Halflings';
+ content: '\e013';
+}
+
+.query-builder.bt-checkbox-glyphicons .checkbox label::after {
+ padding-left: 4px;
+ padding-top: 2px;
+ font-size: 9px;
+}
+
+.query-builder .error-container + .tooltip .tooltip-inner {
+ color: #F22 !important;
+}
+
+.query-builder p.filter-description {
+ margin: 5px 0 0 0;
+ background: rgba(0, 170, 255, 0.2);
+ border: 1px solid #346F7B;
+ color: #AAD1E4;
+ border-radius: 5px;
+ padding: 2.5px 5px;
+ font-size: .8em;
+}
+
+.query-builder .rules-group-header [data-invert] {
+ margin-left: 5px;
+}
+
+.query-builder .drag-handle {
+ cursor: move;
+ vertical-align: middle;
+ margin-left: 5px;
+}
+
+.query-builder .dragging {
+ position: fixed;
+ opacity: .5;
+ z-index: 100;
+}
+
+.query-builder .dragging::before, .query-builder .dragging::after {
+ display: none;
+}
+
+.query-builder .rule-placeholder {
+ border: 1px dashed #BBB;
+ opacity: .7;
+}
diff --git a/dist/css/query-builder.dark.min.css b/dist/css/query-builder.dark.min.css
new file mode 100644
index 00000000..75d4452a
--- /dev/null
+++ b/dist/css/query-builder.dark.min.css
@@ -0,0 +1,6 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+.query-builder .rule-container,.query-builder .rule-placeholder,.query-builder .rules-group-container{position:relative;margin:4px 0;border-radius:5px;padding:5px;border:1px solid #111;background:rgba(40,40,40,.9)}.query-builder .drag-handle,.query-builder .error-container,.query-builder .rule-container .rule-filter-container,.query-builder .rule-container .rule-operator-container,.query-builder .rule-container .rule-value-container{display:inline-block;margin:0 5px 0 0;vertical-align:middle}.query-builder .rules-group-container{padding:10px;padding-bottom:6px;border:1px solid #00164a;background:rgba(50,70,80,.5)}.query-builder .rules-group-header{margin-bottom:10px}.query-builder .rules-group-header .group-conditions .btn.readonly:not(.active),.query-builder .rules-group-header .group-conditions input[name$='_cond']{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.query-builder .rules-group-header .group-conditions .btn.readonly{border-radius:3px}.query-builder .rules-list{list-style:none;padding:0 0 0 15px;margin:0}.query-builder .rule-value-container{border-left:1px solid #ddd;padding-left:5px}.query-builder .rule-value-container label{margin-bottom:0;font-weight:400}.query-builder .rule-value-container label.block{display:block}.query-builder .rule-value-container input[type=number],.query-builder .rule-value-container input[type=text],.query-builder .rule-value-container select{padding:1px}.query-builder .error-container{display:none;cursor:help;color:red}.query-builder .has-error{background-color:#322;border-color:#800}.query-builder .has-error .error-container{display:inline-block!important}.query-builder .rules-list>::after,.query-builder .rules-list>::before{content:'';position:absolute;left:-10px;width:10px;height:calc(50% + 4px);border-color:#222;border-style:solid}.query-builder .rules-list>::before{top:-4px;border-width:0 0 2px 2px}.query-builder .rules-list>::after{top:50%;border-width:0 0 0 2px}.query-builder .rules-list>:first-child::before{top:-12px;height:calc(50% + 14px)}.query-builder .rules-list>:last-child::before{border-radius:0 0 0 4px}.query-builder .rules-list>:last-child::after{display:none}.query-builder.bt-checkbox-glyphicons .checkbox input[type=checkbox]:checked+label::after{font-family:'Glyphicons Halflings';content:'\e013'}.query-builder.bt-checkbox-glyphicons .checkbox label::after{padding-left:4px;padding-top:2px;font-size:9px}.query-builder .error-container+.tooltip .tooltip-inner{color:#f22!important}.query-builder p.filter-description{margin:5px 0 0 0;background:rgba(0,170,255,.2);border:1px solid #346f7b;color:#aad1e4;border-radius:5px;padding:2.5px 5px;font-size:.8em}.query-builder .rules-group-header [data-invert]{margin-left:5px}.query-builder .drag-handle{cursor:move;vertical-align:middle;margin-left:5px}.query-builder .dragging{position:fixed;opacity:.5;z-index:100}.query-builder .dragging::after,.query-builder .dragging::before{display:none}.query-builder .rule-placeholder{border:1px dashed #bbb;opacity:.7}
\ No newline at end of file
diff --git a/dist/css/query-builder.default.css b/dist/css/query-builder.default.css
new file mode 100644
index 00000000..ea17165a
--- /dev/null
+++ b/dist/css/query-builder.default.css
@@ -0,0 +1,173 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+.query-builder .rules-group-container, .query-builder .rule-container, .query-builder .rule-placeholder {
+ position: relative;
+ margin: 4px 0;
+ border-radius: 5px;
+ padding: 5px;
+ border: 1px solid #EEE;
+ background: rgba(255, 255, 255, 0.9);
+}
+
+.query-builder .rule-container .rule-filter-container,
+.query-builder .rule-container .rule-operator-container,
+.query-builder .rule-container .rule-value-container, .query-builder .error-container, .query-builder .drag-handle {
+ display: inline-block;
+ margin: 0 5px 0 0;
+ vertical-align: middle;
+}
+
+.query-builder .rules-group-container {
+ padding: 10px;
+ padding-bottom: 6px;
+ border: 1px solid #DCC896;
+ background: rgba(250, 240, 210, 0.5);
+}
+
+.query-builder .rules-group-header {
+ margin-bottom: 10px;
+}
+
+.query-builder .rules-group-header .group-conditions .btn.readonly:not(.active),
+.query-builder .rules-group-header .group-conditions input[name$='_cond'] {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+ white-space: nowrap;
+}
+
+.query-builder .rules-group-header .group-conditions .btn.readonly {
+ border-radius: 3px;
+}
+
+.query-builder .rules-list {
+ list-style: none;
+ padding: 0 0 0 15px;
+ margin: 0;
+}
+
+.query-builder .rule-value-container {
+ border-left: 1px solid #DDD;
+ padding-left: 5px;
+}
+
+.query-builder .rule-value-container label {
+ margin-bottom: 0;
+ font-weight: normal;
+}
+
+.query-builder .rule-value-container label.block {
+ display: block;
+}
+
+.query-builder .rule-value-container select,
+.query-builder .rule-value-container input[type='text'],
+.query-builder .rule-value-container input[type='number'] {
+ padding: 1px;
+}
+
+.query-builder .error-container {
+ display: none;
+ cursor: help;
+ color: #F00;
+}
+
+.query-builder .has-error {
+ background-color: #FDD;
+ border-color: #F99;
+}
+
+.query-builder .has-error .error-container {
+ display: inline-block !important;
+}
+
+.query-builder .rules-list > *::before, .query-builder .rules-list > *::after {
+ content: '';
+ position: absolute;
+ left: -10px;
+ width: 10px;
+ height: calc(50% + 4px);
+ border-color: #CCC;
+ border-style: solid;
+}
+
+.query-builder .rules-list > *::before {
+ top: -4px;
+ border-width: 0 0 2px 2px;
+}
+
+.query-builder .rules-list > *::after {
+ top: 50%;
+ border-width: 0 0 0 2px;
+}
+
+.query-builder .rules-list > *:first-child::before {
+ top: -12px;
+ height: calc(50% + 14px);
+}
+
+.query-builder .rules-list > *:last-child::before {
+ border-radius: 0 0 0 4px;
+}
+
+.query-builder .rules-list > *:last-child::after {
+ display: none;
+}
+
+.query-builder.bt-checkbox-glyphicons .checkbox input[type='checkbox']:checked + label::after {
+ font-family: 'Glyphicons Halflings';
+ content: '\e013';
+}
+
+.query-builder.bt-checkbox-glyphicons .checkbox label::after {
+ padding-left: 4px;
+ padding-top: 2px;
+ font-size: 9px;
+}
+
+.query-builder .error-container + .tooltip .tooltip-inner {
+ color: #F99 !important;
+}
+
+.query-builder p.filter-description {
+ margin: 5px 0 0 0;
+ background: #D9EDF7;
+ border: 1px solid #BCE8F1;
+ color: #31708F;
+ border-radius: 5px;
+ padding: 2.5px 5px;
+ font-size: .8em;
+}
+
+.query-builder .rules-group-header [data-invert] {
+ margin-left: 5px;
+}
+
+.query-builder .drag-handle {
+ cursor: move;
+ vertical-align: middle;
+ margin-left: 5px;
+}
+
+.query-builder .dragging {
+ position: fixed;
+ opacity: .5;
+ z-index: 100;
+}
+
+.query-builder .dragging::before, .query-builder .dragging::after {
+ display: none;
+}
+
+.query-builder .rule-placeholder {
+ border: 1px dashed #BBB;
+ opacity: .7;
+}
diff --git a/dist/css/query-builder.default.min.css b/dist/css/query-builder.default.min.css
new file mode 100644
index 00000000..d2a22134
--- /dev/null
+++ b/dist/css/query-builder.default.min.css
@@ -0,0 +1,6 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+.query-builder .rule-container,.query-builder .rule-placeholder,.query-builder .rules-group-container{position:relative;margin:4px 0;border-radius:5px;padding:5px;border:1px solid #eee;background:rgba(255,255,255,.9)}.query-builder .drag-handle,.query-builder .error-container,.query-builder .rule-container .rule-filter-container,.query-builder .rule-container .rule-operator-container,.query-builder .rule-container .rule-value-container{display:inline-block;margin:0 5px 0 0;vertical-align:middle}.query-builder .rules-group-container{padding:10px;padding-bottom:6px;border:1px solid #dcc896;background:rgba(250,240,210,.5)}.query-builder .rules-group-header{margin-bottom:10px}.query-builder .rules-group-header .group-conditions .btn.readonly:not(.active),.query-builder .rules-group-header .group-conditions input[name$='_cond']{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.query-builder .rules-group-header .group-conditions .btn.readonly{border-radius:3px}.query-builder .rules-list{list-style:none;padding:0 0 0 15px;margin:0}.query-builder .rule-value-container{border-left:1px solid #ddd;padding-left:5px}.query-builder .rule-value-container label{margin-bottom:0;font-weight:400}.query-builder .rule-value-container label.block{display:block}.query-builder .rule-value-container input[type=number],.query-builder .rule-value-container input[type=text],.query-builder .rule-value-container select{padding:1px}.query-builder .error-container{display:none;cursor:help;color:red}.query-builder .has-error{background-color:#fdd;border-color:#f99}.query-builder .has-error .error-container{display:inline-block!important}.query-builder .rules-list>::after,.query-builder .rules-list>::before{content:'';position:absolute;left:-10px;width:10px;height:calc(50% + 4px);border-color:#ccc;border-style:solid}.query-builder .rules-list>::before{top:-4px;border-width:0 0 2px 2px}.query-builder .rules-list>::after{top:50%;border-width:0 0 0 2px}.query-builder .rules-list>:first-child::before{top:-12px;height:calc(50% + 14px)}.query-builder .rules-list>:last-child::before{border-radius:0 0 0 4px}.query-builder .rules-list>:last-child::after{display:none}.query-builder.bt-checkbox-glyphicons .checkbox input[type=checkbox]:checked+label::after{font-family:'Glyphicons Halflings';content:'\e013'}.query-builder.bt-checkbox-glyphicons .checkbox label::after{padding-left:4px;padding-top:2px;font-size:9px}.query-builder .error-container+.tooltip .tooltip-inner{color:#f99!important}.query-builder p.filter-description{margin:5px 0 0 0;background:#d9edf7;border:1px solid #bce8f1;color:#31708f;border-radius:5px;padding:2.5px 5px;font-size:.8em}.query-builder .rules-group-header [data-invert]{margin-left:5px}.query-builder .drag-handle{cursor:move;vertical-align:middle;margin-left:5px}.query-builder .dragging{position:fixed;opacity:.5;z-index:100}.query-builder .dragging::after,.query-builder .dragging::before{display:none}.query-builder .rule-placeholder{border:1px dashed #bbb;opacity:.7}
\ No newline at end of file
diff --git a/dist/i18n/query-builder.ar.js b/dist/i18n/query-builder.ar.js
new file mode 100644
index 00000000..0ae131d5
--- /dev/null
+++ b/dist/i18n/query-builder.ar.js
@@ -0,0 +1,80 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Arabic (ar)
+ * Author: Mohamed YOUNES, https://github.com/MedYOUNES
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['ar'] = {
+ "__locale": "Arabic (ar)",
+ "__author": "Mohamed YOUNES, https://github.com/MedYOUNES",
+ "add_rule": "إضافة حُكم",
+ "add_group": "إضافة زُمْرَة",
+ "delete_rule": "حذف",
+ "delete_group": "حذف",
+ "conditions": {
+ "AND": "و",
+ "OR": "أو"
+ },
+ "operators": {
+ "equal": "يساوي",
+ "not_equal": "غير مساوٍ",
+ "in": "في",
+ "not_in": "ليس في",
+ "less": "أقل من",
+ "less_or_equal": "أصغر أو مساو",
+ "greater": "أكبر",
+ "greater_or_equal": "أكبر أو مساو",
+ "between": "محصور بين",
+ "not_between": "غير محصور بين",
+ "begins_with": "يبدأ بـ",
+ "not_begins_with": "لا يبدأ بـ",
+ "contains": "يحتوي على",
+ "not_contains": "لا يحتوي على",
+ "ends_with": "ينتهي بـ",
+ "not_ends_with": "لا ينتهي بـ",
+ "is_empty": "فارغ",
+ "is_not_empty": "غير فارغ",
+ "is_null": "صفر",
+ "is_not_null": "ليس صفرا"
+ },
+ "errors": {
+ "no_filter": "لم تحدد أي مرشح",
+ "empty_group": "الزمرة فارغة",
+ "radio_empty": "لم تحدد أي قيمة",
+ "checkbox_empty": "لم تحدد أي قيمة",
+ "select_empty": "لم تحدد أي قيمة",
+ "string_empty": "النص فارغ",
+ "string_exceed_min_length": "النص دون الأدنى المسموح به",
+ "string_exceed_max_length": "النص فوق الأقصى المسموح به",
+ "string_invalid_format": "تركيبة غير صحيحة",
+ "number_nan": "ليس عددا",
+ "number_not_integer": "ليس عددا صحيحا",
+ "number_not_double": "ليس عددا كسريا",
+ "number_exceed_min": "العدد أصغر من الأدنى المسموح به",
+ "number_exceed_max": "العدد أكبر من الأقصى المسموح به",
+ "number_wrong_step": "أخطأت في حساب مضاعفات العدد",
+ "datetime_empty": "لم تحدد التاريخ",
+ "datetime_invalid": "صيغة التاريخ غير صحيحة",
+ "datetime_exceed_min": "التاريخ دون الأدنى المسموح به",
+ "datetime_exceed_max": "التاريخ أكبر من الأقصى المسموح به",
+ "boolean_not_valid": "ليست قيمة منطقية ثنائية",
+ "operator_not_multiple": "العامل ليس متعدد القيَم"
+ },
+ "invert": "قَلْبُ"
+};
+
+QueryBuilder.defaults({ lang_code: 'ar' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.az.js b/dist/i18n/query-builder.az.js
new file mode 100644
index 00000000..8ffdfe1f
--- /dev/null
+++ b/dist/i18n/query-builder.az.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Azerbaijan (az)
+ * Author: Megaplan, mborisv
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['az'] = {
+ "__locale": "Azerbaijan (az)",
+ "__author": "Megaplan, mborisv ",
+ "add_rule": "Əlavə etmək",
+ "add_group": "Qrup əlavə etmək",
+ "delete_rule": "Silmək",
+ "delete_group": "Silmək",
+ "conditions": {
+ "AND": "VƏ",
+ "OR": "VƏ YA"
+ },
+ "operators": {
+ "equal": "bərabərdir",
+ "not_equal": "bərabər deyil",
+ "in": "qeyd edilmişlərdən",
+ "not_in": "qeyd olunmamışlardan",
+ "less": "daha az",
+ "less_or_equal": "daha az və ya bərabər",
+ "greater": "daha çox",
+ "greater_or_equal": "daha çox və ya bərabər",
+ "between": "arasında",
+ "begins_with": "başlayır",
+ "not_begins_with": "başlamır",
+ "contains": "ibarətdir",
+ "not_contains": "yoxdur",
+ "ends_with": "başa çatır",
+ "not_ends_with": "başa çatmır",
+ "is_empty": "boş sətir",
+ "is_not_empty": "boş olmayan sətir",
+ "is_null": "boşdur",
+ "is_not_null": "boş deyil"
+ },
+ "errors": {
+ "no_filter": "Filterlər seçilməyib",
+ "empty_group": "Qrup boşdur",
+ "radio_empty": "Məna seçilməyib",
+ "checkbox_empty": "Məna seçilməyib",
+ "select_empty": "Məna seçilməyib",
+ "string_empty": "Doldurulmayıb",
+ "string_exceed_min_length": "{0} daha çox simvol olmalıdır",
+ "string_exceed_max_length": "{0} daha az simvol olmalıdır",
+ "string_invalid_format": "Yanlış format ({0})",
+ "number_nan": "Rəqəm deyil",
+ "number_not_integer": "Rəqəm deyil",
+ "number_not_double": "Rəqəm deyil",
+ "number_exceed_min": "{0} daha çox olmalıdır",
+ "number_exceed_max": "{0} daha az olmalıdır",
+ "number_wrong_step": "{0} bölünən olmalıdır",
+ "datetime_empty": "Doldurulmayıb",
+ "datetime_invalid": "Yanlış tarix formatı ({0})",
+ "datetime_exceed_min": "{0} sonra olmalıdır",
+ "datetime_exceed_max": "{0} əvvəl olmalıdır",
+ "boolean_not_valid": "Loqik olmayan",
+ "operator_not_multiple": "\"{1}\" operatoru çoxlu məna daşımır"
+ },
+ "invert": "invert"
+};
+
+QueryBuilder.defaults({ lang_code: 'az' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.bg.js b/dist/i18n/query-builder.bg.js
new file mode 100644
index 00000000..f47fad4f
--- /dev/null
+++ b/dist/i18n/query-builder.bg.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Bulgarian (bg)
+ * Author: Valentin Hristov
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['bg'] = {
+ "__locale": "Bulgarian (bg)",
+ "__author": "Valentin Hristov",
+ "add_rule": "Добави правило",
+ "add_group": "Добави група",
+ "delete_rule": "Изтрий",
+ "delete_group": "Изтрий",
+ "conditions": {
+ "AND": "И",
+ "OR": "ИЛИ"
+ },
+ "operators": {
+ "equal": "равно",
+ "not_equal": "различно",
+ "in": "в",
+ "not_in": "не е в",
+ "less": "по-малко",
+ "less_or_equal": "по-малко или равно",
+ "greater": "по-голям",
+ "greater_or_equal": "по-голям или равно",
+ "between": "между",
+ "not_between": "не е между",
+ "begins_with": "започва с",
+ "not_begins_with": "не започва с",
+ "contains": "съдържа",
+ "not_contains": "не съдържа",
+ "ends_with": "завършва с",
+ "not_ends_with": "не завършва с",
+ "is_empty": "е празно",
+ "is_not_empty": "не е празно",
+ "is_null": "е нищо",
+ "is_not_null": "различно от нищо"
+ },
+ "errors": {
+ "no_filter": "Не е избран филтър",
+ "empty_group": "Групата е празна",
+ "radio_empty": "Не е селектирана стойност",
+ "checkbox_empty": "Не е селектирана стойност",
+ "select_empty": "Не е селектирана стойност",
+ "string_empty": "Празна стойност",
+ "string_exceed_min_length": "Необходимо е да съдържа поне {0} символа",
+ "string_exceed_max_length": "Необходимо е да съдържа повече от {0} символа",
+ "string_invalid_format": "Невалиден формат ({0})",
+ "number_nan": "Не е число",
+ "number_not_integer": "Не е цяло число",
+ "number_not_double": "Не е реално число",
+ "number_exceed_min": "Трябва да е по-голямо от {0}",
+ "number_exceed_max": "Трябва да е по-малко от {0}",
+ "number_wrong_step": "Трябва да е кратно на {0}",
+ "datetime_empty": "Празна стойност",
+ "datetime_invalid": "Невалиден формат на дата ({0})",
+ "datetime_exceed_min": "Трябва да е след {0}",
+ "datetime_exceed_max": "Трябва да е преди {0}",
+ "boolean_not_valid": "Не е булева",
+ "operator_not_multiple": "Оператора \"{1}\" не може да приеме множество стойности"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'bg' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.cs.js b/dist/i18n/query-builder.cs.js
new file mode 100644
index 00000000..7b1c55a1
--- /dev/null
+++ b/dist/i18n/query-builder.cs.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Čeština (cs)
+ * Author: Megaplan, mborisv
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['cs'] = {
+ "__locale": "Čeština (cs)",
+ "__author": "Megaplan, mborisv ",
+ "add_rule": "Přidat",
+ "add_group": "Přidat skupinu",
+ "delete_rule": "Odstranit",
+ "delete_group": "Odstranit skupinu",
+ "conditions": {
+ "AND": "I",
+ "OR": "NEBO"
+ },
+ "operators": {
+ "equal": "stejně",
+ "not_equal": "liší se",
+ "in": "z uvedených",
+ "not_in": "ne z uvedených",
+ "less": "méně",
+ "less_or_equal": "méně nebo stejně",
+ "greater": "více",
+ "greater_or_equal": "více nebo stejně",
+ "between": "mezi",
+ "begins_with": "začíná z",
+ "not_begins_with": "nezačíná z",
+ "contains": "obsahuje",
+ "not_contains": "neobsahuje",
+ "ends_with": "končí na",
+ "not_ends_with": "nekončí na",
+ "is_empty": "prázdný řádek",
+ "is_not_empty": "neprázdný řádek",
+ "is_null": "prázdno",
+ "is_not_null": "plno"
+ },
+ "errors": {
+ "no_filter": "není vybraný filtr",
+ "empty_group": "prázdná skupina",
+ "radio_empty": "Není udaná hodnota",
+ "checkbox_empty": "Není udaná hodnota",
+ "select_empty": "Není udaná hodnota",
+ "string_empty": "Nevyplněno",
+ "string_exceed_min_length": "Musí obsahovat více {0} symbolů",
+ "string_exceed_max_length": "Musí obsahovat méně {0} symbolů",
+ "string_invalid_format": "Nesprávný formát ({0})",
+ "number_nan": "Žádné číslo",
+ "number_not_integer": "Žádné číslo",
+ "number_not_double": "Žádné číslo",
+ "number_exceed_min": "Musí být více {0}",
+ "number_exceed_max": "Musí být méně {0}",
+ "number_wrong_step": "Musí být násobkem {0}",
+ "datetime_empty": "Nevyplněno",
+ "datetime_invalid": "Nesprávný formát datumu ({0})",
+ "datetime_exceed_min": "Musí být po {0}",
+ "datetime_exceed_max": "Musí být do {0}",
+ "boolean_not_valid": "Nelogické",
+ "operator_not_multiple": "Operátor \"{1}\" nepodporuje mnoho hodnot"
+ },
+ "invert": "invertní"
+};
+
+QueryBuilder.defaults({ lang_code: 'cs' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.da.js b/dist/i18n/query-builder.da.js
new file mode 100644
index 00000000..2c73f9e0
--- /dev/null
+++ b/dist/i18n/query-builder.da.js
@@ -0,0 +1,56 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Danish (da)
+ * Author: Jna Borup Coyle, github@coyle.dk
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['da'] = {
+ "__locale": "Danish (da)",
+ "__author": "Jna Borup Coyle, github@coyle.dk",
+ "add_rule": "Tilføj regel",
+ "add_group": "Tilføj gruppe",
+ "delete_rule": "Slet regel",
+ "delete_group": "Slet gruppe",
+ "conditions": {
+ "AND": "OG",
+ "OR": "ELLER"
+ },
+ "condition_and": "OG",
+ "condition_or": "ELLER",
+ "operators": {
+ "equal": "lig med",
+ "not_equal": "ikke lige med",
+ "in": "i",
+ "not_in": "ikke i",
+ "less": "mindre",
+ "less_or_equal": "mindre eller lig med",
+ "greater": "større",
+ "greater_or_equal": "større eller lig med",
+ "begins_with": "begynder med",
+ "not_begins_with": "begynder ikke med",
+ "contains": "indeholder",
+ "not_contains": "indeholder ikke",
+ "ends_with": "slutter med",
+ "not_ends_with": "slutter ikke med",
+ "is_empty": "er tom",
+ "is_not_empty": "er ikke tom",
+ "is_null": "er null",
+ "is_not_null": "er ikke null"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'da' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.de.js b/dist/i18n/query-builder.de.js
new file mode 100644
index 00000000..7f9eb0a4
--- /dev/null
+++ b/dist/i18n/query-builder.de.js
@@ -0,0 +1,76 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: German (de)
+ * Author: "raimu"
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['de'] = {
+ "__locale": "German (de)",
+ "__author": "\"raimu\"",
+ "add_rule": "neue Regel",
+ "add_group": "neue Gruppe",
+ "delete_rule": "löschen",
+ "delete_group": "löschen",
+ "conditions": {
+ "AND": "UND",
+ "OR": "ODER"
+ },
+ "operators": {
+ "equal": "gleich",
+ "not_equal": "ungleich",
+ "in": "in",
+ "not_in": "nicht in",
+ "less": "kleiner",
+ "less_or_equal": "kleiner gleich",
+ "greater": "größer",
+ "greater_or_equal": "größer gleich",
+ "between": "zwischen",
+ "not_between": "nicht zwischen",
+ "begins_with": "beginnt mit",
+ "not_begins_with": "beginnt nicht mit",
+ "contains": "enthält",
+ "not_contains": "enthält nicht",
+ "ends_with": "endet mit",
+ "not_ends_with": "endet nicht mit",
+ "is_empty": "ist leer",
+ "is_not_empty": "ist nicht leer",
+ "is_null": "ist null",
+ "is_not_null": "ist nicht null"
+ },
+ "errors": {
+ "no_filter": "Kein Filter ausgewählt",
+ "empty_group": "Die Gruppe ist leer",
+ "radio_empty": "Kein Wert ausgewählt",
+ "checkbox_empty": "Kein Wert ausgewählt",
+ "select_empty": "Kein Wert ausgewählt",
+ "string_empty": "Leerer Wert",
+ "string_exceed_min_length": "Muss mindestens {0} Zeichen enthalten",
+ "string_exceed_max_length": "Darf nicht mehr als {0} Zeichen enthalten",
+ "string_invalid_format": "Ungültiges Format ({0})",
+ "number_nan": "Keine Zahl",
+ "number_not_integer": "Keine Ganzzahl",
+ "number_not_double": "Keine Dezimalzahl",
+ "number_exceed_min": "Muss größer als {0} sein",
+ "number_exceed_max": "Muss kleiner als {0} sein",
+ "number_wrong_step": "Muss ein Vielfaches von {0} sein",
+ "datetime_invalid": "Ungültiges Datumsformat ({0})",
+ "datetime_exceed_min": "Muss nach dem {0} sein",
+ "datetime_exceed_max": "Muss vor dem {0} sein"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'de' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.el.js b/dist/i18n/query-builder.el.js
new file mode 100644
index 00000000..f8521d81
--- /dev/null
+++ b/dist/i18n/query-builder.el.js
@@ -0,0 +1,80 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Greek (el)
+ * Author: Stelios Patsatzis, https://www.linkedin.com/in/stelios-patsatzis-89841561
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['el'] = {
+ "__locale": "Greek (el)",
+ "__author": "Stelios Patsatzis, https://www.linkedin.com/in/stelios-patsatzis-89841561",
+ "add_rule": "Προσθήκη Συνθήκης",
+ "add_group": "Προσθήκη Ομάδας",
+ "delete_rule": "Διαγραφή",
+ "delete_group": "Διαγραφή",
+ "conditions": {
+ "AND": "Λογικό ΚΑΙ",
+ "OR": "Λογικό Η"
+ },
+ "operators": {
+ "equal": "Ισούται με",
+ "not_equal": "Διάφορο από ",
+ "in": "Περιέχει",
+ "not_in": "Δεν Περιέχει",
+ "less": "Λιγότερο από",
+ "less_or_equal": "Λιγότερο ή Ίσο",
+ "greater": "Μεγαλύτερο από",
+ "greater_or_equal": "Μεγαλύτερο ή Ίσο",
+ "between": "Μεταξύ",
+ "not_between": "Εκτός",
+ "begins_with": "Αρχίζει με",
+ "not_begins_with": "Δεν αρχίζει με",
+ "contains": "Περιέχει",
+ "not_contains": "Δεν περιέχει",
+ "ends_with": "Τελειώνει σε",
+ "not_ends_with": "Δεν τελειώνει σε",
+ "is_empty": "Είναι άδειο",
+ "is_not_empty": "Δεν είναι άδειο",
+ "is_null": "Είναι NULL",
+ "is_not_null": "Δεν είναι NULL"
+ },
+ "errors": {
+ "no_filter": "Χωρίς φίλτρα",
+ "empty_group": "Άδεια ομάδα",
+ "radio_empty": "Χωρίς τιμή",
+ "checkbox_empty": "Χωρίς τιμή",
+ "select_empty": "Χωρίς τιμή",
+ "string_empty": "Χωρίς τιμή",
+ "string_exceed_min_length": "Ελάχιστο όριο {0} χαρακτήρων",
+ "string_exceed_max_length": "Μέγιστο όριο {0} χαρακτήρων",
+ "string_invalid_format": "Λανθασμένη μορφή ({0})",
+ "number_nan": "Δεν είναι αριθμός",
+ "number_not_integer": "Δεν είναι ακέραιος αριθμός",
+ "number_not_double": "Δεν είναι πραγματικός αριθμός",
+ "number_exceed_min": "Πρέπει να είναι μεγαλύτερο απο {0}",
+ "number_exceed_max": "Πρέπει να είναι μικρότερο απο {0}",
+ "number_wrong_step": "Πρέπει να είναι πολλαπλάσιο του {0}",
+ "datetime_empty": "Χωρίς τιμή",
+ "datetime_invalid": "Λανθασμένη μορφή ημερομηνίας ({0})",
+ "datetime_exceed_min": "Νεότερο από {0}",
+ "datetime_exceed_max": "Παλαιότερο από {0}",
+ "boolean_not_valid": "Δεν είναι BOOLEAN",
+ "operator_not_multiple": "Η συνθήκη \"{1}\" δεν μπορεί να δεχθεί πολλαπλές τιμές"
+ },
+ "invert": "Εναλλαγή"
+};
+
+QueryBuilder.defaults({ lang_code: 'el' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.en.js b/dist/i18n/query-builder.en.js
new file mode 100644
index 00000000..c699789a
--- /dev/null
+++ b/dist/i18n/query-builder.en.js
@@ -0,0 +1,83 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: English (en)
+ * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['en'] = {
+ "__locale": "English (en)",
+ "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr",
+ "add_rule": "Add rule",
+ "add_group": "Add group",
+ "delete_rule": "Delete",
+ "delete_group": "Delete",
+ "conditions": {
+ "AND": "AND",
+ "OR": "OR"
+ },
+ "operators": {
+ "equal": "equal",
+ "not_equal": "not equal",
+ "in": "in",
+ "not_in": "not in",
+ "less": "less",
+ "less_or_equal": "less or equal",
+ "greater": "greater",
+ "greater_or_equal": "greater or equal",
+ "between": "between",
+ "not_between": "not between",
+ "begins_with": "begins with",
+ "not_begins_with": "doesn't begin with",
+ "contains": "contains",
+ "not_contains": "doesn't contain",
+ "ends_with": "ends with",
+ "not_ends_with": "doesn't end with",
+ "is_empty": "is empty",
+ "is_not_empty": "is not empty",
+ "is_null": "is null",
+ "is_not_null": "is not null"
+ },
+ "errors": {
+ "no_filter": "No filter selected",
+ "empty_group": "The group is empty",
+ "radio_empty": "No value selected",
+ "checkbox_empty": "No value selected",
+ "select_empty": "No value selected",
+ "string_empty": "Input field cannot be blank",
+ "string_exceed_min_length": "Must contain at least {0} characters",
+ "string_exceed_max_length": "Must not contain more than {0} characters",
+ "string_invalid_format": "Invalid format ({0})",
+ "number_nan": "Not a number",
+ "number_not_integer": "This field must contain numbers 0-9. No letters, spaces, or special characters allowed.",
+ "number_not_double": "This field must contain numbers 0-9 with decimals separated by point “.” - For Example 10 or 50.60. No letters, spaces, or special characters allowed.",
+ "number_exceed_min": "Must be greater than {0}",
+ "number_exceed_max": "Must be lower than {0}",
+ "number_wrong_step": "Must be a multiple of {0}",
+ "number_between_invalid": "Invalid values, {0} is greater than {1}",
+ "datetime_empty": "Input field cannot be blank",
+ "datetime_invalid": "Invalid date format ({0})",
+ "datetime_exceed_min": "Must be after {0}",
+ "datetime_exceed_max": "Must be before {0}",
+ "datetime_between_invalid": "Invalid values, {0} is greater than {1}",
+ "boolean_not_valid": "Not a boolean",
+ "operator_not_multiple": "Operator \"{1}\" cannot accept multiple values"
+ },
+ "invert": "Invert",
+ "NOT": "NOT"
+};
+
+QueryBuilder.defaults({ lang_code: 'en' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.es.js b/dist/i18n/query-builder.es.js
new file mode 100644
index 00000000..d9075cc5
--- /dev/null
+++ b/dist/i18n/query-builder.es.js
@@ -0,0 +1,81 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Spanish (es)
+ * Author: "pyarza", "kddlb"
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['es'] = {
+ "__locale": "Spanish (es)",
+ "__author": "\"pyarza\", \"kddlb\"",
+ "add_rule": "Añadir regla",
+ "add_group": "Añadir grupo",
+ "delete_rule": "Borrar",
+ "delete_group": "Borrar",
+ "conditions": {
+ "AND": "Y",
+ "OR": "O"
+ },
+ "operators": {
+ "equal": "igual",
+ "not_equal": "distinto",
+ "in": "en",
+ "not_in": "no en",
+ "less": "menor",
+ "less_or_equal": "menor o igual",
+ "greater": "mayor",
+ "greater_or_equal": "mayor o igual",
+ "between": "entre",
+ "not_between": "no está entre",
+ "begins_with": "empieza por",
+ "not_begins_with": "no empieza por",
+ "contains": "contiene",
+ "not_contains": "no contiene",
+ "ends_with": "acaba con",
+ "not_ends_with": "no acaba con",
+ "is_empty": "está vacío",
+ "is_not_empty": "no está vacío",
+ "is_null": "es nulo",
+ "is_not_null": "no es nulo"
+ },
+ "errors": {
+ "no_filter": "No se ha seleccionado ningún filtro",
+ "empty_group": "El grupo está vacío",
+ "radio_empty": "Ningún valor seleccionado",
+ "checkbox_empty": "Ningún valor seleccionado",
+ "select_empty": "Ningún valor seleccionado",
+ "string_empty": "Cadena vacía",
+ "string_exceed_min_length": "Debe contener al menos {0} caracteres",
+ "string_exceed_max_length": "No debe contener más de {0} caracteres",
+ "string_invalid_format": "Formato inválido ({0})",
+ "number_nan": "No es un número",
+ "number_not_integer": "No es un número entero",
+ "number_not_double": "No es un número real",
+ "number_exceed_min": "Debe ser mayor que {0}",
+ "number_exceed_max": "Debe ser menor que {0}",
+ "number_wrong_step": "Debe ser múltiplo de {0}",
+ "datetime_invalid": "Formato de fecha inválido ({0})",
+ "datetime_exceed_min": "Debe ser posterior a {0}",
+ "datetime_exceed_max": "Debe ser anterior a {0}",
+ "number_between_invalid": "Valores Inválidos, {0} es mayor que {1}",
+ "datetime_empty": "Campo vacio",
+ "datetime_between_invalid": "Valores Inválidos, {0} es mayor que {1}",
+ "boolean_not_valid": "No es booleano",
+ "operator_not_multiple": "El operador \"{1}\" no puede aceptar valores multiples"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'es' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.fa-IR.js b/dist/i18n/query-builder.fa-IR.js
new file mode 100644
index 00000000..3116c55e
--- /dev/null
+++ b/dist/i18n/query-builder.fa-IR.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Farsi (fa-ir)
+ * Author: Behzad Sedighzade, behzad.sedighzade@gmail.com
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['fa-IR'] = {
+ "__locale": "Farsi (fa-ir)",
+ "__author": "Behzad Sedighzade, behzad.sedighzade@gmail.com",
+ "add_rule": "افزودن قاعده",
+ "add_group": "افزودن گروه",
+ "delete_rule": "حذف قاعده",
+ "delete_group": "حذف گروه",
+ "conditions": {
+ "AND": "و",
+ "OR": "یا"
+ },
+ "operators": {
+ "equal": "برابر با",
+ "not_equal": "مخالف",
+ "in": "شامل مجموعه شود",
+ "not_in": "شامل مجموعه نشود",
+ "less": "کمتر از",
+ "less_or_equal": "کمتر یا مساوی با",
+ "greater": "بزرگتر از",
+ "greater_or_equal": "بزرگتر یا مساوی با",
+ "between": "مابین",
+ "not_between": "مابین نباشد",
+ "begins_with": "شروع شود با",
+ "not_begins_with": "شروع نشود با",
+ "contains": "شامل شود",
+ "not_contains": "شامل نشود",
+ "ends_with": "خاتمه یابد با",
+ "not_ends_with": "خاتمه نیابد با",
+ "is_empty": "خالی باشد",
+ "is_not_empty": "خالی نباشد",
+ "is_null": "باشد ( null ) پوچ",
+ "is_not_null": "نباشد( null ) پوچ "
+ },
+ "errors": {
+ "no_filter": "هیچ قاعده ای انتخاب نشده است",
+ "empty_group": "گروه خالی است",
+ "radio_empty": "مقداری انتخاب نشده است",
+ "checkbox_empty": "مقداری انتخاب نشده است",
+ "select_empty": "مقداری انتخاب نشده است",
+ "string_empty": "مقدار متنی خالی است",
+ "string_exceed_min_length": "رشته حداقل باید {0} عدد حرف داشته باشد",
+ "string_exceed_max_length": "رشته حداکثر {0} عدد حرف می تواند قبول کند",
+ "string_invalid_format": "قالب رشته {0} نامعتبر ست",
+ "number_nan": "عدد وارد کنید",
+ "number_not_integer": "مقدار صحیح وارد کنید",
+ "number_not_double": "مقدار اعشاری وارد کنید",
+ "number_exceed_min": "باید از {0} بزرگتر باشد",
+ "number_exceed_max": "باید از {0} کمتر باشد",
+ "number_wrong_step": "باید مضربی از {0} باشد",
+ "datetime_empty": "مقدار تاریخ خالی وارد شده!",
+ "datetime_invalid": "قالب تاریخ ( {0} ) اشتباه است",
+ "datetime_exceed_min": "باید بعد از {0} باشد",
+ "datetime_exceed_max": "باید قبل از {0} باشد",
+ "boolean_not_valid": "مقدار دودویی وارد کنید",
+ "operator_not_multiple": "اپراتور \"{1}\" نمی تواند چند مقدار قبول کند"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'fa-IR' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.fr.js b/dist/i18n/query-builder.fr.js
new file mode 100644
index 00000000..868b31cf
--- /dev/null
+++ b/dist/i18n/query-builder.fr.js
@@ -0,0 +1,83 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: French (fr)
+ * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['fr'] = {
+ "__locale": "French (fr)",
+ "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr",
+ "add_rule": "Ajouter une règle",
+ "add_group": "Ajouter un groupe",
+ "delete_rule": "Supprimer",
+ "delete_group": "Supprimer",
+ "conditions": {
+ "AND": "ET",
+ "OR": "OU"
+ },
+ "operators": {
+ "equal": "est égal à",
+ "not_equal": "n'est pas égal à",
+ "in": "est compris dans",
+ "not_in": "n'est pas compris dans",
+ "less": "est inférieur à",
+ "less_or_equal": "est inférieur ou égal à",
+ "greater": "est supérieur à",
+ "greater_or_equal": "est supérieur ou égal à",
+ "between": "est entre",
+ "not_between": "n'est pas entre",
+ "begins_with": "commence par",
+ "not_begins_with": "ne commence pas par",
+ "contains": "contient",
+ "not_contains": "ne contient pas",
+ "ends_with": "finit par",
+ "not_ends_with": "ne finit pas par",
+ "is_empty": "est vide",
+ "is_not_empty": "n'est pas vide",
+ "is_null": "est nul",
+ "is_not_null": "n'est pas nul"
+ },
+ "errors": {
+ "no_filter": "Aucun filtre sélectionné",
+ "empty_group": "Le groupe est vide",
+ "radio_empty": "Pas de valeur selectionnée",
+ "checkbox_empty": "Pas de valeur selectionnée",
+ "select_empty": "Pas de valeur selectionnée",
+ "string_empty": "Valeur vide",
+ "string_exceed_min_length": "Doit contenir au moins {0} caractères",
+ "string_exceed_max_length": "Ne doit pas contenir plus de {0} caractères",
+ "string_invalid_format": "Format invalide ({0})",
+ "number_nan": "N'est pas un nombre",
+ "number_not_integer": "N'est pas un entier",
+ "number_not_double": "N'est pas un nombre réel",
+ "number_exceed_min": "Doit être plus grand que {0}",
+ "number_exceed_max": "Doit être plus petit que {0}",
+ "number_wrong_step": "Doit être un multiple de {0}",
+ "number_between_invalid": "Valeurs invalides, {0} est plus grand que {1}",
+ "datetime_empty": "Valeur vide",
+ "datetime_invalid": "Fomat de date invalide ({0})",
+ "datetime_exceed_min": "Doit être après {0}",
+ "datetime_exceed_max": "Doit être avant {0}",
+ "datetime_between_invalid": "Valeurs invalides, {0} est plus grand que {1}",
+ "boolean_not_valid": "N'est pas un booléen",
+ "operator_not_multiple": "L'opérateur \"{1}\" ne peut utiliser plusieurs valeurs"
+ },
+ "invert": "Inverser",
+ "NOT": "NON"
+};
+
+QueryBuilder.defaults({ lang_code: 'fr' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.he.js b/dist/i18n/query-builder.he.js
new file mode 100644
index 00000000..5279fff4
--- /dev/null
+++ b/dist/i18n/query-builder.he.js
@@ -0,0 +1,81 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Hebrew (he)
+ * Author: Kfir Stri https://github.com/kfirstri
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['he'] = {
+ "__locale": "Hebrew (he)",
+ "__author": "Kfir Stri https://github.com/kfirstri",
+ "add_rule": "הוסף כלל",
+ "add_group": "הוסף קבוצה",
+ "delete_rule": "מחק",
+ "delete_group": "מחק",
+ "conditions": {
+ "AND": "וגם",
+ "OR": "או"
+ },
+ "operators": {
+ "equal": "שווה ל",
+ "not_equal": "שונה מ",
+ "in": "חלק מ",
+ "not_in": "לא חלק מ",
+ "less": "פחות מ",
+ "less_or_equal": "פחות או שווה ל",
+ "greater": "גדול מ",
+ "greater_or_equal": "גדול או שווה ל",
+ "between": "בין",
+ "not_between": "לא בין",
+ "begins_with": "מתחיל ב",
+ "not_begins_with": "לא מתחיל ב",
+ "contains": "מכיל",
+ "not_contains": "לא מכיל",
+ "ends_with": "מסתיים ב",
+ "not_ends_with": "לא מסתיים ב",
+ "is_empty": "ריק",
+ "is_not_empty": "לא ריק",
+ "is_null": "חסר ערך",
+ "is_not_null": "לא חסר ערך"
+ },
+ "errors": {
+ "no_filter": "לא נבחרו מסננים",
+ "empty_group": "הקבוצה רירקה",
+ "radio_empty": "לא נבחר אף ערך",
+ "checkbox_empty": "לא נבחר אף ערך",
+ "select_empty": "לא נבחר אף ערך",
+ "string_empty": "חסר ערך",
+ "string_exceed_min_length": "המחרוזת חייבת להכיל לפחות {0} תווים",
+ "string_exceed_max_length": "המחרוזת לא יכולה להכיל יותר מ{0} תווים",
+ "string_invalid_format": "המחרוזת בפורמט שגוי ({0})",
+ "number_nan": "זהו לא מספר",
+ "number_not_integer": "המספר אינו מספר שלם",
+ "number_not_double": "המספר אינו מספר עשרוני",
+ "number_exceed_min": "המספר צריך להיות גדול מ {0}",
+ "number_exceed_max": "המספר צריך להיות קטן מ{0}",
+ "number_wrong_step": "המספר צריך להיות כפולה של {0}",
+ "datetime_empty": "תאריך ריק",
+ "datetime_invalid": "פורמט תאריך שגוי ({0})",
+ "datetime_exceed_min": "התאריך חייב להיות אחרי {0}",
+ "datetime_exceed_max": "התאריך חייב להיות לפני {0}",
+ "boolean_not_valid": "זהו לא בוליאני",
+ "operator_not_multiple": "האופרטור \"{1}\" לא יכול לקבל ערכים מרובים"
+ },
+ "invert": "הפוך שאילתא",
+ "NOT": "לא"
+};
+
+QueryBuilder.defaults({ lang_code: 'he' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.it.js b/dist/i18n/query-builder.it.js
new file mode 100644
index 00000000..f5be7698
--- /dev/null
+++ b/dist/i18n/query-builder.it.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Italian (it)
+ * Author: davegraziosi
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['it'] = {
+ "__locale": "Italian (it)",
+ "__author": "davegraziosi",
+ "add_rule": "Aggiungi regola",
+ "add_group": "Aggiungi gruppo",
+ "delete_rule": "Elimina",
+ "delete_group": "Elimina",
+ "conditions": {
+ "AND": "E",
+ "OR": "O"
+ },
+ "operators": {
+ "equal": "uguale",
+ "not_equal": "non uguale",
+ "in": "in",
+ "not_in": "non in",
+ "less": "minore",
+ "less_or_equal": "minore o uguale",
+ "greater": "maggiore",
+ "greater_or_equal": "maggiore o uguale",
+ "between": "compreso tra",
+ "not_between": "non compreso tra",
+ "begins_with": "inizia con",
+ "not_begins_with": "non inizia con",
+ "contains": "contiene",
+ "not_contains": "non contiene",
+ "ends_with": "finisce con",
+ "not_ends_with": "non finisce con",
+ "is_empty": "è vuoto",
+ "is_not_empty": "non è vuoto",
+ "is_null": "è nullo",
+ "is_not_null": "non è nullo"
+ },
+ "errors": {
+ "no_filter": "Nessun filtro selezionato",
+ "empty_group": "Il gruppo è vuoto",
+ "radio_empty": "No value selected",
+ "checkbox_empty": "Nessun valore selezionato",
+ "select_empty": "Nessun valore selezionato",
+ "string_empty": "Valore vuoto",
+ "string_exceed_min_length": "Deve contenere almeno {0} caratteri",
+ "string_exceed_max_length": "Non deve contenere più di {0} caratteri",
+ "string_invalid_format": "Formato non valido ({0})",
+ "number_nan": "Non è un numero",
+ "number_not_integer": "Non è un intero",
+ "number_not_double": "Non è un numero con la virgola",
+ "number_exceed_min": "Deve essere maggiore di {0}",
+ "number_exceed_max": "Deve essere minore di {0}",
+ "number_wrong_step": "Deve essere multiplo di {0}",
+ "datetime_empty": "Valore vuoto",
+ "datetime_invalid": "Formato data non valido ({0})",
+ "datetime_exceed_min": "Deve essere successivo a {0}",
+ "datetime_exceed_max": "Deve essere precedente a {0}",
+ "boolean_not_valid": "Non è un booleano",
+ "operator_not_multiple": "L'Operatore {0} non può accettare valori multipli"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'it' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.lt.js b/dist/i18n/query-builder.lt.js
new file mode 100644
index 00000000..99f9779f
--- /dev/null
+++ b/dist/i18n/query-builder.lt.js
@@ -0,0 +1,83 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Lithuanian (lt)
+ * Author: Dalius Guzauskas (aka Tichij), https://lt.linkedin.com/in/daliusg
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['lt'] = {
+ "__locale": "Lithuanian (lt)",
+ "__author": "Dalius Guzauskas (aka Tichij), https://lt.linkedin.com/in/daliusg",
+ "add_rule": "Pridėti taisyklę",
+ "add_group": "Pridėti grupę",
+ "delete_rule": "Ištrinti",
+ "delete_group": "Ištrinti",
+ "conditions": {
+ "AND": "IR",
+ "OR": "ARBA"
+ },
+ "operators": {
+ "equal": "lygu",
+ "not_equal": "nėra lygu",
+ "in": "iš nurodytų",
+ "not_in": "ne iš nurodytų",
+ "less": "mažiau",
+ "less_or_equal": "mažiau arba lygu",
+ "greater": "daugiau",
+ "greater_or_equal": "daugiau arba lygu",
+ "between": "tarp",
+ "not_between": "nėra tarp",
+ "begins_with": "prasideda",
+ "not_begins_with": "neprasideda",
+ "contains": "turi",
+ "not_contains": "neturi",
+ "ends_with": "baigiasi",
+ "not_ends_with": "nesibaigia",
+ "is_empty": "tuščia",
+ "is_not_empty": "ne tuščia",
+ "is_null": "neapibrėžta",
+ "is_not_null": "nėra neapibrėžta"
+ },
+ "errors": {
+ "no_filter": "Nepasirinktas filtras",
+ "empty_group": "Grupė tuščia",
+ "radio_empty": "Nepasirinkta reikšmė",
+ "checkbox_empty": "Nepasirinkta reikšmė",
+ "select_empty": "Nepasirinkta reikšmė",
+ "string_empty": "Tuščia reikšmė",
+ "string_exceed_min_length": "Turi būti bent {0} simbolių",
+ "string_exceed_max_length": "Turi būti ne daugiau kaip {0} simbolių",
+ "string_invalid_format": "Klaidingas formatas ({0})",
+ "number_nan": "Nėra skaičius",
+ "number_not_integer": "Ne sveikasis skaičius",
+ "number_not_double": "Ne realusis skaičius",
+ "number_exceed_min": "Turi būti daugiau už {0}",
+ "number_exceed_max": "Turi būti mažiau už {0}",
+ "number_wrong_step": "Turi būti {0} kartotinis",
+ "number_between_invalid": "Klaidingos reikšmės, {0} yra daugiau už {1}",
+ "datetime_empty": "Tuščia reikšmė",
+ "datetime_invalid": "Klaidingas datos formatas ({0})",
+ "datetime_exceed_min": "Turi būti po {0}",
+ "datetime_exceed_max": "Turi būti prieš {0}",
+ "datetime_between_invalid": "Klaidingos reikšmės, {0} yra daugiau už {1}",
+ "boolean_not_valid": "Nėra loginis tipas",
+ "operator_not_multiple": "Operatorius \"{1}\" negali priimti kelių reikšmių"
+ },
+ "invert": "Invertuoti",
+ "NOT": "NE"
+};
+
+QueryBuilder.defaults({ lang_code: 'lt' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.nl.js b/dist/i18n/query-builder.nl.js
new file mode 100644
index 00000000..0b7d9d7c
--- /dev/null
+++ b/dist/i18n/query-builder.nl.js
@@ -0,0 +1,76 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Dutch (nl)
+ * Author: "Roywcm"
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['nl'] = {
+ "__locale": "Dutch (nl)",
+ "__author": "\"Roywcm\"",
+ "add_rule": "Nieuwe regel",
+ "add_group": "Nieuwe groep",
+ "delete_rule": "Verwijder",
+ "delete_group": "Verwijder",
+ "conditions": {
+ "AND": "EN",
+ "OR": "OF"
+ },
+ "operators": {
+ "equal": "gelijk",
+ "not_equal": "niet gelijk",
+ "in": "in",
+ "not_in": "niet in",
+ "less": "minder",
+ "less_or_equal": "minder of gelijk",
+ "greater": "groter",
+ "greater_or_equal": "groter of gelijk",
+ "between": "tussen",
+ "not_between": "niet tussen",
+ "begins_with": "begint met",
+ "not_begins_with": "begint niet met",
+ "contains": "bevat",
+ "not_contains": "bevat niet",
+ "ends_with": "eindigt met",
+ "not_ends_with": "eindigt niet met",
+ "is_empty": "is leeg",
+ "is_not_empty": "is niet leeg",
+ "is_null": "is null",
+ "is_not_null": "is niet null"
+ },
+ "errors": {
+ "no_filter": "Geen filter geselecteerd",
+ "empty_group": "De groep is leeg",
+ "radio_empty": "Geen waarde geselecteerd",
+ "checkbox_empty": "Geen waarde geselecteerd",
+ "select_empty": "Geen waarde geselecteerd",
+ "string_empty": "Lege waarde",
+ "string_exceed_min_length": "Dient minstens {0} karakters te bevatten",
+ "string_exceed_max_length": "Dient niet meer dan {0} karakters te bevatten",
+ "string_invalid_format": "Ongeldig format ({0})",
+ "number_nan": "Niet een nummer",
+ "number_not_integer": "Geen geheel getal",
+ "number_not_double": "Geen echt nummer",
+ "number_exceed_min": "Dient groter te zijn dan {0}",
+ "number_exceed_max": "Dient lager te zijn dan {0}",
+ "number_wrong_step": "Dient een veelvoud te zijn van {0}",
+ "datetime_invalid": "Ongeldige datumformat ({0})",
+ "datetime_exceed_min": "Dient na {0}",
+ "datetime_exceed_max": "Dient voor {0}"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'nl' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.no.js b/dist/i18n/query-builder.no.js
new file mode 100644
index 00000000..ccd3f5ac
--- /dev/null
+++ b/dist/i18n/query-builder.no.js
@@ -0,0 +1,54 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Norwegian (no)
+ * Author: Jna Borup Coyle, github@coyle.dk
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['no'] = {
+ "__locale": "Norwegian (no)",
+ "__author": "Jna Borup Coyle, github@coyle.dk",
+ "add_rule": "Legg til regel",
+ "add_group": "Legg til gruppe",
+ "delete_rule": "Slett regel",
+ "delete_group": "Slett gruppe",
+ "conditions": {
+ "AND": "OG",
+ "OR": "ELLER"
+ },
+ "operators": {
+ "equal": "er lik",
+ "not_equal": "er ikke lik",
+ "in": "finnes i",
+ "not_in": "finnes ikke i",
+ "less": "er mindre enn",
+ "less_or_equal": "er mindre eller lik",
+ "greater": "er større enn",
+ "greater_or_equal": "er større eller lik",
+ "begins_with": "begynner med",
+ "not_begins_with": "begynner ikke med",
+ "contains": "inneholder",
+ "not_contains": "inneholder ikke",
+ "ends_with": "slutter med",
+ "not_ends_with": "slutter ikke med",
+ "is_empty": "er tom",
+ "is_not_empty": "er ikke tom",
+ "is_null": "er null",
+ "is_not_null": "er ikke null"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'no' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.pl.js b/dist/i18n/query-builder.pl.js
new file mode 100644
index 00000000..7610a618
--- /dev/null
+++ b/dist/i18n/query-builder.pl.js
@@ -0,0 +1,80 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Polish (pl)
+ * Author: Artur Smolarek
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['pl'] = {
+ "__locale": "Polish (pl)",
+ "__author": "Artur Smolarek",
+ "add_rule": "Dodaj regułę",
+ "add_group": "Dodaj grupę",
+ "delete_rule": "Usuń",
+ "delete_group": "Usuń",
+ "conditions": {
+ "AND": "ORAZ",
+ "OR": "LUB"
+ },
+ "operators": {
+ "equal": "równa się",
+ "not_equal": "jest różne od",
+ "in": "zawiera",
+ "not_in": "nie zawiera",
+ "less": "mniejsze",
+ "less_or_equal": "mniejsze lub równe",
+ "greater": "większe",
+ "greater_or_equal": "większe lub równe",
+ "between": "pomiędzy",
+ "not_between": "nie jest pomiędzy",
+ "begins_with": "rozpoczyna się od",
+ "not_begins_with": "nie rozpoczyna się od",
+ "contains": "zawiera",
+ "not_contains": "nie zawiera",
+ "ends_with": "kończy się na",
+ "not_ends_with": "nie kończy się na",
+ "is_empty": "jest puste",
+ "is_not_empty": "nie jest puste",
+ "is_null": "jest niezdefiniowane",
+ "is_not_null": "nie jest niezdefiniowane"
+ },
+ "errors": {
+ "no_filter": "Nie wybrano żadnego filtra",
+ "empty_group": "Grupa jest pusta",
+ "radio_empty": "Nie wybrano wartości",
+ "checkbox_empty": "Nie wybrano wartości",
+ "select_empty": "Nie wybrano wartości",
+ "string_empty": "Nie wpisano wartości",
+ "string_exceed_min_length": "Minimalna długość to {0} znaków",
+ "string_exceed_max_length": "Maksymalna długość to {0} znaków",
+ "string_invalid_format": "Nieprawidłowy format ({0})",
+ "number_nan": "To nie jest liczba",
+ "number_not_integer": "To nie jest liczba całkowita",
+ "number_not_double": "To nie jest liczba rzeczywista",
+ "number_exceed_min": "Musi być większe niż {0}",
+ "number_exceed_max": "Musi być mniejsze niż {0}",
+ "number_wrong_step": "Musi być wielokrotnością {0}",
+ "datetime_empty": "Nie wybrano wartości",
+ "datetime_invalid": "Nieprawidłowy format daty ({0})",
+ "datetime_exceed_min": "Musi być po {0}",
+ "datetime_exceed_max": "Musi być przed {0}",
+ "boolean_not_valid": "Niepoprawna wartość logiczna",
+ "operator_not_multiple": "Operator \"{1}\" nie przyjmuje wielu wartości"
+ },
+ "invert": "Odwróć"
+};
+
+QueryBuilder.defaults({ lang_code: 'pl' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.pt-BR.js b/dist/i18n/query-builder.pt-BR.js
new file mode 100644
index 00000000..2b227d9d
--- /dev/null
+++ b/dist/i18n/query-builder.pt-BR.js
@@ -0,0 +1,80 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Brazilian Portuguese (pr-BR)
+ * Author: Leandro Gehlen, leandrogehlen@gmail.com; Marcos Ferretti, marcosvferretti@gmail.com
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['pt-BR'] = {
+ "__locale": "Brazilian Portuguese (pr-BR)",
+ "__author": "Leandro Gehlen, leandrogehlen@gmail.com; Marcos Ferretti, marcosvferretti@gmail.com",
+ "add_rule": "Nova Regra",
+ "add_group": "Novo Grupo",
+ "delete_rule": "Excluir",
+ "delete_group": "Excluir",
+ "conditions": {
+ "AND": "E",
+ "OR": "OU"
+ },
+ "operators": {
+ "equal": "Igual",
+ "not_equal": "Diferente",
+ "in": "Contido",
+ "not_in": "Não contido",
+ "less": "Menor",
+ "less_or_equal": "Menor ou igual",
+ "greater": "Maior",
+ "greater_or_equal": "Maior ou igual",
+ "between": "Entre",
+ "not_between": "Não entre",
+ "begins_with": "Iniciando com",
+ "not_begins_with": "Não iniciando com",
+ "contains": "Contém",
+ "not_contains": "Não contém",
+ "ends_with": "Terminando com",
+ "not_ends_with": "Terminando sem",
+ "is_empty": "É vazio",
+ "is_not_empty": "Não é vazio",
+ "is_null": "É nulo",
+ "is_not_null": "Não é nulo"
+ },
+ "errors": {
+ "no_filter": "Nenhum filtro selecionado",
+ "empty_group": "O grupo está vazio",
+ "radio_empty": "Nenhum valor selecionado",
+ "checkbox_empty": "Nenhum valor selecionado",
+ "select_empty": "Nenhum valor selecionado",
+ "string_empty": "Valor vazio",
+ "string_exceed_min_length": "É necessário conter pelo menos {0} caracteres",
+ "string_exceed_max_length": "É necessário conter mais de {0} caracteres",
+ "string_invalid_format": "Formato inválido ({0})",
+ "number_nan": "Não é um número",
+ "number_not_integer": "Não é um número inteiro",
+ "number_not_double": "Não é um número real",
+ "number_exceed_min": "É necessário ser maior que {0}",
+ "number_exceed_max": "É necessário ser menor que {0}",
+ "number_wrong_step": "É necessário ser múltiplo de {0}",
+ "datetime_invalid": "Formato de data inválido ({0})",
+ "datetime_exceed_min": "É necessário ser superior a {0}",
+ "datetime_exceed_max": "É necessário ser inferior a {0}",
+ "datetime_empty": "Nenhuma data selecionada",
+ "boolean_not_valid": "Não é um valor booleano",
+ "operator_not_multiple": "O operador \"{1}\" não aceita valores múltiplos"
+ },
+ "invert": "Inverter"
+};
+
+QueryBuilder.defaults({ lang_code: 'pt-BR' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.pt-PT.js b/dist/i18n/query-builder.pt-PT.js
new file mode 100644
index 00000000..2edbcca7
--- /dev/null
+++ b/dist/i18n/query-builder.pt-PT.js
@@ -0,0 +1,75 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Portuguese (pt-PT)
+ * Author: Miguel Guerreiro, migas.csi@gmail.com
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['pt-PT'] = {
+ "__locale": "Portuguese (pt-PT)",
+ "__author": "Miguel Guerreiro, migas.csi@gmail.com",
+ "add_rule": "Nova Regra",
+ "add_group": "Novo Grupo",
+ "delete_rule": "Excluir",
+ "delete_group": "Excluir",
+ "conditions": {
+ "AND": "E",
+ "OR": "OU"
+ },
+ "operators": {
+ "equal": "Igual a",
+ "not_equal": "Diferente de",
+ "in": "Contido",
+ "not_in": "Não contido",
+ "less": "Menor que",
+ "less_or_equal": "Menor ou igual a",
+ "greater": "Maior que",
+ "greater_or_equal": "Maior ou igual que",
+ "between": "Entre",
+ "begins_with": "Começar por",
+ "not_begins_with": "Não a começar por",
+ "contains": "Contém",
+ "not_contains": "Não contém",
+ "ends_with": "Terminando com",
+ "not_ends_with": "Terminando sem",
+ "is_empty": "É vazio",
+ "is_not_empty": "Não é vazio",
+ "is_null": "É nulo",
+ "is_not_null": "Não é nulo"
+ },
+ "errors": {
+ "no_filter": "Nenhum filtro selecionado",
+ "empty_group": "O grupo está vazio",
+ "radio_empty": "Nenhum valor selecionado",
+ "checkbox_empty": "Nenhum valor selecionado",
+ "select_empty": "Nenhum valor selecionado",
+ "string_empty": "Valor vazio",
+ "string_exceed_min_length": "É necessário conter pelo menos {0} caracteres",
+ "string_exceed_max_length": "É necessário conter mais de {0} caracteres",
+ "string_invalid_format": "Formato inválido ({0})",
+ "number_nan": "Não é um número",
+ "number_not_integer": "Não é um número inteiro",
+ "number_not_double": "Não é um número real",
+ "number_exceed_min": "É necessário ser maior que {0}",
+ "number_exceed_max": "É necessário ser menor que {0}",
+ "number_wrong_step": "É necessário ser múltiplo de {0}",
+ "datetime_invalid": "Formato de data inválido ({0})",
+ "datetime_exceed_min": "É necessário ser superior a {0}",
+ "datetime_exceed_max": "É necessário ser inferior a {0}"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'pt-PT' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.ro.js b/dist/i18n/query-builder.ro.js
new file mode 100644
index 00000000..703fec6b
--- /dev/null
+++ b/dist/i18n/query-builder.ro.js
@@ -0,0 +1,54 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Romanian (ro)
+ * Author: ArianServ
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['ro'] = {
+ "__locale": "Romanian (ro)",
+ "__author": "ArianServ",
+ "add_rule": "Adaugă regulă",
+ "add_group": "Adaugă grup",
+ "delete_rule": "Şterge",
+ "delete_group": "Şterge",
+ "conditions": {
+ "AND": "ŞI",
+ "OR": "SAU"
+ },
+ "operators": {
+ "equal": "egal",
+ "not_equal": "diferit",
+ "in": "în",
+ "not_in": "nu în",
+ "less": "mai puţin",
+ "less_or_equal": "mai puţin sau egal",
+ "greater": "mai mare",
+ "greater_or_equal": "mai mare sau egal",
+ "begins_with": "începe cu",
+ "not_begins_with": "nu începe cu",
+ "contains": "conţine",
+ "not_contains": "nu conţine",
+ "ends_with": "se termină cu",
+ "not_ends_with": "nu se termină cu",
+ "is_empty": "este gol",
+ "is_not_empty": "nu este gol",
+ "is_null": "e nul",
+ "is_not_null": "nu e nul"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'ro' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.ru.js b/dist/i18n/query-builder.ru.js
new file mode 100644
index 00000000..e38cd5e6
--- /dev/null
+++ b/dist/i18n/query-builder.ru.js
@@ -0,0 +1,81 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Russian (ru)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['ru'] = {
+ "__locale": "Russian (ru)",
+ "add_rule": "Добавить",
+ "add_group": "Добавить группу",
+ "delete_rule": "Удалить",
+ "delete_group": "Удалить",
+ "conditions": {
+ "AND": "И",
+ "OR": "ИЛИ"
+ },
+ "operators": {
+ "equal": "равно",
+ "not_equal": "не равно",
+ "in": "из указанных",
+ "not_in": "не из указанных",
+ "less": "меньше",
+ "less_or_equal": "меньше или равно",
+ "greater": "больше",
+ "greater_or_equal": "больше или равно",
+ "between": "между",
+ "not_between": "не между",
+ "begins_with": "начинается с",
+ "not_begins_with": "не начинается с",
+ "contains": "содержит",
+ "not_contains": "не содержит",
+ "ends_with": "оканчивается на",
+ "not_ends_with": "не оканчивается на",
+ "is_empty": "пустая строка",
+ "is_not_empty": "не пустая строка",
+ "is_null": "пусто",
+ "is_not_null": "не пусто"
+ },
+ "errors": {
+ "no_filter": "Фильтр не выбран",
+ "empty_group": "Группа пуста",
+ "radio_empty": "Не выбранно значение",
+ "checkbox_empty": "Не выбранно значение",
+ "select_empty": "Не выбранно значение",
+ "string_empty": "Не заполненно",
+ "string_exceed_min_length": "Должен содержать больше {0} символов",
+ "string_exceed_max_length": "Должен содержать меньше {0} символов",
+ "string_invalid_format": "Неверный формат ({0})",
+ "number_nan": "Не число",
+ "number_not_integer": "Не число",
+ "number_not_double": "Не число",
+ "number_exceed_min": "Должно быть больше {0}",
+ "number_exceed_max": "Должно быть меньше, чем {0}",
+ "number_wrong_step": "Должно быть кратно {0}",
+ "number_between_invalid": "Недопустимые значения, {0} больше {1}",
+ "datetime_empty": "Не заполненно",
+ "datetime_invalid": "Неверный формат даты ({0})",
+ "datetime_exceed_min": "Должно быть, после {0}",
+ "datetime_exceed_max": "Должно быть, до {0}",
+ "datetime_between_invalid": "Недопустимые значения, {0} больше {1}",
+ "boolean_not_valid": "Не логическое",
+ "operator_not_multiple": "Оператор \"{1}\" не поддерживает много значений"
+ },
+ "invert": "Инвертировать",
+ "NOT": "НЕ"
+};
+
+QueryBuilder.defaults({ lang_code: 'ru' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.sq.js b/dist/i18n/query-builder.sq.js
new file mode 100644
index 00000000..3446000e
--- /dev/null
+++ b/dist/i18n/query-builder.sq.js
@@ -0,0 +1,78 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Albanian (sq)
+ * Author: Tomor Pupovci
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['sq'] = {
+ "__locale": "Albanian (sq)",
+ "__author": "Tomor Pupovci",
+ "add_rule": "Shto rregull",
+ "add_group": "Shto grup",
+ "delete_rule": "Fshij",
+ "delete_group": "Fshij",
+ "conditions": {
+ "AND": "DHE",
+ "OR": "OSE"
+ },
+ "operators": {
+ "equal": "barabartë",
+ "not_equal": "e ndryshme prej",
+ "in": "në",
+ "not_in": "jo në",
+ "less": "më e vogël",
+ "less_or_equal": "më e vogël ose e barabartë me",
+ "greater": "më e madhe",
+ "greater_or_equal": "më e madhe ose e barabartë",
+ "between": "në mes",
+ "begins_with": "fillon me",
+ "not_begins_with": "nuk fillon me",
+ "contains": "përmban",
+ "not_contains": "nuk përmban",
+ "ends_with": "mbaron me",
+ "not_ends_with": "nuk mbaron me",
+ "is_empty": "është e zbrazët",
+ "is_not_empty": "nuk është e zbrazët",
+ "is_null": "është null",
+ "is_not_null": "nuk është null"
+ },
+ "errors": {
+ "no_filter": "Nuk ka filter të zgjedhur",
+ "empty_group": "Grupi është i zbrazët",
+ "radio_empty": "Nuk ka vlerë të zgjedhur",
+ "checkbox_empty": "Nuk ka vlerë të zgjedhur",
+ "select_empty": "Nuk ka vlerë të zgjedhur",
+ "string_empty": "Vlerë e zbrazët",
+ "string_exceed_min_length": "Duhet të përmbajë së paku {0} karaktere",
+ "string_exceed_max_length": "Nuk duhet të përmbajë më shumë se {0} karaktere",
+ "string_invalid_format": "Format i pasaktë ({0})",
+ "number_nan": "Nuk është numër",
+ "number_not_integer": "Nuk është numër i plotë",
+ "number_not_double": "Nuk është numër me presje",
+ "number_exceed_min": "Duhet të jetë më i madh se {0}",
+ "number_exceed_max": "Duhet të jetë më i vogël se {0}",
+ "number_wrong_step": "Duhet të jetë shumëfish i {0}",
+ "datetime_empty": "Vlerë e zbrazët",
+ "datetime_invalid": "Format i pasaktë i datës ({0})",
+ "datetime_exceed_min": "Duhet të jetë pas {0}",
+ "datetime_exceed_max": "Duhet të jetë para {0}",
+ "boolean_not_valid": "Nuk është boolean",
+ "operator_not_multiple": "Operatori \"{1}\" nuk mund të pranojë vlera të shumëfishta"
+ }
+};
+
+QueryBuilder.defaults({ lang_code: 'sq' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.sw.js b/dist/i18n/query-builder.sw.js
new file mode 100644
index 00000000..fe3b36e2
--- /dev/null
+++ b/dist/i18n/query-builder.sw.js
@@ -0,0 +1,83 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Swahili (sw)
+ * Author: Timothy Anyona
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['sw'] = {
+ "__locale": "Swahili (sw)",
+ "__author": "Timothy Anyona",
+ "add_rule": "Ongeza kanuni",
+ "add_group": "Ongeza kikundi",
+ "delete_rule": "Futa",
+ "delete_group": "Futa",
+ "conditions": {
+ "AND": "NA",
+ "OR": "AU"
+ },
+ "operators": {
+ "equal": "ni",
+ "not_equal": "sio",
+ "in": "mojawapo ya",
+ "not_in": "sio mojawapo ya",
+ "less": "isiyozidi",
+ "less_or_equal": "isiyozidi au ni sawa na",
+ "greater": "inayozidi",
+ "greater_or_equal": "inayozidi au ni sawa na",
+ "between": "kati ya",
+ "not_between": "isiyo kati ya",
+ "begins_with": "inaanza na",
+ "not_begins_with": "isiyoanza na",
+ "contains": "ina",
+ "not_contains": "haina",
+ "ends_with": "inaisha na",
+ "not_ends_with": "isiyoisha na",
+ "is_empty": "ni tupu",
+ "is_not_empty": "sio tupu",
+ "is_null": "ni batili",
+ "is_not_null": "sio batili"
+ },
+ "errors": {
+ "no_filter": "Chujio halijachaguliwa",
+ "empty_group": "Kikundi ki tupu",
+ "radio_empty": "Thamani haijachaguliwa",
+ "checkbox_empty": "Thamani haijachaguliwa",
+ "select_empty": "Thamani haijachaguliwa",
+ "string_empty": "Thamani tupu",
+ "string_exceed_min_length": "Lazima iwe na vibambo visiopungua {0}",
+ "string_exceed_max_length": "Haifai kuwa na vibambo zaidi ya {0}",
+ "string_invalid_format": "Fomati batili ({0})",
+ "number_nan": "Sio nambari",
+ "number_not_integer": "Sio namba kamili",
+ "number_not_double": "Sio namba desimali",
+ "number_exceed_min": "Lazima iwe zaidi ya {0}",
+ "number_exceed_max": "Lazima iwe chini ya {0}",
+ "number_wrong_step": "Lazima iwe kigawe cha {0}",
+ "number_between_invalid": "Thamani batili, {0} ni kubwa kuliko {1}",
+ "datetime_empty": "Thamani tupu",
+ "datetime_invalid": "Fomati tarehe batili ({0})",
+ "datetime_exceed_min": "Lazima iwe baada ya {0}",
+ "datetime_exceed_max": "Lazima iwe kabla ya {0}",
+ "datetime_between_invalid": "Thamani batili, {0} ni baada ya {1}",
+ "boolean_not_valid": "Sio buleani",
+ "operator_not_multiple": "Opereta \"{1}\" haikubali thamani nyingi"
+ },
+ "invert": "Pindua",
+ "NOT": "SIO"
+};
+
+QueryBuilder.defaults({ lang_code: 'sw' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.tr.js b/dist/i18n/query-builder.tr.js
new file mode 100644
index 00000000..b7e82cda
--- /dev/null
+++ b/dist/i18n/query-builder.tr.js
@@ -0,0 +1,82 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Turkish (tr)
+ * Author: Aykut Alpgiray Ateş
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['tr'] = {
+ "__locale": "Turkish (tr)",
+ "__author": "Aykut Alpgiray Ateş",
+ "add_rule": "Kural Ekle",
+ "add_group": "Grup Ekle",
+ "delete_rule": "Sil",
+ "delete_group": "Sil",
+ "conditions": {
+ "AND": "Ve",
+ "OR": "Veya"
+ },
+ "operators": {
+ "equal": "eşit",
+ "not_equal": "eşit değil",
+ "in": "içinde",
+ "not_in": "içinde değil",
+ "less": "küçük",
+ "less_or_equal": "küçük veya eşit",
+ "greater": "büyük",
+ "greater_or_equal": "büyük veya eşit",
+ "between": "arasında",
+ "not_between": "arasında değil",
+ "begins_with": "ile başlayan",
+ "not_begins_with": "ile başlamayan",
+ "contains": "içeren",
+ "not_contains": "içermeyen",
+ "ends_with": "ile biten",
+ "not_ends_with": "ile bitmeyen",
+ "is_empty": "boş ise",
+ "is_not_empty": "boş değil ise",
+ "is_null": "var ise",
+ "is_not_null": "yok ise"
+ },
+ "errors": {
+ "no_filter": "Bir filtre seçili değil",
+ "empty_group": "Grup bir eleman içermiyor",
+ "radio_empty": "Seçim yapılmalı",
+ "checkbox_empty": "Seçim yapılmalı",
+ "select_empty": "Seçim yapılmalı",
+ "string_empty": "Bir metin girilmeli",
+ "string_exceed_min_length": "En az {0} karakter girilmeli",
+ "string_exceed_max_length": "En fazla {0} karakter girilebilir",
+ "string_invalid_format": "Uyumsuz format ({0})",
+ "number_nan": "Sayı değil",
+ "number_not_integer": "Tam sayı değil",
+ "number_not_double": "Ondalıklı sayı değil",
+ "number_exceed_min": "Sayı {0}'den/dan daha büyük olmalı",
+ "number_exceed_max": "Sayı {0}'den/dan daha küçük olmalı",
+ "number_wrong_step": "{0} veya katı olmalı",
+ "number_between_invalid": "Geçersiz değerler, {0} değeri {1} değerinden büyük",
+ "datetime_empty": "Tarih Seçilmemiş",
+ "datetime_invalid": "Uygun olmayan tarih formatı ({0})",
+ "datetime_exceed_min": "{0} Tarihinden daha sonrası olmalı.",
+ "datetime_exceed_max": "{0} Tarihinden daha öncesi olmalı.",
+ "datetime_between_invalid": "Geçersiz değerler, {0} değeri {1} değerinden büyük",
+ "boolean_not_valid": "Değer Doğru/Yanlış(bool) olmalı",
+ "operator_not_multiple": "Operatör \"{1}\" birden fazla değer kabul etmiyor"
+ },
+ "invert": "Ters Çevir"
+};
+
+QueryBuilder.defaults({ lang_code: 'tr' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.ua.js b/dist/i18n/query-builder.ua.js
new file mode 100644
index 00000000..77fa1f6d
--- /dev/null
+++ b/dist/i18n/query-builder.ua.js
@@ -0,0 +1,79 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Ukrainian (ua)
+ * Author: Megaplan, mborisv
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['ua'] = {
+ "__locale": "Ukrainian (ua)",
+ "__author": "Megaplan, mborisv ",
+ "add_rule": "Додати",
+ "add_group": "Додати групу",
+ "delete_rule": "Видалити",
+ "delete_group": "Видалити",
+ "conditions": {
+ "AND": "І",
+ "OR": "АБО"
+ },
+ "operators": {
+ "equal": "дорівнює",
+ "not_equal": "не дорівнює",
+ "in": "з вказаних",
+ "not_in": "не з вказаних",
+ "less": "менше",
+ "less_or_equal": "менше або дорівнюж",
+ "greater": "більше",
+ "greater_or_equal": "більше або дорівнює",
+ "between": "між",
+ "begins_with": "починається з",
+ "not_begins_with": "не починається з",
+ "contains": "містить",
+ "not_contains": "не містить",
+ "ends_with": "закінчується на",
+ "not_ends_with": "не не закінчується на",
+ "is_empty": "порожній рядок",
+ "is_not_empty": "не порожній рядок",
+ "is_null": "порожньо",
+ "is_not_null": "не порожньо"
+ },
+ "errors": {
+ "no_filter": "Фільтр не вибраний",
+ "empty_group": "Група порожня",
+ "radio_empty": "Значення не вибрано",
+ "checkbox_empty": "Значення не вибрано",
+ "select_empty": "Значення не вибрано",
+ "string_empty": "Не заповнено",
+ "string_exceed_min_length": "Повинен містити більше {0} символів",
+ "string_exceed_max_length": "Повинен містити менше {0} символів",
+ "string_invalid_format": "Невірний формат ({0})",
+ "number_nan": "Не число",
+ "number_not_integer": "Не число",
+ "number_not_double": "Не число",
+ "number_exceed_min": "Повинне бути більше {0}",
+ "number_exceed_max": "Повинне бути менше, ніж {0}",
+ "number_wrong_step": "Повинне бути кратне {0}",
+ "datetime_empty": "Не заповнено",
+ "datetime_invalid": "Невірний формат дати ({0})",
+ "datetime_exceed_min": "Повинне бути, після {0}",
+ "datetime_exceed_max": "Повинне бути, до {0}",
+ "boolean_not_valid": "Не логічне",
+ "operator_not_multiple": "Оператор \"{1}\" не підтримує багато значень"
+ },
+ "invert": "інвертувати"
+};
+
+QueryBuilder.defaults({ lang_code: 'ua' });
+}));
\ No newline at end of file
diff --git a/dist/i18n/query-builder.zh-CN.js b/dist/i18n/query-builder.zh-CN.js
new file mode 100644
index 00000000..49a65e2b
--- /dev/null
+++ b/dist/i18n/query-builder.zh-CN.js
@@ -0,0 +1,80 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: Simplified Chinese (zh_CN)
+ * Author: shadowwind, shatteredwindgo@gmail.com
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'query-builder'], factory);
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function($) {
+"use strict";
+
+var QueryBuilder = $.fn.queryBuilder;
+
+QueryBuilder.regional['zh-CN'] = {
+ "__locale": "Simplified Chinese (zh_CN)",
+ "__author": "shadowwind, shatteredwindgo@gmail.com",
+ "add_rule": "添加规则",
+ "add_group": "添加组",
+ "delete_rule": "删除",
+ "delete_group": "删除组",
+ "conditions": {
+ "AND": "和",
+ "OR": "或"
+ },
+ "operators": {
+ "equal": "等于",
+ "not_equal": "不等于",
+ "in": "在...之內",
+ "not_in": "不在...之內",
+ "less": "小于",
+ "less_or_equal": "小于或等于",
+ "greater": "大于",
+ "greater_or_equal": "大于或等于",
+ "between": "在...之间",
+ "not_between": "不在...之间",
+ "begins_with": "以...开始",
+ "not_begins_with": "不以...开始",
+ "contains": "包含以下内容",
+ "not_contains": "不包含以下内容",
+ "ends_with": "以...结束",
+ "not_ends_with": "不以...结束",
+ "is_empty": "为空",
+ "is_not_empty": "不为空",
+ "is_null": "为 null",
+ "is_not_null": "不为 null"
+ },
+ "errors": {
+ "no_filter": "没有选择过滤器",
+ "empty_group": "该组为空",
+ "radio_empty": "没有选中项",
+ "checkbox_empty": "没有选中项",
+ "select_empty": "没有选中项",
+ "string_empty": "没有输入值",
+ "string_exceed_min_length": "必须至少包含{0}个字符",
+ "string_exceed_max_length": "必须不超过{0}个字符",
+ "string_invalid_format": "无效格式({0})",
+ "number_nan": "值不是数字",
+ "number_not_integer": "不是整数",
+ "number_not_double": "不是浮点数",
+ "number_exceed_min": "必须大于{0}",
+ "number_exceed_max": "必须小于{0}",
+ "number_wrong_step": "必须是{0}的倍数",
+ "datetime_empty": "值为空",
+ "datetime_invalid": "不是有效日期({0})",
+ "datetime_exceed_min": "必须在{0}之后",
+ "datetime_exceed_max": "必须在{0}之前",
+ "boolean_not_valid": "不是布尔值",
+ "operator_not_multiple": "选项\"{1}\"无法接受多个值"
+ },
+ "invert": "倒置"
+};
+
+QueryBuilder.defaults({ lang_code: 'zh-CN' });
+}));
\ No newline at end of file
diff --git a/dist/js/query-builder.js b/dist/js/query-builder.js
new file mode 100644
index 00000000..82ae620f
--- /dev/null
+++ b/dist/js/query-builder.js
@@ -0,0 +1,6229 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+(function(root, factory) {
+ if (typeof define == 'function' && define.amd) {
+ define(['jquery', 'dot/doT', 'jquery-extendext'], factory);
+ }
+ else if (typeof module === 'object' && module.exports) {
+ module.exports = factory(require('jquery'), require('dot/doT'), require('jquery-extendext'));
+ }
+ else {
+ factory(root.jQuery, root.doT);
+ }
+}(this, function($, doT) {
+"use strict";
+
+/**
+ * @typedef {object} Filter
+ * @memberof QueryBuilder
+ * @description See {@link http://querybuilder.js.org/index.html#filters}
+ */
+
+/**
+ * @typedef {object} Operator
+ * @memberof QueryBuilder
+ * @description See {@link http://querybuilder.js.org/index.html#operators}
+ */
+
+/**
+ * @param {jQuery} $el
+ * @param {object} options - see {@link http://querybuilder.js.org/#options}
+ * @constructor
+ */
+var QueryBuilder = function($el, options) {
+ $el[0].queryBuilder = this;
+
+ /**
+ * Element container
+ * @member {jQuery}
+ * @readonly
+ */
+ this.$el = $el;
+
+ /**
+ * Configuration object
+ * @member {object}
+ * @readonly
+ */
+ this.settings = $.extendext(true, 'replace', {}, QueryBuilder.DEFAULTS, options);
+
+ /**
+ * Internal model
+ * @member {Model}
+ * @readonly
+ */
+ this.model = new Model();
+
+ /**
+ * Internal status
+ * @member {object}
+ * @property {string} id - id of the container
+ * @property {boolean} generated_id - if the container id has been generated
+ * @property {int} group_id - current group id
+ * @property {int} rule_id - current rule id
+ * @property {boolean} has_optgroup - if filters have optgroups
+ * @property {boolean} has_operator_optgroup - if operators have optgroups
+ * @readonly
+ * @private
+ */
+ this.status = {
+ id: null,
+ generated_id: false,
+ group_id: 0,
+ rule_id: 0,
+ has_optgroup: false,
+ has_operator_optgroup: false
+ };
+
+ /**
+ * List of filters
+ * @member {QueryBuilder.Filter[]}
+ * @readonly
+ */
+ this.filters = this.settings.filters;
+
+ /**
+ * List of icons
+ * @member {object.}
+ * @readonly
+ */
+ this.icons = this.settings.icons;
+
+ /**
+ * List of operators
+ * @member {QueryBuilder.Operator[]}
+ * @readonly
+ */
+ this.operators = this.settings.operators;
+
+ /**
+ * List of templates
+ * @member {object.}
+ * @readonly
+ */
+ this.templates = this.settings.templates;
+
+ /**
+ * Plugins configuration
+ * @member {object.}
+ * @readonly
+ */
+ this.plugins = this.settings.plugins;
+
+ /**
+ * Translations object
+ * @member {object}
+ * @readonly
+ */
+ this.lang = null;
+
+ // translations : english << 'lang_code' << custom
+ if (QueryBuilder.regional['en'] === undefined) {
+ Utils.error('Config', '"i18n/en.js" not loaded.');
+ }
+ this.lang = $.extendext(true, 'replace', {}, QueryBuilder.regional['en'], QueryBuilder.regional[this.settings.lang_code], this.settings.lang);
+
+ // "allow_groups" can be boolean or int
+ if (this.settings.allow_groups === false) {
+ this.settings.allow_groups = 0;
+ }
+ else if (this.settings.allow_groups === true) {
+ this.settings.allow_groups = -1;
+ }
+
+ // init templates
+ Object.keys(this.templates).forEach(function(tpl) {
+ if (!this.templates[tpl]) {
+ this.templates[tpl] = QueryBuilder.templates[tpl];
+ }
+ if (typeof this.templates[tpl] == 'string') {
+ this.templates[tpl] = doT.template(this.templates[tpl]);
+ }
+ }, this);
+
+ // ensure we have a container id
+ if (!this.$el.attr('id')) {
+ this.$el.attr('id', 'qb_' + Math.floor(Math.random() * 99999));
+ this.status.generated_id = true;
+ }
+ this.status.id = this.$el.attr('id');
+
+ // INIT
+ this.$el.addClass('query-builder form-inline');
+
+ this.filters = this.checkFilters(this.filters);
+ this.operators = this.checkOperators(this.operators);
+ this.bindEvents();
+ this.initPlugins();
+};
+
+$.extend(QueryBuilder.prototype, /** @lends QueryBuilder.prototype */ {
+ /**
+ * Triggers an event on the builder container
+ * @param {string} type
+ * @returns {$.Event}
+ */
+ trigger: function(type) {
+ var event = new $.Event(this._tojQueryEvent(type), {
+ builder: this
+ });
+
+ this.$el.triggerHandler(event, Array.prototype.slice.call(arguments, 1));
+
+ return event;
+ },
+
+ /**
+ * Triggers an event on the builder container and returns the modified value
+ * @param {string} type
+ * @param {*} value
+ * @returns {*}
+ */
+ change: function(type, value) {
+ var event = new $.Event(this._tojQueryEvent(type, true), {
+ builder: this,
+ value: value
+ });
+
+ this.$el.triggerHandler(event, Array.prototype.slice.call(arguments, 2));
+
+ return event.value;
+ },
+
+ /**
+ * Attaches an event listener on the builder container
+ * @param {string} type
+ * @param {function} cb
+ * @returns {QueryBuilder}
+ */
+ on: function(type, cb) {
+ this.$el.on(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Removes an event listener from the builder container
+ * @param {string} type
+ * @param {function} [cb]
+ * @returns {QueryBuilder}
+ */
+ off: function(type, cb) {
+ this.$el.off(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Attaches an event listener called once on the builder container
+ * @param {string} type
+ * @param {function} cb
+ * @returns {QueryBuilder}
+ */
+ once: function(type, cb) {
+ this.$el.one(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Appends `.queryBuilder` and optionally `.filter` to the events names
+ * @param {string} name
+ * @param {boolean} [filter=false]
+ * @returns {string}
+ * @private
+ */
+ _tojQueryEvent: function(name, filter) {
+ return name.split(' ').map(function(type) {
+ return type + '.queryBuilder' + (filter ? '.filter' : '');
+ }).join(' ');
+ }
+});
+
+
+/**
+ * Allowed types and their internal representation
+ * @type {object.}
+ * @readonly
+ * @private
+ */
+QueryBuilder.types = {
+ 'string': 'string',
+ 'integer': 'number',
+ 'double': 'number',
+ 'date': 'datetime',
+ 'time': 'datetime',
+ 'datetime': 'datetime',
+ 'boolean': 'boolean'
+};
+
+/**
+* Allowed inputs
+* @type {string[]}
+* @readonly
+* @private
+*/
+QueryBuilder.inputs = [
+ 'text',
+ 'number',
+ 'textarea',
+ 'radio',
+ 'checkbox',
+ 'select'
+];
+
+/**
+* Runtime modifiable options with `setOptions` method
+* @type {string[]}
+* @readonly
+* @private
+*/
+QueryBuilder.modifiable_options = [
+ 'display_errors',
+ 'allow_groups',
+ 'allow_empty',
+ 'default_condition',
+ 'default_filter'
+];
+
+/**
+* CSS selectors for common components
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.selectors = {
+ group_container: '.rules-group-container',
+ rule_container: '.rule-container',
+ filter_container: '.rule-filter-container',
+ operator_container: '.rule-operator-container',
+ value_container: '.rule-value-container',
+ error_container: '.error-container',
+ condition_container: '.rules-group-header .group-conditions',
+ tooltip: '.tooltip-container',
+ description: '.description-container',
+
+ rule_header: '.rule-header',
+ group_header: '.rules-group-header',
+ group_actions: '.group-actions',
+ rule_actions: '.rule-actions',
+
+ rules_list: '.rules-group-body>.rules-list',
+
+ group_condition: '.rules-group-header [name$=_cond]',
+ rule_filter: '.rule-filter-container [name$=_filter]',
+ rule_operator: '.rule-operator-container [name$=_operator]',
+ rule_value: '.rule-value-container [name*=_value_]',
+
+ add_rule: '[data-add=rule]',
+ delete_rule: '[data-delete=rule]',
+ add_group: '[data-add=group]',
+ delete_group: '[data-delete=group]'
+};
+
+/**
+* Template strings (see template.js)
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.templates = {};
+
+/**
+* Localized strings (see i18n/)
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.regional = {};
+
+/**
+* Default operators
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.OPERATORS = {
+ equal: { type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ not_equal: { type: 'not_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ in: { type: 'in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ not_in: { type: 'not_in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ less: { type: 'less', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ less_or_equal: { type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater: { type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater_or_equal: { type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ between: { type: 'between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ not_between: { type: 'not_between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ begins_with: { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_begins_with: { type: 'not_begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ contains: { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_contains: { type: 'not_contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ ends_with: { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_ends_with: { type: 'not_ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ is_empty: { type: 'is_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_not_empty: { type: 'is_not_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_null: { type: 'is_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ is_not_null: { type: 'is_not_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] }
+};
+
+/**
+* Default configuration
+* @type {object}
+* @readonly
+*/
+QueryBuilder.DEFAULTS = {
+ filters: [],
+ plugins: [],
+
+ sort_filters: false,
+ display_errors: true,
+ allow_groups: -1,
+ allow_empty: false,
+ conditions: ['AND', 'OR'],
+ default_condition: 'AND',
+ inputs_separator: " AND ",
+ select_placeholder: '------',
+ display_empty_filter: true,
+ default_filter: null,
+ optgroups: {},
+
+ default_rule_flags: {
+ filter_readonly: false,
+ operator_readonly: false,
+ value_readonly: false,
+ no_delete: false
+ },
+
+ default_group_flags: {
+ condition_readonly: false,
+ no_add_rule: false,
+ no_add_group: false,
+ no_delete: false
+ },
+
+ templates: {
+ group: null,
+ rule: null,
+ filterSelect: null,
+ operatorSelect: null,
+ ruleValueSelect: null
+ },
+
+ lang_code: 'en',
+ lang: {},
+
+ operators: [
+ 'equal',
+ 'not_equal',
+ 'in',
+ 'not_in',
+ 'less',
+ 'less_or_equal',
+ 'greater',
+ 'greater_or_equal',
+ 'between',
+ 'not_between',
+ 'begins_with',
+ 'not_begins_with',
+ 'contains',
+ 'not_contains',
+ 'ends_with',
+ 'not_ends_with',
+ 'is_empty',
+ 'is_not_empty',
+ 'is_null',
+ 'is_not_null'
+ ],
+
+ icons: {
+ add_group: 'glyphicon glyphicon-plus-sign',
+ add_rule: 'glyphicon glyphicon-plus',
+ remove_group: 'glyphicon glyphicon-remove',
+ remove_rule: 'glyphicon glyphicon-remove',
+ error: 'glyphicon glyphicon-warning-sign',
+ tooltip: 'glyphicon glyphicon-info-sign',
+ }
+};
+
+
+/**
+ * @module plugins
+ */
+
+/**
+ * Definition of available plugins
+ * @type {object.}
+ */
+QueryBuilder.plugins = {};
+
+/**
+ * Gets or extends the default configuration
+ * @param {object} [options] - new configuration
+ * @returns {undefined|object} nothing or configuration object (copy)
+ */
+QueryBuilder.defaults = function(options) {
+ if (typeof options == 'object') {
+ $.extendext(true, 'replace', QueryBuilder.DEFAULTS, options);
+ }
+ else if (typeof options == 'string') {
+ if (typeof QueryBuilder.DEFAULTS[options] == 'object') {
+ return $.extend(true, {}, QueryBuilder.DEFAULTS[options]);
+ }
+ else {
+ return QueryBuilder.DEFAULTS[options];
+ }
+ }
+ else {
+ return $.extend(true, {}, QueryBuilder.DEFAULTS);
+ }
+};
+
+/**
+ * Registers a new plugin
+ * @param {string} name
+ * @param {function} fct - init function
+ * @param {object} [def] - default options
+ */
+QueryBuilder.define = function(name, fct, def) {
+ QueryBuilder.plugins[name] = {
+ fct: fct,
+ def: def || {}
+ };
+};
+
+/**
+ * Adds new methods to QueryBuilder prototype
+ * @param {object.} methods
+ */
+QueryBuilder.extend = function(methods) {
+ $.extend(QueryBuilder.prototype, methods);
+};
+
+/**
+ * Initializes plugins for an instance
+ * @throws ConfigError
+ * @private
+ */
+QueryBuilder.prototype.initPlugins = function() {
+ if (!this.plugins) {
+ return;
+ }
+
+ if ($.isArray(this.plugins)) {
+ var tmp = {};
+ this.plugins.forEach(function(plugin) {
+ tmp[plugin] = null;
+ });
+ this.plugins = tmp;
+ }
+
+ Object.keys(this.plugins).forEach(function(plugin) {
+ if (plugin in QueryBuilder.plugins) {
+ this.plugins[plugin] = $.extend(true, {},
+ QueryBuilder.plugins[plugin].def,
+ this.plugins[plugin] || {}
+ );
+
+ QueryBuilder.plugins[plugin].fct.call(this, this.plugins[plugin]);
+ }
+ else {
+ Utils.error('Config', 'Unable to find plugin "{0}"', plugin);
+ }
+ }, this);
+};
+
+/**
+ * Returns the config of a plugin, if the plugin is not loaded, returns the default config.
+ * @param {string} name
+ * @param {string} [property]
+ * @throws ConfigError
+ * @returns {*}
+ */
+QueryBuilder.prototype.getPluginOptions = function(name, property) {
+ var plugin;
+ if (this.plugins && this.plugins[name]) {
+ plugin = this.plugins[name];
+ }
+ else if (QueryBuilder.plugins[name]) {
+ plugin = QueryBuilder.plugins[name].def;
+ }
+
+ if (plugin) {
+ if (property) {
+ return plugin[property];
+ }
+ else {
+ return plugin;
+ }
+ }
+ else {
+ Utils.error('Config', 'Unable to find plugin "{0}"', name);
+ }
+};
+
+
+/**
+ * Final initialisation of the builder
+ * @param {object} [rules]
+ * @fires QueryBuilder.afterInit
+ * @private
+ */
+QueryBuilder.prototype.init = function(rules) {
+ /**
+ * When the initilization is done, just before creating the root group
+ * @event afterInit
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterInit');
+
+ if (rules) {
+ this.setRules(rules);
+ delete this.settings.rules;
+ }
+ else {
+ this.setRoot(true);
+ }
+};
+
+/**
+* Checks the configuration of each filter
+* @param {QueryBuilder.Filter[]} filters
+* @returns {QueryBuilder.Filter[]}
+* @throws ConfigError
+*/
+QueryBuilder.prototype.checkFilters = function(filters) {
+ var definedFilters = [];
+
+ if (!filters || filters.length === 0) {
+ Utils.error('Config', 'Missing filters list');
+ }
+
+ filters.forEach(function(filter, i) {
+ if (!filter.id) {
+ Utils.error('Config', 'Missing filter {0} id', i);
+ }
+ if (definedFilters.indexOf(filter.id) != -1) {
+ Utils.error('Config', 'Filter "{0}" already defined', filter.id);
+ }
+ definedFilters.push(filter.id);
+
+ if (!filter.type) {
+ filter.type = 'string';
+ }
+ else if (!QueryBuilder.types[filter.type]) {
+ Utils.error('Config', 'Invalid type "{0}"', filter.type);
+ }
+
+ if (!filter.input) {
+ filter.input = QueryBuilder.types[filter.type] === 'number' ? 'number' : 'text';
+ }
+ else if (typeof filter.input != 'function' && QueryBuilder.inputs.indexOf(filter.input) == -1) {
+ Utils.error('Config', 'Invalid input "{0}"', filter.input);
+ }
+
+ if (filter.operators) {
+ filter.operators.forEach(function(operator) {
+ if (typeof operator != 'string') {
+ Utils.error('Config', 'Filter operators must be global operators types (string)');
+ }
+ });
+ }
+
+ if (!filter.field) {
+ filter.field = filter.id;
+ }
+ if (!filter.label) {
+ filter.label = filter.field;
+ }
+
+ if (!filter.optgroup) {
+ filter.optgroup = null;
+ }
+ else {
+ this.status.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[filter.optgroup]) {
+ this.settings.optgroups[filter.optgroup] = filter.optgroup;
+ }
+ }
+
+ switch (filter.input) {
+ case 'radio':
+ case 'checkbox':
+ if (!filter.values || filter.values.length < 1) {
+ Utils.error('Config', 'Missing filter "{0}" values', filter.id);
+ }
+ break;
+
+ case 'select':
+ var cleanValues = [];
+ filter.has_optgroup = false;
+
+ Utils.iterateOptions(filter.values, function(value, label, optgroup) {
+ cleanValues.push({
+ value: value,
+ label: label,
+ optgroup: optgroup || null
+ });
+
+ if (optgroup) {
+ filter.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[optgroup]) {
+ this.settings.optgroups[optgroup] = optgroup;
+ }
+ }
+ }.bind(this));
+
+ if (filter.has_optgroup) {
+ filter.values = Utils.groupSort(cleanValues, 'optgroup');
+ }
+ else {
+ filter.values = cleanValues;
+ }
+
+ if (filter.placeholder) {
+ if (filter.placeholder_value === undefined) {
+ filter.placeholder_value = -1;
+ }
+
+ filter.values.forEach(function(entry) {
+ if (entry.value == filter.placeholder_value) {
+ Utils.error('Config', 'Placeholder of filter "{0}" overlaps with one of its values', filter.id);
+ }
+ });
+ }
+ break;
+ }
+ }, this);
+
+ if (this.settings.sort_filters) {
+ if (typeof this.settings.sort_filters == 'function') {
+ filters.sort(this.settings.sort_filters);
+ }
+ else {
+ var self = this;
+ filters.sort(function(a, b) {
+ return self.translate(a.label).localeCompare(self.translate(b.label));
+ });
+ }
+ }
+
+ if (this.status.has_optgroup) {
+ filters = Utils.groupSort(filters, 'optgroup');
+ }
+
+ return filters;
+};
+
+/**
+* Checks the configuration of each operator
+* @param {QueryBuilder.Operator[]} operators
+* @returns {QueryBuilder.Operator[]}
+* @throws ConfigError
+*/
+QueryBuilder.prototype.checkOperators = function(operators) {
+ var definedOperators = [];
+
+ operators.forEach(function(operator, i) {
+ if (typeof operator == 'string') {
+ if (!QueryBuilder.OPERATORS[operator]) {
+ Utils.error('Config', 'Unknown operator "{0}"', operator);
+ }
+
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator]);
+ }
+ else {
+ if (!operator.type) {
+ Utils.error('Config', 'Missing "type" for operator {0}', i);
+ }
+
+ if (QueryBuilder.OPERATORS[operator.type]) {
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator.type], operator);
+ }
+
+ if (operator.nb_inputs === undefined || operator.apply_to === undefined) {
+ Utils.error('Config', 'Missing "nb_inputs" and/or "apply_to" for operator "{0}"', operator.type);
+ }
+ }
+
+ if (definedOperators.indexOf(operator.type) != -1) {
+ Utils.error('Config', 'Operator "{0}" already defined', operator.type);
+ }
+ definedOperators.push(operator.type);
+
+ if (!operator.optgroup) {
+ operator.optgroup = null;
+ }
+ else {
+ this.status.has_operator_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[operator.optgroup]) {
+ this.settings.optgroups[operator.optgroup] = operator.optgroup;
+ }
+ }
+ }, this);
+
+ if (this.status.has_operator_optgroup) {
+ operators = Utils.groupSort(operators, 'optgroup');
+ }
+
+ return operators;
+};
+
+/**
+* Adds all events listeners to the builder
+* @private
+*/
+QueryBuilder.prototype.bindEvents = function() {
+ var self = this;
+ var Selectors = QueryBuilder.selectors;
+
+ // group condition change
+ this.$el.on('change.queryBuilder', Selectors.group_condition, function() {
+ if ($(this).is(':checked')) {
+ var $group = $(this).closest(Selectors.group_container);
+ self.getModel($group).condition = $(this).val();
+ }
+ });
+
+ // rule filter change
+ this.$el.on('change.queryBuilder', Selectors.rule_filter, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).filter = self.getFilterById($(this).val());
+ });
+
+ // rule operator change
+ this.$el.on('change.queryBuilder', Selectors.rule_operator, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).operator = self.getOperatorByType($(this).val());
+ });
+
+ // add rule button
+ this.$el.on('click.queryBuilder', Selectors.add_rule, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addRule(self.getModel($group));
+ });
+
+ // delete rule button
+ this.$el.on('click.queryBuilder', Selectors.delete_rule, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.deleteRule(self.getModel($rule));
+ });
+
+ if (this.settings.allow_groups !== 0) {
+ // add group button
+ this.$el.on('click.queryBuilder', Selectors.add_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addGroup(self.getModel($group));
+ });
+
+ // delete group button
+ this.$el.on('click.queryBuilder', Selectors.delete_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.deleteGroup(self.getModel($group));
+ });
+ }
+
+ // model events
+ this.model.on({
+ 'drop': function(e, node) {
+ node.$el.remove();
+ self.refreshGroupsConditions();
+ },
+ 'add': function(e, parent, node, index) {
+ if (index === 0) {
+ node.$el.prependTo(parent.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(parent.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'move': function(e, node, group, index) {
+ node.$el.detach();
+
+ if (index === 0) {
+ node.$el.prependTo(group.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(group.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'update': function(e, node, field, value, oldValue) {
+ if (node instanceof Rule) {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyRuleFlags(node);
+ break;
+
+ case 'filter':
+ self.updateRuleFilter(node, oldValue);
+ break;
+
+ case 'operator':
+ self.updateRuleOperator(node, oldValue);
+ break;
+
+ case 'value':
+ self.updateRuleValue(node, oldValue);
+ break;
+ }
+ }
+ else {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyGroupFlags(node);
+ break;
+
+ case 'condition':
+ self.updateGroupCondition(node, oldValue);
+ break;
+ }
+ }
+ }
+ });
+};
+
+/**
+* Creates the root group
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group} root group
+* @fires QueryBuilder.afterAddGroup
+*/
+QueryBuilder.prototype.setRoot = function(addRule, data, flags) {
+ addRule = (addRule === undefined || addRule === true);
+
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, 1));
+
+ this.$el.append($group);
+ this.model.root = new Group(null, $group);
+ this.model.root.model = this.model;
+
+ this.model.root.data = data;
+ this.model.root.flags = $.extend({}, this.settings.default_group_flags, flags);
+ this.model.root.condition = this.settings.default_condition;
+
+ this.trigger('afterAddGroup', this.model.root);
+
+ if (addRule) {
+ this.addRule(this.model.root);
+ }
+
+ return this.model.root;
+};
+
+/**
+* Adds a new group
+* @param {Group} parent
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group}
+* @fires QueryBuilder.beforeAddGroup
+* @fires QueryBuilder.afterAddGroup
+*/
+QueryBuilder.prototype.addGroup = function(parent, addRule, data, flags) {
+ addRule = (addRule === undefined || addRule === true);
+
+ var level = parent.level + 1;
+
+ /**
+ * Just before adding a group, can be prevented.
+ * @event beforeAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ * @param {boolean} addRule - if an empty rule will be added in the group
+ * @param {int} level - nesting level of the group, 1 is the root group
+ */
+ var e = this.trigger('beforeAddGroup', parent, addRule, level);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, level));
+ var model = parent.addGroup($group);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_group_flags, flags);
+ model.condition = this.settings.default_condition;
+
+ /**
+ * Just after adding a group
+ * @event afterAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterAddGroup', model);
+
+ /**
+ * After any change in the rules
+ * @event rulesChanged
+ * @memberof QueryBuilder
+ */
+ this.trigger('rulesChanged');
+
+ if (addRule) {
+ this.addRule(model);
+ }
+
+ return model;
+};
+
+/**
+* Tries to delete a group. The group is not deleted if at least one rule is flagged `no_delete`.
+* @param {Group} group
+* @returns {boolean} if the group has been deleted
+* @fires QueryBuilder.beforeDeleteGroup
+* @fires QueryBuilder.afterDeleteGroup
+*/
+QueryBuilder.prototype.deleteGroup = function(group) {
+ if (group.isRoot()) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a group, can be prevented
+ * @event beforeDeleteGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeDeleteGroup', group);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ var del = true;
+
+ group.each('reverse', function(rule) {
+ del &= this.deleteRule(rule);
+ }, function(group) {
+ del &= this.deleteGroup(group);
+ }, this);
+
+ if (del) {
+ group.drop();
+
+ /**
+ * Just after deleting a group
+ * @event afterDeleteGroup
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteGroup');
+
+ this.trigger('rulesChanged');
+ }
+
+ return del;
+};
+
+/**
+* Performs actions when a group's condition changes
+* @param {Group} group
+* @param {object} previousCondition
+* @fires QueryBuilder.afterUpdateGroupCondition
+* @private
+*/
+QueryBuilder.prototype.updateGroupCondition = function(group, previousCondition) {
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).each(function() {
+ var $this = $(this);
+ $this.prop('checked', $this.val() === group.condition);
+ $this.parent().toggleClass('active', $this.val() === group.condition);
+ });
+
+ /**
+ * After the group condition has been modified
+ * @event afterUpdateGroupCondition
+ * @memberof QueryBuilder
+ * @param {Group} group
+ * @param {object} previousCondition
+ */
+ this.trigger('afterUpdateGroupCondition', group, previousCondition);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Updates the visibility of conditions based on number of rules inside each group
+* @private
+*/
+QueryBuilder.prototype.refreshGroupsConditions = function() {
+ (function walk(group) {
+ if (!group.flags || (group.flags && !group.flags.condition_readonly)) {
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).prop('disabled', group.rules.length <= 1)
+ .parent().toggleClass('disabled', group.rules.length <= 1);
+ }
+
+ group.each(null, function(group) {
+ walk(group);
+ }, this);
+ }(this.model.root));
+};
+
+/**
+* Adds a new rule
+* @param {Group} parent
+* @param {object} [data] - rule custom data
+* @param {object} [flags] - flags to apply to the rule
+* @returns {Rule}
+* @fires QueryBuilder.beforeAddRule
+* @fires QueryBuilder.afterAddRule
+* @fires QueryBuilder.changer:getDefaultFilter
+*/
+QueryBuilder.prototype.addRule = function(parent, data, flags) {
+ /**
+ * Just before adding a rule, can be prevented
+ * @event beforeAddRule
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeAddRule', parent);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var rule_id = this.nextRuleId();
+ var $rule = $(this.getRuleTemplate(rule_id));
+ var model = parent.addRule($rule);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_rule_flags, flags);
+
+ /**
+ * Just after adding a rule
+ * @event afterAddRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterAddRule', model);
+
+ this.trigger('rulesChanged');
+
+ this.createRuleFilters(model);
+
+ if (this.settings.default_filter || !this.settings.display_empty_filter) {
+ /**
+ * Modifies the default filter for a rule
+ * @event changer:getDefaultFilter
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter} filter
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter}
+ */
+ model.filter = this.change('getDefaultFilter',
+ this.getFilterById(this.settings.default_filter || this.filters[0].id),
+ model
+ );
+ }
+
+ return model;
+};
+
+/**
+* Tries to delete a rule
+* @param {Rule} rule
+* @returns {boolean} if the rule has been deleted
+* @fires QueryBuilder.beforeDeleteRule
+* @fires QueryBuilder.afterDeleteRule
+*/
+QueryBuilder.prototype.deleteRule = function(rule) {
+ if (rule.flags.no_delete) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a rule, can be prevented
+ * @event beforeDeleteRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ var e = this.trigger('beforeDeleteRule', rule);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ rule.drop();
+
+ /**
+ * Just after deleting a rule
+ * @event afterDeleteRule
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteRule');
+
+ this.trigger('rulesChanged');
+
+ return true;
+};
+
+/**
+* Creates the filters for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.changer:getRuleFilters
+* @fires QueryBuilder.afterCreateRuleFilters
+* @private
+*/
+QueryBuilder.prototype.createRuleFilters = function(rule) {
+ /**
+ * Modifies the list a filters available for a rule
+ * @event changer:getRuleFilters
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter[]} filters
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter[]}
+ */
+ var filters = this.change('getRuleFilters', this.filters, rule);
+ var $filterSelect = $(this.getRuleFilterSelect(rule, filters));
+
+ rule.$el.find(QueryBuilder.selectors.filter_container).html($filterSelect);
+
+ /**
+ * After creating the dropdown for filters
+ * @event afterCreateRuleFilters
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleFilters', rule);
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Creates the operators for a rule and init the rule operator
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleOperators
+* @private
+*/
+QueryBuilder.prototype.createRuleOperators = function(rule) {
+ var $operatorContainer = rule.$el.find(QueryBuilder.selectors.operator_container).empty();
+
+ if (!rule.filter) {
+ return;
+ }
+
+ var operators = this.getOperators(rule.filter);
+ var $operatorSelect = $(this.getRuleOperatorSelect(rule, operators));
+
+ $operatorContainer.html($operatorSelect);
+
+ // set the operator without triggering update event
+ if (rule.filter.default_operator) {
+ rule.__.operator = this.getOperatorByType(rule.filter.default_operator);
+ }
+ else {
+ rule.__.operator = operators[0];
+ }
+
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+
+ /**
+ * After creating the dropdown for operators
+ * @event afterCreateRuleOperators
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {QueryBuilder.Operator[]} operators - allowed operators for this rule
+ */
+ this.trigger('afterCreateRuleOperators', rule, operators);
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Creates the main input for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleInput
+* @private
+*/
+QueryBuilder.prototype.createRuleInput = function(rule) {
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container).empty();
+
+ rule.__.value = undefined;
+
+ if (!rule.filter || !rule.operator || rule.operator.nb_inputs === 0) {
+ return;
+ }
+
+ var self = this;
+ var $inputs = $();
+ var filter = rule.filter;
+
+ for (var i = 0; i < rule.operator.nb_inputs; i++) {
+ var $ruleInput = $(this.getRuleInput(rule, i));
+ if (i > 0) $valueContainer.append(this.settings.inputs_separator);
+ $valueContainer.append($ruleInput);
+ $inputs = $inputs.add($ruleInput);
+ }
+
+ $valueContainer.css('display', '');
+
+ $inputs.on('change ' + (filter.input_event || ''), function() {
+ if (!rule._updating_input) {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+ });
+
+ if (filter.plugin) {
+ $inputs[filter.plugin](filter.plugin_config || {});
+ }
+
+ /**
+ * After creating the input for a rule and initializing optional plugin
+ * @event afterCreateRuleInput
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleInput', rule);
+
+ if (filter.default_value !== undefined) {
+ rule.value = filter.default_value;
+ }
+ else {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Performs action when a rule's filter changes
+* @param {Rule} rule
+* @param {object} previousFilter
+* @fires QueryBuilder.afterUpdateRuleFilter
+* @private
+*/
+QueryBuilder.prototype.updateRuleFilter = function(rule, previousFilter) {
+ //Reset filter
+ rule.$el.find(QueryBuilder.selectors.tooltip).hide();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", "");
+ rule.$el.find(QueryBuilder.selectors.description).hide().find("span").text("");
+
+ var tooltip = rule.filter.tooltip;
+ var description = rule.filter.description;
+
+ this.createRuleOperators(rule);
+ this.createRuleInput(rule);
+
+ rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
+ if(tooltip) {
+ rule.$el.find(QueryBuilder.selectors.tooltip).show();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", tooltip);
+ }
+ if(description) {
+ rule.$el.find(QueryBuilder.selectors.description).show().find("span").text(description);
+ }
+
+ // clear rule data if the filter changed
+ if (previousFilter && rule.filter && previousFilter.id !== rule.filter.id) {
+ rule.data = undefined;
+ }
+
+ /**
+ * After the filter has been updated and the operators and input re-created
+ * @event afterUpdateRuleFilter
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousFilter
+ */
+ this.trigger('afterUpdateRuleFilter', rule, previousFilter);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Performs actions when a rule's operator changes
+* @param {Rule} rule
+* @param {object} previousOperator
+* @fires QueryBuilder.afterUpdateRuleOperator
+* @private
+*/
+QueryBuilder.prototype.updateRuleOperator = function(rule, previousOperator) {
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ if (!rule.operator || rule.operator.nb_inputs === 0) {
+ $valueContainer.hide();
+
+ rule.__.value = undefined;
+ }
+ else {
+ $valueContainer.css('display', '');
+
+ if ($valueContainer.is(':empty') || !previousOperator ||
+ rule.operator.nb_inputs !== previousOperator.nb_inputs ||
+ rule.operator.optgroup !== previousOperator.optgroup
+ ) {
+ this.createRuleInput(rule);
+ }
+ }
+
+ if (rule.operator) {
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+
+ // refresh value if the format changed for this operator
+ rule.__.value = this.getRuleInputValue(rule);
+ }
+
+ /**
+ * After the operator has been updated and the input optionally re-created
+ * @event afterUpdateRuleOperator
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousOperator
+ */
+ this.trigger('afterUpdateRuleOperator', rule, previousOperator);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Performs actions when rule's value changes
+* @param {Rule} rule
+* @param {object} previousValue
+* @fires QueryBuilder.afterUpdateRuleValue
+* @private
+*/
+QueryBuilder.prototype.updateRuleValue = function(rule, previousValue) {
+ if (!rule._updating_value) {
+ this.setRuleInputValue(rule, rule.value);
+ }
+
+ /**
+ * After the rule value has been modified
+ * @event afterUpdateRuleValue
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {*} previousValue
+ */
+ this.trigger('afterUpdateRuleValue', rule, previousValue);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Changes a rule's properties depending on its flags
+* @param {Rule} rule
+* @fires QueryBuilder.afterApplyRuleFlags
+* @private
+*/
+QueryBuilder.prototype.applyRuleFlags = function(rule) {
+ var flags = rule.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ rule.$el.find(Selectors.rule_filter).prop('disabled', flags.filter_readonly);
+ rule.$el.find(Selectors.rule_operator).prop('disabled', flags.operator_readonly);
+ rule.$el.find(Selectors.rule_value).prop('disabled', flags.value_readonly);
+
+ if (flags.no_delete) {
+ rule.$el.find(Selectors.delete_rule).remove();
+ }
+
+ /**
+ * After rule's flags has been applied
+ * @event afterApplyRuleFlags
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterApplyRuleFlags', rule);
+};
+
+/**
+* Changes group's properties depending on its flags
+* @param {Group} group
+* @fires QueryBuilder.afterApplyGroupFlags
+* @private
+*/
+QueryBuilder.prototype.applyGroupFlags = function(group) {
+ var flags = group.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ group.$el.find('>' + Selectors.group_condition).prop('disabled', flags.condition_readonly)
+ .parent().toggleClass('readonly', flags.condition_readonly);
+
+ if (flags.no_add_rule) {
+ group.$el.find(Selectors.add_rule).remove();
+ }
+ if (flags.no_add_group) {
+ group.$el.find(Selectors.add_group).remove();
+ }
+ if (flags.no_delete) {
+ group.$el.find(Selectors.delete_group).remove();
+ }
+
+ /**
+ * After group's flags has been applied
+ * @event afterApplyGroupFlags
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterApplyGroupFlags', group);
+};
+
+/**
+* Clears all errors markers
+* @param {Node} [node] default is root Group
+*/
+QueryBuilder.prototype.clearErrors = function(node) {
+ node = node || this.model.root;
+
+ if (!node) {
+ return;
+ }
+
+ node.error = null;
+
+ if (node instanceof Group) {
+ node.each(function(rule) {
+ rule.error = null;
+ }, function(group) {
+ this.clearErrors(group);
+ }, this);
+ }
+};
+
+/**
+* Adds/Removes error on a Rule or Group
+* @param {Node} node
+* @fires QueryBuilder.changer:displayError
+* @private
+*/
+QueryBuilder.prototype.updateError = function(node) {
+ if (this.settings.display_errors) {
+ if (node.error === null) {
+ node.$el.removeClass('has-error');
+ }
+ else {
+ var errorMessage = this.translate('errors', node.error[0]);
+ errorMessage = Utils.fmt(errorMessage, node.error.slice(1));
+
+ /**
+ * Modifies an error message before display
+ * @event changer:displayError
+ * @memberof QueryBuilder
+ * @param {string} errorMessage - the error message (translated and formatted)
+ * @param {array} error - the raw error array (error code and optional arguments)
+ * @param {Node} node
+ * @returns {string}
+ */
+ errorMessage = this.change('displayError', errorMessage, node.error, node);
+
+ node.$el.addClass('has-error')
+ .find(QueryBuilder.selectors.error_container).eq(0)
+ .attr('data-tooltip', errorMessage);
+ }
+ }
+};
+
+/**
+* Triggers a validation error event
+* @param {Node} node
+* @param {string|array} error
+* @param {*} value
+* @fires QueryBuilder.validationError
+* @private
+*/
+QueryBuilder.prototype.triggerValidationError = function(node, error, value) {
+ if (!$.isArray(error)) {
+ error = [error];
+ }
+
+ /**
+ * Fired when a validation error occurred, can be prevented
+ * @event validationError
+ * @memberof QueryBuilder
+ * @param {Node} node
+ * @param {string} error
+ * @param {*} value
+ */
+ var e = this.trigger('validationError', node, error, value);
+ if (!e.isDefaultPrevented()) {
+ node.error = error;
+ }
+};
+
+
+/**
+ * Destroys the builder
+ * @fires QueryBuilder.beforeDestroy
+ */
+QueryBuilder.prototype.destroy = function() {
+ /**
+ * Before the {@link QueryBuilder#destroy} method
+ * @event beforeDestroy
+ * @memberof QueryBuilder
+ */
+ this.trigger('beforeDestroy');
+
+ if (this.status.generated_id) {
+ this.$el.removeAttr('id');
+ }
+
+ this.clear();
+ this.model = null;
+
+ this.$el
+ .off('.queryBuilder')
+ .removeClass('query-builder')
+ .removeData('queryBuilder');
+
+ delete this.$el[0].queryBuilder;
+};
+
+/**
+ * Clear all rules and resets the root group
+ * @fires QueryBuilder.beforeReset
+ * @fires QueryBuilder.afterReset
+ */
+QueryBuilder.prototype.reset = function() {
+ /**
+ * Before the {@link QueryBuilder#reset} method, can be prevented
+ * @event beforeReset
+ * @memberof QueryBuilder
+ */
+ var e = this.trigger('beforeReset');
+ if (e.isDefaultPrevented()) {
+ return;
+ }
+
+ this.status.group_id = 1;
+ this.status.rule_id = 0;
+
+ this.model.root.empty();
+
+ this.model.root.data = undefined;
+ this.model.root.flags = $.extend({}, this.settings.default_group_flags);
+ this.model.root.condition = this.settings.default_condition;
+
+ this.addRule(this.model.root);
+
+ /**
+ * After the {@link QueryBuilder#reset} method
+ * @event afterReset
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterReset');
+
+ this.trigger('rulesChanged');
+};
+
+/**
+ * Clears all rules and removes the root group
+ * @fires QueryBuilder.beforeClear
+ * @fires QueryBuilder.afterClear
+ */
+QueryBuilder.prototype.clear = function() {
+ /**
+ * Before the {@link QueryBuilder#clear} method, can be prevented
+ * @event beforeClear
+ * @memberof QueryBuilder
+ */
+ var e = this.trigger('beforeClear');
+ if (e.isDefaultPrevented()) {
+ return;
+ }
+
+ this.status.group_id = 0;
+ this.status.rule_id = 0;
+
+ if (this.model.root) {
+ this.model.root.drop();
+ this.model.root = null;
+ }
+
+ /**
+ * After the {@link QueryBuilder#clear} method
+ * @event afterClear
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterClear');
+
+ this.trigger('rulesChanged');
+};
+
+/**
+ * Modifies the builder configuration.
+ * Only options defined in QueryBuilder.modifiable_options are modifiable
+ * @param {object} options
+ */
+QueryBuilder.prototype.setOptions = function(options) {
+ $.each(options, function(opt, value) {
+ if (QueryBuilder.modifiable_options.indexOf(opt) !== -1) {
+ this.settings[opt] = value;
+ }
+ }.bind(this));
+};
+
+/**
+ * Returns the model associated to a DOM object, or the root model
+ * @param {jQuery} [target]
+ * @returns {Node}
+ */
+QueryBuilder.prototype.getModel = function(target) {
+ if (!target) {
+ return this.model.root;
+ }
+ else if (target instanceof Node) {
+ return target;
+ }
+ else {
+ return $(target).data('queryBuilderModel');
+ }
+};
+
+/**
+ * Validates the whole builder
+ * @param {object} [options]
+ * @param {boolean} [options.skip_empty=false] - skips validating rules that have no filter selected
+ * @returns {boolean}
+ * @fires QueryBuilder.changer:validate
+ */
+QueryBuilder.prototype.validate = function(options) {
+ options = $.extend({
+ skip_empty: false
+ }, options);
+
+ this.clearErrors();
+
+ var self = this;
+
+ var valid = (function parse(group) {
+ var done = 0;
+ var errors = 0;
+
+ group.each(function(rule) {
+ if (!rule.filter && options.skip_empty) {
+ return;
+ }
+
+ if (!rule.filter) {
+ self.triggerValidationError(rule, 'no_filter', null);
+ errors++;
+ return;
+ }
+
+ if (!rule.operator) {
+ self.triggerValidationError(rule, 'no_operator', null);
+ errors++;
+ return;
+ }
+
+ if (rule.operator.nb_inputs !== 0) {
+ var valid = self.validateValue(rule, rule.value);
+
+ if (valid !== true) {
+ self.triggerValidationError(rule, valid, rule.value);
+ errors++;
+ return;
+ }
+ }
+
+ done++;
+
+ }, function(group) {
+ var res = parse(group);
+ if (res === true) {
+ done++;
+ }
+ else if (res === false) {
+ errors++;
+ }
+ });
+
+ if (errors > 0) {
+ return false;
+ }
+ else if (done === 0 && !group.isRoot() && options.skip_empty) {
+ return null;
+ }
+ else if (done === 0 && (!self.settings.allow_empty || !group.isRoot())) {
+ self.triggerValidationError(group, 'empty_group', null);
+ return false;
+ }
+
+ return true;
+
+ }(this.model.root));
+
+ /**
+ * Modifies the result of the {@link QueryBuilder#validate} method
+ * @event changer:validate
+ * @memberof QueryBuilder
+ * @param {boolean} valid
+ * @returns {boolean}
+ */
+ return this.change('validate', valid);
+};
+
+/**
+ * Gets an object representing current rules
+ * @param {object} [options]
+ * @param {boolean|string} [options.get_flags=false] - export flags, true: only changes from default flags or 'all'
+ * @param {boolean} [options.allow_invalid=false] - returns rules even if they are invalid
+ * @param {boolean} [options.skip_empty=false] - remove rules that have no filter selected
+ * @returns {object}
+ * @fires QueryBuilder.changer:ruleToJson
+ * @fires QueryBuilder.changer:groupToJson
+ * @fires QueryBuilder.changer:getRules
+ */
+QueryBuilder.prototype.getRules = function(options) {
+ options = $.extend({
+ get_flags: false,
+ allow_invalid: false,
+ skip_empty: false
+ }, options);
+
+ var valid = this.validate(options);
+ if (!valid && !options.allow_invalid) {
+ return null;
+ }
+
+ var self = this;
+
+ var out = (function parse(group) {
+ var groupData = {
+ condition: group.condition,
+ rules: []
+ };
+
+ if (group.data) {
+ groupData.data = $.extendext(true, 'replace', {}, group.data);
+ }
+
+ if (options.get_flags) {
+ var flags = self.getGroupFlags(group.flags, options.get_flags === 'all');
+ if (!$.isEmptyObject(flags)) {
+ groupData.flags = flags;
+ }
+ }
+
+ group.each(function(rule) {
+ if (!rule.filter && options.skip_empty) {
+ return;
+ }
+
+ var value = null;
+ if (!rule.operator || rule.operator.nb_inputs !== 0) {
+ value = rule.value;
+ }
+
+ var ruleData = {
+ id: rule.filter ? rule.filter.id : null,
+ field: rule.filter ? rule.filter.field : null,
+ type: rule.filter ? rule.filter.type : null,
+ input: rule.filter ? rule.filter.input : null,
+ operator: rule.operator ? rule.operator.type : null,
+ value: rule.filter.type == "boolean" ? ((value == true || value == 1 || value == "1") ? "1" : "0") : value
+ };
+
+ if (rule.filter && rule.filter.data || rule.data) {
+ ruleData.data = $.extendext(true, 'replace', {}, rule.filter.data, rule.data);
+ }
+
+ if (options.get_flags) {
+ var flags = self.getRuleFlags(rule.flags, options.get_flags === 'all');
+ if (!$.isEmptyObject(flags)) {
+ ruleData.flags = flags;
+ }
+ }
+
+ /**
+ * Modifies the JSON generated from a Rule object
+ * @event changer:ruleToJson
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {Rule} rule
+ * @returns {object}
+ */
+ groupData.rules.push(self.change('ruleToJson', ruleData, rule));
+
+ }, function(model) {
+ var data = parse(model);
+ if (data.rules.length !== 0 || !options.skip_empty) {
+ groupData.rules.push(data);
+ }
+ }, this);
+
+ /**
+ * Modifies the JSON generated from a Group object
+ * @event changer:groupToJson
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {Group} group
+ * @returns {object}
+ */
+ return self.change('groupToJson', groupData, group);
+
+ }(this.model.root));
+
+ out.valid = valid;
+
+ /**
+ * Modifies the result of the {@link QueryBuilder#getRules} method
+ * @event changer:getRules
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @returns {object}
+ */
+ return this.change('getRules', out);
+};
+
+/**
+ * Sets rules from object
+ * @param {object} data
+ * @param {object} [options]
+ * @param {boolean} [options.allow_invalid=false] - silent-fail if the data are invalid
+ * @throws RulesError, UndefinedConditionError
+ * @fires QueryBuilder.changer:setRules
+ * @fires QueryBuilder.changer:jsonToRule
+ * @fires QueryBuilder.changer:jsonToGroup
+ * @fires QueryBuilder.afterSetRules
+ */
+QueryBuilder.prototype.setRules = function(data, options) {
+ options = $.extend({
+ allow_invalid: false
+ }, options);
+
+ if ($.isArray(data)) {
+ data = {
+ condition: this.settings.default_condition,
+ rules: data
+ };
+ }
+
+ if (!data || !data.rules || (data.rules.length === 0 && !this.settings.allow_empty)) {
+ Utils.error('RulesParse', 'Incorrect data object passed');
+ }
+
+ this.clear();
+ this.setRoot(false, data.data, this.parseGroupFlags(data));
+
+ /**
+ * Modifies data before the {@link QueryBuilder#setRules} method
+ * @event changer:setRules
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {object} options
+ * @returns {object}
+ */
+ data = this.change('setRules', data, options);
+
+ var self = this;
+
+ (function add(data, group) {
+ if (group === null) {
+ return;
+ }
+
+ if (data.condition === undefined) {
+ data.condition = self.settings.default_condition;
+ }
+ else if (self.settings.conditions.indexOf(data.condition) == -1) {
+ Utils.error(!options.allow_invalid, 'UndefinedCondition', 'Invalid condition "{0}"', data.condition);
+ data.condition = self.settings.default_condition;
+ }
+
+ group.condition = data.condition;
+
+ data.rules.forEach(function(item) {
+ var model;
+
+ if (item.rules !== undefined) {
+ if (self.settings.allow_groups !== -1 && self.settings.allow_groups < group.level) {
+ Utils.error(!options.allow_invalid, 'RulesParse', 'No more than {0} groups are allowed', self.settings.allow_groups);
+ self.reset();
+ }
+ else {
+ model = self.addGroup(group, false, item.data, self.parseGroupFlags(item));
+ if (model === null) {
+ return;
+ }
+
+ add(item, model);
+ }
+ }
+ else {
+ if (!item.empty) {
+ if (item.id === undefined) {
+ Utils.error(!options.allow_invalid, 'RulesParse', 'Missing rule field id');
+ item.empty = true;
+ }
+ if (item.operator === undefined) {
+ item.operator = 'equal';
+ }
+ }
+
+ model = self.addRule(group, item.data, self.parseRuleFlags(item));
+ if (model === null) {
+ return;
+ }
+
+ if (!item.empty) {
+ model.filter = self.getFilterById(item.id, !options.allow_invalid);
+ }
+
+ if (model.filter) {
+ model.operator = self.getOperatorByType(item.operator, !options.allow_invalid);
+
+ if (!model.operator) {
+ model.operator = self.getOperators(model.filter)[0];
+ }
+ }
+
+ if (model.operator && model.operator.nb_inputs !== 0) {
+ if (item.value !== undefined) {
+ model.value = item.value;
+ }
+ else if (model.filter.default_value !== undefined) {
+ model.value = model.filter.default_value;
+ }
+ }
+
+ /**
+ * Modifies the Rule object generated from the JSON
+ * @event changer:jsonToRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} json
+ * @returns {Rule} the same rule
+ */
+ if (self.change('jsonToRule', model, item) != model) {
+ Utils.error('RulesParse', 'Plugin tried to change rule reference');
+ }
+ }
+ });
+
+ /**
+ * Modifies the Group object generated from the JSON
+ * @event changer:jsonToGroup
+ * @memberof QueryBuilder
+ * @param {Group} group
+ * @param {object} json
+ * @returns {Group} the same group
+ */
+ if (self.change('jsonToGroup', group, data) != group) {
+ Utils.error('RulesParse', 'Plugin tried to change group reference');
+ }
+
+ }(data, this.model.root));
+
+ /**
+ * After the {@link QueryBuilder#setRules} method
+ * @event afterSetRules
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterSetRules');
+};
+
+
+/**
+ * Performs value validation
+ * @param {Rule} rule
+ * @param {string|string[]} value
+ * @returns {array|boolean} true or error array
+ * @fires QueryBuilder.changer:validateValue
+ */
+QueryBuilder.prototype.validateValue = function(rule, value) {
+ var validation = rule.filter.validation || {};
+ var result = true;
+
+ if (validation.callback) {
+ result = validation.callback.call(this, value, rule);
+ }
+ else {
+ result = this._validateValue(rule, value);
+ }
+
+ /**
+ * Modifies the result of the rule validation method
+ * @event changer:validateValue
+ * @memberof QueryBuilder
+ * @param {array|boolean} result - true or an error array
+ * @param {*} value
+ * @param {Rule} rule
+ * @returns {array|boolean}
+ */
+ return this.change('validateValue', result, value, rule);
+};
+
+/**
+ * Default validation function
+ * @param {Rule} rule
+ * @param {string|string[]} value
+ * @returns {array|boolean} true or error array
+ * @throws ConfigError
+ * @private
+ */
+QueryBuilder.prototype._validateValue = function(rule, value) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+ var validation = filter.validation || {};
+ var result = true;
+ var tmp, tempValue;
+
+ if (rule.operator.nb_inputs === 1) {
+ value = [value];
+ }
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ if (!operator.multiple && $.isArray(value[i]) && value[i].length > 1) {
+ result = ['operator_not_multiple', operator.type, this.translate('operators', operator.type)];
+ break;
+ }
+
+ switch (filter.input) {
+ case 'radio':
+ if (value[i] === undefined || value[i].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['radio_empty'];
+ }
+ break;
+ }
+ break;
+
+ case 'checkbox':
+ if (value[i] === undefined || value[i].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['checkbox_empty'];
+ }
+ break;
+ }
+ break;
+
+ case 'select':
+ if (value[i] === undefined || value[i].length === 0 || (filter.placeholder && value[i] == filter.placeholder_value)) {
+ if (!validation.allow_empty_value) {
+ result = ['select_empty'];
+ }
+ break;
+ }
+ break;
+
+ default:
+ tempValue = $.isArray(value[i]) ? value[i] : [value[i]];
+
+ for (var j = 0; j < tempValue.length; j++) {
+ switch (QueryBuilder.types[filter.type]) {
+ case 'string':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['string_empty'];
+ }
+ break;
+ }
+ if (validation.min !== undefined) {
+ if (tempValue[j].length < parseInt(validation.min)) {
+ result = [this.getValidationMessage(validation, 'min', 'string_exceed_min_length'), validation.min];
+ break;
+ }
+ }
+ if (validation.max !== undefined) {
+ if (tempValue[j].length > parseInt(validation.max)) {
+ result = [this.getValidationMessage(validation, 'max', 'string_exceed_max_length'), validation.max];
+ break;
+ }
+ }
+ if (validation.format) {
+ if (typeof validation.format == 'string') {
+ validation.format = new RegExp(validation.format);
+ }
+ if (!validation.format.test(tempValue[j])) {
+ result = [this.getValidationMessage(validation, 'format', 'string_invalid_format'), validation.format];
+ break;
+ }
+ }
+ break;
+
+ case 'number':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['number_nan'];
+ }
+ break;
+ }
+ if (isNaN(tempValue[j])) {
+ result = ['number_nan'];
+ break;
+ }
+ if (filter.type == 'integer') {
+ if (parseInt(tempValue[j]) != tempValue[j]) {
+ result = ['number_not_integer'];
+ break;
+ }
+ }
+ else {
+ if (parseFloat(tempValue[j]) != tempValue[j]) {
+ result = ['number_not_double'];
+ break;
+ }
+ }
+ if (validation.min !== undefined) {
+ if (tempValue[j] < parseFloat(validation.min)) {
+ result = [this.getValidationMessage(validation, 'min', 'number_exceed_min'), validation.min];
+ break;
+ }
+ }
+ if (validation.max !== undefined) {
+ if (tempValue[j] > parseFloat(validation.max)) {
+ result = [this.getValidationMessage(validation, 'max', 'number_exceed_max'), validation.max];
+ break;
+ }
+ }
+ if (validation.step !== undefined && validation.step !== 'any') {
+ var v = (tempValue[j] / validation.step).toPrecision(14);
+ if (parseInt(v) != v) {
+ result = [this.getValidationMessage(validation, 'step', 'number_wrong_step'), validation.step];
+ break;
+ }
+ }
+ break;
+
+ case 'datetime':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['datetime_empty'];
+ }
+ break;
+ }
+
+ // we need MomentJS
+ if (validation.format) {
+ if (!('moment' in window)) {
+ Utils.error('MissingLibrary', 'MomentJS is required for Date/Time validation. Get it here http://momentjs.com');
+ }
+
+ var datetime = moment(tempValue[j], validation.format);
+ if (!datetime.isValid()) {
+ result = [this.getValidationMessage(validation, 'format', 'datetime_invalid'), validation.format];
+ break;
+ }
+ else {
+ if (validation.min) {
+ if (datetime < moment(validation.min, validation.format)) {
+ result = [this.getValidationMessage(validation, 'min', 'datetime_exceed_min'), validation.min];
+ break;
+ }
+ }
+ if (validation.max) {
+ if (datetime > moment(validation.max, validation.format)) {
+ result = [this.getValidationMessage(validation, 'max', 'datetime_exceed_max'), validation.max];
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case 'boolean':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['boolean_not_valid'];
+ }
+ break;
+ }
+ tmp = ('' + tempValue[j]).trim().toLowerCase();
+ if (tmp !== 'true' && tmp !== 'false' && tmp !== '1' && tmp !== '0' && tempValue[j] !== 1 && tempValue[j] !== 0) {
+ result = ['boolean_not_valid'];
+ break;
+ }
+ }
+
+ if (result !== true) {
+ break;
+ }
+ }
+ }
+
+ if (result !== true) {
+ break;
+ }
+ }
+
+ if ((rule.operator.type === 'between' || rule.operator.type === 'not_between') && value.length === 2) {
+ switch (QueryBuilder.types[filter.type]) {
+ case 'number':
+ if (value[0] > value[1]) {
+ result = ['number_between_invalid', value[0], value[1]];
+ }
+ break;
+
+ case 'datetime':
+ // we need MomentJS
+ if (validation.format) {
+ if (!('moment' in window)) {
+ Utils.error('MissingLibrary', 'MomentJS is required for Date/Time validation. Get it here http://momentjs.com');
+ }
+
+ if (moment(value[0], validation.format).isAfter(moment(value[1], validation.format))) {
+ result = ['datetime_between_invalid', value[0], value[1]];
+ }
+ }
+ break;
+ }
+ }
+
+ return result;
+};
+
+/**
+ * Returns an incremented group ID
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.nextGroupId = function() {
+ return this.status.id + '_group_' + (this.status.group_id++);
+};
+
+/**
+ * Returns an incremented rule ID
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.nextRuleId = function() {
+ return this.status.id + '_rule_' + (this.status.rule_id++);
+};
+
+/**
+ * Returns the operators for a filter
+ * @param {string|object} filter - filter id or filter object
+ * @returns {object[]}
+ * @fires QueryBuilder.changer:getOperators
+ */
+QueryBuilder.prototype.getOperators = function(filter) {
+ if (typeof filter == 'string') {
+ filter = this.getFilterById(filter);
+ }
+
+ var result = [];
+
+ for (var i = 0, l = this.operators.length; i < l; i++) {
+ // filter operators check
+ if (filter.operators) {
+ if (filter.operators.indexOf(this.operators[i].type) == -1) {
+ continue;
+ }
+ }
+ // type check
+ else if (this.operators[i].apply_to.indexOf(QueryBuilder.types[filter.type]) == -1) {
+ continue;
+ }
+
+ result.push(this.operators[i]);
+ }
+
+ // keep sort order defined for the filter
+ if (filter.operators) {
+ result.sort(function(a, b) {
+ return filter.operators.indexOf(a.type) - filter.operators.indexOf(b.type);
+ });
+ }
+
+ /**
+ * Modifies the operators available for a filter
+ * @event changer:getOperators
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Operator[]} operators
+ * @param {QueryBuilder.Filter} filter
+ * @returns {QueryBuilder.Operator[]}
+ */
+ return this.change('getOperators', result, filter);
+};
+
+/**
+ * Returns a particular filter by its id
+ * @param {string} id
+ * @param {boolean} [doThrow=true]
+ * @returns {object|null}
+ * @throws UndefinedFilterError
+ */
+QueryBuilder.prototype.getFilterById = function(id, doThrow) {
+ if (id == '-1') {
+ return null;
+ }
+
+ for (var i = 0, l = this.filters.length; i < l; i++) {
+ if (this.filters[i].id == id) {
+ return this.filters[i];
+ }
+ }
+
+ Utils.error(doThrow !== false, 'UndefinedFilter', 'Undefined filter "{0}"', id);
+
+ return null;
+};
+
+/**
+ * Returns a particular operator by its type
+ * @param {string} type
+ * @param {boolean} [doThrow=true]
+ * @returns {object|null}
+ * @throws UndefinedOperatorError
+ */
+QueryBuilder.prototype.getOperatorByType = function(type, doThrow) {
+ if (type == '-1') {
+ return null;
+ }
+
+ for (var i = 0, l = this.operators.length; i < l; i++) {
+ if (this.operators[i].type == type) {
+ return this.operators[i];
+ }
+ }
+
+ Utils.error(doThrow !== false, 'UndefinedOperator', 'Undefined operator "{0}"', type);
+
+ return null;
+};
+
+/**
+ * Returns rule's current input value
+ * @param {Rule} rule
+ * @returns {*}
+ * @fires QueryBuilder.changer:getRuleValue
+ * @private
+ */
+QueryBuilder.prototype.getRuleInputValue = function(rule) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+ var value = [];
+
+ if (filter.valueGetter) {
+ value = filter.valueGetter.call(this, rule);
+ }
+ else {
+ var $value = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ var name = Utils.escapeElementId(rule.id + '_value_' + i);
+ var tmp;
+
+ switch (filter.input) {
+ case 'radio':
+ value.push($value.find('[name=' + name + ']:checked').val());
+ break;
+
+ case 'checkbox':
+ tmp = [];
+ // jshint loopfunc:true
+ $value.find('[name=' + name + ']:checked').each(function() {
+ tmp.push($(this).val());
+ });
+ // jshint loopfunc:false
+ value.push(tmp);
+ break;
+
+ case 'select':
+ if (filter.multiple) {
+ tmp = [];
+ // jshint loopfunc:true
+ $value.find('[name=' + name + '] option:selected').each(function() {
+ tmp.push($(this).val());
+ });
+ // jshint loopfunc:false
+ value.push(tmp);
+ }
+ else {
+ value.push($value.find('[name=' + name + '] option:selected').val());
+ }
+ break;
+
+ default:
+ value.push($value.find('[name=' + name + ']').val());
+ }
+ }
+
+ value = value.map(function(val) {
+ if (operator.multiple && filter.value_separator && typeof val == 'string') {
+ val = val.split(filter.value_separator);
+ }
+
+ if ($.isArray(val)) {
+ return val.map(function(subval) {
+ return Utils.changeType(subval, filter.type);
+ });
+ }
+ else {
+ return Utils.changeType(val, filter.type);
+ }
+ });
+
+ if (operator.nb_inputs === 1) {
+ value = value[0];
+ }
+
+ // @deprecated
+ if (filter.valueParser) {
+ value = filter.valueParser.call(this, rule, value);
+ }
+ }
+
+ /**
+ * Modifies the rule's value grabbed from the DOM
+ * @event changer:getRuleValue
+ * @memberof QueryBuilder
+ * @param {*} value
+ * @param {Rule} rule
+ * @returns {*}
+ */
+ return this.change('getRuleValue', value, rule);
+};
+
+/**
+ * Sets the value of a rule's input
+ * @param {Rule} rule
+ * @param {*} value
+ * @private
+ */
+QueryBuilder.prototype.setRuleInputValue = function(rule, value) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+
+ if (!filter || !operator) {
+ return;
+ }
+
+ rule._updating_input = true;
+
+ if (filter.valueSetter) {
+ filter.valueSetter.call(this, rule, value);
+ }
+ else {
+ var $value = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ if (operator.nb_inputs == 1) {
+ value = [value];
+ }
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ var name = Utils.escapeElementId(rule.id + '_value_' + i);
+
+ switch (filter.input) {
+ case 'radio':
+ $value.find('[name=' + name + '][value="' + value[i] + '"]').prop('checked', true).trigger('change');
+ break;
+
+ case 'checkbox':
+ if (!$.isArray(value[i])) {
+ value[i] = [value[i]];
+ }
+ // jshint loopfunc:true
+ value[i].forEach(function(value) {
+ $value.find('[name=' + name + '][value="' + value + '"]').prop('checked', true).trigger('change');
+ });
+ // jshint loopfunc:false
+ break;
+
+ default:
+ if (operator.multiple && filter.value_separator && $.isArray(value[i])) {
+ value[i] = value[i].join(filter.value_separator);
+ }
+ if (operator.type === 'between') {
+
+ var arrval = value.split(",");
+ $value.find('[name=' + name + ']').val(arrval[i]).trigger('change');
+
+ } else {
+
+ $value.find('[name=' + name + ']').val(value[i]).trigger('change');
+ } break;
+ }
+ }
+ }
+
+ rule._updating_input = false;
+};
+
+/**
+ * Parses rule flags
+ * @param {object} rule
+ * @returns {object}
+ * @fires QueryBuilder.changer:parseRuleFlags
+ * @private
+ */
+QueryBuilder.prototype.parseRuleFlags = function(rule) {
+ var flags = $.extend({}, this.settings.default_rule_flags);
+
+ if (rule.readonly) {
+ $.extend(flags, {
+ filter_readonly: true,
+ operator_readonly: true,
+ value_readonly: true,
+ no_delete: true
+ });
+ }
+
+ if (rule.flags) {
+ $.extend(flags, rule.flags);
+ }
+
+ /**
+ * Modifies the consolidated rule's flags
+ * @event changer:parseRuleFlags
+ * @memberof QueryBuilder
+ * @param {object} flags
+ * @param {object} rule - not a Rule object
+ * @returns {object}
+ */
+ return this.change('parseRuleFlags', flags, rule);
+};
+
+/**
+ * Gets a copy of flags of a rule
+ * @param {object} flags
+ * @param {boolean} [all=false] - return all flags or only changes from default flags
+ * @returns {object}
+ * @private
+ */
+QueryBuilder.prototype.getRuleFlags = function(flags, all) {
+ if (all) {
+ return $.extend({}, flags);
+ }
+ else {
+ var ret = {};
+ $.each(this.settings.default_rule_flags, function(key, value) {
+ if (flags[key] !== value) {
+ ret[key] = flags[key];
+ }
+ });
+ return ret;
+ }
+};
+
+/**
+ * Parses group flags
+ * @param {object} group
+ * @returns {object}
+ * @fires QueryBuilder.changer:parseGroupFlags
+ * @private
+ */
+QueryBuilder.prototype.parseGroupFlags = function(group) {
+ var flags = $.extend({}, this.settings.default_group_flags);
+
+ if (group.readonly) {
+ $.extend(flags, {
+ condition_readonly: true,
+ no_add_rule: true,
+ no_add_group: true,
+ no_delete: true
+ });
+ }
+
+ if (group.flags) {
+ $.extend(flags, group.flags);
+ }
+
+ /**
+ * Modifies the consolidated group's flags
+ * @event changer:parseGroupFlags
+ * @memberof QueryBuilder
+ * @param {object} flags
+ * @param {object} group - not a Group object
+ * @returns {object}
+ */
+ return this.change('parseGroupFlags', flags, group);
+};
+
+/**
+ * Gets a copy of flags of a group
+ * @param {object} flags
+ * @param {boolean} [all=false] - return all flags or only changes from default flags
+ * @returns {object}
+ * @private
+ */
+QueryBuilder.prototype.getGroupFlags = function(flags, all) {
+ if (all) {
+ return $.extend({}, flags);
+ }
+ else {
+ var ret = {};
+ $.each(this.settings.default_group_flags, function(key, value) {
+ if (flags[key] !== value) {
+ ret[key] = flags[key];
+ }
+ });
+ return ret;
+ }
+};
+
+/**
+ * Translate a label either by looking in the `lang` object or in itself if it's an object where keys are language codes
+ * @param {string} [category]
+ * @param {string|object} key
+ * @returns {string}
+ * @fires QueryBuilder.changer:translate
+ */
+QueryBuilder.prototype.translate = function(category, key) {
+ if (!key) {
+ key = category;
+ category = undefined;
+ }
+
+ var translation;
+ if (typeof key === 'object') {
+ translation = key[this.settings.lang_code] || key['en'];
+ }
+ else {
+ translation = (category ? this.lang[category] : this.lang)[key] || key;
+ }
+
+ /**
+ * Modifies the translated label
+ * @event changer:translate
+ * @memberof QueryBuilder
+ * @param {string} translation
+ * @param {string|object} key
+ * @param {string} [category]
+ * @returns {string}
+ */
+ return this.change('translate', translation, key, category);
+};
+
+/**
+ * Returns a validation message
+ * @param {object} validation
+ * @param {string} type
+ * @param {string} def
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.getValidationMessage = function(validation, type, def) {
+ return validation.messages && validation.messages[type] || def;
+};
+
+
+QueryBuilder.templates.group = '\
+';
+
+QueryBuilder.templates.rule = '\
+ \
+
\
+ \
+
\
+
\
+
\
+ {{? it.settings.display_errors }} \
+
\
+ {{?}} \
+
\
+
\
+
\
\
+
';
+
+QueryBuilder.templates.filterSelect = '\
+{{ var optgroup = null; }} \
+ \
+ {{? it.settings.display_empty_filter }} \
+ {{= it.settings.select_placeholder }} \
+ {{?}} \
+ {{~ it.filters: filter }} \
+ {{? optgroup !== filter.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = filter.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= it.translate(filter.label) }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+QueryBuilder.templates.operatorSelect = '\
+{{? it.operators.length === 1 }} \
+ \
+{{= it.translate("operators", it.operators[0].type) }} \
+ \
+{{?}} \
+{{ var optgroup = null; }} \
+ \
+ {{~ it.operators: operator }} \
+ {{? optgroup !== operator.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = operator.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= it.translate("operators", operator.type) }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+QueryBuilder.templates.ruleValueSelect = '\
+{{ var optgroup = null; }} \
+ \
+ {{? it.rule.filter.placeholder }} \
+ {{= it.rule.filter.placeholder }} \
+ {{?}} \
+ {{~ it.rule.filter.values: entry }} \
+ {{? optgroup !== entry.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = entry.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= entry.label }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+/**
+ * Returns group's HTML
+ * @param {string} group_id
+ * @param {int} level
+ * @returns {string}
+ * @fires QueryBuilder.changer:getGroupTemplate
+ * @private
+ */
+QueryBuilder.prototype.getGroupTemplate = function(group_id, level) {
+ var h = this.templates.group({
+ builder: this,
+ group_id: group_id,
+ level: level,
+ conditions: this.settings.conditions,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of a group
+ * @event changer:getGroupTemplate
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {int} level
+ * @returns {string}
+ */
+ return this.change('getGroupTemplate', h, level);
+};
+
+/**
+ * Returns rule's HTML
+ * @param {string} rule_id
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleTemplate = function(rule_id) {
+ var h = this.templates.rule({
+ builder: this,
+ rule_id: rule_id,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of a rule
+ * @event changer:getRuleTemplate
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @returns {string}
+ */
+ return this.change('getRuleTemplate', h);
+};
+
+/**
+ * Returns rule's filter HTML
+ * @param {Rule} rule
+ * @param {object[]} filters
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleFilterTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleFilterSelect = function(rule, filters) {
+ var h = this.templates.filterSelect({
+ builder: this,
+ rule: rule,
+ filters: filters,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's filter dropdown
+ * @event changer:getRuleFilterSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {Rule} rule
+ * @param {QueryBuilder.Filter[]} filters
+ * @returns {string}
+ */
+ return this.change('getRuleFilterSelect', h, rule, filters);
+};
+
+/**
+ * Returns rule's operator HTML
+ * @param {Rule} rule
+ * @param {object[]} operators
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleOperatorTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleOperatorSelect = function(rule, operators) {
+ var h = this.templates.operatorSelect({
+ builder: this,
+ rule: rule,
+ operators: operators,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's operator dropdown
+ * @event changer:getRuleOperatorSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {Rule} rule
+ * @param {QueryBuilder.Operator[]} operators
+ * @returns {string}
+ */
+ return this.change('getRuleOperatorSelect', h, rule, operators);
+};
+
+/**
+ * Returns the rule's value select HTML
+ * @param {string} name
+ * @param {Rule} rule
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleValueSelect
+ * @private
+ */
+QueryBuilder.prototype.getRuleValueSelect = function(name, rule) {
+ var h = this.templates.ruleValueSelect({
+ builder: this,
+ name: name,
+ rule: rule,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's value dropdown (in case of a "select filter)
+ * @event changer:getRuleValueSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param [string} name
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ return this.change('getRuleValueSelect', h, name, rule);
+};
+
+/**
+ * Returns the rule's value HTML
+ * @param {Rule} rule
+ * @param {int} value_id
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleInput
+ * @private
+ */
+QueryBuilder.prototype.getRuleInput = function(rule, value_id) {
+ var filter = rule.filter;
+ var validation = rule.filter.validation || {};
+ var name = rule.id + '_value_' + value_id;
+ var c = filter.vertical ? ' class=block' : '';
+ var h = '';
+ var placeholder = Array.isArray(filter.placeholder) ? filter.placeholder[value_id] : filter.placeholder;
+
+ if (typeof filter.input == 'function') {
+ h = filter.input.call(this, rule, name);
+ }
+ else {
+ switch (filter.input) {
+ case 'radio':
+ case 'checkbox':
+ Utils.iterateOptions(filter.values, function(key, val) {
+ h += ' ' + val + ' ';
+ });
+ break;
+
+ case 'select':
+ h = this.getRuleValueSelect(name, rule);
+ break;
+
+ case 'textarea':
+ h += '" ; + break + + case number : + h +=' " ; + break + + default + h +=' " ; + } + } + + + * Modifies the raw HTML of the rule s input + * @event changer:getRuleInput + * @memberof QueryBuilder + * @param {string html + * @param {Rule rule + * @param {string name - the name that the input must have + * @returns {string + * + return this.change getRuleInput , h rule name + + + + + * @namespace + * +var Utils="{};" + + + * @member {object + * @memberof QueryBuilder + * @see Utils + * +QueryBuilder.utils="Utils;" + + + * @callback Utils#OptionsIteratee + * @param {string key + * @param {string value + * @param {string [optgroup + * + + + * Iterates over radio/checkbox/selection options it accept four formats + * + * @example + * array of values + * options="['one'," two , three ] + * @example + * simple key-value map + * options="{1:" one , 2 two , 3 three } + * @example + * array of 1-element maps + * options="[{1:" one } {2 two } {3 three } + * @example + * array of elements + * options="[{value:" 1 label one , optgroup group } {value 2 label two } + * + * @param {object|array options + * @param {Utils#OptionsIteratee tpl + * +Utils.iterateOptions="function(options," tpl { + if (options { + if ($.isArray(options { + options.forEach(function(entry { + if ($.isPlainObject(entry { + array of elements + if ( value in entry { + tpl(entry.value entry.label | entry.value entry.optgroup + } + array of one-element maps + else { + $.each(entry function(key val { + tpl(key val + return false break after first entry + } + } + } + array of values + else { + tpl(entry entry + } + } + } + unordered map + else { + $.each(options function(key val { + tpl(key val + } + } + } + + + + * Replaces {0 {1 . in a string + * @param {string str + * @param { args + * @returns {string + * +Utils.fmt="function(str," args { + if (!Array.isArray(args { + args="Array.prototype.slice.call(arguments," 1 + } + + return str.replace(/{([0-9]+)}/g function(m i { + return args[parseInt(i + } + + + + * Throws an Error object with custom name or logs an error + * @param {boolean [doThrow="true]" + * @param {string type + * @param {string message + * @param { args + * +Utils.error="function()" { + var i="0;" + var doThrow="typeof" arguments[i="==" boolean ? arguments[i : true + var type="arguments[i++];" + var message="arguments[i++];" + var args="Array.isArray(arguments[i])" ? arguments[i : Array.prototype.slice.call(arguments i + + if (doThrow { + var err="new" Error(Utils.fmt(message args + err.name="type" + Error ; + err.args="args;" + throw err + } + else { + console.error(type + Error + Utils.fmt(message args + } + + + + * Changes the type of a value to int float or bool + * @param { value + * @param {string type - integer , double , boolean or anything else (passthrough + * @returns { + * +Utils.changeType="function(value," type { + if (value="==" | value="==" undefined { + return undefined + } + + switch (type { + @formatter:off + case integer : + if (typeof value="==" string & !/^-?\d+$/.test(value { + return value + } + return parseInt(value + case double : + if (typeof value="==" string & !/^-?\d+\.?\d*$/.test(value { + return value + } + return parseFloat(value + case boolean : + if (typeof value="==" string & !/^(0|1|true|false){1}$/i.test(value { + return value + } + return value="==" true | value="==" 1 | value.toLowerCase="==" true | value="==" 1 ; + default return value + @formatter:on + } + + + + * Escapes a string like PHP s mysql_real_escape_string does + * @param {string value + * @returns {string + * +Utils.escapeString="function(value)" { + if (typeof value !="string" ) { + return value + } + + return value + .replace(/[\0\n\r\b \ ]/g function(s { + switch (s { + @formatter:off + case \0 : return \\0 ; + case \n : return \\n ; + case \r : return \\r ; + case \b : return \\b ; + default return \ + s + @formatter:off + } + } + uglify compliant + .replace(/\t/g \\t ) + .replace(/\x1a/g \\Z ) + + + + * Escapes a string for use in regex + * @param {string str + * @returns {string + * +Utils.escapeRegExp="function(str)" { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g \ ) + + + + * Escapes a string for use in HTML element id + * @param {string str + * @returns {string + * +Utils.escapeElementId="function(str)" { + Regex based on that suggested by + https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation + - escapes : . [ ] , + - avoids escaping already escaped values + return (str ? str.replace(/(\\)?([:.\[\],])/g + function $0 $1 $2 ) { return $1 ? $0 : \ + $2 } : str + + + + * Sorts objects by grouping them by `key preserving initial order when possible + * @param {object items + * @param {string key + * @returns {object + * +Utils.groupSort="function(items," key { + var optgroups="[];" + var newItems="[];" + + items.forEach(function(item { + var idx + + if (item[key { + idx="optgroups.lastIndexOf(item[key]);" + + if (idx="=" -1 { + idx="optgroups.length;" + } + else { + idx + } + } + else { + idx="optgroups.length;" + } + + optgroups.splice(idx 0 item[key + newItems.splice(idx 0 item + } + + return newItems + + + + * Defines properties on an Node prototype with getter and setter />
+ * Update events are emitted in the setter through root Model (if any).
+ * The object must have a `__` object, non enumerable property to store values.
+ * @param {function} obj
+ * @param {string[]} fields
+ */
+Utils.defineModelProperties = function(obj, fields) {
+ fields.forEach(function(field) {
+ Object.defineProperty(obj.prototype, field, {
+ enumerable: true,
+ get: function() {
+ return this.__[field];
+ },
+ set: function(value) {
+ var previousValue = (this.__[field] !== null && typeof this.__[field] == 'object') ?
+ $.extend({}, this.__[field]) :
+ this.__[field];
+
+ this.__[field] = value;
+
+ if (this.model !== null) {
+ /**
+ * After a value of the model changed
+ * @event model:update
+ * @memberof Model
+ * @param {Node} node
+ * @param {string} field
+ * @param {*} value
+ * @param {*} previousValue
+ */
+ this.model.trigger('update', this, field, value, previousValue);
+ }
+ }
+ });
+ });
+};
+
+
+/**
+ * Main object storing data model and emitting model events
+ * @constructor
+ */
+function Model() {
+ /**
+ * @member {Group}
+ * @readonly
+ */
+ this.root = null;
+
+ /**
+ * Base for event emitting
+ * @member {jQuery}
+ * @readonly
+ * @private
+ */
+ this.$ = $(this);
+}
+
+$.extend(Model.prototype, /** @lends Model.prototype */ {
+ /**
+ * Triggers an event on the model
+ * @param {string} type
+ * @returns {$.Event}
+ */
+ trigger: function(type) {
+ var event = new $.Event(type);
+ this.$.triggerHandler(event, Array.prototype.slice.call(arguments, 1));
+ return event;
+ },
+
+ /**
+ * Attaches an event listener on the model
+ * @param {string} type
+ * @param {function} cb
+ * @returns {Model}
+ */
+ on: function() {
+ this.$.on.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ },
+
+ /**
+ * Removes an event listener from the model
+ * @param {string} type
+ * @param {function} [cb]
+ * @returns {Model}
+ */
+ off: function() {
+ this.$.off.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ },
+
+ /**
+ * Attaches an event listener called once on the model
+ * @param {string} type
+ * @param {function} cb
+ * @returns {Model}
+ */
+ once: function() {
+ this.$.one.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ }
+});
+
+
+/**
+ * Root abstract object
+ * @constructor
+ * @param {Node} [parent]
+ * @param {jQuery} $el
+ */
+var Node = function(parent, $el) {
+ if (!(this instanceof Node)) {
+ return new Node(parent, $el);
+ }
+
+ Object.defineProperty(this, '__', { value: {} });
+
+ $el.data('queryBuilderModel', this);
+
+ /**
+ * @name level
+ * @member {int}
+ * @memberof Node
+ * @instance
+ * @readonly
+ */
+ this.__.level = 1;
+
+ /**
+ * @name error
+ * @member {string}
+ * @memberof Node
+ * @instance
+ */
+ this.__.error = null;
+
+ /**
+ * @name flags
+ * @member {object}
+ * @memberof Node
+ * @instance
+ * @readonly
+ */
+ this.__.flags = {};
+
+ /**
+ * @name data
+ * @member {object}
+ * @memberof Node
+ * @instance
+ */
+ this.__.data = undefined;
+
+ /**
+ * @member {jQuery}
+ * @readonly
+ */
+ this.$el = $el;
+
+ /**
+ * @member {string}
+ * @readonly
+ */
+ this.id = $el[0].id;
+
+ /**
+ * @member {Model}
+ * @readonly
+ */
+ this.model = null;
+
+ /**
+ * @member {Group}
+ * @readonly
+ */
+ this.parent = parent;
+};
+
+Utils.defineModelProperties(Node, ['level', 'error', 'data', 'flags']);
+
+Object.defineProperty(Node.prototype, 'parent', {
+ enumerable: true,
+ get: function() {
+ return this.__.parent;
+ },
+ set: function(value) {
+ this.__.parent = value;
+ this.level = value === null ? 1 : value.level + 1;
+ this.model = value === null ? null : value.model;
+ }
+});
+
+/**
+ * Checks if this Node is the root
+ * @returns {boolean}
+ */
+Node.prototype.isRoot = function() {
+ return (this.level === 1);
+};
+
+/**
+ * Returns the node position inside its parent
+ * @returns {int}
+ */
+Node.prototype.getPos = function() {
+ if (this.isRoot()) {
+ return -1;
+ }
+ else {
+ return this.parent.getNodePos(this);
+ }
+};
+
+/**
+ * Deletes self
+ * @fires Model.model:drop
+ */
+Node.prototype.drop = function() {
+ var model = this.model;
+
+ if (!!this.parent) {
+ this.parent.removeNode(this);
+ }
+
+ this.$el.removeData('queryBuilderModel');
+
+ if (model !== null) {
+ /**
+ * After a node of the model has been removed
+ * @event model:drop
+ * @memberof Model
+ * @param {Node} node
+ */
+ model.trigger('drop', this);
+ }
+};
+
+/**
+ * Moves itself after another Node
+ * @param {Node} target
+ * @fires Model.model:move
+ */
+Node.prototype.moveAfter = function(target) {
+ if (!this.isRoot()) {
+ this.move(target.parent, target.getPos() + 1);
+ }
+};
+
+/**
+ * Moves itself at the beginning of parent or another Group
+ * @param {Group} [target]
+ * @fires Model.model:move
+ */
+Node.prototype.moveAtBegin = function(target) {
+ if (!this.isRoot()) {
+ if (target === undefined) {
+ target = this.parent;
+ }
+
+ this.move(target, 0);
+ }
+};
+
+/**
+ * Moves itself at the end of parent or another Group
+ * @param {Group} [target]
+ * @fires Model.model:move
+ */
+Node.prototype.moveAtEnd = function(target) {
+ if (!this.isRoot()) {
+ if (target === undefined) {
+ target = this.parent;
+ }
+
+ this.move(target, target.length() === 0 ? 0 : target.length() - 1);
+ }
+};
+
+/**
+ * Moves itself at specific position of Group
+ * @param {Group} target
+ * @param {int} index
+ * @fires Model.model:move
+ */
+Node.prototype.move = function(target, index) {
+ if (!this.isRoot()) {
+ if (typeof target === 'number') {
+ index = target;
+ target = this.parent;
+ }
+
+ this.parent.removeNode(this);
+ target.insertNode(this, index, false);
+
+ if (this.model !== null) {
+ /**
+ * After a node of the model has been moved
+ * @event model:move
+ * @memberof Model
+ * @param {Node} node
+ * @param {Node} target
+ * @param {int} index
+ */
+ this.model.trigger('move', this, target, index);
+ }
+ }
+};
+
+
+/**
+ * Group object
+ * @constructor
+ * @extends Node
+ * @param {Group} [parent]
+ * @param {jQuery} $el
+ */
+var Group = function(parent, $el) {
+ if (!(this instanceof Group)) {
+ return new Group(parent, $el);
+ }
+
+ Node.call(this, parent, $el);
+
+ /**
+ * @member {object[]}
+ * @readonly
+ */
+ this.rules = [];
+
+ /**
+ * @name condition
+ * @member {string}
+ * @memberof Group
+ * @instance
+ */
+ this.__.condition = null;
+};
+
+Group.prototype = Object.create(Node.prototype);
+Group.prototype.constructor = Group;
+
+Utils.defineModelProperties(Group, ['condition']);
+
+/**
+ * Removes group's content
+ */
+Group.prototype.empty = function() {
+ this.each('reverse', function(rule) {
+ rule.drop();
+ }, function(group) {
+ group.drop();
+ });
+};
+
+/**
+ * Deletes self
+ */
+Group.prototype.drop = function() {
+ this.empty();
+ Node.prototype.drop.call(this);
+};
+
+/**
+ * Returns the number of children
+ * @returns {int}
+ */
+Group.prototype.length = function() {
+ return this.rules.length;
+};
+
+/**
+ * Adds a Node at specified index
+ * @param {Node} node
+ * @param {int} [index=end]
+ * @param {boolean} [trigger=false] - fire 'add' event
+ * @returns {Node} the inserted node
+ * @fires Model.model:add
+ */
+Group.prototype.insertNode = function(node, index, trigger) {
+ if (index === undefined) {
+ index = this.length();
+ }
+
+ this.rules.splice(index, 0, node);
+ node.parent = this;
+
+ if (trigger && this.model !== null) {
+ /**
+ * After a node of the model has been added
+ * @event model:add
+ * @memberof Model
+ * @param {Node} parent
+ * @param {Node} node
+ * @param {int} index
+ */
+ this.model.trigger('add', this, node, index);
+ }
+
+ return node;
+};
+
+/**
+ * Adds a new Group at specified index
+ * @param {jQuery} $el
+ * @param {int} [index=end]
+ * @returns {Group}
+ * @fires Model.model:add
+ */
+Group.prototype.addGroup = function($el, index) {
+ return this.insertNode(new Group(this, $el), index, true);
+};
+
+/**
+ * Adds a new Rule at specified index
+ * @param {jQuery} $el
+ * @param {int} [index=end]
+ * @returns {Rule}
+ * @fires Model.model:add
+ */
+Group.prototype.addRule = function($el, index) {
+ return this.insertNode(new Rule(this, $el), index, true);
+};
+
+/**
+ * Deletes a specific Node
+ * @param {Node} node
+ */
+Group.prototype.removeNode = function(node) {
+ var index = this.getNodePos(node);
+ if (index !== -1) {
+ node.parent = null;
+ this.rules.splice(index, 1);
+ }
+};
+
+/**
+ * Returns the position of a child Node
+ * @param {Node} node
+ * @returns {int}
+ */
+Group.prototype.getNodePos = function(node) {
+ return this.rules.indexOf(node);
+};
+
+/**
+ * @callback Model#GroupIteratee
+ * @param {Node} node
+ * @returns {boolean} stop the iteration
+ */
+
+/**
+ * Iterate over all Nodes
+ * @param {boolean} [reverse=false] - iterate in reverse order, required if you delete nodes
+ * @param {Model#GroupIteratee} cbRule - callback for Rules (can be `null` but not omitted)
+ * @param {Model#GroupIteratee} [cbGroup] - callback for Groups
+ * @param {object} [context] - context for callbacks
+ * @returns {boolean} if the iteration has been stopped by a callback
+ */
+Group.prototype.each = function(reverse, cbRule, cbGroup, context) {
+ if (typeof reverse !== 'boolean' && typeof reverse !== 'string') {
+ context = cbGroup;
+ cbGroup = cbRule;
+ cbRule = reverse;
+ reverse = false;
+ }
+ context = context === undefined ? null : context;
+
+ var i = reverse ? this.rules.length - 1 : 0;
+ var l = reverse ? 0 : this.rules.length - 1;
+ var c = reverse ? -1 : 1;
+ var next = function() {
+ return reverse ? i >= l : i <= l;
+ };
+ var stop = false;
+
+ for (; next(); i += c) {
+ if (this.rules[i] instanceof Group) {
+ if (!!cbGroup) {
+ stop = cbGroup.call(context, this.rules[i]) === false;
+ }
+ }
+ else if (!!cbRule) {
+ stop = cbRule.call(context, this.rules[i]) === false;
+ }
+
+ if (stop) {
+ break;
+ }
+ }
+
+ return !stop;
+};
+
+/**
+ * Checks if the group contains a particular Node
+ * @param {Node} node
+ * @param {boolean} [recursive=false]
+ * @returns {boolean}
+ */
+Group.prototype.contains = function(node, recursive) {
+ if (this.getNodePos(node) !== -1) {
+ return true;
+ }
+ else if (!recursive) {
+ return false;
+ }
+ else {
+ // the loop will return with false as soon as the Node is found
+ return !this.each(function() {
+ return true;
+ }, function(group) {
+ return !group.contains(node, true);
+ });
+ }
+};
+
+
+/**
+ * Rule object
+ * @constructor
+ * @extends Node
+ * @param {Group} parent
+ * @param {jQuery} $el
+ */
+var Rule = function(parent, $el) {
+ if (!(this instanceof Rule)) {
+ return new Rule(parent, $el);
+ }
+
+ Node.call(this, parent, $el);
+
+ this._updating_value = false;
+ this._updating_input = false;
+
+ /**
+ * @name filter
+ * @member {QueryBuilder.Filter}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.filter = null;
+
+ /**
+ * @name operator
+ * @member {QueryBuilder.Operator}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.operator = null;
+
+ /**
+ * @name value
+ * @member {*}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.value = undefined;
+};
+
+Rule.prototype = Object.create(Node.prototype);
+Rule.prototype.constructor = Rule;
+
+Utils.defineModelProperties(Rule, ['filter', 'operator', 'value']);
+
+/**
+ * Checks if this Node is the root
+ * @returns {boolean} always false
+ */
+Rule.prototype.isRoot = function() {
+ return false;
+};
+
+
+/**
+ * @member {function}
+ * @memberof QueryBuilder
+ * @see Group
+ */
+QueryBuilder.Group = Group;
+
+/**
+ * @member {function}
+ * @memberof QueryBuilder
+ * @see Rule
+ */
+QueryBuilder.Rule = Rule;
+
+
+/**
+ * The {@link http://learn.jquery.com/plugins/|jQuery Plugins} namespace
+ * @external "jQuery.fn"
+ */
+
+/**
+ * Instanciates or accesses the {@link QueryBuilder} on an element
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @param {*} option - initial configuration or method name
+ * @param {...*} args - method arguments
+ *
+ * @example
+ * $('#builder').queryBuilder({ /** configuration object *\/ });
+ * @example
+ * $('#builder').queryBuilder('methodName', methodParam1, methodParam2);
+ */
+$.fn.queryBuilder = function(option) {
+ if (this.length === 0) {
+ Utils.error('Config', 'No target defined');
+ }
+ if (this.length > 1) {
+ Utils.error('Config', 'Unable to initialize on multiple target');
+ }
+
+ var data = this.data('queryBuilder');
+ var options = (typeof option == 'object' && option) || {};
+
+ if (!data && option == 'destroy') {
+ return this;
+ }
+ if (!data) {
+ var builder = new QueryBuilder(this, options);
+ this.data('queryBuilder', builder);
+ builder.init(options.rules);
+ }
+ if (typeof option == 'string') {
+ return data[option].apply(data, Array.prototype.slice.call(arguments, 1));
+ }
+
+ return this;
+};
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder
+ */
+$.fn.queryBuilder.constructor = QueryBuilder;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.defaults
+ */
+$.fn.queryBuilder.defaults = QueryBuilder.defaults;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.defaults
+ */
+$.fn.queryBuilder.extend = QueryBuilder.extend;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.define
+ */
+$.fn.queryBuilder.define = QueryBuilder.define;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.regional
+ */
+$.fn.queryBuilder.regional = QueryBuilder.regional;
+
+
+/**
+ * @class BtCheckbox
+ * @memberof module:plugins
+ * @description Applies Awesome Bootstrap Checkbox for checkbox and radio inputs.
+ * @param {object} [options]
+ * @param {string} [options.font='glyphicons']
+ * @param {string} [options.color='default']
+ */
+QueryBuilder.define('bt-checkbox', function(options) {
+ if (options.font == 'glyphicons') {
+ this.$el.addClass('bt-checkbox-glyphicons');
+ }
+
+ this.on('getRuleInput.filter', function(h, rule, name) {
+ var filter = rule.filter;
+
+ if ((filter.input === 'radio' || filter.input === 'checkbox') && !filter.plugin) {
+ h.value = '';
+
+ if (!filter.colors) {
+ filter.colors = {};
+ }
+ if (filter.color) {
+ filter.colors._def_ = filter.color;
+ }
+
+ var style = filter.vertical ? ' style="display:block"' : '';
+ var i = 0;
+
+ Utils.iterateOptions(filter.values, function(key, val) {
+ var color = filter.colors[key] || filter.colors._def_ || options.color;
+ var id = name + '_' + (i++);
+
+ h.value+= '\
+ \
+ \
+ ' + val + ' \
+
';
+ });
+ }
+ });
+}, {
+ font: 'glyphicons',
+ color: 'default'
+});
+
+
+/**
+ * @class BtSelectpicker
+ * @memberof module:plugins
+ * @descriptioon Applies Bootstrap Select on filters and operators combo-boxes.
+ * @param {object} [options]
+ * @param {string} [options.container='body']
+ * @param {string} [options.style='btn-inverse btn-xs']
+ * @param {int|string} [options.width='auto']
+ * @param {boolean} [options.showIcon=false]
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('bt-selectpicker', function(options) {
+ if (!$.fn.selectpicker || !$.fn.selectpicker.Constructor) {
+ Utils.error('MissingLibrary', 'Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select');
+ }
+
+ var Selectors = QueryBuilder.selectors;
+
+ // init selectpicker
+ this.on('afterCreateRuleFilters', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).removeClass('form-control').selectpicker(options);
+ });
+
+ this.on('afterCreateRuleOperators', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).removeClass('form-control').selectpicker(options);
+ });
+
+ // update selectpicker on change
+ this.on('afterUpdateRuleFilter', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).selectpicker('render');
+ });
+
+ this.on('afterUpdateRuleOperator', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).selectpicker('render');
+ });
+
+ this.on('beforeDeleteRule', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).selectpicker('destroy');
+ rule.$el.find(Selectors.rule_operator).selectpicker('destroy');
+ });
+}, {
+ container: 'body',
+ style: 'btn-inverse btn-xs',
+ width: 'auto',
+ showIcon: false
+});
+
+
+/**
+ * @class BtTooltipErrors
+ * @memberof module:plugins
+ * @description Applies Bootstrap Tooltips on validation error messages.
+ * @param {object} [options]
+ * @param {string} [options.placement='right']
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('bt-tooltip-errors', function(options) {
+ if (!$.fn.tooltip || !$.fn.tooltip.Constructor || !$.fn.tooltip.Constructor.prototype.fixTitle) {
+ Utils.error('MissingLibrary', 'Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com');
+ }
+
+ var self = this;
+
+ // add BT Tooltip data
+ this.on('getRuleTemplate.filter getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.error_container).attr('data-toggle', 'tooltip');
+ h.value = $h.prop('outerHTML');
+ });
+
+ // init/refresh tooltip when title changes
+ this.model.on('update', function(e, node, field) {
+ if (field == 'error' && self.settings.display_errors) {
+ node.$el.find(QueryBuilder.selectors.error_container).eq(0)
+ .tooltip(options)
+ .tooltip('hide')
+ .tooltip('fixTitle');
+ }
+ });
+}, {
+ placement: 'right'
+});
+
+
+/**
+ * @class ChangeFilters
+ * @memberof module:plugins
+ * @description Allows to change available filters after plugin initialization.
+ */
+
+QueryBuilder.extend(/** @lends module:plugins.ChangeFilters.prototype */ {
+ /**
+ * Change the filters of the builder
+ * @param {boolean} [deleteOrphans=false] - delete rules using old filters
+ * @param {QueryBuilder[]} filters
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ setFilters: function(deleteOrphans, filters) {
+ var self = this;
+
+ if (filters === undefined) {
+ filters = deleteOrphans;
+ deleteOrphans = false;
+ }
+
+ filters = this.checkFilters(filters);
+
+ /**
+ * Modifies the filters before {@link module:plugins.ChangeFilters.setFilters} method
+ * @event changer:setFilters
+ * @memberof module:plugins.ChangeFilters
+ * @param {QueryBuilder.Filter[]} filters
+ * @returns {QueryBuilder.Filter[]}
+ */
+ filters = this.change('setFilters', filters);
+
+ var filtersIds = filters.map(function(filter) {
+ return filter.id;
+ });
+
+ // check for orphans
+ if (!deleteOrphans) {
+ (function checkOrphans(node) {
+ node.each(
+ function(rule) {
+ if (rule.filter && filtersIds.indexOf(rule.filter.id) === -1) {
+ Utils.error('ChangeFilter', 'A rule is using filter "{0}"', rule.filter.id);
+ }
+ },
+ checkOrphans
+ );
+ }(this.model.root));
+ }
+
+ // replace filters
+ this.filters = filters;
+
+ // apply on existing DOM
+ (function updateBuilder(node) {
+ node.each(true,
+ function(rule) {
+ if (rule.filter && filtersIds.indexOf(rule.filter.id) === -1) {
+ rule.drop();
+
+ self.trigger('rulesChanged');
+ }
+ else {
+ self.createRuleFilters(rule);
+
+ rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
+ self.trigger('afterUpdateRuleFilter', rule);
+ }
+ },
+ updateBuilder
+ );
+ }(this.model.root));
+
+ // update plugins
+ if (this.settings.plugins) {
+ if (this.settings.plugins['unique-filter']) {
+ this.updateDisabledFilters();
+ }
+ if (this.settings.plugins['bt-selectpicker']) {
+ this.$el.find(QueryBuilder.selectors.rule_filter).selectpicker('render');
+ }
+ }
+
+ // reset the default_filter if does not exist anymore
+ if (this.settings.default_filter) {
+ try {
+ this.getFilterById(this.settings.default_filter);
+ }
+ catch (e) {
+ this.settings.default_filter = null;
+ }
+ }
+
+ /**
+ * After {@link module:plugins.ChangeFilters.setFilters} method
+ * @event afterSetFilters
+ * @memberof module:plugins.ChangeFilters
+ * @param {QueryBuilder.Filter[]} filters
+ */
+ this.trigger('afterSetFilters', filters);
+ },
+
+ /**
+ * Adds a new filter to the builder
+ * @param {QueryBuilder.Filter|Filter[]} newFilters
+ * @param {int|string} [position=#end] - index or '#start' or '#end'
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ addFilter: function(newFilters, position) {
+ if (position === undefined || position == '#end') {
+ position = this.filters.length;
+ }
+ else if (position == '#start') {
+ position = 0;
+ }
+
+ if (!$.isArray(newFilters)) {
+ newFilters = [newFilters];
+ }
+
+ var filters = $.extend(true, [], this.filters);
+
+ // numeric position
+ if (parseInt(position) == position) {
+ Array.prototype.splice.apply(filters, [position, 0].concat(newFilters));
+ }
+ else {
+ // after filter by its id
+ if (this.filters.some(function(filter, index) {
+ if (filter.id == position) {
+ position = index + 1;
+ return true;
+ }
+ })
+ ) {
+ Array.prototype.splice.apply(filters, [position, 0].concat(newFilters));
+ }
+ // defaults to end of list
+ else {
+ Array.prototype.push.apply(filters, newFilters);
+ }
+ }
+
+ this.setFilters(filters);
+ },
+
+ /**
+ * Removes a filter from the builder
+ * @param {string|string[]} filterIds
+ * @param {boolean} [deleteOrphans=false] delete rules using old filters
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ removeFilter: function(filterIds, deleteOrphans) {
+ var filters = $.extend(true, [], this.filters);
+ if (typeof filterIds === 'string') {
+ filterIds = [filterIds];
+ }
+
+ filters = filters.filter(function(filter) {
+ return filterIds.indexOf(filter.id) === -1;
+ });
+
+ this.setFilters(deleteOrphans, filters);
+ }
+});
+
+
+/**
+ * @class ChosenSelectpicker
+ * @memberof module:plugins
+ * @descriptioon Applies chosen-js Select on filters and operators combo-boxes.
+ * @param {object} [options] Supports all the options for chosen
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('chosen-selectpicker', function(options) {
+
+ if (!$.fn.chosen) {
+ Utils.error('MissingLibrary', 'chosen is required to use "chosen-selectpicker" plugin. Get it here: https://github.com/harvesthq/chosen');
+ }
+
+ if (this.settings.plugins['bt-selectpicker']) {
+ Utils.error('Conflict', 'bt-selectpicker is already selected as the dropdown plugin. Please remove chosen-selectpicker from the plugin list');
+ }
+
+ var Selectors = QueryBuilder.selectors;
+
+ // init selectpicker
+ this.on('afterCreateRuleFilters', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).removeClass('form-control').chosen(options);
+ });
+
+ this.on('afterCreateRuleOperators', function(e, rule) {
+ if (e.builder.getOperators(rule.filter).length > 1) {
+ rule.$el.find(Selectors.rule_operator).removeClass('form-control').chosen(options);
+ }
+ });
+
+ // update selectpicker on change
+ this.on('afterUpdateRuleFilter', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).trigger('chosen:updated');
+ });
+
+ this.on('afterUpdateRuleOperator', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).trigger('chosen:updated');
+ });
+
+ this.on('beforeDeleteRule', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).chosen('destroy');
+ rule.$el.find(Selectors.rule_operator).chosen('destroy');
+ });
+});
+
+
+/**
+ * @class FilterDescription
+ * @memberof module:plugins
+ * @description Provides three ways to display a description about a filter: inline, Bootsrap Popover or Bootbox.
+ * @param {object} [options]
+ * @param {string} [options.icon='glyphicon glyphicon-info-sign']
+ * @param {string} [options.mode='popover'] - inline, popover or bootbox
+ * @throws ConfigError
+ */
+QueryBuilder.define('filter-description', function(options) {
+ // INLINE
+ if (options.mode === 'inline') {
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $p = rule.$el.find('p.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $p.hide();
+ }
+ else {
+ if ($p.length === 0) {
+ $p = $('
');
+ $p.appendTo(rule.$el);
+ }
+ else {
+ $p.css('display', '');
+ }
+
+ $p.html(' ' + description);
+ }
+ });
+ }
+ // POPOVER
+ else if (options.mode === 'popover') {
+ if (!$.fn.popover || !$.fn.popover.Constructor || !$.fn.popover.Constructor.prototype.fixTitle) {
+ Utils.error('MissingLibrary', 'Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com');
+ }
+
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $b = rule.$el.find('button.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $b.hide();
+
+ if ($b.data('bs.popover')) {
+ $b.popover('hide');
+ }
+ }
+ else {
+ if ($b.length === 0) {
+ $b = $(' ');
+ $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions));
+
+ $b.popover({
+ placement: 'left',
+ container: 'body',
+ html: true
+ });
+
+ $b.on('mouseout', function() {
+ $b.popover('hide');
+ });
+ }
+ else {
+ $b.css('display', '');
+ }
+
+ $b.data('bs.popover').options.content = description;
+
+ if ($b.attr('aria-describedby')) {
+ $b.popover('show');
+ }
+ }
+ });
+ }
+ // BOOTBOX
+ else if (options.mode === 'bootbox') {
+ if (!('bootbox' in window)) {
+ Utils.error('MissingLibrary', 'Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com');
+ }
+
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $b = rule.$el.find('button.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $b.hide();
+ }
+ else {
+ if ($b.length === 0) {
+ $b = $(' ');
+ $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions));
+
+ $b.on('click', function() {
+ bootbox.alert($b.data('description'));
+ });
+ }
+ else {
+ $b.css('display', '');
+ }
+
+ $b.data('description', description);
+ }
+ });
+ }
+}, {
+ icon: 'glyphicon glyphicon-info-sign',
+ mode: 'popover'
+});
+
+QueryBuilder.extend(/** @lends module:plugins.FilterDescription.prototype */ {
+ /**
+ * Returns the description of a filter for a particular rule (if present)
+ * @param {object} filter
+ * @param {Rule} [rule]
+ * @returns {string}
+ * @private
+ */
+ getFilterDescription: function(filter, rule) {
+ if (!filter) {
+ return undefined;
+ }
+ else if (typeof filter.description == 'function') {
+ return filter.description.call(this, rule);
+ }
+ else {
+ return filter.description;
+ }
+ }
+});
+
+
+/**
+ * @class Invert
+ * @memberof module:plugins
+ * @description Allows to invert a rule operator, a group condition or the entire builder.
+ * @param {object} [options]
+ * @param {string} [options.icon='glyphicon glyphicon-random']
+ * @param {boolean} [options.recursive=true]
+ * @param {boolean} [options.invert_rules=true]
+ * @param {boolean} [options.display_rules_button=false]
+ * @param {boolean} [options.silent_fail=false]
+ */
+QueryBuilder.define('invert', function(options) {
+ var self = this;
+ var Selectors = QueryBuilder.selectors;
+
+ // Bind events
+ this.on('afterInit', function() {
+ self.$el.on('click.queryBuilder', '[data-invert=group]', function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.invert(self.getModel($group), options);
+ });
+
+ if (options.display_rules_button && options.invert_rules) {
+ self.$el.on('click.queryBuilder', '[data-invert=rule]', function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.invert(self.getModel($rule), options);
+ });
+ }
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(Selectors.condition_container).after(
+ '' +
+ ' ' + self.translate('invert') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+
+ if (options.display_rules_button && options.invert_rules) {
+ this.on('getRuleTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(Selectors.rule_actions).prepend(
+ '' +
+ ' ' + self.translate('invert') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+ }
+ }
+}, {
+ icon: 'glyphicon glyphicon-random',
+ recursive: true,
+ invert_rules: true,
+ display_rules_button: false,
+ silent_fail: false,
+ disable_template: false
+});
+
+QueryBuilder.defaults({
+ operatorOpposites: {
+ 'equal': 'not_equal',
+ 'not_equal': 'equal',
+ 'in': 'not_in',
+ 'not_in': 'in',
+ 'less': 'greater_or_equal',
+ 'less_or_equal': 'greater',
+ 'greater': 'less_or_equal',
+ 'greater_or_equal': 'less',
+ 'between': 'not_between',
+ 'not_between': 'between',
+ 'begins_with': 'not_begins_with',
+ 'not_begins_with': 'begins_with',
+ 'contains': 'not_contains',
+ 'not_contains': 'contains',
+ 'ends_with': 'not_ends_with',
+ 'not_ends_with': 'ends_with',
+ 'is_empty': 'is_not_empty',
+ 'is_not_empty': 'is_empty',
+ 'is_null': 'is_not_null',
+ 'is_not_null': 'is_null'
+ },
+
+ conditionOpposites: {
+ 'AND': 'OR',
+ 'OR': 'AND'
+ }
+});
+
+QueryBuilder.extend(/** @lends module:plugins.Invert.prototype */ {
+ /**
+ * Invert a Group, a Rule or the whole builder
+ * @param {Node} [node]
+ * @param {object} [options] {@link module:plugins.Invert}
+ * @fires module:plugins.Invert.afterInvert
+ * @throws InvertConditionError, InvertOperatorError
+ */
+ invert: function(node, options) {
+ if (!(node instanceof Node)) {
+ if (!this.model.root) return;
+ options = node;
+ node = this.model.root;
+ }
+
+ if (typeof options != 'object') options = {};
+ if (options.recursive === undefined) options.recursive = true;
+ if (options.invert_rules === undefined) options.invert_rules = true;
+ if (options.silent_fail === undefined) options.silent_fail = false;
+ if (options.trigger === undefined) options.trigger = true;
+
+ if (node instanceof Group) {
+ // invert group condition
+ if (this.settings.conditionOpposites[node.condition]) {
+ node.condition = this.settings.conditionOpposites[node.condition];
+ }
+ else if (!options.silent_fail) {
+ Utils.error('InvertCondition', 'Unknown inverse of condition "{0}"', node.condition);
+ }
+
+ // recursive call
+ if (options.recursive) {
+ var tempOpts = $.extend({}, options, { trigger: false });
+ node.each(function(rule) {
+ if (options.invert_rules) {
+ this.invert(rule, tempOpts);
+ }
+ }, function(group) {
+ this.invert(group, tempOpts);
+ }, this);
+ }
+ }
+ else if (node instanceof Rule) {
+ if (node.operator && !node.filter.no_invert) {
+ // invert rule operator
+ if (this.settings.operatorOpposites[node.operator.type]) {
+ var invert = this.settings.operatorOpposites[node.operator.type];
+ // check if the invert is "authorized"
+ if (!node.filter.operators || node.filter.operators.indexOf(invert) != -1) {
+ node.operator = this.getOperatorByType(invert);
+ }
+ }
+ else if (!options.silent_fail) {
+ Utils.error('InvertOperator', 'Unknown inverse of operator "{0}"', node.operator.type);
+ }
+ }
+ }
+
+ if (options.trigger) {
+ /**
+ * After {@link module:plugins.Invert.invert} method
+ * @event afterInvert
+ * @memberof module:plugins.Invert
+ * @param {Node} node - the main group or rule that has been modified
+ * @param {object} options
+ */
+ this.trigger('afterInvert', node, options);
+
+ this.trigger('rulesChanged');
+ }
+ }
+});
+
+
+/**
+ * @class MongoDbSupport
+ * @memberof module:plugins
+ * @description Allows to export rules as a MongoDB find object as well as populating the builder from a MongoDB object.
+ */
+
+QueryBuilder.defaults({
+ mongoOperators: {
+ // @formatter:off
+ equal: function(v) { return v[0]; },
+ not_equal: function(v) { return { '$ne': v[0] }; },
+ in: function(v) { return { '$in': v }; },
+ not_in: function(v) { return { '$nin': v }; },
+ less: function(v) { return { '$lt': v[0] }; },
+ less_or_equal: function(v) { return { '$lte': v[0] }; },
+ greater: function(v) { return { '$gt': v[0] }; },
+ greater_or_equal: function(v) { return { '$gte': v[0] }; },
+ between: function(v) { return { '$gte': v[0], '$lte': v[1] }; },
+ not_between: function(v) { return { '$lt': v[0], '$gt': v[1] }; },
+ begins_with: function(v) { return { '$regex': '^' + Utils.escapeRegExp(v[0]) }; },
+ not_begins_with: function(v) { return { '$regex': '^(?!' + Utils.escapeRegExp(v[0]) + ')' }; },
+ contains: function(v) { return { '$regex': Utils.escapeRegExp(v[0]) }; },
+ not_contains: function(v) { return { '$regex': '^((?!' + Utils.escapeRegExp(v[0]) + ').)*$', '$options': 's' }; },
+ ends_with: function(v) { return { '$regex': Utils.escapeRegExp(v[0]) + '$' }; },
+ not_ends_with: function(v) { return { '$regex': '(? 0) {
+ parts.push(parse(rule));
+ }
+ else {
+ var mdb = self.settings.mongoOperators[rule.operator];
+ var ope = self.getOperatorByType(rule.operator);
+
+ if (mdb === undefined) {
+ Utils.error('UndefinedMongoOperator', 'Unknown MongoDB operation for operator "{0}"', rule.operator);
+ }
+
+ if (ope.nb_inputs !== 0) {
+ if (!(rule.value instanceof Array)) {
+ rule.value = [rule.value];
+ }
+ }
+
+ /**
+ * Modifies the MongoDB field used by a rule
+ * @event changer:getMongoDBField
+ * @memberof module:plugins.MongoDbSupport
+ * @param {string} field
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ var field = self.change('getMongoDBField', rule.field, rule);
+
+ var ruleExpression = {};
+ ruleExpression[field] = mdb.call(self, rule.value);
+
+ /**
+ * Modifies the MongoDB expression generated for a rul
+ * @event changer:ruleToMongo
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @param {Rule} rule
+ * @param {*} value
+ * @param {function} valueWrapper - function that takes the value and adds the operator
+ * @returns {object}
+ */
+ parts.push(self.change('ruleToMongo', ruleExpression, rule, rule.value, mdb));
+ }
+ });
+
+ var groupExpression = {};
+ groupExpression['$' + group.condition.toLowerCase()] = parts;
+
+ /**
+ * Modifies the MongoDB expression generated for a group
+ * @event changer:groupToMongo
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @param {Group} group
+ * @returns {object}
+ */
+ return self.change('groupToMongo', groupExpression, group);
+ }(data));
+ },
+
+ /**
+ * Converts a MongoDB query to rules
+ * @param {object} query
+ * @returns {object}
+ * @fires module:plugins.MongoDbSupport.changer:parseMongoNode
+ * @fires module:plugins.MongoDbSupport.changer:getMongoDBFieldID
+ * @fires module:plugins.MongoDbSupport.changer:mongoToRule
+ * @fires module:plugins.MongoDbSupport.changer:mongoToGroup
+ * @throws MongoParseError, UndefinedMongoConditionError, UndefinedMongoOperatorError
+ */
+ getRulesFromMongo: function(query) {
+ if (query === undefined || query === null) {
+ return null;
+ }
+
+ var self = this;
+
+ /**
+ * Custom parsing of a MongoDB expression, you can return a sub-part of the expression, or a well formed group or rule JSON
+ * @event changer:parseMongoNode
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @returns {object} expression, rule or group
+ */
+ query = self.change('parseMongoNode', query);
+
+ // a plugin returned a group
+ if ('rules' in query && 'condition' in query) {
+ return query;
+ }
+
+ // a plugin returned a rule
+ if ('id' in query && 'operator' in query && 'value' in query) {
+ return {
+ condition: this.settings.default_condition,
+ rules: [query]
+ };
+ }
+
+ var key = self.getMongoCondition(query);
+ if (!key) {
+ Utils.error('MongoParse', 'Invalid MongoDB query format');
+ }
+
+ return (function parse(data, topKey) {
+ var rules = data[topKey];
+ var parts = [];
+
+ rules.forEach(function(data) {
+ // allow plugins to manually parse or handle special cases
+ data = self.change('parseMongoNode', data);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ parts.push(data);
+ return;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ parts.push(data);
+ return;
+ }
+
+ var key = self.getMongoCondition(data);
+ if (key) {
+ parts.push(parse(data, key));
+ }
+ else {
+ var field = Object.keys(data)[0];
+ var value = data[field];
+
+ var operator = self.getMongoOperator(value);
+ if (operator === undefined) {
+ Utils.error('MongoParse', 'Invalid MongoDB query format');
+ }
+
+ var mdbrl = self.settings.mongoRuleOperators[operator];
+ if (mdbrl === undefined) {
+ Utils.error('UndefinedMongoOperator', 'JSON Rule operation unknown for operator "{0}"', operator);
+ }
+
+ var opVal = mdbrl.call(self, value);
+
+ var id = self.getMongoDBFieldID(field, value);
+
+ /**
+ * Modifies the rule generated from the MongoDB expression
+ * @event changer:mongoToRule
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} rule
+ * @param {object} expression
+ * @returns {object}
+ */
+ var rule = self.change('mongoToRule', {
+ id: id,
+ field: field,
+ operator: opVal.op,
+ value: opVal.val
+ }, data);
+
+ parts.push(rule);
+ }
+ });
+
+ /**
+ * Modifies the group generated from the MongoDB expression
+ * @event changer:mongoToGroup
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} group
+ * @param {object} expression
+ * @returns {object}
+ */
+ return self.change('mongoToGroup', {
+ condition: topKey.replace('$', '').toUpperCase(),
+ rules: parts
+ }, data);
+ }(query, key));
+ },
+
+ /**
+ * Sets rules a from MongoDB query
+ * @see module:plugins.MongoDbSupport.getRulesFromMongo
+ */
+ setRulesFromMongo: function(query) {
+ this.setRules(this.getRulesFromMongo(query));
+ },
+
+ /**
+ * Returns a filter identifier from the MongoDB field.
+ * Automatically use the only one filter with a matching field, fires a changer otherwise.
+ * @param {string} field
+ * @param {*} value
+ * @fires module:plugins.MongoDbSupport:changer:getMongoDBFieldID
+ * @returns {string}
+ * @private
+ */
+ getMongoDBFieldID: function(field, value) {
+ var matchingFilters = this.filters.filter(function(filter) {
+ return filter.field === field;
+ });
+
+ var id;
+ if (matchingFilters.length === 1) {
+ id = matchingFilters[0].id;
+ }
+ else {
+ /**
+ * Returns a filter identifier from the MongoDB field
+ * @event changer:getMongoDBFieldID
+ * @memberof module:plugins.MongoDbSupport
+ * @param {string} field
+ * @param {*} value
+ * @returns {string}
+ */
+ id = this.change('getMongoDBFieldID', field, value);
+ }
+
+ return id;
+ },
+
+ /**
+ * Finds which operator is used in a MongoDB sub-object
+ * @param {*} data
+ * @returns {string|undefined}
+ * @private
+ */
+ getMongoOperator: function(data) {
+ if (data !== null && typeof data === 'object') {
+ if (data.$gte !== undefined && data.$lte !== undefined) {
+ return 'between';
+ }
+ if (data.$lt !== undefined && data.$gt !== undefined) {
+ return 'not_between';
+ }
+
+ var knownKeys = Object.keys(data).filter(function(key) {
+ return !!this.settings.mongoRuleOperators[key];
+ }.bind(this));
+
+ if (knownKeys.length === 1) {
+ return knownKeys[0];
+ }
+ }
+ else {
+ return '$eq';
+ }
+ },
+
+
+ /**
+ * Returns the key corresponding to "$or" or "$and"
+ * @param {object} data
+ * @returns {string|undefined}
+ * @private
+ */
+ getMongoCondition: function(data) {
+ var keys = Object.keys(data);
+
+ for (var i = 0, l = keys.length; i < l; i++) {
+ if (keys[i].toLowerCase() === '$or' || keys[i].toLowerCase() === '$and') {
+ return keys[i];
+ }
+ }
+ }
+});
+
+
+/**
+ * @class NotGroup
+ * @memberof module:plugins
+ * @description Adds a "Not" checkbox in front of group conditions.
+ * @param {object} [options]
+ * @param {string} [options.icon_checked='glyphicon glyphicon-checked']
+ * @param {string} [options.icon_unchecked='glyphicon glyphicon-unchecked']
+ */
+QueryBuilder.define('not-group', function(options) {
+ var self = this;
+
+ // Bind events
+ this.on('afterInit', function() {
+ self.$el.on('click.queryBuilder', '[data-not=group]', function() {
+ var $group = $(this).closest(QueryBuilder.selectors.group_container);
+ var group = self.getModel($group);
+ group.not = !group.not;
+ });
+
+ self.model.on('update', function(e, node, field) {
+ if (node instanceof Group && field === 'not') {
+ self.updateGroupNot(node);
+ }
+ });
+ });
+
+ // Init "not" property
+ this.on('afterAddGroup', function(e, group) {
+ group.__.not = false;
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.condition_container).prepend(
+ '' +
+ ' ' + self.translate('NOT') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+ }
+
+ // Export "not" to JSON
+ this.on('groupToJson.filter', function(e, group) {
+ e.value.not = group.not;
+ });
+
+ // Read "not" from JSON
+ this.on('jsonToGroup.filter', function(e, json) {
+ e.value.not = !!json.not;
+ });
+
+ // Export "not" to SQL
+ this.on('groupToSQL.filter', function(e, group) {
+ if (group.not) {
+ e.value = 'NOT ( ' + e.value + ' )';
+ }
+ });
+
+ // Parse "NOT" function from sqlparser
+ this.on('parseSQLNode.filter', function(e) {
+ if (e.value.name && e.value.name.toUpperCase() == 'NOT') {
+ e.value = e.value.arguments.value[0];
+
+ // if the there is no sub-group, create one
+ if (['AND', 'OR'].indexOf(e.value.operation.toUpperCase()) === -1) {
+ e.value = new SQLParser.nodes.Op(
+ self.settings.default_condition,
+ e.value,
+ null
+ );
+ }
+
+ e.value.not = true;
+ }
+ });
+
+ // Request to create sub-group if the "not" flag is set
+ this.on('sqlGroupsDistinct.filter', function(e, group, data, i) {
+ if (data.not && i > 0) {
+ e.value = true;
+ }
+ });
+
+ // Read "not" from parsed SQL
+ this.on('sqlToGroup.filter', function(e, data) {
+ e.value.not = !!data.not;
+ });
+
+ // Export "not" to Mongo
+ this.on('groupToMongo.filter', function(e, group) {
+ var key = '$' + group.condition.toLowerCase();
+ if (group.not && e.value[key]) {
+ e.value = { '$nor': [e.value] };
+ }
+ });
+
+ // Parse "$nor" operator from Mongo
+ this.on('parseMongoNode.filter', function(e) {
+ var keys = Object.keys(e.value);
+
+ if (keys[0] == '$nor') {
+ e.value = e.value[keys[0]][0];
+ e.value.not = true;
+ }
+ });
+
+ // Read "not" from parsed Mongo
+ this.on('mongoToGroup.filter', function(e, data) {
+ e.value.not = !!data.not;
+ });
+}, {
+ icon_unchecked: 'glyphicon glyphicon-unchecked',
+ icon_checked: 'glyphicon glyphicon-check',
+ disable_template: false
+});
+
+/**
+ * From {@link module:plugins.NotGroup}
+ * @name not
+ * @member {boolean}
+ * @memberof Group
+ * @instance
+ */
+Utils.defineModelProperties(Group, ['not']);
+
+QueryBuilder.selectors.group_not = QueryBuilder.selectors.group_header + ' [data-not=group]';
+
+QueryBuilder.extend(/** @lends module:plugins.NotGroup.prototype */ {
+ /**
+ * Performs actions when a group's not changes
+ * @param {Group} group
+ * @fires module:plugins.NotGroup.afterUpdateGroupNot
+ * @private
+ */
+ updateGroupNot: function(group) {
+ var options = this.plugins['not-group'];
+ group.$el.find('>' + QueryBuilder.selectors.group_not)
+ .toggleClass('active', group.not)
+ .find('i').attr('class', group.not ? options.icon_checked : options.icon_unchecked);
+
+ /**
+ * After the group's not flag has been modified
+ * @event afterUpdateGroupNot
+ * @memberof module:plugins.NotGroup
+ * @param {Group} group
+ */
+ this.trigger('afterUpdateGroupNot', group);
+
+ this.trigger('rulesChanged');
+ }
+});
+
+
+/**
+ * @class Sortable
+ * @memberof module:plugins
+ * @description Enables drag & drop sort of rules.
+ * @param {object} [options]
+ * @param {boolean} [options.inherit_no_drop=true]
+ * @param {boolean} [options.inherit_no_sortable=true]
+ * @param {string} [options.icon='glyphicon glyphicon-sort']
+ * @throws MissingLibraryError, ConfigError
+ */
+QueryBuilder.define('sortable', function(options) {
+ if (!('interact' in window)) {
+ Utils.error('MissingLibrary', 'interact.js is required to use "sortable" plugin. Get it here: http://interactjs.io');
+ }
+
+ if (options.default_no_sortable !== undefined) {
+ Utils.error(false, 'Config', 'Sortable plugin : "default_no_sortable" options is deprecated, use standard "default_rule_flags" and "default_group_flags" instead');
+ this.settings.default_rule_flags.no_sortable = this.settings.default_group_flags.no_sortable = options.default_no_sortable;
+ }
+
+ // recompute drop-zones during drag (when a rule is hidden)
+ interact.dynamicDrop(true);
+
+ // set move threshold to 10px
+ interact.pointerMoveTolerance(10);
+
+ var placeholder;
+ var ghost;
+ var src;
+ var moved;
+
+ // Init drag and drop
+ this.on('afterAddRule afterAddGroup', function(e, node) {
+ if (node == placeholder) {
+ return;
+ }
+
+ var self = e.builder;
+
+ // Inherit flags
+ if (options.inherit_no_sortable && node.parent && node.parent.flags.no_sortable) {
+ node.flags.no_sortable = true;
+ }
+ if (options.inherit_no_drop && node.parent && node.parent.flags.no_drop) {
+ node.flags.no_drop = true;
+ }
+
+ // Configure drag
+ if (!node.flags.no_sortable) {
+ interact(node.$el[0])
+ .draggable({
+ allowFrom: QueryBuilder.selectors.drag_handle,
+ onstart: function(event) {
+ moved = false;
+
+ // get model of dragged element
+ src = self.getModel(event.target);
+
+ // create ghost
+ ghost = src.$el.clone()
+ .appendTo(src.$el.parent())
+ .width(src.$el.outerWidth())
+ .addClass('dragging');
+
+ // create drop placeholder
+ var ph = $('
')
+ .height(src.$el.outerHeight());
+
+ placeholder = src.parent.addRule(ph, src.getPos());
+
+ // hide dragged element
+ src.$el.hide();
+ },
+ onmove: function(event) {
+ // make the ghost follow the cursor
+ ghost[0].style.top = event.clientY - 15 + 'px';
+ ghost[0].style.left = event.clientX - 15 + 'px';
+ },
+ onend: function(event) {
+ // starting from Interact 1.3.3, onend is called before ondrop
+ if (event.dropzone) {
+ moveSortableToTarget(src, $(event.relatedTarget), self);
+ moved = true;
+ }
+
+ // remove ghost
+ ghost.remove();
+ ghost = undefined;
+
+ // remove placeholder
+ placeholder.drop();
+ placeholder = undefined;
+
+ // show element
+ src.$el.css('display', '');
+
+ /**
+ * After a node has been moved with {@link module:plugins.Sortable}
+ * @event afterMove
+ * @memberof module:plugins.Sortable
+ * @param {Node} node
+ */
+ self.trigger('afterMove', src);
+
+ self.trigger('rulesChanged');
+ }
+ });
+ }
+
+ if (!node.flags.no_drop) {
+ // Configure drop on groups and rules
+ interact(node.$el[0])
+ .dropzone({
+ accept: QueryBuilder.selectors.rule_and_group_containers,
+ ondragenter: function(event) {
+ moveSortableToTarget(placeholder, $(event.target), self);
+ },
+ ondrop: function(event) {
+ if (!moved) {
+ moveSortableToTarget(src, $(event.target), self);
+ }
+ }
+ });
+
+ // Configure drop on group headers
+ if (node instanceof Group) {
+ interact(node.$el.find(QueryBuilder.selectors.group_header)[0])
+ .dropzone({
+ accept: QueryBuilder.selectors.rule_and_group_containers,
+ ondragenter: function(event) {
+ moveSortableToTarget(placeholder, $(event.target), self);
+ },
+ ondrop: function(event) {
+ if (!moved) {
+ moveSortableToTarget(src, $(event.target), self);
+ }
+ }
+ });
+ }
+ }
+ });
+
+ // Detach interactables
+ this.on('beforeDeleteRule beforeDeleteGroup', function(e, node) {
+ if (!e.isDefaultPrevented()) {
+ interact(node.$el[0]).unset();
+
+ if (node instanceof Group) {
+ interact(node.$el.find(QueryBuilder.selectors.group_header)[0]).unset();
+ }
+ }
+ });
+
+ // Remove drag handle from non-sortable items
+ this.on('afterApplyRuleFlags afterApplyGroupFlags', function(e, node) {
+ if (node.flags.no_sortable) {
+ node.$el.find('.drag-handle').remove();
+ }
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h, level) {
+ if (level > 1) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.condition_container).after('
');
+ h.value = $h.prop('outerHTML');
+ }
+ });
+
+ this.on('getRuleTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.rule_header).after('
');
+ h.value = $h.prop('outerHTML');
+ });
+ }
+}, {
+ inherit_no_sortable: true,
+ inherit_no_drop: true,
+ icon: 'glyphicon glyphicon-sort',
+ disable_template: false
+});
+
+QueryBuilder.selectors.rule_and_group_containers = QueryBuilder.selectors.rule_container + ', ' + QueryBuilder.selectors.group_container;
+QueryBuilder.selectors.drag_handle = '.drag-handle';
+
+QueryBuilder.defaults({
+ default_rule_flags: {
+ no_sortable: false,
+ no_drop: false
+ },
+ default_group_flags: {
+ no_sortable: false,
+ no_drop: false
+ }
+});
+
+/**
+ * Moves an element (placeholder or actual object) depending on active target
+ * @memberof module:plugins.Sortable
+ * @param {Node} node
+ * @param {jQuery} target
+ * @param {QueryBuilder} [builder]
+ * @private
+ */
+function moveSortableToTarget(node, target, builder) {
+ var parent, method;
+ var Selectors = QueryBuilder.selectors;
+
+ // on rule
+ parent = target.closest(Selectors.rule_container);
+ if (parent.length) {
+ method = 'moveAfter';
+ }
+
+ // on group header
+ if (!method) {
+ parent = target.closest(Selectors.group_header);
+ if (parent.length) {
+ parent = target.closest(Selectors.group_container);
+ method = 'moveAtBegin';
+ }
+ }
+
+ // on group
+ if (!method) {
+ parent = target.closest(Selectors.group_container);
+ if (parent.length) {
+ method = 'moveAtEnd';
+ }
+ }
+
+ if (method) {
+ node[method](builder.getModel(parent));
+
+ // refresh radio value
+ if (builder && node instanceof Rule) {
+ builder.setRuleInputValue(node, node.value);
+ }
+ }
+}
+
+
+/**
+ * @class SqlSupport
+ * @memberof module:plugins
+ * @description Allows to export rules as a SQL WHERE statement as well as populating the builder from an SQL query.
+ * @param {object} [options]
+ * @param {boolean} [options.boolean_as_integer=true] - `true` to convert boolean values to integer in the SQL output
+ */
+QueryBuilder.define('sql-support', function(options) {
+
+}, {
+ boolean_as_integer: true
+});
+
+QueryBuilder.defaults({
+ // operators for internal -> SQL conversion
+ sqlOperators: {
+ equal: { op: '= ?' },
+ not_equal: { op: '!= ?' },
+ in: { op: 'IN(?)', sep: ', ' },
+ not_in: { op: 'NOT IN(?)', sep: ', ' },
+ less: { op: '< ?' },
+ less_or_equal: { op: '<= ?' },
+ greater: { op: '> ?' },
+ greater_or_equal: { op: '>= ?' },
+ between: { op: 'BETWEEN ?', sep: ' AND ' },
+ not_between: { op: 'NOT BETWEEN ?', sep: ' AND ' },
+ begins_with: { op: 'LIKE(?)', mod: '{0}%' },
+ not_begins_with: { op: 'NOT LIKE(?)', mod: '{0}%' },
+ contains: { op: 'LIKE(?)', mod: '%{0}%' },
+ not_contains: { op: 'NOT LIKE(?)', mod: '%{0}%' },
+ ends_with: { op: 'LIKE(?)', mod: '%{0}' },
+ not_ends_with: { op: 'NOT LIKE(?)', mod: '%{0}' },
+ is_empty: { op: '= \'\'' },
+ is_not_empty: { op: '!= \'\'' },
+ is_null: { op: 'IS NULL' },
+ is_not_null: { op: 'IS NOT NULL' }
+ },
+
+ // operators for SQL -> internal conversion
+ sqlRuleOperator: {
+ '=': function(v) {
+ return {
+ val: v,
+ op: v === '' ? 'is_empty' : 'equal'
+ };
+ },
+ '!=': function(v) {
+ return {
+ val: v,
+ op: v === '' ? 'is_not_empty' : 'not_equal'
+ };
+ },
+ 'LIKE': function(v) {
+ if (v.slice(0, 1) == '%' && v.slice(-1) == '%') {
+ return {
+ val: v.slice(1, -1),
+ op: 'contains'
+ };
+ }
+ else if (v.slice(0, 1) == '%') {
+ return {
+ val: v.slice(1),
+ op: 'ends_with'
+ };
+ }
+ else if (v.slice(-1) == '%') {
+ return {
+ val: v.slice(0, -1),
+ op: 'begins_with'
+ };
+ }
+ else {
+ Utils.error('SQLParse', 'Invalid value for LIKE operator "{0}"', v);
+ }
+ },
+ 'NOT LIKE': function(v) {
+ if (v.slice(0, 1) == '%' && v.slice(-1) == '%') {
+ return {
+ val: v.slice(1, -1),
+ op: 'not_contains'
+ };
+ }
+ else if (v.slice(0, 1) == '%') {
+ return {
+ val: v.slice(1),
+ op: 'not_ends_with'
+ };
+ }
+ else if (v.slice(-1) == '%') {
+ return {
+ val: v.slice(0, -1),
+ op: 'not_begins_with'
+ };
+ }
+ else {
+ Utils.error('SQLParse', 'Invalid value for NOT LIKE operator "{0}"', v);
+ }
+ },
+ 'IN': function(v) {
+ return { val: v, op: 'in' };
+ },
+ 'NOT IN': function(v) {
+ return { val: v, op: 'not_in' };
+ },
+ '<': function(v) {
+ return { val: v, op: 'less' };
+ },
+ '<=': function(v) {
+ return { val: v, op: 'less_or_equal' };
+ },
+ '>': function(v) {
+ return { val: v, op: 'greater' };
+ },
+ '>=': function(v) {
+ return { val: v, op: 'greater_or_equal' };
+ },
+ 'BETWEEN': function(v) {
+ return { val: v, op: 'between' };
+ },
+ 'NOT BETWEEN': function(v) {
+ return { val: v, op: 'not_between' };
+ },
+ 'IS': function(v) {
+ if (v !== null) {
+ Utils.error('SQLParse', 'Invalid value for IS operator');
+ }
+ return { val: null, op: 'is_null' };
+ },
+ 'IS NOT': function(v) {
+ if (v !== null) {
+ Utils.error('SQLParse', 'Invalid value for IS operator');
+ }
+ return { val: null, op: 'is_not_null' };
+ }
+ },
+
+ // statements for internal -> SQL conversion
+ sqlStatements: {
+ 'question_mark': function() {
+ var params = [];
+ return {
+ add: function(rule, value) {
+ params.push(value);
+ return '?';
+ },
+ run: function() {
+ return params;
+ }
+ };
+ },
+
+ 'numbered': function(char) {
+ if (!char || char.length > 1) char = '$';
+ var index = 0;
+ var params = [];
+ return {
+ add: function(rule, value) {
+ params.push(value);
+ index++;
+ return char + index;
+ },
+ run: function() {
+ return params;
+ }
+ };
+ },
+
+ 'named': function(char) {
+ if (!char || char.length > 1) char = ':';
+ var indexes = {};
+ var params = {};
+ return {
+ add: function(rule, value) {
+ if (!indexes[rule.field]) indexes[rule.field] = 1;
+ var key = rule.field + '_' + (indexes[rule.field]++);
+ params[key] = value;
+ return char + key;
+ },
+ run: function() {
+ return params;
+ }
+ };
+ }
+ },
+
+ // statements for SQL -> internal conversion
+ sqlRuleStatement: {
+ 'question_mark': function(values) {
+ var index = 0;
+ return {
+ parse: function(v) {
+ return v == '?' ? values[index++] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(/\?/g, '\'?\'');
+ }
+ };
+ },
+
+ 'numbered': function(values, char) {
+ if (!char || char.length > 1) char = '$';
+ var regex1 = new RegExp('^\\' + char + '[0-9]+$');
+ var regex2 = new RegExp('\\' + char + '([0-9]+)', 'g');
+ return {
+ parse: function(v) {
+ return regex1.test(v) ? values[v.slice(1) - 1] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(regex2, '\'' + (char == '$' ? '$$' : char) + '$1\'');
+ }
+ };
+ },
+
+ 'named': function(values, char) {
+ if (!char || char.length > 1) char = ':';
+ var regex1 = new RegExp('^\\' + char);
+ var regex2 = new RegExp('\\' + char + '(' + Object.keys(values).join('|') + ')', 'g');
+ return {
+ parse: function(v) {
+ return regex1.test(v) ? values[v.slice(1)] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(regex2, '\'' + (char == '$' ? '$$' : char) + '$1\'');
+ }
+ };
+ }
+ }
+});
+
+/**
+ * @typedef {object} SqlQuery
+ * @memberof module:plugins.SqlSupport
+ * @property {string} sql
+ * @property {object} params
+ */
+
+QueryBuilder.extend(/** @lends module:plugins.SqlSupport.prototype */ {
+ /**
+ * Returns rules as a SQL query
+ * @param {boolean|string} [stmt] - use prepared statements: false, 'question_mark', 'numbered', 'numbered(@)', 'named', 'named(@)'
+ * @param {boolean} [nl=false] output with new lines
+ * @param {object} [data] - current rules by default
+ * @returns {module:plugins.SqlSupport.SqlQuery}
+ * @fires module:plugins.SqlSupport.changer:getSQLField
+ * @fires module:plugins.SqlSupport.changer:ruleToSQL
+ * @fires module:plugins.SqlSupport.changer:groupToSQL
+ * @throws UndefinedSQLConditionError, UndefinedSQLOperatorError
+ */
+ getSQL: function(stmt, nl, data) {
+ data = (data === undefined) ? this.getRules() : data;
+
+ if (!data) {
+ return null;
+ }
+
+ nl = !!nl ? '\n' : ' ';
+ var boolean_as_integer = this.getPluginOptions('sql-support', 'boolean_as_integer');
+
+ if (stmt === true) {
+ stmt = 'question_mark';
+ }
+ if (typeof stmt == 'string') {
+ var config = getStmtConfig(stmt);
+ stmt = this.settings.sqlStatements[config[1]](config[2]);
+ }
+
+ var self = this;
+
+ var sql = (function parse(group) {
+ if (!group.condition) {
+ group.condition = self.settings.default_condition;
+ }
+ if (['AND', 'OR'].indexOf(group.condition.toUpperCase()) === -1) {
+ Utils.error('UndefinedSQLCondition', 'Unable to build SQL query with condition "{0}"', group.condition);
+ }
+
+ if (!group.rules) {
+ return '';
+ }
+
+ var parts = [];
+
+ group.rules.forEach(function(rule) {
+ if (rule.rules && rule.rules.length > 0) {
+ parts.push('(' + nl + parse(rule) + nl + ')' + nl);
+ }
+ else {
+ var sql = self.settings.sqlOperators[rule.operator];
+ var ope = self.getOperatorByType(rule.operator);
+ var value = '';
+
+ if (sql === undefined) {
+ Utils.error('UndefinedSQLOperator', 'Unknown SQL operation for operator "{0}"', rule.operator);
+ }
+
+ if (ope.nb_inputs !== 0) {
+ if (!(rule.value instanceof Array)) {
+ rule.value = [rule.value];
+ }
+
+ rule.value.forEach(function(v, i) {
+ if (i > 0) {
+ value += sql.sep;
+ }
+
+ if (rule.type == 'boolean' && boolean_as_integer) {
+ v = v ? 1 : 0;
+ }
+ else if (!stmt && rule.type !== 'integer' && rule.type !== 'double' && rule.type !== 'boolean') {
+ v = Utils.escapeString(v);
+ }
+
+ if (sql.mod) {
+ v = Utils.fmt(sql.mod, v);
+ }
+
+ if (stmt) {
+ value += stmt.add(rule, v);
+ }
+ else {
+ if (typeof v == 'string') {
+ v = '\'' + v + '\'';
+ }
+
+ value += v;
+ }
+ });
+ }
+
+ var sqlFn = function(v) {
+ return sql.op.replace('?', function() {
+ return v;
+ });
+ };
+
+ /**
+ * Modifies the SQL field used by a rule
+ * @event changer:getSQLField
+ * @memberof module:plugins.SqlSupport
+ * @param {string} field
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ var field = self.change('getSQLField', rule.field, rule);
+
+ var ruleExpression = field + ' ' + sqlFn(value);
+
+ /**
+ * Modifies the SQL generated for a rule
+ * @event changer:ruleToSQL
+ * @memberof module:plugins.SqlSupport
+ * @param {string} expression
+ * @param {Rule} rule
+ * @param {*} value
+ * @param {function} valueWrapper - function that takes the value and adds the operator
+ * @returns {string}
+ */
+ parts.push(self.change('ruleToSQL', ruleExpression, rule, value, sqlFn));
+ }
+ });
+
+ var groupExpression = parts.join(' ' + group.condition + nl);
+
+ /**
+ * Modifies the SQL generated for a group
+ * @event changer:groupToSQL
+ * @memberof module:plugins.SqlSupport
+ * @param {string} expression
+ * @param {Group} group
+ * @returns {string}
+ */
+ return self.change('groupToSQL', groupExpression, group);
+ }(data));
+
+ if (stmt) {
+ return {
+ sql: sql,
+ params: stmt.run()
+ };
+ }
+ else {
+ return {
+ sql: sql
+ };
+ }
+ },
+
+ /**
+ * Convert a SQL query to rules
+ * @param {string|module:plugins.SqlSupport.SqlQuery} query
+ * @param {boolean|string} stmt
+ * @returns {object}
+ * @fires module:plugins.SqlSupport.changer:parseSQLNode
+ * @fires module:plugins.SqlSupport.changer:getSQLFieldID
+ * @fires module:plugins.SqlSupport.changer:sqlToRule
+ * @fires module:plugins.SqlSupport.changer:sqlToGroup
+ * @throws MissingLibraryError, SQLParseError, UndefinedSQLOperatorError
+ */
+ getRulesFromSQL: function(query, stmt) {
+ if (!('SQLParser' in window)) {
+ Utils.error('MissingLibrary', 'SQLParser is required to parse SQL queries. Get it here https://github.com/mistic100/sql-parser');
+ }
+
+ var self = this;
+
+ if (typeof query == 'string') {
+ query = { sql: query };
+ }
+
+ if (stmt === true) stmt = 'question_mark';
+ if (typeof stmt == 'string') {
+ var config = getStmtConfig(stmt);
+ stmt = this.settings.sqlRuleStatement[config[1]](query.params, config[2]);
+ }
+
+ if (stmt) {
+ query.sql = stmt.esc(query.sql);
+ }
+
+ if (query.sql.toUpperCase().indexOf('SELECT') !== 0) {
+ query.sql = 'SELECT * FROM table WHERE ' + query.sql;
+ }
+
+ var parsed = SQLParser.parse(query.sql);
+
+ if (!parsed.where) {
+ Utils.error('SQLParse', 'No WHERE clause found');
+ }
+
+ /**
+ * Custom parsing of an AST node generated by SQLParser, you can return a sub-part of the tree, or a well formed group or rule JSON
+ * @event changer:parseSQLNode
+ * @memberof module:plugins.SqlSupport
+ * @param {object} AST node
+ * @returns {object} tree, rule or group
+ */
+ var data = self.change('parseSQLNode', parsed.where.conditions);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ return data;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ return {
+ condition: this.settings.default_condition,
+ rules: [data]
+ };
+ }
+
+ // create root group
+ var out = self.change('sqlToGroup', {
+ condition: this.settings.default_condition,
+ rules: []
+ }, data);
+
+ // keep track of current group
+ var curr = out;
+
+ (function flatten(data, i) {
+ if (data === null) {
+ return;
+ }
+
+ // allow plugins to manually parse or handle special cases
+ data = self.change('parseSQLNode', data);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ curr.rules.push(data);
+ return;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ curr.rules.push(data);
+ return;
+ }
+
+ // data must be a SQL parser node
+ if (!('left' in data) || !('right' in data) || !('operation' in data)) {
+ Utils.error('SQLParse', 'Unable to parse WHERE clause');
+ }
+
+ // it's a node
+ if (['AND', 'OR'].indexOf(data.operation.toUpperCase()) !== -1) {
+ // create a sub-group if the condition is not the same and it's not the first level
+
+ /**
+ * Given an existing group and an AST node, determines if a sub-group must be created
+ * @event changer:sqlGroupsDistinct
+ * @memberof module:plugins.SqlSupport
+ * @param {boolean} create - true by default if the group condition is different
+ * @param {object} group
+ * @param {object} AST
+ * @param {int} current group level
+ * @returns {boolean}
+ */
+ var createGroup = self.change('sqlGroupsDistinct', i > 0 && curr.condition != data.operation.toUpperCase(), curr, data, i);
+
+ if (createGroup) {
+ /**
+ * Modifies the group generated from the SQL expression (this is called before the group is filled with rules)
+ * @event changer:sqlToGroup
+ * @memberof module:plugins.SqlSupport
+ * @param {object} group
+ * @param {object} AST
+ * @returns {object}
+ */
+ var group = self.change('sqlToGroup', {
+ condition: self.settings.default_condition,
+ rules: []
+ }, data);
+
+ curr.rules.push(group);
+ curr = group;
+ }
+
+ curr.condition = data.operation.toUpperCase();
+ i++;
+
+ // some magic !
+ var next = curr;
+ flatten(data.left, i);
+
+ curr = next;
+ flatten(data.right, i);
+ }
+ // it's a leaf
+ else {
+ if ($.isPlainObject(data.right.value)) {
+ Utils.error('SQLParse', 'Value format not supported for {0}.', data.left.value);
+ }
+
+ // convert array
+ var value;
+ if ($.isArray(data.right.value)) {
+ value = data.right.value.map(function(v) {
+ return v.value;
+ });
+ }
+ else {
+ value = data.right.value;
+ }
+
+ // get actual values
+ if (stmt) {
+ if ($.isArray(value)) {
+ value = value.map(stmt.parse);
+ }
+ else {
+ value = stmt.parse(value);
+ }
+ }
+
+ // convert operator
+ var operator = data.operation.toUpperCase();
+ if (operator == '<>') {
+ operator = '!=';
+ }
+
+ var sqlrl = self.settings.sqlRuleOperator[operator];
+ if (sqlrl === undefined) {
+ Utils.error('UndefinedSQLOperator', 'Invalid SQL operation "{0}".', data.operation);
+ }
+
+ var opVal = sqlrl.call(this, value, data.operation);
+
+ // find field name
+ var field;
+ if ('values' in data.left) {
+ field = data.left.values.join('.');
+ }
+ else if ('value' in data.left) {
+ field = data.left.value;
+ }
+ else {
+ Utils.error('SQLParse', 'Cannot find field name in {0}', JSON.stringify(data.left));
+ }
+
+ var id = self.getSQLFieldID(field, value);
+
+ /**
+ * Modifies the rule generated from the SQL expression
+ * @event changer:sqlToRule
+ * @memberof module:plugins.SqlSupport
+ * @param {object} rule
+ * @param {object} AST
+ * @returns {object}
+ */
+ var rule = self.change('sqlToRule', {
+ id: id,
+ field: field,
+ operator: opVal.op,
+ value: opVal.val
+ }, data);
+
+ curr.rules.push(rule);
+ }
+ }(data, 0));
+
+ return out;
+ },
+
+ /**
+ * Sets the builder's rules from a SQL query
+ * @see module:plugins.SqlSupport.getRulesFromSQL
+ */
+ setRulesFromSQL: function(query, stmt) {
+ this.setRules(this.getRulesFromSQL(query, stmt));
+ },
+
+ /**
+ * Returns a filter identifier from the SQL field.
+ * Automatically use the only one filter with a matching field, fires a changer otherwise.
+ * @param {string} field
+ * @param {*} value
+ * @fires module:plugins.SqlSupport:changer:getSQLFieldID
+ * @returns {string}
+ * @private
+ */
+ getSQLFieldID: function(field, value) {
+ var matchingFilters = this.filters.filter(function(filter) {
+ return filter.field.toLowerCase() === field.toLowerCase();
+ });
+
+ var id;
+ if (matchingFilters.length === 1) {
+ id = matchingFilters[0].id;
+ }
+ else {
+ /**
+ * Returns a filter identifier from the SQL field
+ * @event changer:getSQLFieldID
+ * @memberof module:plugins.SqlSupport
+ * @param {string} field
+ * @param {*} value
+ * @returns {string}
+ */
+ id = this.change('getSQLFieldID', field, value);
+ }
+
+ return id;
+ }
+});
+
+/**
+ * Parses the statement configuration
+ * @memberof module:plugins.SqlSupport
+ * @param {string} stmt
+ * @returns {Array} null, mode, option
+ * @private
+ */
+function getStmtConfig(stmt) {
+ var config = stmt.match(/(question_mark|numbered|named)(?:\((.)\))?/);
+ if (!config) config = [null, 'question_mark', undefined];
+ return config;
+}
+
+
+/**
+ * @class UniqueFilter
+ * @memberof module:plugins
+ * @description Allows to define some filters as "unique": ie which can be used for only one rule, globally or in the same group.
+ */
+QueryBuilder.define('unique-filter', function() {
+ this.status.used_filters = {};
+
+ this.on('afterUpdateRuleFilter', this.updateDisabledFilters);
+ this.on('afterDeleteRule', this.updateDisabledFilters);
+ this.on('afterCreateRuleFilters', this.applyDisabledFilters);
+ this.on('afterReset', this.clearDisabledFilters);
+ this.on('afterClear', this.clearDisabledFilters);
+
+ // Ensure that the default filter is not already used if unique
+ this.on('getDefaultFilter.filter', function(e, model) {
+ var self = e.builder;
+
+ self.updateDisabledFilters();
+
+ if (e.value.id in self.status.used_filters) {
+ var found = self.filters.some(function(filter) {
+ if (!(filter.id in self.status.used_filters) || self.status.used_filters[filter.id].length > 0 && self.status.used_filters[filter.id].indexOf(model.parent) === -1) {
+ e.value = filter;
+ return true;
+ }
+ });
+
+ if (!found) {
+ Utils.error(false, 'UniqueFilter', 'No more non-unique filters available');
+ e.value = undefined;
+ }
+ }
+ });
+});
+
+QueryBuilder.extend(/** @lends module:plugins.UniqueFilter.prototype */ {
+ /**
+ * Updates the list of used filters
+ * @param {$.Event} [e]
+ * @private
+ */
+ updateDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ self.status.used_filters = {};
+
+ if (!self.model) {
+ return;
+ }
+
+ // get used filters
+ (function walk(group) {
+ group.each(function(rule) {
+ if (rule.filter && rule.filter.unique) {
+ if (!self.status.used_filters[rule.filter.id]) {
+ self.status.used_filters[rule.filter.id] = [];
+ }
+ if (rule.filter.unique == 'group') {
+ self.status.used_filters[rule.filter.id].push(rule.parent);
+ }
+ }
+ }, function(group) {
+ walk(group);
+ });
+ }(self.model.root));
+
+ self.applyDisabledFilters(e);
+ },
+
+ /**
+ * Clear the list of used filters
+ * @param {$.Event} [e]
+ * @private
+ */
+ clearDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ self.status.used_filters = {};
+
+ self.applyDisabledFilters(e);
+ },
+
+ /**
+ * Disabled filters depending on the list of used ones
+ * @param {$.Event} [e]
+ * @private
+ */
+ applyDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ // re-enable everything
+ self.$el.find(QueryBuilder.selectors.filter_container + ' option').prop('disabled', false);
+
+ // disable some
+ $.each(self.status.used_filters, function(filterId, groups) {
+ if (groups.length === 0) {
+ self.$el.find(QueryBuilder.selectors.filter_container + ' option[value="' + filterId + '"]:not(:selected)').prop('disabled', true);
+ }
+ else {
+ groups.forEach(function(group) {
+ group.each(function(rule) {
+ rule.$el.find(QueryBuilder.selectors.filter_container + ' option[value="' + filterId + '"]:not(:selected)').prop('disabled', true);
+ });
+ });
+ }
+ });
+
+ // update Selectpicker
+ if (self.settings.plugins && self.settings.plugins['bt-selectpicker']) {
+ self.$el.find(QueryBuilder.selectors.rule_filter).selectpicker('render');
+ }
+ }
+});
+
+
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: English (en)
+ * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+QueryBuilder.regional['en'] = {
+ "__locale": "English (en)",
+ "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr",
+ "add_rule": "Add rule",
+ "add_group": "Add group",
+ "delete_rule": "Delete",
+ "delete_group": "Delete",
+ "conditions": {
+ "AND": "AND",
+ "OR": "OR"
+ },
+ "operators": {
+ "equal": "equal",
+ "not_equal": "not equal",
+ "in": "in",
+ "not_in": "not in",
+ "less": "less",
+ "less_or_equal": "less or equal",
+ "greater": "greater",
+ "greater_or_equal": "greater or equal",
+ "between": "between",
+ "not_between": "not between",
+ "begins_with": "begins with",
+ "not_begins_with": "doesn't begin with",
+ "contains": "contains",
+ "not_contains": "doesn't contain",
+ "ends_with": "ends with",
+ "not_ends_with": "doesn't end with",
+ "is_empty": "is empty",
+ "is_not_empty": "is not empty",
+ "is_null": "is null",
+ "is_not_null": "is not null"
+ },
+ "errors": {
+ "no_filter": "No filter selected",
+ "empty_group": "The group is empty",
+ "radio_empty": "No value selected",
+ "checkbox_empty": "No value selected",
+ "select_empty": "No value selected",
+ "string_empty": "Input field cannot be blank",
+ "string_exceed_min_length": "Must contain at least {0} characters",
+ "string_exceed_max_length": "Must not contain more than {0} characters",
+ "string_invalid_format": "Invalid format ({0})",
+ "number_nan": "Not a number",
+ "number_not_integer": "This field must contain numbers 0-9. No letters, spaces, or special characters allowed.",
+ "number_not_double": "This field must contain numbers 0-9 with decimals separated by point “.” - For Example 10 or 50.60. No letters, spaces, or special characters allowed.",
+ "number_exceed_min": "Must be greater than {0}",
+ "number_exceed_max": "Must be lower than {0}",
+ "number_wrong_step": "Must be a multiple of {0}",
+ "number_between_invalid": "Invalid values, {0} is greater than {1}",
+ "datetime_empty": "Input field cannot be blank",
+ "datetime_invalid": "Invalid date format ({0})",
+ "datetime_exceed_min": "Must be after {0}",
+ "datetime_exceed_max": "Must be before {0}",
+ "datetime_between_invalid": "Invalid values, {0} is greater than {1}",
+ "boolean_not_valid": "Not a boolean",
+ "operator_not_multiple": "Operator \"{1}\" cannot accept multiple values"
+ },
+ "invert": "Invert",
+ "NOT": "NOT"
+};
+
+QueryBuilder.defaults({ lang_code: 'en' });
+return QueryBuilder;
+
+}));
diff --git a/dist/js/query-builder.min.js b/dist/js/query-builder.min.js
new file mode 100644
index 00000000..794dcea6
--- /dev/null
+++ b/dist/js/query-builder.min.js
@@ -0,0 +1,8 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+!function(e,t){"function"==typeof define&&define.amd?define(["jquery","dot/doT","jquery-extendext"],t):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),require("dot/doT"),require("jquery-extendext")):t(e.jQuery,e.doT)}(this,function($,r){"use strict";var c=function(e,t){(e[0].queryBuilder=this).$el=e,this.settings=$.extendext(!0,"replace",{},c.DEFAULTS,t),this.model=new i,this.status={id:null,generated_id:!1,group_id:0,rule_id:0,has_optgroup:!1,has_operator_optgroup:!1},this.filters=this.settings.filters,this.icons=this.settings.icons,this.operators=this.settings.operators,this.templates=this.settings.templates,this.plugins=this.settings.plugins,this.lang=null,void 0===c.regional.en&&h.error("Config",'"i18n/en.js" not loaded.'),this.lang=$.extendext(!0,"replace",{},c.regional.en,c.regional[this.settings.lang_code],this.settings.lang),!1===this.settings.allow_groups?this.settings.allow_groups=0:!0===this.settings.allow_groups&&(this.settings.allow_groups=-1),Object.keys(this.templates).forEach(function(e){this.templates[e]||(this.templates[e]=c.templates[e]),"string"==typeof this.templates[e]&&(this.templates[e]=r.template(this.templates[e]))},this),this.$el.attr("id")||(this.$el.attr("id","qb_"+Math.floor(99999*Math.random())),this.status.generated_id=!0),this.status.id=this.$el.attr("id"),this.$el.addClass("query-builder form-inline"),this.filters=this.checkFilters(this.filters),this.operators=this.checkOperators(this.operators),this.bindEvents(),this.initPlugins()};$.extend(c.prototype,{trigger:function(e){var t=new $.Event(this._tojQueryEvent(e),{builder:this});return this.$el.triggerHandler(t,Array.prototype.slice.call(arguments,1)),t},change:function(e,t){var r=new $.Event(this._tojQueryEvent(e,!0),{builder:this,value:t});return this.$el.triggerHandler(r,Array.prototype.slice.call(arguments,2)),r.value},on:function(e,t){return this.$el.on(this._tojQueryEvent(e),t),this},off:function(e,t){return this.$el.off(this._tojQueryEvent(e),t),this},once:function(e,t){return this.$el.one(this._tojQueryEvent(e),t),this},_tojQueryEvent:function(e,t){return e.split(" ").map(function(e){return e+".queryBuilder"+(t?".filter":"")}).join(" ")}}),c.types={string:"string",integer:"number",double:"number",date:"datetime",time:"datetime",datetime:"datetime",boolean:"boolean"},c.inputs=["text","number","textarea","radio","checkbox","select"],c.modifiable_options=["display_errors","allow_groups","allow_empty","default_condition","default_filter"],c.selectors={group_container:".rules-group-container",rule_container:".rule-container",filter_container:".rule-filter-container",operator_container:".rule-operator-container",value_container:".rule-value-container",error_container:".error-container",condition_container:".rules-group-header .group-conditions",tooltip:".tooltip-container",description:".description-container",rule_header:".rule-header",group_header:".rules-group-header",group_actions:".group-actions",rule_actions:".rule-actions",rules_list:".rules-group-body>.rules-list",group_condition:".rules-group-header [name$=_cond]",rule_filter:".rule-filter-container [name$=_filter]",rule_operator:".rule-operator-container [name$=_operator]",rule_value:".rule-value-container [name*=_value_]",add_rule:"[data-add=rule]",delete_rule:"[data-delete=rule]",add_group:"[data-add=group]",delete_group:"[data-delete=group]"},c.templates={},c.regional={},c.OPERATORS={equal:{type:"equal",nb_inputs:1,multiple:!1,apply_to:["string","number","datetime","boolean"]},not_equal:{type:"not_equal",nb_inputs:1,multiple:!1,apply_to:["string","number","datetime","boolean"]},in:{type:"in",nb_inputs:1,multiple:!0,apply_to:["string","number","datetime"]},not_in:{type:"not_in",nb_inputs:1,multiple:!0,apply_to:["string","number","datetime"]},less:{type:"less",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},less_or_equal:{type:"less_or_equal",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},greater:{type:"greater",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},greater_or_equal:{type:"greater_or_equal",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},between:{type:"between",nb_inputs:2,multiple:!1,apply_to:["number","datetime"]},not_between:{type:"not_between",nb_inputs:2,multiple:!1,apply_to:["number","datetime"]},begins_with:{type:"begins_with",nb_inputs:1,multiple:!1,apply_to:["string"]},not_begins_with:{type:"not_begins_with",nb_inputs:1,multiple:!1,apply_to:["string"]},contains:{type:"contains",nb_inputs:1,multiple:!1,apply_to:["string"]},not_contains:{type:"not_contains",nb_inputs:1,multiple:!1,apply_to:["string"]},ends_with:{type:"ends_with",nb_inputs:1,multiple:!1,apply_to:["string"]},not_ends_with:{type:"not_ends_with",nb_inputs:1,multiple:!1,apply_to:["string"]},is_empty:{type:"is_empty",nb_inputs:0,multiple:!1,apply_to:["string"]},is_not_empty:{type:"is_not_empty",nb_inputs:0,multiple:!1,apply_to:["string"]},is_null:{type:"is_null",nb_inputs:0,multiple:!1,apply_to:["string","number","datetime","boolean"]},is_not_null:{type:"is_not_null",nb_inputs:0,multiple:!1,apply_to:["string","number","datetime","boolean"]}},c.DEFAULTS={filters:[],plugins:[],sort_filters:!1,display_errors:!0,allow_groups:-1,allow_empty:!1,conditions:["AND","OR"],default_condition:"AND",inputs_separator:" , ",select_placeholder:"------",display_empty_filter:!0,default_filter:null,optgroups:{},default_rule_flags:{filter_readonly:!1,operator_readonly:!1,value_readonly:!1,no_delete:!1},default_group_flags:{condition_readonly:!1,no_add_rule:!1,no_add_group:!1,no_delete:!1},templates:{group:null,rule:null,filterSelect:null,operatorSelect:null,ruleValueSelect:null},lang_code:"en",lang:{},operators:["equal","not_equal","in","not_in","less","less_or_equal","greater","greater_or_equal","between","not_between","begins_with","not_begins_with","contains","not_contains","ends_with","not_ends_with","is_empty","is_not_empty","is_null","is_not_null"],icons:{add_group:"glyphicon glyphicon-plus-sign",add_rule:"glyphicon glyphicon-plus",remove_group:"glyphicon glyphicon-remove",remove_rule:"glyphicon glyphicon-remove",error:"glyphicon glyphicon-warning-sign",tooltip:"glyphicon glyphicon-info-sign"}},c.plugins={},c.defaults=function(e){if("object"!=typeof e)return"string"==typeof e?"object"==typeof c.DEFAULTS[e]?$.extend(!0,{},c.DEFAULTS[e]):c.DEFAULTS[e]:$.extend(!0,{},c.DEFAULTS);$.extendext(!0,"replace",c.DEFAULTS,e)},c.define=function(e,t,r){c.plugins[e]={fct:t,def:r||{}}},c.extend=function(e){$.extend(c.prototype,e)},c.prototype.initPlugins=function(){if(this.plugins){if($.isArray(this.plugins)){var t={};this.plugins.forEach(function(e){t[e]=null}),this.plugins=t}Object.keys(this.plugins).forEach(function(e){e in c.plugins?(this.plugins[e]=$.extend(!0,{},c.plugins[e].def,this.plugins[e]||{}),c.plugins[e].fct.call(this,this.plugins[e])):h.error("Config",'Unable to find plugin "{0}"',e)},this)}},c.prototype.getPluginOptions=function(e,t){var r;if(this.plugins&&this.plugins[e]?r=this.plugins[e]:c.plugins[e]&&(r=c.plugins[e].def),r)return t?r[t]:r;h.error("Config",'Unable to find plugin "{0}"',e)},c.prototype.init=function(e){this.trigger("afterInit"),e?(this.setRules(e),delete this.settings.rules):this.setRoot(!0)},c.prototype.checkFilters=function(e){var t=[];if(e&&0!==e.length||h.error("Config","Missing filters list"),e.forEach(function(i,e){switch(i.id||h.error("Config","Missing filter {0} id",e),-1!=t.indexOf(i.id)&&h.error("Config",'Filter "{0}" already defined',i.id),t.push(i.id),i.type?c.types[i.type]||h.error("Config",'Invalid type "{0}"',i.type):i.type="string",i.input?"function"!=typeof i.input&&-1==c.inputs.indexOf(i.input)&&h.error("Config",'Invalid input "{0}"',i.input):i.input="number"===c.types[i.type]?"number":"text",i.operators&&i.operators.forEach(function(e){"string"!=typeof e&&h.error("Config","Filter operators must be global operators types (string)")}),i.field||(i.field=i.id),i.label||(i.label=i.field),i.optgroup?(this.status.has_optgroup=!0,this.settings.optgroups[i.optgroup]||(this.settings.optgroups[i.optgroup]=i.optgroup)):i.optgroup=null,i.input){case"radio":case"checkbox":(!i.values||i.values.length<1)&&h.error("Config",'Missing filter "{0}" values',i.id);break;case"select":var o=[];i.has_optgroup=!1,h.iterateOptions(i.values,function(e,t,r){o.push({value:e,label:t,optgroup:r||null}),r&&(i.has_optgroup=!0,this.settings.optgroups[r]||(this.settings.optgroups[r]=r))}.bind(this)),i.has_optgroup?i.values=h.groupSort(o,"optgroup"):i.values=o,i.placeholder&&(void 0===i.placeholder_value&&(i.placeholder_value=-1),i.values.forEach(function(e){e.value==i.placeholder_value&&h.error("Config",'Placeholder of filter "{0}" overlaps with one of its values',i.id)}))}},this),this.settings.sort_filters)if("function"==typeof this.settings.sort_filters)e.sort(this.settings.sort_filters);else{var r=this;e.sort(function(e,t){return r.translate(e.label).localeCompare(r.translate(t.label))})}return this.status.has_optgroup&&(e=h.groupSort(e,"optgroup")),e},c.prototype.checkOperators=function(r){var i=[];return r.forEach(function(e,t){"string"==typeof e?(c.OPERATORS[e]||h.error("Config",'Unknown operator "{0}"',e),r[t]=e=$.extendext(!0,"replace",{},c.OPERATORS[e])):(e.type||h.error("Config",'Missing "type" for operator {0}',t),c.OPERATORS[e.type]&&(r[t]=e=$.extendext(!0,"replace",{},c.OPERATORS[e.type],e)),void 0!==e.nb_inputs&&void 0!==e.apply_to||h.error("Config",'Missing "nb_inputs" and/or "apply_to" for operator "{0}"',e.type)),-1!=i.indexOf(e.type)&&h.error("Config",'Operator "{0}" already defined',e.type),i.push(e.type),e.optgroup?(this.status.has_operator_optgroup=!0,this.settings.optgroups[e.optgroup]||(this.settings.optgroups[e.optgroup]=e.optgroup)):e.optgroup=null},this),this.status.has_operator_optgroup&&(r=h.groupSort(r,"optgroup")),r},c.prototype.bindEvents=function(){var n=this,t=c.selectors;this.$el.on("change.queryBuilder",t.group_condition,function(){if($(this).is(":checked")){var e=$(this).closest(t.group_container);n.getModel(e).condition=$(this).val()}}),this.$el.on("change.queryBuilder",t.rule_filter,function(){var e=$(this).closest(t.rule_container);n.getModel(e).filter=n.getFilterById($(this).val())}),this.$el.on("change.queryBuilder",t.rule_operator,function(){var e=$(this).closest(t.rule_container);n.getModel(e).operator=n.getOperatorByType($(this).val())}),this.$el.on("click.queryBuilder",t.add_rule,function(){var e=$(this).closest(t.group_container);n.addRule(n.getModel(e))}),this.$el.on("click.queryBuilder",t.delete_rule,function(){var e=$(this).closest(t.rule_container);n.deleteRule(n.getModel(e))}),0!==this.settings.allow_groups&&(this.$el.on("click.queryBuilder",t.add_group,function(){var e=$(this).closest(t.group_container);n.addGroup(n.getModel(e))}),this.$el.on("click.queryBuilder",t.delete_group,function(){var e=$(this).closest(t.group_container);n.deleteGroup(n.getModel(e))})),this.model.on({drop:function(e,t){t.$el.remove(),n.refreshGroupsConditions()},add:function(e,t,r,i){0===i?r.$el.prependTo(t.$el.find(">"+c.selectors.rules_list)):r.$el.insertAfter(t.rules[i-1].$el),n.refreshGroupsConditions()},move:function(e,t,r,i){t.$el.detach(),0===i?t.$el.prependTo(r.$el.find(">"+c.selectors.rules_list)):t.$el.insertAfter(r.rules[i-1].$el),n.refreshGroupsConditions()},update:function(e,t,r,i,o){if(t instanceof l)switch(r){case"error":n.updateError(t);break;case"flags":n.applyRuleFlags(t);break;case"filter":n.updateRuleFilter(t,o);break;case"operator":n.updateRuleOperator(t,o);break;case"value":n.updateRuleValue(t,o)}else switch(r){case"error":n.updateError(t);break;case"flags":n.applyGroupFlags(t);break;case"condition":n.updateGroupCondition(t,o)}}})},c.prototype.setRoot=function(e,t,r){e=void 0===e||!0===e;var i=this.nextGroupId(),o=$(this.getGroupTemplate(i,1));return this.$el.append(o),this.model.root=new a(null,o),this.model.root.model=this.model,this.model.root.data=t,this.model.root.flags=$.extend({},this.settings.default_group_flags,r),this.model.root.condition=this.settings.default_condition,this.trigger("afterAddGroup",this.model.root),e&&this.addRule(this.model.root),this.model.root},c.prototype.addGroup=function(e,t,r,i){t=void 0===t||!0===t;var o=e.level+1;if(this.trigger("beforeAddGroup",e,t,o).isDefaultPrevented())return null;var n=this.nextGroupId(),l=$(this.getGroupTemplate(n,o)),s=e.addGroup(l);return s.data=r,s.flags=$.extend({},this.settings.default_group_flags,i),s.condition=this.settings.default_condition,this.trigger("afterAddGroup",s),this.trigger("rulesChanged"),t&&this.addRule(s),s},c.prototype.deleteGroup=function(e){if(e.isRoot())return!1;if(this.trigger("beforeDeleteGroup",e).isDefaultPrevented())return!1;var t=!0;return e.each("reverse",function(e){t&=this.deleteRule(e)},function(e){t&=this.deleteGroup(e)},this),t&&(e.drop(),this.trigger("afterDeleteGroup"),this.trigger("rulesChanged")),t},c.prototype.updateGroupCondition=function(t,e){t.$el.find(">"+c.selectors.group_condition).each(function(){var e=$(this);e.prop("checked",e.val()===t.condition),e.parent().toggleClass("active",e.val()===t.condition)}),this.trigger("afterUpdateGroupCondition",t,e),this.trigger("rulesChanged")},c.prototype.refreshGroupsConditions=function(){!function t(e){(!e.flags||e.flags&&!e.flags.condition_readonly)&&e.$el.find(">"+c.selectors.group_condition).prop("disabled",e.rules.length<=1).parent().toggleClass("disabled",e.rules.length<=1),e.each(null,function(e){t(e)},this)}(this.model.root)},c.prototype.addRule=function(e,t,r){if(this.trigger("beforeAddRule",e).isDefaultPrevented())return null;var i=this.nextRuleId(),o=$(this.getRuleTemplate(i)),n=e.addRule(o);return n.data=t,n.flags=$.extend({},this.settings.default_rule_flags,r),this.trigger("afterAddRule",n),this.trigger("rulesChanged"),this.createRuleFilters(n),!this.settings.default_filter&&this.settings.display_empty_filter||(n.filter=this.change("getDefaultFilter",this.getFilterById(this.settings.default_filter||this.filters[0].id),n)),n},c.prototype.deleteRule=function(e){return!e.flags.no_delete&&(!this.trigger("beforeDeleteRule",e).isDefaultPrevented()&&(e.drop(),this.trigger("afterDeleteRule"),this.trigger("rulesChanged"),!0))},c.prototype.createRuleFilters=function(e){var t=this.change("getRuleFilters",this.filters,e),r=$(this.getRuleFilterSelect(e,t));e.$el.find(c.selectors.filter_container).html(r),this.trigger("afterCreateRuleFilters",e),this.applyRuleFlags(e)},c.prototype.createRuleOperators=function(e){var t=e.$el.find(c.selectors.operator_container).empty();if(e.filter){var r=this.getOperators(e.filter),i=$(this.getRuleOperatorSelect(e,r));t.html(i),e.filter.default_operator?e.__.operator=this.getOperatorByType(e.filter.default_operator):e.__.operator=r[0],e.$el.find(c.selectors.rule_operator).val(e.operator.type),this.trigger("afterCreateRuleOperators",e,r),this.applyRuleFlags(e)}},c.prototype.createRuleInput=function(e){var t=e.$el.find(c.selectors.value_container).empty();if(e.__.value=void 0,e.filter&&e.operator&&0!==e.operator.nb_inputs){for(var r=this,i=$(),o=e.filter,n=0;n"+r.group_condition).prop("disabled",t.condition_readonly).parent().toggleClass("readonly",t.condition_readonly),t.no_add_rule&&e.$el.find(r.add_rule).remove(),t.no_add_group&&e.$el.find(r.add_group).remove(),t.no_delete&&e.$el.find(r.delete_group).remove(),this.trigger("afterApplyGroupFlags",e)},c.prototype.clearErrors=function(e){(e=e||this.model.root)&&(e.error=null,e instanceof a&&e.each(function(e){e.error=null},function(e){this.clearErrors(e)},this))},c.prototype.updateError=function(e){if(this.settings.display_errors)if(null===e.error)e.$el.removeClass("has-error");else{var t=this.translate("errors",e.error[0]);t=h.fmt(t,e.error.slice(1)),t=this.change("displayError",t,e.error,e),e.$el.addClass("has-error").find(c.selectors.error_container).eq(0).attr("data-tooltip",t)}},c.prototype.triggerValidationError=function(e,t,r){$.isArray(t)||(t=[t]),this.trigger("validationError",e,t,r).isDefaultPrevented()||(e.error=t)},c.prototype.destroy=function(){this.trigger("beforeDestroy"),this.status.generated_id&&this.$el.removeAttr("id"),this.clear(),this.model=null,this.$el.off(".queryBuilder").removeClass("query-builder").removeData("queryBuilder"),delete this.$el[0].queryBuilder},c.prototype.reset=function(){this.trigger("beforeReset").isDefaultPrevented()||(this.status.group_id=1,this.status.rule_id=0,this.model.root.empty(),this.model.root.data=void 0,this.model.root.flags=$.extend({},this.settings.default_group_flags),this.model.root.condition=this.settings.default_condition,this.addRule(this.model.root),this.trigger("afterReset"),this.trigger("rulesChanged"))},c.prototype.clear=function(){this.trigger("beforeClear").isDefaultPrevented()||(this.status.group_id=0,this.status.rule_id=0,this.model.root&&(this.model.root.drop(),this.model.root=null),this.trigger("afterClear"),this.trigger("rulesChanged"))},c.prototype.setOptions=function(e){$.each(e,function(e,t){-1!==c.modifiable_options.indexOf(e)&&(this.settings[e]=t)}.bind(this))},c.prototype.getModel=function(e){return e?e instanceof o?e:$(e).data("queryBuilderModel"):this.model.root},c.prototype.validate=function(n){n=$.extend({skip_empty:!1},n),this.clearErrors();var l=this,e=function r(e){var i=0,o=0;return e.each(function(e){if(e.filter||!n.skip_empty){if(!e.filter)return l.triggerValidationError(e,"no_filter",null),void o++;if(!e.operator)return l.triggerValidationError(e,"no_operator",null),void o++;if(0!==e.operator.nb_inputs){var t=l.validateValue(e,e.value);if(!0!==t)return l.triggerValidationError(e,t,e.value),void o++}i++}},function(e){var t=r(e);!0===t?i++:!1===t&&o++}),!(0parseInt(l.max)){s=[this.getValidationMessage(l,"max","string_exceed_max_length"),l.max];break}if(!l.format||("string"==typeof l.format&&(l.format=new RegExp(l.format)),l.format.test(i[u])))break;s=[this.getValidationMessage(l,"format","string_invalid_format"),l.format];break;case"number":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["number_nan"]);break}if(isNaN(i[u])){s=["number_nan"];break}if("integer"==o.type){if(parseInt(i[u])!=i[u]){s=["number_not_integer"];break}}else if(parseFloat(i[u])!=i[u]){s=["number_not_double"];break}if(void 0!==l.min&&i[u]parseFloat(l.max)){s=[this.getValidationMessage(l,"max","number_exceed_max"),l.max];break}if(void 0!==l.step&&"any"!==l.step){var p=(i[u]/l.step).toPrecision(14);if(parseInt(p)!=p){s=[this.getValidationMessage(l,"step","number_wrong_step"),l.step];break}}break;case"datetime":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["datetime_empty"]);break}if(l.format){"moment"in window||h.error("MissingLibrary","MomentJS is required for Date/Time validation. Get it here http://momentjs.com");var d=moment(i[u],l.format);if(!d.isValid()){s=[this.getValidationMessage(l,"format","datetime_invalid"),l.format];break}if(l.min&&dmoment(l.max,l.format)){s=[this.getValidationMessage(l,"max","datetime_exceed_max"),l.max];break}}break;case"boolean":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["boolean_not_valid"]);break}if("true"!==(r=(""+i[u]).trim().toLowerCase())&&"false"!==r&&"1"!==r&&"0"!==r&&1!==i[u]&&0!==i[u]){s=["boolean_not_valid"];break}}if(!0!==s)break}}if(!0!==s)break}if(("between"===e.operator.type||"not_between"===e.operator.type)&&2===t.length)switch(c.types[o.type]){case"number":t[0]>t[1]&&(s=["number_between_invalid",t[0],t[1]]);break;case"datetime":l.format&&("moment"in window||h.error("MissingLibrary","MomentJS is required for Date/Time validation. Get it here http://momentjs.com"),moment(t[0],l.format).isAfter(moment(t[1],l.format))&&(s=["datetime_between_invalid",t[0],t[1]]))}return s},c.prototype.nextGroupId=function(){return this.status.id+"_group_"+this.status.group_id++},c.prototype.nextRuleId=function(){return this.status.id+"_rule_"+this.status.rule_id++},c.prototype.getOperators=function(r){"string"==typeof r&&(r=this.getFilterById(r));for(var e=[],t=0,i=this.operators.length;t ',c.templates.rule='
{{? it.settings.display_errors }}
{{?}}
',c.templates.filterSelect='{{ var optgroup = null; }} {{? it.settings.display_empty_filter }} {{= it.settings.select_placeholder }} {{?}} {{~ it.filters: filter }} {{? optgroup !== filter.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = filter.optgroup) !== null }} {{?}} {{?}} {{= it.translate(filter.label) }} {{~}} {{? optgroup !== null }} {{?}} ',c.templates.operatorSelect='{{? it.operators.length === 1 }} {{= it.translate("operators", it.operators[0].type) }} {{?}} {{ var optgroup = null; }} {{~ it.operators: operator }} {{? optgroup !== operator.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = operator.optgroup) !== null }} {{?}} {{?}} {{= it.translate("operators", operator.type) }} {{~}} {{? optgroup !== null }} {{?}} ',c.templates.ruleValueSelect='{{ var optgroup = null; }} {{? it.rule.filter.placeholder }} {{= it.rule.filter.placeholder }} {{?}} {{~ it.rule.filter.values: entry }} {{? optgroup !== entry.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = entry.optgroup) !== null }} {{?}} {{?}} {{= entry.label }} {{~}} {{? optgroup !== null }} {{?}} ',c.prototype.getGroupTemplate=function(e,t){var r=this.templates.group({builder:this,group_id:e,level:t,conditions:this.settings.conditions,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getGroupTemplate",r,t)},c.prototype.getRuleTemplate=function(e){var t=this.templates.rule({builder:this,rule_id:e,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleTemplate",t)},c.prototype.getRuleFilterSelect=function(e,t){var r=this.templates.filterSelect({builder:this,rule:e,filters:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleFilterSelect",r,e,t)},c.prototype.getRuleOperatorSelect=function(e,t){var r=this.templates.operatorSelect({builder:this,rule:e,operators:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleOperatorSelect",r,e,t)},c.prototype.getRuleValueSelect=function(e,t){var r=this.templates.ruleValueSelect({builder:this,name:e,rule:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleValueSelect",r,e,t)},c.prototype.getRuleInput=function(e,t){var r=e.filter,i=e.filter.validation||{},o=e.id+"_value_"+t,n=r.vertical?" class=block":"",l="",s=Array.isArray(r.placeholder)?r.placeholder[t]:r.placeholder;if("function"==typeof r.input)l=r.input.call(this,e,o);else switch(r.input){case"radio":case"checkbox":h.iterateOptions(r.values,function(e,t){l+=" '+t+" "});break;case"select":l=this.getRuleValueSelect(o,e);break;case"textarea":l+='";break;case"number":l+=' " ;break;default:l=' " }return this.change getRuleInput ,l,e,o)};var h="{};function" i(){this.root='null,this.$=$(this)}(c.utils=h).iterateOptions=function(e,r){e&&($.isArray(e)?e.forEach(function(e){$.isPlainObject(e)?"value"in' e?r(e.value,e.label||e.value,e.optgroup):$.each(e,function(e,t){return r(e,t),!1}):r(e,e)}):$.each(e,function(e,t){r(e,t)}))},h.fmt="function(e,r){return" Array.isArray(r)||(r="Array.prototype.slice.call(arguments,1)),e.replace(/{([0-9]+)}/g,function(e,t){return" r[parseInt(t)]})},h.error="function(){var" e='0,t="boolean"!=typeof' arguments[e]||arguments[e++],r="arguments[e++],i=arguments[e++],o=Array.isArray(arguments[e])?arguments[e]:Array.prototype.slice.call(arguments,e);if(t){var" n="new" Error(h.fmt(i,o));throw n.name='r+"Error",n.args=o,n}console.error(r+"Error:' +h.fmt(i,o))},h.changeType='function(e,t){if(""!==e&&void' 0='=e)switch(t){case"integer":return"string"!=typeof' e||/^-?\d+$/.test(e)?parseInt(e):e;case double :return string !="typeof" e||/^-?\d+\.?\d*$/.test(e)?parseFloat(e):e;case boolean :return string !="typeof" e||/^(0|1|true|false){1}$/i.test(e)?!0='==e||1===e||"true"===e.toLowerCase()||"1"===e:e;default:return' e}},h.escapeString='function(e){return"string"!=typeof' e?e:e.replace(/[\0\n\r\b \ ]/g,function(e){switch(e){case \0 :return \\0 ;case \n :return \\n ;case \r :return \\r ;case \b :return \\b ;default:return \ +e}}).replace(/\t/g \\t ).replace(/\x1a/g \\Z )},h.escapeRegExp="function(e){return" e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g \ )},h.escapeElementId="function(e){return" e?e.replace(/(\\)?([:.\[\],])/g,function(e,t,r){return t?e \ +r}):e},h.groupSort="function(e,r){var" i="[],o=[];return" e.forEach(function(e){var t;e[r]?-1="=(t=i.lastIndexOf(e[r]))?t=i.length:t++:t=i.length,i.splice(t,0,e[r]),o.splice(t,0,e)}),o},h.defineModelProperties=function(e,t){t.forEach(function(r){Object.defineProperty(e.prototype,r,{enumerable:!0,get:function(){return" this.__[r]},set:function(e){var t='null!==this.__[r]&&"object"==typeof' this.__[r]?$.extend({},this.__[r]):this.__[r];this.__[r='e,null!==this.model&&this.model.trigger("update",this,r,e,t)}})})},$.extend(i.prototype,{trigger:function(e){var' t="new" $.Event(e);return this.$.triggerHandler(t,Array.prototype.slice.call(arguments,1)),t},on:function(){return this.$.on.apply(this.$,Array.prototype.slice.call(arguments)),this},off:function(){return this.$.off.apply(this.$,Array.prototype.slice.call(arguments)),this},once:function(){return this.$.one.apply(this.$,Array.prototype.slice.call(arguments)),this}});var o="function(e,t){if(!(this" instanceof o))return new o(e,t);Object.defineProperty(this _ ,{value:{}}),t.data queryBuilderModel ,this),this.__.level="1,this.__.error=null,this.__.flags={},this.__.data=void" 0,this.$el='t,this.id=t[0].id,this.model=null,this.parent=e};h.defineModelProperties(o,["level","error","data","flags"]),Object.defineProperty(o.prototype,"parent",{enumerable:!0,get:function(){return' this.__.parent},set:function(e){this.__.parent="e,this.level=null===e?1:e.level+1,this.model=null===e?null:e.model}}),o.prototype.isRoot=function(){return" 1="==this.level},o.prototype.getPos=function(){return" this.isRoot()?-1:this.parent.getNodePos(this)},o.prototype.drop="function(){var" e='this.model;this.parent&&this.parent.removeNode(this),this.$el.removeData("queryBuilderModel"),null!==e&&e.trigger("drop",this)},o.prototype.moveAfter=function(e){this.isRoot()||this.move(e.parent,e.getPos()+1)},o.prototype.moveAtBegin=function(e){this.isRoot()||(void' 0="==e&&(e=this.parent),this.move(e,0))},o.prototype.moveAtEnd=function(e){this.isRoot()||(void" 0='==e&&(e=this.parent),this.move(e,0===e.length()?0:e.length()-1))},o.prototype.move=function(e,t){this.isRoot()||("number"==typeof' e&&(t='e,e=this.parent),this.parent.removeNode(this),e.insertNode(this,t,!1),null!==this.model&&this.model.trigger("move",this,e,t))};var' a="function(e,t){if(!(this" instanceof a))return new a(e,t);o.call(this,e,t),this.rules='[],this.__.condition=null};a.prototype=Object.create(o.prototype),a.prototype.constructor=a,h.defineModelProperties(a,["condition"]),a.prototype.empty=function(){this.each("reverse",function(e){e.drop()},function(e){e.drop()})},a.prototype.drop=function(){this.empty(),o.prototype.drop.call(this)},a.prototype.length=function(){return' this.rules.length},a.prototype.insertNode="function(e,t,r){return" void 0='==t&&(t=this.length()),this.rules.splice(t,0,e),e.parent=this,r&&null!==this.model&&this.model.trigger("add",this,e,t),e},a.prototype.addGroup=function(e,t){return' this.insertNode(new a(this,e),t,!0)},a.prototype.addRule="function(e,t){return" this.insertNode(new l(this,e),t,!0)},a.prototype.removeNode="function(e){var" t="this.getNodePos(e);-1!==t&&(e.parent=null,this.rules.splice(t,1))},a.prototype.getNodePos=function(e){return" this.rules.indexOf(e)},a.prototype.each='function(e,t,r,i){"boolean"!=typeof' e string !="typeof" e&&(i="r,r=t,t=e,e=!1),i=void" 0="==i?null:i;for(var" o="e?this.rules.length-1:0,n=e?0:this.rules.length-1,l=e?-1:1,s=!1;(e?n<=o:o<=n)&&(this.rules[o]instanceof" a?r&&(s="!1===r.call(i,this.rules[o])):t&&(s=!1===t.call(i,this.rules[o])),!s);o+=l);return!s},a.prototype.contains=function(t,e){return-1!==this.getNodePos(t)||!!e&&!this.each(function(){return!0},function(e){return!e.contains(t,!0)})};var" l="function(e,t){if(!(this" instanceof l))return new l(e,t);o.call(this,e,t),this._updating_value="!1,this._updating_input=!1,this.__.filter=null,this.__.operator=null,this.__.value=void" 0};function u(e,t,r){var i,o,n='c.selectors;(i=t.closest(n.rule_container)).length&&(o="moveAfter"),o||(i=t.closest(n.group_header)).length&&(i=t.closest(n.group_container),o="moveAtBegin"),o||(i=t.closest(n.group_container)).length&&(o="moveAtEnd"),o&&(e[o](r.getModel(i)),r&&e' instanceof l&&r.setRuleInputValue(e,e.value))}function n(e){var t="e.match(/(question_mark|numbered|named)(?:\((.)\))?/);return" t||(t='[null,"question_mark",void' 0]),t}return l.prototype='Object.create(o.prototype),l.prototype.constructor=l,h.defineModelProperties(l,["filter","operator","value"]),l.prototype.isRoot=function(){return!1},c.Group=a,c.Rule=l,$.fn.queryBuilder=function(e){0===this.length&&h.error("Config","No' target defined ),1> '+t+" "})}})},{font:"glyphicons",color:"default"}),c.define("bt-selectpicker",function(r){$.fn.selectpicker&&$.fn.selectpicker.Constructor||h.error("MissingLibrary",'Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select');var i=c.selectors;this.on("afterCreateRuleFilters",function(e,t){t.$el.find(i.rule_filter).removeClass("form-control").selectpicker(r)}),this.on("afterCreateRuleOperators",function(e,t){t.$el.find(i.rule_operator).removeClass("form-control").selectpicker(r)}),this.on("afterUpdateRuleFilter",function(e,t){t.$el.find(i.rule_filter).selectpicker("render")}),this.on("afterUpdateRuleOperator",function(e,t){t.$el.find(i.rule_operator).selectpicker("render")}),this.on("beforeDeleteRule",function(e,t){t.$el.find(i.rule_filter).selectpicker("destroy"),t.$el.find(i.rule_operator).selectpicker("destroy")})},{container:"body",style:"btn-inverse btn-xs",width:"auto",showIcon:!1}),c.define("bt-tooltip-errors",function(i){$.fn.tooltip&&$.fn.tooltip.Constructor&&$.fn.tooltip.Constructor.prototype.fixTitle||h.error("MissingLibrary",'Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com');var o=this;this.on("getRuleTemplate.filter getGroupTemplate.filter",function(e){var t=$(e.value);t.find(c.selectors.error_container).attr("data-toggle","tooltip"),e.value=t.prop("outerHTML")}),this.model.on("update",function(e,t,r){"error"==r&&o.settings.display_errors&&t.$el.find(c.selectors.error_container).eq(0).tooltip(i).tooltip("hide").tooltip("fixTitle")})},{placement:"right"}),c.extend({setFilters:function(e,t){var r=this;void 0===t&&(t=e,e=!1),t=this.checkFilters(t);var i=(t=this.change("setFilters",t)).map(function(e){return e.id});if(e||function e(t){t.each(function(e){e.filter&&-1===i.indexOf(e.filter.id)&&h.error("ChangeFilter",'A rule is using filter "{0}"',e.filter.id)},e)}(this.model.root),this.filters=t,function e(t){t.each(!0,function(e){e.filter&&-1===i.indexOf(e.filter.id)?(e.drop(),r.trigger("rulesChanged")):(r.createRuleFilters(e),e.$el.find(c.selectors.rule_filter).val(e.filter?e.filter.id:"-1"),r.trigger("afterUpdateRuleFilter",e))},e)}(this.model.root),this.settings.plugins&&(this.settings.plugins["unique-filter"]&&this.updateDisabledFilters(),this.settings.plugins["bt-selectpicker"]&&this.$el.find(c.selectors.rule_filter).selectpicker("render")),this.settings.default_filter)try{this.getFilterById(this.settings.default_filter)}catch(e){this.settings.default_filter=null}this.trigger("afterSetFilters",t)},addFilter:function(e,r){void 0===r||"#end"==r?r=this.filters.length:"#start"==r&&(r=0),$.isArray(e)||(e=[e]);var t=$.extend(!0,[],this.filters);parseInt(r)==r?Array.prototype.splice.apply(t,[r,0].concat(e)):this.filters.some(function(e,t){if(e.id==r)return r=t+1,!0})?Array.prototype.splice.apply(t,[r,0].concat(e)):Array.prototype.push.apply(t,e),this.setFilters(t)},removeFilter:function(t,e){var r=$.extend(!0,[],this.filters);"string"==typeof t&&(t=[t]),r=r.filter(function(e){return-1===t.indexOf(e.id)}),this.setFilters(e,r)}}),c.define("chosen-selectpicker",function(r){$.fn.chosen||h.error("MissingLibrary",'chosen is required to use "chosen-selectpicker" plugin. Get it here: https://github.com/harvesthq/chosen'),this.settings.plugins["bt-selectpicker"]&&h.error("Conflict","bt-selectpicker is already selected as the dropdown plugin. Please remove chosen-selectpicker from the plugin list");var i=c.selectors;this.on("afterCreateRuleFilters",function(e,t){t.$el.find(i.rule_filter).removeClass("form-control").chosen(r)}),this.on("afterCreateRuleOperators",function(e,t){1
')).appendTo(t.$el):r.css("display",""),r.html(' '+i)):r.hide()}):"popover"===o.mode?($.fn.popover&&$.fn.popover.Constructor&&$.fn.popover.Constructor.prototype.fixTitle||h.error("MissingLibrary",'Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com'),this.on("afterUpdateRuleFilter afterUpdateRuleOperator",function(e,t){var r=t.$el.find("button.filter-description"),i=e.builder.getFilterDescription(t.filter,t);i?(0===r.length?((r=$(' ')).prependTo(t.$el.find(c.selectors.rule_actions)),r.popover({placement:"left",container:"body",html:!0}),r.on("mouseout",function(){r.popover("hide")})):r.css("display",""),r.data("bs.popover").options.content=i,r.attr("aria-describedby")&&r.popover("show")):(r.hide(),r.data("bs.popover")&&r.popover("hide"))})):"bootbox"===o.mode&&("bootbox"in window||h.error("MissingLibrary",'Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com'),this.on("afterUpdateRuleFilter afterUpdateRuleOperator",function(e,t){var r=t.$el.find("button.filter-description"),i=e.builder.getFilterDescription(t.filter,t);i?(0===r.length?((r=$(' ')).prependTo(t.$el.find(c.selectors.rule_actions)),r.on("click",function(){bootbox.alert(r.data("description"))})):r.css("display",""),r.data("description",i)):r.hide()}))},{icon:"glyphicon glyphicon-info-sign",mode:"popover"}),c.extend({getFilterDescription:function(e,t){return e?"function"==typeof e.description?e.description.call(this,t):e.description:void 0}}),c.define("invert",function(r){var i=this,o=c.selectors;this.on("afterInit",function(){i.$el.on("click.queryBuilder","[data-invert=group]",function(){var e=$(this).closest(o.group_container);i.invert(i.getModel(e),r)}),r.display_rules_button&&r.invert_rules&&i.$el.on("click.queryBuilder","[data-invert=rule]",function(){var e=$(this).closest(o.rule_container);i.invert(i.getModel(e),r)})}),r.disable_template||(this.on("getGroupTemplate.filter",function(e){var t=$(e.value);t.find(o.condition_container).after(' '+i.translate("invert")+" "),e.value=t.prop("outerHTML")}),r.display_rules_button&&r.invert_rules&&this.on("getRuleTemplate.filter",function(e){var t=$(e.value);t.find(o.rule_actions).prepend(' '+i.translate("invert")+" "),e.value=t.prop("outerHTML")}))},{icon:"glyphicon glyphicon-random",recursive:!0,invert_rules:!0,display_rules_button:!1,silent_fail:!1,disable_template:!1}),c.defaults({operatorOpposites:{equal:"not_equal",not_equal:"equal",in:"not_in",not_in:"in",less:"greater_or_equal",less_or_equal:"greater",greater:"less_or_equal",greater_or_equal:"less",between:"not_between",not_between:"between",begins_with:"not_begins_with",not_begins_with:"begins_with",contains:"not_contains",not_contains:"contains",ends_with:"not_ends_with",not_ends_with:"ends_with",is_empty:"is_not_empty",is_not_empty:"is_empty",is_null:"is_not_null",is_not_null:"is_null"},conditionOpposites:{AND:"OR",OR:"AND"}}),c.extend({invert:function(e,t){if(!(e instanceof o)){if(!this.model.root)return;t=e,e=this.model.root}if("object"!=typeof t&&(t={}),void 0===t.recursive&&(t.recursive=!0),void 0===t.invert_rules&&(t.invert_rules=!0),void 0===t.silent_fail&&(t.silent_fail=!1),void 0===t.trigger&&(t.trigger=!0),e instanceof a){if(this.settings.conditionOpposites[e.condition]?e.condition=this.settings.conditionOpposites[e.condition]:t.silent_fail||h.error("InvertCondition",'Unknown inverse of condition "{0}"',e.condition),t.recursive){var r=$.extend({},t,{trigger:!1});e.each(function(e){t.invert_rules&&this.invert(e,r)},function(e){this.invert(e,r)},this)}}else if(e instanceof l&&e.operator&&!e.filter.no_invert)if(this.settings.operatorOpposites[e.operator.type]){var i=this.settings.operatorOpposites[e.operator.type];e.filter.operators&&-1==e.filter.operators.indexOf(i)||(e.operator=this.getOperatorByType(i))}else t.silent_fail||h.error("InvertOperator",'Unknown inverse of operator "{0}"',e.operator.type);t.trigger&&(this.trigger("afterInvert",e,t),this.trigger("rulesChanged"))}}),c.defaults({mongoOperators:{equal:function(e){return e[0]},not_equal:function(e){return{$ne:e[0]}},in:function(e){return{$in:e}},not_in:function(e){return{$nin:e}},less:function(e){return{$lt:e[0]}},less_or_equal:function(e){return{$lte:e[0]}},greater:function(e){return{$gt:e[0]}},greater_or_equal:function(e){return{$gte:e[0]}},between:function(e){return{$gte:e[0],$lte:e[1]}},not_between:function(e){return{$lt:e[0],$gt:e[1]}},begins_with:function(e){return{$regex:"^"+h.escapeRegExp(e[0])}},not_begins_with:function(e){return{$regex:"^(?!"+h.escapeRegExp(e[0])+")"}},contains:function(e){return{$regex:h.escapeRegExp(e[0])}},not_contains:function(e){return{$regex:"^((?!"+h.escapeRegExp(e[0])+").)*$",$options:"s"}},ends_with:function(e){return{$regex:h.escapeRegExp(e[0])+"$"}},not_ends_with:function(e){return{$regex:"(? '+i.translate("NOT")+""),e.value=t.prop("outerHTML")}),this.on("groupToJson.filter",function(e,t){e.value.not=t.not}),this.on("jsonToGroup.filter",function(e,t){e.value.not=!!t.not}),this.on("groupToSQL.filter",function(e,t){t.not&&(e.value="NOT ( "+e.value+" )")}),this.on("parseSQLNode.filter",function(e){e.value.name&&"NOT"==e.value.name.toUpperCase()&&(e.value=e.value.arguments.value[0],-1===["AND","OR"].indexOf(e.value.operation.toUpperCase())&&(e.value=new SQLParser.nodes.Op(i.settings.default_condition,e.value,null)),e.value.not=!0)}),this.on("sqlGroupsDistinct.filter",function(e,t,r,i){r.not&&0"+c.selectors.group_not).toggleClass("active",e.not).find("i").attr("class",e.not?t.icon_checked:t.icon_unchecked),this.trigger("afterUpdateGroupNot",e),this.trigger("rulesChanged")}}),c.define("sortable",function(i){var o,n,l,s;"interact"in window||h.error("MissingLibrary",'interact.js is required to use "sortable" plugin. Get it here: http://interactjs.io'),void 0!==i.default_no_sortable&&(h.error(!1,"Config",'Sortable plugin : "default_no_sortable" options is deprecated, use standard "default_rule_flags" and "default_group_flags" instead'),this.settings.default_rule_flags.no_sortable=this.settings.default_group_flags.no_sortable=i.default_no_sortable),interact.dynamicDrop(!0),interact.pointerMoveTolerance(10),this.on("afterAddRule afterAddGroup",function(e,t){if(t!=o){var r=e.builder;i.inherit_no_sortable&&t.parent&&t.parent.flags.no_sortable&&(t.flags.no_sortable=!0),i.inherit_no_drop&&t.parent&&t.parent.flags.no_drop&&(t.flags.no_drop=!0),t.flags.no_sortable||interact(t.$el[0]).draggable({allowFrom:c.selectors.drag_handle,onstart:function(e){s=!1,l=r.getModel(e.target),n=l.$el.clone().appendTo(l.$el.parent()).width(l.$el.outerWidth()).addClass("dragging");var t=$('
').height(l.$el.outerHeight());o=l.parent.addRule(t,l.getPos()),l.$el.hide()},onmove:function(e){n[0].style.top=e.clientY-15+"px",n[0].style.left=e.clientX-15+"px"},onend:function(e){e.dropzone&&(u(l,$(e.relatedTarget),r),s=!0),n.remove(),n=void 0,o.drop(),o=void 0,l.$el.css("display",""),r.trigger("afterMove",l),r.trigger("rulesChanged")}}),t.flags.no_drop||(interact(t.$el[0]).dropzone({accept:c.selectors.rule_and_group_containers,ondragenter:function(e){u(o,$(e.target),r)},ondrop:function(e){s||u(l,$(e.target),r)}}),t instanceof a&&interact(t.$el.find(c.selectors.group_header)[0]).dropzone({accept:c.selectors.rule_and_group_containers,ondragenter:function(e){u(o,$(e.target),r)},ondrop:function(e){s||u(l,$(e.target),r)}}))}}),this.on("beforeDeleteRule beforeDeleteGroup",function(e,t){e.isDefaultPrevented()||(interact(t.$el[0]).unset(),t instanceof a&&interact(t.$el.find(c.selectors.group_header)[0]).unset())}),this.on("afterApplyRuleFlags afterApplyGroupFlags",function(e,t){t.flags.no_sortable&&t.$el.find(".drag-handle").remove()}),i.disable_template||(this.on("getGroupTemplate.filter",function(e,t){if(1 '),e.value=r.prop("outerHTML")}}),this.on("getRuleTemplate.filter",function(e){var t=$(e.value);t.find(c.selectors.rule_header).after('
'),e.value=t.prop("outerHTML")}))},{inherit_no_sortable:!0,inherit_no_drop:!0,icon:"glyphicon glyphicon-sort",disable_template:!1}),c.selectors.rule_and_group_containers=c.selectors.rule_container+", "+c.selectors.group_container,c.selectors.drag_handle=".drag-handle",c.defaults({default_rule_flags:{no_sortable:!1,no_drop:!1},default_group_flags:{no_sortable:!1,no_drop:!1}}),c.define("sql-support",function(e){},{boolean_as_integer:!0}),c.defaults({sqlOperators:{equal:{op:"= ?"},not_equal:{op:"!= ?"},in:{op:"IN(?)",sep:", "},not_in:{op:"NOT IN(?)",sep:", "},less:{op:"< ?"},less_or_equal:{op:"<= ?"},greater:{op:"> ?"},greater_or_equal:{op:">= ?"},between:{op:"BETWEEN ?",sep:" AND "},not_between:{op:"NOT BETWEEN ?",sep:" AND "},begins_with:{op:"LIKE(?)",mod:"{0}%"},not_begins_with:{op:"NOT LIKE(?)",mod:"{0}%"},contains:{op:"LIKE(?)",mod:"%{0}%"},not_contains:{op:"NOT LIKE(?)",mod:"%{0}%"},ends_with:{op:"LIKE(?)",mod:"%{0}"},not_ends_with:{op:"NOT LIKE(?)",mod:"%{0}"},is_empty:{op:"= ''"},is_not_empty:{op:"!= ''"},is_null:{op:"IS NULL"},is_not_null:{op:"IS NOT NULL"}},sqlRuleOperator:{"=":function(e){return{val:e,op:""===e?"is_empty":"equal"}},"!=":function(e){return{val:e,op:""===e?"is_not_empty":"not_equal"}},LIKE:function(e){return"%"==e.slice(0,1)&&"%"==e.slice(-1)?{val:e.slice(1,-1),op:"contains"}:"%"==e.slice(0,1)?{val:e.slice(1),op:"ends_with"}:"%"==e.slice(-1)?{val:e.slice(0,-1),op:"begins_with"}:void h.error("SQLParse",'Invalid value for LIKE operator "{0}"',e)},"NOT LIKE":function(e){return"%"==e.slice(0,1)&&"%"==e.slice(-1)?{val:e.slice(1,-1),op:"not_contains"}:"%"==e.slice(0,1)?{val:e.slice(1),op:"not_ends_with"}:"%"==e.slice(-1)?{val:e.slice(0,-1),op:"not_begins_with"}:void h.error("SQLParse",'Invalid value for NOT LIKE operator "{0}"',e)},IN:function(e){return{val:e,op:"in"}},"NOT IN":function(e){return{val:e,op:"not_in"}},"<":function(e){return{val:e,op:"less"}},"<=":function(e){return{val:e,op:"less_or_equal"}},">":function(e){return{val:e,op:"greater"}},">=":function(e){return{val:e,op:"greater_or_equal"}},BETWEEN:function(e){return{val:e,op:"between"}},"NOT BETWEEN":function(e){return{val:e,op:"not_between"}},IS:function(e){return null!==e&&h.error("SQLParse","Invalid value for IS operator"),{val:null,op:"is_null"}},"IS NOT":function(e){return null!==e&&h.error("SQLParse","Invalid value for IS operator"),{val:null,op:"is_not_null"}}},sqlStatements:{question_mark:function(){var r=[];return{add:function(e,t){return r.push(t),"?"},run:function(){return r}}},numbered:function(r){(!r||1"==l&&(l="!=");var s=f.settings.sqlRuleOperator[l];void 0===s&&h.error("UndefinedSQLOperator",'Invalid SQL operation "{0}".',t.operation);var a,u=s.call(this,n,t.operation);"values"in t.left?a=t.left.values.join("."):"value"in t.left?a=t.left.value:h.error("SQLParse","Cannot find field name in {0}",JSON.stringify(t.left));var p=f.getSQLFieldID(a,n),d=f.change("sqlToRule",{id:p,field:a,operator:u.op,value:u.val},t);g.rules.push(d)}}(i,0),o},setRulesFromSQL:function(e,t){this.setRules(this.getRulesFromSQL(e,t))},getSQLFieldID:function(t,e){var r=this.filters.filter(function(e){return e.field.toLowerCase()===t.toLowerCase()});return 1===r.length?r[0].id:this.change("getSQLFieldID",t,e)}}),c.define("unique-filter",function(){this.status.used_filters={},this.on("afterUpdateRuleFilter",this.updateDisabledFilters),this.on("afterDeleteRule",this.updateDisabledFilters),this.on("afterCreateRuleFilters",this.applyDisabledFilters),this.on("afterReset",this.clearDisabledFilters),this.on("afterClear",this.clearDisabledFilters),this.on("getDefaultFilter.filter",function(t,r){var i=t.builder;(i.updateDisabledFilters(),t.value.id in i.status.used_filters)&&(i.filters.some(function(e){if(!(e.id in i.status.used_filters)||0 <","<=",">",">=","BETWEEN","NOT BETWEEN","IS","IS NOT","sqlStatements","question_mark","params","run","numbered","char","named","indexes","sqlRuleStatement","esc","sql","regex1","regex2","getSQL","nl","sqlFn","getRulesFromSQL","parsed","where","curr","flatten","next","right","sqlrl","JSON","stringify","getSQLFieldID","setRulesFromSQL","used_filters","applyDisabledFilters","clearDisabledFilters","unique","filterId","groups","__locale","__author","no_filter","empty_group","radio_empty","checkbox_empty","select_empty","string_empty","string_exceed_min_length","string_exceed_max_length","string_invalid_format","number_nan","number_not_integer","number_not_double","number_exceed_min","number_exceed_max","number_wrong_step","number_between_invalid","datetime_empty","datetime_invalid","datetime_exceed_min","datetime_exceed_max","datetime_between_invalid","boolean_not_valid","operator_not_multiple","NOT"],"mappings":"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","file":"query-builder.min.js"}
\ No newline at end of file
diff --git a/dist/js/query-builder.standalone.js b/dist/js/query-builder.standalone.js
new file mode 100644
index 00000000..99ec0bb0
--- /dev/null
+++ b/dist/js/query-builder.standalone.js
@@ -0,0 +1,6507 @@
+/*!
+ * jQuery.extendext 0.1.2
+ *
+ * Copyright 2014-2016 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (http://opensource.org/licenses/MIT)
+ *
+ * Based on jQuery.extend by jQuery Foundation, Inc. and other contributors
+ */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define('jQuery.extendext', ['jquery'], factory);
+ }
+ else if (typeof module === 'object' && module.exports) {
+ module.exports = factory(require('jquery'));
+ }
+ else {
+ factory(root.jQuery);
+ }
+}(this, function ($) {
+ "use strict";
+
+ $.extendext = function () {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false,
+ arrayMode = 'default';
+
+ // Handle a deep copy situation
+ if (typeof target === "boolean") {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[i++] || {};
+ }
+
+ // Handle array mode parameter
+ if (typeof target === "string") {
+ arrayMode = target.toLowerCase();
+ if (arrayMode !== 'concat' && arrayMode !== 'replace' && arrayMode !== 'extend') {
+ arrayMode = 'default';
+ }
+
+ // Skip the string param
+ target = arguments[i++] || {};
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if (typeof target !== "object" && !$.isFunction(target)) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if (i === length) {
+ target = this;
+ i--;
+ }
+
+ for (; i < length; i++) {
+ // Only deal with non-null/undefined values
+ if ((options = arguments[i]) !== null) {
+ // Special operations for arrays
+ if ($.isArray(options) && arrayMode !== 'default') {
+ clone = target && $.isArray(target) ? target : [];
+
+ switch (arrayMode) {
+ case 'concat':
+ target = clone.concat($.extend(deep, [], options));
+ break;
+
+ case 'replace':
+ target = $.extend(deep, [], options);
+ break;
+
+ case 'extend':
+ options.forEach(function (e, i) {
+ if (typeof e === 'object') {
+ var type = $.isArray(e) ? [] : {};
+ clone[i] = $.extendext(deep, arrayMode, clone[i] || type, e);
+
+ } else if (clone.indexOf(e) === -1) {
+ clone.push(e);
+ }
+ });
+
+ target = clone;
+ break;
+ }
+
+ } else {
+ // Extend the base object
+ for (name in options) {
+ src = target[name];
+ copy = options[name];
+
+ // Prevent never-ending loop
+ if (target === copy) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if (deep && copy && ( $.isPlainObject(copy) ||
+ (copyIsArray = $.isArray(copy)) )) {
+
+ if (copyIsArray) {
+ copyIsArray = false;
+ clone = src && $.isArray(src) ? src : [];
+
+ } else {
+ clone = src && $.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[name] = $.extendext(deep, arrayMode, clone, copy);
+
+ // Don't bring in undefined values
+ } else if (copy !== undefined) {
+ target[name] = copy;
+ }
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+ };
+}));
+
+// doT.js
+// 2011-2014, Laura Doktorova, https://github.com/olado/doT
+// Licensed under the MIT license.
+
+(function () {
+ "use strict";
+
+ var doT = {
+ name: "doT",
+ version: "1.1.1",
+ templateSettings: {
+ evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
+ interpolate: /\{\{=([\s\S]+?)\}\}/g,
+ encode: /\{\{!([\s\S]+?)\}\}/g,
+ use: /\{\{#([\s\S]+?)\}\}/g,
+ useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
+ define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
+ defineParams:/^\s*([\w$]+):([\s\S]+)/,
+ conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
+ iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
+ varname: "it",
+ strip: true,
+ append: true,
+ selfcontained: false,
+ doNotSkipEncoded: false
+ },
+ template: undefined, //fn, compile template
+ compile: undefined, //fn, for express
+ log: true
+ }, _globals;
+
+ doT.encodeHTMLSource = function(doNotSkipEncoded) {
+ var encodeHTMLRules = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'", "/": "/" },
+ matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g;
+ return function(code) {
+ return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : "";
+ };
+ };
+
+ _globals = (function(){ return this || (0,eval)("this"); }());
+
+ /* istanbul ignore else */
+ if (typeof module !== "undefined" && module.exports) {
+ module.exports = doT;
+ } else if (typeof define === "function" && define.amd) {
+ define('doT', function(){return doT;});
+ } else {
+ _globals.doT = doT;
+ }
+
+ var startend = {
+ append: { start: "'+(", end: ")+'", startencode: "'+encodeHTML(" },
+ split: { start: "';out+=(", end: ");out+='", startencode: "';out+=encodeHTML(" }
+ }, skip = /$^/;
+
+ function resolveDefs(c, block, def) {
+ return ((typeof block === "string") ? block : block.toString())
+ .replace(c.define || skip, function(m, code, assign, value) {
+ if (code.indexOf("def.") === 0) {
+ code = code.substring(4);
+ }
+ if (!(code in def)) {
+ if (assign === ":") {
+ if (c.defineParams) value.replace(c.defineParams, function(m, param, v) {
+ def[code] = {arg: param, text: v};
+ });
+ if (!(code in def)) def[code]= value;
+ } else {
+ new Function("def", "def['"+code+"']=" + value)(def);
+ }
+ }
+ return "";
+ })
+ .replace(c.use || skip, function(m, code) {
+ if (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
+ if (def[d] && def[d].arg && param) {
+ var rw = (d+":"+param).replace(/'|\\/g, "_");
+ def.__exp = def.__exp || {};
+ def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
+ return s + "def.__exp['"+rw+"']";
+ }
+ });
+ var v = new Function("def", "return " + code)(def);
+ return v ? resolveDefs(c, v, def) : v;
+ });
+ }
+
+ function unescape(code) {
+ return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, " ");
+ }
+
+ doT.template = function(tmpl, c, def) {
+ c = c || doT.templateSettings;
+ var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,
+ str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
+
+ str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ")
+ .replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""): str)
+ .replace(/'|\\/g, "\\$&")
+ .replace(c.interpolate || skip, function(m, code) {
+ return cse.start + unescape(code) + cse.end;
+ })
+ .replace(c.encode || skip, function(m, code) {
+ needhtmlencode = true;
+ return cse.startencode + unescape(code) + cse.end;
+ })
+ .replace(c.conditional || skip, function(m, elsecase, code) {
+ return elsecase ?
+ (code ? "';}else if(" + unescape(code) + "){out+='" : "';}else{out+='") :
+ (code ? "';if(" + unescape(code) + "){out+='" : "';}out+='");
+ })
+ .replace(c.iterate || skip, function(m, iterate, vname, iname) {
+ if (!iterate) return "';} } out+='";
+ sid+=1; indv=iname || "i"+sid; iterate=unescape(iterate);
+ return "';var arr"+sid+"="+iterate+";if(arr"+sid+"){var "+vname+","+indv+"=-1,l"+sid+"=arr"+sid+".length-1;while("+indv+"}
+ * @readonly
+ */
+ this.icons = this.settings.icons;
+
+ /**
+ * List of operators
+ * @member {QueryBuilder.Operator[]}
+ * @readonly
+ */
+ this.operators = this.settings.operators;
+
+ /**
+ * List of templates
+ * @member {object.}
+ * @readonly
+ */
+ this.templates = this.settings.templates;
+
+ /**
+ * Plugins configuration
+ * @member {object.}
+ * @readonly
+ */
+ this.plugins = this.settings.plugins;
+
+ /**
+ * Translations object
+ * @member {object}
+ * @readonly
+ */
+ this.lang = null;
+
+ // translations : english << 'lang_code' << custom
+ if (QueryBuilder.regional['en'] === undefined) {
+ Utils.error('Config', '"i18n/en.js" not loaded.');
+ }
+ this.lang = $.extendext(true, 'replace', {}, QueryBuilder.regional['en'], QueryBuilder.regional[this.settings.lang_code], this.settings.lang);
+
+ // "allow_groups" can be boolean or int
+ if (this.settings.allow_groups === false) {
+ this.settings.allow_groups = 0;
+ }
+ else if (this.settings.allow_groups === true) {
+ this.settings.allow_groups = -1;
+ }
+
+ // init templates
+ Object.keys(this.templates).forEach(function(tpl) {
+ if (!this.templates[tpl]) {
+ this.templates[tpl] = QueryBuilder.templates[tpl];
+ }
+ if (typeof this.templates[tpl] == 'string') {
+ this.templates[tpl] = doT.template(this.templates[tpl]);
+ }
+ }, this);
+
+ // ensure we have a container id
+ if (!this.$el.attr('id')) {
+ this.$el.attr('id', 'qb_' + Math.floor(Math.random() * 99999));
+ this.status.generated_id = true;
+ }
+ this.status.id = this.$el.attr('id');
+
+ // INIT
+ this.$el.addClass('query-builder form-inline');
+
+ this.filters = this.checkFilters(this.filters);
+ this.operators = this.checkOperators(this.operators);
+ this.bindEvents();
+ this.initPlugins();
+};
+
+$.extend(QueryBuilder.prototype, /** @lends QueryBuilder.prototype */ {
+ /**
+ * Triggers an event on the builder container
+ * @param {string} type
+ * @returns {$.Event}
+ */
+ trigger: function(type) {
+ var event = new $.Event(this._tojQueryEvent(type), {
+ builder: this
+ });
+
+ this.$el.triggerHandler(event, Array.prototype.slice.call(arguments, 1));
+
+ return event;
+ },
+
+ /**
+ * Triggers an event on the builder container and returns the modified value
+ * @param {string} type
+ * @param {*} value
+ * @returns {*}
+ */
+ change: function(type, value) {
+ var event = new $.Event(this._tojQueryEvent(type, true), {
+ builder: this,
+ value: value
+ });
+
+ this.$el.triggerHandler(event, Array.prototype.slice.call(arguments, 2));
+
+ return event.value;
+ },
+
+ /**
+ * Attaches an event listener on the builder container
+ * @param {string} type
+ * @param {function} cb
+ * @returns {QueryBuilder}
+ */
+ on: function(type, cb) {
+ this.$el.on(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Removes an event listener from the builder container
+ * @param {string} type
+ * @param {function} [cb]
+ * @returns {QueryBuilder}
+ */
+ off: function(type, cb) {
+ this.$el.off(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Attaches an event listener called once on the builder container
+ * @param {string} type
+ * @param {function} cb
+ * @returns {QueryBuilder}
+ */
+ once: function(type, cb) {
+ this.$el.one(this._tojQueryEvent(type), cb);
+ return this;
+ },
+
+ /**
+ * Appends `.queryBuilder` and optionally `.filter` to the events names
+ * @param {string} name
+ * @param {boolean} [filter=false]
+ * @returns {string}
+ * @private
+ */
+ _tojQueryEvent: function(name, filter) {
+ return name.split(' ').map(function(type) {
+ return type + '.queryBuilder' + (filter ? '.filter' : '');
+ }).join(' ');
+ }
+});
+
+
+/**
+ * Allowed types and their internal representation
+ * @type {object.}
+ * @readonly
+ * @private
+ */
+QueryBuilder.types = {
+ 'string': 'string',
+ 'integer': 'number',
+ 'double': 'number',
+ 'date': 'datetime',
+ 'time': 'datetime',
+ 'datetime': 'datetime',
+ 'boolean': 'boolean'
+};
+
+/**
+* Allowed inputs
+* @type {string[]}
+* @readonly
+* @private
+*/
+QueryBuilder.inputs = [
+ 'text',
+ 'number',
+ 'textarea',
+ 'radio',
+ 'checkbox',
+ 'select'
+];
+
+/**
+* Runtime modifiable options with `setOptions` method
+* @type {string[]}
+* @readonly
+* @private
+*/
+QueryBuilder.modifiable_options = [
+ 'display_errors',
+ 'allow_groups',
+ 'allow_empty',
+ 'default_condition',
+ 'default_filter'
+];
+
+/**
+* CSS selectors for common components
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.selectors = {
+ group_container: '.rules-group-container',
+ rule_container: '.rule-container',
+ filter_container: '.rule-filter-container',
+ operator_container: '.rule-operator-container',
+ value_container: '.rule-value-container',
+ error_container: '.error-container',
+ condition_container: '.rules-group-header .group-conditions',
+ tooltip: '.tooltip-container',
+ description: '.description-container',
+
+ rule_header: '.rule-header',
+ group_header: '.rules-group-header',
+ group_actions: '.group-actions',
+ rule_actions: '.rule-actions',
+
+ rules_list: '.rules-group-body>.rules-list',
+
+ group_condition: '.rules-group-header [name$=_cond]',
+ rule_filter: '.rule-filter-container [name$=_filter]',
+ rule_operator: '.rule-operator-container [name$=_operator]',
+ rule_value: '.rule-value-container [name*=_value_]',
+
+ add_rule: '[data-add=rule]',
+ delete_rule: '[data-delete=rule]',
+ add_group: '[data-add=group]',
+ delete_group: '[data-delete=group]'
+};
+
+/**
+* Template strings (see template.js)
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.templates = {};
+
+/**
+* Localized strings (see i18n/)
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.regional = {};
+
+/**
+* Default operators
+* @type {object.}
+* @readonly
+*/
+QueryBuilder.OPERATORS = {
+ equal: { type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ not_equal: { type: 'not_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ in: { type: 'in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ not_in: { type: 'not_in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ less: { type: 'less', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ less_or_equal: { type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater: { type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater_or_equal: { type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ between: { type: 'between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ not_between: { type: 'not_between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ begins_with: { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_begins_with: { type: 'not_begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ contains: { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_contains: { type: 'not_contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ ends_with: { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_ends_with: { type: 'not_ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ is_empty: { type: 'is_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_not_empty: { type: 'is_not_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_null: { type: 'is_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ is_not_null: { type: 'is_not_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] }
+};
+
+/**
+* Default configuration
+* @type {object}
+* @readonly
+*/
+QueryBuilder.DEFAULTS = {
+ filters: [],
+ plugins: [],
+
+ sort_filters: false,
+ display_errors: true,
+ allow_groups: -1,
+ allow_empty: false,
+ conditions: ['AND', 'OR'],
+ default_condition: 'AND',
+ inputs_separator: " AND ",
+ select_placeholder: '------',
+ display_empty_filter: true,
+ default_filter: null,
+ optgroups: {},
+
+ default_rule_flags: {
+ filter_readonly: false,
+ operator_readonly: false,
+ value_readonly: false,
+ no_delete: false
+ },
+
+ default_group_flags: {
+ condition_readonly: false,
+ no_add_rule: false,
+ no_add_group: false,
+ no_delete: false
+ },
+
+ templates: {
+ group: null,
+ rule: null,
+ filterSelect: null,
+ operatorSelect: null,
+ ruleValueSelect: null
+ },
+
+ lang_code: 'en',
+ lang: {},
+
+ operators: [
+ 'equal',
+ 'not_equal',
+ 'in',
+ 'not_in',
+ 'less',
+ 'less_or_equal',
+ 'greater',
+ 'greater_or_equal',
+ 'between',
+ 'not_between',
+ 'begins_with',
+ 'not_begins_with',
+ 'contains',
+ 'not_contains',
+ 'ends_with',
+ 'not_ends_with',
+ 'is_empty',
+ 'is_not_empty',
+ 'is_null',
+ 'is_not_null'
+ ],
+
+ icons: {
+ add_group: 'glyphicon glyphicon-plus-sign',
+ add_rule: 'glyphicon glyphicon-plus',
+ remove_group: 'glyphicon glyphicon-remove',
+ remove_rule: 'glyphicon glyphicon-remove',
+ error: 'glyphicon glyphicon-warning-sign',
+ tooltip: 'glyphicon glyphicon-info-sign',
+ }
+};
+
+
+/**
+ * @module plugins
+ */
+
+/**
+ * Definition of available plugins
+ * @type {object.}
+ */
+QueryBuilder.plugins = {};
+
+/**
+ * Gets or extends the default configuration
+ * @param {object} [options] - new configuration
+ * @returns {undefined|object} nothing or configuration object (copy)
+ */
+QueryBuilder.defaults = function(options) {
+ if (typeof options == 'object') {
+ $.extendext(true, 'replace', QueryBuilder.DEFAULTS, options);
+ }
+ else if (typeof options == 'string') {
+ if (typeof QueryBuilder.DEFAULTS[options] == 'object') {
+ return $.extend(true, {}, QueryBuilder.DEFAULTS[options]);
+ }
+ else {
+ return QueryBuilder.DEFAULTS[options];
+ }
+ }
+ else {
+ return $.extend(true, {}, QueryBuilder.DEFAULTS);
+ }
+};
+
+/**
+ * Registers a new plugin
+ * @param {string} name
+ * @param {function} fct - init function
+ * @param {object} [def] - default options
+ */
+QueryBuilder.define = function(name, fct, def) {
+ QueryBuilder.plugins[name] = {
+ fct: fct,
+ def: def || {}
+ };
+};
+
+/**
+ * Adds new methods to QueryBuilder prototype
+ * @param {object.} methods
+ */
+QueryBuilder.extend = function(methods) {
+ $.extend(QueryBuilder.prototype, methods);
+};
+
+/**
+ * Initializes plugins for an instance
+ * @throws ConfigError
+ * @private
+ */
+QueryBuilder.prototype.initPlugins = function() {
+ if (!this.plugins) {
+ return;
+ }
+
+ if ($.isArray(this.plugins)) {
+ var tmp = {};
+ this.plugins.forEach(function(plugin) {
+ tmp[plugin] = null;
+ });
+ this.plugins = tmp;
+ }
+
+ Object.keys(this.plugins).forEach(function(plugin) {
+ if (plugin in QueryBuilder.plugins) {
+ this.plugins[plugin] = $.extend(true, {},
+ QueryBuilder.plugins[plugin].def,
+ this.plugins[plugin] || {}
+ );
+
+ QueryBuilder.plugins[plugin].fct.call(this, this.plugins[plugin]);
+ }
+ else {
+ Utils.error('Config', 'Unable to find plugin "{0}"', plugin);
+ }
+ }, this);
+};
+
+/**
+ * Returns the config of a plugin, if the plugin is not loaded, returns the default config.
+ * @param {string} name
+ * @param {string} [property]
+ * @throws ConfigError
+ * @returns {*}
+ */
+QueryBuilder.prototype.getPluginOptions = function(name, property) {
+ var plugin;
+ if (this.plugins && this.plugins[name]) {
+ plugin = this.plugins[name];
+ }
+ else if (QueryBuilder.plugins[name]) {
+ plugin = QueryBuilder.plugins[name].def;
+ }
+
+ if (plugin) {
+ if (property) {
+ return plugin[property];
+ }
+ else {
+ return plugin;
+ }
+ }
+ else {
+ Utils.error('Config', 'Unable to find plugin "{0}"', name);
+ }
+};
+
+
+/**
+ * Final initialisation of the builder
+ * @param {object} [rules]
+ * @fires QueryBuilder.afterInit
+ * @private
+ */
+QueryBuilder.prototype.init = function(rules) {
+ /**
+ * When the initilization is done, just before creating the root group
+ * @event afterInit
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterInit');
+
+ if (rules) {
+ this.setRules(rules);
+ delete this.settings.rules;
+ }
+ else {
+ this.setRoot(true);
+ }
+};
+
+/**
+* Checks the configuration of each filter
+* @param {QueryBuilder.Filter[]} filters
+* @returns {QueryBuilder.Filter[]}
+* @throws ConfigError
+*/
+QueryBuilder.prototype.checkFilters = function(filters) {
+ var definedFilters = [];
+
+ if (!filters || filters.length === 0) {
+ Utils.error('Config', 'Missing filters list');
+ }
+
+ filters.forEach(function(filter, i) {
+ if (!filter.id) {
+ Utils.error('Config', 'Missing filter {0} id', i);
+ }
+ if (definedFilters.indexOf(filter.id) != -1) {
+ Utils.error('Config', 'Filter "{0}" already defined', filter.id);
+ }
+ definedFilters.push(filter.id);
+
+ if (!filter.type) {
+ filter.type = 'string';
+ }
+ else if (!QueryBuilder.types[filter.type]) {
+ Utils.error('Config', 'Invalid type "{0}"', filter.type);
+ }
+
+ if (!filter.input) {
+ filter.input = QueryBuilder.types[filter.type] === 'number' ? 'number' : 'text';
+ }
+ else if (typeof filter.input != 'function' && QueryBuilder.inputs.indexOf(filter.input) == -1) {
+ Utils.error('Config', 'Invalid input "{0}"', filter.input);
+ }
+
+ if (filter.operators) {
+ filter.operators.forEach(function(operator) {
+ if (typeof operator != 'string') {
+ Utils.error('Config', 'Filter operators must be global operators types (string)');
+ }
+ });
+ }
+
+ if (!filter.field) {
+ filter.field = filter.id;
+ }
+ if (!filter.label) {
+ filter.label = filter.field;
+ }
+
+ if (!filter.optgroup) {
+ filter.optgroup = null;
+ }
+ else {
+ this.status.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[filter.optgroup]) {
+ this.settings.optgroups[filter.optgroup] = filter.optgroup;
+ }
+ }
+
+ switch (filter.input) {
+ case 'radio':
+ case 'checkbox':
+ if (!filter.values || filter.values.length < 1) {
+ Utils.error('Config', 'Missing filter "{0}" values', filter.id);
+ }
+ break;
+
+ case 'select':
+ var cleanValues = [];
+ filter.has_optgroup = false;
+
+ Utils.iterateOptions(filter.values, function(value, label, optgroup) {
+ cleanValues.push({
+ value: value,
+ label: label,
+ optgroup: optgroup || null
+ });
+
+ if (optgroup) {
+ filter.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[optgroup]) {
+ this.settings.optgroups[optgroup] = optgroup;
+ }
+ }
+ }.bind(this));
+
+ if (filter.has_optgroup) {
+ filter.values = Utils.groupSort(cleanValues, 'optgroup');
+ }
+ else {
+ filter.values = cleanValues;
+ }
+
+ if (filter.placeholder) {
+ if (filter.placeholder_value === undefined) {
+ filter.placeholder_value = -1;
+ }
+
+ filter.values.forEach(function(entry) {
+ if (entry.value == filter.placeholder_value) {
+ Utils.error('Config', 'Placeholder of filter "{0}" overlaps with one of its values', filter.id);
+ }
+ });
+ }
+ break;
+ }
+ }, this);
+
+ if (this.settings.sort_filters) {
+ if (typeof this.settings.sort_filters == 'function') {
+ filters.sort(this.settings.sort_filters);
+ }
+ else {
+ var self = this;
+ filters.sort(function(a, b) {
+ return self.translate(a.label).localeCompare(self.translate(b.label));
+ });
+ }
+ }
+
+ if (this.status.has_optgroup) {
+ filters = Utils.groupSort(filters, 'optgroup');
+ }
+
+ return filters;
+};
+
+/**
+* Checks the configuration of each operator
+* @param {QueryBuilder.Operator[]} operators
+* @returns {QueryBuilder.Operator[]}
+* @throws ConfigError
+*/
+QueryBuilder.prototype.checkOperators = function(operators) {
+ var definedOperators = [];
+
+ operators.forEach(function(operator, i) {
+ if (typeof operator == 'string') {
+ if (!QueryBuilder.OPERATORS[operator]) {
+ Utils.error('Config', 'Unknown operator "{0}"', operator);
+ }
+
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator]);
+ }
+ else {
+ if (!operator.type) {
+ Utils.error('Config', 'Missing "type" for operator {0}', i);
+ }
+
+ if (QueryBuilder.OPERATORS[operator.type]) {
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator.type], operator);
+ }
+
+ if (operator.nb_inputs === undefined || operator.apply_to === undefined) {
+ Utils.error('Config', 'Missing "nb_inputs" and/or "apply_to" for operator "{0}"', operator.type);
+ }
+ }
+
+ if (definedOperators.indexOf(operator.type) != -1) {
+ Utils.error('Config', 'Operator "{0}" already defined', operator.type);
+ }
+ definedOperators.push(operator.type);
+
+ if (!operator.optgroup) {
+ operator.optgroup = null;
+ }
+ else {
+ this.status.has_operator_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[operator.optgroup]) {
+ this.settings.optgroups[operator.optgroup] = operator.optgroup;
+ }
+ }
+ }, this);
+
+ if (this.status.has_operator_optgroup) {
+ operators = Utils.groupSort(operators, 'optgroup');
+ }
+
+ return operators;
+};
+
+/**
+* Adds all events listeners to the builder
+* @private
+*/
+QueryBuilder.prototype.bindEvents = function() {
+ var self = this;
+ var Selectors = QueryBuilder.selectors;
+
+ // group condition change
+ this.$el.on('change.queryBuilder', Selectors.group_condition, function() {
+ if ($(this).is(':checked')) {
+ var $group = $(this).closest(Selectors.group_container);
+ self.getModel($group).condition = $(this).val();
+ }
+ });
+
+ // rule filter change
+ this.$el.on('change.queryBuilder', Selectors.rule_filter, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).filter = self.getFilterById($(this).val());
+ });
+
+ // rule operator change
+ this.$el.on('change.queryBuilder', Selectors.rule_operator, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).operator = self.getOperatorByType($(this).val());
+ });
+
+ // add rule button
+ this.$el.on('click.queryBuilder', Selectors.add_rule, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addRule(self.getModel($group));
+ });
+
+ // delete rule button
+ this.$el.on('click.queryBuilder', Selectors.delete_rule, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.deleteRule(self.getModel($rule));
+ });
+
+ if (this.settings.allow_groups !== 0) {
+ // add group button
+ this.$el.on('click.queryBuilder', Selectors.add_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addGroup(self.getModel($group));
+ });
+
+ // delete group button
+ this.$el.on('click.queryBuilder', Selectors.delete_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.deleteGroup(self.getModel($group));
+ });
+ }
+
+ // model events
+ this.model.on({
+ 'drop': function(e, node) {
+ node.$el.remove();
+ self.refreshGroupsConditions();
+ },
+ 'add': function(e, parent, node, index) {
+ if (index === 0) {
+ node.$el.prependTo(parent.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(parent.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'move': function(e, node, group, index) {
+ node.$el.detach();
+
+ if (index === 0) {
+ node.$el.prependTo(group.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(group.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'update': function(e, node, field, value, oldValue) {
+ if (node instanceof Rule) {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyRuleFlags(node);
+ break;
+
+ case 'filter':
+ self.updateRuleFilter(node, oldValue);
+ break;
+
+ case 'operator':
+ self.updateRuleOperator(node, oldValue);
+ break;
+
+ case 'value':
+ self.updateRuleValue(node, oldValue);
+ break;
+ }
+ }
+ else {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyGroupFlags(node);
+ break;
+
+ case 'condition':
+ self.updateGroupCondition(node, oldValue);
+ break;
+ }
+ }
+ }
+ });
+};
+
+/**
+* Creates the root group
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group} root group
+* @fires QueryBuilder.afterAddGroup
+*/
+QueryBuilder.prototype.setRoot = function(addRule, data, flags) {
+ addRule = (addRule === undefined || addRule === true);
+
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, 1));
+
+ this.$el.append($group);
+ this.model.root = new Group(null, $group);
+ this.model.root.model = this.model;
+
+ this.model.root.data = data;
+ this.model.root.flags = $.extend({}, this.settings.default_group_flags, flags);
+ this.model.root.condition = this.settings.default_condition;
+
+ this.trigger('afterAddGroup', this.model.root);
+
+ if (addRule) {
+ this.addRule(this.model.root);
+ }
+
+ return this.model.root;
+};
+
+/**
+* Adds a new group
+* @param {Group} parent
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group}
+* @fires QueryBuilder.beforeAddGroup
+* @fires QueryBuilder.afterAddGroup
+*/
+QueryBuilder.prototype.addGroup = function(parent, addRule, data, flags) {
+ addRule = (addRule === undefined || addRule === true);
+
+ var level = parent.level + 1;
+
+ /**
+ * Just before adding a group, can be prevented.
+ * @event beforeAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ * @param {boolean} addRule - if an empty rule will be added in the group
+ * @param {int} level - nesting level of the group, 1 is the root group
+ */
+ var e = this.trigger('beforeAddGroup', parent, addRule, level);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, level));
+ var model = parent.addGroup($group);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_group_flags, flags);
+ model.condition = this.settings.default_condition;
+
+ /**
+ * Just after adding a group
+ * @event afterAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterAddGroup', model);
+
+ /**
+ * After any change in the rules
+ * @event rulesChanged
+ * @memberof QueryBuilder
+ */
+ this.trigger('rulesChanged');
+
+ if (addRule) {
+ this.addRule(model);
+ }
+
+ return model;
+};
+
+/**
+* Tries to delete a group. The group is not deleted if at least one rule is flagged `no_delete`.
+* @param {Group} group
+* @returns {boolean} if the group has been deleted
+* @fires QueryBuilder.beforeDeleteGroup
+* @fires QueryBuilder.afterDeleteGroup
+*/
+QueryBuilder.prototype.deleteGroup = function(group) {
+ if (group.isRoot()) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a group, can be prevented
+ * @event beforeDeleteGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeDeleteGroup', group);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ var del = true;
+
+ group.each('reverse', function(rule) {
+ del &= this.deleteRule(rule);
+ }, function(group) {
+ del &= this.deleteGroup(group);
+ }, this);
+
+ if (del) {
+ group.drop();
+
+ /**
+ * Just after deleting a group
+ * @event afterDeleteGroup
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteGroup');
+
+ this.trigger('rulesChanged');
+ }
+
+ return del;
+};
+
+/**
+* Performs actions when a group's condition changes
+* @param {Group} group
+* @param {object} previousCondition
+* @fires QueryBuilder.afterUpdateGroupCondition
+* @private
+*/
+QueryBuilder.prototype.updateGroupCondition = function(group, previousCondition) {
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).each(function() {
+ var $this = $(this);
+ $this.prop('checked', $this.val() === group.condition);
+ $this.parent().toggleClass('active', $this.val() === group.condition);
+ });
+
+ /**
+ * After the group condition has been modified
+ * @event afterUpdateGroupCondition
+ * @memberof QueryBuilder
+ * @param {Group} group
+ * @param {object} previousCondition
+ */
+ this.trigger('afterUpdateGroupCondition', group, previousCondition);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Updates the visibility of conditions based on number of rules inside each group
+* @private
+*/
+QueryBuilder.prototype.refreshGroupsConditions = function() {
+ (function walk(group) {
+ if (!group.flags || (group.flags && !group.flags.condition_readonly)) {
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).prop('disabled', group.rules.length <= 1)
+ .parent().toggleClass('disabled', group.rules.length <= 1);
+ }
+
+ group.each(null, function(group) {
+ walk(group);
+ }, this);
+ }(this.model.root));
+};
+
+/**
+* Adds a new rule
+* @param {Group} parent
+* @param {object} [data] - rule custom data
+* @param {object} [flags] - flags to apply to the rule
+* @returns {Rule}
+* @fires QueryBuilder.beforeAddRule
+* @fires QueryBuilder.afterAddRule
+* @fires QueryBuilder.changer:getDefaultFilter
+*/
+QueryBuilder.prototype.addRule = function(parent, data, flags) {
+ /**
+ * Just before adding a rule, can be prevented
+ * @event beforeAddRule
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeAddRule', parent);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var rule_id = this.nextRuleId();
+ var $rule = $(this.getRuleTemplate(rule_id));
+ var model = parent.addRule($rule);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_rule_flags, flags);
+
+ /**
+ * Just after adding a rule
+ * @event afterAddRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterAddRule', model);
+
+ this.trigger('rulesChanged');
+
+ this.createRuleFilters(model);
+
+ if (this.settings.default_filter || !this.settings.display_empty_filter) {
+ /**
+ * Modifies the default filter for a rule
+ * @event changer:getDefaultFilter
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter} filter
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter}
+ */
+ model.filter = this.change('getDefaultFilter',
+ this.getFilterById(this.settings.default_filter || this.filters[0].id),
+ model
+ );
+ }
+
+ return model;
+};
+
+/**
+* Tries to delete a rule
+* @param {Rule} rule
+* @returns {boolean} if the rule has been deleted
+* @fires QueryBuilder.beforeDeleteRule
+* @fires QueryBuilder.afterDeleteRule
+*/
+QueryBuilder.prototype.deleteRule = function(rule) {
+ if (rule.flags.no_delete) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a rule, can be prevented
+ * @event beforeDeleteRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ var e = this.trigger('beforeDeleteRule', rule);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ rule.drop();
+
+ /**
+ * Just after deleting a rule
+ * @event afterDeleteRule
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteRule');
+
+ this.trigger('rulesChanged');
+
+ return true;
+};
+
+/**
+* Creates the filters for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.changer:getRuleFilters
+* @fires QueryBuilder.afterCreateRuleFilters
+* @private
+*/
+QueryBuilder.prototype.createRuleFilters = function(rule) {
+ /**
+ * Modifies the list a filters available for a rule
+ * @event changer:getRuleFilters
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter[]} filters
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter[]}
+ */
+ var filters = this.change('getRuleFilters', this.filters, rule);
+ var $filterSelect = $(this.getRuleFilterSelect(rule, filters));
+
+ rule.$el.find(QueryBuilder.selectors.filter_container).html($filterSelect);
+
+ /**
+ * After creating the dropdown for filters
+ * @event afterCreateRuleFilters
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleFilters', rule);
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Creates the operators for a rule and init the rule operator
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleOperators
+* @private
+*/
+QueryBuilder.prototype.createRuleOperators = function(rule) {
+ var $operatorContainer = rule.$el.find(QueryBuilder.selectors.operator_container).empty();
+
+ if (!rule.filter) {
+ return;
+ }
+
+ var operators = this.getOperators(rule.filter);
+ var $operatorSelect = $(this.getRuleOperatorSelect(rule, operators));
+
+ $operatorContainer.html($operatorSelect);
+
+ // set the operator without triggering update event
+ if (rule.filter.default_operator) {
+ rule.__.operator = this.getOperatorByType(rule.filter.default_operator);
+ }
+ else {
+ rule.__.operator = operators[0];
+ }
+
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+
+ /**
+ * After creating the dropdown for operators
+ * @event afterCreateRuleOperators
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {QueryBuilder.Operator[]} operators - allowed operators for this rule
+ */
+ this.trigger('afterCreateRuleOperators', rule, operators);
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Creates the main input for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleInput
+* @private
+*/
+QueryBuilder.prototype.createRuleInput = function(rule) {
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container).empty();
+
+ rule.__.value = undefined;
+
+ if (!rule.filter || !rule.operator || rule.operator.nb_inputs === 0) {
+ return;
+ }
+
+ var self = this;
+ var $inputs = $();
+ var filter = rule.filter;
+
+ for (var i = 0; i < rule.operator.nb_inputs; i++) {
+ var $ruleInput = $(this.getRuleInput(rule, i));
+ if (i > 0) $valueContainer.append(this.settings.inputs_separator);
+ $valueContainer.append($ruleInput);
+ $inputs = $inputs.add($ruleInput);
+ }
+
+ $valueContainer.css('display', '');
+
+ $inputs.on('change ' + (filter.input_event || ''), function() {
+ if (!rule._updating_input) {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+ });
+
+ if (filter.plugin) {
+ $inputs[filter.plugin](filter.plugin_config || {});
+ }
+
+ /**
+ * After creating the input for a rule and initializing optional plugin
+ * @event afterCreateRuleInput
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleInput', rule);
+
+ if (filter.default_value !== undefined) {
+ rule.value = filter.default_value;
+ }
+ else {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+
+ this.applyRuleFlags(rule);
+};
+
+/**
+* Performs action when a rule's filter changes
+* @param {Rule} rule
+* @param {object} previousFilter
+* @fires QueryBuilder.afterUpdateRuleFilter
+* @private
+*/
+QueryBuilder.prototype.updateRuleFilter = function(rule, previousFilter) {
+ //Reset filter
+ rule.$el.find(QueryBuilder.selectors.tooltip).hide();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", "");
+ rule.$el.find(QueryBuilder.selectors.description).hide().find("span").text("");
+
+ var tooltip = rule.filter.tooltip;
+ var description = rule.filter.description;
+
+ this.createRuleOperators(rule);
+ this.createRuleInput(rule);
+
+ rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
+ if(tooltip) {
+ rule.$el.find(QueryBuilder.selectors.tooltip).show();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", tooltip);
+ }
+ if(description) {
+ rule.$el.find(QueryBuilder.selectors.description).show().find("span").text(description);
+ }
+
+ // clear rule data if the filter changed
+ if (previousFilter && rule.filter && previousFilter.id !== rule.filter.id) {
+ rule.data = undefined;
+ }
+
+ /**
+ * After the filter has been updated and the operators and input re-created
+ * @event afterUpdateRuleFilter
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousFilter
+ */
+ this.trigger('afterUpdateRuleFilter', rule, previousFilter);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Performs actions when a rule's operator changes
+* @param {Rule} rule
+* @param {object} previousOperator
+* @fires QueryBuilder.afterUpdateRuleOperator
+* @private
+*/
+QueryBuilder.prototype.updateRuleOperator = function(rule, previousOperator) {
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ if (!rule.operator || rule.operator.nb_inputs === 0) {
+ $valueContainer.hide();
+
+ rule.__.value = undefined;
+ }
+ else {
+ $valueContainer.css('display', '');
+
+ if ($valueContainer.is(':empty') || !previousOperator ||
+ rule.operator.nb_inputs !== previousOperator.nb_inputs ||
+ rule.operator.optgroup !== previousOperator.optgroup
+ ) {
+ this.createRuleInput(rule);
+ }
+ }
+
+ if (rule.operator) {
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+
+ // refresh value if the format changed for this operator
+ rule.__.value = this.getRuleInputValue(rule);
+ }
+
+ /**
+ * After the operator has been updated and the input optionally re-created
+ * @event afterUpdateRuleOperator
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousOperator
+ */
+ this.trigger('afterUpdateRuleOperator', rule, previousOperator);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Performs actions when rule's value changes
+* @param {Rule} rule
+* @param {object} previousValue
+* @fires QueryBuilder.afterUpdateRuleValue
+* @private
+*/
+QueryBuilder.prototype.updateRuleValue = function(rule, previousValue) {
+ if (!rule._updating_value) {
+ this.setRuleInputValue(rule, rule.value);
+ }
+
+ /**
+ * After the rule value has been modified
+ * @event afterUpdateRuleValue
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {*} previousValue
+ */
+ this.trigger('afterUpdateRuleValue', rule, previousValue);
+
+ this.trigger('rulesChanged');
+};
+
+/**
+* Changes a rule's properties depending on its flags
+* @param {Rule} rule
+* @fires QueryBuilder.afterApplyRuleFlags
+* @private
+*/
+QueryBuilder.prototype.applyRuleFlags = function(rule) {
+ var flags = rule.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ rule.$el.find(Selectors.rule_filter).prop('disabled', flags.filter_readonly);
+ rule.$el.find(Selectors.rule_operator).prop('disabled', flags.operator_readonly);
+ rule.$el.find(Selectors.rule_value).prop('disabled', flags.value_readonly);
+
+ if (flags.no_delete) {
+ rule.$el.find(Selectors.delete_rule).remove();
+ }
+
+ /**
+ * After rule's flags has been applied
+ * @event afterApplyRuleFlags
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterApplyRuleFlags', rule);
+};
+
+/**
+* Changes group's properties depending on its flags
+* @param {Group} group
+* @fires QueryBuilder.afterApplyGroupFlags
+* @private
+*/
+QueryBuilder.prototype.applyGroupFlags = function(group) {
+ var flags = group.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ group.$el.find('>' + Selectors.group_condition).prop('disabled', flags.condition_readonly)
+ .parent().toggleClass('readonly', flags.condition_readonly);
+
+ if (flags.no_add_rule) {
+ group.$el.find(Selectors.add_rule).remove();
+ }
+ if (flags.no_add_group) {
+ group.$el.find(Selectors.add_group).remove();
+ }
+ if (flags.no_delete) {
+ group.$el.find(Selectors.delete_group).remove();
+ }
+
+ /**
+ * After group's flags has been applied
+ * @event afterApplyGroupFlags
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterApplyGroupFlags', group);
+};
+
+/**
+* Clears all errors markers
+* @param {Node} [node] default is root Group
+*/
+QueryBuilder.prototype.clearErrors = function(node) {
+ node = node || this.model.root;
+
+ if (!node) {
+ return;
+ }
+
+ node.error = null;
+
+ if (node instanceof Group) {
+ node.each(function(rule) {
+ rule.error = null;
+ }, function(group) {
+ this.clearErrors(group);
+ }, this);
+ }
+};
+
+/**
+* Adds/Removes error on a Rule or Group
+* @param {Node} node
+* @fires QueryBuilder.changer:displayError
+* @private
+*/
+QueryBuilder.prototype.updateError = function(node) {
+ if (this.settings.display_errors) {
+ if (node.error === null) {
+ node.$el.removeClass('has-error');
+ }
+ else {
+ var errorMessage = this.translate('errors', node.error[0]);
+ errorMessage = Utils.fmt(errorMessage, node.error.slice(1));
+
+ /**
+ * Modifies an error message before display
+ * @event changer:displayError
+ * @memberof QueryBuilder
+ * @param {string} errorMessage - the error message (translated and formatted)
+ * @param {array} error - the raw error array (error code and optional arguments)
+ * @param {Node} node
+ * @returns {string}
+ */
+ errorMessage = this.change('displayError', errorMessage, node.error, node);
+
+ node.$el.addClass('has-error')
+ .find(QueryBuilder.selectors.error_container).eq(0)
+ .attr('data-tooltip', errorMessage);
+ }
+ }
+};
+
+/**
+* Triggers a validation error event
+* @param {Node} node
+* @param {string|array} error
+* @param {*} value
+* @fires QueryBuilder.validationError
+* @private
+*/
+QueryBuilder.prototype.triggerValidationError = function(node, error, value) {
+ if (!$.isArray(error)) {
+ error = [error];
+ }
+
+ /**
+ * Fired when a validation error occurred, can be prevented
+ * @event validationError
+ * @memberof QueryBuilder
+ * @param {Node} node
+ * @param {string} error
+ * @param {*} value
+ */
+ var e = this.trigger('validationError', node, error, value);
+ if (!e.isDefaultPrevented()) {
+ node.error = error;
+ }
+};
+
+
+/**
+ * Destroys the builder
+ * @fires QueryBuilder.beforeDestroy
+ */
+QueryBuilder.prototype.destroy = function() {
+ /**
+ * Before the {@link QueryBuilder#destroy} method
+ * @event beforeDestroy
+ * @memberof QueryBuilder
+ */
+ this.trigger('beforeDestroy');
+
+ if (this.status.generated_id) {
+ this.$el.removeAttr('id');
+ }
+
+ this.clear();
+ this.model = null;
+
+ this.$el
+ .off('.queryBuilder')
+ .removeClass('query-builder')
+ .removeData('queryBuilder');
+
+ delete this.$el[0].queryBuilder;
+};
+
+/**
+ * Clear all rules and resets the root group
+ * @fires QueryBuilder.beforeReset
+ * @fires QueryBuilder.afterReset
+ */
+QueryBuilder.prototype.reset = function() {
+ /**
+ * Before the {@link QueryBuilder#reset} method, can be prevented
+ * @event beforeReset
+ * @memberof QueryBuilder
+ */
+ var e = this.trigger('beforeReset');
+ if (e.isDefaultPrevented()) {
+ return;
+ }
+
+ this.status.group_id = 1;
+ this.status.rule_id = 0;
+
+ this.model.root.empty();
+
+ this.model.root.data = undefined;
+ this.model.root.flags = $.extend({}, this.settings.default_group_flags);
+ this.model.root.condition = this.settings.default_condition;
+
+ this.addRule(this.model.root);
+
+ /**
+ * After the {@link QueryBuilder#reset} method
+ * @event afterReset
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterReset');
+
+ this.trigger('rulesChanged');
+};
+
+/**
+ * Clears all rules and removes the root group
+ * @fires QueryBuilder.beforeClear
+ * @fires QueryBuilder.afterClear
+ */
+QueryBuilder.prototype.clear = function() {
+ /**
+ * Before the {@link QueryBuilder#clear} method, can be prevented
+ * @event beforeClear
+ * @memberof QueryBuilder
+ */
+ var e = this.trigger('beforeClear');
+ if (e.isDefaultPrevented()) {
+ return;
+ }
+
+ this.status.group_id = 0;
+ this.status.rule_id = 0;
+
+ if (this.model.root) {
+ this.model.root.drop();
+ this.model.root = null;
+ }
+
+ /**
+ * After the {@link QueryBuilder#clear} method
+ * @event afterClear
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterClear');
+
+ this.trigger('rulesChanged');
+};
+
+/**
+ * Modifies the builder configuration.
+ * Only options defined in QueryBuilder.modifiable_options are modifiable
+ * @param {object} options
+ */
+QueryBuilder.prototype.setOptions = function(options) {
+ $.each(options, function(opt, value) {
+ if (QueryBuilder.modifiable_options.indexOf(opt) !== -1) {
+ this.settings[opt] = value;
+ }
+ }.bind(this));
+};
+
+/**
+ * Returns the model associated to a DOM object, or the root model
+ * @param {jQuery} [target]
+ * @returns {Node}
+ */
+QueryBuilder.prototype.getModel = function(target) {
+ if (!target) {
+ return this.model.root;
+ }
+ else if (target instanceof Node) {
+ return target;
+ }
+ else {
+ return $(target).data('queryBuilderModel');
+ }
+};
+
+/**
+ * Validates the whole builder
+ * @param {object} [options]
+ * @param {boolean} [options.skip_empty=false] - skips validating rules that have no filter selected
+ * @returns {boolean}
+ * @fires QueryBuilder.changer:validate
+ */
+QueryBuilder.prototype.validate = function(options) {
+ options = $.extend({
+ skip_empty: false
+ }, options);
+
+ this.clearErrors();
+
+ var self = this;
+
+ var valid = (function parse(group) {
+ var done = 0;
+ var errors = 0;
+
+ group.each(function(rule) {
+ if (!rule.filter && options.skip_empty) {
+ return;
+ }
+
+ if (!rule.filter) {
+ self.triggerValidationError(rule, 'no_filter', null);
+ errors++;
+ return;
+ }
+
+ if (!rule.operator) {
+ self.triggerValidationError(rule, 'no_operator', null);
+ errors++;
+ return;
+ }
+
+ if (rule.operator.nb_inputs !== 0) {
+ var valid = self.validateValue(rule, rule.value);
+
+ if (valid !== true) {
+ self.triggerValidationError(rule, valid, rule.value);
+ errors++;
+ return;
+ }
+ }
+
+ done++;
+
+ }, function(group) {
+ var res = parse(group);
+ if (res === true) {
+ done++;
+ }
+ else if (res === false) {
+ errors++;
+ }
+ });
+
+ if (errors > 0) {
+ return false;
+ }
+ else if (done === 0 && !group.isRoot() && options.skip_empty) {
+ return null;
+ }
+ else if (done === 0 && (!self.settings.allow_empty || !group.isRoot())) {
+ self.triggerValidationError(group, 'empty_group', null);
+ return false;
+ }
+
+ return true;
+
+ }(this.model.root));
+
+ /**
+ * Modifies the result of the {@link QueryBuilder#validate} method
+ * @event changer:validate
+ * @memberof QueryBuilder
+ * @param {boolean} valid
+ * @returns {boolean}
+ */
+ return this.change('validate', valid);
+};
+
+/**
+ * Gets an object representing current rules
+ * @param {object} [options]
+ * @param {boolean|string} [options.get_flags=false] - export flags, true: only changes from default flags or 'all'
+ * @param {boolean} [options.allow_invalid=false] - returns rules even if they are invalid
+ * @param {boolean} [options.skip_empty=false] - remove rules that have no filter selected
+ * @returns {object}
+ * @fires QueryBuilder.changer:ruleToJson
+ * @fires QueryBuilder.changer:groupToJson
+ * @fires QueryBuilder.changer:getRules
+ */
+QueryBuilder.prototype.getRules = function(options) {
+ options = $.extend({
+ get_flags: false,
+ allow_invalid: false,
+ skip_empty: false
+ }, options);
+
+ var valid = this.validate(options);
+ if (!valid && !options.allow_invalid) {
+ return null;
+ }
+
+ var self = this;
+
+ var out = (function parse(group) {
+ var groupData = {
+ condition: group.condition,
+ rules: []
+ };
+
+ if (group.data) {
+ groupData.data = $.extendext(true, 'replace', {}, group.data);
+ }
+
+ if (options.get_flags) {
+ var flags = self.getGroupFlags(group.flags, options.get_flags === 'all');
+ if (!$.isEmptyObject(flags)) {
+ groupData.flags = flags;
+ }
+ }
+
+ group.each(function(rule) {
+ if (!rule.filter && options.skip_empty) {
+ return;
+ }
+
+ var value = null;
+ if (!rule.operator || rule.operator.nb_inputs !== 0) {
+ value = rule.value;
+ }
+
+ var ruleData = {
+ id: rule.filter ? rule.filter.id : null,
+ field: rule.filter ? rule.filter.field : null,
+ type: rule.filter ? rule.filter.type : null,
+ input: rule.filter ? rule.filter.input : null,
+ operator: rule.operator ? rule.operator.type : null,
+ value: rule.filter.type == "boolean" ? ((value == true || value == 1 || value == "1") ? "1" : "0") : value
+ };
+
+ if (rule.filter && rule.filter.data || rule.data) {
+ ruleData.data = $.extendext(true, 'replace', {}, rule.filter.data, rule.data);
+ }
+
+ if (options.get_flags) {
+ var flags = self.getRuleFlags(rule.flags, options.get_flags === 'all');
+ if (!$.isEmptyObject(flags)) {
+ ruleData.flags = flags;
+ }
+ }
+
+ /**
+ * Modifies the JSON generated from a Rule object
+ * @event changer:ruleToJson
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {Rule} rule
+ * @returns {object}
+ */
+ groupData.rules.push(self.change('ruleToJson', ruleData, rule));
+
+ }, function(model) {
+ var data = parse(model);
+ if (data.rules.length !== 0 || !options.skip_empty) {
+ groupData.rules.push(data);
+ }
+ }, this);
+
+ /**
+ * Modifies the JSON generated from a Group object
+ * @event changer:groupToJson
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {Group} group
+ * @returns {object}
+ */
+ return self.change('groupToJson', groupData, group);
+
+ }(this.model.root));
+
+ out.valid = valid;
+
+ /**
+ * Modifies the result of the {@link QueryBuilder#getRules} method
+ * @event changer:getRules
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @returns {object}
+ */
+ return this.change('getRules', out);
+};
+
+/**
+ * Sets rules from object
+ * @param {object} data
+ * @param {object} [options]
+ * @param {boolean} [options.allow_invalid=false] - silent-fail if the data are invalid
+ * @throws RulesError, UndefinedConditionError
+ * @fires QueryBuilder.changer:setRules
+ * @fires QueryBuilder.changer:jsonToRule
+ * @fires QueryBuilder.changer:jsonToGroup
+ * @fires QueryBuilder.afterSetRules
+ */
+QueryBuilder.prototype.setRules = function(data, options) {
+ options = $.extend({
+ allow_invalid: false
+ }, options);
+
+ if ($.isArray(data)) {
+ data = {
+ condition: this.settings.default_condition,
+ rules: data
+ };
+ }
+
+ if (!data || !data.rules || (data.rules.length === 0 && !this.settings.allow_empty)) {
+ Utils.error('RulesParse', 'Incorrect data object passed');
+ }
+
+ this.clear();
+ this.setRoot(false, data.data, this.parseGroupFlags(data));
+
+ /**
+ * Modifies data before the {@link QueryBuilder#setRules} method
+ * @event changer:setRules
+ * @memberof QueryBuilder
+ * @param {object} json
+ * @param {object} options
+ * @returns {object}
+ */
+ data = this.change('setRules', data, options);
+
+ var self = this;
+
+ (function add(data, group) {
+ if (group === null) {
+ return;
+ }
+
+ if (data.condition === undefined) {
+ data.condition = self.settings.default_condition;
+ }
+ else if (self.settings.conditions.indexOf(data.condition) == -1) {
+ Utils.error(!options.allow_invalid, 'UndefinedCondition', 'Invalid condition "{0}"', data.condition);
+ data.condition = self.settings.default_condition;
+ }
+
+ group.condition = data.condition;
+
+ data.rules.forEach(function(item) {
+ var model;
+
+ if (item.rules !== undefined) {
+ if (self.settings.allow_groups !== -1 && self.settings.allow_groups < group.level) {
+ Utils.error(!options.allow_invalid, 'RulesParse', 'No more than {0} groups are allowed', self.settings.allow_groups);
+ self.reset();
+ }
+ else {
+ model = self.addGroup(group, false, item.data, self.parseGroupFlags(item));
+ if (model === null) {
+ return;
+ }
+
+ add(item, model);
+ }
+ }
+ else {
+ if (!item.empty) {
+ if (item.id === undefined) {
+ Utils.error(!options.allow_invalid, 'RulesParse', 'Missing rule field id');
+ item.empty = true;
+ }
+ if (item.operator === undefined) {
+ item.operator = 'equal';
+ }
+ }
+
+ model = self.addRule(group, item.data, self.parseRuleFlags(item));
+ if (model === null) {
+ return;
+ }
+
+ if (!item.empty) {
+ model.filter = self.getFilterById(item.id, !options.allow_invalid);
+ }
+
+ if (model.filter) {
+ model.operator = self.getOperatorByType(item.operator, !options.allow_invalid);
+
+ if (!model.operator) {
+ model.operator = self.getOperators(model.filter)[0];
+ }
+ }
+
+ if (model.operator && model.operator.nb_inputs !== 0) {
+ if (item.value !== undefined) {
+ model.value = item.value;
+ }
+ else if (model.filter.default_value !== undefined) {
+ model.value = model.filter.default_value;
+ }
+ }
+
+ /**
+ * Modifies the Rule object generated from the JSON
+ * @event changer:jsonToRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} json
+ * @returns {Rule} the same rule
+ */
+ if (self.change('jsonToRule', model, item) != model) {
+ Utils.error('RulesParse', 'Plugin tried to change rule reference');
+ }
+ }
+ });
+
+ /**
+ * Modifies the Group object generated from the JSON
+ * @event changer:jsonToGroup
+ * @memberof QueryBuilder
+ * @param {Group} group
+ * @param {object} json
+ * @returns {Group} the same group
+ */
+ if (self.change('jsonToGroup', group, data) != group) {
+ Utils.error('RulesParse', 'Plugin tried to change group reference');
+ }
+
+ }(data, this.model.root));
+
+ /**
+ * After the {@link QueryBuilder#setRules} method
+ * @event afterSetRules
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterSetRules');
+};
+
+
+/**
+ * Performs value validation
+ * @param {Rule} rule
+ * @param {string|string[]} value
+ * @returns {array|boolean} true or error array
+ * @fires QueryBuilder.changer:validateValue
+ */
+QueryBuilder.prototype.validateValue = function(rule, value) {
+ var validation = rule.filter.validation || {};
+ var result = true;
+
+ if (validation.callback) {
+ result = validation.callback.call(this, value, rule);
+ }
+ else {
+ result = this._validateValue(rule, value);
+ }
+
+ /**
+ * Modifies the result of the rule validation method
+ * @event changer:validateValue
+ * @memberof QueryBuilder
+ * @param {array|boolean} result - true or an error array
+ * @param {*} value
+ * @param {Rule} rule
+ * @returns {array|boolean}
+ */
+ return this.change('validateValue', result, value, rule);
+};
+
+/**
+ * Default validation function
+ * @param {Rule} rule
+ * @param {string|string[]} value
+ * @returns {array|boolean} true or error array
+ * @throws ConfigError
+ * @private
+ */
+QueryBuilder.prototype._validateValue = function(rule, value) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+ var validation = filter.validation || {};
+ var result = true;
+ var tmp, tempValue;
+
+ if (rule.operator.nb_inputs === 1) {
+ value = [value];
+ }
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ if (!operator.multiple && $.isArray(value[i]) && value[i].length > 1) {
+ result = ['operator_not_multiple', operator.type, this.translate('operators', operator.type)];
+ break;
+ }
+
+ switch (filter.input) {
+ case 'radio':
+ if (value[i] === undefined || value[i].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['radio_empty'];
+ }
+ break;
+ }
+ break;
+
+ case 'checkbox':
+ if (value[i] === undefined || value[i].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['checkbox_empty'];
+ }
+ break;
+ }
+ break;
+
+ case 'select':
+ if (value[i] === undefined || value[i].length === 0 || (filter.placeholder && value[i] == filter.placeholder_value)) {
+ if (!validation.allow_empty_value) {
+ result = ['select_empty'];
+ }
+ break;
+ }
+ break;
+
+ default:
+ tempValue = $.isArray(value[i]) ? value[i] : [value[i]];
+
+ for (var j = 0; j < tempValue.length; j++) {
+ switch (QueryBuilder.types[filter.type]) {
+ case 'string':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['string_empty'];
+ }
+ break;
+ }
+ if (validation.min !== undefined) {
+ if (tempValue[j].length < parseInt(validation.min)) {
+ result = [this.getValidationMessage(validation, 'min', 'string_exceed_min_length'), validation.min];
+ break;
+ }
+ }
+ if (validation.max !== undefined) {
+ if (tempValue[j].length > parseInt(validation.max)) {
+ result = [this.getValidationMessage(validation, 'max', 'string_exceed_max_length'), validation.max];
+ break;
+ }
+ }
+ if (validation.format) {
+ if (typeof validation.format == 'string') {
+ validation.format = new RegExp(validation.format);
+ }
+ if (!validation.format.test(tempValue[j])) {
+ result = [this.getValidationMessage(validation, 'format', 'string_invalid_format'), validation.format];
+ break;
+ }
+ }
+ break;
+
+ case 'number':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['number_nan'];
+ }
+ break;
+ }
+ if (isNaN(tempValue[j])) {
+ result = ['number_nan'];
+ break;
+ }
+ if (filter.type == 'integer') {
+ if (parseInt(tempValue[j]) != tempValue[j]) {
+ result = ['number_not_integer'];
+ break;
+ }
+ }
+ else {
+ if (parseFloat(tempValue[j]) != tempValue[j]) {
+ result = ['number_not_double'];
+ break;
+ }
+ }
+ if (validation.min !== undefined) {
+ if (tempValue[j] < parseFloat(validation.min)) {
+ result = [this.getValidationMessage(validation, 'min', 'number_exceed_min'), validation.min];
+ break;
+ }
+ }
+ if (validation.max !== undefined) {
+ if (tempValue[j] > parseFloat(validation.max)) {
+ result = [this.getValidationMessage(validation, 'max', 'number_exceed_max'), validation.max];
+ break;
+ }
+ }
+ if (validation.step !== undefined && validation.step !== 'any') {
+ var v = (tempValue[j] / validation.step).toPrecision(14);
+ if (parseInt(v) != v) {
+ result = [this.getValidationMessage(validation, 'step', 'number_wrong_step'), validation.step];
+ break;
+ }
+ }
+ break;
+
+ case 'datetime':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['datetime_empty'];
+ }
+ break;
+ }
+
+ // we need MomentJS
+ if (validation.format) {
+ if (!('moment' in window)) {
+ Utils.error('MissingLibrary', 'MomentJS is required for Date/Time validation. Get it here http://momentjs.com');
+ }
+
+ var datetime = moment(tempValue[j], validation.format);
+ if (!datetime.isValid()) {
+ result = [this.getValidationMessage(validation, 'format', 'datetime_invalid'), validation.format];
+ break;
+ }
+ else {
+ if (validation.min) {
+ if (datetime < moment(validation.min, validation.format)) {
+ result = [this.getValidationMessage(validation, 'min', 'datetime_exceed_min'), validation.min];
+ break;
+ }
+ }
+ if (validation.max) {
+ if (datetime > moment(validation.max, validation.format)) {
+ result = [this.getValidationMessage(validation, 'max', 'datetime_exceed_max'), validation.max];
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case 'boolean':
+ if (tempValue[j] === undefined || tempValue[j].length === 0) {
+ if (!validation.allow_empty_value) {
+ result = ['boolean_not_valid'];
+ }
+ break;
+ }
+ tmp = ('' + tempValue[j]).trim().toLowerCase();
+ if (tmp !== 'true' && tmp !== 'false' && tmp !== '1' && tmp !== '0' && tempValue[j] !== 1 && tempValue[j] !== 0) {
+ result = ['boolean_not_valid'];
+ break;
+ }
+ }
+
+ if (result !== true) {
+ break;
+ }
+ }
+ }
+
+ if (result !== true) {
+ break;
+ }
+ }
+
+ if ((rule.operator.type === 'between' || rule.operator.type === 'not_between') && value.length === 2) {
+ switch (QueryBuilder.types[filter.type]) {
+ case 'number':
+ if (value[0] > value[1]) {
+ result = ['number_between_invalid', value[0], value[1]];
+ }
+ break;
+
+ case 'datetime':
+ // we need MomentJS
+ if (validation.format) {
+ if (!('moment' in window)) {
+ Utils.error('MissingLibrary', 'MomentJS is required for Date/Time validation. Get it here http://momentjs.com');
+ }
+
+ if (moment(value[0], validation.format).isAfter(moment(value[1], validation.format))) {
+ result = ['datetime_between_invalid', value[0], value[1]];
+ }
+ }
+ break;
+ }
+ }
+
+ return result;
+};
+
+/**
+ * Returns an incremented group ID
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.nextGroupId = function() {
+ return this.status.id + '_group_' + (this.status.group_id++);
+};
+
+/**
+ * Returns an incremented rule ID
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.nextRuleId = function() {
+ return this.status.id + '_rule_' + (this.status.rule_id++);
+};
+
+/**
+ * Returns the operators for a filter
+ * @param {string|object} filter - filter id or filter object
+ * @returns {object[]}
+ * @fires QueryBuilder.changer:getOperators
+ */
+QueryBuilder.prototype.getOperators = function(filter) {
+ if (typeof filter == 'string') {
+ filter = this.getFilterById(filter);
+ }
+
+ var result = [];
+
+ for (var i = 0, l = this.operators.length; i < l; i++) {
+ // filter operators check
+ if (filter.operators) {
+ if (filter.operators.indexOf(this.operators[i].type) == -1) {
+ continue;
+ }
+ }
+ // type check
+ else if (this.operators[i].apply_to.indexOf(QueryBuilder.types[filter.type]) == -1) {
+ continue;
+ }
+
+ result.push(this.operators[i]);
+ }
+
+ // keep sort order defined for the filter
+ if (filter.operators) {
+ result.sort(function(a, b) {
+ return filter.operators.indexOf(a.type) - filter.operators.indexOf(b.type);
+ });
+ }
+
+ /**
+ * Modifies the operators available for a filter
+ * @event changer:getOperators
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Operator[]} operators
+ * @param {QueryBuilder.Filter} filter
+ * @returns {QueryBuilder.Operator[]}
+ */
+ return this.change('getOperators', result, filter);
+};
+
+/**
+ * Returns a particular filter by its id
+ * @param {string} id
+ * @param {boolean} [doThrow=true]
+ * @returns {object|null}
+ * @throws UndefinedFilterError
+ */
+QueryBuilder.prototype.getFilterById = function(id, doThrow) {
+ if (id == '-1') {
+ return null;
+ }
+
+ for (var i = 0, l = this.filters.length; i < l; i++) {
+ if (this.filters[i].id == id) {
+ return this.filters[i];
+ }
+ }
+
+ Utils.error(doThrow !== false, 'UndefinedFilter', 'Undefined filter "{0}"', id);
+
+ return null;
+};
+
+/**
+ * Returns a particular operator by its type
+ * @param {string} type
+ * @param {boolean} [doThrow=true]
+ * @returns {object|null}
+ * @throws UndefinedOperatorError
+ */
+QueryBuilder.prototype.getOperatorByType = function(type, doThrow) {
+ if (type == '-1') {
+ return null;
+ }
+
+ for (var i = 0, l = this.operators.length; i < l; i++) {
+ if (this.operators[i].type == type) {
+ return this.operators[i];
+ }
+ }
+
+ Utils.error(doThrow !== false, 'UndefinedOperator', 'Undefined operator "{0}"', type);
+
+ return null;
+};
+
+/**
+ * Returns rule's current input value
+ * @param {Rule} rule
+ * @returns {*}
+ * @fires QueryBuilder.changer:getRuleValue
+ * @private
+ */
+QueryBuilder.prototype.getRuleInputValue = function(rule) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+ var value = [];
+
+ if (filter.valueGetter) {
+ value = filter.valueGetter.call(this, rule);
+ }
+ else {
+ var $value = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ var name = Utils.escapeElementId(rule.id + '_value_' + i);
+ var tmp;
+
+ switch (filter.input) {
+ case 'radio':
+ value.push($value.find('[name=' + name + ']:checked').val());
+ break;
+
+ case 'checkbox':
+ tmp = [];
+ // jshint loopfunc:true
+ $value.find('[name=' + name + ']:checked').each(function() {
+ tmp.push($(this).val());
+ });
+ // jshint loopfunc:false
+ value.push(tmp);
+ break;
+
+ case 'select':
+ if (filter.multiple) {
+ tmp = [];
+ // jshint loopfunc:true
+ $value.find('[name=' + name + '] option:selected').each(function() {
+ tmp.push($(this).val());
+ });
+ // jshint loopfunc:false
+ value.push(tmp);
+ }
+ else {
+ value.push($value.find('[name=' + name + '] option:selected').val());
+ }
+ break;
+
+ default:
+ value.push($value.find('[name=' + name + ']').val());
+ }
+ }
+
+ value = value.map(function(val) {
+ if (operator.multiple && filter.value_separator && typeof val == 'string') {
+ val = val.split(filter.value_separator);
+ }
+
+ if ($.isArray(val)) {
+ return val.map(function(subval) {
+ return Utils.changeType(subval, filter.type);
+ });
+ }
+ else {
+ return Utils.changeType(val, filter.type);
+ }
+ });
+
+ if (operator.nb_inputs === 1) {
+ value = value[0];
+ }
+
+ // @deprecated
+ if (filter.valueParser) {
+ value = filter.valueParser.call(this, rule, value);
+ }
+ }
+
+ /**
+ * Modifies the rule's value grabbed from the DOM
+ * @event changer:getRuleValue
+ * @memberof QueryBuilder
+ * @param {*} value
+ * @param {Rule} rule
+ * @returns {*}
+ */
+ return this.change('getRuleValue', value, rule);
+};
+
+/**
+ * Sets the value of a rule's input
+ * @param {Rule} rule
+ * @param {*} value
+ * @private
+ */
+QueryBuilder.prototype.setRuleInputValue = function(rule, value) {
+ var filter = rule.filter;
+ var operator = rule.operator;
+
+ if (!filter || !operator) {
+ return;
+ }
+
+ rule._updating_input = true;
+
+ if (filter.valueSetter) {
+ filter.valueSetter.call(this, rule, value);
+ }
+ else {
+ var $value = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ if (operator.nb_inputs == 1) {
+ value = [value];
+ }
+
+ for (var i = 0; i < operator.nb_inputs; i++) {
+ var name = Utils.escapeElementId(rule.id + '_value_' + i);
+
+ switch (filter.input) {
+ case 'radio':
+ $value.find('[name=' + name + '][value="' + value[i] + '"]').prop('checked', true).trigger('change');
+ break;
+
+ case 'checkbox':
+ if (!$.isArray(value[i])) {
+ value[i] = [value[i]];
+ }
+ // jshint loopfunc:true
+ value[i].forEach(function(value) {
+ $value.find('[name=' + name + '][value="' + value + '"]').prop('checked', true).trigger('change');
+ });
+ // jshint loopfunc:false
+ break;
+
+ default:
+ if (operator.multiple && filter.value_separator && $.isArray(value[i])) {
+ value[i] = value[i].join(filter.value_separator);
+ }
+ if (operator.type === 'between') {
+
+ var arrval = value.split(",");
+ $value.find('[name=' + name + ']').val(arrval[i]).trigger('change');
+
+ } else {
+
+ $value.find('[name=' + name + ']').val(value[i]).trigger('change');
+ }
+ break;
+ }
+ }
+ }
+
+ rule._updating_input = false;
+};
+
+/**
+ * Parses rule flags
+ * @param {object} rule
+ * @returns {object}
+ * @fires QueryBuilder.changer:parseRuleFlags
+ * @private
+ */
+QueryBuilder.prototype.parseRuleFlags = function(rule) {
+ var flags = $.extend({}, this.settings.default_rule_flags);
+
+ if (rule.readonly) {
+ $.extend(flags, {
+ filter_readonly: true,
+ operator_readonly: true,
+ value_readonly: true,
+ no_delete: true
+ });
+ }
+
+ if (rule.flags) {
+ $.extend(flags, rule.flags);
+ }
+
+ /**
+ * Modifies the consolidated rule's flags
+ * @event changer:parseRuleFlags
+ * @memberof QueryBuilder
+ * @param {object} flags
+ * @param {object} rule - not a Rule object
+ * @returns {object}
+ */
+ return this.change('parseRuleFlags', flags, rule);
+};
+
+/**
+ * Gets a copy of flags of a rule
+ * @param {object} flags
+ * @param {boolean} [all=false] - return all flags or only changes from default flags
+ * @returns {object}
+ * @private
+ */
+QueryBuilder.prototype.getRuleFlags = function(flags, all) {
+ if (all) {
+ return $.extend({}, flags);
+ }
+ else {
+ var ret = {};
+ $.each(this.settings.default_rule_flags, function(key, value) {
+ if (flags[key] !== value) {
+ ret[key] = flags[key];
+ }
+ });
+ return ret;
+ }
+};
+
+/**
+ * Parses group flags
+ * @param {object} group
+ * @returns {object}
+ * @fires QueryBuilder.changer:parseGroupFlags
+ * @private
+ */
+QueryBuilder.prototype.parseGroupFlags = function(group) {
+ var flags = $.extend({}, this.settings.default_group_flags);
+
+ if (group.readonly) {
+ $.extend(flags, {
+ condition_readonly: true,
+ no_add_rule: true,
+ no_add_group: true,
+ no_delete: true
+ });
+ }
+
+ if (group.flags) {
+ $.extend(flags, group.flags);
+ }
+
+ /**
+ * Modifies the consolidated group's flags
+ * @event changer:parseGroupFlags
+ * @memberof QueryBuilder
+ * @param {object} flags
+ * @param {object} group - not a Group object
+ * @returns {object}
+ */
+ return this.change('parseGroupFlags', flags, group);
+};
+
+/**
+ * Gets a copy of flags of a group
+ * @param {object} flags
+ * @param {boolean} [all=false] - return all flags or only changes from default flags
+ * @returns {object}
+ * @private
+ */
+QueryBuilder.prototype.getGroupFlags = function(flags, all) {
+ if (all) {
+ return $.extend({}, flags);
+ }
+ else {
+ var ret = {};
+ $.each(this.settings.default_group_flags, function(key, value) {
+ if (flags[key] !== value) {
+ ret[key] = flags[key];
+ }
+ });
+ return ret;
+ }
+};
+
+/**
+ * Translate a label either by looking in the `lang` object or in itself if it's an object where keys are language codes
+ * @param {string} [category]
+ * @param {string|object} key
+ * @returns {string}
+ * @fires QueryBuilder.changer:translate
+ */
+QueryBuilder.prototype.translate = function(category, key) {
+ if (!key) {
+ key = category;
+ category = undefined;
+ }
+
+ var translation;
+ if (typeof key === 'object') {
+ translation = key[this.settings.lang_code] || key['en'];
+ }
+ else {
+ translation = (category ? this.lang[category] : this.lang)[key] || key;
+ }
+
+ /**
+ * Modifies the translated label
+ * @event changer:translate
+ * @memberof QueryBuilder
+ * @param {string} translation
+ * @param {string|object} key
+ * @param {string} [category]
+ * @returns {string}
+ */
+ return this.change('translate', translation, key, category);
+};
+
+/**
+ * Returns a validation message
+ * @param {object} validation
+ * @param {string} type
+ * @param {string} def
+ * @returns {string}
+ * @private
+ */
+QueryBuilder.prototype.getValidationMessage = function(validation, type, def) {
+ return validation.messages && validation.messages[type] || def;
+};
+
+
+QueryBuilder.templates.group = '\
+';
+
+QueryBuilder.templates.rule = '\
+ \
+
\
+ \
+
\
+
\
+
\
+ {{? it.settings.display_errors }} \
+
\
+ {{?}} \
+
\
+
\
+
\
\
+
';
+
+QueryBuilder.templates.filterSelect = '\
+{{ var optgroup = null; }} \
+ \
+ {{? it.settings.display_empty_filter }} \
+ {{= it.settings.select_placeholder }} \
+ {{?}} \
+ {{~ it.filters: filter }} \
+ {{? optgroup !== filter.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = filter.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= it.translate(filter.label) }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+QueryBuilder.templates.operatorSelect = '\
+{{? it.operators.length === 1 }} \
+ \
+{{= it.translate("operators", it.operators[0].type) }} \
+ \
+{{?}} \
+{{ var optgroup = null; }} \
+ \
+ {{~ it.operators: operator }} \
+ {{? optgroup !== operator.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = operator.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= it.translate("operators", operator.type) }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+QueryBuilder.templates.ruleValueSelect = '\
+{{ var optgroup = null; }} \
+ \
+ {{? it.rule.filter.placeholder }} \
+ {{= it.rule.filter.placeholder }} \
+ {{?}} \
+ {{~ it.rule.filter.values: entry }} \
+ {{? optgroup !== entry.optgroup }} \
+ {{? optgroup !== null }}{{?}} \
+ {{? (optgroup = entry.optgroup) !== null }} \
+ \
+ {{?}} \
+ {{?}} \
+ {{= entry.label }} \
+ {{~}} \
+ {{? optgroup !== null }} {{?}} \
+ ';
+
+/**
+ * Returns group's HTML
+ * @param {string} group_id
+ * @param {int} level
+ * @returns {string}
+ * @fires QueryBuilder.changer:getGroupTemplate
+ * @private
+ */
+QueryBuilder.prototype.getGroupTemplate = function(group_id, level) {
+ var h = this.templates.group({
+ builder: this,
+ group_id: group_id,
+ level: level,
+ conditions: this.settings.conditions,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of a group
+ * @event changer:getGroupTemplate
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {int} level
+ * @returns {string}
+ */
+ return this.change('getGroupTemplate', h, level);
+};
+
+/**
+ * Returns rule's HTML
+ * @param {string} rule_id
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleTemplate = function(rule_id) {
+ var h = this.templates.rule({
+ builder: this,
+ rule_id: rule_id,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of a rule
+ * @event changer:getRuleTemplate
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @returns {string}
+ */
+ return this.change('getRuleTemplate', h);
+};
+
+/**
+ * Returns rule's filter HTML
+ * @param {Rule} rule
+ * @param {object[]} filters
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleFilterTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleFilterSelect = function(rule, filters) {
+ var h = this.templates.filterSelect({
+ builder: this,
+ rule: rule,
+ filters: filters,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's filter dropdown
+ * @event changer:getRuleFilterSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {Rule} rule
+ * @param {QueryBuilder.Filter[]} filters
+ * @returns {string}
+ */
+ return this.change('getRuleFilterSelect', h, rule, filters);
+};
+
+/**
+ * Returns rule's operator HTML
+ * @param {Rule} rule
+ * @param {object[]} operators
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleOperatorTemplate
+ * @private
+ */
+QueryBuilder.prototype.getRuleOperatorSelect = function(rule, operators) {
+ var h = this.templates.operatorSelect({
+ builder: this,
+ rule: rule,
+ operators: operators,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's operator dropdown
+ * @event changer:getRuleOperatorSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param {Rule} rule
+ * @param {QueryBuilder.Operator[]} operators
+ * @returns {string}
+ */
+ return this.change('getRuleOperatorSelect', h, rule, operators);
+};
+
+/**
+ * Returns the rule's value select HTML
+ * @param {string} name
+ * @param {Rule} rule
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleValueSelect
+ * @private
+ */
+QueryBuilder.prototype.getRuleValueSelect = function(name, rule) {
+ var h = this.templates.ruleValueSelect({
+ builder: this,
+ name: name,
+ rule: rule,
+ icons: this.icons,
+ settings: this.settings,
+ translate: this.translate.bind(this)
+ });
+
+ /**
+ * Modifies the raw HTML of the rule's value dropdown (in case of a "select filter)
+ * @event changer:getRuleValueSelect
+ * @memberof QueryBuilder
+ * @param {string} html
+ * @param [string} name
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ return this.change('getRuleValueSelect', h, name, rule);
+};
+
+/**
+ * Returns the rule's value HTML
+ * @param {Rule} rule
+ * @param {int} value_id
+ * @returns {string}
+ * @fires QueryBuilder.changer:getRuleInput
+ * @private
+ */
+QueryBuilder.prototype.getRuleInput = function(rule, value_id) {
+ var filter = rule.filter;
+ var validation = rule.filter.validation || {};
+ var name = rule.id + '_value_' + value_id;
+ var c = filter.vertical ? ' class=block' : '';
+ var h = '';
+ var placeholder = Array.isArray(filter.placeholder) ? filter.placeholder[value_id] : filter.placeholder;
+
+ if (typeof filter.input == 'function') {
+ h = filter.input.call(this, rule, name);
+ }
+ else {
+ switch (filter.input) {
+ case 'radio':
+ case 'checkbox':
+ Utils.iterateOptions(filter.values, function(key, val) {
+ h += ' ' + val + ' ';
+ });
+ break;
+
+ case 'select':
+ h = this.getRuleValueSelect(name, rule);
+ break;
+
+ case 'textarea':
+ h += '" ; + break + + case number : + h +=' " ; + break + + default + h +=' " ; + } + } + + + * Modifies the raw HTML of the rule s input + * @event changer:getRuleInput + * @memberof QueryBuilder + * @param {string html + * @param {Rule rule + * @param {string name - the name that the input must have + * @returns {string + * + return this.change getRuleInput , h rule name + + + + + * @namespace + * +var Utils="{};" + + + * @member {object + * @memberof QueryBuilder + * @see Utils + * +QueryBuilder.utils="Utils;" + + + * @callback Utils#OptionsIteratee + * @param {string key + * @param {string value + * @param {string [optgroup + * + + + * Iterates over radio/checkbox/selection options it accept four formats + * + * @example + * array of values + * options="['one'," two , three ] + * @example + * simple key-value map + * options="{1:" one , 2 two , 3 three } + * @example + * array of 1-element maps + * options="[{1:" one } {2 two } {3 three } + * @example + * array of elements + * options="[{value:" 1 label one , optgroup group } {value 2 label two } + * + * @param {object|array options + * @param {Utils#OptionsIteratee tpl + * +Utils.iterateOptions="function(options," tpl { + if (options { + if ($.isArray(options { + options.forEach(function(entry { + if ($.isPlainObject(entry { + array of elements + if ( value in entry { + tpl(entry.value entry.label | entry.value entry.optgroup + } + array of one-element maps + else { + $.each(entry function(key val { + tpl(key val + return false break after first entry + } + } + } + array of values + else { + tpl(entry entry + } + } + } + unordered map + else { + $.each(options function(key val { + tpl(key val + } + } + } + + + + * Replaces {0 {1 . in a string + * @param {string str + * @param { args + * @returns {string + * +Utils.fmt="function(str," args { + if (!Array.isArray(args { + args="Array.prototype.slice.call(arguments," 1 + } + + return str.replace(/{([0-9]+)}/g function(m i { + return args[parseInt(i + } + + + + * Throws an Error object with custom name or logs an error + * @param {boolean [doThrow="true]" + * @param {string type + * @param {string message + * @param { args + * +Utils.error="function()" { + var i="0;" + var doThrow="typeof" arguments[i="==" boolean ? arguments[i : true + var type="arguments[i++];" + var message="arguments[i++];" + var args="Array.isArray(arguments[i])" ? arguments[i : Array.prototype.slice.call(arguments i + + if (doThrow { + var err="new" Error(Utils.fmt(message args + err.name="type" + Error ; + err.args="args;" + throw err + } + else { + console.error(type + Error + Utils.fmt(message args + } + + + + * Changes the type of a value to int float or bool + * @param { value + * @param {string type - integer , double , boolean or anything else (passthrough + * @returns { + * +Utils.changeType="function(value," type { + if (value="==" | value="==" undefined { + return undefined + } + + switch (type { + @formatter:off + case integer : + if (typeof value="==" string & !/^-?\d+$/.test(value { + return value + } + return parseInt(value + case double : + if (typeof value="==" string & !/^-?\d+\.?\d*$/.test(value { + return value + } + return parseFloat(value + case boolean : + if (typeof value="==" string & !/^(0|1|true|false){1}$/i.test(value { + return value + } + return value="==" true | value="==" 1 | value.toLowerCase="==" true | value="==" 1 ; + default return value + @formatter:on + } + + + + * Escapes a string like PHP s mysql_real_escape_string does + * @param {string value + * @returns {string + * +Utils.escapeString="function(value)" { + if (typeof value !="string" ) { + return value + } + + return value + .replace(/[\0\n\r\b \ ]/g function(s { + switch (s { + @formatter:off + case \0 : return \\0 ; + case \n : return \\n ; + case \r : return \\r ; + case \b : return \\b ; + default return \ + s + @formatter:off + } + } + uglify compliant + .replace(/\t/g \\t ) + .replace(/\x1a/g \\Z ) + + + + * Escapes a string for use in regex + * @param {string str + * @returns {string + * +Utils.escapeRegExp="function(str)" { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g \ ) + + + + * Escapes a string for use in HTML element id + * @param {string str + * @returns {string + * +Utils.escapeElementId="function(str)" { + Regex based on that suggested by + https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation + - escapes : . [ ] , + - avoids escaping already escaped values + return (str ? str.replace(/(\\)?([:.\[\],])/g + function $0 $1 $2 ) { return $1 ? $0 : \ + $2 } : str + + + + * Sorts objects by grouping them by `key preserving initial order when possible + * @param {object items + * @param {string key + * @returns {object + * +Utils.groupSort="function(items," key { + var optgroups="[];" + var newItems="[];" + + items.forEach(function(item { + var idx + + if (item[key { + idx="optgroups.lastIndexOf(item[key]);" + + if (idx="=" -1 { + idx="optgroups.length;" + } + else { + idx + } + } + else { + idx="optgroups.length;" + } + + optgroups.splice(idx 0 item[key + newItems.splice(idx 0 item + } + + return newItems + + + + * Defines properties on an Node prototype with getter and setter />
+ * Update events are emitted in the setter through root Model (if any).
+ * The object must have a `__` object, non enumerable property to store values.
+ * @param {function} obj
+ * @param {string[]} fields
+ */
+Utils.defineModelProperties = function(obj, fields) {
+ fields.forEach(function(field) {
+ Object.defineProperty(obj.prototype, field, {
+ enumerable: true,
+ get: function() {
+ return this.__[field];
+ },
+ set: function(value) {
+ var previousValue = (this.__[field] !== null && typeof this.__[field] == 'object') ?
+ $.extend({}, this.__[field]) :
+ this.__[field];
+
+ this.__[field] = value;
+
+ if (this.model !== null) {
+ /**
+ * After a value of the model changed
+ * @event model:update
+ * @memberof Model
+ * @param {Node} node
+ * @param {string} field
+ * @param {*} value
+ * @param {*} previousValue
+ */
+ this.model.trigger('update', this, field, value, previousValue);
+ }
+ }
+ });
+ });
+};
+
+
+/**
+ * Main object storing data model and emitting model events
+ * @constructor
+ */
+function Model() {
+ /**
+ * @member {Group}
+ * @readonly
+ */
+ this.root = null;
+
+ /**
+ * Base for event emitting
+ * @member {jQuery}
+ * @readonly
+ * @private
+ */
+ this.$ = $(this);
+}
+
+$.extend(Model.prototype, /** @lends Model.prototype */ {
+ /**
+ * Triggers an event on the model
+ * @param {string} type
+ * @returns {$.Event}
+ */
+ trigger: function(type) {
+ var event = new $.Event(type);
+ this.$.triggerHandler(event, Array.prototype.slice.call(arguments, 1));
+ return event;
+ },
+
+ /**
+ * Attaches an event listener on the model
+ * @param {string} type
+ * @param {function} cb
+ * @returns {Model}
+ */
+ on: function() {
+ this.$.on.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ },
+
+ /**
+ * Removes an event listener from the model
+ * @param {string} type
+ * @param {function} [cb]
+ * @returns {Model}
+ */
+ off: function() {
+ this.$.off.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ },
+
+ /**
+ * Attaches an event listener called once on the model
+ * @param {string} type
+ * @param {function} cb
+ * @returns {Model}
+ */
+ once: function() {
+ this.$.one.apply(this.$, Array.prototype.slice.call(arguments));
+ return this;
+ }
+});
+
+
+/**
+ * Root abstract object
+ * @constructor
+ * @param {Node} [parent]
+ * @param {jQuery} $el
+ */
+var Node = function(parent, $el) {
+ if (!(this instanceof Node)) {
+ return new Node(parent, $el);
+ }
+
+ Object.defineProperty(this, '__', { value: {} });
+
+ $el.data('queryBuilderModel', this);
+
+ /**
+ * @name level
+ * @member {int}
+ * @memberof Node
+ * @instance
+ * @readonly
+ */
+ this.__.level = 1;
+
+ /**
+ * @name error
+ * @member {string}
+ * @memberof Node
+ * @instance
+ */
+ this.__.error = null;
+
+ /**
+ * @name flags
+ * @member {object}
+ * @memberof Node
+ * @instance
+ * @readonly
+ */
+ this.__.flags = {};
+
+ /**
+ * @name data
+ * @member {object}
+ * @memberof Node
+ * @instance
+ */
+ this.__.data = undefined;
+
+ /**
+ * @member {jQuery}
+ * @readonly
+ */
+ this.$el = $el;
+
+ /**
+ * @member {string}
+ * @readonly
+ */
+ this.id = $el[0].id;
+
+ /**
+ * @member {Model}
+ * @readonly
+ */
+ this.model = null;
+
+ /**
+ * @member {Group}
+ * @readonly
+ */
+ this.parent = parent;
+};
+
+Utils.defineModelProperties(Node, ['level', 'error', 'data', 'flags']);
+
+Object.defineProperty(Node.prototype, 'parent', {
+ enumerable: true,
+ get: function() {
+ return this.__.parent;
+ },
+ set: function(value) {
+ this.__.parent = value;
+ this.level = value === null ? 1 : value.level + 1;
+ this.model = value === null ? null : value.model;
+ }
+});
+
+/**
+ * Checks if this Node is the root
+ * @returns {boolean}
+ */
+Node.prototype.isRoot = function() {
+ return (this.level === 1);
+};
+
+/**
+ * Returns the node position inside its parent
+ * @returns {int}
+ */
+Node.prototype.getPos = function() {
+ if (this.isRoot()) {
+ return -1;
+ }
+ else {
+ return this.parent.getNodePos(this);
+ }
+};
+
+/**
+ * Deletes self
+ * @fires Model.model:drop
+ */
+Node.prototype.drop = function() {
+ var model = this.model;
+
+ if (!!this.parent) {
+ this.parent.removeNode(this);
+ }
+
+ this.$el.removeData('queryBuilderModel');
+
+ if (model !== null) {
+ /**
+ * After a node of the model has been removed
+ * @event model:drop
+ * @memberof Model
+ * @param {Node} node
+ */
+ model.trigger('drop', this);
+ }
+};
+
+/**
+ * Moves itself after another Node
+ * @param {Node} target
+ * @fires Model.model:move
+ */
+Node.prototype.moveAfter = function(target) {
+ if (!this.isRoot()) {
+ this.move(target.parent, target.getPos() + 1);
+ }
+};
+
+/**
+ * Moves itself at the beginning of parent or another Group
+ * @param {Group} [target]
+ * @fires Model.model:move
+ */
+Node.prototype.moveAtBegin = function(target) {
+ if (!this.isRoot()) {
+ if (target === undefined) {
+ target = this.parent;
+ }
+
+ this.move(target, 0);
+ }
+};
+
+/**
+ * Moves itself at the end of parent or another Group
+ * @param {Group} [target]
+ * @fires Model.model:move
+ */
+Node.prototype.moveAtEnd = function(target) {
+ if (!this.isRoot()) {
+ if (target === undefined) {
+ target = this.parent;
+ }
+
+ this.move(target, target.length() === 0 ? 0 : target.length() - 1);
+ }
+};
+
+/**
+ * Moves itself at specific position of Group
+ * @param {Group} target
+ * @param {int} index
+ * @fires Model.model:move
+ */
+Node.prototype.move = function(target, index) {
+ if (!this.isRoot()) {
+ if (typeof target === 'number') {
+ index = target;
+ target = this.parent;
+ }
+
+ this.parent.removeNode(this);
+ target.insertNode(this, index, false);
+
+ if (this.model !== null) {
+ /**
+ * After a node of the model has been moved
+ * @event model:move
+ * @memberof Model
+ * @param {Node} node
+ * @param {Node} target
+ * @param {int} index
+ */
+ this.model.trigger('move', this, target, index);
+ }
+ }
+};
+
+
+/**
+ * Group object
+ * @constructor
+ * @extends Node
+ * @param {Group} [parent]
+ * @param {jQuery} $el
+ */
+var Group = function(parent, $el) {
+ if (!(this instanceof Group)) {
+ return new Group(parent, $el);
+ }
+
+ Node.call(this, parent, $el);
+
+ /**
+ * @member {object[]}
+ * @readonly
+ */
+ this.rules = [];
+
+ /**
+ * @name condition
+ * @member {string}
+ * @memberof Group
+ * @instance
+ */
+ this.__.condition = null;
+};
+
+Group.prototype = Object.create(Node.prototype);
+Group.prototype.constructor = Group;
+
+Utils.defineModelProperties(Group, ['condition']);
+
+/**
+ * Removes group's content
+ */
+Group.prototype.empty = function() {
+ this.each('reverse', function(rule) {
+ rule.drop();
+ }, function(group) {
+ group.drop();
+ });
+};
+
+/**
+ * Deletes self
+ */
+Group.prototype.drop = function() {
+ this.empty();
+ Node.prototype.drop.call(this);
+};
+
+/**
+ * Returns the number of children
+ * @returns {int}
+ */
+Group.prototype.length = function() {
+ return this.rules.length;
+};
+
+/**
+ * Adds a Node at specified index
+ * @param {Node} node
+ * @param {int} [index=end]
+ * @param {boolean} [trigger=false] - fire 'add' event
+ * @returns {Node} the inserted node
+ * @fires Model.model:add
+ */
+Group.prototype.insertNode = function(node, index, trigger) {
+ if (index === undefined) {
+ index = this.length();
+ }
+
+ this.rules.splice(index, 0, node);
+ node.parent = this;
+
+ if (trigger && this.model !== null) {
+ /**
+ * After a node of the model has been added
+ * @event model:add
+ * @memberof Model
+ * @param {Node} parent
+ * @param {Node} node
+ * @param {int} index
+ */
+ this.model.trigger('add', this, node, index);
+ }
+
+ return node;
+};
+
+/**
+ * Adds a new Group at specified index
+ * @param {jQuery} $el
+ * @param {int} [index=end]
+ * @returns {Group}
+ * @fires Model.model:add
+ */
+Group.prototype.addGroup = function($el, index) {
+ return this.insertNode(new Group(this, $el), index, true);
+};
+
+/**
+ * Adds a new Rule at specified index
+ * @param {jQuery} $el
+ * @param {int} [index=end]
+ * @returns {Rule}
+ * @fires Model.model:add
+ */
+Group.prototype.addRule = function($el, index) {
+ return this.insertNode(new Rule(this, $el), index, true);
+};
+
+/**
+ * Deletes a specific Node
+ * @param {Node} node
+ */
+Group.prototype.removeNode = function(node) {
+ var index = this.getNodePos(node);
+ if (index !== -1) {
+ node.parent = null;
+ this.rules.splice(index, 1);
+ }
+};
+
+/**
+ * Returns the position of a child Node
+ * @param {Node} node
+ * @returns {int}
+ */
+Group.prototype.getNodePos = function(node) {
+ return this.rules.indexOf(node);
+};
+
+/**
+ * @callback Model#GroupIteratee
+ * @param {Node} node
+ * @returns {boolean} stop the iteration
+ */
+
+/**
+ * Iterate over all Nodes
+ * @param {boolean} [reverse=false] - iterate in reverse order, required if you delete nodes
+ * @param {Model#GroupIteratee} cbRule - callback for Rules (can be `null` but not omitted)
+ * @param {Model#GroupIteratee} [cbGroup] - callback for Groups
+ * @param {object} [context] - context for callbacks
+ * @returns {boolean} if the iteration has been stopped by a callback
+ */
+Group.prototype.each = function(reverse, cbRule, cbGroup, context) {
+ if (typeof reverse !== 'boolean' && typeof reverse !== 'string') {
+ context = cbGroup;
+ cbGroup = cbRule;
+ cbRule = reverse;
+ reverse = false;
+ }
+ context = context === undefined ? null : context;
+
+ var i = reverse ? this.rules.length - 1 : 0;
+ var l = reverse ? 0 : this.rules.length - 1;
+ var c = reverse ? -1 : 1;
+ var next = function() {
+ return reverse ? i >= l : i <= l;
+ };
+ var stop = false;
+
+ for (; next(); i += c) {
+ if (this.rules[i] instanceof Group) {
+ if (!!cbGroup) {
+ stop = cbGroup.call(context, this.rules[i]) === false;
+ }
+ }
+ else if (!!cbRule) {
+ stop = cbRule.call(context, this.rules[i]) === false;
+ }
+
+ if (stop) {
+ break;
+ }
+ }
+
+ return !stop;
+};
+
+/**
+ * Checks if the group contains a particular Node
+ * @param {Node} node
+ * @param {boolean} [recursive=false]
+ * @returns {boolean}
+ */
+Group.prototype.contains = function(node, recursive) {
+ if (this.getNodePos(node) !== -1) {
+ return true;
+ }
+ else if (!recursive) {
+ return false;
+ }
+ else {
+ // the loop will return with false as soon as the Node is found
+ return !this.each(function() {
+ return true;
+ }, function(group) {
+ return !group.contains(node, true);
+ });
+ }
+};
+
+
+/**
+ * Rule object
+ * @constructor
+ * @extends Node
+ * @param {Group} parent
+ * @param {jQuery} $el
+ */
+var Rule = function(parent, $el) {
+ if (!(this instanceof Rule)) {
+ return new Rule(parent, $el);
+ }
+
+ Node.call(this, parent, $el);
+
+ this._updating_value = false;
+ this._updating_input = false;
+
+ /**
+ * @name filter
+ * @member {QueryBuilder.Filter}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.filter = null;
+
+ /**
+ * @name operator
+ * @member {QueryBuilder.Operator}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.operator = null;
+
+ /**
+ * @name value
+ * @member {*}
+ * @memberof Rule
+ * @instance
+ */
+ this.__.value = undefined;
+};
+
+Rule.prototype = Object.create(Node.prototype);
+Rule.prototype.constructor = Rule;
+
+Utils.defineModelProperties(Rule, ['filter', 'operator', 'value']);
+
+/**
+ * Checks if this Node is the root
+ * @returns {boolean} always false
+ */
+Rule.prototype.isRoot = function() {
+ return false;
+};
+
+
+/**
+ * @member {function}
+ * @memberof QueryBuilder
+ * @see Group
+ */
+QueryBuilder.Group = Group;
+
+/**
+ * @member {function}
+ * @memberof QueryBuilder
+ * @see Rule
+ */
+QueryBuilder.Rule = Rule;
+
+
+/**
+ * The {@link http://learn.jquery.com/plugins/|jQuery Plugins} namespace
+ * @external "jQuery.fn"
+ */
+
+/**
+ * Instanciates or accesses the {@link QueryBuilder} on an element
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @param {*} option - initial configuration or method name
+ * @param {...*} args - method arguments
+ *
+ * @example
+ * $('#builder').queryBuilder({ /** configuration object *\/ });
+ * @example
+ * $('#builder').queryBuilder('methodName', methodParam1, methodParam2);
+ */
+$.fn.queryBuilder = function(option) {
+ if (this.length === 0) {
+ Utils.error('Config', 'No target defined');
+ }
+ if (this.length > 1) {
+ Utils.error('Config', 'Unable to initialize on multiple target');
+ }
+
+ var data = this.data('queryBuilder');
+ var options = (typeof option == 'object' && option) || {};
+
+ if (!data && option == 'destroy') {
+ return this;
+ }
+ if (!data) {
+ var builder = new QueryBuilder(this, options);
+ this.data('queryBuilder', builder);
+ builder.init(options.rules);
+ }
+ if (typeof option == 'string') {
+ return data[option].apply(data, Array.prototype.slice.call(arguments, 1));
+ }
+
+ return this;
+};
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder
+ */
+$.fn.queryBuilder.constructor = QueryBuilder;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.defaults
+ */
+$.fn.queryBuilder.defaults = QueryBuilder.defaults;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.defaults
+ */
+$.fn.queryBuilder.extend = QueryBuilder.extend;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.define
+ */
+$.fn.queryBuilder.define = QueryBuilder.define;
+
+/**
+ * @function
+ * @memberof external:"jQuery.fn"
+ * @see QueryBuilder.regional
+ */
+$.fn.queryBuilder.regional = QueryBuilder.regional;
+
+
+/**
+ * @class BtCheckbox
+ * @memberof module:plugins
+ * @description Applies Awesome Bootstrap Checkbox for checkbox and radio inputs.
+ * @param {object} [options]
+ * @param {string} [options.font='glyphicons']
+ * @param {string} [options.color='default']
+ */
+QueryBuilder.define('bt-checkbox', function(options) {
+ if (options.font == 'glyphicons') {
+ this.$el.addClass('bt-checkbox-glyphicons');
+ }
+
+ this.on('getRuleInput.filter', function(h, rule, name) {
+ var filter = rule.filter;
+
+ if ((filter.input === 'radio' || filter.input === 'checkbox') && !filter.plugin) {
+ h.value = '';
+
+ if (!filter.colors) {
+ filter.colors = {};
+ }
+ if (filter.color) {
+ filter.colors._def_ = filter.color;
+ }
+
+ var style = filter.vertical ? ' style="display:block"' : '';
+ var i = 0;
+
+ Utils.iterateOptions(filter.values, function(key, val) {
+ var color = filter.colors[key] || filter.colors._def_ || options.color;
+ var id = name + '_' + (i++);
+
+ h.value+= '\
+ \
+ \
+ ' + val + ' \
+
';
+ });
+ }
+ });
+}, {
+ font: 'glyphicons',
+ color: 'default'
+});
+
+
+/**
+ * @class BtSelectpicker
+ * @memberof module:plugins
+ * @descriptioon Applies Bootstrap Select on filters and operators combo-boxes.
+ * @param {object} [options]
+ * @param {string} [options.container='body']
+ * @param {string} [options.style='btn-inverse btn-xs']
+ * @param {int|string} [options.width='auto']
+ * @param {boolean} [options.showIcon=false]
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('bt-selectpicker', function(options) {
+ if (!$.fn.selectpicker || !$.fn.selectpicker.Constructor) {
+ Utils.error('MissingLibrary', 'Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select');
+ }
+
+ var Selectors = QueryBuilder.selectors;
+
+ // init selectpicker
+ this.on('afterCreateRuleFilters', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).removeClass('form-control').selectpicker(options);
+ });
+
+ this.on('afterCreateRuleOperators', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).removeClass('form-control').selectpicker(options);
+ });
+
+ // update selectpicker on change
+ this.on('afterUpdateRuleFilter', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).selectpicker('render');
+ });
+
+ this.on('afterUpdateRuleOperator', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).selectpicker('render');
+ });
+
+ this.on('beforeDeleteRule', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).selectpicker('destroy');
+ rule.$el.find(Selectors.rule_operator).selectpicker('destroy');
+ });
+}, {
+ container: 'body',
+ style: 'btn-inverse btn-xs',
+ width: 'auto',
+ showIcon: false
+});
+
+
+/**
+ * @class BtTooltipErrors
+ * @memberof module:plugins
+ * @description Applies Bootstrap Tooltips on validation error messages.
+ * @param {object} [options]
+ * @param {string} [options.placement='right']
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('bt-tooltip-errors', function(options) {
+ if (!$.fn.tooltip || !$.fn.tooltip.Constructor || !$.fn.tooltip.Constructor.prototype.fixTitle) {
+ Utils.error('MissingLibrary', 'Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com');
+ }
+
+ var self = this;
+
+ // add BT Tooltip data
+ this.on('getRuleTemplate.filter getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.error_container).attr('data-toggle', 'tooltip');
+ h.value = $h.prop('outerHTML');
+ });
+
+ // init/refresh tooltip when title changes
+ this.model.on('update', function(e, node, field) {
+ if (field == 'error' && self.settings.display_errors) {
+ node.$el.find(QueryBuilder.selectors.error_container).eq(0)
+ .tooltip(options)
+ .tooltip('hide')
+ .tooltip('fixTitle');
+ }
+ });
+}, {
+ placement: 'right'
+});
+
+
+/**
+ * @class ChangeFilters
+ * @memberof module:plugins
+ * @description Allows to change available filters after plugin initialization.
+ */
+
+QueryBuilder.extend(/** @lends module:plugins.ChangeFilters.prototype */ {
+ /**
+ * Change the filters of the builder
+ * @param {boolean} [deleteOrphans=false] - delete rules using old filters
+ * @param {QueryBuilder[]} filters
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ setFilters: function(deleteOrphans, filters) {
+ var self = this;
+
+ if (filters === undefined) {
+ filters = deleteOrphans;
+ deleteOrphans = false;
+ }
+
+ filters = this.checkFilters(filters);
+
+ /**
+ * Modifies the filters before {@link module:plugins.ChangeFilters.setFilters} method
+ * @event changer:setFilters
+ * @memberof module:plugins.ChangeFilters
+ * @param {QueryBuilder.Filter[]} filters
+ * @returns {QueryBuilder.Filter[]}
+ */
+ filters = this.change('setFilters', filters);
+
+ var filtersIds = filters.map(function(filter) {
+ return filter.id;
+ });
+
+ // check for orphans
+ if (!deleteOrphans) {
+ (function checkOrphans(node) {
+ node.each(
+ function(rule) {
+ if (rule.filter && filtersIds.indexOf(rule.filter.id) === -1) {
+ Utils.error('ChangeFilter', 'A rule is using filter "{0}"', rule.filter.id);
+ }
+ },
+ checkOrphans
+ );
+ }(this.model.root));
+ }
+
+ // replace filters
+ this.filters = filters;
+
+ // apply on existing DOM
+ (function updateBuilder(node) {
+ node.each(true,
+ function(rule) {
+ if (rule.filter && filtersIds.indexOf(rule.filter.id) === -1) {
+ rule.drop();
+
+ self.trigger('rulesChanged');
+ }
+ else {
+ self.createRuleFilters(rule);
+
+ rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
+ self.trigger('afterUpdateRuleFilter', rule);
+ }
+ },
+ updateBuilder
+ );
+ }(this.model.root));
+
+ // update plugins
+ if (this.settings.plugins) {
+ if (this.settings.plugins['unique-filter']) {
+ this.updateDisabledFilters();
+ }
+ if (this.settings.plugins['bt-selectpicker']) {
+ this.$el.find(QueryBuilder.selectors.rule_filter).selectpicker('render');
+ }
+ }
+
+ // reset the default_filter if does not exist anymore
+ if (this.settings.default_filter) {
+ try {
+ this.getFilterById(this.settings.default_filter);
+ }
+ catch (e) {
+ this.settings.default_filter = null;
+ }
+ }
+
+ /**
+ * After {@link module:plugins.ChangeFilters.setFilters} method
+ * @event afterSetFilters
+ * @memberof module:plugins.ChangeFilters
+ * @param {QueryBuilder.Filter[]} filters
+ */
+ this.trigger('afterSetFilters', filters);
+ },
+
+ /**
+ * Adds a new filter to the builder
+ * @param {QueryBuilder.Filter|Filter[]} newFilters
+ * @param {int|string} [position=#end] - index or '#start' or '#end'
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ addFilter: function(newFilters, position) {
+ if (position === undefined || position == '#end') {
+ position = this.filters.length;
+ }
+ else if (position == '#start') {
+ position = 0;
+ }
+
+ if (!$.isArray(newFilters)) {
+ newFilters = [newFilters];
+ }
+
+ var filters = $.extend(true, [], this.filters);
+
+ // numeric position
+ if (parseInt(position) == position) {
+ Array.prototype.splice.apply(filters, [position, 0].concat(newFilters));
+ }
+ else {
+ // after filter by its id
+ if (this.filters.some(function(filter, index) {
+ if (filter.id == position) {
+ position = index + 1;
+ return true;
+ }
+ })
+ ) {
+ Array.prototype.splice.apply(filters, [position, 0].concat(newFilters));
+ }
+ // defaults to end of list
+ else {
+ Array.prototype.push.apply(filters, newFilters);
+ }
+ }
+
+ this.setFilters(filters);
+ },
+
+ /**
+ * Removes a filter from the builder
+ * @param {string|string[]} filterIds
+ * @param {boolean} [deleteOrphans=false] delete rules using old filters
+ * @fires module:plugins.ChangeFilters.changer:setFilters
+ * @fires module:plugins.ChangeFilters.afterSetFilters
+ * @throws ChangeFilterError
+ */
+ removeFilter: function(filterIds, deleteOrphans) {
+ var filters = $.extend(true, [], this.filters);
+ if (typeof filterIds === 'string') {
+ filterIds = [filterIds];
+ }
+
+ filters = filters.filter(function(filter) {
+ return filterIds.indexOf(filter.id) === -1;
+ });
+
+ this.setFilters(deleteOrphans, filters);
+ }
+});
+
+
+/**
+ * @class ChosenSelectpicker
+ * @memberof module:plugins
+ * @descriptioon Applies chosen-js Select on filters and operators combo-boxes.
+ * @param {object} [options] Supports all the options for chosen
+ * @throws MissingLibraryError
+ */
+QueryBuilder.define('chosen-selectpicker', function(options) {
+
+ if (!$.fn.chosen) {
+ Utils.error('MissingLibrary', 'chosen is required to use "chosen-selectpicker" plugin. Get it here: https://github.com/harvesthq/chosen');
+ }
+
+ if (this.settings.plugins['bt-selectpicker']) {
+ Utils.error('Conflict', 'bt-selectpicker is already selected as the dropdown plugin. Please remove chosen-selectpicker from the plugin list');
+ }
+
+ var Selectors = QueryBuilder.selectors;
+
+ // init selectpicker
+ this.on('afterCreateRuleFilters', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).removeClass('form-control').chosen(options);
+ });
+
+ this.on('afterCreateRuleOperators', function(e, rule) {
+ if (e.builder.getOperators(rule.filter).length > 1) {
+ rule.$el.find(Selectors.rule_operator).removeClass('form-control').chosen(options);
+ }
+ });
+
+ // update selectpicker on change
+ this.on('afterUpdateRuleFilter', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).trigger('chosen:updated');
+ });
+
+ this.on('afterUpdateRuleOperator', function(e, rule) {
+ rule.$el.find(Selectors.rule_operator).trigger('chosen:updated');
+ });
+
+ this.on('beforeDeleteRule', function(e, rule) {
+ rule.$el.find(Selectors.rule_filter).chosen('destroy');
+ rule.$el.find(Selectors.rule_operator).chosen('destroy');
+ });
+});
+
+
+/**
+ * @class FilterDescription
+ * @memberof module:plugins
+ * @description Provides three ways to display a description about a filter: inline, Bootsrap Popover or Bootbox.
+ * @param {object} [options]
+ * @param {string} [options.icon='glyphicon glyphicon-info-sign']
+ * @param {string} [options.mode='popover'] - inline, popover or bootbox
+ * @throws ConfigError
+ */
+QueryBuilder.define('filter-description', function(options) {
+ // INLINE
+ if (options.mode === 'inline') {
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $p = rule.$el.find('p.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $p.hide();
+ }
+ else {
+ if ($p.length === 0) {
+ $p = $('
');
+ $p.appendTo(rule.$el);
+ }
+ else {
+ $p.css('display', '');
+ }
+
+ $p.html(' ' + description);
+ }
+ });
+ }
+ // POPOVER
+ else if (options.mode === 'popover') {
+ if (!$.fn.popover || !$.fn.popover.Constructor || !$.fn.popover.Constructor.prototype.fixTitle) {
+ Utils.error('MissingLibrary', 'Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com');
+ }
+
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $b = rule.$el.find('button.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $b.hide();
+
+ if ($b.data('bs.popover')) {
+ $b.popover('hide');
+ }
+ }
+ else {
+ if ($b.length === 0) {
+ $b = $(' ');
+ $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions));
+
+ $b.popover({
+ placement: 'left',
+ container: 'body',
+ html: true
+ });
+
+ $b.on('mouseout', function() {
+ $b.popover('hide');
+ });
+ }
+ else {
+ $b.css('display', '');
+ }
+
+ $b.data('bs.popover').options.content = description;
+
+ if ($b.attr('aria-describedby')) {
+ $b.popover('show');
+ }
+ }
+ });
+ }
+ // BOOTBOX
+ else if (options.mode === 'bootbox') {
+ if (!('bootbox' in window)) {
+ Utils.error('MissingLibrary', 'Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com');
+ }
+
+ this.on('afterUpdateRuleFilter afterUpdateRuleOperator', function(e, rule) {
+ var $b = rule.$el.find('button.filter-description');
+ var description = e.builder.getFilterDescription(rule.filter, rule);
+
+ if (!description) {
+ $b.hide();
+ }
+ else {
+ if ($b.length === 0) {
+ $b = $(' ');
+ $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions));
+
+ $b.on('click', function() {
+ bootbox.alert($b.data('description'));
+ });
+ }
+ else {
+ $b.css('display', '');
+ }
+
+ $b.data('description', description);
+ }
+ });
+ }
+}, {
+ icon: 'glyphicon glyphicon-info-sign',
+ mode: 'popover'
+});
+
+QueryBuilder.extend(/** @lends module:plugins.FilterDescription.prototype */ {
+ /**
+ * Returns the description of a filter for a particular rule (if present)
+ * @param {object} filter
+ * @param {Rule} [rule]
+ * @returns {string}
+ * @private
+ */
+ getFilterDescription: function(filter, rule) {
+ if (!filter) {
+ return undefined;
+ }
+ else if (typeof filter.description == 'function') {
+ return filter.description.call(this, rule);
+ }
+ else {
+ return filter.description;
+ }
+ }
+});
+
+
+/**
+ * @class Invert
+ * @memberof module:plugins
+ * @description Allows to invert a rule operator, a group condition or the entire builder.
+ * @param {object} [options]
+ * @param {string} [options.icon='glyphicon glyphicon-random']
+ * @param {boolean} [options.recursive=true]
+ * @param {boolean} [options.invert_rules=true]
+ * @param {boolean} [options.display_rules_button=false]
+ * @param {boolean} [options.silent_fail=false]
+ */
+QueryBuilder.define('invert', function(options) {
+ var self = this;
+ var Selectors = QueryBuilder.selectors;
+
+ // Bind events
+ this.on('afterInit', function() {
+ self.$el.on('click.queryBuilder', '[data-invert=group]', function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.invert(self.getModel($group), options);
+ });
+
+ if (options.display_rules_button && options.invert_rules) {
+ self.$el.on('click.queryBuilder', '[data-invert=rule]', function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.invert(self.getModel($rule), options);
+ });
+ }
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(Selectors.condition_container).after(
+ '' +
+ ' ' + self.translate('invert') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+
+ if (options.display_rules_button && options.invert_rules) {
+ this.on('getRuleTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(Selectors.rule_actions).prepend(
+ '' +
+ ' ' + self.translate('invert') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+ }
+ }
+}, {
+ icon: 'glyphicon glyphicon-random',
+ recursive: true,
+ invert_rules: true,
+ display_rules_button: false,
+ silent_fail: false,
+ disable_template: false
+});
+
+QueryBuilder.defaults({
+ operatorOpposites: {
+ 'equal': 'not_equal',
+ 'not_equal': 'equal',
+ 'in': 'not_in',
+ 'not_in': 'in',
+ 'less': 'greater_or_equal',
+ 'less_or_equal': 'greater',
+ 'greater': 'less_or_equal',
+ 'greater_or_equal': 'less',
+ 'between': 'not_between',
+ 'not_between': 'between',
+ 'begins_with': 'not_begins_with',
+ 'not_begins_with': 'begins_with',
+ 'contains': 'not_contains',
+ 'not_contains': 'contains',
+ 'ends_with': 'not_ends_with',
+ 'not_ends_with': 'ends_with',
+ 'is_empty': 'is_not_empty',
+ 'is_not_empty': 'is_empty',
+ 'is_null': 'is_not_null',
+ 'is_not_null': 'is_null'
+ },
+
+ conditionOpposites: {
+ 'AND': 'OR',
+ 'OR': 'AND'
+ }
+});
+
+QueryBuilder.extend(/** @lends module:plugins.Invert.prototype */ {
+ /**
+ * Invert a Group, a Rule or the whole builder
+ * @param {Node} [node]
+ * @param {object} [options] {@link module:plugins.Invert}
+ * @fires module:plugins.Invert.afterInvert
+ * @throws InvertConditionError, InvertOperatorError
+ */
+ invert: function(node, options) {
+ if (!(node instanceof Node)) {
+ if (!this.model.root) return;
+ options = node;
+ node = this.model.root;
+ }
+
+ if (typeof options != 'object') options = {};
+ if (options.recursive === undefined) options.recursive = true;
+ if (options.invert_rules === undefined) options.invert_rules = true;
+ if (options.silent_fail === undefined) options.silent_fail = false;
+ if (options.trigger === undefined) options.trigger = true;
+
+ if (node instanceof Group) {
+ // invert group condition
+ if (this.settings.conditionOpposites[node.condition]) {
+ node.condition = this.settings.conditionOpposites[node.condition];
+ }
+ else if (!options.silent_fail) {
+ Utils.error('InvertCondition', 'Unknown inverse of condition "{0}"', node.condition);
+ }
+
+ // recursive call
+ if (options.recursive) {
+ var tempOpts = $.extend({}, options, { trigger: false });
+ node.each(function(rule) {
+ if (options.invert_rules) {
+ this.invert(rule, tempOpts);
+ }
+ }, function(group) {
+ this.invert(group, tempOpts);
+ }, this);
+ }
+ }
+ else if (node instanceof Rule) {
+ if (node.operator && !node.filter.no_invert) {
+ // invert rule operator
+ if (this.settings.operatorOpposites[node.operator.type]) {
+ var invert = this.settings.operatorOpposites[node.operator.type];
+ // check if the invert is "authorized"
+ if (!node.filter.operators || node.filter.operators.indexOf(invert) != -1) {
+ node.operator = this.getOperatorByType(invert);
+ }
+ }
+ else if (!options.silent_fail) {
+ Utils.error('InvertOperator', 'Unknown inverse of operator "{0}"', node.operator.type);
+ }
+ }
+ }
+
+ if (options.trigger) {
+ /**
+ * After {@link module:plugins.Invert.invert} method
+ * @event afterInvert
+ * @memberof module:plugins.Invert
+ * @param {Node} node - the main group or rule that has been modified
+ * @param {object} options
+ */
+ this.trigger('afterInvert', node, options);
+
+ this.trigger('rulesChanged');
+ }
+ }
+});
+
+
+/**
+ * @class MongoDbSupport
+ * @memberof module:plugins
+ * @description Allows to export rules as a MongoDB find object as well as populating the builder from a MongoDB object.
+ */
+
+QueryBuilder.defaults({
+ mongoOperators: {
+ // @formatter:off
+ equal: function(v) { return v[0]; },
+ not_equal: function(v) { return { '$ne': v[0] }; },
+ in: function(v) { return { '$in': v }; },
+ not_in: function(v) { return { '$nin': v }; },
+ less: function(v) { return { '$lt': v[0] }; },
+ less_or_equal: function(v) { return { '$lte': v[0] }; },
+ greater: function(v) { return { '$gt': v[0] }; },
+ greater_or_equal: function(v) { return { '$gte': v[0] }; },
+ between: function(v) { return { '$gte': v[0], '$lte': v[1] }; },
+ not_between: function(v) { return { '$lt': v[0], '$gt': v[1] }; },
+ begins_with: function(v) { return { '$regex': '^' + Utils.escapeRegExp(v[0]) }; },
+ not_begins_with: function(v) { return { '$regex': '^(?!' + Utils.escapeRegExp(v[0]) + ')' }; },
+ contains: function(v) { return { '$regex': Utils.escapeRegExp(v[0]) }; },
+ not_contains: function(v) { return { '$regex': '^((?!' + Utils.escapeRegExp(v[0]) + ').)*$', '$options': 's' }; },
+ ends_with: function(v) { return { '$regex': Utils.escapeRegExp(v[0]) + '$' }; },
+ not_ends_with: function(v) { return { '$regex': '(? 0) {
+ parts.push(parse(rule));
+ }
+ else {
+ var mdb = self.settings.mongoOperators[rule.operator];
+ var ope = self.getOperatorByType(rule.operator);
+
+ if (mdb === undefined) {
+ Utils.error('UndefinedMongoOperator', 'Unknown MongoDB operation for operator "{0}"', rule.operator);
+ }
+
+ if (ope.nb_inputs !== 0) {
+ if (!(rule.value instanceof Array)) {
+ rule.value = [rule.value];
+ }
+ }
+
+ /**
+ * Modifies the MongoDB field used by a rule
+ * @event changer:getMongoDBField
+ * @memberof module:plugins.MongoDbSupport
+ * @param {string} field
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ var field = self.change('getMongoDBField', rule.field, rule);
+
+ var ruleExpression = {};
+ ruleExpression[field] = mdb.call(self, rule.value);
+
+ /**
+ * Modifies the MongoDB expression generated for a rul
+ * @event changer:ruleToMongo
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @param {Rule} rule
+ * @param {*} value
+ * @param {function} valueWrapper - function that takes the value and adds the operator
+ * @returns {object}
+ */
+ parts.push(self.change('ruleToMongo', ruleExpression, rule, rule.value, mdb));
+ }
+ });
+
+ var groupExpression = {};
+ groupExpression['$' + group.condition.toLowerCase()] = parts;
+
+ /**
+ * Modifies the MongoDB expression generated for a group
+ * @event changer:groupToMongo
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @param {Group} group
+ * @returns {object}
+ */
+ return self.change('groupToMongo', groupExpression, group);
+ }(data));
+ },
+
+ /**
+ * Converts a MongoDB query to rules
+ * @param {object} query
+ * @returns {object}
+ * @fires module:plugins.MongoDbSupport.changer:parseMongoNode
+ * @fires module:plugins.MongoDbSupport.changer:getMongoDBFieldID
+ * @fires module:plugins.MongoDbSupport.changer:mongoToRule
+ * @fires module:plugins.MongoDbSupport.changer:mongoToGroup
+ * @throws MongoParseError, UndefinedMongoConditionError, UndefinedMongoOperatorError
+ */
+ getRulesFromMongo: function(query) {
+ if (query === undefined || query === null) {
+ return null;
+ }
+
+ var self = this;
+
+ /**
+ * Custom parsing of a MongoDB expression, you can return a sub-part of the expression, or a well formed group or rule JSON
+ * @event changer:parseMongoNode
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} expression
+ * @returns {object} expression, rule or group
+ */
+ query = self.change('parseMongoNode', query);
+
+ // a plugin returned a group
+ if ('rules' in query && 'condition' in query) {
+ return query;
+ }
+
+ // a plugin returned a rule
+ if ('id' in query && 'operator' in query && 'value' in query) {
+ return {
+ condition: this.settings.default_condition,
+ rules: [query]
+ };
+ }
+
+ var key = self.getMongoCondition(query);
+ if (!key) {
+ Utils.error('MongoParse', 'Invalid MongoDB query format');
+ }
+
+ return (function parse(data, topKey) {
+ var rules = data[topKey];
+ var parts = [];
+
+ rules.forEach(function(data) {
+ // allow plugins to manually parse or handle special cases
+ data = self.change('parseMongoNode', data);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ parts.push(data);
+ return;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ parts.push(data);
+ return;
+ }
+
+ var key = self.getMongoCondition(data);
+ if (key) {
+ parts.push(parse(data, key));
+ }
+ else {
+ var field = Object.keys(data)[0];
+ var value = data[field];
+
+ var operator = self.getMongoOperator(value);
+ if (operator === undefined) {
+ Utils.error('MongoParse', 'Invalid MongoDB query format');
+ }
+
+ var mdbrl = self.settings.mongoRuleOperators[operator];
+ if (mdbrl === undefined) {
+ Utils.error('UndefinedMongoOperator', 'JSON Rule operation unknown for operator "{0}"', operator);
+ }
+
+ var opVal = mdbrl.call(self, value);
+
+ var id = self.getMongoDBFieldID(field, value);
+
+ /**
+ * Modifies the rule generated from the MongoDB expression
+ * @event changer:mongoToRule
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} rule
+ * @param {object} expression
+ * @returns {object}
+ */
+ var rule = self.change('mongoToRule', {
+ id: id,
+ field: field,
+ operator: opVal.op,
+ value: opVal.val
+ }, data);
+
+ parts.push(rule);
+ }
+ });
+
+ /**
+ * Modifies the group generated from the MongoDB expression
+ * @event changer:mongoToGroup
+ * @memberof module:plugins.MongoDbSupport
+ * @param {object} group
+ * @param {object} expression
+ * @returns {object}
+ */
+ return self.change('mongoToGroup', {
+ condition: topKey.replace('$', '').toUpperCase(),
+ rules: parts
+ }, data);
+ }(query, key));
+ },
+
+ /**
+ * Sets rules a from MongoDB query
+ * @see module:plugins.MongoDbSupport.getRulesFromMongo
+ */
+ setRulesFromMongo: function(query) {
+ this.setRules(this.getRulesFromMongo(query));
+ },
+
+ /**
+ * Returns a filter identifier from the MongoDB field.
+ * Automatically use the only one filter with a matching field, fires a changer otherwise.
+ * @param {string} field
+ * @param {*} value
+ * @fires module:plugins.MongoDbSupport:changer:getMongoDBFieldID
+ * @returns {string}
+ * @private
+ */
+ getMongoDBFieldID: function(field, value) {
+ var matchingFilters = this.filters.filter(function(filter) {
+ return filter.field === field;
+ });
+
+ var id;
+ if (matchingFilters.length === 1) {
+ id = matchingFilters[0].id;
+ }
+ else {
+ /**
+ * Returns a filter identifier from the MongoDB field
+ * @event changer:getMongoDBFieldID
+ * @memberof module:plugins.MongoDbSupport
+ * @param {string} field
+ * @param {*} value
+ * @returns {string}
+ */
+ id = this.change('getMongoDBFieldID', field, value);
+ }
+
+ return id;
+ },
+
+ /**
+ * Finds which operator is used in a MongoDB sub-object
+ * @param {*} data
+ * @returns {string|undefined}
+ * @private
+ */
+ getMongoOperator: function(data) {
+ if (data !== null && typeof data === 'object') {
+ if (data.$gte !== undefined && data.$lte !== undefined) {
+ return 'between';
+ }
+ if (data.$lt !== undefined && data.$gt !== undefined) {
+ return 'not_between';
+ }
+
+ var knownKeys = Object.keys(data).filter(function(key) {
+ return !!this.settings.mongoRuleOperators[key];
+ }.bind(this));
+
+ if (knownKeys.length === 1) {
+ return knownKeys[0];
+ }
+ }
+ else {
+ return '$eq';
+ }
+ },
+
+
+ /**
+ * Returns the key corresponding to "$or" or "$and"
+ * @param {object} data
+ * @returns {string|undefined}
+ * @private
+ */
+ getMongoCondition: function(data) {
+ var keys = Object.keys(data);
+
+ for (var i = 0, l = keys.length; i < l; i++) {
+ if (keys[i].toLowerCase() === '$or' || keys[i].toLowerCase() === '$and') {
+ return keys[i];
+ }
+ }
+ }
+});
+
+
+/**
+ * @class NotGroup
+ * @memberof module:plugins
+ * @description Adds a "Not" checkbox in front of group conditions.
+ * @param {object} [options]
+ * @param {string} [options.icon_checked='glyphicon glyphicon-checked']
+ * @param {string} [options.icon_unchecked='glyphicon glyphicon-unchecked']
+ */
+QueryBuilder.define('not-group', function(options) {
+ var self = this;
+
+ // Bind events
+ this.on('afterInit', function() {
+ self.$el.on('click.queryBuilder', '[data-not=group]', function() {
+ var $group = $(this).closest(QueryBuilder.selectors.group_container);
+ var group = self.getModel($group);
+ group.not = !group.not;
+ });
+
+ self.model.on('update', function(e, node, field) {
+ if (node instanceof Group && field === 'not') {
+ self.updateGroupNot(node);
+ }
+ });
+ });
+
+ // Init "not" property
+ this.on('afterAddGroup', function(e, group) {
+ group.__.not = false;
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.condition_container).prepend(
+ '' +
+ ' ' + self.translate('NOT') +
+ ' '
+ );
+ h.value = $h.prop('outerHTML');
+ });
+ }
+
+ // Export "not" to JSON
+ this.on('groupToJson.filter', function(e, group) {
+ e.value.not = group.not;
+ });
+
+ // Read "not" from JSON
+ this.on('jsonToGroup.filter', function(e, json) {
+ e.value.not = !!json.not;
+ });
+
+ // Export "not" to SQL
+ this.on('groupToSQL.filter', function(e, group) {
+ if (group.not) {
+ e.value = 'NOT ( ' + e.value + ' )';
+ }
+ });
+
+ // Parse "NOT" function from sqlparser
+ this.on('parseSQLNode.filter', function(e) {
+ if (e.value.name && e.value.name.toUpperCase() == 'NOT') {
+ e.value = e.value.arguments.value[0];
+
+ // if the there is no sub-group, create one
+ if (['AND', 'OR'].indexOf(e.value.operation.toUpperCase()) === -1) {
+ e.value = new SQLParser.nodes.Op(
+ self.settings.default_condition,
+ e.value,
+ null
+ );
+ }
+
+ e.value.not = true;
+ }
+ });
+
+ // Request to create sub-group if the "not" flag is set
+ this.on('sqlGroupsDistinct.filter', function(e, group, data, i) {
+ if (data.not && i > 0) {
+ e.value = true;
+ }
+ });
+
+ // Read "not" from parsed SQL
+ this.on('sqlToGroup.filter', function(e, data) {
+ e.value.not = !!data.not;
+ });
+
+ // Export "not" to Mongo
+ this.on('groupToMongo.filter', function(e, group) {
+ var key = '$' + group.condition.toLowerCase();
+ if (group.not && e.value[key]) {
+ e.value = { '$nor': [e.value] };
+ }
+ });
+
+ // Parse "$nor" operator from Mongo
+ this.on('parseMongoNode.filter', function(e) {
+ var keys = Object.keys(e.value);
+
+ if (keys[0] == '$nor') {
+ e.value = e.value[keys[0]][0];
+ e.value.not = true;
+ }
+ });
+
+ // Read "not" from parsed Mongo
+ this.on('mongoToGroup.filter', function(e, data) {
+ e.value.not = !!data.not;
+ });
+}, {
+ icon_unchecked: 'glyphicon glyphicon-unchecked',
+ icon_checked: 'glyphicon glyphicon-check',
+ disable_template: false
+});
+
+/**
+ * From {@link module:plugins.NotGroup}
+ * @name not
+ * @member {boolean}
+ * @memberof Group
+ * @instance
+ */
+Utils.defineModelProperties(Group, ['not']);
+
+QueryBuilder.selectors.group_not = QueryBuilder.selectors.group_header + ' [data-not=group]';
+
+QueryBuilder.extend(/** @lends module:plugins.NotGroup.prototype */ {
+ /**
+ * Performs actions when a group's not changes
+ * @param {Group} group
+ * @fires module:plugins.NotGroup.afterUpdateGroupNot
+ * @private
+ */
+ updateGroupNot: function(group) {
+ var options = this.plugins['not-group'];
+ group.$el.find('>' + QueryBuilder.selectors.group_not)
+ .toggleClass('active', group.not)
+ .find('i').attr('class', group.not ? options.icon_checked : options.icon_unchecked);
+
+ /**
+ * After the group's not flag has been modified
+ * @event afterUpdateGroupNot
+ * @memberof module:plugins.NotGroup
+ * @param {Group} group
+ */
+ this.trigger('afterUpdateGroupNot', group);
+
+ this.trigger('rulesChanged');
+ }
+});
+
+
+/**
+ * @class Sortable
+ * @memberof module:plugins
+ * @description Enables drag & drop sort of rules.
+ * @param {object} [options]
+ * @param {boolean} [options.inherit_no_drop=true]
+ * @param {boolean} [options.inherit_no_sortable=true]
+ * @param {string} [options.icon='glyphicon glyphicon-sort']
+ * @throws MissingLibraryError, ConfigError
+ */
+QueryBuilder.define('sortable', function(options) {
+ if (!('interact' in window)) {
+ Utils.error('MissingLibrary', 'interact.js is required to use "sortable" plugin. Get it here: http://interactjs.io');
+ }
+
+ if (options.default_no_sortable !== undefined) {
+ Utils.error(false, 'Config', 'Sortable plugin : "default_no_sortable" options is deprecated, use standard "default_rule_flags" and "default_group_flags" instead');
+ this.settings.default_rule_flags.no_sortable = this.settings.default_group_flags.no_sortable = options.default_no_sortable;
+ }
+
+ // recompute drop-zones during drag (when a rule is hidden)
+ interact.dynamicDrop(true);
+
+ // set move threshold to 10px
+ interact.pointerMoveTolerance(10);
+
+ var placeholder;
+ var ghost;
+ var src;
+ var moved;
+
+ // Init drag and drop
+ this.on('afterAddRule afterAddGroup', function(e, node) {
+ if (node == placeholder) {
+ return;
+ }
+
+ var self = e.builder;
+
+ // Inherit flags
+ if (options.inherit_no_sortable && node.parent && node.parent.flags.no_sortable) {
+ node.flags.no_sortable = true;
+ }
+ if (options.inherit_no_drop && node.parent && node.parent.flags.no_drop) {
+ node.flags.no_drop = true;
+ }
+
+ // Configure drag
+ if (!node.flags.no_sortable) {
+ interact(node.$el[0])
+ .draggable({
+ allowFrom: QueryBuilder.selectors.drag_handle,
+ onstart: function(event) {
+ moved = false;
+
+ // get model of dragged element
+ src = self.getModel(event.target);
+
+ // create ghost
+ ghost = src.$el.clone()
+ .appendTo(src.$el.parent())
+ .width(src.$el.outerWidth())
+ .addClass('dragging');
+
+ // create drop placeholder
+ var ph = $('
')
+ .height(src.$el.outerHeight());
+
+ placeholder = src.parent.addRule(ph, src.getPos());
+
+ // hide dragged element
+ src.$el.hide();
+ },
+ onmove: function(event) {
+ // make the ghost follow the cursor
+ ghost[0].style.top = event.clientY - 15 + 'px';
+ ghost[0].style.left = event.clientX - 15 + 'px';
+ },
+ onend: function(event) {
+ // starting from Interact 1.3.3, onend is called before ondrop
+ if (event.dropzone) {
+ moveSortableToTarget(src, $(event.relatedTarget), self);
+ moved = true;
+ }
+
+ // remove ghost
+ ghost.remove();
+ ghost = undefined;
+
+ // remove placeholder
+ placeholder.drop();
+ placeholder = undefined;
+
+ // show element
+ src.$el.css('display', '');
+
+ /**
+ * After a node has been moved with {@link module:plugins.Sortable}
+ * @event afterMove
+ * @memberof module:plugins.Sortable
+ * @param {Node} node
+ */
+ self.trigger('afterMove', src);
+
+ self.trigger('rulesChanged');
+ }
+ });
+ }
+
+ if (!node.flags.no_drop) {
+ // Configure drop on groups and rules
+ interact(node.$el[0])
+ .dropzone({
+ accept: QueryBuilder.selectors.rule_and_group_containers,
+ ondragenter: function(event) {
+ moveSortableToTarget(placeholder, $(event.target), self);
+ },
+ ondrop: function(event) {
+ if (!moved) {
+ moveSortableToTarget(src, $(event.target), self);
+ }
+ }
+ });
+
+ // Configure drop on group headers
+ if (node instanceof Group) {
+ interact(node.$el.find(QueryBuilder.selectors.group_header)[0])
+ .dropzone({
+ accept: QueryBuilder.selectors.rule_and_group_containers,
+ ondragenter: function(event) {
+ moveSortableToTarget(placeholder, $(event.target), self);
+ },
+ ondrop: function(event) {
+ if (!moved) {
+ moveSortableToTarget(src, $(event.target), self);
+ }
+ }
+ });
+ }
+ }
+ });
+
+ // Detach interactables
+ this.on('beforeDeleteRule beforeDeleteGroup', function(e, node) {
+ if (!e.isDefaultPrevented()) {
+ interact(node.$el[0]).unset();
+
+ if (node instanceof Group) {
+ interact(node.$el.find(QueryBuilder.selectors.group_header)[0]).unset();
+ }
+ }
+ });
+
+ // Remove drag handle from non-sortable items
+ this.on('afterApplyRuleFlags afterApplyGroupFlags', function(e, node) {
+ if (node.flags.no_sortable) {
+ node.$el.find('.drag-handle').remove();
+ }
+ });
+
+ // Modify templates
+ if (!options.disable_template) {
+ this.on('getGroupTemplate.filter', function(h, level) {
+ if (level > 1) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.condition_container).after('
');
+ h.value = $h.prop('outerHTML');
+ }
+ });
+
+ this.on('getRuleTemplate.filter', function(h) {
+ var $h = $(h.value);
+ $h.find(QueryBuilder.selectors.rule_header).after('
');
+ h.value = $h.prop('outerHTML');
+ });
+ }
+}, {
+ inherit_no_sortable: true,
+ inherit_no_drop: true,
+ icon: 'glyphicon glyphicon-sort',
+ disable_template: false
+});
+
+QueryBuilder.selectors.rule_and_group_containers = QueryBuilder.selectors.rule_container + ', ' + QueryBuilder.selectors.group_container;
+QueryBuilder.selectors.drag_handle = '.drag-handle';
+
+QueryBuilder.defaults({
+ default_rule_flags: {
+ no_sortable: false,
+ no_drop: false
+ },
+ default_group_flags: {
+ no_sortable: false,
+ no_drop: false
+ }
+});
+
+/**
+ * Moves an element (placeholder or actual object) depending on active target
+ * @memberof module:plugins.Sortable
+ * @param {Node} node
+ * @param {jQuery} target
+ * @param {QueryBuilder} [builder]
+ * @private
+ */
+function moveSortableToTarget(node, target, builder) {
+ var parent, method;
+ var Selectors = QueryBuilder.selectors;
+
+ // on rule
+ parent = target.closest(Selectors.rule_container);
+ if (parent.length) {
+ method = 'moveAfter';
+ }
+
+ // on group header
+ if (!method) {
+ parent = target.closest(Selectors.group_header);
+ if (parent.length) {
+ parent = target.closest(Selectors.group_container);
+ method = 'moveAtBegin';
+ }
+ }
+
+ // on group
+ if (!method) {
+ parent = target.closest(Selectors.group_container);
+ if (parent.length) {
+ method = 'moveAtEnd';
+ }
+ }
+
+ if (method) {
+ node[method](builder.getModel(parent));
+
+ // refresh radio value
+ if (builder && node instanceof Rule) {
+ builder.setRuleInputValue(node, node.value);
+ }
+ }
+}
+
+
+/**
+ * @class SqlSupport
+ * @memberof module:plugins
+ * @description Allows to export rules as a SQL WHERE statement as well as populating the builder from an SQL query.
+ * @param {object} [options]
+ * @param {boolean} [options.boolean_as_integer=true] - `true` to convert boolean values to integer in the SQL output
+ */
+QueryBuilder.define('sql-support', function(options) {
+
+}, {
+ boolean_as_integer: true
+});
+
+QueryBuilder.defaults({
+ // operators for internal -> SQL conversion
+ sqlOperators: {
+ equal: { op: '= ?' },
+ not_equal: { op: '!= ?' },
+ in: { op: 'IN(?)', sep: ', ' },
+ not_in: { op: 'NOT IN(?)', sep: ', ' },
+ less: { op: '< ?' },
+ less_or_equal: { op: '<= ?' },
+ greater: { op: '> ?' },
+ greater_or_equal: { op: '>= ?' },
+ between: { op: 'BETWEEN ?', sep: ' AND ' },
+ not_between: { op: 'NOT BETWEEN ?', sep: ' AND ' },
+ begins_with: { op: 'LIKE(?)', mod: '{0}%' },
+ not_begins_with: { op: 'NOT LIKE(?)', mod: '{0}%' },
+ contains: { op: 'LIKE(?)', mod: '%{0}%' },
+ not_contains: { op: 'NOT LIKE(?)', mod: '%{0}%' },
+ ends_with: { op: 'LIKE(?)', mod: '%{0}' },
+ not_ends_with: { op: 'NOT LIKE(?)', mod: '%{0}' },
+ is_empty: { op: '= \'\'' },
+ is_not_empty: { op: '!= \'\'' },
+ is_null: { op: 'IS NULL' },
+ is_not_null: { op: 'IS NOT NULL' }
+ },
+
+ // operators for SQL -> internal conversion
+ sqlRuleOperator: {
+ '=': function(v) {
+ return {
+ val: v,
+ op: v === '' ? 'is_empty' : 'equal'
+ };
+ },
+ '!=': function(v) {
+ return {
+ val: v,
+ op: v === '' ? 'is_not_empty' : 'not_equal'
+ };
+ },
+ 'LIKE': function(v) {
+ if (v.slice(0, 1) == '%' && v.slice(-1) == '%') {
+ return {
+ val: v.slice(1, -1),
+ op: 'contains'
+ };
+ }
+ else if (v.slice(0, 1) == '%') {
+ return {
+ val: v.slice(1),
+ op: 'ends_with'
+ };
+ }
+ else if (v.slice(-1) == '%') {
+ return {
+ val: v.slice(0, -1),
+ op: 'begins_with'
+ };
+ }
+ else {
+ Utils.error('SQLParse', 'Invalid value for LIKE operator "{0}"', v);
+ }
+ },
+ 'NOT LIKE': function(v) {
+ if (v.slice(0, 1) == '%' && v.slice(-1) == '%') {
+ return {
+ val: v.slice(1, -1),
+ op: 'not_contains'
+ };
+ }
+ else if (v.slice(0, 1) == '%') {
+ return {
+ val: v.slice(1),
+ op: 'not_ends_with'
+ };
+ }
+ else if (v.slice(-1) == '%') {
+ return {
+ val: v.slice(0, -1),
+ op: 'not_begins_with'
+ };
+ }
+ else {
+ Utils.error('SQLParse', 'Invalid value for NOT LIKE operator "{0}"', v);
+ }
+ },
+ 'IN': function(v) {
+ return { val: v, op: 'in' };
+ },
+ 'NOT IN': function(v) {
+ return { val: v, op: 'not_in' };
+ },
+ '<': function(v) {
+ return { val: v, op: 'less' };
+ },
+ '<=': function(v) {
+ return { val: v, op: 'less_or_equal' };
+ },
+ '>': function(v) {
+ return { val: v, op: 'greater' };
+ },
+ '>=': function(v) {
+ return { val: v, op: 'greater_or_equal' };
+ },
+ 'BETWEEN': function(v) {
+ return { val: v, op: 'between' };
+ },
+ 'NOT BETWEEN': function(v) {
+ return { val: v, op: 'not_between' };
+ },
+ 'IS': function(v) {
+ if (v !== null) {
+ Utils.error('SQLParse', 'Invalid value for IS operator');
+ }
+ return { val: null, op: 'is_null' };
+ },
+ 'IS NOT': function(v) {
+ if (v !== null) {
+ Utils.error('SQLParse', 'Invalid value for IS operator');
+ }
+ return { val: null, op: 'is_not_null' };
+ }
+ },
+
+ // statements for internal -> SQL conversion
+ sqlStatements: {
+ 'question_mark': function() {
+ var params = [];
+ return {
+ add: function(rule, value) {
+ params.push(value);
+ return '?';
+ },
+ run: function() {
+ return params;
+ }
+ };
+ },
+
+ 'numbered': function(char) {
+ if (!char || char.length > 1) char = '$';
+ var index = 0;
+ var params = [];
+ return {
+ add: function(rule, value) {
+ params.push(value);
+ index++;
+ return char + index;
+ },
+ run: function() {
+ return params;
+ }
+ };
+ },
+
+ 'named': function(char) {
+ if (!char || char.length > 1) char = ':';
+ var indexes = {};
+ var params = {};
+ return {
+ add: function(rule, value) {
+ if (!indexes[rule.field]) indexes[rule.field] = 1;
+ var key = rule.field + '_' + (indexes[rule.field]++);
+ params[key] = value;
+ return char + key;
+ },
+ run: function() {
+ return params;
+ }
+ };
+ }
+ },
+
+ // statements for SQL -> internal conversion
+ sqlRuleStatement: {
+ 'question_mark': function(values) {
+ var index = 0;
+ return {
+ parse: function(v) {
+ return v == '?' ? values[index++] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(/\?/g, '\'?\'');
+ }
+ };
+ },
+
+ 'numbered': function(values, char) {
+ if (!char || char.length > 1) char = '$';
+ var regex1 = new RegExp('^\\' + char + '[0-9]+$');
+ var regex2 = new RegExp('\\' + char + '([0-9]+)', 'g');
+ return {
+ parse: function(v) {
+ return regex1.test(v) ? values[v.slice(1) - 1] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(regex2, '\'' + (char == '$' ? '$$' : char) + '$1\'');
+ }
+ };
+ },
+
+ 'named': function(values, char) {
+ if (!char || char.length > 1) char = ':';
+ var regex1 = new RegExp('^\\' + char);
+ var regex2 = new RegExp('\\' + char + '(' + Object.keys(values).join('|') + ')', 'g');
+ return {
+ parse: function(v) {
+ return regex1.test(v) ? values[v.slice(1)] : v;
+ },
+ esc: function(sql) {
+ return sql.replace(regex2, '\'' + (char == '$' ? '$$' : char) + '$1\'');
+ }
+ };
+ }
+ }
+});
+
+/**
+ * @typedef {object} SqlQuery
+ * @memberof module:plugins.SqlSupport
+ * @property {string} sql
+ * @property {object} params
+ */
+
+QueryBuilder.extend(/** @lends module:plugins.SqlSupport.prototype */ {
+ /**
+ * Returns rules as a SQL query
+ * @param {boolean|string} [stmt] - use prepared statements: false, 'question_mark', 'numbered', 'numbered(@)', 'named', 'named(@)'
+ * @param {boolean} [nl=false] output with new lines
+ * @param {object} [data] - current rules by default
+ * @returns {module:plugins.SqlSupport.SqlQuery}
+ * @fires module:plugins.SqlSupport.changer:getSQLField
+ * @fires module:plugins.SqlSupport.changer:ruleToSQL
+ * @fires module:plugins.SqlSupport.changer:groupToSQL
+ * @throws UndefinedSQLConditionError, UndefinedSQLOperatorError
+ */
+ getSQL: function(stmt, nl, data) {
+ data = (data === undefined) ? this.getRules() : data;
+
+ if (!data) {
+ return null;
+ }
+
+ nl = !!nl ? '\n' : ' ';
+ var boolean_as_integer = this.getPluginOptions('sql-support', 'boolean_as_integer');
+
+ if (stmt === true) {
+ stmt = 'question_mark';
+ }
+ if (typeof stmt == 'string') {
+ var config = getStmtConfig(stmt);
+ stmt = this.settings.sqlStatements[config[1]](config[2]);
+ }
+
+ var self = this;
+
+ var sql = (function parse(group) {
+ if (!group.condition) {
+ group.condition = self.settings.default_condition;
+ }
+ if (['AND', 'OR'].indexOf(group.condition.toUpperCase()) === -1) {
+ Utils.error('UndefinedSQLCondition', 'Unable to build SQL query with condition "{0}"', group.condition);
+ }
+
+ if (!group.rules) {
+ return '';
+ }
+
+ var parts = [];
+
+ group.rules.forEach(function(rule) {
+ if (rule.rules && rule.rules.length > 0) {
+ parts.push('(' + nl + parse(rule) + nl + ')' + nl);
+ }
+ else {
+ var sql = self.settings.sqlOperators[rule.operator];
+ var ope = self.getOperatorByType(rule.operator);
+ var value = '';
+
+ if (sql === undefined) {
+ Utils.error('UndefinedSQLOperator', 'Unknown SQL operation for operator "{0}"', rule.operator);
+ }
+
+ if (ope.nb_inputs !== 0) {
+ if (!(rule.value instanceof Array)) {
+ rule.value = [rule.value];
+ }
+
+ rule.value.forEach(function(v, i) {
+ if (i > 0) {
+ value += sql.sep;
+ }
+
+ if (rule.type == 'boolean' && boolean_as_integer) {
+ v = v ? 1 : 0;
+ }
+ else if (!stmt && rule.type !== 'integer' && rule.type !== 'double' && rule.type !== 'boolean') {
+ v = Utils.escapeString(v);
+ }
+
+ if (sql.mod) {
+ v = Utils.fmt(sql.mod, v);
+ }
+
+ if (stmt) {
+ value += stmt.add(rule, v);
+ }
+ else {
+ if (typeof v == 'string') {
+ v = '\'' + v + '\'';
+ }
+
+ value += v;
+ }
+ });
+ }
+
+ var sqlFn = function(v) {
+ return sql.op.replace('?', function() {
+ return v;
+ });
+ };
+
+ /**
+ * Modifies the SQL field used by a rule
+ * @event changer:getSQLField
+ * @memberof module:plugins.SqlSupport
+ * @param {string} field
+ * @param {Rule} rule
+ * @returns {string}
+ */
+ var field = self.change('getSQLField', rule.field, rule);
+
+ var ruleExpression = field + ' ' + sqlFn(value);
+
+ /**
+ * Modifies the SQL generated for a rule
+ * @event changer:ruleToSQL
+ * @memberof module:plugins.SqlSupport
+ * @param {string} expression
+ * @param {Rule} rule
+ * @param {*} value
+ * @param {function} valueWrapper - function that takes the value and adds the operator
+ * @returns {string}
+ */
+ parts.push(self.change('ruleToSQL', ruleExpression, rule, value, sqlFn));
+ }
+ });
+
+ var groupExpression = parts.join(' ' + group.condition + nl);
+
+ /**
+ * Modifies the SQL generated for a group
+ * @event changer:groupToSQL
+ * @memberof module:plugins.SqlSupport
+ * @param {string} expression
+ * @param {Group} group
+ * @returns {string}
+ */
+ return self.change('groupToSQL', groupExpression, group);
+ }(data));
+
+ if (stmt) {
+ return {
+ sql: sql,
+ params: stmt.run()
+ };
+ }
+ else {
+ return {
+ sql: sql
+ };
+ }
+ },
+
+ /**
+ * Convert a SQL query to rules
+ * @param {string|module:plugins.SqlSupport.SqlQuery} query
+ * @param {boolean|string} stmt
+ * @returns {object}
+ * @fires module:plugins.SqlSupport.changer:parseSQLNode
+ * @fires module:plugins.SqlSupport.changer:getSQLFieldID
+ * @fires module:plugins.SqlSupport.changer:sqlToRule
+ * @fires module:plugins.SqlSupport.changer:sqlToGroup
+ * @throws MissingLibraryError, SQLParseError, UndefinedSQLOperatorError
+ */
+ getRulesFromSQL: function(query, stmt) {
+ if (!('SQLParser' in window)) {
+ Utils.error('MissingLibrary', 'SQLParser is required to parse SQL queries. Get it here https://github.com/mistic100/sql-parser');
+ }
+
+ var self = this;
+
+ if (typeof query == 'string') {
+ query = { sql: query };
+ }
+
+ if (stmt === true) stmt = 'question_mark';
+ if (typeof stmt == 'string') {
+ var config = getStmtConfig(stmt);
+ stmt = this.settings.sqlRuleStatement[config[1]](query.params, config[2]);
+ }
+
+ if (stmt) {
+ query.sql = stmt.esc(query.sql);
+ }
+
+ if (query.sql.toUpperCase().indexOf('SELECT') !== 0) {
+ query.sql = 'SELECT * FROM table WHERE ' + query.sql;
+ }
+
+ var parsed = SQLParser.parse(query.sql);
+
+ if (!parsed.where) {
+ Utils.error('SQLParse', 'No WHERE clause found');
+ }
+
+ /**
+ * Custom parsing of an AST node generated by SQLParser, you can return a sub-part of the tree, or a well formed group or rule JSON
+ * @event changer:parseSQLNode
+ * @memberof module:plugins.SqlSupport
+ * @param {object} AST node
+ * @returns {object} tree, rule or group
+ */
+ var data = self.change('parseSQLNode', parsed.where.conditions);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ return data;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ return {
+ condition: this.settings.default_condition,
+ rules: [data]
+ };
+ }
+
+ // create root group
+ var out = self.change('sqlToGroup', {
+ condition: this.settings.default_condition,
+ rules: []
+ }, data);
+
+ // keep track of current group
+ var curr = out;
+
+ (function flatten(data, i) {
+ if (data === null) {
+ return;
+ }
+
+ // allow plugins to manually parse or handle special cases
+ data = self.change('parseSQLNode', data);
+
+ // a plugin returned a group
+ if ('rules' in data && 'condition' in data) {
+ curr.rules.push(data);
+ return;
+ }
+
+ // a plugin returned a rule
+ if ('id' in data && 'operator' in data && 'value' in data) {
+ curr.rules.push(data);
+ return;
+ }
+
+ // data must be a SQL parser node
+ if (!('left' in data) || !('right' in data) || !('operation' in data)) {
+ Utils.error('SQLParse', 'Unable to parse WHERE clause');
+ }
+
+ // it's a node
+ if (['AND', 'OR'].indexOf(data.operation.toUpperCase()) !== -1) {
+ // create a sub-group if the condition is not the same and it's not the first level
+
+ /**
+ * Given an existing group and an AST node, determines if a sub-group must be created
+ * @event changer:sqlGroupsDistinct
+ * @memberof module:plugins.SqlSupport
+ * @param {boolean} create - true by default if the group condition is different
+ * @param {object} group
+ * @param {object} AST
+ * @param {int} current group level
+ * @returns {boolean}
+ */
+ var createGroup = self.change('sqlGroupsDistinct', i > 0 && curr.condition != data.operation.toUpperCase(), curr, data, i);
+
+ if (createGroup) {
+ /**
+ * Modifies the group generated from the SQL expression (this is called before the group is filled with rules)
+ * @event changer:sqlToGroup
+ * @memberof module:plugins.SqlSupport
+ * @param {object} group
+ * @param {object} AST
+ * @returns {object}
+ */
+ var group = self.change('sqlToGroup', {
+ condition: self.settings.default_condition,
+ rules: []
+ }, data);
+
+ curr.rules.push(group);
+ curr = group;
+ }
+
+ curr.condition = data.operation.toUpperCase();
+ i++;
+
+ // some magic !
+ var next = curr;
+ flatten(data.left, i);
+
+ curr = next;
+ flatten(data.right, i);
+ }
+ // it's a leaf
+ else {
+ if ($.isPlainObject(data.right.value)) {
+ Utils.error('SQLParse', 'Value format not supported for {0}.', data.left.value);
+ }
+
+ // convert array
+ var value;
+ if ($.isArray(data.right.value)) {
+ value = data.right.value.map(function(v) {
+ return v.value;
+ });
+ }
+ else {
+ value = data.right.value;
+ }
+
+ // get actual values
+ if (stmt) {
+ if ($.isArray(value)) {
+ value = value.map(stmt.parse);
+ }
+ else {
+ value = stmt.parse(value);
+ }
+ }
+
+ // convert operator
+ var operator = data.operation.toUpperCase();
+ if (operator == '<>') {
+ operator = '!=';
+ }
+
+ var sqlrl = self.settings.sqlRuleOperator[operator];
+ if (sqlrl === undefined) {
+ Utils.error('UndefinedSQLOperator', 'Invalid SQL operation "{0}".', data.operation);
+ }
+
+ var opVal = sqlrl.call(this, value, data.operation);
+
+ // find field name
+ var field;
+ if ('values' in data.left) {
+ field = data.left.values.join('.');
+ }
+ else if ('value' in data.left) {
+ field = data.left.value;
+ }
+ else {
+ Utils.error('SQLParse', 'Cannot find field name in {0}', JSON.stringify(data.left));
+ }
+
+ var id = self.getSQLFieldID(field, value);
+
+ /**
+ * Modifies the rule generated from the SQL expression
+ * @event changer:sqlToRule
+ * @memberof module:plugins.SqlSupport
+ * @param {object} rule
+ * @param {object} AST
+ * @returns {object}
+ */
+ var rule = self.change('sqlToRule', {
+ id: id,
+ field: field,
+ operator: opVal.op,
+ value: opVal.val
+ }, data);
+
+ curr.rules.push(rule);
+ }
+ }(data, 0));
+
+ return out;
+ },
+
+ /**
+ * Sets the builder's rules from a SQL query
+ * @see module:plugins.SqlSupport.getRulesFromSQL
+ */
+ setRulesFromSQL: function(query, stmt) {
+ this.setRules(this.getRulesFromSQL(query, stmt));
+ },
+
+ /**
+ * Returns a filter identifier from the SQL field.
+ * Automatically use the only one filter with a matching field, fires a changer otherwise.
+ * @param {string} field
+ * @param {*} value
+ * @fires module:plugins.SqlSupport:changer:getSQLFieldID
+ * @returns {string}
+ * @private
+ */
+ getSQLFieldID: function(field, value) {
+ var matchingFilters = this.filters.filter(function(filter) {
+ return filter.field.toLowerCase() === field.toLowerCase();
+ });
+
+ var id;
+ if (matchingFilters.length === 1) {
+ id = matchingFilters[0].id;
+ }
+ else {
+ /**
+ * Returns a filter identifier from the SQL field
+ * @event changer:getSQLFieldID
+ * @memberof module:plugins.SqlSupport
+ * @param {string} field
+ * @param {*} value
+ * @returns {string}
+ */
+ id = this.change('getSQLFieldID', field, value);
+ }
+
+ return id;
+ }
+});
+
+/**
+ * Parses the statement configuration
+ * @memberof module:plugins.SqlSupport
+ * @param {string} stmt
+ * @returns {Array} null, mode, option
+ * @private
+ */
+function getStmtConfig(stmt) {
+ var config = stmt.match(/(question_mark|numbered|named)(?:\((.)\))?/);
+ if (!config) config = [null, 'question_mark', undefined];
+ return config;
+}
+
+
+/**
+ * @class UniqueFilter
+ * @memberof module:plugins
+ * @description Allows to define some filters as "unique": ie which can be used for only one rule, globally or in the same group.
+ */
+QueryBuilder.define('unique-filter', function() {
+ this.status.used_filters = {};
+
+ this.on('afterUpdateRuleFilter', this.updateDisabledFilters);
+ this.on('afterDeleteRule', this.updateDisabledFilters);
+ this.on('afterCreateRuleFilters', this.applyDisabledFilters);
+ this.on('afterReset', this.clearDisabledFilters);
+ this.on('afterClear', this.clearDisabledFilters);
+
+ // Ensure that the default filter is not already used if unique
+ this.on('getDefaultFilter.filter', function(e, model) {
+ var self = e.builder;
+
+ self.updateDisabledFilters();
+
+ if (e.value.id in self.status.used_filters) {
+ var found = self.filters.some(function(filter) {
+ if (!(filter.id in self.status.used_filters) || self.status.used_filters[filter.id].length > 0 && self.status.used_filters[filter.id].indexOf(model.parent) === -1) {
+ e.value = filter;
+ return true;
+ }
+ });
+
+ if (!found) {
+ Utils.error(false, 'UniqueFilter', 'No more non-unique filters available');
+ e.value = undefined;
+ }
+ }
+ });
+});
+
+QueryBuilder.extend(/** @lends module:plugins.UniqueFilter.prototype */ {
+ /**
+ * Updates the list of used filters
+ * @param {$.Event} [e]
+ * @private
+ */
+ updateDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ self.status.used_filters = {};
+
+ if (!self.model) {
+ return;
+ }
+
+ // get used filters
+ (function walk(group) {
+ group.each(function(rule) {
+ if (rule.filter && rule.filter.unique) {
+ if (!self.status.used_filters[rule.filter.id]) {
+ self.status.used_filters[rule.filter.id] = [];
+ }
+ if (rule.filter.unique == 'group') {
+ self.status.used_filters[rule.filter.id].push(rule.parent);
+ }
+ }
+ }, function(group) {
+ walk(group);
+ });
+ }(self.model.root));
+
+ self.applyDisabledFilters(e);
+ },
+
+ /**
+ * Clear the list of used filters
+ * @param {$.Event} [e]
+ * @private
+ */
+ clearDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ self.status.used_filters = {};
+
+ self.applyDisabledFilters(e);
+ },
+
+ /**
+ * Disabled filters depending on the list of used ones
+ * @param {$.Event} [e]
+ * @private
+ */
+ applyDisabledFilters: function(e) {
+ var self = e ? e.builder : this;
+
+ // re-enable everything
+ self.$el.find(QueryBuilder.selectors.filter_container + ' option').prop('disabled', false);
+
+ // disable some
+ $.each(self.status.used_filters, function(filterId, groups) {
+ if (groups.length === 0) {
+ self.$el.find(QueryBuilder.selectors.filter_container + ' option[value="' + filterId + '"]:not(:selected)').prop('disabled', true);
+ }
+ else {
+ groups.forEach(function(group) {
+ group.each(function(rule) {
+ rule.$el.find(QueryBuilder.selectors.filter_container + ' option[value="' + filterId + '"]:not(:selected)').prop('disabled', true);
+ });
+ });
+ }
+ });
+
+ // update Selectpicker
+ if (self.settings.plugins && self.settings.plugins['bt-selectpicker']) {
+ self.$el.find(QueryBuilder.selectors.rule_filter).selectpicker('render');
+ }
+ }
+});
+
+
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Locale: English (en)
+ * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+QueryBuilder.regional['en'] = {
+ "__locale": "English (en)",
+ "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr",
+ "add_rule": "Add rule",
+ "add_group": "Add group",
+ "delete_rule": "Delete",
+ "delete_group": "Delete",
+ "conditions": {
+ "AND": "AND",
+ "OR": "OR"
+ },
+ "operators": {
+ "equal": "equal",
+ "not_equal": "not equal",
+ "in": "in",
+ "not_in": "not in",
+ "less": "less",
+ "less_or_equal": "less or equal",
+ "greater": "greater",
+ "greater_or_equal": "greater or equal",
+ "between": "between",
+ "not_between": "not between",
+ "begins_with": "begins with",
+ "not_begins_with": "doesn't begin with",
+ "contains": "contains",
+ "not_contains": "doesn't contain",
+ "ends_with": "ends with",
+ "not_ends_with": "doesn't end with",
+ "is_empty": "is empty",
+ "is_not_empty": "is not empty",
+ "is_null": "is null",
+ "is_not_null": "is not null"
+ },
+ "errors": {
+ "no_filter": "No filter selected",
+ "empty_group": "The group is empty",
+ "radio_empty": "No value selected",
+ "checkbox_empty": "No value selected",
+ "select_empty": "No value selected",
+ "string_empty": "Input field cannot be blank",
+ "string_exceed_min_length": "Must contain at least {0} characters",
+ "string_exceed_max_length": "Must not contain more than {0} characters",
+ "string_invalid_format": "Invalid format ({0})",
+ "number_nan": "Not a number",
+ "number_not_integer": "This field must contain numbers 0-9. No letters, spaces, or special characters allowed.",
+ "number_not_double": "This field must contain numbers 0-9 with decimals separated by point “.” - For Example 10 or 50.60. No letters, spaces, or special characters allowed.",
+ "number_exceed_min": "Must be greater than {0}",
+ "number_exceed_max": "Must be lower than {0}",
+ "number_wrong_step": "Must be a multiple of {0}",
+ "number_between_invalid": "Invalid values, {0} is greater than {1}",
+ "datetime_empty": "Input field cannot be blank",
+ "datetime_invalid": "Invalid date format ({0})",
+ "datetime_exceed_min": "Must be after {0}",
+ "datetime_exceed_max": "Must be before {0}",
+ "datetime_between_invalid": "Invalid values, {0} is greater than {1}",
+ "boolean_not_valid": "Not a boolean",
+ "operator_not_multiple": "Operator \"{1}\" cannot accept multiple values"
+ },
+ "invert": "Invert",
+ "NOT": "NOT"
+};
+
+QueryBuilder.defaults({ lang_code: 'en' });
+return QueryBuilder;
+
+}));
diff --git a/dist/js/query-builder.standalone.min.js b/dist/js/query-builder.standalone.min.js
new file mode 100644
index 00000000..924b5ea4
--- /dev/null
+++ b/dist/js/query-builder.standalone.min.js
@@ -0,0 +1,8 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+
+!function(e,t){"function"==typeof define&&define.amd?define("jQuery.extendext",["jquery"],t):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(e.jQuery)}(this,function($){"use strict";$.extendext=function(){var e,t,r,i,n,o,l=arguments[0]||{},s=1,a=arguments.length,u=!1,p="default";for("boolean"==typeof l&&(u=l,l=arguments[s++]||{}),"string"==typeof l&&("concat"!==(p=l.toLowerCase())&&"replace"!==p&&"extend"!==p&&(p="default"),l=arguments[s++]||{}),"object"==typeof l||$.isFunction(l)||(l={}),s===a&&(l=this,s--);s":">",'"':""","'":"'","/":"/"},r=e?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(e){return e?e.toString().replace(r,function(e){return t[e]||e}):""}},a=function(){return this||(0,eval)("this")}(),"undefined"!=typeof module&&module.exports?module.exports=u:"function"==typeof define&&define.amd?define("doT",function(){return u}):a.doT=u;var p={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},d=/$^/;function c(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}u.template=function(e,t,r){var i,n,o=(t=t||u.templateSettings).append?p.append:p.split,l=0,s=t.use||t.define?function i(n,e,o){return("string"==typeof e?e:e.toString()).replace(n.define||d,function(e,i,t,r){return 0===i.indexOf("def.")&&(i=i.substring(4)),i in o||(":"===t?(n.defineParams&&r.replace(n.defineParams,function(e,t,r){o[i]={arg:t,text:r}}),i in o||(o[i]=r)):new Function("def","def['"+i+"']="+r)(o)),""}).replace(n.use||d,function(e,t){n.useParams&&(t=t.replace(n.useParams,function(e,t,r,i){if(o[r]&&o[r].arg&&i){var n=(r+":"+i).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[n]=o[r].text.replace(new RegExp("(^|[^\\w$])"+o[r].arg+"([^\\w$])","g"),"$1"+i+"$2"),t+"def.__exp['"+n+"']"}}));var r=new Function("def","return "+t)(o);return r?i(n,r,o):r})}(t,e,r||{}):e;s=("var out='"+(t.strip?s.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):s).replace(/'|\\/g,"\\$&").replace(t.interpolate||d,function(e,t){return o.start+c(t)+o.end}).replace(t.encode||d,function(e,t){return i=!0,o.startencode+c(t)+o.end}).replace(t.conditional||d,function(e,t,r){return t?r?"';}else if("+c(r)+"){out+='":"';}else{out+='":r?"';if("+c(r)+"){out+='":"';}out+='"}).replace(t.iterate||d,function(e,t,r,i){return t?(l+=1,n=i||"i"+l,t=c(t),"';var arr"+l+"="+t+";if(arr"+l+"){var "+r+","+n+"=-1,l"+l+"=arr"+l+".length-1;while("+n+".rules-list",group_condition:".rules-group-header [name$=_cond]",rule_filter:".rule-filter-container [name$=_filter]",rule_operator:".rule-operator-container [name$=_operator]",rule_value:".rule-value-container [name*=_value_]",add_rule:"[data-add=rule]",delete_rule:"[data-delete=rule]",add_group:"[data-add=group]",delete_group:"[data-delete=group]"},c.templates={},c.regional={},c.OPERATORS={equal:{type:"equal",nb_inputs:1,multiple:!1,apply_to:["string","number","datetime","boolean"]},not_equal:{type:"not_equal",nb_inputs:1,multiple:!1,apply_to:["string","number","datetime","boolean"]},in:{type:"in",nb_inputs:1,multiple:!0,apply_to:["string","number","datetime"]},not_in:{type:"not_in",nb_inputs:1,multiple:!0,apply_to:["string","number","datetime"]},less:{type:"less",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},less_or_equal:{type:"less_or_equal",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},greater:{type:"greater",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},greater_or_equal:{type:"greater_or_equal",nb_inputs:1,multiple:!1,apply_to:["number","datetime"]},between:{type:"between",nb_inputs:2,multiple:!1,apply_to:["number","datetime"]},not_between:{type:"not_between",nb_inputs:2,multiple:!1,apply_to:["number","datetime"]},begins_with:{type:"begins_with",nb_inputs:1,multiple:!1,apply_to:["string"]},not_begins_with:{type:"not_begins_with",nb_inputs:1,multiple:!1,apply_to:["string"]},contains:{type:"contains",nb_inputs:1,multiple:!1,apply_to:["string"]},not_contains:{type:"not_contains",nb_inputs:1,multiple:!1,apply_to:["string"]},ends_with:{type:"ends_with",nb_inputs:1,multiple:!1,apply_to:["string"]},not_ends_with:{type:"not_ends_with",nb_inputs:1,multiple:!1,apply_to:["string"]},is_empty:{type:"is_empty",nb_inputs:0,multiple:!1,apply_to:["string"]},is_not_empty:{type:"is_not_empty",nb_inputs:0,multiple:!1,apply_to:["string"]},is_null:{type:"is_null",nb_inputs:0,multiple:!1,apply_to:["string","number","datetime","boolean"]},is_not_null:{type:"is_not_null",nb_inputs:0,multiple:!1,apply_to:["string","number","datetime","boolean"]}},c.DEFAULTS={filters:[],plugins:[],sort_filters:!1,display_errors:!0,allow_groups:-1,allow_empty:!1,conditions:["AND","OR"],default_condition:"AND",inputs_separator:" , ",select_placeholder:"------",display_empty_filter:!0,default_filter:null,optgroups:{},default_rule_flags:{filter_readonly:!1,operator_readonly:!1,value_readonly:!1,no_delete:!1},default_group_flags:{condition_readonly:!1,no_add_rule:!1,no_add_group:!1,no_delete:!1},templates:{group:null,rule:null,filterSelect:null,operatorSelect:null,ruleValueSelect:null},lang_code:"en",lang:{},operators:["equal","not_equal","in","not_in","less","less_or_equal","greater","greater_or_equal","between","not_between","begins_with","not_begins_with","contains","not_contains","ends_with","not_ends_with","is_empty","is_not_empty","is_null","is_not_null"],icons:{add_group:"glyphicon glyphicon-plus-sign",add_rule:"glyphicon glyphicon-plus",remove_group:"glyphicon glyphicon-remove",remove_rule:"glyphicon glyphicon-remove",error:"glyphicon glyphicon-warning-sign",tooltip:"glyphicon glyphicon-info-sign"}},c.plugins={},c.defaults=function(e){if("object"!=typeof e)return"string"==typeof e?"object"==typeof c.DEFAULTS[e]?$.extend(!0,{},c.DEFAULTS[e]):c.DEFAULTS[e]:$.extend(!0,{},c.DEFAULTS);$.extendext(!0,"replace",c.DEFAULTS,e)},c.define=function(e,t,r){c.plugins[e]={fct:t,def:r||{}}},c.extend=function(e){$.extend(c.prototype,e)},c.prototype.initPlugins=function(){if(this.plugins){if($.isArray(this.plugins)){var t={};this.plugins.forEach(function(e){t[e]=null}),this.plugins=t}Object.keys(this.plugins).forEach(function(e){e in c.plugins?(this.plugins[e]=$.extend(!0,{},c.plugins[e].def,this.plugins[e]||{}),c.plugins[e].fct.call(this,this.plugins[e])):h.error("Config",'Unable to find plugin "{0}"',e)},this)}},c.prototype.getPluginOptions=function(e,t){var r;if(this.plugins&&this.plugins[e]?r=this.plugins[e]:c.plugins[e]&&(r=c.plugins[e].def),r)return t?r[t]:r;h.error("Config",'Unable to find plugin "{0}"',e)},c.prototype.init=function(e){this.trigger("afterInit"),e?(this.setRules(e),delete this.settings.rules):this.setRoot(!0)},c.prototype.checkFilters=function(e){var t=[];if(e&&0!==e.length||h.error("Config","Missing filters list"),e.forEach(function(i,e){switch(i.id||h.error("Config","Missing filter {0} id",e),-1!=t.indexOf(i.id)&&h.error("Config",'Filter "{0}" already defined',i.id),t.push(i.id),i.type?c.types[i.type]||h.error("Config",'Invalid type "{0}"',i.type):i.type="string",i.input?"function"!=typeof i.input&&-1==c.inputs.indexOf(i.input)&&h.error("Config",'Invalid input "{0}"',i.input):i.input="number"===c.types[i.type]?"number":"text",i.operators&&i.operators.forEach(function(e){"string"!=typeof e&&h.error("Config","Filter operators must be global operators types (string)")}),i.field||(i.field=i.id),i.label||(i.label=i.field),i.optgroup?(this.status.has_optgroup=!0,this.settings.optgroups[i.optgroup]||(this.settings.optgroups[i.optgroup]=i.optgroup)):i.optgroup=null,i.input){case"radio":case"checkbox":(!i.values||i.values.length<1)&&h.error("Config",'Missing filter "{0}" values',i.id);break;case"select":var n=[];i.has_optgroup=!1,h.iterateOptions(i.values,function(e,t,r){n.push({value:e,label:t,optgroup:r||null}),r&&(i.has_optgroup=!0,this.settings.optgroups[r]||(this.settings.optgroups[r]=r))}.bind(this)),i.has_optgroup?i.values=h.groupSort(n,"optgroup"):i.values=n,i.placeholder&&(void 0===i.placeholder_value&&(i.placeholder_value=-1),i.values.forEach(function(e){e.value==i.placeholder_value&&h.error("Config",'Placeholder of filter "{0}" overlaps with one of its values',i.id)}))}},this),this.settings.sort_filters)if("function"==typeof this.settings.sort_filters)e.sort(this.settings.sort_filters);else{var r=this;e.sort(function(e,t){return r.translate(e.label).localeCompare(r.translate(t.label))})}return this.status.has_optgroup&&(e=h.groupSort(e,"optgroup")),e},c.prototype.checkOperators=function(r){var i=[];return r.forEach(function(e,t){"string"==typeof e?(c.OPERATORS[e]||h.error("Config",'Unknown operator "{0}"',e),r[t]=e=$.extendext(!0,"replace",{},c.OPERATORS[e])):(e.type||h.error("Config",'Missing "type" for operator {0}',t),c.OPERATORS[e.type]&&(r[t]=e=$.extendext(!0,"replace",{},c.OPERATORS[e.type],e)),void 0!==e.nb_inputs&&void 0!==e.apply_to||h.error("Config",'Missing "nb_inputs" and/or "apply_to" for operator "{0}"',e.type)),-1!=i.indexOf(e.type)&&h.error("Config",'Operator "{0}" already defined',e.type),i.push(e.type),e.optgroup?(this.status.has_operator_optgroup=!0,this.settings.optgroups[e.optgroup]||(this.settings.optgroups[e.optgroup]=e.optgroup)):e.optgroup=null},this),this.status.has_operator_optgroup&&(r=h.groupSort(r,"optgroup")),r},c.prototype.bindEvents=function(){var o=this,t=c.selectors;this.$el.on("change.queryBuilder",t.group_condition,function(){if($(this).is(":checked")){var e=$(this).closest(t.group_container);o.getModel(e).condition=$(this).val()}}),this.$el.on("change.queryBuilder",t.rule_filter,function(){var e=$(this).closest(t.rule_container);o.getModel(e).filter=o.getFilterById($(this).val())}),this.$el.on("change.queryBuilder",t.rule_operator,function(){var e=$(this).closest(t.rule_container);o.getModel(e).operator=o.getOperatorByType($(this).val())}),this.$el.on("click.queryBuilder",t.add_rule,function(){var e=$(this).closest(t.group_container);o.addRule(o.getModel(e))}),this.$el.on("click.queryBuilder",t.delete_rule,function(){var e=$(this).closest(t.rule_container);o.deleteRule(o.getModel(e))}),0!==this.settings.allow_groups&&(this.$el.on("click.queryBuilder",t.add_group,function(){var e=$(this).closest(t.group_container);o.addGroup(o.getModel(e))}),this.$el.on("click.queryBuilder",t.delete_group,function(){var e=$(this).closest(t.group_container);o.deleteGroup(o.getModel(e))})),this.model.on({drop:function(e,t){t.$el.remove(),o.refreshGroupsConditions()},add:function(e,t,r,i){0===i?r.$el.prependTo(t.$el.find(">"+c.selectors.rules_list)):r.$el.insertAfter(t.rules[i-1].$el),o.refreshGroupsConditions()},move:function(e,t,r,i){t.$el.detach(),0===i?t.$el.prependTo(r.$el.find(">"+c.selectors.rules_list)):t.$el.insertAfter(r.rules[i-1].$el),o.refreshGroupsConditions()},update:function(e,t,r,i,n){if(t instanceof l)switch(r){case"error":o.updateError(t);break;case"flags":o.applyRuleFlags(t);break;case"filter":o.updateRuleFilter(t,n);break;case"operator":o.updateRuleOperator(t,n);break;case"value":o.updateRuleValue(t,n)}else switch(r){case"error":o.updateError(t);break;case"flags":o.applyGroupFlags(t);break;case"condition":o.updateGroupCondition(t,n)}}})},c.prototype.setRoot=function(e,t,r){e=void 0===e||!0===e;var i=this.nextGroupId(),n=$(this.getGroupTemplate(i,1));return this.$el.append(n),this.model.root=new a(null,n),this.model.root.model=this.model,this.model.root.data=t,this.model.root.flags=$.extend({},this.settings.default_group_flags,r),this.model.root.condition=this.settings.default_condition,this.trigger("afterAddGroup",this.model.root),e&&this.addRule(this.model.root),this.model.root},c.prototype.addGroup=function(e,t,r,i){t=void 0===t||!0===t;var n=e.level+1;if(this.trigger("beforeAddGroup",e,t,n).isDefaultPrevented())return null;var o=this.nextGroupId(),l=$(this.getGroupTemplate(o,n)),s=e.addGroup(l);return s.data=r,s.flags=$.extend({},this.settings.default_group_flags,i),s.condition=this.settings.default_condition,this.trigger("afterAddGroup",s),this.trigger("rulesChanged"),t&&this.addRule(s),s},c.prototype.deleteGroup=function(e){if(e.isRoot())return!1;if(this.trigger("beforeDeleteGroup",e).isDefaultPrevented())return!1;var t=!0;return e.each("reverse",function(e){t&=this.deleteRule(e)},function(e){t&=this.deleteGroup(e)},this),t&&(e.drop(),this.trigger("afterDeleteGroup"),this.trigger("rulesChanged")),t},c.prototype.updateGroupCondition=function(t,e){t.$el.find(">"+c.selectors.group_condition).each(function(){var e=$(this);e.prop("checked",e.val()===t.condition),e.parent().toggleClass("active",e.val()===t.condition)}),this.trigger("afterUpdateGroupCondition",t,e),this.trigger("rulesChanged")},c.prototype.refreshGroupsConditions=function(){!function t(e){(!e.flags||e.flags&&!e.flags.condition_readonly)&&e.$el.find(">"+c.selectors.group_condition).prop("disabled",e.rules.length<=1).parent().toggleClass("disabled",e.rules.length<=1),e.each(null,function(e){t(e)},this)}(this.model.root)},c.prototype.addRule=function(e,t,r){if(this.trigger("beforeAddRule",e).isDefaultPrevented())return null;var i=this.nextRuleId(),n=$(this.getRuleTemplate(i)),o=e.addRule(n);return o.data=t,o.flags=$.extend({},this.settings.default_rule_flags,r),this.trigger("afterAddRule",o),this.trigger("rulesChanged"),this.createRuleFilters(o),!this.settings.default_filter&&this.settings.display_empty_filter||(o.filter=this.change("getDefaultFilter",this.getFilterById(this.settings.default_filter||this.filters[0].id),o)),o},c.prototype.deleteRule=function(e){return!e.flags.no_delete&&(!this.trigger("beforeDeleteRule",e).isDefaultPrevented()&&(e.drop(),this.trigger("afterDeleteRule"),this.trigger("rulesChanged"),!0))},c.prototype.createRuleFilters=function(e){var t=this.change("getRuleFilters",this.filters,e),r=$(this.getRuleFilterSelect(e,t));e.$el.find(c.selectors.filter_container).html(r),this.trigger("afterCreateRuleFilters",e),this.applyRuleFlags(e)},c.prototype.createRuleOperators=function(e){var t=e.$el.find(c.selectors.operator_container).empty();if(e.filter){var r=this.getOperators(e.filter),i=$(this.getRuleOperatorSelect(e,r));t.html(i),e.filter.default_operator?e.__.operator=this.getOperatorByType(e.filter.default_operator):e.__.operator=r[0],e.$el.find(c.selectors.rule_operator).val(e.operator.type),this.trigger("afterCreateRuleOperators",e,r),this.applyRuleFlags(e)}},c.prototype.createRuleInput=function(e){var t=e.$el.find(c.selectors.value_container).empty();if(e.__.value=void 0,e.filter&&e.operator&&0!==e.operator.nb_inputs){for(var r=this,i=$(),n=e.filter,o=0;o"+r.group_condition).prop("disabled",t.condition_readonly).parent().toggleClass("readonly",t.condition_readonly),t.no_add_rule&&e.$el.find(r.add_rule).remove(),t.no_add_group&&e.$el.find(r.add_group).remove(),t.no_delete&&e.$el.find(r.delete_group).remove(),this.trigger("afterApplyGroupFlags",e)},c.prototype.clearErrors=function(e){(e=e||this.model.root)&&(e.error=null,e instanceof a&&e.each(function(e){e.error=null},function(e){this.clearErrors(e)},this))},c.prototype.updateError=function(e){if(this.settings.display_errors)if(null===e.error)e.$el.removeClass("has-error");else{var t=this.translate("errors",e.error[0]);t=h.fmt(t,e.error.slice(1)),t=this.change("displayError",t,e.error,e),e.$el.addClass("has-error").find(c.selectors.error_container).eq(0).attr("data-tooltip",t)}},c.prototype.triggerValidationError=function(e,t,r){$.isArray(t)||(t=[t]),this.trigger("validationError",e,t,r).isDefaultPrevented()||(e.error=t)},c.prototype.destroy=function(){this.trigger("beforeDestroy"),this.status.generated_id&&this.$el.removeAttr("id"),this.clear(),this.model=null,this.$el.off(".queryBuilder").removeClass("query-builder").removeData("queryBuilder"),delete this.$el[0].queryBuilder},c.prototype.reset=function(){this.trigger("beforeReset").isDefaultPrevented()||(this.status.group_id=1,this.status.rule_id=0,this.model.root.empty(),this.model.root.data=void 0,this.model.root.flags=$.extend({},this.settings.default_group_flags),this.model.root.condition=this.settings.default_condition,this.addRule(this.model.root),this.trigger("afterReset"),this.trigger("rulesChanged"))},c.prototype.clear=function(){this.trigger("beforeClear").isDefaultPrevented()||(this.status.group_id=0,this.status.rule_id=0,this.model.root&&(this.model.root.drop(),this.model.root=null),this.trigger("afterClear"),this.trigger("rulesChanged"))},c.prototype.setOptions=function(e){$.each(e,function(e,t){-1!==c.modifiable_options.indexOf(e)&&(this.settings[e]=t)}.bind(this))},c.prototype.getModel=function(e){return e?e instanceof n?e:$(e).data("queryBuilderModel"):this.model.root},c.prototype.validate=function(o){o=$.extend({skip_empty:!1},o),this.clearErrors();var l=this,e=function r(e){var i=0,n=0;return e.each(function(e){if(e.filter||!o.skip_empty){if(!e.filter)return l.triggerValidationError(e,"no_filter",null),void n++;if(!e.operator)return l.triggerValidationError(e,"no_operator",null),void n++;if(0!==e.operator.nb_inputs){var t=l.validateValue(e,e.value);if(!0!==t)return l.triggerValidationError(e,t,e.value),void n++}i++}},function(e){var t=r(e);!0===t?i++:!1===t&&n++}),!(0parseInt(l.max)){s=[this.getValidationMessage(l,"max","string_exceed_max_length"),l.max];break}if(!l.format||("string"==typeof l.format&&(l.format=new RegExp(l.format)),l.format.test(i[u])))break;s=[this.getValidationMessage(l,"format","string_invalid_format"),l.format];break;case"number":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["number_nan"]);break}if(isNaN(i[u])){s=["number_nan"];break}if("integer"==n.type){if(parseInt(i[u])!=i[u]){s=["number_not_integer"];break}}else if(parseFloat(i[u])!=i[u]){s=["number_not_double"];break}if(void 0!==l.min&&i[u]parseFloat(l.max)){s=[this.getValidationMessage(l,"max","number_exceed_max"),l.max];break}if(void 0!==l.step&&"any"!==l.step){var p=(i[u]/l.step).toPrecision(14);if(parseInt(p)!=p){s=[this.getValidationMessage(l,"step","number_wrong_step"),l.step];break}}break;case"datetime":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["datetime_empty"]);break}if(l.format){"moment"in window||h.error("MissingLibrary","MomentJS is required for Date/Time validation. Get it here http://momentjs.com");var d=moment(i[u],l.format);if(!d.isValid()){s=[this.getValidationMessage(l,"format","datetime_invalid"),l.format];break}if(l.min&&dmoment(l.max,l.format)){s=[this.getValidationMessage(l,"max","datetime_exceed_max"),l.max];break}}break;case"boolean":if(void 0===i[u]||0===i[u].length){l.allow_empty_value||(s=["boolean_not_valid"]);break}if("true"!==(r=(""+i[u]).trim().toLowerCase())&&"false"!==r&&"1"!==r&&"0"!==r&&1!==i[u]&&0!==i[u]){s=["boolean_not_valid"];break}}if(!0!==s)break}}if(!0!==s)break}if(("between"===e.operator.type||"not_between"===e.operator.type)&&2===t.length)switch(c.types[n.type]){case"number":t[0]>t[1]&&(s=["number_between_invalid",t[0],t[1]]);break;case"datetime":l.format&&("moment"in window||h.error("MissingLibrary","MomentJS is required for Date/Time validation. Get it here http://momentjs.com"),moment(t[0],l.format).isAfter(moment(t[1],l.format))&&(s=["datetime_between_invalid",t[0],t[1]]))}return s},c.prototype.nextGroupId=function(){return this.status.id+"_group_"+this.status.group_id++},c.prototype.nextRuleId=function(){return this.status.id+"_rule_"+this.status.rule_id++},c.prototype.getOperators=function(r){"string"==typeof r&&(r=this.getFilterById(r));for(var e=[],t=0,i=this.operators.length;t ',c.templates.rule='
{{? it.settings.display_errors }}
{{?}}
',c.templates.filterSelect='{{ var optgroup = null; }} {{? it.settings.display_empty_filter }} {{= it.settings.select_placeholder }} {{?}} {{~ it.filters: filter }} {{? optgroup !== filter.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = filter.optgroup) !== null }} {{?}} {{?}} {{= it.translate(filter.label) }} {{~}} {{? optgroup !== null }} {{?}} ',c.templates.operatorSelect='{{? it.operators.length === 1 }} {{= it.translate("operators", it.operators[0].type) }} {{?}} {{ var optgroup = null; }} {{~ it.operators: operator }} {{? optgroup !== operator.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = operator.optgroup) !== null }} {{?}} {{?}} {{= it.translate("operators", operator.type) }} {{~}} {{? optgroup !== null }} {{?}} ',c.templates.ruleValueSelect='{{ var optgroup = null; }} {{? it.rule.filter.placeholder }} {{= it.rule.filter.placeholder }} {{?}} {{~ it.rule.filter.values: entry }} {{? optgroup !== entry.optgroup }} {{? optgroup !== null }}{{?}} {{? (optgroup = entry.optgroup) !== null }} {{?}} {{?}} {{= entry.label }} {{~}} {{? optgroup !== null }} {{?}} ',c.prototype.getGroupTemplate=function(e,t){var r=this.templates.group({builder:this,group_id:e,level:t,conditions:this.settings.conditions,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getGroupTemplate",r,t)},c.prototype.getRuleTemplate=function(e){var t=this.templates.rule({builder:this,rule_id:e,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleTemplate",t)},c.prototype.getRuleFilterSelect=function(e,t){var r=this.templates.filterSelect({builder:this,rule:e,filters:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleFilterSelect",r,e,t)},c.prototype.getRuleOperatorSelect=function(e,t){var r=this.templates.operatorSelect({builder:this,rule:e,operators:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleOperatorSelect",r,e,t)},c.prototype.getRuleValueSelect=function(e,t){var r=this.templates.ruleValueSelect({builder:this,name:e,rule:t,icons:this.icons,settings:this.settings,translate:this.translate.bind(this)});return this.change("getRuleValueSelect",r,e,t)},c.prototype.getRuleInput=function(e,t){var r=e.filter,i=e.filter.validation||{},n=e.id+"_value_"+t,o=r.vertical?" class=block":"",l="",s=Array.isArray(r.placeholder)?r.placeholder[t]:r.placeholder;if("function"==typeof r.input)l=r.input.call(this,e,n);else switch(r.input){case"radio":case"checkbox":h.iterateOptions(r.values,function(e,t){l+=" '+t+" "});break;case"select":l=this.getRuleValueSelect(n,e);break;case"textarea":l+='";break;case"number":l+=' " ;break;default:l=' " }return this.change getRuleInput ,l,e,n)};var h="{};function" i(){this.root='null,this.$=$(this)}(c.utils=h).iterateOptions=function(e,r){e&&($.isArray(e)?e.forEach(function(e){$.isPlainObject(e)?"value"in' e?r(e.value,e.label||e.value,e.optgroup):$.each(e,function(e,t){return r(e,t),!1}):r(e,e)}):$.each(e,function(e,t){r(e,t)}))},h.fmt="function(e,r){return" Array.isArray(r)||(r="Array.prototype.slice.call(arguments,1)),e.replace(/{([0-9]+)}/g,function(e,t){return" r[parseInt(t)]})},h.error="function(){var" e='0,t="boolean"!=typeof' arguments[e]||arguments[e++],r="arguments[e++],i=arguments[e++],n=Array.isArray(arguments[e])?arguments[e]:Array.prototype.slice.call(arguments,e);if(t){var" o="new" Error(h.fmt(i,n));throw o.name='r+"Error",o.args=n,o}console.error(r+"Error:' +h.fmt(i,n))},h.changeType='function(e,t){if(""!==e&&void' 0='=e)switch(t){case"integer":return"string"!=typeof' e||/^-?\d+$/.test(e)?parseInt(e):e;case double :return string !="typeof" e||/^-?\d+\.?\d*$/.test(e)?parseFloat(e):e;case boolean :return string !="typeof" e||/^(0|1|true|false){1}$/i.test(e)?!0='==e||1===e||"true"===e.toLowerCase()||"1"===e:e;default:return' e}},h.escapeString='function(e){return"string"!=typeof' e?e:e.replace(/[\0\n\r\b \ ]/g,function(e){switch(e){case \0 :return \\0 ;case \n :return \\n ;case \r :return \\r ;case \b :return \\b ;default:return \ +e}}).replace(/\t/g \\t ).replace(/\x1a/g \\Z )},h.escapeRegExp="function(e){return" e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g \ )},h.escapeElementId="function(e){return" e?e.replace(/(\\)?([:.\[\],])/g,function(e,t,r){return t?e \ +r}):e},h.groupSort="function(e,r){var" i="[],n=[];return" e.forEach(function(e){var t;e[r]?-1="=(t=i.lastIndexOf(e[r]))?t=i.length:t++:t=i.length,i.splice(t,0,e[r]),n.splice(t,0,e)}),n},h.defineModelProperties=function(e,t){t.forEach(function(r){Object.defineProperty(e.prototype,r,{enumerable:!0,get:function(){return" this.__[r]},set:function(e){var t='null!==this.__[r]&&"object"==typeof' this.__[r]?$.extend({},this.__[r]):this.__[r];this.__[r='e,null!==this.model&&this.model.trigger("update",this,r,e,t)}})})},$.extend(i.prototype,{trigger:function(e){var' t="new" $.Event(e);return this.$.triggerHandler(t,Array.prototype.slice.call(arguments,1)),t},on:function(){return this.$.on.apply(this.$,Array.prototype.slice.call(arguments)),this},off:function(){return this.$.off.apply(this.$,Array.prototype.slice.call(arguments)),this},once:function(){return this.$.one.apply(this.$,Array.prototype.slice.call(arguments)),this}});var n="function(e,t){if(!(this" instanceof n))return new n(e,t);Object.defineProperty(this _ ,{value:{}}),t.data queryBuilderModel ,this),this.__.level="1,this.__.error=null,this.__.flags={},this.__.data=void" 0,this.$el='t,this.id=t[0].id,this.model=null,this.parent=e};h.defineModelProperties(n,["level","error","data","flags"]),Object.defineProperty(n.prototype,"parent",{enumerable:!0,get:function(){return' this.__.parent},set:function(e){this.__.parent="e,this.level=null===e?1:e.level+1,this.model=null===e?null:e.model}}),n.prototype.isRoot=function(){return" 1="==this.level},n.prototype.getPos=function(){return" this.isRoot()?-1:this.parent.getNodePos(this)},n.prototype.drop="function(){var" e='this.model;this.parent&&this.parent.removeNode(this),this.$el.removeData("queryBuilderModel"),null!==e&&e.trigger("drop",this)},n.prototype.moveAfter=function(e){this.isRoot()||this.move(e.parent,e.getPos()+1)},n.prototype.moveAtBegin=function(e){this.isRoot()||(void' 0="==e&&(e=this.parent),this.move(e,0))},n.prototype.moveAtEnd=function(e){this.isRoot()||(void" 0='==e&&(e=this.parent),this.move(e,0===e.length()?0:e.length()-1))},n.prototype.move=function(e,t){this.isRoot()||("number"==typeof' e&&(t='e,e=this.parent),this.parent.removeNode(this),e.insertNode(this,t,!1),null!==this.model&&this.model.trigger("move",this,e,t))};var' a="function(e,t){if(!(this" instanceof a))return new a(e,t);n.call(this,e,t),this.rules='[],this.__.condition=null};a.prototype=Object.create(n.prototype),a.prototype.constructor=a,h.defineModelProperties(a,["condition"]),a.prototype.empty=function(){this.each("reverse",function(e){e.drop()},function(e){e.drop()})},a.prototype.drop=function(){this.empty(),n.prototype.drop.call(this)},a.prototype.length=function(){return' this.rules.length},a.prototype.insertNode="function(e,t,r){return" void 0='==t&&(t=this.length()),this.rules.splice(t,0,e),e.parent=this,r&&null!==this.model&&this.model.trigger("add",this,e,t),e},a.prototype.addGroup=function(e,t){return' this.insertNode(new a(this,e),t,!0)},a.prototype.addRule="function(e,t){return" this.insertNode(new l(this,e),t,!0)},a.prototype.removeNode="function(e){var" t="this.getNodePos(e);-1!==t&&(e.parent=null,this.rules.splice(t,1))},a.prototype.getNodePos=function(e){return" this.rules.indexOf(e)},a.prototype.each='function(e,t,r,i){"boolean"!=typeof' e string !="typeof" e&&(i="r,r=t,t=e,e=!1),i=void" 0="==i?null:i;for(var" n="e?this.rules.length-1:0,o=e?0:this.rules.length-1,l=e?-1:1,s=!1;(e?o<=n:n<=o)&&(this.rules[n]instanceof" a?r&&(s="!1===r.call(i,this.rules[n])):t&&(s=!1===t.call(i,this.rules[n])),!s);n+=l);return!s},a.prototype.contains=function(t,e){return-1!==this.getNodePos(t)||!!e&&!this.each(function(){return!0},function(e){return!e.contains(t,!0)})};var" l="function(e,t){if(!(this" instanceof l))return new l(e,t);n.call(this,e,t),this._updating_value="!1,this._updating_input=!1,this.__.filter=null,this.__.operator=null,this.__.value=void" 0};function u(e,t,r){var i,n,o='c.selectors;(i=t.closest(o.rule_container)).length&&(n="moveAfter"),n||(i=t.closest(o.group_header)).length&&(i=t.closest(o.group_container),n="moveAtBegin"),n||(i=t.closest(o.group_container)).length&&(n="moveAtEnd"),n&&(e[n](r.getModel(i)),r&&e' instanceof l&&r.setRuleInputValue(e,e.value))}function o(e){var t="e.match(/(question_mark|numbered|named)(?:\((.)\))?/);return" t||(t='[null,"question_mark",void' 0]),t}return l.prototype='Object.create(n.prototype),l.prototype.constructor=l,h.defineModelProperties(l,["filter","operator","value"]),l.prototype.isRoot=function(){return!1},c.Group=a,c.Rule=l,$.fn.queryBuilder=function(e){0===this.length&&h.error("Config","No' target defined ),1> '+t+" "})}})},{font:"glyphicons",color:"default"}),c.define("bt-selectpicker",function(r){$.fn.selectpicker&&$.fn.selectpicker.Constructor||h.error("MissingLibrary",'Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select');var i=c.selectors;this.on("afterCreateRuleFilters",function(e,t){t.$el.find(i.rule_filter).removeClass("form-control").selectpicker(r)}),this.on("afterCreateRuleOperators",function(e,t){t.$el.find(i.rule_operator).removeClass("form-control").selectpicker(r)}),this.on("afterUpdateRuleFilter",function(e,t){t.$el.find(i.rule_filter).selectpicker("render")}),this.on("afterUpdateRuleOperator",function(e,t){t.$el.find(i.rule_operator).selectpicker("render")}),this.on("beforeDeleteRule",function(e,t){t.$el.find(i.rule_filter).selectpicker("destroy"),t.$el.find(i.rule_operator).selectpicker("destroy")})},{container:"body",style:"btn-inverse btn-xs",width:"auto",showIcon:!1}),c.define("bt-tooltip-errors",function(i){$.fn.tooltip&&$.fn.tooltip.Constructor&&$.fn.tooltip.Constructor.prototype.fixTitle||h.error("MissingLibrary",'Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com');var n=this;this.on("getRuleTemplate.filter getGroupTemplate.filter",function(e){var t=$(e.value);t.find(c.selectors.error_container).attr("data-toggle","tooltip"),e.value=t.prop("outerHTML")}),this.model.on("update",function(e,t,r){"error"==r&&n.settings.display_errors&&t.$el.find(c.selectors.error_container).eq(0).tooltip(i).tooltip("hide").tooltip("fixTitle")})},{placement:"right"}),c.extend({setFilters:function(e,t){var r=this;void 0===t&&(t=e,e=!1),t=this.checkFilters(t);var i=(t=this.change("setFilters",t)).map(function(e){return e.id});if(e||function e(t){t.each(function(e){e.filter&&-1===i.indexOf(e.filter.id)&&h.error("ChangeFilter",'A rule is using filter "{0}"',e.filter.id)},e)}(this.model.root),this.filters=t,function e(t){t.each(!0,function(e){e.filter&&-1===i.indexOf(e.filter.id)?(e.drop(),r.trigger("rulesChanged")):(r.createRuleFilters(e),e.$el.find(c.selectors.rule_filter).val(e.filter?e.filter.id:"-1"),r.trigger("afterUpdateRuleFilter",e))},e)}(this.model.root),this.settings.plugins&&(this.settings.plugins["unique-filter"]&&this.updateDisabledFilters(),this.settings.plugins["bt-selectpicker"]&&this.$el.find(c.selectors.rule_filter).selectpicker("render")),this.settings.default_filter)try{this.getFilterById(this.settings.default_filter)}catch(e){this.settings.default_filter=null}this.trigger("afterSetFilters",t)},addFilter:function(e,r){void 0===r||"#end"==r?r=this.filters.length:"#start"==r&&(r=0),$.isArray(e)||(e=[e]);var t=$.extend(!0,[],this.filters);parseInt(r)==r?Array.prototype.splice.apply(t,[r,0].concat(e)):this.filters.some(function(e,t){if(e.id==r)return r=t+1,!0})?Array.prototype.splice.apply(t,[r,0].concat(e)):Array.prototype.push.apply(t,e),this.setFilters(t)},removeFilter:function(t,e){var r=$.extend(!0,[],this.filters);"string"==typeof t&&(t=[t]),r=r.filter(function(e){return-1===t.indexOf(e.id)}),this.setFilters(e,r)}}),c.define("chosen-selectpicker",function(r){$.fn.chosen||h.error("MissingLibrary",'chosen is required to use "chosen-selectpicker" plugin. Get it here: https://github.com/harvesthq/chosen'),this.settings.plugins["bt-selectpicker"]&&h.error("Conflict","bt-selectpicker is already selected as the dropdown plugin. Please remove chosen-selectpicker from the plugin list");var i=c.selectors;this.on("afterCreateRuleFilters",function(e,t){t.$el.find(i.rule_filter).removeClass("form-control").chosen(r)}),this.on("afterCreateRuleOperators",function(e,t){1')).appendTo(t.$el):r.css("display",""),r.html(' '+i)):r.hide()}):"popover"===n.mode?($.fn.popover&&$.fn.popover.Constructor&&$.fn.popover.Constructor.prototype.fixTitle||h.error("MissingLibrary",'Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com'),this.on("afterUpdateRuleFilter afterUpdateRuleOperator",function(e,t){var r=t.$el.find("button.filter-description"),i=e.builder.getFilterDescription(t.filter,t);i?(0===r.length?((r=$(' ')).prependTo(t.$el.find(c.selectors.rule_actions)),r.popover({placement:"left",container:"body",html:!0}),r.on("mouseout",function(){r.popover("hide")})):r.css("display",""),r.data("bs.popover").options.content=i,r.attr("aria-describedby")&&r.popover("show")):(r.hide(),r.data("bs.popover")&&r.popover("hide"))})):"bootbox"===n.mode&&("bootbox"in window||h.error("MissingLibrary",'Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com'),this.on("afterUpdateRuleFilter afterUpdateRuleOperator",function(e,t){var r=t.$el.find("button.filter-description"),i=e.builder.getFilterDescription(t.filter,t);i?(0===r.length?((r=$(' ')).prependTo(t.$el.find(c.selectors.rule_actions)),r.on("click",function(){bootbox.alert(r.data("description"))})):r.css("display",""),r.data("description",i)):r.hide()}))},{icon:"glyphicon glyphicon-info-sign",mode:"popover"}),c.extend({getFilterDescription:function(e,t){return e?"function"==typeof e.description?e.description.call(this,t):e.description:void 0}}),c.define("invert",function(r){var i=this,n=c.selectors;this.on("afterInit",function(){i.$el.on("click.queryBuilder","[data-invert=group]",function(){var e=$(this).closest(n.group_container);i.invert(i.getModel(e),r)}),r.display_rules_button&&r.invert_rules&&i.$el.on("click.queryBuilder","[data-invert=rule]",function(){var e=$(this).closest(n.rule_container);i.invert(i.getModel(e),r)})}),r.disable_template||(this.on("getGroupTemplate.filter",function(e){var t=$(e.value);t.find(n.condition_container).after(' '+i.translate("invert")+" "),e.value=t.prop("outerHTML")}),r.display_rules_button&&r.invert_rules&&this.on("getRuleTemplate.filter",function(e){var t=$(e.value);t.find(n.rule_actions).prepend(' '+i.translate("invert")+" "),e.value=t.prop("outerHTML")}))},{icon:"glyphicon glyphicon-random",recursive:!0,invert_rules:!0,display_rules_button:!1,silent_fail:!1,disable_template:!1}),c.defaults({operatorOpposites:{equal:"not_equal",not_equal:"equal",in:"not_in",not_in:"in",less:"greater_or_equal",less_or_equal:"greater",greater:"less_or_equal",greater_or_equal:"less",between:"not_between",not_between:"between",begins_with:"not_begins_with",not_begins_with:"begins_with",contains:"not_contains",not_contains:"contains",ends_with:"not_ends_with",not_ends_with:"ends_with",is_empty:"is_not_empty",is_not_empty:"is_empty",is_null:"is_not_null",is_not_null:"is_null"},conditionOpposites:{AND:"OR",OR:"AND"}}),c.extend({invert:function(e,t){if(!(e instanceof n)){if(!this.model.root)return;t=e,e=this.model.root}if("object"!=typeof t&&(t={}),void 0===t.recursive&&(t.recursive=!0),void 0===t.invert_rules&&(t.invert_rules=!0),void 0===t.silent_fail&&(t.silent_fail=!1),void 0===t.trigger&&(t.trigger=!0),e instanceof a){if(this.settings.conditionOpposites[e.condition]?e.condition=this.settings.conditionOpposites[e.condition]:t.silent_fail||h.error("InvertCondition",'Unknown inverse of condition "{0}"',e.condition),t.recursive){var r=$.extend({},t,{trigger:!1});e.each(function(e){t.invert_rules&&this.invert(e,r)},function(e){this.invert(e,r)},this)}}else if(e instanceof l&&e.operator&&!e.filter.no_invert)if(this.settings.operatorOpposites[e.operator.type]){var i=this.settings.operatorOpposites[e.operator.type];e.filter.operators&&-1==e.filter.operators.indexOf(i)||(e.operator=this.getOperatorByType(i))}else t.silent_fail||h.error("InvertOperator",'Unknown inverse of operator "{0}"',e.operator.type);t.trigger&&(this.trigger("afterInvert",e,t),this.trigger("rulesChanged"))}}),c.defaults({mongoOperators:{equal:function(e){return e[0]},not_equal:function(e){return{$ne:e[0]}},in:function(e){return{$in:e}},not_in:function(e){return{$nin:e}},less:function(e){return{$lt:e[0]}},less_or_equal:function(e){return{$lte:e[0]}},greater:function(e){return{$gt:e[0]}},greater_or_equal:function(e){return{$gte:e[0]}},between:function(e){return{$gte:e[0],$lte:e[1]}},not_between:function(e){return{$lt:e[0],$gt:e[1]}},begins_with:function(e){return{$regex:"^"+h.escapeRegExp(e[0])}},not_begins_with:function(e){return{$regex:"^(?!"+h.escapeRegExp(e[0])+")"}},contains:function(e){return{$regex:h.escapeRegExp(e[0])}},not_contains:function(e){return{$regex:"^((?!"+h.escapeRegExp(e[0])+").)*$",$options:"s"}},ends_with:function(e){return{$regex:h.escapeRegExp(e[0])+"$"}},not_ends_with:function(e){return{$regex:"(? '+i.translate("NOT")+""),e.value=t.prop("outerHTML")}),this.on("groupToJson.filter",function(e,t){e.value.not=t.not}),this.on("jsonToGroup.filter",function(e,t){e.value.not=!!t.not}),this.on("groupToSQL.filter",function(e,t){t.not&&(e.value="NOT ( "+e.value+" )")}),this.on("parseSQLNode.filter",function(e){e.value.name&&"NOT"==e.value.name.toUpperCase()&&(e.value=e.value.arguments.value[0],-1===["AND","OR"].indexOf(e.value.operation.toUpperCase())&&(e.value=new SQLParser.nodes.Op(i.settings.default_condition,e.value,null)),e.value.not=!0)}),this.on("sqlGroupsDistinct.filter",function(e,t,r,i){r.not&&0"+c.selectors.group_not).toggleClass("active",e.not).find("i").attr("class",e.not?t.icon_checked:t.icon_unchecked),this.trigger("afterUpdateGroupNot",e),this.trigger("rulesChanged")}}),c.define("sortable",function(i){var n,o,l,s;"interact"in window||h.error("MissingLibrary",'interact.js is required to use "sortable" plugin. Get it here: http://interactjs.io'),void 0!==i.default_no_sortable&&(h.error(!1,"Config",'Sortable plugin : "default_no_sortable" options is deprecated, use standard "default_rule_flags" and "default_group_flags" instead'),this.settings.default_rule_flags.no_sortable=this.settings.default_group_flags.no_sortable=i.default_no_sortable),interact.dynamicDrop(!0),interact.pointerMoveTolerance(10),this.on("afterAddRule afterAddGroup",function(e,t){if(t!=n){var r=e.builder;i.inherit_no_sortable&&t.parent&&t.parent.flags.no_sortable&&(t.flags.no_sortable=!0),i.inherit_no_drop&&t.parent&&t.parent.flags.no_drop&&(t.flags.no_drop=!0),t.flags.no_sortable||interact(t.$el[0]).draggable({allowFrom:c.selectors.drag_handle,onstart:function(e){s=!1,l=r.getModel(e.target),o=l.$el.clone().appendTo(l.$el.parent()).width(l.$el.outerWidth()).addClass("dragging");var t=$('
').height(l.$el.outerHeight());n=l.parent.addRule(t,l.getPos()),l.$el.hide()},onmove:function(e){o[0].style.top=e.clientY-15+"px",o[0].style.left=e.clientX-15+"px"},onend:function(e){e.dropzone&&(u(l,$(e.relatedTarget),r),s=!0),o.remove(),o=void 0,n.drop(),n=void 0,l.$el.css("display",""),r.trigger("afterMove",l),r.trigger("rulesChanged")}}),t.flags.no_drop||(interact(t.$el[0]).dropzone({accept:c.selectors.rule_and_group_containers,ondragenter:function(e){u(n,$(e.target),r)},ondrop:function(e){s||u(l,$(e.target),r)}}),t instanceof a&&interact(t.$el.find(c.selectors.group_header)[0]).dropzone({accept:c.selectors.rule_and_group_containers,ondragenter:function(e){u(n,$(e.target),r)},ondrop:function(e){s||u(l,$(e.target),r)}}))}}),this.on("beforeDeleteRule beforeDeleteGroup",function(e,t){e.isDefaultPrevented()||(interact(t.$el[0]).unset(),t instanceof a&&interact(t.$el.find(c.selectors.group_header)[0]).unset())}),this.on("afterApplyRuleFlags afterApplyGroupFlags",function(e,t){t.flags.no_sortable&&t.$el.find(".drag-handle").remove()}),i.disable_template||(this.on("getGroupTemplate.filter",function(e,t){if(1 '),e.value=r.prop("outerHTML")}}),this.on("getRuleTemplate.filter",function(e){var t=$(e.value);t.find(c.selectors.rule_header).after('
'),e.value=t.prop("outerHTML")}))},{inherit_no_sortable:!0,inherit_no_drop:!0,icon:"glyphicon glyphicon-sort",disable_template:!1}),c.selectors.rule_and_group_containers=c.selectors.rule_container+", "+c.selectors.group_container,c.selectors.drag_handle=".drag-handle",c.defaults({default_rule_flags:{no_sortable:!1,no_drop:!1},default_group_flags:{no_sortable:!1,no_drop:!1}}),c.define("sql-support",function(e){},{boolean_as_integer:!0}),c.defaults({sqlOperators:{equal:{op:"= ?"},not_equal:{op:"!= ?"},in:{op:"IN(?)",sep:", "},not_in:{op:"NOT IN(?)",sep:", "},less:{op:"< ?"},less_or_equal:{op:"<= ?"},greater:{op:"> ?"},greater_or_equal:{op:">= ?"},between:{op:"BETWEEN ?",sep:" AND "},not_between:{op:"NOT BETWEEN ?",sep:" AND "},begins_with:{op:"LIKE(?)",mod:"{0}%"},not_begins_with:{op:"NOT LIKE(?)",mod:"{0}%"},contains:{op:"LIKE(?)",mod:"%{0}%"},not_contains:{op:"NOT LIKE(?)",mod:"%{0}%"},ends_with:{op:"LIKE(?)",mod:"%{0}"},not_ends_with:{op:"NOT LIKE(?)",mod:"%{0}"},is_empty:{op:"= ''"},is_not_empty:{op:"!= ''"},is_null:{op:"IS NULL"},is_not_null:{op:"IS NOT NULL"}},sqlRuleOperator:{"=":function(e){return{val:e,op:""===e?"is_empty":"equal"}},"!=":function(e){return{val:e,op:""===e?"is_not_empty":"not_equal"}},LIKE:function(e){return"%"==e.slice(0,1)&&"%"==e.slice(-1)?{val:e.slice(1,-1),op:"contains"}:"%"==e.slice(0,1)?{val:e.slice(1),op:"ends_with"}:"%"==e.slice(-1)?{val:e.slice(0,-1),op:"begins_with"}:void h.error("SQLParse",'Invalid value for LIKE operator "{0}"',e)},"NOT LIKE":function(e){return"%"==e.slice(0,1)&&"%"==e.slice(-1)?{val:e.slice(1,-1),op:"not_contains"}:"%"==e.slice(0,1)?{val:e.slice(1),op:"not_ends_with"}:"%"==e.slice(-1)?{val:e.slice(0,-1),op:"not_begins_with"}:void h.error("SQLParse",'Invalid value for NOT LIKE operator "{0}"',e)},IN:function(e){return{val:e,op:"in"}},"NOT IN":function(e){return{val:e,op:"not_in"}},"<":function(e){return{val:e,op:"less"}},"<=":function(e){return{val:e,op:"less_or_equal"}},">":function(e){return{val:e,op:"greater"}},">=":function(e){return{val:e,op:"greater_or_equal"}},BETWEEN:function(e){return{val:e,op:"between"}},"NOT BETWEEN":function(e){return{val:e,op:"not_between"}},IS:function(e){return null!==e&&h.error("SQLParse","Invalid value for IS operator"),{val:null,op:"is_null"}},"IS NOT":function(e){return null!==e&&h.error("SQLParse","Invalid value for IS operator"),{val:null,op:"is_not_null"}}},sqlStatements:{question_mark:function(){var r=[];return{add:function(e,t){return r.push(t),"?"},run:function(){return r}}},numbered:function(r){(!r||1"==l&&(l="!=");var s=f.settings.sqlRuleOperator[l];void 0===s&&h.error("UndefinedSQLOperator",'Invalid SQL operation "{0}".',t.operation);var a,u=s.call(this,o,t.operation);"values"in t.left?a=t.left.values.join("."):"value"in t.left?a=t.left.value:h.error("SQLParse","Cannot find field name in {0}",JSON.stringify(t.left));var p=f.getSQLFieldID(a,o),d=f.change("sqlToRule",{id:p,field:a,operator:u.op,value:u.val},t);g.rules.push(d)}}(i,0),n},setRulesFromSQL:function(e,t){this.setRules(this.getRulesFromSQL(e,t))},getSQLFieldID:function(t,e){var r=this.filters.filter(function(e){return e.field.toLowerCase()===t.toLowerCase()});return 1===r.length?r[0].id:this.change("getSQLFieldID",t,e)}}),c.define("unique-filter",function(){this.status.used_filters={},this.on("afterUpdateRuleFilter",this.updateDisabledFilters),this.on("afterDeleteRule",this.updateDisabledFilters),this.on("afterCreateRuleFilters",this.applyDisabledFilters),this.on("afterReset",this.clearDisabledFilters),this.on("afterClear",this.clearDisabledFilters),this.on("getDefaultFilter.filter",function(t,r){var i=t.builder;(i.updateDisabledFilters(),t.value.id in i.status.used_filters)&&(i.filters.some(function(e){if(!(e.id in i.status.used_filters)||0 <",">","\"","'","/","matchHTML","code","toString","replace","m","eval","startend","start","end","startencode","split","skip","unescape","tmpl","c","def","needhtmlencode","indv","cse","sid","str","resolveDefs","block","assign","value","substring","param","v","arg","text","Function","s","d","rw","__exp","RegExp","elsecase","vname","iname","_encodeHTML","console","QueryBuilder","$el","queryBuilder","settings","DEFAULTS","model","Model","status","id","generated_id","group_id","rule_id","has_optgroup","has_operator_optgroup","filters","icons","operators","templates","plugins","lang","regional","Utils","error","lang_code","allow_groups","Object","keys","tpl","attr","Math","floor","random","addClass","checkFilters","checkOperators","bindEvents","initPlugins","prototype","trigger","event","Event","_tojQueryEvent","builder","triggerHandler","Array","slice","call","change","on","cb","off","once","one","filter","map","join","types","string","integer","double","date","time","datetime","boolean","inputs","modifiable_options","selectors","group_container","rule_container","filter_container","operator_container","value_container","error_container","condition_container","tooltip","description","rule_header","group_header","group_actions","rule_actions","rules_list","group_condition","rule_filter","rule_operator","rule_value","add_rule","delete_rule","add_group","delete_group","OPERATORS","equal","nb_inputs","multiple","apply_to","not_equal","in","not_in","less","less_or_equal","greater","greater_or_equal","between","not_between","begins_with","not_begins_with","contains","not_contains","ends_with","not_ends_with","is_empty","is_not_empty","is_null","is_not_null","sort_filters","display_errors","allow_empty","conditions","default_condition","inputs_separator","select_placeholder","display_empty_filter","default_filter","optgroups","default_rule_flags","filter_readonly","operator_readonly","value_readonly","no_delete","default_group_flags","condition_readonly","no_add_rule","no_add_group","group","rule","filterSelect","operatorSelect","ruleValueSelect","remove_group","remove_rule","defaults","fct","methods","tmp","plugin","getPluginOptions","property","init","rules","setRules","setRoot","definedFilters","input","operator","field","label","optgroup","values","cleanValues","iterateOptions","bind","groupSort","placeholder","placeholder_value","entry","sort","self","a","b","translate","localeCompare","definedOperators","Selectors","is","$group","closest","getModel","condition","val","$rule","getFilterById","getOperatorByType","addRule","deleteRule","addGroup","deleteGroup","drop","node","remove","refreshGroupsConditions","add","parent","index","prependTo","find","insertAfter","move","detach","update","oldValue","Rule","updateError","applyRuleFlags","updateRuleFilter","updateRuleOperator","updateRuleValue","applyGroupFlags","updateGroupCondition","data","flags","nextGroupId","getGroupTemplate","Group","level","isDefaultPrevented","isRoot","del","each","previousCondition","$this","prop","toggleClass","walk","nextRuleId","getRuleTemplate","createRuleFilters","$filterSelect","getRuleFilterSelect","html","createRuleOperators","$operatorContainer","empty","getOperators","$operatorSelect","getRuleOperatorSelect","default_operator","__","createRuleInput","$valueContainer","$inputs","$ruleInput","getRuleInput","css","input_event","_updating_input","_updating_value","getRuleInputValue","plugin_config","default_value","previousFilter","hide","show","previousOperator","previousValue","setRuleInputValue","clearErrors","removeClass","errorMessage","fmt","eq","triggerValidationError","destroy","removeAttr","clear","removeData","reset","setOptions","opt","Node","validate","skip_empty","valid","parse","done","errors","validateValue","res","getRules","get_flags","allow_invalid","out","groupData","getGroupFlags","isEmptyObject","ruleData","getRuleFlags","parseGroupFlags","item","parseRuleFlags","validation","result","callback","_validateValue","tempValue","allow_empty_value","j","min","parseInt","getValidationMessage","max","format","test","isNaN","parseFloat","step","toPrecision","window","moment","isValid","trim","isAfter","l","doThrow","valueGetter","$value","escapeElementId","value_separator","subval","changeType","valueParser","valueSetter","readonly","all","ret","key","category","translation","messages","h","getRuleValueSelect","value_id","vertical","size","rows","utils","args","message","err","Error","escapeString","escapeRegExp","$0","$1","$2","items","newItems","idx","lastIndexOf","splice","defineModelProperties","obj","fields","defineProperty","enumerable","get","set","apply","getPos","getNodePos","removeNode","moveAfter","moveAtBegin","moveAtEnd","insertNode","create","constructor","reverse","cbRule","cbGroup","context","stop","recursive","moveSortableToTarget","method","getStmtConfig","stmt","config","match","fn","option","font","colors","color","_def_","style","selectpicker","Constructor","container","width","showIcon","fixTitle","$h","placement","setFilters","deleteOrphans","filtersIds","checkOrphans","updateBuilder","updateDisabledFilters","addFilter","newFilters","position","some","removeFilter","filterIds","chosen","mode","$p","getFilterDescription","appendTo","icon","popover","$b","content","bootbox","alert","invert","display_rules_button","invert_rules","disable_template","after","prepend","silent_fail","operatorOpposites","conditionOpposites","AND","OR","tempOpts","no_invert","mongoOperators","$ne","$in","$nin","$lt","$lte","$gt","$gte","$regex","$options","mongoRuleOperators","$eq","op","getMongo","toUpperCase","parts","mdb","ope","ruleExpression","groupExpression","getRulesFromMongo","query","getMongoCondition","topKey","getMongoOperator","mdbrl","opVal","getMongoDBFieldID","setRulesFromMongo","matchingFilters","knownKeys","not","updateGroupNot","icon_unchecked","json","operation","SQLParser","nodes","Op","$nor","icon_checked","group_not","ghost","moved","default_no_sortable","no_sortable","interact","dynamicDrop","pointerMoveTolerance","inherit_no_sortable","inherit_no_drop","no_drop","draggable","allowFrom","drag_handle","onstart","outerWidth","ph","height","outerHeight","onmove","top","clientY","left","clientX","onend","dropzone","relatedTarget","accept","rule_and_group_containers","ondragenter","ondrop","unset","boolean_as_integer","sqlOperators","sep","mod","sqlRuleOperator","=","!=","LIKE","NOT LIKE","IN","NOT IN","<=",">=","BETWEEN","NOT BETWEEN","IS","IS NOT","sqlStatements","question_mark","params","run","numbered","char","named","indexes","sqlRuleStatement","esc","sql","regex1","regex2","getSQL","nl","sqlFn","getRulesFromSQL","parsed","where","curr","flatten","next","right","sqlrl","JSON","stringify","getSQLFieldID","setRulesFromSQL","used_filters","applyDisabledFilters","clearDisabledFilters","unique","filterId","groups","__locale","__author","no_filter","empty_group","radio_empty","checkbox_empty","select_empty","string_empty","string_exceed_min_length","string_exceed_max_length","string_invalid_format","number_nan","number_not_integer","number_not_double","number_exceed_min","number_exceed_max","number_wrong_step","number_between_invalid","datetime_empty","datetime_invalid","datetime_exceed_min","datetime_exceed_max","datetime_between_invalid","boolean_not_valid","operator_not_multiple","NOT"],"mappings":"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","file":"query-builder.standalone.min.js"}
\ No newline at end of file
diff --git a/dist/scss/dark.scss b/dist/scss/dark.scss
new file mode 100644
index 00000000..19468b2d
--- /dev/null
+++ b/dist/scss/dark.scss
@@ -0,0 +1,19 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+$theme-name: dark;
+
+$group-background-color: rgba(50, 70, 80, .5);
+$group-border-color: #00164A;
+
+$rule-background-color: rgba(40, 40, 40, .9);
+$rule-border-color: #111;
+
+$error-border-color: #800;
+$error-background-color: #322;
+
+$ticks-color: #222;
+
+@import 'default';
diff --git a/dist/scss/default.scss b/dist/scss/default.scss
new file mode 100644
index 00000000..ade88f56
--- /dev/null
+++ b/dist/scss/default.scss
@@ -0,0 +1,186 @@
+/*!
+ * jQuery QueryBuilder 1.2.1
+ * Copyright 2014-2019 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
+ * Licensed under MIT (https://opensource.org/licenses/MIT)
+ */
+$theme-name: default !default;
+
+// common
+$item-vertical-spacing: 4px !default;
+$item-border-radius: 5px !default;
+
+// groups
+$group-background-color: rgba(250, 240, 210, .5) !default;
+$group-border-color: #DCC896 !default;
+$group-border: 1px solid $group-border-color !default;
+$group-padding: 10px !default;
+
+// rules
+$rule-background-color: rgba(255, 255, 255, .9) !default;
+$rule-border-color: #EEE !default;
+$rule-border: 1px solid $rule-border-color !default;
+$rule-padding: 5px !default;
+// scss-lint:disable ColorVariable
+$rule-value-separator: 1px solid #DDD !default;
+
+// errors
+$error-icon-color: #F00 !default;
+$error-border-color: #F99 !default;
+$error-background-color: #FDD !default;
+
+// ticks
+$ticks-width: 2px !default;
+$ticks-color: #CCC !default;
+$ticks-position: 5px, 10px !default;
+
+
+// ABSTRACTS
+%base-container {
+ position: relative;
+ margin: $item-vertical-spacing 0;
+ border-radius: $item-border-radius;
+ padding: $rule-padding;
+ border: $rule-border;
+ background: $rule-background-color;
+}
+
+%rule-component {
+ display: inline-block;
+ margin: 0 5px 0 0;
+ vertical-align: middle;
+}
+
+.query-builder {
+
+ // GROUPS
+ .rules-group-container {
+ @extend %base-container;
+
+ padding: $group-padding;
+ padding-bottom: #{$group-padding - $item-vertical-spacing};
+ border: $group-border;
+ background: $group-background-color;
+ }
+
+ .rules-group-header {
+ margin-bottom: $group-padding;
+
+ .group-conditions {
+ .btn.readonly:not(.active),
+ input[name$='_cond'] {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+ white-space: nowrap;
+ }
+
+ .btn.readonly {
+ border-radius: 3px;
+ }
+ }
+ }
+
+ .rules-list {
+ list-style: none;
+ padding: 0 0 0 #{nth($ticks-position, 1) + nth($ticks-position, 2)};
+ margin: 0;
+ }
+
+ // RULES
+ .rule-container {
+ @extend %base-container;
+
+ .rule-filter-container,
+ .rule-operator-container,
+ .rule-value-container {
+ @extend %rule-component;
+ }
+ }
+
+ .rule-value-container {
+ border-left: $rule-value-separator;
+ padding-left: 5px;
+
+ label {
+ margin-bottom: 0;
+ font-weight: normal;
+
+ &.block {
+ display: block;
+ }
+ }
+
+ select,
+ input[type='text'],
+ input[type='number'] {
+ padding: 1px;
+ }
+ }
+
+ // ERRORS
+ .error-container {
+ @extend %rule-component;
+ display: none;
+ cursor: help;
+ color: $error-icon-color;
+ }
+
+ .has-error {
+ background-color: $error-background-color;
+ border-color: $error-border-color;
+
+ .error-container {
+ display: inline-block !important;
+ }
+ }
+
+ // TICKS
+ .rules-list>* {
+ &::before,
+ &::after {
+ content: '';
+ position: absolute;
+ left: #{-1 * nth($ticks-position, 2)};
+ width: nth($ticks-position, 2);
+ height: calc(50% + #{$item-vertical-spacing});
+ border-color: $ticks-color;
+ border-style: solid;
+ }
+
+ &::before {
+ top: #{-2 * $ticks-width};
+ border-width: 0 0 $ticks-width $ticks-width;
+ }
+
+ &::after {
+ top: 50%;
+ border-width: 0 0 0 $ticks-width;
+ }
+
+ &:first-child::before {
+ top: #{-$group-padding - $ticks-width};
+ height: calc(50% + #{$group-padding + $item-vertical-spacing});
+ }
+
+ &:last-child::before {
+ border-radius: 0 0 0 #{2 * $ticks-width};
+ }
+
+ &:last-child::after {
+ display: none;
+ }
+ }
+}
+
+// import
+@import "plugins/_bt-checkbox";
+@import "plugins/_bt-tooltip-errors";
+@import "plugins/_filter-description";
+@import "plugins/_invert";
+@import "plugins/_sortable";
+// endimport
diff --git a/dist/scss/plugins/_bt-checkbox.scss b/dist/scss/plugins/_bt-checkbox.scss
new file mode 100644
index 00000000..324f610f
--- /dev/null
+++ b/dist/scss/plugins/_bt-checkbox.scss
@@ -0,0 +1,12 @@
+.query-builder.bt-checkbox-glyphicons {
+ .checkbox input[type='checkbox']:checked + label::after {
+ font-family: 'Glyphicons Halflings';
+ content: '\e013';
+ }
+
+ .checkbox label::after {
+ padding-left: 4px;
+ padding-top: 2px;
+ font-size: 9px;
+ }
+}
diff --git a/dist/scss/plugins/_bt-tooltip-errors.scss b/dist/scss/plugins/_bt-tooltip-errors.scss
new file mode 100644
index 00000000..21323e5f
--- /dev/null
+++ b/dist/scss/plugins/_bt-tooltip-errors.scss
@@ -0,0 +1,9 @@
+$error-tooltip-color: #F99;
+
+@if $theme-name == 'dark' {
+ $error-tooltip-color: #F22;
+}
+
+.query-builder .error-container + .tooltip .tooltip-inner {
+ color: $error-tooltip-color !important;
+}
diff --git a/dist/scss/plugins/_filter-description.scss b/dist/scss/plugins/_filter-description.scss
new file mode 100644
index 00000000..80a2af71
--- /dev/null
+++ b/dist/scss/plugins/_filter-description.scss
@@ -0,0 +1,21 @@
+$description-background-color: #D9EDF7;
+$description-border-color: #BCE8F1;
+$description-text-color: #31708F;
+
+@if $theme-name == 'dark' {
+ $description-background-color: rgba(0, 170, 255, .2);
+ $description-text-color: #AAD1E4;
+ $description-border-color: #346F7B;
+}
+
+$description-border: 1px solid $description-border-color;
+
+.query-builder p.filter-description {
+ margin: $rule-padding 0 0 0;
+ background: $description-background-color;
+ border: $description-border;
+ color: $description-text-color;
+ border-radius: $item-border-radius;
+ padding: #{$rule-padding / 2} $rule-padding;
+ font-size: .8em;
+}
diff --git a/dist/scss/plugins/_invert.scss b/dist/scss/plugins/_invert.scss
new file mode 100644
index 00000000..5eb0458b
--- /dev/null
+++ b/dist/scss/plugins/_invert.scss
@@ -0,0 +1,5 @@
+.query-builder {
+ .rules-group-header [data-invert] {
+ margin-left: 5px;
+ }
+}
diff --git a/dist/scss/plugins/_sortable.scss b/dist/scss/plugins/_sortable.scss
new file mode 100644
index 00000000..ac902fe1
--- /dev/null
+++ b/dist/scss/plugins/_sortable.scss
@@ -0,0 +1,28 @@
+$placeholder-border-color: #BBB;
+$placeholder-border: 1px dashed $placeholder-border-color;
+
+.query-builder {
+ .drag-handle {
+ @extend %rule-component;
+ cursor: move;
+ vertical-align: middle;
+ margin-left: 5px;
+ }
+
+ .dragging {
+ position: fixed;
+ opacity: .5;
+ z-index: 100;
+
+ &::before,
+ &::after {
+ display: none;
+ }
+ }
+
+ .rule-placeholder {
+ @extend %base-container;
+ border: $placeholder-border;
+ opacity: .7;
+ }
+}
diff --git a/examples/screenshot.png b/examples/scr.png
similarity index 100%
rename from examples/screenshot.png
rename to examples/scr.png
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..d09d4b48
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,5901 @@
+{
+ "name": "@fasttrack-solutions/querybuilder",
+ "version": "1.2.6",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/parser": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz",
+ "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==",
+ "dev": true
+ },
+ "@interactjs/actions": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/actions/-/actions-1.4.10.tgz",
+ "integrity": "sha512-4FRftli1hNvqLHyFMdWZYccpkjU4+rw/yM8KYcac/np7l9f5oQ7lRmnX8e2oH+uz62hEubHu/VLJwasr/TwA6Q==",
+ "dev": true
+ },
+ "@interactjs/auto-scroll": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/auto-scroll/-/auto-scroll-1.4.10.tgz",
+ "integrity": "sha512-HrVQLHs6+RP0rXgMYPq4hqhOik5SiDQ+tGxljLU5TgMZk7DzulyASSzJLBrZNtO+Icw+wdjTo+qwPSwng97+7Q==",
+ "dev": true
+ },
+ "@interactjs/auto-start": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/auto-start/-/auto-start-1.4.10.tgz",
+ "integrity": "sha512-cQgNpc7rzjS6HTS1b8ch+4d95q1O6sGGbt5pCH7BCnnAH+wTQCyGNyoytzHrOfmkRSxHPgkVEDqhDc3M4UGFrw==",
+ "dev": true
+ },
+ "@interactjs/core": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/core/-/core-1.4.10.tgz",
+ "integrity": "sha512-DV0NfxWwcBQybzpuRU7j+byIps3V+SUdwwJCS5HKM4GLgcMAeht4ZxiymjemXv+qxWWrsMKwPmDS7/kKKRtTLQ==",
+ "dev": true
+ },
+ "@interactjs/dev-tools": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/dev-tools/-/dev-tools-1.4.10.tgz",
+ "integrity": "sha512-BDTS6z/XYVZbZ53o9jltOH6PTN7BI2/9XyRcc21Bez0JNTF3eh98G6o7Cqr/AXDjwFn71YlPKeWD2eVhLrFebQ==",
+ "dev": true,
+ "requires": {
+ "@interactjs/utils": "1.4.10"
+ }
+ },
+ "@interactjs/inertia": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/inertia/-/inertia-1.4.10.tgz",
+ "integrity": "sha512-DJy6qRYa5YedL10pZTjU+ZjFY10ffhezBrD1iCusv8tSiK3UWS0ztGs1e7u9Fsp7sM/5ZKbIaIZVK1zW+NdKVw==",
+ "dev": true
+ },
+ "@interactjs/interact": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/interact/-/interact-1.4.10.tgz",
+ "integrity": "sha512-+ycYqX9laP+CaklcNaBN8NC1S6L88+nQwZ9X2AXG3J7U+0yhwIefglrIEHN8bzlZlZgvWYvxNt/rk0sdRv5kFQ==",
+ "dev": true
+ },
+ "@interactjs/modifiers": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/modifiers/-/modifiers-1.4.10.tgz",
+ "integrity": "sha512-ElsUqngDp+FRtzxEaNdCtWo8ukoiZ3LW3NUO7zRs2VFulUCYN6W/pSPozHtQ2n5WnNr6CMUrBT4mdsSim/HhHA==",
+ "dev": true
+ },
+ "@interactjs/pointer-events": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/pointer-events/-/pointer-events-1.4.10.tgz",
+ "integrity": "sha512-A1kZcBQfsqTARFBJRqEiJ9ZdZLmMwmd6lGFQ63Z9eyrBO5B8Su4W5GM1uufACyJ8piD4QFScrSnyft1LkOMQ0Q==",
+ "dev": true
+ },
+ "@interactjs/reflow": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/reflow/-/reflow-1.4.10.tgz",
+ "integrity": "sha512-bko+bhGm4KI3TRUqD0a7AUR9jqQduZThdKbl4k7rRADd0mKga0ZvssYgB3aYU2W7hDtPlc4hHgvD7kJuRqOv4g==",
+ "dev": true
+ },
+ "@interactjs/types": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/types/-/types-1.4.10.tgz",
+ "integrity": "sha512-RnyVh9TiHXmCiDGEOIpbcpDTdbH2ffHvlMcuniBCphtB+xyZMrdyA+4WZLg6TtAos8kt9K9wwMRfam6wMxe+Dw==",
+ "dev": true,
+ "requires": {
+ "@interactjs/actions": "1.4.10",
+ "@interactjs/auto-scroll": "1.4.10",
+ "@interactjs/auto-start": "1.4.10",
+ "@interactjs/core": "1.4.10",
+ "@interactjs/dev-tools": "1.4.10",
+ "@interactjs/inertia": "1.4.10",
+ "@interactjs/interact": "1.4.10",
+ "@interactjs/modifiers": "1.4.10",
+ "@interactjs/pointer-events": "1.4.10",
+ "@interactjs/reflow": "1.4.10",
+ "@interactjs/utils": "1.4.10"
+ }
+ },
+ "@interactjs/utils": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@interactjs/utils/-/utils-1.4.10.tgz",
+ "integrity": "sha512-PPqC5BdfZdH6qXXCNvzqCytYzKpvAxzYCoNXGx3nQMsV6tWrfI6qF/pKQ8qt99kSSceGwJp3kQIS28kIy3ghEg==",
+ "dev": true
+ },
+ "JSV": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz",
+ "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "acorn": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz",
+ "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+ "dev": true,
+ "requires": {
+ "acorn": "^3.0.4"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+ "dev": true
+ }
+ }
+ },
+ "ajv": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
+ "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+ "dev": true
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "ansicolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz",
+ "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ }
+ }
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "async-foreach": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "awesome-bootstrap-checkbox": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-0.3.7.tgz",
+ "integrity": "sha1-sRKXPubVv/QKshfEIBhcRwJR0OI=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+ "dev": true
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "blanket": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/blanket/-/blanket-1.2.3.tgz",
+ "integrity": "sha1-FRtJh8O9hFUrtfA7kO9fflkx5HM=",
+ "dev": true,
+ "requires": {
+ "acorn": "^1.0.3",
+ "falafel": "~1.2.0",
+ "foreach": "^2.0.5",
+ "isarray": "0.0.1",
+ "object-keys": "^1.0.6",
+ "xtend": "~4.0.0"
+ }
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.0"
+ }
+ },
+ "bluebird": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
+ "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
+ "dev": true
+ },
+ "body": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
+ "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=",
+ "dev": true,
+ "requires": {
+ "continuable-cache": "^0.3.1",
+ "error": "^7.0.0",
+ "raw-body": "~1.1.0",
+ "safe-json-parse": "~1.0.1"
+ }
+ },
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "bootbox": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/bootbox/-/bootbox-4.4.0.tgz",
+ "integrity": "sha1-/3+Jj7h9RSflR/62QVj4hFDRoMk=",
+ "dev": true
+ },
+ "bootstrap": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
+ "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA=="
+ },
+ "bootstrap-select": {
+ "version": "1.13.10",
+ "resolved": "https://registry.npmjs.org/bootstrap-select/-/bootstrap-select-1.13.10.tgz",
+ "integrity": "sha512-mwfyd+VWHY8wDN4je4Y8PPEaOAzDPUz95z5F5zxzlIqebqxtbrujclFWLrhkVOyETpsgZCL1rsfyEnHpAugtGg==",
+ "dev": true
+ },
+ "bootstrap-slider": {
+ "version": "10.6.1",
+ "resolved": "https://registry.npmjs.org/bootstrap-slider/-/bootstrap-slider-10.6.1.tgz",
+ "integrity": "sha512-lA6SwGr33YcKHtpt0lYjwspc4RCgM2bdrFdHU1U77Lal6gZGjVF/Ii9/Mff0b1dyZ4RvSAzaOlSsuY1d5wCtdA==",
+ "dev": true
+ },
+ "bootswatch-dist": {
+ "version": "git+https://github.com/dbtek/bootswatch-dist.git#f55986534babf801f99fde84e7144ca7a584263b",
+ "from": "git+https://github.com/dbtek/bootswatch-dist.git#slate",
+ "dev": true
+ },
+ "bower-config": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-1.4.1.tgz",
+ "integrity": "sha1-hf2d82fCuNu9DKpMXyutQM2Ewsw=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.3",
+ "mout": "^1.0.0",
+ "optimist": "^0.6.1",
+ "osenv": "^0.1.3",
+ "untildify": "^2.1.0"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "bytes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+ "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=",
+ "dev": true
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "^0.2.0"
+ }
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ }
+ },
+ "cardinal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz",
+ "integrity": "sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=",
+ "dev": true,
+ "requires": {
+ "ansicolors": "~0.2.1",
+ "redeyed": "~1.0.0"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "catharsis": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.10.tgz",
+ "integrity": "sha512-l2OUaz/3PU3MZylspVFJvwHCVfWyvcduPq4lv3AzZ2pJzZCo7kNKFNyatwujD7XgvGkNAE/Jhhbh2uARNwNkfw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "cheerio": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
+ "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=",
+ "dev": true,
+ "requires": {
+ "css-select": "~1.2.0",
+ "dom-serializer": "~0.1.0",
+ "entities": "~1.1.1",
+ "htmlparser2": "^3.9.1",
+ "lodash.assignin": "^4.0.9",
+ "lodash.bind": "^4.1.4",
+ "lodash.defaults": "^4.0.1",
+ "lodash.filter": "^4.4.0",
+ "lodash.flatten": "^4.2.0",
+ "lodash.foreach": "^4.3.0",
+ "lodash.map": "^4.4.0",
+ "lodash.merge": "^4.4.0",
+ "lodash.pick": "^4.2.1",
+ "lodash.reduce": "^4.4.0",
+ "lodash.reject": "^4.4.0",
+ "lodash.some": "^4.4.0"
+ }
+ },
+ "chosenjs": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/chosenjs/-/chosenjs-1.4.3.tgz",
+ "integrity": "sha1-fhcc+UQ5ILhjgYTEdGA1zAuNTCE=",
+ "dev": true,
+ "requires": {
+ "jquery": ">=1.4.4"
+ }
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "clean-css": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz",
+ "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.x"
+ }
+ },
+ "cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "dev": true,
+ "requires": {
+ "exit": "0.1.2",
+ "glob": "^7.1.1"
+ }
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^1.0.1"
+ }
+ },
+ "cli-table": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
+ "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
+ "dev": true,
+ "requires": {
+ "colors": "1.0.3"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+ "dev": true
+ }
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "coffeescript": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
+ "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+ "dev": true
+ },
+ "comment-parser": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.3.2.tgz",
+ "integrity": "sha1-PAPwd2uGo239mgosl8YwfzMggv4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.4"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ }
+ },
+ "connect-livereload": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz",
+ "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true
+ },
+ "continuable-cache": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
+ "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
+ "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "coveralls": {
+ "version": "2.13.3",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.3.tgz",
+ "integrity": "sha512-iiAmn+l1XqRwNLXhW8Rs5qHZRFMYp9ZIPjEOVRpC/c4so6Y/f4/lFi0FfR5B9cCqgyhkJ5cZmbvcVRfP8MHchw==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "3.6.1",
+ "lcov-parse": "0.0.10",
+ "log-driver": "1.2.5",
+ "minimist": "1.2.0",
+ "request": "2.79.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "commander": "^2.9.0",
+ "is-my-json-valid": "^2.12.4",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "js-yaml": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz",
+ "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^2.6.0"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "caseless": "~0.11.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.1.1",
+ "har-validator": "~2.0.6",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "oauth-sign": "~0.8.1",
+ "qs": "~6.3.0",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "~0.4.1",
+ "uuid": "^3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "dev": true,
+ "requires": {
+ "punycode": "^1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ }
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x"
+ }
+ },
+ "css-select": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+ "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+ "dev": true,
+ "requires": {
+ "boolbase": "~1.0.0",
+ "css-what": "2.1",
+ "domutils": "1.5.1",
+ "nth-check": "~1.0.1"
+ }
+ },
+ "css-what": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+ "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+ "dev": true
+ },
+ "cst": {
+ "version": "0.4.10",
+ "resolved": "https://registry.npmjs.org/cst/-/cst-0.4.10.tgz",
+ "integrity": "sha512-U5ETe1IOjq2h56ZcBE3oe9rT7XryCH6IKgPMv0L7sSk6w29yR3p5egCK0T3BDNHHV95OoUBgXsqiVG+3a900Ag==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.9.2",
+ "babylon": "^6.8.1",
+ "source-map-support": "^0.4.0"
+ }
+ },
+ "csv-parse": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-2.5.0.tgz",
+ "integrity": "sha512-4OcjOJQByI0YDU5COYw9HAqjo8/MOLLmT9EKyMCXUzgvh30vS1SlMK+Ho84IH5exN44cSnrYecw/7Zpu2m4lkA==",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "cycle": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+ "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.9"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+ "dev": true
+ },
+ "date-time": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
+ "integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=",
+ "dev": true,
+ "requires": {
+ "time-zone": "^0.1.0"
+ }
+ },
+ "dateformat": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.3.0"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "deep-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+ "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "dom-serializer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+ "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.0",
+ "entities": "^1.1.1"
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "dot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/dot/-/dot-1.1.2.tgz",
+ "integrity": "sha1-xzdwGfxOVQeYkosrmv62ar+h8vk="
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
+ "each-async": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz",
+ "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=",
+ "dev": true,
+ "requires": {
+ "onetime": "^1.0.0",
+ "set-immediate-shim": "^1.0.0"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "error": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
+ "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=",
+ "dev": true,
+ "requires": {
+ "string-template": "~0.2.1",
+ "xtend": "~4.0.0"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.50",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz",
+ "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.1",
+ "next-tick": "^1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-promise": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
+ "dev": true
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+ "dev": true,
+ "requires": {
+ "es6-map": "^0.1.3",
+ "es6-weak-map": "^2.0.1",
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz",
+ "integrity": "sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "concat-stream": "^1.4.6",
+ "debug": "^2.1.1",
+ "doctrine": "^1.2.2",
+ "es6-map": "^0.1.3",
+ "escope": "^3.6.0",
+ "espree": "^3.1.6",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^1.1.1",
+ "glob": "^7.0.3",
+ "globals": "^9.2.0",
+ "ignore": "^3.1.2",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^0.12.0",
+ "is-my-json-valid": "^2.10.0",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.5.1",
+ "json-stable-stringify": "^1.0.0",
+ "levn": "^0.3.0",
+ "lodash": "^4.0.0",
+ "mkdirp": "^0.5.0",
+ "optionator": "^0.8.1",
+ "path-is-absolute": "^1.0.0",
+ "path-is-inside": "^1.0.1",
+ "pluralize": "^1.2.1",
+ "progress": "^1.1.8",
+ "require-uncached": "^1.0.2",
+ "shelljs": "^0.6.0",
+ "strip-json-comments": "~1.0.1",
+ "table": "^3.7.8",
+ "text-table": "~0.2.0",
+ "user-home": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "shelljs": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz",
+ "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "espree": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.5.0",
+ "acorn-jsx": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+ "dev": true
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "exit-hook": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extract-zip": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+ "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.2",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.1",
+ "yauzl": "2.4.1"
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "eyes": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+ "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=",
+ "dev": true
+ },
+ "falafel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz",
+ "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=",
+ "dev": true,
+ "requires": {
+ "acorn": "^1.0.3",
+ "foreach": "^2.0.5",
+ "isarray": "0.0.1",
+ "object-keys": "^1.0.6"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "faye-websocket": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "file-entry-cache": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz",
+ "integrity": "sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "file-sync-cmp": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz",
+ "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=",
+ "dev": true
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
+ "dev": true,
+ "requires": {
+ "glob": "~5.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+ "dev": true,
+ "requires": {
+ "circular-json": "^0.3.1",
+ "graceful-fs": "^4.1.2",
+ "rimraf": "~2.6.2",
+ "write": "^0.2.1"
+ }
+ },
+ "foodoc": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/foodoc/-/foodoc-0.0.9.tgz",
+ "integrity": "sha1-c4IqsBvzRG7+hs3ZfobuZJZtVj8=",
+ "dev": true,
+ "requires": {
+ "cheerio": "^0.22.0",
+ "extend": "^3.0.1",
+ "glob": "^7.1.2",
+ "grunt": "^1.0.2",
+ "grunt-contrib-clean": "^1.1.0",
+ "grunt-contrib-copy": "^1.0.0",
+ "grunt-contrib-cssmin": "^2.2.1",
+ "grunt-contrib-uglify": "^3.3.0",
+ "handlebars": "^4.0.11",
+ "handlebars-layouts": "^3.1.4",
+ "jsdoc": "^3.5.5",
+ "lunr": "^1.0.0",
+ "moment": "^2.22.1",
+ "sanitize-html": "^1.18.2"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "front-matter": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz",
+ "integrity": "sha1-91mDufL0E75ljJPf172M5AePXNs=",
+ "dev": true,
+ "requires": {
+ "js-yaml": "^3.4.6"
+ }
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0"
+ },
+ "dependencies": {
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fstream": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "gaze": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+ "dev": true,
+ "requires": {
+ "globule": "^1.0.0"
+ }
+ },
+ "generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globule": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
+ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
+ "dev": true,
+ "requires": {
+ "glob": "~7.1.1",
+ "lodash": "~4.17.10",
+ "minimatch": "~3.0.2"
+ }
+ },
+ "gonzales-pe-sl": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz",
+ "integrity": "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=",
+ "dev": true,
+ "requires": {
+ "minimist": "1.1.x"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+ "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+ "dev": true
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+ "dev": true
+ },
+ "grunt": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz",
+ "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==",
+ "dev": true,
+ "requires": {
+ "coffeescript": "~1.10.0",
+ "dateformat": "~1.0.12",
+ "eventemitter2": "~0.4.13",
+ "exit": "~0.1.1",
+ "findup-sync": "~0.3.0",
+ "glob": "~7.0.0",
+ "grunt-cli": "~1.2.0",
+ "grunt-known-options": "~1.1.0",
+ "grunt-legacy-log": "~2.0.0",
+ "grunt-legacy-util": "~1.1.1",
+ "iconv-lite": "~0.4.13",
+ "js-yaml": "~3.13.0",
+ "minimatch": "~3.0.2",
+ "mkdirp": "~0.5.1",
+ "nopt": "~3.0.6",
+ "path-is-absolute": "~1.0.0",
+ "rimraf": "~2.6.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.2",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "grunt-cli": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
+ "dev": true,
+ "requires": {
+ "findup-sync": "~0.3.0",
+ "grunt-known-options": "~1.1.0",
+ "nopt": "~3.0.6",
+ "resolve": "~1.1.0"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-banner": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.6.0.tgz",
+ "integrity": "sha1-P4eQIdEj+linuloLb7a+QStYhaw=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-clean": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz",
+ "integrity": "sha1-Vkq/LQN4qYOhW54/MO51tzjEBjg=",
+ "dev": true,
+ "requires": {
+ "async": "^1.5.2",
+ "rimraf": "^2.5.1"
+ }
+ },
+ "grunt-contrib-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz",
+ "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "source-map": "^0.5.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-connect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz",
+ "integrity": "sha1-XPkzuRpnOGBEJzwLJERgPNmIebo=",
+ "dev": true,
+ "requires": {
+ "async": "^1.5.2",
+ "connect": "^3.4.0",
+ "connect-livereload": "^0.5.0",
+ "http2": "^3.3.4",
+ "morgan": "^1.6.1",
+ "opn": "^4.0.0",
+ "portscanner": "^1.0.0",
+ "serve-index": "^1.7.1",
+ "serve-static": "^1.10.0"
+ }
+ },
+ "grunt-contrib-copy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz",
+ "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "file-sync-cmp": "^0.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-cssmin": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-2.2.1.tgz",
+ "integrity": "sha512-IXNomhQ5ekVZbDbj/ik5YccoD9khU6LT2fDXqO1+/Txjq8cp0tQKjVS8i8EAbHOrSDkL7/UD6A7b+xj98gqh9w==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "clean-css": "~4.1.1",
+ "maxmin": "^2.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-jshint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.1.0.tgz",
+ "integrity": "sha1-Np2QmyWTxA6L55lAshNAhQx5Oaw=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "hooker": "^0.2.3",
+ "jshint": "~2.9.4"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-qunit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-2.0.0.tgz",
+ "integrity": "sha1-VKUbSyyE/uYsO34AFFySjR7Ct+w=",
+ "dev": true,
+ "requires": {
+ "grunt-lib-phantomjs": "^1.0.0"
+ }
+ },
+ "grunt-contrib-uglify": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.4.0.tgz",
+ "integrity": "sha512-UXsTpeP0pytpTYlmll3RDndsRXfdwmrf1tI/AtD/PrArQAzGmKMvj83aVt3D8egWlE6KqPjsJBLCCvfC52LI/A==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "maxmin": "^2.1.0",
+ "uglify-js": "~3.4.0",
+ "uri-path": "^1.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-watch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz",
+ "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.0",
+ "gaze": "^1.1.0",
+ "lodash": "^4.17.10",
+ "tiny-lr": "^1.1.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+ "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ }
+ }
+ },
+ "grunt-coveralls": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-coveralls/-/grunt-coveralls-1.0.1.tgz",
+ "integrity": "sha1-LwxvA8wfJ/o5ior13XuPR0+DXY0=",
+ "dev": true,
+ "requires": {
+ "coveralls": "^2.11.1"
+ }
+ },
+ "grunt-injector": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-injector/-/grunt-injector-1.1.0.tgz",
+ "integrity": "sha1-WmERPch5OT10cXh0ccbpmFj4XR0=",
+ "dev": true,
+ "requires": {
+ "lodash": "~4.15.0",
+ "wiredep": "~4.0.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.15.0",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.15.0.tgz",
+ "integrity": "sha1-MWI5HY8BQKoiz49rPDTWt/Y9Oqk=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-jscs": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-jscs/-/grunt-jscs-3.0.1.tgz",
+ "integrity": "sha1-H65Q4+lV3546nZQlrsIqzK4AgJI=",
+ "dev": true,
+ "requires": {
+ "hooker": "~0.2.3",
+ "jscs": "~3.0.5",
+ "lodash": "~4.6.1",
+ "vow": "~0.4.1"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.6.1.tgz",
+ "integrity": "sha1-3wDBFkrSNrGDz8OIel6NOMxjy7w=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-jsdoc": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.4.0.tgz",
+ "integrity": "sha512-JpZd1W7HbK0sHbpiL9+VyDFwZlkYoDQMaP+v6z1R23W/NYLoqJM76L9eBOr7O6NycqtddRHN5DzlSkW45MJ82w==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.5",
+ "jsdoc": "~3.6.0"
+ }
+ },
+ "grunt-known-options": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
+ "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==",
+ "dev": true
+ },
+ "grunt-legacy-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
+ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
+ "dev": true,
+ "requires": {
+ "colors": "~1.1.2",
+ "grunt-legacy-log-utils": "~2.0.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.5"
+ }
+ },
+ "grunt-legacy-log-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
+ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "~2.4.1",
+ "lodash": "~4.17.10"
+ }
+ },
+ "grunt-legacy-util": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
+ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
+ "dev": true,
+ "requires": {
+ "async": "~1.5.2",
+ "exit": "~0.1.1",
+ "getobject": "~0.1.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.10",
+ "underscore.string": "~3.3.4",
+ "which": "~1.3.0"
+ }
+ },
+ "grunt-lib-phantomjs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz",
+ "integrity": "sha1-np7c3Z/S3UDgwYHJQ3HVcqpe6tI=",
+ "dev": true,
+ "requires": {
+ "eventemitter2": "^0.4.9",
+ "phantomjs-prebuilt": "^2.1.3",
+ "rimraf": "^2.5.2",
+ "semver": "^5.1.0",
+ "temporary": "^0.0.8"
+ }
+ },
+ "grunt-open": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/grunt-open/-/grunt-open-0.2.4.tgz",
+ "integrity": "sha512-3VxPWr6zZBVvEPtCMkjVtP30saT/VDIeUE8nWs8Y2tNgUPROKwWoWFwo1AUTNRM5oufJ2PL1eMVaL7Byv4NhQg==",
+ "dev": true,
+ "requires": {
+ "opn": "^5.4.0"
+ },
+ "dependencies": {
+ "opn": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+ "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ }
+ }
+ },
+ "grunt-qunit-blanket-lcov": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-qunit-blanket-lcov/-/grunt-qunit-blanket-lcov-1.0.0.tgz",
+ "integrity": "sha1-bzGA5sOyGdWoaTFQz4Q8Q/Ycu4M=",
+ "dev": true
+ },
+ "grunt-sass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-sass/-/grunt-sass-2.1.0.tgz",
+ "integrity": "sha512-XkexnQt/9rhReNd+Y7T0n/2g5FqYOQKfi2iSlpwDqvgs7EgEaGTxNhnWzHnbW5oNRvzL9AHopBG3AgRxL0d+DA==",
+ "dev": true,
+ "requires": {
+ "each-async": "^1.0.0",
+ "node-sass": "^4.7.2",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "grunt-sass-injection": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/grunt-sass-injection/-/grunt-sass-injection-1.0.3.tgz",
+ "integrity": "sha1-9VYdLpGxoqwtoF/rub8o/X/6moo=",
+ "dev": true
+ },
+ "grunt-sass-lint": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/grunt-sass-lint/-/grunt-sass-lint-0.2.4.tgz",
+ "integrity": "sha512-jV88yXoxFFvr4R3WVBl0uz4YBzNxXTrCJ7ZBKrYby/SjRCw2sieKPkt5tpWDcQZIj9XrKsOpKuHQn08MaECVwg==",
+ "dev": true,
+ "requires": {
+ "sass-lint": "^1.12.0"
+ }
+ },
+ "grunt-wrap": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/grunt-wrap/-/grunt-wrap-0.3.1.tgz",
+ "integrity": "sha512-S8sSNn2LYbTVutRy/N71H8OIBMk4isH74Qc8S2DE2MsOFn7MrBPpFa+B7tTDjdenaoiOWpL0ugYFtWAmST18Mg==",
+ "dev": true
+ },
+ "gzip-size": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
+ "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=",
+ "dev": true,
+ "requires": {
+ "duplexer": "^0.1.1"
+ }
+ },
+ "handlebars": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
+ "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
+ "dev": true,
+ "requires": {
+ "neo-async": "^2.6.0",
+ "optimist": "^0.6.1",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "handlebars-layouts": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/handlebars-layouts/-/handlebars-layouts-3.1.4.tgz",
+ "integrity": "sha1-JrO+uTG0uHffv35v6vQFjuYiiwI=",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "^1.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x",
+ "cryptiles": "2.x.x",
+ "hoek": "2.x.x",
+ "sntp": "1.x.x"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ }
+ },
+ "http-parser-js": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
+ "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "http2": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.7.tgz",
+ "integrity": "sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==",
+ "dev": true
+ },
+ "humanize": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/humanize/-/humanize-0.0.9.tgz",
+ "integrity": "sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ=",
+ "dev": true
+ },
+ "i": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
+ "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "in-publish": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+ "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherit": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/inherit/-/inherit-2.2.7.tgz",
+ "integrity": "sha512-dxJmC1j0Q32NFAjvbd6g3lXYLZ49HgzotgbSMwMkoiTXGhC9412Oc24g7A7M9cPPkw/vDsF2cSII+2zJwocUtQ==",
+ "dev": true
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^1.1.0",
+ "ansi-regex": "^2.0.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^1.0.1",
+ "cli-width": "^2.0.0",
+ "figures": "^1.3.5",
+ "lodash": "^4.3.0",
+ "readline2": "^1.0.1",
+ "run-async": "^0.1.0",
+ "rx-lite": "^3.1.2",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "interactjs": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/interactjs/-/interactjs-1.4.10.tgz",
+ "integrity": "sha512-oYWYSMwFrsvjID1Rc5uFm8lWUx1aRMTGC2ySCmSU+I3eb02WrId4T6WDOhC7iZ4vmy5/Wxz6vEIU7Y1aOF269Q==",
+ "dev": true,
+ "requires": {
+ "@interactjs/types": "1.4.10"
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz",
+ "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==",
+ "dev": true,
+ "requires": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^4.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "jit-grunt": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/jit-grunt/-/jit-grunt-0.10.0.tgz",
+ "integrity": "sha1-AIw6f+Hpa9DYTiYOofoXg0V/ecI=",
+ "dev": true
+ },
+ "jquery": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
+ "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
+ },
+ "jquery-extendext": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/jquery-extendext/-/jquery-extendext-0.1.2.tgz",
+ "integrity": "sha1-1FtUi1EtF0oqcz16wkSLkEVscVY=",
+ "requires": {
+ "jquery": ">=1.9.1"
+ }
+ },
+ "js-base64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
+ "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==",
+ "dev": true
+ },
+ "js-reporters": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz",
+ "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "js2xmlparser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz",
+ "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==",
+ "dev": true,
+ "requires": {
+ "xmlcreate": "^2.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true
+ },
+ "jscs": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/jscs/-/jscs-3.0.7.tgz",
+ "integrity": "sha1-cUG03/W4bjLQ6Z12S4NnZ8MNIBo=",
+ "dev": true,
+ "requires": {
+ "chalk": "~1.1.0",
+ "cli-table": "~0.3.1",
+ "commander": "~2.9.0",
+ "cst": "^0.4.3",
+ "estraverse": "^4.1.0",
+ "exit": "~0.1.2",
+ "glob": "^5.0.1",
+ "htmlparser2": "3.8.3",
+ "js-yaml": "~3.4.0",
+ "jscs-jsdoc": "^2.0.0",
+ "jscs-preset-wikimedia": "~1.0.0",
+ "jsonlint": "~1.6.2",
+ "lodash": "~3.10.0",
+ "minimatch": "~3.0.0",
+ "natural-compare": "~1.2.2",
+ "pathval": "~0.1.1",
+ "prompt": "~0.2.14",
+ "reserved-words": "^0.1.1",
+ "resolve": "^1.1.6",
+ "strip-bom": "^2.0.0",
+ "strip-json-comments": "~1.0.2",
+ "to-double-quotes": "^2.0.0",
+ "to-single-quotes": "^2.0.0",
+ "vow": "~0.4.8",
+ "vow-fs": "~0.3.4",
+ "xmlbuilder": "^3.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+ "dev": true,
+ "requires": {
+ "graceful-readlink": ">= 1.0.0"
+ }
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+ "dev": true
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ }
+ },
+ "js-yaml": {
+ "version": "3.4.6",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz",
+ "integrity": "sha1-a+GyP2JJ9T0pM3D9TRqqY84bTrA=",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.2",
+ "esprima": "^2.6.0",
+ "inherit": "^2.2.2"
+ }
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "jscs-jsdoc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/jscs-jsdoc/-/jscs-jsdoc-2.0.0.tgz",
+ "integrity": "sha1-9T684CmqMSW9iCkLpQ1k1FEKSHE=",
+ "dev": true,
+ "requires": {
+ "comment-parser": "^0.3.1",
+ "jsdoctypeparser": "~1.2.0"
+ }
+ },
+ "jscs-preset-wikimedia": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.1.tgz",
+ "integrity": "sha512-RWqu6IYSUlnYuCRCF0obCOHjJV0vhpLcvKbauwxmLQoZ0PiXDTWBYlfpsEfdhg7pmREAEwrARfDRz5qWD6qknA==",
+ "dev": true
+ },
+ "jsdoc": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.2.tgz",
+ "integrity": "sha512-S2vzg99C5+gb7FWlrK4TVdyzVPGGkdvpDkCEJH1JABi2PKzPeLu5/zZffcJUifgWUJqXWl41Hoc+MmuM2GukIg==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.4.4",
+ "bluebird": "^3.5.4",
+ "catharsis": "^0.8.10",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.0",
+ "klaw": "^3.0.0",
+ "markdown-it": "^8.4.2",
+ "markdown-it-anchor": "^5.0.2",
+ "marked": "^0.6.2",
+ "mkdirp": "^0.5.1",
+ "requizzle": "^0.2.2",
+ "strip-json-comments": "^3.0.1",
+ "taffydb": "2.6.2",
+ "underscore": "~1.9.1"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
+ }
+ },
+ "jsdoctypeparser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz",
+ "integrity": "sha1-597cFToRhJ/8UUEUSuhqfvDCU5I=",
+ "dev": true,
+ "requires": {
+ "lodash": "^3.7.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
+ "jshint": {
+ "version": "2.9.7",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.7.tgz",
+ "integrity": "sha512-Q8XN38hGsVQhdlM+4gd1Xl7OB1VieSuCJf+fEJjpo59JH99bVJhXRXAh26qQ15wfdd1VPMuDWNeSWoNl53T4YA==",
+ "dev": true,
+ "requires": {
+ "cli": "~1.0.0",
+ "console-browserify": "1.1.x",
+ "exit": "0.1.x",
+ "htmlparser2": "3.8.x",
+ "lodash": "~4.17.10",
+ "minimatch": "~3.0.2",
+ "shelljs": "0.3.x",
+ "strip-json-comments": "1.0.x"
+ },
+ "dependencies": {
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ }
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "dev": true
+ }
+ }
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonlint": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz",
+ "integrity": "sha512-jMVTMzP+7gU/IyC6hvKyWpUU8tmTkK5b3BPNuMI9U8Sit+YAWLlZwB6Y6YrdCxfg2kNz05p3XY3Bmm4m26Nv3A==",
+ "dev": true,
+ "requires": {
+ "JSV": "^4.0.x",
+ "nomnom": "^1.5.x"
+ }
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "known-css-properties": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz",
+ "integrity": "sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==",
+ "dev": true
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "lcov-parse": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
+ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "linkify-it": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
+ "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "livereload-js": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
+ "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "dev": true
+ },
+ "lodash.assignin": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
+ "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=",
+ "dev": true
+ },
+ "lodash.bind": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz",
+ "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=",
+ "dev": true
+ },
+ "lodash.capitalize": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
+ "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=",
+ "dev": true
+ },
+ "lodash.escaperegexp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=",
+ "dev": true
+ },
+ "lodash.filter": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
+ "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=",
+ "dev": true
+ },
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
+ "dev": true
+ },
+ "lodash.foreach": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
+ "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=",
+ "dev": true
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
+ "dev": true
+ },
+ "lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
+ "dev": true
+ },
+ "lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+ "dev": true
+ },
+ "lodash.map": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
+ "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=",
+ "dev": true
+ },
+ "lodash.merge": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
+ "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==",
+ "dev": true
+ },
+ "lodash.mergewith": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
+ "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
+ "dev": true
+ },
+ "lodash.pick": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
+ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
+ "dev": true
+ },
+ "lodash.reduce": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
+ "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=",
+ "dev": true
+ },
+ "lodash.reject": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz",
+ "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=",
+ "dev": true
+ },
+ "lodash.some": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
+ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=",
+ "dev": true
+ },
+ "log-driver": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
+ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "lunr": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-1.0.0.tgz",
+ "integrity": "sha1-XJJ2ySyRrDWpJBtQGNRnI9kuL18=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "markdown-it": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
+ "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~1.1.1",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ }
+ },
+ "markdown-it-anchor": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz",
+ "integrity": "sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A==",
+ "dev": true
+ },
+ "marked": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz",
+ "integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA==",
+ "dev": true
+ },
+ "maxmin": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz",
+ "integrity": "sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "figures": "^1.0.1",
+ "gzip-size": "^3.0.0",
+ "pretty-bytes": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
+ }
+ },
+ "merge": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
+ "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
+ "dev": true
+ },
+ "microplugin": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/microplugin/-/microplugin-0.0.3.tgz",
+ "integrity": "sha1-H8Lhu3yeGegr2Eu6kTe75xJQ2M0=",
+ "dev": true
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
+ }
+ },
+ "moment": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+ },
+ "morgan": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
+ "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
+ "dev": true,
+ "requires": {
+ "basic-auth": "~2.0.0",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "on-headers": "~1.0.1"
+ }
+ },
+ "mout": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mout/-/mout-1.1.0.tgz",
+ "integrity": "sha512-XsP0vf4As6BfqglxZqbqQ8SR6KQot2AgxvR0gG+WtUkf90vUXchMOZQtPf/Hml1rEffJupqL/tIrU6EYhsUQjw==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.2.2.tgz",
+ "integrity": "sha1-H5bWDjFBysG20FZTzg2urHY69qo=",
+ "dev": true
+ },
+ "ncp": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz",
+ "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+ "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+ "dev": true,
+ "requires": {
+ "fstream": "^1.0.0",
+ "glob": "^7.0.3",
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "^0.5.0",
+ "nopt": "2 || 3",
+ "npmlog": "0 || 1 || 2 || 3 || 4",
+ "osenv": "0",
+ "request": "^2.87.0",
+ "rimraf": "2",
+ "semver": "~5.3.0",
+ "tar": "^2.0.0",
+ "which": "1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true
+ }
+ }
+ },
+ "node-sass": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
+ "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
+ "dev": true,
+ "requires": {
+ "async-foreach": "^0.1.3",
+ "chalk": "^1.1.1",
+ "cross-spawn": "^3.0.0",
+ "gaze": "^1.0.0",
+ "get-stdin": "^4.0.1",
+ "glob": "^7.0.3",
+ "in-publish": "^2.0.0",
+ "lodash": "^4.17.11",
+ "meow": "^3.7.0",
+ "mkdirp": "^0.5.1",
+ "nan": "^2.13.2",
+ "node-gyp": "^3.8.0",
+ "npmlog": "^4.0.0",
+ "request": "^2.88.0",
+ "sass-graph": "^2.2.4",
+ "stdout-stream": "^1.4.0",
+ "true-case-path": "^1.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "which": "^1.2.9"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "node-watch": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.0.tgz",
+ "integrity": "sha512-XAgTL05z75ptd7JSVejH1a2Dm1zmXYhuDr9l230Qk6Z7/7GPcnAs/UyJJ4ggsXSvWil8iOzwQLW0zuGUvHpG8g==",
+ "dev": true
+ },
+ "nomnom": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz",
+ "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=",
+ "dev": true,
+ "requires": {
+ "chalk": "~0.4.0",
+ "underscore": "~1.6.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
+ "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+ "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "~1.0.0",
+ "has-color": "~0.1.0",
+ "strip-ansi": "~0.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+ "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=",
+ "dev": true
+ },
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+ "dev": true
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "nth-check": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+ "dev": true,
+ "requires": {
+ "boolbase": "~1.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+ "dev": true
+ },
+ "opn": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
+ "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "~0.0.1",
+ "wordwrap": "~0.0.2"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "package": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz",
+ "integrity": "sha1-0lofmeJQbcsn1nBLg9yooxLk7cw=",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-ms": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
+ "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
+ "dev": true
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "pathval": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-0.1.1.tgz",
+ "integrity": "sha1-CPkRzcqczllCiA2ngXvAtyO2bYI=",
+ "dev": true
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "^4.0.3",
+ "extract-zip": "^1.6.5",
+ "fs-extra": "^1.0.0",
+ "hasha": "^2.2.0",
+ "kew": "^0.7.0",
+ "progress": "^1.1.8",
+ "request": "^2.81.0",
+ "request-progress": "^2.0.1",
+ "which": "^1.2.10"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pkginfo": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
+ "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=",
+ "dev": true
+ },
+ "plur": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
+ "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
+ "dev": true
+ },
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+ "dev": true
+ },
+ "portscanner": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz",
+ "integrity": "sha1-sUu9olfRTDEPqcwJaCrwLUCWGAI=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2"
+ }
+ },
+ "postcss": {
+ "version": "7.0.17",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz",
+ "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
+ "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "pretty-ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
+ "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.1",
+ "parse-ms": "^1.0.0",
+ "plur": "^1.0.0"
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
+ "prompt": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz",
+ "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=",
+ "dev": true,
+ "requires": {
+ "pkginfo": "0.x.x",
+ "read": "1.0.x",
+ "revalidator": "0.1.x",
+ "utile": "0.2.x",
+ "winston": "0.8.x"
+ }
+ },
+ "propprop": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/propprop/-/propprop-0.3.1.tgz",
+ "integrity": "sha1-oEmjVouJZEAGfRXY7J8zc15XAXg=",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.1.32",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz",
+ "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
+ "qunit": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz",
+ "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==",
+ "dev": true,
+ "requires": {
+ "commander": "2.12.2",
+ "js-reporters": "1.2.1",
+ "minimatch": "3.0.4",
+ "node-watch": "0.6.0",
+ "resolve": "1.9.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+ "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
+ "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
+ "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=",
+ "dev": true,
+ "requires": {
+ "bytes": "1",
+ "string_decoder": "0.10"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+ "dev": true,
+ "requires": {
+ "mute-stream": "~0.0.4"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
+ "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "readline2": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "mute-stream": "0.0.5"
+ },
+ "dependencies": {
+ "mute-stream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
+ "dev": true
+ }
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
+ }
+ },
+ "redeyed": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz",
+ "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=",
+ "dev": true,
+ "requires": {
+ "esprima": "~3.0.0"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz",
+ "integrity": "sha1-U88kes2ncxPlUcOqLnM0LT+099k=",
+ "dev": true
+ }
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.0"
+ }
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
+ }
+ },
+ "requizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.2.tgz",
+ "integrity": "sha512-oJ6y7JcUJkblRGhMByGNcszeLgU0qDxNKFCiUZR1XyzHyVsev+Mxb1tyygxLd1ORsKee1SA5BInFdUwY64GE/A==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "reserved-words": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
+ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
+ "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+ "dev": true,
+ "requires": {
+ "exit-hook": "^1.0.0",
+ "onetime": "^1.0.0"
+ }
+ },
+ "revalidator": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz",
+ "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "run-async": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0"
+ }
+ },
+ "rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safe-json-parse": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
+ "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=",
+ "dev": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "sanitize-html": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.1.tgz",
+ "integrity": "sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "htmlparser2": "^3.10.0",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.mergewith": "^4.6.1",
+ "postcss": "^7.0.5",
+ "srcset": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "sass-graph": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+ "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.0",
+ "lodash": "^4.0.0",
+ "scss-tokenizer": "^0.2.3",
+ "yargs": "^7.0.0"
+ }
+ },
+ "sass-lint": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sass-lint/-/sass-lint-1.13.1.tgz",
+ "integrity": "sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.8.1",
+ "eslint": "^2.7.0",
+ "front-matter": "2.1.2",
+ "fs-extra": "^3.0.1",
+ "glob": "^7.0.0",
+ "globule": "^1.0.0",
+ "gonzales-pe-sl": "^4.2.3",
+ "js-yaml": "^3.5.4",
+ "known-css-properties": "^0.3.0",
+ "lodash.capitalize": "^4.1.0",
+ "lodash.kebabcase": "^4.0.0",
+ "merge": "^1.2.0",
+ "path-is-absolute": "^1.0.0",
+ "util": "^0.10.3"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
+ "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^3.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
+ "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ }
+ }
+ },
+ "scss-tokenizer": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+ "dev": true,
+ "requires": {
+ "js-base64": "^2.1.8",
+ "source-map": "^0.4.2"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
+ "selectize": {
+ "version": "0.12.6",
+ "resolved": "https://registry.npmjs.org/selectize/-/selectize-0.12.6.tgz",
+ "integrity": "sha512-bWO5A7G+I8+QXyjLfQUgh31VI4WKYagUZQxAXlDyUmDDNrFxrASV0W9hxCOl0XJ/XQ1dZEu3G9HjXV4Wj0yb6w==",
+ "dev": true,
+ "requires": {
+ "microplugin": "0.0.3",
+ "sifter": "^0.5.1"
+ }
+ },
+ "semver": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+ "dev": true
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "dev": true
+ }
+ }
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+ "dev": true
+ },
+ "sifter": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/sifter/-/sifter-0.5.3.tgz",
+ "integrity": "sha1-XmUH/owRSyso2Qtr9OW2NuYR5Is=",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.0",
+ "cardinal": "^1.0.0",
+ "csv-parse": "^2.0.0",
+ "humanize": "^0.0.9",
+ "optimist": "^0.6.1"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+ "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ }
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+ "dev": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.6"
+ }
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
+ "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ },
+ "sql-parser-mistic": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/sql-parser-mistic/-/sql-parser-mistic-1.2.3.tgz",
+ "integrity": "sha512-2jyVSr7jIgbeFnPW8JO4hTMkDP5mTxbbWX+P7GcCbCwHp+ffiJeQGBK4dDLoPZvexK2Wgy0aUBfsWgc2DPhYRg==",
+ "dev": true
+ },
+ "srcset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz",
+ "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.2",
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
+ "stdout-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+ "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "string-template": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
+ "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
+ "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
+ "dev": true,
+ "requires": {
+ "ajv": "^4.7.0",
+ "ajv-keywords": "^1.0.0",
+ "chalk": "^1.1.1",
+ "lodash": "^4.0.0",
+ "slice-ansi": "0.0.4",
+ "string-width": "^2.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
+ "tar": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+ "dev": true,
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.12",
+ "inherits": "2"
+ }
+ },
+ "temporary": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz",
+ "integrity": "sha1-oYqYHSi6jKNgJ/s8MFOMPst0CsA=",
+ "dev": true,
+ "requires": {
+ "package": ">= 1.0.0 < 1.2.0"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "time-grunt": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz",
+ "integrity": "sha1-BiIT5mDJB+hvRAVWwB6mWXtxJCA=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "date-time": "^1.1.0",
+ "figures": "^1.0.0",
+ "hooker": "^0.2.3",
+ "number-is-nan": "^1.0.0",
+ "pretty-ms": "^2.1.0",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "time-zone": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
+ "integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=",
+ "dev": true
+ },
+ "tiny-lr": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
+ "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
+ "dev": true,
+ "requires": {
+ "body": "^5.1.0",
+ "debug": "^3.1.0",
+ "faye-websocket": "~0.10.0",
+ "livereload-js": "^2.3.0",
+ "object-assign": "^4.1.0",
+ "qs": "^6.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "to-double-quotes": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-double-quotes/-/to-double-quotes-2.0.0.tgz",
+ "integrity": "sha1-qvIx1vqUiUn4GTAburRITYWI5Kc=",
+ "dev": true
+ },
+ "to-single-quotes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/to-single-quotes/-/to-single-quotes-2.0.1.tgz",
+ "integrity": "sha1-fMKRUfD18sQZRvEZ9ZMv5VQXASU=",
+ "dev": true
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "true-case-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+ "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.2"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
+ "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
+ "dev": true,
+ "requires": {
+ "commander": "~2.19.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+ "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
+ "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "^1.0.3",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "untildify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz",
+ "integrity": "sha1-F+soB5h/dpUunASF/DEdBqgmouA=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0"
+ }
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "uri-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
+ "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=",
+ "dev": true
+ },
+ "user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0"
+ }
+ },
+ "util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "utile": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz",
+ "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=",
+ "dev": true,
+ "requires": {
+ "async": "~0.2.9",
+ "deep-equal": "*",
+ "i": "0.3.x",
+ "mkdirp": "0.x.x",
+ "ncp": "0.4.x",
+ "rimraf": "2.x.x"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ }
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "vow": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/vow/-/vow-0.4.19.tgz",
+ "integrity": "sha512-S+0+CiQlbUhTNWMlJdqo/ARuXOttXdvw5ACGyh1W97NFHUdwt3Fzyaus03Kvdmo733dwnYS9AGJSDg0Zu8mNfA==",
+ "dev": true
+ },
+ "vow-fs": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.3.6.tgz",
+ "integrity": "sha1-LUxZviLivyYY3fWXq0uqkjvnIA0=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5",
+ "uuid": "^2.0.2",
+ "vow": "^0.4.7",
+ "vow-queue": "^0.4.1"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+ "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
+ "dev": true
+ }
+ }
+ },
+ "vow-queue": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.4.3.tgz",
+ "integrity": "sha512-/poAKDTFL3zYbeQg7cl4BGcfP4sGgXKrHnRFSKj97dteUFu8oyXMwIcdwu8NSx/RmPGIuYx1Bik/y5vU4H/VKw==",
+ "dev": true,
+ "requires": {
+ "vow": "^0.4.17"
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.1.tgz",
+ "integrity": "sha512-EC4YX5LEHtiB1XjaCh6++35jGaFmhT7687pySyCfPX9bB8Quw7+Fpx8gSCpkD78tPjalxuoOm8TtTz8K4dAQEg==",
+ "dev": true,
+ "requires": {
+ "http-parser-js": ">=0.4.0",
+ "safe-buffer": ">=5.1.1",
+ "websocket-extensions": ">=0.1.1"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "winston": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz",
+ "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=",
+ "dev": true,
+ "requires": {
+ "async": "0.2.x",
+ "colors": "0.6.x",
+ "cycle": "1.0.x",
+ "eyes": "0.1.x",
+ "isstream": "0.1.x",
+ "pkginfo": "0.3.x",
+ "stack-trace": "0.0.x"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ },
+ "colors": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
+ "dev": true
+ },
+ "pkginfo": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
+ "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=",
+ "dev": true
+ }
+ }
+ },
+ "wiredep": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/wiredep/-/wiredep-4.0.0.tgz",
+ "integrity": "sha1-7pVIqVBN/n6FQBpDXb7SybTqLkQ=",
+ "dev": true,
+ "requires": {
+ "bower-config": "^1.3.0",
+ "glob": "^7.0.3",
+ "lodash": "^4.6.1",
+ "propprop": "^0.3.0",
+ "through2": "^2.0.1",
+ "wiredep-cli": "^0.1.0"
+ }
+ },
+ "wiredep-cli": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/wiredep-cli/-/wiredep-cli-0.1.0.tgz",
+ "integrity": "sha1-ZCcr/KKUYfvQdEMVix4FZSb2xzk=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "minimist": "^1.1.0",
+ "wiredep": "*"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "xmlbuilder": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz",
+ "integrity": "sha1-LIaIjy1OrehQ+jjKf3Ij9yCVFuE=",
+ "dev": true,
+ "requires": {
+ "lodash": "^3.5.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "dev": true
+ }
+ }
+ },
+ "xmlcreate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz",
+ "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "~1.0.1"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index ad930ee5..a9149ee6 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,7 @@
{
- "name": "jQuery-QueryBuilder",
- "version": "2.5.0",
- "author": {
- "name": "Damien \"Mistic\" Sorel",
- "email": "contact@git.strangeplanet.fr",
- "url": "https://www.strangeplanet.fr"
- },
+ "name": "@fasttrack-solutions/querybuilder",
+ "version": "1.2.5",
+ "author": "Damien \"Mistic\" Sorel (https://www.strangeplanet.fr)",
"description": "jQuery plugin for user friendly query/filter creator",
"main": "dist/js/query-builder.js",
"dependencies": {
@@ -15,6 +11,9 @@
"jquery-extendext": ">=0.1.2",
"moment": "^2.21.0"
},
+ "publishConfig": {
+ "registry": "https://npm.pkg.github.com/"
+ },
"devDependencies": {
"awesome-bootstrap-checkbox": "^0.3.7",
"blanket": "^1.2.3",
@@ -63,7 +62,7 @@
"homepage": "https://querybuilder.js.org",
"repository": {
"type": "git",
- "url": "git://github.com/mistic100/jQuery-QueryBuilder.git"
+ "url": "git+https://github.com/fasttrack-solutions/jQuery-QueryBuilder.git"
},
"bugs": {
"url": "https://github.com/mistic100/jQuery-QueryBuilder/issues"
@@ -71,5 +70,9 @@
"scripts": {
"serve": "grunt serve",
"test": "grunt test"
+ },
+ "directories": {
+ "example": "examples",
+ "test": "tests"
}
}
diff --git a/src/core.js b/src/core.js
index 305a9e53..ada7b16e 100644
--- a/src/core.js
+++ b/src/core.js
@@ -5,977 +5,992 @@
* @private
*/
QueryBuilder.prototype.init = function(rules) {
- /**
- * When the initilization is done, just before creating the root group
- * @event afterInit
- * @memberof QueryBuilder
- */
- this.trigger('afterInit');
-
- if (rules) {
- this.setRules(rules);
- delete this.settings.rules;
- }
- else {
- this.setRoot(true);
- }
+ /**
+ * When the initilization is done, just before creating the root group
+ * @event afterInit
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterInit');
+
+ if (rules) {
+ this.setRules(rules);
+ delete this.settings.rules;
+ }
+ else {
+ this.setRoot(true);
+ }
};
/**
- * Checks the configuration of each filter
- * @param {QueryBuilder.Filter[]} filters
- * @returns {QueryBuilder.Filter[]}
- * @throws ConfigError
- */
+* Checks the configuration of each filter
+* @param {QueryBuilder.Filter[]} filters
+* @returns {QueryBuilder.Filter[]}
+* @throws ConfigError
+*/
QueryBuilder.prototype.checkFilters = function(filters) {
- var definedFilters = [];
-
- if (!filters || filters.length === 0) {
- Utils.error('Config', 'Missing filters list');
- }
-
- filters.forEach(function(filter, i) {
- if (!filter.id) {
- Utils.error('Config', 'Missing filter {0} id', i);
- }
- if (definedFilters.indexOf(filter.id) != -1) {
- Utils.error('Config', 'Filter "{0}" already defined', filter.id);
- }
- definedFilters.push(filter.id);
-
- if (!filter.type) {
- filter.type = 'string';
- }
- else if (!QueryBuilder.types[filter.type]) {
- Utils.error('Config', 'Invalid type "{0}"', filter.type);
- }
-
- if (!filter.input) {
- filter.input = QueryBuilder.types[filter.type] === 'number' ? 'number' : 'text';
- }
- else if (typeof filter.input != 'function' && QueryBuilder.inputs.indexOf(filter.input) == -1) {
- Utils.error('Config', 'Invalid input "{0}"', filter.input);
- }
-
- if (filter.operators) {
- filter.operators.forEach(function(operator) {
- if (typeof operator != 'string') {
- Utils.error('Config', 'Filter operators must be global operators types (string)');
- }
- });
- }
-
- if (!filter.field) {
- filter.field = filter.id;
- }
- if (!filter.label) {
- filter.label = filter.field;
- }
-
- if (!filter.optgroup) {
- filter.optgroup = null;
- }
- else {
- this.status.has_optgroup = true;
-
- // register optgroup if needed
- if (!this.settings.optgroups[filter.optgroup]) {
- this.settings.optgroups[filter.optgroup] = filter.optgroup;
- }
- }
-
- switch (filter.input) {
- case 'radio':
- case 'checkbox':
- if (!filter.values || filter.values.length < 1) {
- Utils.error('Config', 'Missing filter "{0}" values', filter.id);
- }
- break;
-
- case 'select':
- var cleanValues = [];
- filter.has_optgroup = false;
-
- Utils.iterateOptions(filter.values, function(value, label, optgroup) {
- cleanValues.push({
- value: value,
- label: label,
- optgroup: optgroup || null
- });
-
- if (optgroup) {
- filter.has_optgroup = true;
-
- // register optgroup if needed
- if (!this.settings.optgroups[optgroup]) {
- this.settings.optgroups[optgroup] = optgroup;
- }
- }
- }.bind(this));
-
- if (filter.has_optgroup) {
- filter.values = Utils.groupSort(cleanValues, 'optgroup');
- }
- else {
- filter.values = cleanValues;
- }
-
- if (filter.placeholder) {
- if (filter.placeholder_value === undefined) {
- filter.placeholder_value = -1;
- }
-
- filter.values.forEach(function(entry) {
- if (entry.value == filter.placeholder_value) {
- Utils.error('Config', 'Placeholder of filter "{0}" overlaps with one of its values', filter.id);
- }
- });
- }
- break;
- }
- }, this);
-
- if (this.settings.sort_filters) {
- if (typeof this.settings.sort_filters == 'function') {
- filters.sort(this.settings.sort_filters);
- }
- else {
- var self = this;
- filters.sort(function(a, b) {
- return self.translate(a.label).localeCompare(self.translate(b.label));
- });
- }
- }
-
- if (this.status.has_optgroup) {
- filters = Utils.groupSort(filters, 'optgroup');
- }
-
- return filters;
+ var definedFilters = [];
+
+ if (!filters || filters.length === 0) {
+ Utils.error('Config', 'Missing filters list');
+ }
+
+ filters.forEach(function(filter, i) {
+ if (!filter.id) {
+ Utils.error('Config', 'Missing filter {0} id', i);
+ }
+ if (definedFilters.indexOf(filter.id) != -1) {
+ Utils.error('Config', 'Filter "{0}" already defined', filter.id);
+ }
+ definedFilters.push(filter.id);
+
+ if (!filter.type) {
+ filter.type = 'string';
+ }
+ else if (!QueryBuilder.types[filter.type]) {
+ Utils.error('Config', 'Invalid type "{0}"', filter.type);
+ }
+
+ if (!filter.input) {
+ filter.input = 'text';
+ }
+ else if (typeof filter.input != 'function' && QueryBuilder.inputs.indexOf(filter.input) == -1) {
+ Utils.error('Config', 'Invalid input "{0}"', filter.input);
+ }
+
+ if (filter.operators) {
+ filter.operators.forEach(function(operator) {
+ if (typeof operator != 'string') {
+ Utils.error('Config', 'Filter operators must be global operators types (string)');
+ }
+ });
+ }
+
+ if (!filter.field) {
+ filter.field = filter.id;
+ }
+ if (!filter.label) {
+ filter.label = filter.field;
+ }
+
+ if (!filter.optgroup) {
+ filter.optgroup = null;
+ }
+ else {
+ this.status.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[filter.optgroup]) {
+ this.settings.optgroups[filter.optgroup] = filter.optgroup;
+ }
+ }
+
+ switch (filter.input) {
+ case 'radio':
+ case 'checkbox':
+ if (!filter.values || filter.values.length < 1) {
+ Utils.error('Config', 'Missing filter "{0}" values', filter.id);
+ }
+ break;
+
+ case 'select':
+ var cleanValues = [];
+ filter.has_optgroup = false;
+
+ Utils.iterateOptions(filter.values, function(value, label, optgroup) {
+ cleanValues.push({
+ value: value,
+ label: label,
+ optgroup: optgroup || null
+ });
+
+ if (optgroup) {
+ filter.has_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[optgroup]) {
+ this.settings.optgroups[optgroup] = optgroup;
+ }
+ }
+ }.bind(this));
+
+ if (filter.has_optgroup) {
+ filter.values = Utils.groupSort(cleanValues, 'optgroup');
+ }
+ else {
+ filter.values = cleanValues;
+ }
+
+ if (filter.placeholder) {
+ if (filter.placeholder_value === undefined) {
+ filter.placeholder_value = -1;
+ }
+
+ filter.values.forEach(function(entry) {
+ if (entry.value == filter.placeholder_value) {
+ Utils.error('Config', 'Placeholder of filter "{0}" overlaps with one of its values', filter.id);
+ }
+ });
+ }
+ break;
+ }
+ }, this);
+
+ if (this.settings.sort_filters) {
+ if (typeof this.settings.sort_filters == 'function') {
+ filters.sort(this.settings.sort_filters);
+ }
+ else {
+ var self = this;
+ filters.sort(function(a, b) {
+ return self.translate(a.label).localeCompare(self.translate(b.label));
+ });
+ }
+ }
+
+ if (this.status.has_optgroup) {
+ filters = Utils.groupSort(filters, 'optgroup');
+ }
+
+ return filters;
};
/**
- * Checks the configuration of each operator
- * @param {QueryBuilder.Operator[]} operators
- * @returns {QueryBuilder.Operator[]}
- * @throws ConfigError
- */
+* Checks the configuration of each operator
+* @param {QueryBuilder.Operator[]} operators
+* @returns {QueryBuilder.Operator[]}
+* @throws ConfigError
+*/
QueryBuilder.prototype.checkOperators = function(operators) {
- var definedOperators = [];
-
- operators.forEach(function(operator, i) {
- if (typeof operator == 'string') {
- if (!QueryBuilder.OPERATORS[operator]) {
- Utils.error('Config', 'Unknown operator "{0}"', operator);
- }
-
- operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator]);
- }
- else {
- if (!operator.type) {
- Utils.error('Config', 'Missing "type" for operator {0}', i);
- }
-
- if (QueryBuilder.OPERATORS[operator.type]) {
- operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator.type], operator);
- }
-
- if (operator.nb_inputs === undefined || operator.apply_to === undefined) {
- Utils.error('Config', 'Missing "nb_inputs" and/or "apply_to" for operator "{0}"', operator.type);
- }
- }
-
- if (definedOperators.indexOf(operator.type) != -1) {
- Utils.error('Config', 'Operator "{0}" already defined', operator.type);
- }
- definedOperators.push(operator.type);
-
- if (!operator.optgroup) {
- operator.optgroup = null;
- }
- else {
- this.status.has_operator_optgroup = true;
-
- // register optgroup if needed
- if (!this.settings.optgroups[operator.optgroup]) {
- this.settings.optgroups[operator.optgroup] = operator.optgroup;
- }
- }
- }, this);
-
- if (this.status.has_operator_optgroup) {
- operators = Utils.groupSort(operators, 'optgroup');
- }
-
- return operators;
+ var definedOperators = [];
+
+ operators.forEach(function(operator, i) {
+ if (typeof operator == 'string') {
+ if (!QueryBuilder.OPERATORS[operator]) {
+ Utils.error('Config', 'Unknown operator "{0}"', operator);
+ }
+
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator]);
+ }
+ else {
+ if (!operator.type) {
+ Utils.error('Config', 'Missing "type" for operator {0}', i);
+ }
+
+ if (QueryBuilder.OPERATORS[operator.type]) {
+ operators[i] = operator = $.extendext(true, 'replace', {}, QueryBuilder.OPERATORS[operator.type], operator);
+ }
+
+ if (operator.nb_inputs === undefined || operator.apply_to === undefined) {
+ Utils.error('Config', 'Missing "nb_inputs" and/or "apply_to" for operator "{0}"', operator.type);
+ }
+ }
+
+ if (definedOperators.indexOf(operator.type) != -1) {
+ Utils.error('Config', 'Operator "{0}" already defined', operator.type);
+ }
+ definedOperators.push(operator.type);
+
+ if (!operator.optgroup) {
+ operator.optgroup = null;
+ }
+ else {
+ this.status.has_operator_optgroup = true;
+
+ // register optgroup if needed
+ if (!this.settings.optgroups[operator.optgroup]) {
+ this.settings.optgroups[operator.optgroup] = operator.optgroup;
+ }
+ }
+ }, this);
+
+ if (this.status.has_operator_optgroup) {
+ operators = Utils.groupSort(operators, 'optgroup');
+ }
+
+ return operators;
};
/**
- * Adds all events listeners to the builder
- * @private
- */
+* Adds all events listeners to the builder
+* @private
+*/
QueryBuilder.prototype.bindEvents = function() {
- var self = this;
- var Selectors = QueryBuilder.selectors;
-
- // group condition change
- this.$el.on('change.queryBuilder', Selectors.group_condition, function() {
- if ($(this).is(':checked')) {
- var $group = $(this).closest(Selectors.group_container);
- self.getModel($group).condition = $(this).val();
- }
- });
-
- // rule filter change
- this.$el.on('change.queryBuilder', Selectors.rule_filter, function() {
- var $rule = $(this).closest(Selectors.rule_container);
- self.getModel($rule).filter = self.getFilterById($(this).val());
- });
-
- // rule operator change
- this.$el.on('change.queryBuilder', Selectors.rule_operator, function() {
- var $rule = $(this).closest(Selectors.rule_container);
- self.getModel($rule).operator = self.getOperatorByType($(this).val());
- });
-
- // add rule button
- this.$el.on('click.queryBuilder', Selectors.add_rule, function() {
- var $group = $(this).closest(Selectors.group_container);
- self.addRule(self.getModel($group));
- });
-
- // delete rule button
- this.$el.on('click.queryBuilder', Selectors.delete_rule, function() {
- var $rule = $(this).closest(Selectors.rule_container);
- self.deleteRule(self.getModel($rule));
- });
-
- if (this.settings.allow_groups !== 0) {
- // add group button
- this.$el.on('click.queryBuilder', Selectors.add_group, function() {
- var $group = $(this).closest(Selectors.group_container);
- self.addGroup(self.getModel($group));
- });
-
- // delete group button
- this.$el.on('click.queryBuilder', Selectors.delete_group, function() {
- var $group = $(this).closest(Selectors.group_container);
- self.deleteGroup(self.getModel($group));
- });
- }
-
- // model events
- this.model.on({
- 'drop': function(e, node) {
- node.$el.remove();
- self.refreshGroupsConditions();
- },
- 'add': function(e, parent, node, index) {
- if (index === 0) {
- node.$el.prependTo(parent.$el.find('>' + QueryBuilder.selectors.rules_list));
- }
- else {
- node.$el.insertAfter(parent.rules[index - 1].$el);
- }
- self.refreshGroupsConditions();
- },
- 'move': function(e, node, group, index) {
- node.$el.detach();
-
- if (index === 0) {
- node.$el.prependTo(group.$el.find('>' + QueryBuilder.selectors.rules_list));
- }
- else {
- node.$el.insertAfter(group.rules[index - 1].$el);
- }
- self.refreshGroupsConditions();
- },
- 'update': function(e, node, field, value, oldValue) {
- if (node instanceof Rule) {
- switch (field) {
- case 'error':
- self.updateError(node);
- break;
-
- case 'flags':
- self.applyRuleFlags(node);
- break;
-
- case 'filter':
- self.updateRuleFilter(node, oldValue);
- break;
-
- case 'operator':
- self.updateRuleOperator(node, oldValue);
- break;
-
- case 'value':
- self.updateRuleValue(node, oldValue);
- break;
- }
- }
- else {
- switch (field) {
- case 'error':
- self.updateError(node);
- break;
-
- case 'flags':
- self.applyGroupFlags(node);
- break;
-
- case 'condition':
- self.updateGroupCondition(node, oldValue);
- break;
- }
- }
- }
- });
+ var self = this;
+ var Selectors = QueryBuilder.selectors;
+
+ // group condition change
+ this.$el.on('change.queryBuilder', Selectors.group_condition, function() {
+ if ($(this).is(':checked')) {
+ var $group = $(this).closest(Selectors.group_container);
+ self.getModel($group).condition = $(this).val();
+ }
+ });
+
+ // rule filter change
+ this.$el.on('change.queryBuilder', Selectors.rule_filter, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).filter = self.getFilterById($(this).val());
+ });
+
+ // rule operator change
+ this.$el.on('change.queryBuilder', Selectors.rule_operator, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.getModel($rule).operator = self.getOperatorByType($(this).val());
+ });
+
+ // add rule button
+ this.$el.on('click.queryBuilder', Selectors.add_rule, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addRule(self.getModel($group));
+ });
+
+ // delete rule button
+ this.$el.on('click.queryBuilder', Selectors.delete_rule, function() {
+ var $rule = $(this).closest(Selectors.rule_container);
+ self.deleteRule(self.getModel($rule));
+ });
+
+ if (this.settings.allow_groups !== 0) {
+ // add group button
+ this.$el.on('click.queryBuilder', Selectors.add_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.addGroup(self.getModel($group));
+ });
+
+ // delete group button
+ this.$el.on('click.queryBuilder', Selectors.delete_group, function() {
+ var $group = $(this).closest(Selectors.group_container);
+ self.deleteGroup(self.getModel($group));
+ });
+ }
+
+ // model events
+ this.model.on({
+ 'drop': function(e, node) {
+ node.$el.remove();
+ self.refreshGroupsConditions();
+ },
+ 'add': function(e, parent, node, index) {
+ if (index === 0) {
+ node.$el.prependTo(parent.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(parent.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'move': function(e, node, group, index) {
+ node.$el.detach();
+
+ if (index === 0) {
+ node.$el.prependTo(group.$el.find('>' + QueryBuilder.selectors.rules_list));
+ }
+ else {
+ node.$el.insertAfter(group.rules[index - 1].$el);
+ }
+ self.refreshGroupsConditions();
+ },
+ 'update': function(e, node, field, value, oldValue) {
+ if (node instanceof Rule) {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyRuleFlags(node);
+ break;
+
+ case 'filter':
+ self.updateRuleFilter(node, oldValue);
+ break;
+
+ case 'operator':
+ self.updateRuleOperator(node, oldValue);
+ break;
+
+ case 'value':
+ self.updateRuleValue(node, oldValue);
+ break;
+ }
+ }
+ else {
+ switch (field) {
+ case 'error':
+ self.updateError(node);
+ break;
+
+ case 'flags':
+ self.applyGroupFlags(node);
+ break;
+
+ case 'condition':
+ self.updateGroupCondition(node, oldValue);
+ break;
+ }
+ }
+ }
+ });
};
/**
- * Creates the root group
- * @param {boolean} [addRule=true] - adds a default empty rule
- * @param {object} [data] - group custom data
- * @param {object} [flags] - flags to apply to the group
- * @returns {Group} root group
- * @fires QueryBuilder.afterAddGroup
- */
+* Creates the root group
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group} root group
+* @fires QueryBuilder.afterAddGroup
+*/
QueryBuilder.prototype.setRoot = function(addRule, data, flags) {
- addRule = (addRule === undefined || addRule === true);
+ addRule = (addRule === undefined || addRule === true);
- var group_id = this.nextGroupId();
- var $group = $(this.getGroupTemplate(group_id, 1));
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, 1));
- this.$el.append($group);
- this.model.root = new Group(null, $group);
- this.model.root.model = this.model;
+ this.$el.append($group);
+ this.model.root = new Group(null, $group);
+ this.model.root.model = this.model;
- this.model.root.data = data;
- this.model.root.flags = $.extend({}, this.settings.default_group_flags, flags);
- this.model.root.condition = this.settings.default_condition;
+ this.model.root.data = data;
+ this.model.root.flags = $.extend({}, this.settings.default_group_flags, flags);
+ this.model.root.condition = this.settings.default_condition;
- this.trigger('afterAddGroup', this.model.root);
+ this.trigger('afterAddGroup', this.model.root);
- if (addRule) {
- this.addRule(this.model.root);
- }
+ if (addRule) {
+ this.addRule(this.model.root);
+ }
- return this.model.root;
+ return this.model.root;
};
/**
- * Adds a new group
- * @param {Group} parent
- * @param {boolean} [addRule=true] - adds a default empty rule
- * @param {object} [data] - group custom data
- * @param {object} [flags] - flags to apply to the group
- * @returns {Group}
- * @fires QueryBuilder.beforeAddGroup
- * @fires QueryBuilder.afterAddGroup
- */
+* Adds a new group
+* @param {Group} parent
+* @param {boolean} [addRule=true] - adds a default empty rule
+* @param {object} [data] - group custom data
+* @param {object} [flags] - flags to apply to the group
+* @returns {Group}
+* @fires QueryBuilder.beforeAddGroup
+* @fires QueryBuilder.afterAddGroup
+*/
QueryBuilder.prototype.addGroup = function(parent, addRule, data, flags) {
- addRule = (addRule === undefined || addRule === true);
-
- var level = parent.level + 1;
-
- /**
- * Just before adding a group, can be prevented.
- * @event beforeAddGroup
- * @memberof QueryBuilder
- * @param {Group} parent
- * @param {boolean} addRule - if an empty rule will be added in the group
- * @param {int} level - nesting level of the group, 1 is the root group
- */
- var e = this.trigger('beforeAddGroup', parent, addRule, level);
- if (e.isDefaultPrevented()) {
- return null;
- }
-
- var group_id = this.nextGroupId();
- var $group = $(this.getGroupTemplate(group_id, level));
- var model = parent.addGroup($group);
-
- model.data = data;
- model.flags = $.extend({}, this.settings.default_group_flags, flags);
- model.condition = this.settings.default_condition;
-
- /**
- * Just after adding a group
- * @event afterAddGroup
- * @memberof QueryBuilder
- * @param {Group} group
- */
- this.trigger('afterAddGroup', model);
-
- /**
- * After any change in the rules
- * @event rulesChanged
- * @memberof QueryBuilder
- */
- this.trigger('rulesChanged');
-
- if (addRule) {
- this.addRule(model);
- }
-
- return model;
+ addRule = (addRule === undefined || addRule === true);
+
+ var level = parent.level + 1;
+
+ /**
+ * Just before adding a group, can be prevented.
+ * @event beforeAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ * @param {boolean} addRule - if an empty rule will be added in the group
+ * @param {int} level - nesting level of the group, 1 is the root group
+ */
+ var e = this.trigger('beforeAddGroup', parent, addRule, level);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var group_id = this.nextGroupId();
+ var $group = $(this.getGroupTemplate(group_id, level));
+ var model = parent.addGroup($group);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_group_flags, flags);
+ model.condition = this.settings.default_condition;
+
+ /**
+ * Just after adding a group
+ * @event afterAddGroup
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterAddGroup', model);
+
+ /**
+ * After any change in the rules
+ * @event rulesChanged
+ * @memberof QueryBuilder
+ */
+ this.trigger('rulesChanged');
+
+ if (addRule) {
+ this.addRule(model);
+ }
+
+ return model;
};
/**
- * Tries to delete a group. The group is not deleted if at least one rule is flagged `no_delete`.
- * @param {Group} group
- * @returns {boolean} if the group has been deleted
- * @fires QueryBuilder.beforeDeleteGroup
- * @fires QueryBuilder.afterDeleteGroup
- */
+* Tries to delete a group. The group is not deleted if at least one rule is flagged `no_delete`.
+* @param {Group} group
+* @returns {boolean} if the group has been deleted
+* @fires QueryBuilder.beforeDeleteGroup
+* @fires QueryBuilder.afterDeleteGroup
+*/
QueryBuilder.prototype.deleteGroup = function(group) {
- if (group.isRoot()) {
- return false;
- }
-
- /**
- * Just before deleting a group, can be prevented
- * @event beforeDeleteGroup
- * @memberof QueryBuilder
- * @param {Group} parent
- */
- var e = this.trigger('beforeDeleteGroup', group);
- if (e.isDefaultPrevented()) {
- return false;
- }
-
- var del = true;
-
- group.each('reverse', function(rule) {
- del &= this.deleteRule(rule);
- }, function(group) {
- del &= this.deleteGroup(group);
- }, this);
-
- if (del) {
- group.drop();
-
- /**
- * Just after deleting a group
- * @event afterDeleteGroup
- * @memberof QueryBuilder
- */
- this.trigger('afterDeleteGroup');
-
- this.trigger('rulesChanged');
- }
-
- return del;
+ if (group.isRoot()) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a group, can be prevented
+ * @event beforeDeleteGroup
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeDeleteGroup', group);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ var del = true;
+
+ group.each('reverse', function(rule) {
+ del &= this.deleteRule(rule);
+ }, function(group) {
+ del &= this.deleteGroup(group);
+ }, this);
+
+ if (del) {
+ group.drop();
+
+ /**
+ * Just after deleting a group
+ * @event afterDeleteGroup
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteGroup');
+
+ this.trigger('rulesChanged');
+ }
+
+ return del;
};
/**
- * Performs actions when a group's condition changes
- * @param {Group} group
- * @param {object} previousCondition
- * @fires QueryBuilder.afterUpdateGroupCondition
- * @private
- */
+* Performs actions when a group's condition changes
+* @param {Group} group
+* @param {object} previousCondition
+* @fires QueryBuilder.afterUpdateGroupCondition
+* @private
+*/
QueryBuilder.prototype.updateGroupCondition = function(group, previousCondition) {
- group.$el.find('>' + QueryBuilder.selectors.group_condition).each(function() {
- var $this = $(this);
- $this.prop('checked', $this.val() === group.condition);
- $this.parent().toggleClass('active', $this.val() === group.condition);
- });
-
- /**
- * After the group condition has been modified
- * @event afterUpdateGroupCondition
- * @memberof QueryBuilder
- * @param {Group} group
- * @param {object} previousCondition
- */
- this.trigger('afterUpdateGroupCondition', group, previousCondition);
-
- this.trigger('rulesChanged');
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).each(function() {
+ var $this = $(this);
+ $this.prop('checked', $this.val() === group.condition);
+ $this.parent().toggleClass('active', $this.val() === group.condition);
+ });
+
+ /**
+ * After the group condition has been modified
+ * @event afterUpdateGroupCondition
+ * @memberof QueryBuilder
+ * @param {Group} group
+ * @param {object} previousCondition
+ */
+ this.trigger('afterUpdateGroupCondition', group, previousCondition);
+
+ this.trigger('rulesChanged');
};
/**
- * Updates the visibility of conditions based on number of rules inside each group
- * @private
- */
+* Updates the visibility of conditions based on number of rules inside each group
+* @private
+*/
QueryBuilder.prototype.refreshGroupsConditions = function() {
- (function walk(group) {
- if (!group.flags || (group.flags && !group.flags.condition_readonly)) {
- group.$el.find('>' + QueryBuilder.selectors.group_condition).prop('disabled', group.rules.length <= 1)
- .parent().toggleClass('disabled', group.rules.length <= 1);
- }
-
- group.each(null, function(group) {
- walk(group);
- }, this);
- }(this.model.root));
+ (function walk(group) {
+ if (!group.flags || (group.flags && !group.flags.condition_readonly)) {
+ group.$el.find('>' + QueryBuilder.selectors.group_condition).prop('disabled', group.rules.length <= 1)
+ .parent().toggleClass('disabled', group.rules.length <= 1);
+ }
+
+ group.each(null, function(group) {
+ walk(group);
+ }, this);
+ }(this.model.root));
};
/**
- * Adds a new rule
- * @param {Group} parent
- * @param {object} [data] - rule custom data
- * @param {object} [flags] - flags to apply to the rule
- * @returns {Rule}
- * @fires QueryBuilder.beforeAddRule
- * @fires QueryBuilder.afterAddRule
- * @fires QueryBuilder.changer:getDefaultFilter
- */
+* Adds a new rule
+* @param {Group} parent
+* @param {object} [data] - rule custom data
+* @param {object} [flags] - flags to apply to the rule
+* @returns {Rule}
+* @fires QueryBuilder.beforeAddRule
+* @fires QueryBuilder.afterAddRule
+* @fires QueryBuilder.changer:getDefaultFilter
+*/
QueryBuilder.prototype.addRule = function(parent, data, flags) {
- /**
- * Just before adding a rule, can be prevented
- * @event beforeAddRule
- * @memberof QueryBuilder
- * @param {Group} parent
- */
- var e = this.trigger('beforeAddRule', parent);
- if (e.isDefaultPrevented()) {
- return null;
- }
-
- var rule_id = this.nextRuleId();
- var $rule = $(this.getRuleTemplate(rule_id));
- var model = parent.addRule($rule);
-
- model.data = data;
- model.flags = $.extend({}, this.settings.default_rule_flags, flags);
-
- /**
- * Just after adding a rule
- * @event afterAddRule
- * @memberof QueryBuilder
- * @param {Rule} rule
- */
- this.trigger('afterAddRule', model);
-
- this.trigger('rulesChanged');
-
- this.createRuleFilters(model);
-
- if (this.settings.default_filter || !this.settings.display_empty_filter) {
- /**
- * Modifies the default filter for a rule
- * @event changer:getDefaultFilter
- * @memberof QueryBuilder
- * @param {QueryBuilder.Filter} filter
- * @param {Rule} rule
- * @returns {QueryBuilder.Filter}
- */
- model.filter = this.change('getDefaultFilter',
- this.getFilterById(this.settings.default_filter || this.filters[0].id),
- model
- );
- }
-
- return model;
+ /**
+ * Just before adding a rule, can be prevented
+ * @event beforeAddRule
+ * @memberof QueryBuilder
+ * @param {Group} parent
+ */
+ var e = this.trigger('beforeAddRule', parent);
+ if (e.isDefaultPrevented()) {
+ return null;
+ }
+
+ var rule_id = this.nextRuleId();
+ var $rule = $(this.getRuleTemplate(rule_id));
+ var model = parent.addRule($rule);
+
+ model.data = data;
+ model.flags = $.extend({}, this.settings.default_rule_flags, flags);
+
+ /**
+ * Just after adding a rule
+ * @event afterAddRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterAddRule', model);
+
+ this.trigger('rulesChanged');
+
+ this.createRuleFilters(model);
+
+ if (this.settings.default_filter || !this.settings.display_empty_filter) {
+ /**
+ * Modifies the default filter for a rule
+ * @event changer:getDefaultFilter
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter} filter
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter}
+ */
+ model.filter = this.change('getDefaultFilter',
+ this.getFilterById(this.settings.default_filter || this.filters[0].id),
+ model
+ );
+ }
+
+ return model;
};
/**
- * Tries to delete a rule
- * @param {Rule} rule
- * @returns {boolean} if the rule has been deleted
- * @fires QueryBuilder.beforeDeleteRule
- * @fires QueryBuilder.afterDeleteRule
- */
+* Tries to delete a rule
+* @param {Rule} rule
+* @returns {boolean} if the rule has been deleted
+* @fires QueryBuilder.beforeDeleteRule
+* @fires QueryBuilder.afterDeleteRule
+*/
QueryBuilder.prototype.deleteRule = function(rule) {
- if (rule.flags.no_delete) {
- return false;
- }
-
- /**
- * Just before deleting a rule, can be prevented
- * @event beforeDeleteRule
- * @memberof QueryBuilder
- * @param {Rule} rule
- */
- var e = this.trigger('beforeDeleteRule', rule);
- if (e.isDefaultPrevented()) {
- return false;
- }
-
- rule.drop();
-
- /**
- * Just after deleting a rule
- * @event afterDeleteRule
- * @memberof QueryBuilder
- */
- this.trigger('afterDeleteRule');
-
- this.trigger('rulesChanged');
-
- return true;
+ if (rule.flags.no_delete) {
+ return false;
+ }
+
+ /**
+ * Just before deleting a rule, can be prevented
+ * @event beforeDeleteRule
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ var e = this.trigger('beforeDeleteRule', rule);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+
+ rule.drop();
+
+ /**
+ * Just after deleting a rule
+ * @event afterDeleteRule
+ * @memberof QueryBuilder
+ */
+ this.trigger('afterDeleteRule');
+
+ this.trigger('rulesChanged');
+
+ return true;
};
/**
- * Creates the filters for a rule
- * @param {Rule} rule
- * @fires QueryBuilder.changer:getRuleFilters
- * @fires QueryBuilder.afterCreateRuleFilters
- * @private
- */
+* Creates the filters for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.changer:getRuleFilters
+* @fires QueryBuilder.afterCreateRuleFilters
+* @private
+*/
QueryBuilder.prototype.createRuleFilters = function(rule) {
- /**
- * Modifies the list a filters available for a rule
- * @event changer:getRuleFilters
- * @memberof QueryBuilder
- * @param {QueryBuilder.Filter[]} filters
- * @param {Rule} rule
- * @returns {QueryBuilder.Filter[]}
- */
- var filters = this.change('getRuleFilters', this.filters, rule);
- var $filterSelect = $(this.getRuleFilterSelect(rule, filters));
-
- rule.$el.find(QueryBuilder.selectors.filter_container).html($filterSelect);
-
- /**
- * After creating the dropdown for filters
- * @event afterCreateRuleFilters
- * @memberof QueryBuilder
- * @param {Rule} rule
- */
- this.trigger('afterCreateRuleFilters', rule);
-
- this.applyRuleFlags(rule);
+ /**
+ * Modifies the list a filters available for a rule
+ * @event changer:getRuleFilters
+ * @memberof QueryBuilder
+ * @param {QueryBuilder.Filter[]} filters
+ * @param {Rule} rule
+ * @returns {QueryBuilder.Filter[]}
+ */
+ var filters = this.change('getRuleFilters', this.filters, rule);
+ var $filterSelect = $(this.getRuleFilterSelect(rule, filters));
+
+ rule.$el.find(QueryBuilder.selectors.filter_container).html($filterSelect);
+
+ /**
+ * After creating the dropdown for filters
+ * @event afterCreateRuleFilters
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleFilters', rule);
+
+ this.applyRuleFlags(rule);
};
/**
- * Creates the operators for a rule and init the rule operator
- * @param {Rule} rule
- * @fires QueryBuilder.afterCreateRuleOperators
- * @private
- */
+* Creates the operators for a rule and init the rule operator
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleOperators
+* @private
+*/
QueryBuilder.prototype.createRuleOperators = function(rule) {
- var $operatorContainer = rule.$el.find(QueryBuilder.selectors.operator_container).empty();
+ var $operatorContainer = rule.$el.find(QueryBuilder.selectors.operator_container).empty();
- if (!rule.filter) {
- return;
- }
+ if (!rule.filter) {
+ return;
+ }
- var operators = this.getOperators(rule.filter);
- var $operatorSelect = $(this.getRuleOperatorSelect(rule, operators));
+ var operators = this.getOperators(rule.filter);
+ var $operatorSelect = $(this.getRuleOperatorSelect(rule, operators));
- $operatorContainer.html($operatorSelect);
+ $operatorContainer.html($operatorSelect);
- // set the operator without triggering update event
- if (rule.filter.default_operator) {
- rule.__.operator = this.getOperatorByType(rule.filter.default_operator);
- }
- else {
- rule.__.operator = operators[0];
- }
+ // set the operator without triggering update event
+ if (rule.filter.default_operator) {
+ rule.__.operator = this.getOperatorByType(rule.filter.default_operator);
+ }
+ else {
+ rule.__.operator = operators[0];
+ }
- rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
- /**
- * After creating the dropdown for operators
- * @event afterCreateRuleOperators
- * @memberof QueryBuilder
- * @param {Rule} rule
- * @param {QueryBuilder.Operator[]} operators - allowed operators for this rule
- */
- this.trigger('afterCreateRuleOperators', rule, operators);
+ /**
+ * After creating the dropdown for operators
+ * @event afterCreateRuleOperators
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {QueryBuilder.Operator[]} operators - allowed operators for this rule
+ */
+ this.trigger('afterCreateRuleOperators', rule, operators);
- this.applyRuleFlags(rule);
+ this.applyRuleFlags(rule);
};
/**
- * Creates the main input for a rule
- * @param {Rule} rule
- * @fires QueryBuilder.afterCreateRuleInput
- * @private
- */
+* Creates the main input for a rule
+* @param {Rule} rule
+* @fires QueryBuilder.afterCreateRuleInput
+* @private
+*/
QueryBuilder.prototype.createRuleInput = function(rule) {
- var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container).empty();
-
- rule.__.value = undefined;
-
- if (!rule.filter || !rule.operator || rule.operator.nb_inputs === 0) {
- return;
- }
-
- var self = this;
- var $inputs = $();
- var filter = rule.filter;
-
- for (var i = 0; i < rule.operator.nb_inputs; i++) {
- var $ruleInput = $(this.getRuleInput(rule, i));
- if (i > 0) $valueContainer.append(this.settings.inputs_separator);
- $valueContainer.append($ruleInput);
- $inputs = $inputs.add($ruleInput);
- }
-
- $valueContainer.css('display', '');
-
- $inputs.on('change ' + (filter.input_event || ''), function() {
- if (!rule._updating_input) {
- rule._updating_value = true;
- rule.value = self.getRuleInputValue(rule);
- rule._updating_value = false;
- }
- });
-
- if (filter.plugin) {
- $inputs[filter.plugin](filter.plugin_config || {});
- }
-
- /**
- * After creating the input for a rule and initializing optional plugin
- * @event afterCreateRuleInput
- * @memberof QueryBuilder
- * @param {Rule} rule
- */
- this.trigger('afterCreateRuleInput', rule);
-
- if (filter.default_value !== undefined) {
- rule.value = filter.default_value;
- }
- else {
- rule._updating_value = true;
- rule.value = self.getRuleInputValue(rule);
- rule._updating_value = false;
- }
-
- this.applyRuleFlags(rule);
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container).empty();
+
+ rule.__.value = undefined;
+
+ if (!rule.filter || !rule.operator || rule.operator.nb_inputs === 0) {
+ return;
+ }
+
+ var self = this;
+ var $inputs = $();
+ var filter = rule.filter;
+
+ for (var i = 0; i < rule.operator.nb_inputs; i++) {
+ var $ruleInput = $(this.getRuleInput(rule, i));
+ if (i > 0) $valueContainer.append(this.settings.inputs_separator);
+ $valueContainer.append($ruleInput);
+ $inputs = $inputs.add($ruleInput);
+ }
+
+ $valueContainer.css('display', '');
+
+ $inputs.on('change ' + (filter.input_event || ''), function() {
+ if (!rule._updating_input) {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+ });
+
+ if (filter.plugin) {
+ $inputs[filter.plugin](filter.plugin_config || {});
+ }
+
+ /**
+ * After creating the input for a rule and initializing optional plugin
+ * @event afterCreateRuleInput
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterCreateRuleInput', rule);
+
+ if (filter.default_value !== undefined) {
+ rule.value = filter.default_value;
+ }
+ else {
+ rule._updating_value = true;
+ rule.value = self.getRuleInputValue(rule);
+ rule._updating_value = false;
+ }
+
+ this.applyRuleFlags(rule);
};
/**
- * Performs action when a rule's filter changes
- * @param {Rule} rule
- * @param {object} previousFilter
- * @fires QueryBuilder.afterUpdateRuleFilter
- * @private
- */
+* Performs action when a rule's filter changes
+* @param {Rule} rule
+* @param {object} previousFilter
+* @fires QueryBuilder.afterUpdateRuleFilter
+* @private
+*/
QueryBuilder.prototype.updateRuleFilter = function(rule, previousFilter) {
- this.createRuleOperators(rule);
- this.createRuleInput(rule);
-
- rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
-
- // clear rule data if the filter changed
- if (previousFilter && rule.filter && previousFilter.id !== rule.filter.id) {
- rule.data = undefined;
- }
-
- /**
- * After the filter has been updated and the operators and input re-created
- * @event afterUpdateRuleFilter
- * @memberof QueryBuilder
- * @param {Rule} rule
- * @param {object} previousFilter
- */
- this.trigger('afterUpdateRuleFilter', rule, previousFilter);
-
- this.trigger('rulesChanged');
+ //Reset filter
+ rule.$el.find(QueryBuilder.selectors.tooltip).hide();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", "");
+ rule.$el.find(QueryBuilder.selectors.description).hide().find("span").text("");
+
+ var tooltip = rule.filter.tooltip;
+ var description = rule.filter.description;
+
+ this.createRuleOperators(rule);
+ this.createRuleInput(rule);
+
+ rule.$el.find(QueryBuilder.selectors.rule_filter).val(rule.filter ? rule.filter.id : '-1');
+ if(tooltip) {
+ rule.$el.find(QueryBuilder.selectors.tooltip).show();
+ rule.$el.find(QueryBuilder.selectors.tooltip).attr("data-tooltip", tooltip);
+ }
+ if(description) {
+ rule.$el.find(QueryBuilder.selectors.description).show().find("span").text(description);
+ }
+
+ // clear rule data if the filter changed
+ if (previousFilter && rule.filter && previousFilter.id !== rule.filter.id) {
+ rule.data = undefined;
+ }
+
+ /**
+ * After the filter has been updated and the operators and input re-created
+ * @event afterUpdateRuleFilter
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousFilter
+ */
+ this.trigger('afterUpdateRuleFilter', rule, previousFilter);
+
+ this.trigger('rulesChanged');
};
/**
- * Performs actions when a rule's operator changes
- * @param {Rule} rule
- * @param {object} previousOperator
- * @fires QueryBuilder.afterUpdateRuleOperator
- * @private
- */
+* Performs actions when a rule's operator changes
+* @param {Rule} rule
+* @param {object} previousOperator
+* @fires QueryBuilder.afterUpdateRuleOperator
+* @private
+*/
QueryBuilder.prototype.updateRuleOperator = function(rule, previousOperator) {
- var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container);
-
- if (!rule.operator || rule.operator.nb_inputs === 0) {
- $valueContainer.hide();
-
- rule.__.value = undefined;
- }
- else {
- $valueContainer.css('display', '');
-
- if ($valueContainer.is(':empty') || !previousOperator ||
- rule.operator.nb_inputs !== previousOperator.nb_inputs ||
- rule.operator.optgroup !== previousOperator.optgroup
- ) {
- this.createRuleInput(rule);
- }
- }
-
- if (rule.operator) {
- rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
-
- // refresh value if the format changed for this operator
- rule.__.value = this.getRuleInputValue(rule);
- }
-
- /**
- * After the operator has been updated and the input optionally re-created
- * @event afterUpdateRuleOperator
- * @memberof QueryBuilder
- * @param {Rule} rule
- * @param {object} previousOperator
- */
- this.trigger('afterUpdateRuleOperator', rule, previousOperator);
-
- this.trigger('rulesChanged');
+ var $valueContainer = rule.$el.find(QueryBuilder.selectors.value_container);
+
+ if (!rule.operator || rule.operator.nb_inputs === 0) {
+ $valueContainer.hide();
+
+ rule.__.value = undefined;
+ }
+ else {
+ $valueContainer.css('display', '');
+
+ if ($valueContainer.is(':empty') || !previousOperator ||
+ rule.operator.nb_inputs !== previousOperator.nb_inputs ||
+ rule.operator.optgroup !== previousOperator.optgroup
+ ) {
+ this.createRuleInput(rule);
+ }
+ }
+
+ if (rule.operator) {
+ rule.$el.find(QueryBuilder.selectors.rule_operator).val(rule.operator.type);
+
+ // refresh value if the format changed for this operator
+ rule.__.value = this.getRuleInputValue(rule);
+ }
+
+ /**
+ * After the operator has been updated and the input optionally re-created
+ * @event afterUpdateRuleOperator
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {object} previousOperator
+ */
+ this.trigger('afterUpdateRuleOperator', rule, previousOperator);
+
+ this.trigger('rulesChanged');
};
/**
- * Performs actions when rule's value changes
- * @param {Rule} rule
- * @param {object} previousValue
- * @fires QueryBuilder.afterUpdateRuleValue
- * @private
- */
+* Performs actions when rule's value changes
+* @param {Rule} rule
+* @param {object} previousValue
+* @fires QueryBuilder.afterUpdateRuleValue
+* @private
+*/
QueryBuilder.prototype.updateRuleValue = function(rule, previousValue) {
- if (!rule._updating_value) {
- this.setRuleInputValue(rule, rule.value);
- }
-
- /**
- * After the rule value has been modified
- * @event afterUpdateRuleValue
- * @memberof QueryBuilder
- * @param {Rule} rule
- * @param {*} previousValue
- */
- this.trigger('afterUpdateRuleValue', rule, previousValue);
-
- this.trigger('rulesChanged');
+ if (!rule._updating_value) {
+ this.setRuleInputValue(rule, rule.value);
+ }
+
+ /**
+ * After the rule value has been modified
+ * @event afterUpdateRuleValue
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ * @param {*} previousValue
+ */
+ this.trigger('afterUpdateRuleValue', rule, previousValue);
+
+ this.trigger('rulesChanged');
};
/**
- * Changes a rule's properties depending on its flags
- * @param {Rule} rule
- * @fires QueryBuilder.afterApplyRuleFlags
- * @private
- */
+* Changes a rule's properties depending on its flags
+* @param {Rule} rule
+* @fires QueryBuilder.afterApplyRuleFlags
+* @private
+*/
QueryBuilder.prototype.applyRuleFlags = function(rule) {
- var flags = rule.flags;
- var Selectors = QueryBuilder.selectors;
-
- rule.$el.find(Selectors.rule_filter).prop('disabled', flags.filter_readonly);
- rule.$el.find(Selectors.rule_operator).prop('disabled', flags.operator_readonly);
- rule.$el.find(Selectors.rule_value).prop('disabled', flags.value_readonly);
-
- if (flags.no_delete) {
- rule.$el.find(Selectors.delete_rule).remove();
- }
-
- /**
- * After rule's flags has been applied
- * @event afterApplyRuleFlags
- * @memberof QueryBuilder
- * @param {Rule} rule
- */
- this.trigger('afterApplyRuleFlags', rule);
+ var flags = rule.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ rule.$el.find(Selectors.rule_filter).prop('disabled', flags.filter_readonly);
+ rule.$el.find(Selectors.rule_operator).prop('disabled', flags.operator_readonly);
+ rule.$el.find(Selectors.rule_value).prop('disabled', flags.value_readonly);
+
+ if (flags.no_delete) {
+ rule.$el.find(Selectors.delete_rule).remove();
+ }
+
+ /**
+ * After rule's flags has been applied
+ * @event afterApplyRuleFlags
+ * @memberof QueryBuilder
+ * @param {Rule} rule
+ */
+ this.trigger('afterApplyRuleFlags', rule);
};
/**
- * Changes group's properties depending on its flags
- * @param {Group} group
- * @fires QueryBuilder.afterApplyGroupFlags
- * @private
- */
+* Changes group's properties depending on its flags
+* @param {Group} group
+* @fires QueryBuilder.afterApplyGroupFlags
+* @private
+*/
QueryBuilder.prototype.applyGroupFlags = function(group) {
- var flags = group.flags;
- var Selectors = QueryBuilder.selectors;
-
- group.$el.find('>' + Selectors.group_condition).prop('disabled', flags.condition_readonly)
- .parent().toggleClass('readonly', flags.condition_readonly);
-
- if (flags.no_add_rule) {
- group.$el.find(Selectors.add_rule).remove();
- }
- if (flags.no_add_group) {
- group.$el.find(Selectors.add_group).remove();
- }
- if (flags.no_delete) {
- group.$el.find(Selectors.delete_group).remove();
- }
-
- /**
- * After group's flags has been applied
- * @event afterApplyGroupFlags
- * @memberof QueryBuilder
- * @param {Group} group
- */
- this.trigger('afterApplyGroupFlags', group);
+ var flags = group.flags;
+ var Selectors = QueryBuilder.selectors;
+
+ group.$el.find('>' + Selectors.group_condition).prop('disabled', flags.condition_readonly)
+ .parent().toggleClass('readonly', flags.condition_readonly);
+
+ if (flags.no_add_rule) {
+ group.$el.find(Selectors.add_rule).remove();
+ }
+ if (flags.no_add_group) {
+ group.$el.find(Selectors.add_group).remove();
+ }
+ if (flags.no_delete) {
+ group.$el.find(Selectors.delete_group).remove();
+ }
+
+ /**
+ * After group's flags has been applied
+ * @event afterApplyGroupFlags
+ * @memberof QueryBuilder
+ * @param {Group} group
+ */
+ this.trigger('afterApplyGroupFlags', group);
};
/**
- * Clears all errors markers
- * @param {Node} [node] default is root Group
- */
+* Clears all errors markers
+* @param {Node} [node] default is root Group
+*/
QueryBuilder.prototype.clearErrors = function(node) {
- node = node || this.model.root;
+ node = node || this.model.root;
- if (!node) {
- return;
- }
+ if (!node) {
+ return;
+ }
- node.error = null;
+ node.error = null;
- if (node instanceof Group) {
- node.each(function(rule) {
- rule.error = null;
- }, function(group) {
- this.clearErrors(group);
- }, this);
- }
+ if (node instanceof Group) {
+ node.each(function(rule) {
+ rule.error = null;
+ }, function(group) {
+ this.clearErrors(group);
+ }, this);
+ }
};
/**
- * Adds/Removes error on a Rule or Group
- * @param {Node} node
- * @fires QueryBuilder.changer:displayError
- * @private
- */
+* Adds/Removes error on a Rule or Group
+* @param {Node} node
+* @fires QueryBuilder.changer:displayError
+* @private
+*/
QueryBuilder.prototype.updateError = function(node) {
- if (this.settings.display_errors) {
- if (node.error === null) {
- node.$el.removeClass('has-error');
- }
- else {
- var errorMessage = this.translate('errors', node.error[0]);
- errorMessage = Utils.fmt(errorMessage, node.error.slice(1));
-
- /**
- * Modifies an error message before display
- * @event changer:displayError
- * @memberof QueryBuilder
- * @param {string} errorMessage - the error message (translated and formatted)
- * @param {array} error - the raw error array (error code and optional arguments)
- * @param {Node} node
- * @returns {string}
- */
- errorMessage = this.change('displayError', errorMessage, node.error, node);
-
- node.$el.addClass('has-error')
- .find(QueryBuilder.selectors.error_container).eq(0)
- .attr('title', errorMessage);
- }
- }
+ if (this.settings.display_errors) {
+ if (node.error === null) {
+ node.$el.removeClass('has-error');
+ }
+ else {
+ var errorMessage = this.translate('errors', node.error[0]);
+ errorMessage = Utils.fmt(errorMessage, node.error.slice(1));
+
+ /**
+ * Modifies an error message before display
+ * @event changer:displayError
+ * @memberof QueryBuilder
+ * @param {string} errorMessage - the error message (translated and formatted)
+ * @param {array} error - the raw error array (error code and optional arguments)
+ * @param {Node} node
+ * @returns {string}
+ */
+ errorMessage = this.change('displayError', errorMessage, node.error, node);
+
+ node.$el.addClass('has-error')
+ .find(QueryBuilder.selectors.error_container).eq(0)
+ .attr('data-tooltip', errorMessage);
+ }
+ }
};
/**
- * Triggers a validation error event
- * @param {Node} node
- * @param {string|array} error
- * @param {*} value
- * @fires QueryBuilder.validationError
- * @private
- */
+* Triggers a validation error event
+* @param {Node} node
+* @param {string|array} error
+* @param {*} value
+* @fires QueryBuilder.validationError
+* @private
+*/
QueryBuilder.prototype.triggerValidationError = function(node, error, value) {
- if (!$.isArray(error)) {
- error = [error];
- }
-
- /**
- * Fired when a validation error occurred, can be prevented
- * @event validationError
- * @memberof QueryBuilder
- * @param {Node} node
- * @param {string} error
- * @param {*} value
- */
- var e = this.trigger('validationError', node, error, value);
- if (!e.isDefaultPrevented()) {
- node.error = error;
- }
+ if (!$.isArray(error)) {
+ error = [error];
+ }
+
+ /**
+ * Fired when a validation error occurred, can be prevented
+ * @event validationError
+ * @memberof QueryBuilder
+ * @param {Node} node
+ * @param {string} error
+ * @param {*} value
+ */
+ var e = this.trigger('validationError', node, error, value);
+ if (!e.isDefaultPrevented()) {
+ node.error = error;
+ }
};
diff --git a/src/data.js b/src/data.js
index 304f8341..b5705bb8 100644
--- a/src/data.js
+++ b/src/data.js
@@ -47,6 +47,10 @@ QueryBuilder.prototype._validateValue = function(rule, value) {
value = [value];
}
+ if (operator.type === "between") {
+ value = value.toString().split(",");
+ }
+
for (var i = 0; i < operator.nb_inputs; i++) {
if (!operator.multiple && $.isArray(value[i]) && value[i].length > 1) {
result = ['operator_not_multiple', operator.type, this.translate('operators', operator.type)];
diff --git a/src/defaults.js b/src/defaults.js
index b6c5a5eb..e8248c88 100644
--- a/src/defaults.js
+++ b/src/defaults.js
@@ -5,192 +5,195 @@
* @private
*/
QueryBuilder.types = {
- 'string': 'string',
- 'integer': 'number',
- 'double': 'number',
- 'date': 'datetime',
- 'time': 'datetime',
- 'datetime': 'datetime',
- 'boolean': 'boolean'
+ 'string': 'string',
+ 'integer': 'number',
+ 'double': 'number',
+ 'date': 'datetime',
+ 'time': 'datetime',
+ 'datetime': 'datetime',
+ 'boolean': 'boolean'
};
/**
- * Allowed inputs
- * @type {string[]}
- * @readonly
- * @private
- */
+* Allowed inputs
+* @type {string[]}
+* @readonly
+* @private
+*/
QueryBuilder.inputs = [
- 'text',
- 'number',
- 'textarea',
- 'radio',
- 'checkbox',
- 'select'
+ 'text',
+ 'number',
+ 'textarea',
+ 'radio',
+ 'checkbox',
+ 'select'
];
/**
- * Runtime modifiable options with `setOptions` method
- * @type {string[]}
- * @readonly
- * @private
- */
+* Runtime modifiable options with `setOptions` method
+* @type {string[]}
+* @readonly
+* @private
+*/
QueryBuilder.modifiable_options = [
- 'display_errors',
- 'allow_groups',
- 'allow_empty',
- 'default_condition',
- 'default_filter'
+ 'display_errors',
+ 'allow_groups',
+ 'allow_empty',
+ 'default_condition',
+ 'default_filter'
];
/**
- * CSS selectors for common components
- * @type {object.}
- * @readonly
- */
+* CSS selectors for common components
+* @type {object.}
+* @readonly
+*/
QueryBuilder.selectors = {
- group_container: '.rules-group-container',
- rule_container: '.rule-container',
- filter_container: '.rule-filter-container',
- operator_container: '.rule-operator-container',
- value_container: '.rule-value-container',
- error_container: '.error-container',
- condition_container: '.rules-group-header .group-conditions',
-
- rule_header: '.rule-header',
- group_header: '.rules-group-header',
- group_actions: '.group-actions',
- rule_actions: '.rule-actions',
-
- rules_list: '.rules-group-body>.rules-list',
-
- group_condition: '.rules-group-header [name$=_cond]',
- rule_filter: '.rule-filter-container [name$=_filter]',
- rule_operator: '.rule-operator-container [name$=_operator]',
- rule_value: '.rule-value-container [name*=_value_]',
-
- add_rule: '[data-add=rule]',
- delete_rule: '[data-delete=rule]',
- add_group: '[data-add=group]',
- delete_group: '[data-delete=group]'
+ group_container: '.rules-group-container',
+ rule_container: '.rule-container',
+ filter_container: '.rule-filter-container',
+ operator_container: '.rule-operator-container',
+ value_container: '.rule-value-container',
+ error_container: '.error-container',
+ condition_container: '.rules-group-header .group-conditions',
+ tooltip: '.tooltip-container',
+ description: '.description-container',
+
+ rule_header: '.rule-header',
+ group_header: '.rules-group-header',
+ group_actions: '.group-actions',
+ rule_actions: '.rule-actions',
+
+ rules_list: '.rules-group-body>.rules-list',
+
+ group_condition: '.rules-group-header [name$=_cond]',
+ rule_filter: '.rule-filter-container [name$=_filter]',
+ rule_operator: '.rule-operator-container [name$=_operator]',
+ rule_value: '.rule-value-container [name*=_value_]',
+
+ add_rule: '[data-add=rule]',
+ delete_rule: '[data-delete=rule]',
+ add_group: '[data-add=group]',
+ delete_group: '[data-delete=group]'
};
/**
- * Template strings (see template.js)
- * @type {object.}
- * @readonly
- */
+* Template strings (see template.js)
+* @type {object.}
+* @readonly
+*/
QueryBuilder.templates = {};
/**
- * Localized strings (see i18n/)
- * @type {object.}
- * @readonly
- */
+* Localized strings (see i18n/)
+* @type {object.}
+* @readonly
+*/
QueryBuilder.regional = {};
/**
- * Default operators
- * @type {object.}
- * @readonly
- */
+* Default operators
+* @type {object.}
+* @readonly
+*/
QueryBuilder.OPERATORS = {
- equal: { type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
- not_equal: { type: 'not_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
- in: { type: 'in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
- not_in: { type: 'not_in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
- less: { type: 'less', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
- less_or_equal: { type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
- greater: { type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
- greater_or_equal: { type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
- between: { type: 'between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
- not_between: { type: 'not_between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
- begins_with: { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- not_begins_with: { type: 'not_begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- contains: { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- not_contains: { type: 'not_contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- ends_with: { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- not_ends_with: { type: 'not_ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- is_empty: { type: 'is_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
- is_not_empty: { type: 'is_not_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
- is_null: { type: 'is_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
- is_not_null: { type: 'is_not_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] }
+ equal: { type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ not_equal: { type: 'not_equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ in: { type: 'in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ not_in: { type: 'not_in', nb_inputs: 1, multiple: true, apply_to: ['string', 'number', 'datetime'] },
+ less: { type: 'less', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ less_or_equal: { type: 'less_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater: { type: 'greater', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ greater_or_equal: { type: 'greater_or_equal', nb_inputs: 1, multiple: false, apply_to: ['number', 'datetime'] },
+ between: { type: 'between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ not_between: { type: 'not_between', nb_inputs: 2, multiple: false, apply_to: ['number', 'datetime'] },
+ begins_with: { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_begins_with: { type: 'not_begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ contains: { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_contains: { type: 'not_contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ ends_with: { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ not_ends_with: { type: 'not_ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ is_empty: { type: 'is_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_not_empty: { type: 'is_not_empty', nb_inputs: 0, multiple: false, apply_to: ['string'] },
+ is_null: { type: 'is_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] },
+ is_not_null: { type: 'is_not_null', nb_inputs: 0, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean'] }
};
/**
- * Default configuration
- * @type {object}
- * @readonly
- */
+* Default configuration
+* @type {object}
+* @readonly
+*/
QueryBuilder.DEFAULTS = {
- filters: [],
- plugins: [],
-
- sort_filters: false,
- display_errors: true,
- allow_groups: -1,
- allow_empty: false,
- conditions: ['AND', 'OR'],
- default_condition: 'AND',
- inputs_separator: ' , ',
- select_placeholder: '------',
- display_empty_filter: true,
- default_filter: null,
- optgroups: {},
-
- default_rule_flags: {
- filter_readonly: false,
- operator_readonly: false,
- value_readonly: false,
- no_delete: false
- },
-
- default_group_flags: {
- condition_readonly: false,
- no_add_rule: false,
- no_add_group: false,
- no_delete: false
- },
-
- templates: {
- group: null,
- rule: null,
- filterSelect: null,
- operatorSelect: null,
- ruleValueSelect: null
- },
-
- lang_code: 'en',
- lang: {},
-
- operators: [
- 'equal',
- 'not_equal',
- 'in',
- 'not_in',
- 'less',
- 'less_or_equal',
- 'greater',
- 'greater_or_equal',
- 'between',
- 'not_between',
- 'begins_with',
- 'not_begins_with',
- 'contains',
- 'not_contains',
- 'ends_with',
- 'not_ends_with',
- 'is_empty',
- 'is_not_empty',
- 'is_null',
- 'is_not_null'
- ],
-
- icons: {
- add_group: 'glyphicon glyphicon-plus-sign',
- add_rule: 'glyphicon glyphicon-plus',
- remove_group: 'glyphicon glyphicon-remove',
- remove_rule: 'glyphicon glyphicon-remove',
- error: 'glyphicon glyphicon-warning-sign'
- }
+ filters: [],
+ plugins: [],
+
+ sort_filters: false,
+ display_errors: true,
+ allow_groups: -1,
+ allow_empty: false,
+ conditions: ['AND', 'OR'],
+ default_condition: 'AND',
+ inputs_separator: " AND ",
+ select_placeholder: '------',
+ display_empty_filter: true,
+ default_filter: null,
+ optgroups: {},
+
+ default_rule_flags: {
+ filter_readonly: false,
+ operator_readonly: false,
+ value_readonly: false,
+ no_delete: false
+ },
+
+ default_group_flags: {
+ condition_readonly: false,
+ no_add_rule: false,
+ no_add_group: false,
+ no_delete: false
+ },
+
+ templates: {
+ group: null,
+ rule: null,
+ filterSelect: null,
+ operatorSelect: null,
+ ruleValueSelect: null
+ },
+
+ lang_code: 'en',
+ lang: {},
+
+ operators: [
+ 'equal',
+ 'not_equal',
+ 'in',
+ 'not_in',
+ 'less',
+ 'less_or_equal',
+ 'greater',
+ 'greater_or_equal',
+ 'between',
+ 'not_between',
+ 'begins_with',
+ 'not_begins_with',
+ 'contains',
+ 'not_contains',
+ 'ends_with',
+ 'not_ends_with',
+ 'is_empty',
+ 'is_not_empty',
+ 'is_null',
+ 'is_not_null'
+ ],
+
+ icons: {
+ add_group: 'glyphicon glyphicon-plus-sign',
+ add_rule: 'glyphicon glyphicon-plus',
+ remove_group: 'glyphicon glyphicon-remove',
+ remove_rule: 'glyphicon glyphicon-remove',
+ error: 'glyphicon glyphicon-warning-sign',
+ tooltip: 'glyphicon glyphicon-info-sign',
+ }
};
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 15bbb139..aae2bc43 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -41,18 +41,18 @@
"radio_empty": "No value selected",
"checkbox_empty": "No value selected",
"select_empty": "No value selected",
- "string_empty": "Empty value",
+ "string_empty": "Input field cannot be blank",
"string_exceed_min_length": "Must contain at least {0} characters",
"string_exceed_max_length": "Must not contain more than {0} characters",
"string_invalid_format": "Invalid format ({0})",
"number_nan": "Not a number",
- "number_not_integer": "Not an integer",
- "number_not_double": "Not a real number",
+ "number_not_integer": "This field must contain numbers 0-9. No letters, spaces, or special characters allowed.",
+ "number_not_double": "This field must contain numbers 0-9 with decimals separated by point “.” - For Example 10 or 50.60. No letters, spaces, or special characters allowed.",
"number_exceed_min": "Must be greater than {0}",
"number_exceed_max": "Must be lower than {0}",
"number_wrong_step": "Must be a multiple of {0}",
"number_between_invalid": "Invalid values, {0} is greater than {1}",
- "datetime_empty": "Empty value",
+ "datetime_empty": "Input field cannot be blank",
"datetime_invalid": "Invalid date format ({0})",
"datetime_exceed_min": "Must be after {0}",
"datetime_exceed_max": "Must be before {0}",
diff --git a/src/public.js b/src/public.js
index 79491b96..fdbf4f67 100644
--- a/src/public.js
+++ b/src/public.js
@@ -268,7 +268,7 @@ QueryBuilder.prototype.getRules = function(options) {
type: rule.filter ? rule.filter.type : null,
input: rule.filter ? rule.filter.input : null,
operator: rule.operator ? rule.operator.type : null,
- value: value
+ value: rule.filter.type == "boolean" ? ((value == true || value == 1 || value == "1") ? "1" : "0") : value
};
if (rule.filter && rule.filter.data || rule.data) {
@@ -311,7 +311,7 @@ QueryBuilder.prototype.getRules = function(options) {
}(this.model.root));
- out.valid = valid;
+ // out.valid = valid;
/**
* Modifies the result of the {@link QueryBuilder#getRules} method
diff --git a/src/template.js b/src/template.js
index 004d4693..0a472cce 100644
--- a/src/template.js
+++ b/src/template.js
@@ -2,18 +2,18 @@ QueryBuilder.templates.group = '\
\