REJack 4 лет назад
Родитель
Сommit
8ed4788d65
60 измененных файлов с 5223 добавлено и 395 удалено
  1. 1 1
      plugins/codemirror/addon/edit/closebrackets.js
  2. 1 1
      plugins/codemirror/addon/edit/continuelist.js
  3. 7 5
      plugins/codemirror/addon/edit/matchbrackets.js
  4. 8 5
      plugins/codemirror/addon/fold/brace-fold.js
  5. 1 1
      plugins/codemirror/addon/hint/javascript-hint.js
  6. 9 7
      plugins/codemirror/addon/hint/show-hint.js
  7. 2 2
      plugins/codemirror/addon/hint/sql-hint.js
  8. 1 1
      plugins/codemirror/addon/search/match-highlighter.js
  9. 3 3
      plugins/codemirror/codemirror.js
  10. 4 4
      plugins/codemirror/keymap/vim.js
  11. 1 1
      plugins/codemirror/mode/asn.1/asn.1.js
  12. 5 5
      plugins/codemirror/mode/clike/clike.js
  13. 4 4
      plugins/codemirror/mode/css/css.js
  14. 2 2
      plugins/codemirror/mode/cypher/cypher.js
  15. 2 2
      plugins/codemirror/mode/dtd/dtd.js
  16. 7 7
      plugins/codemirror/mode/ebnf/ebnf.js
  17. 1 1
      plugins/codemirror/mode/factor/factor.js
  18. 2 2
      plugins/codemirror/mode/gas/gas.js
  19. 1 1
      plugins/codemirror/mode/haml/haml.js
  20. 1 1
      plugins/codemirror/mode/idl/idl.js
  21. 1 1
      plugins/codemirror/mode/javascript/javascript.js
  22. 11 11
      plugins/codemirror/mode/julia/julia.js
  23. 3 3
      plugins/codemirror/mode/markdown/markdown.js
  24. 1 1
      plugins/codemirror/mode/meta.js
  25. 3 3
      plugins/codemirror/mode/modelica/modelica.js
  26. 4 4
      plugins/codemirror/mode/mscgen/mscgen.js
  27. 1 1
      plugins/codemirror/mode/mumps/mumps.js
  28. 2 2
      plugins/codemirror/mode/oz/oz.js
  29. 3 3
      plugins/codemirror/mode/pegjs/pegjs.js
  30. 2 2
      plugins/codemirror/mode/perl/perl.js
  31. 2 2
      plugins/codemirror/mode/php/php.js
  32. 1 1
      plugins/codemirror/mode/pug/pug.js
  33. 1 1
      plugins/codemirror/mode/puppet/puppet.js
  34. 4 4
      plugins/codemirror/mode/rpm/rpm.js
  35. 1 1
      plugins/codemirror/mode/sass/sass.js
  36. 1 1
      plugins/codemirror/mode/scheme/scheme.js
  37. 1 1
      plugins/codemirror/mode/sieve/sieve.js
  38. 5 5
      plugins/codemirror/mode/soy/soy.js
  39. 5 5
      plugins/codemirror/mode/sql/sql.js
  40. 1 1
      plugins/codemirror/mode/stylus/stylus.js
  41. 1 1
      plugins/codemirror/mode/tiddlywiki/tiddlywiki.js
  42. 2 2
      plugins/codemirror/mode/vbscript/vbscript.js
  43. 1 1
      plugins/codemirror/mode/velocity/velocity.js
  44. 2 2
      plugins/codemirror/mode/verilog/verilog.js
  45. 1 1
      plugins/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js
  46. 4 4
      plugins/codemirror/mode/yaml/yaml.js
  47. 340 0
      plugins/datatables-searchbuilder/css/searchBuilder.bootstrap4.css
  48. 0 0
      plugins/datatables-searchbuilder/css/searchBuilder.bootstrap4.min.css
  49. 4376 0
      plugins/datatables-searchbuilder/js/dataTables.searchBuilder.js
  50. 131 0
      plugins/datatables-searchbuilder/js/dataTables.searchBuilder.min.js
  51. 51 0
      plugins/datatables-searchbuilder/js/searchBuilder.bootstrap4.js
  52. 2 0
      plugins/datatables-searchbuilder/js/searchBuilder.bootstrap4.min.js
  53. 3 3
      plugins/sweetalert2/sweetalert2.all.js
  54. 0 0
      plugins/sweetalert2/sweetalert2.all.min.js
  55. 3 3
      plugins/sweetalert2/sweetalert2.js
  56. 0 0
      plugins/sweetalert2/sweetalert2.min.js
  57. 62 88
      plugins/uplot/uPlot.cjs.js
  58. 62 88
      plugins/uplot/uPlot.esm.js
  59. 66 92
      plugins/uplot/uPlot.iife.js
  60. 0 1
      plugins/uplot/uPlot.iife.min.js

+ 1 - 1
plugins/codemirror/addon/edit/closebrackets.js

@@ -102,7 +102,7 @@
     for (var i = 0; i < ranges.length; i++) {
       var range = ranges[i]
       if (range.head == cm.getCursor()) primary = i
-      var pos = {line: range.head.line, ch: range.head.ch + dir}
+      var pos = range.head.ch || dir > 0 ? {line: range.head.line, ch: range.head.ch + dir} : {line: range.head.line - 1}
       newRanges.push({anchor: pos, head: pos})
     }
     cm.setSelections(newRanges, primary)

+ 1 - 1
plugins/codemirror/addon/edit/continuelist.js

@@ -90,7 +90,7 @@
           });
         } else {
           if (startIndent.length > nextIndent.length) return;
-          // This doesn't run if the next line immediatley indents, as it is
+          // This doesn't run if the next line immediately indents, as it is
           // not clear of the users intention (new indented item or same level)
           if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
           skipCount += 1;

+ 7 - 5
plugins/codemirror/addon/edit/matchbrackets.js

@@ -38,7 +38,7 @@
     if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
     var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
 
-    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
+    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style, config);
     if (found == null) return null;
     return {from: Pos(where.line, pos), to: found && found.pos,
             match: found && found.ch == match.charAt(0), forward: dir > 0};
@@ -67,7 +67,8 @@
       if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
       for (; pos != end; pos += dir) {
         var ch = line.charAt(pos);
-        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
+        if (re.test(ch) && (style === undefined ||
+                            (cm.getTokenTypeAt(Pos(lineNo, pos + 1)) || "") == (style || ""))) {
           var match = matching[ch];
           if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
           else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
@@ -80,11 +81,12 @@
 
   function matchBrackets(cm, autoclear, config) {
     // Disable brace matching in long lines, since it'll cause hugely slow updates
-    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
+    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000,
+      highlightNonMatching = config && config.highlightNonMatching;
     var marks = [], ranges = cm.listSelections();
     for (var i = 0; i < ranges.length; i++) {
       var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
-      if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
+      if (match && (match.match || highlightNonMatching !== false) && cm.getLine(match.from.line).length <= maxHighlightLen) {
         var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
         marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
         if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
@@ -94,7 +96,7 @@
 
     if (marks.length) {
       // Kludge to work around the IE bug from issue #1193, where text
-      // input stops going to the textare whever this fires.
+      // input stops going to the textarea whenever this fires.
       if (ie_lt8 && cm.state.focused) cm.focus();
 
       var clear = function() {

+ 8 - 5
plugins/codemirror/addon/fold/brace-fold.js

@@ -31,13 +31,16 @@ CodeMirror.registerHelper("fold", "brace", function(cm, start) {
     }
   }
 
-  var startToken = "{", endToken = "}", startCh = findOpening("{");
-  if (startCh == null) {
-    startToken = "[", endToken = "]";
-    startCh = findOpening("[");
+  var startBrace = findOpening("{"), startBracket = findOpening("[")
+  var startToken, endToken, startCh
+  if (startBrace != null && (startBracket == null || startBracket > startBrace)) {
+    startCh = startBrace; startToken = "{"; endToken = "}"
+  } else if (startBracket != null) {
+    startCh = startBracket; startToken = "["; endToken = "]"
+  } else {
+    return
   }
 
-  if (startCh == null) return;
   var count = 1, lastLine = cm.lastLine(), end, endCh;
   outer: for (var i = line; i <= lastLine; ++i) {
     var text = cm.getLine(i), pos = i == line ? startCh : 0;

+ 1 - 1
plugins/codemirror/addon/hint/javascript-hint.js

@@ -69,7 +69,7 @@
   function getCoffeeScriptToken(editor, cur) {
   // This getToken, it is for coffeescript, imitates the behavior of
   // getTokenAt method in javascript.js, that is, returning "property"
-  // type and treat "." as indepenent token.
+  // type and treat "." as independent token.
     var token = editor.getTokenAt(cur);
     if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
       token.end = token.start;

+ 9 - 7
plugins/codemirror/addon/hint/show-hint.js

@@ -61,8 +61,10 @@
     this.startPos = this.cm.getCursor("start");
     this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
 
-    var self = this;
-    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+    if (this.options.updateOnCursorActivity) {
+      var self = this;
+      cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+    }
   }
 
   var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
@@ -75,7 +77,9 @@
       if (!this.active()) return;
       this.cm.state.completionActive = null;
       this.tick = null;
-      this.cm.off("cursorActivity", this.activityFunc);
+      if (this.options.updateOnCursorActivity) {
+        this.cm.off("cursorActivity", this.activityFunc);
+      }
 
       if (this.widget && this.data) CodeMirror.signal(this.data, "close");
       if (this.widget) this.widget.close();
@@ -117,9 +121,7 @@
       if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
           pos.ch < identStart.ch || this.cm.somethingSelected() ||
           (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
-        if (this.options.closeOnCursorActivity) {
-          this.close();
-        }
+        this.close();
       } else {
         var self = this;
         this.debounce = requestAnimationFrame(function() {self.update();});
@@ -492,9 +494,9 @@
     completeSingle: true,
     alignWithWord: true,
     closeCharacters: /[\s()\[\]{};:>,]/,
-    closeOnCursorActivity: true,
     closeOnPick: true,
     closeOnUnfocus: true,
+    updateOnCursorActivity: true,
     completeOnSingleClick: true,
     container: null,
     customKeys: null,

+ 2 - 2
plugins/codemirror/addon/hint/sql-hint.js

@@ -97,7 +97,7 @@
     if (name.charAt(0) == ".") {
       name = name.substr(1);
     }
-    // replace doublicated identifierQuotes with single identifierQuotes
+    // replace duplicated identifierQuotes with single identifierQuotes
     // and remove single identifierQuotes
     var nameParts = name.split(identifierQuote+identifierQuote);
     for (var i = 0; i < nameParts.length; i++)
@@ -109,7 +109,7 @@
     var nameParts = getText(name).split(".");
     for (var i = 0; i < nameParts.length; i++)
       nameParts[i] = identifierQuote +
-        // doublicate identifierQuotes
+        // duplicate identifierQuotes
         nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
         identifierQuote;
     var escaped = nameParts.join(".");

+ 1 - 1
plugins/codemirror/addon/search/match-highlighter.js

@@ -16,7 +16,7 @@
 // highlighted only if the selected text is a word. showToken, when enabled,
 // will cause the current token to be highlighted when nothing is selected.
 // delay is used to specify how much time to wait, in milliseconds, before
-// highlighting the matches. If annotateScrollbar is enabled, the occurences
+// highlighting the matches. If annotateScrollbar is enabled, the occurrences
 // will be highlighted on the scrollbar via the matchesonscrollbar addon.
 
 (function(mod) {

+ 3 - 3
plugins/codemirror/codemirror.js

@@ -5115,7 +5115,7 @@
       (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
     setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
 
-    if (!(options && options.scroll === false) && doc.cm)
+    if (!(options && options.scroll === false) && doc.cm && doc.cm.getOption("readOnly") != "nocursor")
       { ensureCursorVisible(doc.cm); }
   }
 
@@ -8675,7 +8675,7 @@
     function moveOnce(boundToLine) {
       var next;
       if (unit == "codepoint") {
-        var ch = lineObj.text.charCodeAt(pos.ch + (unit > 0 ? 0 : -1));
+        var ch = lineObj.text.charCodeAt(pos.ch + (dir > 0 ? 0 : -1));
         if (isNaN(ch)) {
           next = null;
         } else {
@@ -9793,7 +9793,7 @@
 
   addLegacyProps(CodeMirror);
 
-  CodeMirror.version = "5.59.1";
+  CodeMirror.version = "5.59.2";
 
   return CodeMirror;
 

+ 4 - 4
plugins/codemirror/keymap/vim.js

@@ -737,7 +737,7 @@
         // TODO: Convert keymap into dictionary format for fast lookup.
       },
       // Testing hook, though it might be useful to expose the register
-      // controller anyways.
+      // controller anyway.
       getRegisterController: function() {
         return vimGlobalState.registerController;
       },
@@ -3483,7 +3483,7 @@
         },
         isComplete: function(state) {
           if (state.nextCh === '#') {
-            var token = state.lineText.match(/#(\w+)/)[1];
+            var token = state.lineText.match(/^#(\w+)/)[1];
             if (token === 'endif') {
               if (state.forward && state.depth === 0) {
                 return true;
@@ -4322,7 +4322,7 @@
         raw += ' <span style="color: #888">' + desc + '</span>';
       return raw;
     }
-    var searchPromptDesc = '(Javascript regexp)';
+    var searchPromptDesc = '(JavaScript regexp)';
     function showPrompt(cm, options) {
       var shortText = (options.prefix || '') + ' ' + (options.desc || '');
       var prompt = makePrompt(options.prefix, options.desc);
@@ -5234,7 +5234,7 @@
     * @param {Cursor} lineEnd Line to stop replacing at.
     * @param {RegExp} query Query for performing matches with.
     * @param {string} replaceWith Text to replace matches with. May contain $1,
-    *     $2, etc for replacing captured groups using Javascript replace.
+    *     $2, etc for replacing captured groups using JavaScript replace.
     * @param {function()} callback A callback for when the replace is done.
     */
     function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query,

+ 1 - 1
plugins/codemirror/mode/asn.1/asn.1.js

@@ -190,7 +190,7 @@
     " NetworkAddress BITS BMPString TimeStamp TimeTicks" +
     " TruthValue RowStatus DisplayString GeneralString" +
     " GraphicString IA5String NumericString" +
-    " PrintableString SnmpAdminAtring TeletexString" +
+    " PrintableString SnmpAdminString TeletexString" +
     " UTF8String VideotexString VisibleString StringStore" +
     " ISO646String T61String UniversalString Unsigned32" +
     " Integer32 Gauge Gauge32 Counter Counter32 Counter64"),

+ 5 - 5
plugins/codemirror/mode/clike/clike.js

@@ -350,8 +350,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
   function cpp11StringHook(stream, state) {
     stream.backUp(1);
     // Raw strings.
-    if (stream.match(/(R|u8R|uR|UR|LR)/)) {
-      var match = stream.match(/"([^\s\\()]{0,16})\(/);
+    if (stream.match(/^(?:R|u8R|uR|UR|LR)/)) {
+      var match = stream.match(/^"([^\s\\()]{0,16})\(/);
       if (!match) {
         return false;
       }
@@ -360,8 +360,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
       return tokenRawString(stream, state);
     }
     // Unicode strings/chars.
-    if (stream.match(/(u8|u|U|L)/)) {
-      if (stream.match(/["']/, /* eat */ false)) {
+    if (stream.match(/^(?:u8|u|U|L)/)) {
+      if (stream.match(/^["']/, /* eat */ false)) {
         return "string";
       }
       return false;
@@ -749,7 +749,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
                 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
                 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
                 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
-                "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
+                "gl_TextureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
                 "gl_ProjectionMatrixInverseTranspose " +
                 "gl_ModelViewProjectionMatrixInverseTranspose " +
                 "gl_TextureMatrixInverseTranspose " +

+ 4 - 4
plugins/codemirror/mode/css/css.js

@@ -78,8 +78,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
       return ret("qualifier", "qualifier");
     } else if (/[:;{}\[\]\(\)]/.test(ch)) {
       return ret(null, ch);
-    } else if (stream.match(/[\w-.]+(?=\()/)) {
-      if (/^(url(-prefix)?|domain|regexp)$/.test(stream.current().toLowerCase())) {
+    } else if (stream.match(/^[\w-.]+(?=\()/)) {
+      if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
         state.tokenize = tokenParenthesized;
       }
       return ret("variable callee", "variable");
@@ -108,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
 
   function tokenParenthesized(stream, state) {
     stream.next(); // Must be '('
-    if (!stream.match(/\s*[\"\')]/, false))
+    if (!stream.match(/^\s*[\"\')]/, false))
       state.tokenize = tokenString(")");
     else
       state.tokenize = null;
@@ -781,7 +781,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
         }
       },
       ":": function(stream) {
-        if (stream.match(/\s*\{/, false))
+        if (stream.match(/^\s*\{/, false))
           return [null, null]
         return false;
       },

+ 2 - 2
plugins/codemirror/mode/cypher/cypher.js

@@ -21,11 +21,11 @@
     var tokenBase = function(stream/*, state*/) {
       var ch = stream.next();
       if (ch ==='"') {
-        stream.match(/.*?"/);
+        stream.match(/^[^"]*"/);
         return "string";
       }
       if (ch === "'") {
-        stream.match(/.*?'/);
+        stream.match(/^[^']*'/);
         return "string";
       }
       if (/[{}\(\),\.;\[\]]/.test(ch)) {

+ 2 - 2
plugins/codemirror/mode/dtd/dtd.js

@@ -34,7 +34,7 @@ CodeMirror.defineMode("dtd", function(config) {
       state.tokenize = inBlock("meta", "?>");
       return ret("meta", ch);
     } else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
-    else if (ch == "|") return ret("keyword", "seperator");
+    else if (ch == "|") return ret("keyword", "separator");
     else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
     else if (ch.match(/[\[\]]/)) return ret("rule", ch);
     else if (ch == "\"" || ch == "'") {
@@ -112,7 +112,7 @@ CodeMirror.defineMode("dtd", function(config) {
     indent: function(state, textAfter) {
       var n = state.stack.length;
 
-      if( textAfter.match(/\]\s+|\]/) )n=n-1;
+      if( textAfter.charAt(0) === ']' )n--;
       else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
         if(textAfter.substr(0,1) === "<") {}
         else if( type == "doindent" && textAfter.length > 1 ) {}

+ 7 - 7
plugins/codemirror/mode/ebnf/ebnf.js

@@ -41,10 +41,10 @@
             state.stringType = stream.peek();
             stream.next(); // Skip quote
             state.stack.unshift(stateType._string);
-          } else if (stream.match(/^\/\*/)) { //comments starting with /*
+          } else if (stream.match('/*')) { //comments starting with /*
             state.stack.unshift(stateType.comment);
             state.commentType = commentType.slash;
-          } else if (stream.match(/^\(\*/)) { //comments starting with (*
+          } else if (stream.match('(*')) { //comments starting with (*
             state.stack.unshift(stateType.comment);
             state.commentType = commentType.parenthesis;
           }
@@ -69,10 +69,10 @@
 
         case stateType.comment:
           while (state.stack[0] === stateType.comment && !stream.eol()) {
-            if (state.commentType === commentType.slash && stream.match(/\*\//)) {
+            if (state.commentType === commentType.slash && stream.match('*/')) {
               state.stack.shift(); // Clear flag
               state.commentType = null;
-            } else if (state.commentType === commentType.parenthesis && stream.match(/\*\)/)) {
+            } else if (state.commentType === commentType.parenthesis && stream.match('*)')) {
               state.stack.shift(); // Clear flag
               state.commentType = null;
             } else {
@@ -83,7 +83,7 @@
 
         case stateType.characterClass:
           while (state.stack[0] === stateType.characterClass && !stream.eol()) {
-            if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
+            if (!(stream.match(/^[^\]\\]+/) || stream.match('.'))) {
               state.stack.shift();
             }
           }
@@ -168,10 +168,10 @@
           }
         }
 
-        if (stream.match(/^\/\//)) {
+        if (stream.match('//')) {
           stream.skipToEnd();
           return "comment";
-        } else if (stream.match(/return/)) {
+        } else if (stream.match('return')) {
           return "operator";
         } else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
           if (stream.match(/(?=[\(.])/)) {

+ 1 - 1
plugins/codemirror/mode/factor/factor.js

@@ -16,7 +16,7 @@
   "use strict";
 
   CodeMirror.defineSimpleMode("factor", {
-    // The start state contains the rules that are intially used
+    // The start state contains the rules that are initially used
     start: [
       // comments
       {regex: /#?!.*/, token: "comment"},

+ 2 - 2
plugins/codemirror/mode/gas/gas.js

@@ -302,11 +302,11 @@ CodeMirror.defineMode("gas", function(_config, parserConfig) {
       }
 
       if (ch === '{') {
-        return "braket";
+        return "bracket";
       }
 
       if (ch === '}') {
-        return "braket";
+        return "bracket";
       }
 
       if (/\d/.test(ch)) {

+ 1 - 1
plugins/codemirror/mode/haml/haml.js

@@ -72,7 +72,7 @@
         }
       }
 
-      // donot handle --> as valid ruby, make it HTML close comment instead
+      // do not handle --> as valid ruby, make it HTML close comment instead
       if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
         state.tokenize = ruby;
         return state.tokenize(stream, state);

+ 1 - 1
plugins/codemirror/mode/idl/idl.js

@@ -62,7 +62,7 @@
     'empty', 'enable_sysrtn', 'eof', 'eos', 'erase',
     'erf', 'erfc', 'erfcx', 'erode', 'errorplot',
     'errplot', 'estimator_filter', 'execute', 'exit', 'exp',
-    'expand', 'expand_path', 'expint', 'extrac', 'extract_slice',
+    'expand', 'expand_path', 'expint', 'extract', 'extract_slice',
     'f_cvf', 'f_pdf', 'factorial', 'fft', 'file_basename',
     'file_chmod', 'file_copy', 'file_delete', 'file_dirname',
     'file_expand_path', 'file_gunzip', 'file_gzip', 'file_info',

+ 1 - 1
plugins/codemirror/mode/javascript/javascript.js

@@ -624,7 +624,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
     if (type == "=>") return cont(typeexpr)
   }
   function typeprops(type) {
-    if (type == "}") return cont()
+    if (type.match(/[\}\)\]]/)) return cont()
     if (type == "," || type == ";") return cont(typeprops)
     return pass(typeprop, typeprops)
   }

+ 11 - 11
plugins/codemirror/mode/julia/julia.js

@@ -80,7 +80,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
   // tokenizers
   function tokenBase(stream, state) {
     // Handle multiline comments
-    if (stream.match(/^#=/, false)) {
+    if (stream.match('#=', false)) {
       state.tokenize = tokenComment;
       return state.tokenize(stream, state);
     }
@@ -141,10 +141,10 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
     }
 
     if (inArray(state)) {
-      if (state.lastToken == "end" && stream.match(/^:/)) {
+      if (state.lastToken == "end" && stream.match(':')) {
         return "operator";
       }
-      if (stream.match(/^end/)) {
+      if (stream.match('end')) {
         return "number";
       }
     }
@@ -201,7 +201,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
     }
 
     // Handle Chars
-    if (stream.match(/^'/)) {
+    if (stream.match('\'')) {
       state.tokenize = tokenChar;
       return state.tokenize(stream, state);
     }
@@ -263,7 +263,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
         state.scopes.push('(');
         charsAdvanced += match[1].length;
       }
-      if (currentScope(state) == '(' && stream.match(/^\)/)) {
+      if (currentScope(state) == '(' && stream.match(')')) {
         state.scopes.pop();
         charsAdvanced += 1;
         if (state.scopes.length <= state.firstParenPos) {
@@ -295,10 +295,10 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
   }
 
   function tokenAnnotation(stream, state) {
-    stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/);
-    if (stream.match(/^{/)) {
+    stream.match(/.*?(?=[,;{}()=\s]|$)/);
+    if (stream.match('{')) {
       state.nestedParameters++;
-    } else if (stream.match(/^}/) && state.nestedParameters > 0) {
+    } else if (stream.match('}') && state.nestedParameters > 0) {
       state.nestedParameters--;
     }
     if (state.nestedParameters > 0) {
@@ -310,13 +310,13 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
   }
 
   function tokenComment(stream, state) {
-    if (stream.match(/^#=/)) {
+    if (stream.match('#=')) {
       state.nestedComments++;
     }
     if (!stream.match(/.*?(?=(#=|=#))/)) {
       stream.skipToEnd();
     }
-    if (stream.match(/^=#/)) {
+    if (stream.match('=#')) {
       state.nestedComments--;
       if (state.nestedComments == 0)
         state.tokenize = tokenBase;
@@ -347,7 +347,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
       return "string";
     }
     if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
-    if (stream.match(/^'/)) { state.tokenize = tokenBase; }
+    if (stream.match('\'')) { state.tokenize = tokenBase; }
     return "error";
   }
 

+ 3 - 3
plugins/codemirror/mode/markdown/markdown.js

@@ -223,7 +223,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
 
       // Add this list item's content's indentation to the stack
       state.listStack.push(state.indentation);
-      // Reset inline styles which shouldn't propagate aross list items
+      // Reset inline styles which shouldn't propagate across list items
       state.em = false;
       state.strong = false;
       state.code = false;
@@ -612,7 +612,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
           return getType(state);
         }
       } else if (ch === ' ') {
-        if (stream.match(/^~~/, true)) { // Probably surrounded by space
+        if (stream.match('~~', true)) { // Probably surrounded by space
           if (stream.peek() === ' ') { // Surrounded by spaces, ignore
             return getType(state);
           } else { // Not surrounded by spaces, back up pointer
@@ -711,7 +711,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
   }
 
   function footnoteLinkInside(stream, state) {
-    if (stream.match(/^\]:/, true)) {
+    if (stream.match(']:', true)) {
       state.f = state.inline = footnoteUrl;
       if (modeCfg.highlightFormatting) state.formatting = "link";
       var returnType = getType(state);

+ 1 - 1
plugins/codemirror/mode/meta.js

@@ -44,7 +44,7 @@
     {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
     {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
     {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
-    {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
+    {name: "Embedded JavaScript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
     {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
     {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
     {name: "Esper", mime: "text/x-esper", mode: "sql"},

+ 3 - 3
plugins/codemirror/mode/modelica/modelica.js

@@ -90,7 +90,7 @@
         return "error";
     }
 
-    function tokenUnsignedNuber(stream, state) {
+    function tokenUnsignedNumber(stream, state) {
       stream.eatWhile(isDigit);
       if (stream.eat('.')) {
         stream.eatWhile(isDigit);
@@ -164,9 +164,9 @@
         else if(ch == '"') {
           state.tokenize = tokenString;
         }
-        // UNSIGNED_NUBER
+        // UNSIGNED_NUMBER
         else if(isDigit.test(ch)) {
-          state.tokenize = tokenUnsignedNuber;
+          state.tokenize = tokenUnsignedNumber;
         }
         // ERROR
         else {

+ 4 - 4
plugins/codemirror/mode/mscgen/mscgen.js

@@ -72,11 +72,11 @@
   CodeMirror.defineMIME("text/x-msgenny", {name: "mscgen", language: "msgenny"});
 
   function wordRegexpBoundary(pWords) {
-    return new RegExp("\\b(" + pWords.join("|") + ")\\b", "i");
+    return new RegExp("^\\b(?:" + pWords.join("|") + ")\\b", "i");
   }
 
   function wordRegexp(pWords) {
-    return new RegExp("(" + pWords.join("|") + ")", "i");
+    return new RegExp("^(?:" + pWords.join("|") + ")", "i");
   }
 
   function startStateFn() {
@@ -153,7 +153,7 @@
         return "variable";
 
       /* attribute lists */
-      if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match(/\[/, true, true)) {
+      if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match('[', true, true)) {
         pConfig.inAttributeList = true;
         return "bracket";
       }
@@ -161,7 +161,7 @@
         if (pConfig.attributes !== null && pStream.match(wordRegexpBoundary(pConfig.attributes), true, true)) {
           return "attribute";
         }
-        if (pStream.match(/]/, true, true)) {
+        if (pStream.match(']', true, true)) {
           pConfig.inAttributeList = false;
           return "bracket";
         }

+ 1 - 1
plugins/codemirror/mode/mumps/mumps.js

@@ -26,7 +26,7 @@
     var brackets = new RegExp("[()]");
     var identifiers = new RegExp("^[%A-Za-z][A-Za-z0-9]*");
     var commandKeywords = ["break","close","do","else","for","goto", "halt", "hang", "if", "job","kill","lock","merge","new","open", "quit", "read", "set", "tcommit", "trollback", "tstart", "use", "view", "write", "xecute", "b","c","d","e","f","g", "h", "i", "j","k","l","m","n","o", "q", "r", "s", "tc", "tro", "ts", "u", "v", "w", "x"];
-    // The following list includes instrinsic functions _and_ special variables
+    // The following list includes intrinsic functions _and_ special variables
     var intrinsicFuncsWords = ["\\$ascii", "\\$char", "\\$data", "\\$ecode", "\\$estack", "\\$etrap", "\\$extract", "\\$find", "\\$fnumber", "\\$get", "\\$horolog", "\\$io", "\\$increment", "\\$job", "\\$justify", "\\$length", "\\$name", "\\$next", "\\$order", "\\$piece", "\\$qlength", "\\$qsubscript", "\\$query", "\\$quit", "\\$random", "\\$reverse", "\\$select", "\\$stack", "\\$test", "\\$text", "\\$translate", "\\$view", "\\$x", "\\$y", "\\$a", "\\$c", "\\$d", "\\$e", "\\$ec", "\\$es", "\\$et", "\\$f", "\\$fn", "\\$g", "\\$h", "\\$i", "\\$j", "\\$l", "\\$n", "\\$na", "\\$o", "\\$p", "\\$q", "\\$ql", "\\$qs", "\\$r", "\\$re", "\\$s", "\\$st", "\\$t", "\\$tr", "\\$v", "\\$z"];
     var intrinsicFuncs = wordRegexp(intrinsicFuncsWords);
     var command = wordRegexp(commandKeywords);

+ 2 - 2
plugins/codemirror/mode/oz/oz.js

@@ -45,7 +45,7 @@ CodeMirror.defineMode("oz", function (conf) {
     }
 
     // Special [] keyword
-    if (stream.match(/(\[])/)) {
+    if (stream.match('[]')) {
         return "keyword"
     }
 
@@ -130,7 +130,7 @@ CodeMirror.defineMode("oz", function (conf) {
       return "operator";
     }
 
-    // If nothing match, we skip the entire alphanumerical block
+    // If nothing match, we skip the entire alphanumeric block
     stream.eatWhile(/\w/);
 
     return "variable";

+ 3 - 3
plugins/codemirror/mode/pegjs/pegjs.js

@@ -39,7 +39,7 @@ CodeMirror.defineMode("pegjs", function (config) {
         stream.next(); // Skip quote
         state.inString = true; // Update state
       }
-      if (!state.inString && !state.inComment && stream.match(/^\/\*/)) {
+      if (!state.inString && !state.inComment && stream.match('/*')) {
         state.inComment = true;
       }
 
@@ -59,7 +59,7 @@ CodeMirror.defineMode("pegjs", function (config) {
         return state.lhs ? "property string" : "string"; // Token style
       } else if (state.inComment) {
         while (state.inComment && !stream.eol()) {
-          if (stream.match(/\*\//)) {
+          if (stream.match('*/')) {
             state.inComment = false; // Clear flag
           } else {
             stream.match(/^.[^\*]*/);
@@ -76,7 +76,7 @@ CodeMirror.defineMode("pegjs", function (config) {
         stream.next();
         state.inCharacterClass = true;
         return 'bracket';
-      } else if (stream.match(/^\/\//)) {
+      } else if (stream.match('//')) {
         stream.skipToEnd();
         return "comment";
       } else if (state.braced || stream.peek() === '{') {

+ 2 - 2
plugins/codemirror/mode/perl/perl.js

@@ -347,7 +347,7 @@ CodeMirror.defineMode("perl",function(){
                 lc                              :1,     // - return lower-case version of a string
                 lcfirst                         :1,     // - return a string with just the next letter in lower case
                 length                          :1,     // - return the number of bytes in a string
-                'link'                          :1,     // - create a hard link in the filesytem
+                'link'                          :1,     // - create a hard link in the filesystem
                 listen                          :1,     // - register your socket as a server
                 local                           : 2,    // - create a temporary value for a global variable (dynamic scoping)
                 localtime                       :1,     // - convert UNIX time into record or string using local time
@@ -441,7 +441,7 @@ CodeMirror.defineMode("perl",function(){
                 state                           :1,     // - declare and assign a state variable (persistent lexical scoping)
                 study                           :1,     // - optimize input data for repeated searches
                 'sub'                           :1,     // - declare a subroutine, possibly anonymously
-                'substr'                        :1,     // - get or alter a portion of a stirng
+                'substr'                        :1,     // - get or alter a portion of a string
                 symlink                         :1,     // - create a symbolic link to a file
                 syscall                         :1,     // - execute an arbitrary system call
                 sysopen                         :1,     // - open a file, pipe, or descriptor

+ 2 - 2
plugins/codemirror/mode/php/php.js

@@ -53,7 +53,7 @@
           [["]", null]]
         ], closing, escapes);
       }
-      if (stream.match(/\-\>\w/, false)) {
+      if (stream.match(/^->\w/, false)) {
         // Match object operator
         state.tokenize = matchSequence([
           [["->", null]],
@@ -106,7 +106,7 @@
       },
       "<": function(stream, state) {
         var before;
-        if (before = stream.match(/<<\s*/)) {
+        if (before = stream.match(/^<<\s*/)) {
           var quoted = stream.eat(/['"]/);
           stream.eatWhile(/[\w\.]/);
           var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));

+ 1 - 1
plugins/codemirror/mode/pug/pug.js

@@ -261,7 +261,7 @@ CodeMirror.defineMode("pug", function (config) {
       }
       return 'variable';
     }
-    if (stream.match(/^\+#{/, false)) {
+    if (stream.match('+#{', false)) {
       stream.next();
       state.mixinCallAfter = true;
       return interpolation(stream, state);

+ 1 - 1
plugins/codemirror/mode/puppet/puppet.js

@@ -176,7 +176,7 @@ CodeMirror.defineMode("puppet", function () {
     // Match characters that we are going to assume
     // are trying to be regex
     if (ch == '/') {
-      stream.match(/.*?\//);
+      stream.match(/^[^\/]*\//);
       return 'variable-3';
     }
     // Match all the numbers

+ 4 - 4
plugins/codemirror/mode/rpm/rpm.js

@@ -12,14 +12,14 @@
 "use strict";
 
 CodeMirror.defineMode("rpm-changes", function() {
-  var headerSeperator = /^-+$/;
+  var headerSeparator = /^-+$/;
   var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)  ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
   var simpleEmail = /^[\w+.-]+@[\w.-]+/;
 
   return {
     token: function(stream) {
       if (stream.sol()) {
-        if (stream.match(headerSeperator)) { return 'tag'; }
+        if (stream.match(headerSeparator)) { return 'tag'; }
         if (stream.match(headerLine)) { return 'tag'; }
       }
       if (stream.match(simpleEmail)) { return 'string'; }
@@ -80,12 +80,12 @@ CodeMirror.defineMode("rpm-spec", function() {
 
       // Macros like '%make_install' or '%attr(0775,root,root)'
       if (stream.match(/^%[\w]+/)) {
-        if (stream.match(/^\(/)) { state.macroParameters = true; }
+        if (stream.match('(')) { state.macroParameters = true; }
         return "keyword";
       }
       if (state.macroParameters) {
         if (stream.match(/^\d+/)) { return "number";}
-        if (stream.match(/^\)/)) {
+        if (stream.match(')')) {
           state.macroParameters = false;
           return "keyword";
         }

+ 1 - 1
plugins/codemirror/mode/sass/sass.js

@@ -231,7 +231,7 @@ CodeMirror.defineMode("sass", function(config) {
       }
 
       if(ch === "@"){
-        if(stream.match(/@extend/)){
+        if(stream.match('@extend')){
           if(!stream.match(/\s*[\w]/))
             dedent(state);
         }

+ 1 - 1
plugins/codemirror/mode/scheme/scheme.js

@@ -170,7 +170,7 @@ CodeMirror.defineMode("scheme", function () {
                             } else if (stream.match(/^[-+0-9.]/, false)) {
                                 hasRadix = false;
                                 numTest = isDecimalNumber;
-                            // re-consume the intial # if all matches failed
+                            // re-consume the initial # if all matches failed
                             } else if (!hasExactness) {
                                 stream.eat('#');
                             }

+ 1 - 1
plugins/codemirror/mode/sieve/sieve.js

@@ -43,7 +43,7 @@ CodeMirror.defineMode("sieve", function(config) {
     if (ch == "(") {
       state._indent.push("(");
       // add virtual angel wings so that editor behaves...
-      // ...more sane incase of broken brackets
+      // ...more sane in case of broken brackets
       state._indent.push("{");
       return null;
     }

+ 5 - 5
plugins/codemirror/mode/soy/soy.js

@@ -411,7 +411,7 @@
             return null;
 
           case "list-literal":
-            if (stream.match(/\]/)) {
+            if (stream.match(']')) {
               state.soyState.pop();
               state.lookupVariables = true;
               popcontext(state);
@@ -517,14 +517,14 @@
             }
             return expression(stream, state);
           case "literal":
-            if (stream.match(/^(?=\{\/literal})/)) {
+            if (stream.match('{/literal}', false)) {
               state.soyState.pop();
               return this.token(stream, state);
             }
             return tokenUntil(stream, state, /\{\/literal}/);
         }
 
-        if (stream.match(/^\{literal}/)) {
+        if (stream.match('{literal}')) {
           state.indent += config.indentUnit;
           state.soyState.push("literal");
           state.context = new Context(state.context, "literal", state.variables);
@@ -581,12 +581,12 @@
           state.soyState.push("import");
           state.indent += 2 * config.indentUnit;
           return "keyword";
-        } else if (match = stream.match(/^<\{/)) {
+        } else if (match = stream.match('<{')) {
           state.soyState.push("template-call-expression");
           state.indent += 2 * config.indentUnit;
           state.soyState.push("tag");
           return "keyword";
-        } else if (match = stream.match(/^<\/>/)) {
+        } else if (match = stream.match('</>')) {
           state.indent -= 1 * config.indentUnit;
           return "keyword";
         }

+ 5 - 5
plugins/codemirror/mode/sql/sql.js

@@ -243,9 +243,9 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
     // varName can be quoted with ` or ' or "
     // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
     if (stream.eat("@")) {
-      stream.match(/^session\./);
-      stream.match(/^local\./);
-      stream.match(/^global\./);
+      stream.match('session.');
+      stream.match('local.');
+      stream.match('global.');
     }
 
     if (stream.eat("'")) {
@@ -370,7 +370,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
       "$":   hookVar,
       // The preferred way to escape Identifiers is using double quotes, ref: http://sqlite.org/lang_keywords.html
       "\"":   hookIdentifierDoublequote,
-      // there is also support for backtics, ref: http://sqlite.org/lang_keywords.html
+      // there is also support for backticks, ref: http://sqlite.org/lang_keywords.html
       "`":   hookIdentifier
     }
   });
@@ -451,7 +451,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
   // Spark SQL
   CodeMirror.defineMIME("text/x-sparksql", {
     name: "sql",
-    keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases datata dbproperties defined delete delimited deny desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on optimize option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"),
+    keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases data dbproperties defined delete delimited deny desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on optimize option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"),
     builtin: set("tinyint smallint int bigint boolean float double string binary timestamp decimal array map struct uniontype delimited serde sequencefile textfile rcfile inputformat outputformat"),
     atoms: set("false true null"),
     operatorChars: /^[*\/+\-%<>!=~&|^]/,

+ 1 - 1
plugins/codemirror/mode/stylus/stylus.js

@@ -138,7 +138,7 @@
         // Variable
         if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
           if (!wordIsTag(stream.current())) {
-            stream.match(/\./);
+            stream.match('.');
             return ["variable-2", "variable-name"];
           }
         }

+ 1 - 1
plugins/codemirror/mode/tiddlywiki/tiddlywiki.js

@@ -114,7 +114,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
         return 'header';
     }
 
-    if (ch == '{' && stream.match(/\{\{/))
+    if (ch == '{' && stream.match('{{'))
       return chain(stream, state, twTokenCode);
 
     // rudimentary html:// file:// link matching. TW knows much more ...

+ 2 - 2
plugins/codemirror/mode/vbscript/vbscript.js

@@ -32,7 +32,7 @@ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
     var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
     var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
     var singleDelimiters = new RegExp('^[\\.,]');
-    var brakets = new RegExp('^[\\(\\)]');
+    var brackets = new RegExp('^[\\(\\)]');
     var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
 
     var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
@@ -183,7 +183,7 @@ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
             return null;
         }
 
-        if (stream.match(brakets)) {
+        if (stream.match(brackets)) {
             return "bracket";
         }
 

+ 1 - 1
plugins/codemirror/mode/velocity/velocity.js

@@ -48,7 +48,7 @@ CodeMirror.defineMode("velocity", function() {
             else if (state.inParams)
                 return chain(stream, state, tokenString(ch));
         }
-        // is it one of the special signs []{}().,;? Seperator?
+        // is it one of the special signs []{}().,;? Separator?
         else if (/[\[\]{}\(\),;\.]/.test(ch)) {
             if (ch == "(" && beforeParams)
                 state.inParams = true;

+ 2 - 2
plugins/codemirror/mode/verilog/verilog.js

@@ -542,7 +542,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
   };
   var tlvIndentUnit = 3;
   var tlvTrackStatements = false;
-  var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/;  // Matches an identifiere.
+  var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/;  // Matches an identifier.
   // Note that ':' is excluded, because of it's use in [:].
   var tlvFirstLevelIndentMatch = /^[! ]  /;
   var tlvLineIndentationMatch = /^[! ] */;
@@ -719,7 +719,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
             } else {
               // Just swallow one character and try again.
               // This enables subsequent identifier match with preceding symbol character, which
-              //   is legal within a statement.  (Eg, !$reset).  It also enables detection of
+              //   is legal within a statement.  (E.g., !$reset).  It also enables detection of
               //   comment start with preceding symbols.
               stream.backUp(stream.current().length - 1);
               style = "tlv-default";

+ 1 - 1
plugins/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js

@@ -36,7 +36,7 @@
       },
       token: function (stream, state) {
         if (state.state == START) {
-          if (stream.match(/---/, false)) {
+          if (stream.match('---', false)) {
             state.state = FRONTMATTER
             return yamlMode.token(stream, state.inner)
           } else {

+ 4 - 4
plugins/codemirror/mode/yaml/yaml.js

@@ -38,9 +38,9 @@ CodeMirror.defineMode("yaml", function() {
         state.pair = false;
         state.pairStart = false;
         /* document start */
-        if(stream.match(/---/)) { return "def"; }
+        if(stream.match('---')) { return "def"; }
         /* document end */
-        if (stream.match(/\.\.\./)) { return "def"; }
+        if (stream.match('...')) { return "def"; }
         /* array list item */
         if (stream.match(/\s*-\s+/)) { return 'meta'; }
       }
@@ -57,12 +57,12 @@ CodeMirror.defineMode("yaml", function() {
         return 'meta';
       }
 
-      /* list seperator */
+      /* list separator */
       if (state.inlineList > 0 && !esc && ch == ',') {
         stream.next();
         return 'meta';
       }
-      /* pairs seperator */
+      /* pairs separator */
       if (state.inlinePairs > 0 && !esc && ch == ',') {
         state.keyCol = 0;
         state.pair = false;

+ 340 - 0
plugins/datatables-searchbuilder/css/searchBuilder.bootstrap4.css

@@ -0,0 +1,340 @@
+div.dt-datetime {
+  position: absolute;
+  background-color: white;
+  z-index: 2050;
+  border: 1px solid #ccc;
+  box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.5);
+  padding: 0 20px 6px 20px;
+  width: 275px;
+}
+div.dt-datetime.inline {
+  position: relative;
+  box-shadow: none;
+}
+div.dt-datetime div.dt-datetime-title {
+  text-align: center;
+  padding: 5px 0px 3px;
+}
+div.dt-datetime table {
+  border-spacing: 0;
+  margin: 12px 0;
+  width: 100%;
+}
+div.dt-datetime table.dt-datetime-table-nospace {
+  margin-top: -12px;
+}
+div.dt-datetime table th {
+  font-size: 0.8em;
+  color: #777;
+  font-weight: normal;
+  width: 14.285714286%;
+  padding: 0 0 4px 0;
+  text-align: center;
+}
+div.dt-datetime table td {
+  font-size: 0.9em;
+  color: #444;
+  padding: 0;
+}
+div.dt-datetime table td.selectable {
+  text-align: center;
+  background: #f5f5f5;
+}
+div.dt-datetime table td.selectable.disabled {
+  color: #aaa;
+  background: white;
+}
+div.dt-datetime table td.selectable.disabled button:hover {
+  color: #aaa;
+  background: white;
+}
+div.dt-datetime table td.selectable.now {
+  background-color: #ddd;
+}
+div.dt-datetime table td.selectable.now button {
+  font-weight: bold;
+}
+div.dt-datetime table td.selectable.selected button {
+  background: #4E6CA3;
+  color: white;
+  border-radius: 2px;
+}
+div.dt-datetime table td.selectable button:hover {
+  background: #ff8000;
+  color: white;
+  border-radius: 2px;
+}
+div.dt-datetime table td.dt-datetime-week {
+  font-size: 0.7em;
+}
+div.dt-datetime table button {
+  width: 100%;
+  box-sizing: border-box;
+  border: none;
+  background: transparent;
+  font-size: inherit;
+  color: inherit;
+  text-align: center;
+  padding: 4px 0;
+  cursor: pointer;
+  margin: 0;
+}
+div.dt-datetime table button span {
+  display: inline-block;
+  min-width: 14px;
+  text-align: right;
+}
+div.dt-datetime table.weekNumber th {
+  width: 12.5%;
+}
+div.dt-datetime div.dt-datetime-calendar table {
+  margin-top: 0;
+}
+div.dt-datetime div.dt-datetime-label {
+  position: relative;
+  display: inline-block;
+  height: 30px;
+  padding: 5px 6px;
+  border: 1px solid transparent;
+  box-sizing: border-box;
+  cursor: pointer;
+}
+div.dt-datetime div.dt-datetime-label:hover {
+  border: 1px solid #ddd;
+  border-radius: 2px;
+  background-color: #f5f5f5;
+}
+div.dt-datetime div.dt-datetime-label select {
+  position: absolute;
+  top: 6px;
+  left: 0;
+  cursor: pointer;
+  opacity: 0;
+}
+div.dt-datetime.horizontal {
+  width: 550px;
+}
+div.dt-datetime.horizontal div.dt-datetime-date,
+div.dt-datetime.horizontal div.dt-datetime-time {
+  width: 48%;
+}
+div.dt-datetime.horizontal div.dt-datetime-time {
+  margin-left: 4%;
+}
+div.dt-datetime div.dt-datetime-date {
+  position: relative;
+  float: left;
+  width: 100%;
+}
+div.dt-datetime div.dt-datetime-time {
+  position: relative;
+  float: left;
+  width: 100%;
+  text-align: center;
+}
+div.dt-datetime div.dt-datetime-time > span {
+  vertical-align: middle;
+}
+div.dt-datetime div.dt-datetime-time th {
+  text-align: left;
+}
+div.dt-datetime div.dt-datetime-time div.dt-datetime-timeblock {
+  display: inline-block;
+  vertical-align: middle;
+}
+div.dt-datetime div.dt-datetime-iconLeft,
+div.dt-datetime div.dt-datetime-iconRight,
+div.dt-datetime div.dt-datetime-iconUp,
+div.dt-datetime div.dt-datetime-iconDown {
+  width: 30px;
+  height: 30px;
+  background-position: center;
+  background-repeat: no-repeat;
+  opacity: 0.3;
+  overflow: hidden;
+  box-sizing: border-box;
+}
+div.dt-datetime div.dt-datetime-iconLeft:hover,
+div.dt-datetime div.dt-datetime-iconRight:hover,
+div.dt-datetime div.dt-datetime-iconUp:hover,
+div.dt-datetime div.dt-datetime-iconDown:hover {
+  border: 1px solid #ccc;
+  border-radius: 2px;
+  background-color: #f0f0f0;
+  opacity: 0.6;
+}
+div.dt-datetime div.dt-datetime-iconLeft button,
+div.dt-datetime div.dt-datetime-iconRight button,
+div.dt-datetime div.dt-datetime-iconUp button,
+div.dt-datetime div.dt-datetime-iconDown button {
+  border: none;
+  background: transparent;
+  text-indent: 30px;
+  height: 100%;
+  width: 100%;
+  cursor: pointer;
+}
+div.dt-datetime div.dt-datetime-iconLeft {
+  position: absolute;
+  top: 5px;
+  left: 5px;
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==");
+}
+div.dt-datetime div.dt-datetime-iconRight {
+  position: absolute;
+  top: 5px;
+  right: 5px;
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=");
+}
+div.dt-datetime div.dt-datetime-iconUp {
+  height: 20px;
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAALCAMAAABf9c24AAAAFVBMVEX///99fX1+fn57e3t6enoAAAAAAAC73bqPAAAABnRSTlMAYmJkZt92bnysAAAAL0lEQVR4AWOgJmBhxCvLyopHnpmVjY2VCadeoCxIHrcsWJ4RlyxCHlMWCTBRJxwAjrIBDMWSiM0AAAAASUVORK5CYII=");
+}
+div.dt-datetime div.dt-datetime-iconDown {
+  height: 20px;
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAALCAMAAABf9c24AAAAFVBMVEX///99fX1+fn57e3t6enoAAAAAAAC73bqPAAAABnRSTlMAYmJkZt92bnysAAAAMElEQVR4AWOgDmBiRQIsmPKMrGxQgJDFlEfIYpoPk8Utz8qM232MYFfhkQfKUg8AANefAQxecJ58AAAAAElFTkSuQmCC");
+}
+
+div.dt-datetime-error {
+  clear: both;
+  padding: 0 1em;
+  max-width: 240px;
+  font-size: 11px;
+  line-height: 1.25em;
+  text-align: center;
+  color: #b11f1f;
+}
+
+div.dt-button-collection {
+  overflow: visible !important;
+}
+
+.dtsb-greyscale {
+  border: 1px solid #cecece !important;
+}
+
+div.dtsb-logicContainer .dtsb-greyscale {
+  border: none !important;
+}
+
+div.dtsb-searchBuilder {
+  justify-content: space-evenly;
+  cursor: default;
+  margin-bottom: 1em;
+  text-align: left;
+}
+div.dtsb-searchBuilder button.dtsb-button,
+div.dtsb-searchBuilder select {
+  font-size: 1em;
+}
+div.dtsb-searchBuilder div.dtsb-titleRow {
+  justify-content: space-evenly;
+  margin-bottom: 0.5em;
+}
+div.dtsb-searchBuilder div.dtsb-titleRow div.dtsb-title {
+  display: inline-block;
+  padding-top: 6px;
+}
+div.dtsb-searchBuilder div.dtsb-titleRow button.dtsb-clearAll {
+  float: right;
+  margin-bottom: 0.333em;
+}
+div.dtsb-searchBuilder div.dtsb-vertical .dtsb-value, div.dtsb-searchBuilder div.dtsb-vertical .dtsb-data, div.dtsb-searchBuilder div.dtsb-vertical .dtsb-condition {
+  display: block;
+}
+div.dtsb-searchBuilder div.dtsb-group {
+  position: relative;
+  clear: both;
+  margin-bottom: 0.8em;
+}
+div.dtsb-searchBuilder div.dtsb-group button.dtsb-clearGroup {
+  margin: 2px;
+  text-align: center;
+  padding: 0;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer {
+  -webkit-transform: rotate(90deg);
+  -moz-transform: rotate(90deg);
+  -o-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  transform: rotate(90deg);
+  position: absolute;
+  margin-top: 0.8em;
+  margin-right: 0.8em;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria {
+  margin-bottom: 0.8em;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-dropDown,
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-input {
+  padding: 0.4em;
+  margin-right: 0.8em;
+  max-width: 20em;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-dropDown option.dtsb-notItalic,
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-input option.dtsb-notItalic {
+  font-style: normal;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-italic {
+  font-style: italic;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer {
+  float: right;
+  display: inline-block;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-delete, div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-right, div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-left {
+  margin-right: 0.8em;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-delete:last-child, div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-right:last-child, div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria div.dtsb-buttonContainer button.dtsb-left:last-child {
+  margin-right: 0;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria span.dtsp-joiner {
+  margin-right: 0.8em;
+}
+
+div.dtsb-searchBuilder div.dtsb-titleRow {
+  height: 40px;
+}
+div.dtsb-searchBuilder div.dtsb-titleRow div.dtsb-title {
+  padding-top: 10px;
+}
+div.dtsb-searchBuilder div.dtsb-group button.dtsb-clearGroup {
+  margin-right: 8px;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria .form-control {
+  width: auto;
+  display: inline-block;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-condition {
+  border-color: #28a745;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-data {
+  border-color: #dc3545;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria select.dtsb-value, div.dtsb-searchBuilder div.dtsb-group div.dtsb-criteria input.dtsb-value {
+  border-color: #007bff;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer {
+  border-radius: 4px;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  align-content: flex-start;
+  align-items: flex-start;
+  margin-top: 10px;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer button.dtsb-logic {
+  border: none;
+  border-radius: 0px;
+  flex-grow: 1;
+  flex-shrink: 0;
+  flex-basis: 40px;
+  margin: 0px;
+}
+div.dtsb-searchBuilder div.dtsb-group div.dtsb-logicContainer button.dtsb-clearGroup {
+  border: none;
+  border-radius: 0px;
+  width: 30px;
+  margin: 0px;
+}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
plugins/datatables-searchbuilder/css/searchBuilder.bootstrap4.min.css


+ 4376 - 0
plugins/datatables-searchbuilder/js/dataTables.searchBuilder.js

@@ -0,0 +1,4376 @@
+(function () {
+	'use strict';
+
+	/*! DateTime picker for DataTables.net v1.0.1
+	 *
+	 * ©2020 SpryMedia Ltd, all rights reserved.
+	 * License: MIT datatables.net/license/mit
+	 */
+
+	/**
+	 * @summary     DateTime picker for DataTables.net
+	 * @version     1.0.1
+	 * @file        dataTables.dateTime.js
+	 * @author      SpryMedia Ltd
+	 * @contact     www.datatables.net/contact
+	 */
+	(function( factory ){
+		if ( typeof define === 'function' && define.amd ) {
+			// AMD
+			define( ['jquery'], function ( $ ) {
+				return factory( $, window, document );
+			} );
+		}
+		else if ( typeof exports === 'object' ) {
+			// CommonJS
+			module.exports = function (root, $) {
+				if ( ! root ) {
+					root = window;
+				}
+
+				return factory( $, root, root.document );
+			};
+		}
+		else {
+			// Browser
+			factory( jQuery, window, document );
+		}
+	}(function( $, window, document, undefined$1 ) {
+
+	// Support libraries which support a Moment like API
+	var dateLib = window.moment
+		? window.moment
+		: window.dayjs
+			? window.dayjs
+			: null;
+
+	/*
+	 * This file provides a DateTime GUI picker (calendar and time input). Only the
+	 * format YYYY-MM-DD is supported without additional software, but the end user
+	 * experience can be greatly enhanced by including the momentjs or dayjs library
+	 * which provide date / time parsing and formatting options.
+	 *
+	 * This functionality is required because the HTML5 date and datetime input
+	 * types are not widely supported in desktop browsers.
+	 *
+	 * Constructed by using:
+	 *
+	 *     new DateTime( input, opts )
+	 *
+	 * where `input` is the HTML input element to use and `opts` is an object of
+	 * options based on the `DateTime.defaults` object.
+	 */
+	var DateTime = function ( input, opts ) {
+		this.c = $.extend( true, {}, DateTime.defaults, opts );
+		var classPrefix = this.c.classPrefix;
+		var i18n = this.c.i18n;
+
+		// Only IS8601 dates are supported without moment pr dayjs
+		if ( ! dateLib && this.c.format !== 'YYYY-MM-DD' ) {
+			throw "DateTime: Without momentjs or dayjs only the format 'YYYY-MM-DD' can be used";
+		}
+
+		// Min and max need to be `Date` objects in the config
+		if (typeof this.c.minDate === 'string') {
+			this.c.minDate = new Date(this.c.minDate);
+		}
+		if (typeof this.c.maxDate === 'string') {
+			this.c.maxDate = new Date(this.c.maxDate);
+		}
+
+		// DOM structure
+		var structure = $(
+			'<div class="'+classPrefix+'">'+
+				'<div class="'+classPrefix+'-date">'+
+					'<div class="'+classPrefix+'-title">'+
+						'<div class="'+classPrefix+'-iconLeft">'+
+							'<button>'+i18n.previous+'</button>'+
+						'</div>'+
+						'<div class="'+classPrefix+'-iconRight">'+
+							'<button>'+i18n.next+'</button>'+
+						'</div>'+
+						'<div class="'+classPrefix+'-label">'+
+							'<span></span>'+
+							'<select class="'+classPrefix+'-month"></select>'+
+						'</div>'+
+						'<div class="'+classPrefix+'-label">'+
+							'<span></span>'+
+							'<select class="'+classPrefix+'-year"></select>'+
+						'</div>'+
+					'</div>'+
+					'<div class="'+classPrefix+'-calendar"></div>'+
+				'</div>'+
+				'<div class="'+classPrefix+'-time">'+
+					'<div class="'+classPrefix+'-hours"></div>'+
+					'<div class="'+classPrefix+'-minutes"></div>'+
+					'<div class="'+classPrefix+'-seconds"></div>'+
+				'</div>'+
+				'<div class="'+classPrefix+'-error"></div>'+
+			'</div>'
+		);
+
+		this.dom = {
+			container: structure,
+			date:      structure.find( '.'+classPrefix+'-date' ),
+			title:     structure.find( '.'+classPrefix+'-title' ),
+			calendar:  structure.find( '.'+classPrefix+'-calendar' ),
+			time:      structure.find( '.'+classPrefix+'-time' ),
+			error:     structure.find( '.'+classPrefix+'-error' ),
+			input:     $(input)
+		};
+
+		this.s = {
+			/** @type {Date} Date value that the picker has currently selected */
+			d: null,
+
+			/** @type {Date} Date of the calendar - might not match the value */
+			display: null,
+
+			/** @type {number} Used to select minutes in a range where the range base is itself unavailable */
+			minutesRange: null,
+
+			/** @type {number} Used to select minutes in a range where the range base is itself unavailable */
+			secondsRange: null,
+
+			/** @type {String} Unique namespace string for this instance */
+			namespace: 'dateime-'+(DateTime._instance++),
+
+			/** @type {Object} Parts of the picker that should be shown */
+			parts: {
+				date:    this.c.format.match( /[YMD]|L(?!T)|l/ ) !== null,
+				time:    this.c.format.match( /[Hhm]|LT|LTS/ ) !== null,
+				seconds: this.c.format.indexOf( 's' )   !== -1,
+				hours12: this.c.format.match( /[haA]/ ) !== null
+			}
+		};
+
+		this.dom.container
+			.append( this.dom.date )
+			.append( this.dom.time )
+			.append( this.dom.error );
+
+		this.dom.date
+			.append( this.dom.title )
+			.append( this.dom.calendar );
+
+		this._constructor();
+	};
+
+	$.extend( DateTime.prototype, {
+		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+		 * Public
+		 */
+		
+		/**
+		 * Destroy the control
+		 */
+		destroy: function () {
+			this._hide(true);
+			this.dom.container.off().empty();
+			this.dom.input.off('.datetime');
+		},
+
+		errorMsg: function ( msg ) {
+			var error = this.dom.error;
+
+			if ( msg ) {
+				error.html( msg );
+			}
+			else {
+				error.empty();
+			}
+
+			return this;
+		},
+
+		hide: function () {
+			this._hide();
+
+			return this;
+		},
+
+		max: function ( date ) {
+			this.c.maxDate = typeof date === 'string'
+				? new Date(date)
+				: date;
+
+			this._optionsTitle();
+			this._setCalander();
+
+			return this;
+		},
+
+		min: function ( date ) {
+			this.c.minDate = typeof date === 'string'
+				? new Date(date)
+				: date;
+
+			this._optionsTitle();
+			this._setCalander();
+
+			return this;
+		},
+
+		/**
+		 * Check if an element belongs to this control
+		 *
+		 * @param  {node} node Element to check
+		 * @return {boolean}   true if owned by this control, false otherwise
+		 */
+		owns: function ( node ) {
+			return $(node).parents().filter( this.dom.container ).length > 0;
+		},
+
+		/**
+		 * Get / set the value
+		 *
+		 * @param  {string|Date} set   Value to set
+		 * @param  {boolean} [write=true] Flag to indicate if the formatted value
+		 *   should be written into the input element
+		 */
+		val: function ( set, write ) {
+			if ( set === undefined$1 ) {
+				return this.s.d;
+			}
+
+			if ( set instanceof Date ) {
+				this.s.d = this._dateToUtc( set );
+			}
+			else if ( set === null || set === '' ) {
+				this.s.d = null;
+			}
+			else if ( set === '--now' ) {
+				this.s.d = new Date();
+			}
+			else if ( typeof set === 'string' ) {
+				if ( dateLib ) {
+					// Use moment or dayjs if possible (even for ISO8601 strings, since it
+					// will correctly handle 0000-00-00 and the like)
+					var m = dateLib.utc( set, this.c.format, this.c.locale, this.c.strict );
+					this.s.d = m.isValid() ? m.toDate() : null;
+				}
+				else {
+					// Else must be using ISO8601 without a date library (constructor would
+					// have thrown an error otherwise)
+					var match = set.match(/(\d{4})\-(\d{2})\-(\d{2})/ );
+					this.s.d = match ?
+						new Date( Date.UTC(match[1], match[2]-1, match[3]) ) :
+						null;
+				}
+			}
+
+			if ( write || write === undefined$1 ) {
+				if ( this.s.d ) {
+					this._writeOutput();
+				}
+				else {
+					// The input value was not valid...
+					this.dom.input.val( set );
+				}
+			}
+
+			// We need a date to be able to display the calendar at all
+			if ( ! this.s.d ) {
+				this.s.d = this._dateToUtc( new Date() );
+			}
+
+			this.s.display = new Date( this.s.d.toString() );
+
+			// Set the day of the month to be 1 so changing between months doesn't
+	        // run into issues when going from day 31 to 28 (for example)
+			this.s.display.setUTCDate( 1 );
+
+			// Update the display elements for the new value
+			this._setTitle();
+			this._setCalander();
+			this._setTime();
+
+			return this;
+		},
+
+
+		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+		 * Constructor
+		 */
+		
+		/**
+		 * Build the control and assign initial event handlers
+		 *
+		 * @private
+		 */
+		_constructor: function () {
+			var that = this;
+			var classPrefix = this.c.classPrefix;
+			var onChange = function () {
+				that.c.onChange.call( that, that.dom.input.val(), that.s.d, that.dom.input );
+			};
+
+			if ( ! this.s.parts.date ) {
+				this.dom.date.css( 'display', 'none' );
+			}
+
+			if ( ! this.s.parts.time ) {
+				this.dom.time.css( 'display', 'none' );
+			}
+
+			if ( ! this.s.parts.seconds ) {
+				this.dom.time.children('div.'+classPrefix+'-seconds').remove();
+				this.dom.time.children('span').eq(1).remove();
+			}
+
+			// Render the options
+			this._optionsTitle();
+
+			window.allan = this;
+
+			// When attached to a hidden input, we always show the input picker, and
+			// do so inline
+			if (this.dom.input.attr('type') === 'hidden') {
+				this.dom.container.addClass('inline');
+				this.c.attachTo = 'input';
+
+				this.val( this.dom.input.val(), false );
+				this._show();
+			}
+
+			// Trigger the display of the widget when clicking or focusing on the
+			// input element
+			this.dom.input
+				.attr('autocomplete', 'off')
+				.on('focus.datetime click.datetime', function () {
+					// If already visible - don't do anything
+					if ( that.dom.container.is(':visible') || that.dom.input.is(':disabled') ) {
+						return;
+					}
+
+					// In case the value has changed by text
+					that.val( that.dom.input.val(), false );
+
+					that._show();
+				} )
+				.on('keyup.datetime', function () {
+					// Update the calendar's displayed value as the user types
+					if ( that.dom.container.is(':visible') ) {
+						that.val( that.dom.input.val(), false );
+					}
+				} );
+
+			// Main event handlers for input in the widget
+			this.dom.container
+				.on( 'change', 'select', function () {
+					var select = $(this);
+					var val = select.val();
+
+					if ( select.hasClass(classPrefix+'-month') ) {
+						// Month select
+						that._correctMonth( that.s.display, val );
+						that._setTitle();
+						that._setCalander();
+					}
+					else if ( select.hasClass(classPrefix+'-year') ) {
+						// Year select
+						that.s.display.setUTCFullYear( val );
+						that._setTitle();
+						that._setCalander();
+					}
+					else if ( select.hasClass(classPrefix+'-hours') || select.hasClass(classPrefix+'-ampm') ) {
+						// Hours - need to take account of AM/PM input if present
+						if ( that.s.parts.hours12 ) {
+							var hours = $(that.dom.container).find('.'+classPrefix+'-hours').val() * 1;
+							var pm = $(that.dom.container).find('.'+classPrefix+'-ampm').val() === 'pm';
+
+							that.s.d.setUTCHours( hours === 12 && !pm ?
+								0 :
+								pm && hours !== 12 ?
+									hours + 12 :
+									hours
+							);
+						}
+						else {
+							that.s.d.setUTCHours( val );
+						}
+
+						that._setTime();
+						that._writeOutput( true );
+
+						onChange();
+					}
+					else if ( select.hasClass(classPrefix+'-minutes') ) {
+						// Minutes select
+						that.s.d.setUTCMinutes( val );
+						that._setTime();
+						that._writeOutput( true );
+
+						onChange();
+					}
+					else if ( select.hasClass(classPrefix+'-seconds') ) {
+						// Seconds select
+						that.s.d.setSeconds( val );
+						that._setTime();
+						that._writeOutput( true );
+
+						onChange();
+					}
+
+					that.dom.input.focus();
+					that._position();
+				} )
+				.on( 'click', function (e) {
+					var d = that.s.d;
+					var nodeName = e.target.nodeName.toLowerCase();
+					var target = nodeName === 'span' ?
+						e.target.parentNode :
+						e.target;
+
+					nodeName = target.nodeName.toLowerCase();
+
+					if ( nodeName === 'select' ) {
+						return;
+					}
+
+					e.stopPropagation();
+
+					if ( nodeName === 'button' ) {
+						var button = $(target);
+						var parent = button.parent();
+
+						if ( parent.hasClass('disabled') && ! parent.hasClass('range') ) {
+							button.blur();
+							return;
+						}
+
+						if ( parent.hasClass(classPrefix+'-iconLeft') ) {
+							// Previous month
+							that.s.display.setUTCMonth( that.s.display.getUTCMonth()-1 );
+							that._setTitle();
+							that._setCalander();
+
+							that.dom.input.focus();
+						}
+						else if ( parent.hasClass(classPrefix+'-iconRight') ) {
+							// Next month
+							that._correctMonth( that.s.display, that.s.display.getUTCMonth()+1 );
+							that._setTitle();
+							that._setCalander();
+
+							that.dom.input.focus();
+						}
+						else if ( button.parents('.'+classPrefix+'-time').length ) {
+							var val = button.data('value');
+							var unit = button.data('unit');
+
+							if ( unit === 'minutes' ) {
+								if ( parent.hasClass('disabled') && parent.hasClass('range') ) {
+									that.s.minutesRange = val;
+									that._setTime();
+									return;
+								}
+								else {
+									that.s.minutesRange = null;
+								}
+							}
+
+							if ( unit === 'seconds' ) {
+								if ( parent.hasClass('disabled') && parent.hasClass('range') ) {
+									that.s.secondsRange = val;
+									that._setTime();
+									return;
+								}
+								else {
+									that.s.secondsRange = null;
+								}
+							}
+
+							// Specific to hours for 12h clock
+							if ( val === 'am' ) {
+								if ( d.getUTCHours() >= 12 ) {
+									val = d.getUTCHours() - 12;
+								}
+								else {
+									return;
+								}
+							}
+							else if ( val === 'pm' ) {
+								if ( d.getUTCHours() < 12 ) {
+									val = d.getUTCHours() + 12;
+								}
+								else {
+									return;
+								}
+							}
+
+							var set = unit === 'hours' ?
+								'setUTCHours' :
+								unit === 'minutes' ?
+									'setUTCMinutes' :
+									'setSeconds';
+
+							d[set]( val );
+							that._setTime();
+							that._writeOutput( true );
+							onChange();
+						}
+						else {
+							// Calendar click
+							if ( ! d ) {
+								d = that._dateToUtc( new Date() );
+							}
+
+							// Can't be certain that the current day will exist in
+							// the new month, and likewise don't know that the
+							// new day will exist in the old month, But 1 always
+							// does, so we can change the month without worry of a
+							// recalculation being done automatically by `Date`
+							d.setUTCDate( 1 );
+							d.setUTCFullYear( button.data('year') );
+							d.setUTCMonth( button.data('month') );
+							d.setUTCDate( button.data('day') );
+
+							that._writeOutput( true );
+
+							// Don't hide if there is a time picker, since we want to
+							// be able to select a time as well.
+							if ( ! that.s.parts.time ) {
+								// This is annoying but IE has some kind of async
+								// behaviour with focus and the focus from the above
+								// write would occur after this hide - resulting in the
+								// calendar opening immediately
+								setTimeout( function () {
+									that._hide();
+								}, 10 );
+							}
+							else {
+								that._setCalander();
+							}
+
+							onChange();
+						}
+					}
+					else {
+						// Click anywhere else in the widget - return focus to the
+						// input element
+						that.dom.input.focus();
+					}
+				} );
+		},
+
+
+		/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+		 * Private
+		 */
+
+		/**
+		 * Compare the date part only of two dates - this is made super easy by the
+		 * toDateString method!
+		 *
+		 * @param  {Date} a Date 1
+		 * @param  {Date} b Date 2
+		 * @private
+		 */
+		_compareDates: function( a, b ) {
+			// Can't use toDateString as that converts to local time
+			return this._dateToUtcString(a) === this._dateToUtcString(b);
+		},
+
+		/**
+		 * When changing month, take account of the fact that some months don't have
+		 * the same number of days. For example going from January to February you
+		 * can have the 31st of Jan selected and just add a month since the date
+		 * would still be 31, and thus drop you into March.
+		 *
+		 * @param  {Date} date  Date - will be modified
+		 * @param  {integer} month Month to set
+		 * @private
+		 */
+		_correctMonth: function ( date, month ) {
+			var days = this._daysInMonth( date.getUTCFullYear(), month );
+			var correctDays = date.getUTCDate() > days;
+
+			date.setUTCMonth( month );
+
+			if ( correctDays ) {
+				date.setUTCDate( days );
+				date.setUTCMonth( month );
+			}
+		},
+
+		/**
+		 * Get the number of days in a method. Based on
+		 * http://stackoverflow.com/a/4881951 by Matti Virkkunen
+		 *
+		 * @param  {integer} year  Year
+		 * @param  {integer} month Month (starting at 0)
+		 * @private
+		 */
+		_daysInMonth: function ( year, month ) {
+			// 
+			var isLeap = ((year % 4) === 0 && ((year % 100) !== 0 || (year % 400) === 0));
+			var months = [31, (isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+			return months[month];
+		},
+
+		/**
+		 * Create a new date object which has the UTC values set to the local time.
+		 * This allows the local time to be used directly for the library which
+		 * always bases its calculations and display on UTC.
+		 *
+		 * @param  {Date} s Date to "convert"
+		 * @return {Date}   Shifted date
+		 */
+		_dateToUtc: function ( s ) {
+			return new Date( Date.UTC(
+				s.getFullYear(), s.getMonth(), s.getDate(),
+				s.getHours(), s.getMinutes(), s.getSeconds()
+			) );
+		},
+
+		/**
+		 * Create a UTC ISO8601 date part from a date object
+		 *
+		 * @param  {Date} d Date to "convert"
+		 * @return {string} ISO formatted date
+		 */
+		_dateToUtcString: function ( d ) {
+			return d.getUTCFullYear()+'-'+
+				this._pad(d.getUTCMonth()+1)+'-'+
+				this._pad(d.getUTCDate());
+		},
+
+		/**
+		 * Hide the control and remove events related to its display
+		 *
+		 * @private
+		 */
+		_hide: function (destroy) {
+			if (! destroy && this.dom.input.attr('type') === 'hidden') {
+				return;
+			}
+
+			var namespace = this.s.namespace;
+
+			this.dom.container.detach();
+
+			$(window).off( '.'+namespace );
+			$(document).off( 'keydown.'+namespace );
+			$('div.dataTables_scrollBody').off( 'scroll.'+namespace );
+			$('div.DTE_Body_Content').off( 'scroll.'+namespace );
+			$('body').off( 'click.'+namespace );
+		},
+
+		/**
+		 * Convert a 24 hour value to a 12 hour value
+		 *
+		 * @param  {integer} val 24 hour value
+		 * @return {integer}     12 hour value
+		 * @private
+		 */
+		_hours24To12: function ( val ) {
+			return val === 0 ?
+				12 :
+				val > 12 ?
+					val - 12 :
+					val;
+		},
+
+		/**
+		 * Generate the HTML for a single day in the calendar - this is basically
+		 * and HTML cell with a button that has data attributes so we know what was
+		 * clicked on (if it is clicked on) and a bunch of classes for styling.
+		 *
+		 * @param  {object} day Day object from the `_htmlMonth` method
+		 * @return {string}     HTML cell
+		 */
+		_htmlDay: function( day )
+		{
+			if ( day.empty ) {
+				return '<td class="empty"></td>';
+			}
+
+			var classes = [ 'selectable' ];
+			var classPrefix = this.c.classPrefix;
+
+			if ( day.disabled ) {
+				classes.push( 'disabled' );
+			}
+
+			if ( day.today ) {
+				classes.push( 'now' );
+			}
+
+			if ( day.selected ) {
+				classes.push( 'selected' );
+			}
+
+			return '<td data-day="' + day.day + '" class="' + classes.join(' ') + '">' +
+					'<button class="'+classPrefix+'-button '+classPrefix+'-day" type="button" ' +'data-year="' + day.year + '" data-month="' + day.month + '" data-day="' + day.day + '">' +
+						'<span>'+day.day+'</span>'+
+					'</button>' +
+				'</td>';
+		},
+
+
+		/**
+		 * Create the HTML for a month to be displayed in the calendar table.
+		 * 
+		 * Based upon the logic used in Pikaday - MIT licensed
+		 * Copyright (c) 2014 David Bushell
+		 * https://github.com/dbushell/Pikaday
+		 *
+		 * @param  {integer} year  Year
+		 * @param  {integer} month Month (starting at 0)
+		 * @return {string} Calendar month HTML
+		 * @private
+		 */
+		_htmlMonth: function ( year, month ) {
+			var now    = this._dateToUtc( new Date() ),
+				days   = this._daysInMonth( year, month ),
+				before = new Date( Date.UTC(year, month, 1) ).getUTCDay(),
+				data   = [],
+				row    = [];
+
+			if ( this.c.firstDay > 0 ) {
+				before -= this.c.firstDay;
+
+				if (before < 0) {
+					before += 7;
+				}
+			}
+
+			var cells = days + before,
+				after = cells;
+
+			while ( after > 7 ) {
+				after -= 7;
+			}
+
+			cells += 7 - after;
+
+			var minDate = this.c.minDate;
+			var maxDate = this.c.maxDate;
+
+			if ( minDate ) {
+				minDate.setUTCHours(0);
+				minDate.setUTCMinutes(0);
+				minDate.setSeconds(0);
+			}
+
+			if ( maxDate ) {
+				maxDate.setUTCHours(23);
+				maxDate.setUTCMinutes(59);
+				maxDate.setSeconds(59);
+			}
+
+			for ( var i=0, r=0 ; i<cells ; i++ ) {
+				var day      = new Date( Date.UTC(year, month, 1 + (i - before)) ),
+					selected = this.s.d ? this._compareDates(day, this.s.d) : false,
+					today    = this._compareDates(day, now),
+					empty    = i < before || i >= (days + before),
+					disabled = (minDate && day < minDate) ||
+					           (maxDate && day > maxDate);
+
+				var disableDays = this.c.disableDays;
+				if ( Array.isArray( disableDays ) && $.inArray( day.getUTCDay(), disableDays ) !== -1 ) {
+					disabled = true;
+				}
+				else if ( typeof disableDays === 'function' && disableDays( day ) === true ) {
+					disabled = true;
+				}
+
+				var dayConfig = {
+					day:      1 + (i - before),
+					month:    month,
+					year:     year,
+					selected: selected,
+					today:    today,
+					disabled: disabled,
+					empty:    empty
+				};
+
+				row.push( this._htmlDay(dayConfig) );
+
+				if ( ++r === 7 ) {
+					if ( this.c.showWeekNumber ) {
+						row.unshift( this._htmlWeekOfYear(i - before, month, year) );
+					}
+
+					data.push( '<tr>'+row.join('')+'</tr>' );
+					row = [];
+					r = 0;
+				}
+			}
+
+			var classPrefix = this.c.classPrefix;
+			var className = classPrefix+'-table';
+			if ( this.c.showWeekNumber ) {
+				className += ' weekNumber';
+			}
+
+			// Show / hide month icons based on min/max
+			if ( minDate ) {
+				var underMin = minDate >= new Date( Date.UTC(year, month, 1, 0, 0, 0 ) );
+
+				this.dom.title.find('div.'+classPrefix+'-iconLeft')
+					.css( 'display', underMin ? 'none' : 'block' );
+			}
+
+			if ( maxDate ) {
+				var overMax = maxDate < new Date( Date.UTC(year, month+1, 1, 0, 0, 0 ) );
+
+				this.dom.title.find('div.'+classPrefix+'-iconRight')
+					.css( 'display', overMax ? 'none' : 'block' );
+			}
+
+			return '<table class="'+className+'">' +
+					'<thead>'+
+						this._htmlMonthHead() +
+					'</thead>'+
+					'<tbody>'+
+						data.join('') +
+					'</tbody>'+
+				'</table>';
+		},
+
+		/**
+		 * Create the calendar table's header (week days)
+		 *
+		 * @return {string} HTML cells for the row
+		 * @private
+		 */
+		_htmlMonthHead: function () {
+			var a = [];
+			var firstDay = this.c.firstDay;
+			var i18n = this.c.i18n;
+
+			// Take account of the first day shift
+			var dayName = function ( day ) {
+				day += firstDay;
+
+				while (day >= 7) {
+					day -= 7;
+				}
+
+				return i18n.weekdays[day];
+			};
+			
+			// Empty cell in the header
+			if ( this.c.showWeekNumber ) {
+				a.push( '<th></th>' );
+			}
+
+			for ( var i=0 ; i<7 ; i++ ) {
+				a.push( '<th>'+dayName( i )+'</th>' );
+			}
+
+			return a.join('');
+		},
+
+		/**
+		 * Create a cell that contains week of the year - ISO8601
+		 *
+		 * Based on https://stackoverflow.com/questions/6117814/ and
+		 * http://techblog.procurios.nl/k/n618/news/view/33796/14863/
+		 *
+		 * @param  {integer} d Day of month
+		 * @param  {integer} m Month of year (zero index)
+		 * @param  {integer} y Year
+		 * @return {string}   
+		 * @private
+		 */
+		_htmlWeekOfYear: function ( d, m, y ) {
+			var date = new Date( y, m, d, 0, 0, 0, 0 );
+
+			// First week of the year always has 4th January in it
+			date.setDate( date.getDate() + 4 - (date.getDay() || 7) );
+
+			var oneJan = new Date( y, 0, 1 );
+			var weekNum = Math.ceil( ( ( (date - oneJan) / 86400000) + 1)/7 );
+
+			return '<td class="'+this.c.classPrefix+'-week">' + weekNum + '</td>';
+		},
+
+		/**
+		 * Create option elements from a range in an array
+		 *
+		 * @param  {string} selector Class name unique to the select element to use
+		 * @param  {array} values   Array of values
+		 * @param  {array} [labels] Array of labels. If given must be the same
+		 *   length as the values parameter.
+		 * @private
+		 */
+		_options: function ( selector, values, labels ) {
+			if ( ! labels ) {
+				labels = values;
+			}
+
+			var select = this.dom.container.find('select.'+this.c.classPrefix+'-'+selector);
+			select.empty();
+
+			for ( var i=0, ien=values.length ; i<ien ; i++ ) {
+				select.append( '<option value="'+values[i]+'">'+labels[i]+'</option>' );
+			}
+		},
+
+		/**
+		 * Set an option and update the option's span pair (since the select element
+		 * has opacity 0 for styling)
+		 *
+		 * @param  {string} selector Class name unique to the select element to use
+		 * @param  {*}      val      Value to set
+		 * @private
+		 */
+		_optionSet: function ( selector, val ) {
+			var select = this.dom.container.find('select.'+this.c.classPrefix+'-'+selector);
+			var span = select.parent().children('span');
+
+			select.val( val );
+
+			var selected = select.find('option:selected');
+			span.html( selected.length !== 0 ?
+				selected.text() :
+				this.c.i18n.unknown
+			);
+		},
+
+		/**
+		 * Create time options list.
+		 *
+		 * @param  {string} unit Time unit - hours, minutes or seconds
+		 * @param  {integer} count Count range - 12, 24 or 60
+		 * @param  {integer} val Existing value for this unit
+		 * @param  {integer[]} allowed Values allow for selection
+		 * @param  {integer} range Override range
+		 * @private
+		 */
+		_optionsTime: function ( unit, count, val, allowed, range ) {
+			var classPrefix = this.c.classPrefix;
+			var container = this.dom.container.find('div.'+classPrefix+'-'+unit);
+			var i, j;
+			var render = count === 12 ?
+				function (i) { return i; } :
+				this._pad;
+			var classPrefix = this.c.classPrefix;
+			var className = classPrefix+'-table';
+			var i18n = this.c.i18n;
+
+			if ( ! container.length ) {
+				return;
+			}
+
+			var a = '';
+			var span = 10;
+			var button = function (value, label, className) {
+				// Shift the value for PM
+				if ( count === 12 && typeof value === 'number' ) {
+					if (val >= 12 ) {
+						value += 12;
+					}
+
+					if (value == 12) {
+						value = 0;
+					}
+					else if (value == 24) {
+						value = 12;
+					}
+				}
+
+				var selected = val === value || (value === 'am' && val < 12) || (value === 'pm' && val >= 12) ?
+					'selected' :
+					'';
+				
+				if (allowed && $.inArray(value, allowed) === -1) {
+					selected += ' disabled';
+				}
+
+				if ( className ) {
+					selected += ' '+className;
+				}
+
+				return '<td class="selectable '+selected+'">' +
+					'<button class="'+classPrefix+'-button '+classPrefix+'-day" type="button" data-unit="'+unit+'" data-value="'+value+ '">' +
+						'<span>'+label+'</span>'+
+					'</button>' +
+				'</td>';
+			};
+
+			if ( count === 12 ) {
+				// Hours with AM/PM
+				a += '<tr>';
+				
+				for ( i=1 ; i<=6 ; i++ ) {
+					a += button(i, render(i));
+				}
+				a += button('am', i18n.amPm[0]);
+
+				a += '</tr>';
+				a += '<tr>';
+
+				for ( i=7 ; i<=12 ; i++ ) {
+					a += button(i, render(i));
+				}
+				a += button('pm', i18n.amPm[1]);
+				a += '</tr>';
+
+				span = 7;
+			}
+			else if ( count === 24 ) {
+				// Hours - 24
+				var c = 0;
+				for (j=0 ; j<4 ; j++ ) {
+					a += '<tr>';
+					for ( i=0 ; i<6 ; i++ ) {
+						a += button(c, render(c));
+						c++;
+					}
+					a += '</tr>';
+				}
+
+				span = 6;
+			}
+			else {
+				// Minutes and seconds
+				a += '<tr>';
+				for (j=0 ; j<60 ; j+=10 ) {
+					a += button(j, render(j), 'range');
+				}
+				a += '</tr>';
+				
+				// Slight hack to allow for the different number of columns
+				a += '</tbody></thead><table class="'+className+' '+className+'-nospace"><tbody>';
+
+				var start = range !== null ?
+					range :
+					Math.floor( val / 10 )*10;
+
+				a += '<tr>';
+				for (j=start+1 ; j<start+10 ; j++ ) {
+					a += button(j, render(j));
+				}
+				a += '</tr>';
+
+				span = 6;
+			}
+
+			container
+				.empty()
+				.append(
+					'<table class="'+className+'">'+
+						'<thead><tr><th colspan="'+span+'">'+
+							i18n[unit] +
+						'</th></tr></thead>'+
+						'<tbody>'+
+							a+
+						'</tbody>'+
+					'</table>'
+				);
+		},
+
+		/**
+		 * Create the options for the month and year
+		 *
+		 * @param  {integer} year  Year
+		 * @param  {integer} month Month (starting at 0)
+		 * @private
+		 */
+		_optionsTitle: function () {
+			var i18n = this.c.i18n;
+			var min = this.c.minDate;
+			var max = this.c.maxDate;
+			var minYear = min ? min.getFullYear() : null;
+			var maxYear = max ? max.getFullYear() : null;
+
+			var i = minYear !== null ? minYear : new Date().getFullYear() - this.c.yearRange;
+			var j = maxYear !== null ? maxYear : new Date().getFullYear() + this.c.yearRange;
+
+			this._options( 'month', this._range( 0, 11 ), i18n.months );
+			this._options( 'year', this._range( i, j ) );
+		},
+
+		/**
+		 * Simple two digit pad
+		 *
+		 * @param  {integer} i      Value that might need padding
+		 * @return {string|integer} Padded value
+		 * @private
+		 */
+		_pad: function ( i ) {
+			return i<10 ? '0'+i : i;
+		},
+
+		/**
+		 * Position the calendar to look attached to the input element
+		 * @private
+		 */
+		_position: function () {
+			var offset = this.c.attachTo === 'input' ? this.dom.input.position() : this.dom.input.offset();
+			var container = this.dom.container;
+			var inputHeight = this.dom.input.outerHeight();
+
+			if (container.hasClass('inline')) {
+				container.insertAfter( this.dom.input );
+				return;
+			}
+
+			if ( this.s.parts.date && this.s.parts.time && $(window).width() > 550 ) {
+				container.addClass('horizontal');
+			}
+			else {
+				container.removeClass('horizontal');
+			}
+
+			if(this.c.attachTo === 'input') {
+				container
+					.css( {
+						top: offset.top + inputHeight,
+						left: offset.left
+					} )
+					.insertAfter( this.dom.input );
+			}
+			else {
+				container
+					.css( {
+						top: offset.top + inputHeight,
+						left: offset.left
+					} )
+					.appendTo( 'body' );
+			}
+
+			var calHeight = container.outerHeight();
+			var calWidth = container.outerWidth();
+			var scrollTop = $(window).scrollTop();
+
+			// Correct to the bottom
+			if ( offset.top + inputHeight + calHeight - scrollTop > $(window).height() ) {
+				var newTop = offset.top - calHeight;
+
+				container.css( 'top', newTop < 0 ? 0 : newTop );
+			}
+
+			// Correct to the right
+			if ( calWidth + offset.left > $(window).width() ) {
+				var newLeft = $(window).width() - calWidth;
+
+				// Account for elements which are inside a position absolute element
+				if (this.c.attachTo === 'input') {
+					newLeft -= $(container).offsetParent().offset().left;
+				}
+
+				container.css( 'left', newLeft < 0 ? 0 : newLeft );
+			}
+		},
+
+		/**
+		 * Create a simple array with a range of values
+		 *
+		 * @param  {integer} start   Start value (inclusive)
+		 * @param  {integer} end     End value (inclusive)
+		 * @param  {integer} [inc=1] Increment value
+		 * @return {array}           Created array
+		 * @private
+		 */
+		_range: function ( start, end, inc ) {
+			var a = [];
+
+			if ( ! inc ) {
+				inc = 1;
+			}
+
+			for ( var i=start ; i<=end ; i+=inc ) {
+				a.push( i );
+			}
+
+			return a;
+		},
+
+		/**
+		 * Redraw the calendar based on the display date - this is a destructive
+		 * operation
+		 *
+		 * @private
+		 */
+		_setCalander: function () {
+			if ( this.s.display ) {
+				this.dom.calendar
+					.empty()
+					.append( this._htmlMonth(
+						this.s.display.getUTCFullYear(),
+						this.s.display.getUTCMonth()
+					) );
+			}
+		},
+
+		/**
+		 * Set the month and year for the calendar based on the current display date
+		 *
+		 * @private
+		 */
+		_setTitle: function () {
+			this._optionSet( 'month', this.s.display.getUTCMonth() );
+			this._optionSet( 'year', this.s.display.getUTCFullYear() );
+		},
+
+		/**
+		 * Set the time based on the current value of the widget
+		 *
+		 * @private
+		 */
+		_setTime: function () {
+			var that = this;
+			var d = this.s.d;
+			var hours = d ? d.getUTCHours() : 0;
+			var allowed = function ( prop ) { // Backwards compt with `Increment` option
+				return that.c[prop+'Available'] ?
+					that.c[prop+'Available'] :
+					that._range( 0, 59, that.c[prop+'Increment'] );
+			};
+
+			this._optionsTime( 'hours', this.s.parts.hours12 ? 12 : 24, hours, this.c.hoursAvailable );
+			this._optionsTime( 'minutes', 60, d ? d.getUTCMinutes() : 0, allowed('minutes'), this.s.minutesRange );
+			this._optionsTime( 'seconds', 60, d ? d.getSeconds() : 0, allowed('seconds'), this.s.secondsRange );
+		},
+
+		/**
+		 * Show the widget and add events to the document required only while it
+		 * is displayed
+		 * 
+		 * @private
+		 */
+		_show: function () {
+			var that = this;
+			var namespace = this.s.namespace;
+
+			this._position();
+
+			// Need to reposition on scroll
+			$(window).on( 'scroll.'+namespace+' resize.'+namespace, function () {
+				that._hide();
+			} );
+
+			$('div.DTE_Body_Content').on( 'scroll.'+namespace, function () {
+				that._hide();
+			} );
+
+			$('div.dataTables_scrollBody').on( 'scroll.'+namespace, function () {
+				that._hide();
+			} );
+
+			var offsetParent = this.dom.input[0].offsetParent;
+
+			if ( offsetParent !== document.body ) {
+				$(offsetParent).on( 'scroll.'+namespace, function () {
+					that._hide();
+				} );
+			}
+
+			// On tab focus will move to a different field (no keyboard navigation
+			// in the date picker - this might need to be changed).
+			$(document).on( 'keydown.'+namespace, function (e) {
+				if (
+					e.keyCode === 9  || // tab
+					e.keyCode === 27 || // esc
+					e.keyCode === 13    // return
+				) {
+					that._hide();
+				}
+			} );
+
+			// Hide if clicking outside of the widget - but in a different click
+			// event from the one that was used to trigger the show (bubble and
+			// inline)
+			setTimeout( function () {
+				$('body').on( 'click.'+namespace, function (e) {
+					var parents = $(e.target).parents();
+
+					if ( ! parents.filter( that.dom.container ).length && e.target !== that.dom.input[0] ) {
+						that._hide();
+					}
+				} );
+			}, 10 );
+		},
+
+		/**
+		 * Write the formatted string to the input element this control is attached
+		 * to
+		 *
+		 * @private
+		 */
+		_writeOutput: function ( focus ) {
+			var date = this.s.d;
+
+			// Use moment or dayjs if possible - otherwise it must be ISO8601 (or the
+			// constructor would have thrown an error)
+			var out = dateLib ?
+				dateLib.utc( date, undefined$1, this.c.locale, this.c.strict ).format( this.c.format ) :
+				date.getUTCFullYear() +'-'+
+					this._pad(date.getUTCMonth() + 1) +'-'+
+					this._pad(date.getUTCDate());
+
+				this.dom.input
+					.val( out )
+					.trigger('change', {write: date});
+			
+			if ( this.dom.input.attr('type') === 'hidden' ) {
+				this.val(out, false);
+			}
+
+			if ( focus ) {
+				this.dom.input.focus();
+			}
+		}
+	} );
+
+	/**
+	 * Use a specificmoment compatible date library
+	 */
+	DateTime.use = function (lib) {
+		dateLib = lib;
+	};
+
+	/**
+	 * For generating unique namespaces
+	 *
+	 * @type {Number}
+	 * @private
+	 */
+	DateTime._instance = 0;
+
+	/**
+	 * Defaults for the date time picker
+	 *
+	 * @type {Object}
+	 */
+	DateTime.defaults = {
+		attachTo: 'body',
+
+		// Not documented - could be an internal property
+		classPrefix: 'dt-datetime',
+
+		// function or array of ints
+		disableDays: null,
+
+		// first day of the week (0: Sunday, 1: Monday, etc)
+		firstDay: 1,
+
+		format: 'YYYY-MM-DD',
+
+		hoursAvailable: null,
+
+		i18n: {
+			previous: 'Previous',
+			next:     'Next',
+			months:   [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
+			weekdays: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
+			amPm:     [ 'am', 'pm' ],
+			hours:    'Hour',
+			minutes:  'Minute',
+			seconds:  'Second',
+			unknown:  '-'
+		},
+
+		maxDate: null,
+
+		minDate: null,
+
+		minutesAvailable: null,
+
+		minutesIncrement: 1, // deprecated
+
+		strict: true,
+
+		locale: 'en',
+
+		onChange: function () {},
+
+		secondsAvailable: null,
+
+		secondsIncrement: 1, // deprecated
+
+		// show the ISO week number at the head of the row
+		showWeekNumber: false,
+
+		// overruled by max / min date
+		yearRange: 25
+	};
+
+	DateTime.version = '1.0.1';
+
+	// Global export - if no conflicts
+	if (! window.DateTime) {
+		window.DateTime = DateTime;
+	}
+
+	// Make available via jQuery
+	$.fn.dtDateTime = function (options) {
+		return this.each(function() {
+			new DateTime(this, options);
+		});
+	};
+
+	// Attach to DataTables if present
+	if ($.fn.dataTable) {
+		$.fn.dataTable.DateTime = DateTime;
+		$.fn.DataTable.DateTime = DateTime;
+	}
+
+	return DateTime;
+
+	}));
+
+	var $;
+	var DataTable;
+	var moment = window.moment;
+	/**
+	 * Sets the value of jQuery for use in the file
+	 * @param jq the instance of jQuery to be set
+	 */
+	function setJQuery(jq) {
+	    $ = jq;
+	    DataTable = jq.fn.dataTable;
+	}
+	/**
+	 * The Criteria class is used within SearchBuilder to represent a search criteria
+	 */
+	var Criteria = /** @class */ (function () {
+	    function Criteria(table, opts, topGroup, index, depth) {
+	        var _this = this;
+	        if (index === void 0) { index = 0; }
+	        if (depth === void 0) { depth = 1; }
+	        // Check that the required version of DataTables is included
+	        if (!DataTable || !DataTable.versionCheck || !DataTable.versionCheck('1.10.0')) {
+	            throw new Error('SearchPane requires DataTables 1.10 or newer');
+	        }
+	        this.classes = $.extend(true, {}, Criteria.classes);
+	        // Get options from user and any extra conditions/column types defined by plug-ins
+	        this.c = $.extend(true, {}, Criteria.defaults, $.fn.dataTable.ext.searchBuilder, opts);
+	        var i18n = this.c.i18n;
+	        this.s = {
+	            condition: undefined,
+	            conditions: {},
+	            data: undefined,
+	            dataIdx: -1,
+	            dataPoints: [],
+	            depth: depth,
+	            dt: table,
+	            filled: false,
+	            index: index,
+	            momentFormat: false,
+	            topGroup: topGroup,
+	            type: '',
+	            value: []
+	        };
+	        this.dom = {
+	            buttons: $('<div/>')
+	                .addClass(this.classes.buttonContainer),
+	            condition: $('<select disabled/>')
+	                .addClass(this.classes.condition)
+	                .addClass(this.classes.dropDown)
+	                .addClass(this.classes.italic)
+	                .attr('autocomplete', 'hacking'),
+	            conditionTitle: $('<option value="" disabled selected hidden/>')
+	                .text(this.s.dt.i18n('searchBuilder.condition', i18n.condition)),
+	            container: $('<div/>')
+	                .addClass(this.classes.container),
+	            data: $('<select/>')
+	                .addClass(this.classes.data)
+	                .addClass(this.classes.dropDown)
+	                .addClass(this.classes.italic),
+	            dataTitle: $('<option value="" disabled selected hidden/>')
+	                .text(this.s.dt.i18n('searchBuilder.data', i18n.data)),
+	            defaultValue: $('<select disabled/>')
+	                .addClass(this.classes.value)
+	                .addClass(this.classes.dropDown),
+	            "delete": $('<button>&times</button>')
+	                .addClass(this.classes["delete"])
+	                .addClass(this.classes.button)
+	                .attr('title', this.s.dt.i18n('searchBuilder.deleteTitle', i18n.deleteTitle))
+	                .attr('type', 'button'),
+	            left: $('<button>\<</button>')
+	                .addClass(this.classes.left)
+	                .addClass(this.classes.button)
+	                .attr('title', this.s.dt.i18n('searchBuilder.leftTitle', i18n.leftTitle))
+	                .attr('type', 'button'),
+	            right: $('<button>\></button>')
+	                .addClass(this.classes.right)
+	                .addClass(this.classes.button)
+	                .attr('title', this.s.dt.i18n('searchBuilder.rightTitle', i18n.rightTitle))
+	                .attr('type', 'button'),
+	            value: [
+	                $('<select disabled/>').addClass(this.classes.value).addClass(this.classes.dropDown).addClass(this.classes.italic)
+	            ],
+	            valueTitle: $('<option value="--valueTitle--" selected/>').text(this.s.dt.i18n('searchBuilder.value', i18n.value))
+	        };
+	        // If the greyscale option is selected then add the class to add the grey colour to SearchBuilder
+	        if (this.c.greyscale) {
+	            $(this.dom.data).addClass(this.classes.greyscale);
+	            $(this.dom.condition).addClass(this.classes.greyscale);
+	            $(this.dom.defaultValue).addClass(this.classes.greyscale);
+	            for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
+	                var val = _a[_i];
+	                $(val).addClass(this.classes.greyscale);
+	            }
+	        }
+	        // For responsive design, adjust the criterias properties on the following events
+	        this.s.dt.on('draw.dtsp', function () {
+	            _this._adjustCriteria();
+	        });
+	        this.s.dt.on('buttons-action', function () {
+	            _this._adjustCriteria();
+	        });
+	        $(window).on('resize.dtsp', DataTable.util.throttle(function () {
+	            _this._adjustCriteria();
+	        }));
+	        this._buildCriteria();
+	        return this;
+	    }
+	    /**
+	     * Adds the left button to the criteria
+	     */
+	    Criteria.prototype.updateArrows = function (hasSiblings, redraw) {
+	        if (hasSiblings === void 0) { hasSiblings = false; }
+	        if (redraw === void 0) { redraw = true; }
+	        // Empty the container and append all of the elements in the correct order
+	        $(this.dom.container)
+	            .empty()
+	            .append(this.dom.data)
+	            .append(this.dom.condition)
+	            .append(this.dom.value[0]);
+	        // Trigger the inserted events for the value elements as they are inserted
+	        $(this.dom.value[0]).trigger('dtsb-inserted');
+	        for (var i = 1; i < this.dom.value.length; i++) {
+	            $(this.dom.container).append(this.dom.value[i]);
+	            $(this.dom.value[i]).trigger('dtsb-inserted');
+	        }
+	        // If this is a top level criteria then don't let it move left
+	        if (this.s.depth > 1) {
+	            $(this.dom.buttons).append(this.dom.left);
+	        }
+	        // If the depthLimit of the query has been hit then don't add the right button
+	        if ((this.c.depthLimit === false || this.s.depth < this.c.depthLimit) && hasSiblings) {
+	            $(this.dom.buttons).append(this.dom.right);
+	        }
+	        else {
+	            $(this.dom.right).remove();
+	        }
+	        $(this.dom.buttons).append(this.dom["delete"]);
+	        $(this.dom.container).append(this.dom.buttons);
+	        if (redraw) {
+	            // A different combination of arrows and selectors may lead to a need for responsive to be triggered
+	            this._adjustCriteria();
+	        }
+	    };
+	    /**
+	     * Destroys the criteria, removing listeners and container from the dom
+	     */
+	    Criteria.prototype.destroy = function () {
+	        // Turn off listeners
+	        $(this.dom.data).off('.dtsb');
+	        $(this.dom.condition).off('.dtsb');
+	        $(this.dom["delete"]).off('.dtsb');
+	        for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
+	            var val = _a[_i];
+	            $(val).off('.dtsb');
+	        }
+	        // Remove container from the dom
+	        $(this.dom.container).remove();
+	    };
+	    /**
+	     * Passes in the data for the row and compares it against this single criteria
+	     * @param rowData The data for the row to be compared
+	     * @returns boolean Whether the criteria has passed
+	     */
+	    Criteria.prototype.search = function (rowData, rowIdx) {
+	        var condition = this.s.conditions[this.s.condition];
+	        if (this.s.condition !== undefined && condition !== undefined) {
+	            // This check is in place for if a custom decimal character is in place
+	            if (this.s.type.indexOf('num') !== -1 && this.s.dt.settings()[0].oLanguage.sDecimal !== '') {
+	                rowData[this.s.dataIdx] = rowData[this.s.dataIdx].replace(this.s.dt.settings()[0].oLanguage.sDecimal, '.');
+	            }
+	            var filter = rowData[this.s.dataIdx];
+	            // If orthogonal data is in place we need to get it's values for searching
+	            if (this.c.orthogonal.search !== 'search') {
+	                var settings = this.s.dt.settings()[0];
+	                filter = settings.oApi._fnGetCellData(settings, rowIdx, this.s.dataIdx, typeof this.c.orthogonal === 'string' ?
+	                    this.c.orthogonal :
+	                    this.c.orthogonal.search);
+	            }
+	            if (this.s.type === 'array') {
+	                // Make sure we are working with an array
+	                if (!Array.isArray(filter)) {
+	                    filter = [filter];
+	                }
+	                filter.sort();
+	            }
+	            return condition.search(filter, this.s.value, this);
+	        }
+	    };
+	    /**
+	     * Gets the details required to rebuild the criteria
+	     */
+	    Criteria.prototype.getDetails = function () {
+	        var value = this.s.value;
+	        // This check is in place for if a custom decimal character is in place
+	        if (this.s.type.indexOf('num') !== -1 && this.s.dt.settings()[0].oLanguage.sDecimal !== '') {
+	            for (var i = 0; i < this.s.value.length; i++) {
+	                if (this.s.value[i].indexOf('.') !== -1) {
+	                    value[i] = this.s.value[i].replace('.', this.s.dt.settings()[0].oLanguage.sDecimal);
+	                }
+	            }
+	        }
+	        return {
+	            condition: this.s.condition,
+	            data: this.s.data,
+	            value: value
+	        };
+	    };
+	    /**
+	     * Getter for the node for the container of the criteria
+	     * @returns JQuery<HTMLElement> the node for the container
+	     */
+	    Criteria.prototype.getNode = function () {
+	        return this.dom.container;
+	    };
+	    /**
+	     * Populates the criteria data, condition and value(s) as far as has been selected
+	     */
+	    Criteria.prototype.populate = function () {
+	        this._populateData();
+	        // If the column index has been found attempt to select a condition
+	        if (this.s.dataIdx !== -1) {
+	            this._populateCondition();
+	            // If the condittion has been found attempt to select the values
+	            if (this.s.condition !== undefined) {
+	                this._populateValue();
+	            }
+	        }
+	    };
+	    /**
+	     * Rebuilds the criteria based upon the details passed in
+	     * @param loadedCriteria the details required to rebuild the criteria
+	     */
+	    Criteria.prototype.rebuild = function (loadedCriteria) {
+	        // Check to see if the previously selected data exists, if so select it
+	        var foundData = false;
+	        var dataIdx;
+	        this._populateData();
+	        // If a data selection has previously been made attempt to find and select it
+	        if (loadedCriteria.data !== undefined) {
+	            var italic_1 = this.classes.italic;
+	            var data_1 = this.dom.data;
+	            $(this.dom.data).children('option').each(function () {
+	                if ($(this).text() === loadedCriteria.data) {
+	                    $(this).attr('selected', true);
+	                    $(data_1).removeClass(italic_1);
+	                    foundData = true;
+	                    dataIdx = $(this).val();
+	                }
+	            });
+	        }
+	        // If the data has been found and selected then the condition can be populated and searched
+	        if (foundData) {
+	            this.s.data = loadedCriteria.data;
+	            this.s.dataIdx = dataIdx;
+	            $(this.dom.dataTitle).remove();
+	            this._populateCondition();
+	            $(this.dom.conditionTitle).remove();
+	            var condition_1;
+	            // Check to see if the previously selected condition exists, if so select it
+	            $(this.dom.condition).children('option').each(function () {
+	                if ((loadedCriteria.condition !== undefined &&
+	                    $(this).val() === loadedCriteria.condition &&
+	                    typeof loadedCriteria.condition === 'string')) {
+	                    $(this).attr('selected', true);
+	                    condition_1 = $(this).val();
+	                }
+	            });
+	            this.s.condition = condition_1;
+	            // If the condition has been found and selected then the value can be populated and searched
+	            if (this.s.condition !== undefined) {
+	                $(this.dom.conditionTitle).remove();
+	                $(this.dom.condition).removeClass(this.classes.italic);
+	                this._populateValue(loadedCriteria);
+	            }
+	            else {
+	                $(this.dom.conditionTitle).prependTo(this.dom.condition).attr('selected', true);
+	            }
+	        }
+	    };
+	    /**
+	     * Sets the listeners for the criteria
+	     */
+	    Criteria.prototype.setListeners = function () {
+	        var _this = this;
+	        $(this.dom.data)
+	            .unbind('input change')
+	            .on('input change', function () {
+	            $(_this.dom.dataTitle).attr('selected', false);
+	            $(_this.dom.data).removeClass(_this.classes.italic);
+	            _this.s.dataIdx = $(_this.dom.data).children('option:selected').val();
+	            _this.s.data = $(_this.dom.data).children('option:selected').text();
+	            _this.c.orthogonal = _this._getOptions().orthogonal;
+	            // When the data is changed, the values in condition and value may also change so need to renew them
+	            _this._clearCondition();
+	            _this._clearValue();
+	            _this._populateCondition();
+	            // If this criteria was previously active in the search then remove it from the search and trigger a new search
+	            if (_this.s.filled) {
+	                _this.s.filled = false;
+	                _this.s.dt.draw();
+	                _this.setListeners();
+	            }
+	            _this.s.dt.state.save();
+	        });
+	        $(this.dom.condition)
+	            .unbind('input change')
+	            .on('input change', function () {
+	            $(_this.dom.conditionTitle).attr('selected', false);
+	            $(_this.dom.condition).removeClass(_this.classes.italic);
+	            var condDisp = $(_this.dom.condition).children('option:selected').val();
+	            // Find the condition that has been selected and store it internally
+	            for (var _i = 0, _a = Object.keys(_this.s.conditions); _i < _a.length; _i++) {
+	                var cond = _a[_i];
+	                if (cond === condDisp) {
+	                    _this.s.condition = condDisp;
+	                    break;
+	                }
+	            }
+	            // When the condition is changed, the value selector may switch between a select element and an input element
+	            _this._clearValue();
+	            _this._populateValue();
+	            for (var _b = 0, _c = _this.dom.value; _b < _c.length; _b++) {
+	                var val = _c[_b];
+	                // If this criteria was previously active in the search then remove it from the search and trigger a new search
+	                if (_this.s.filled && $(_this.dom.container).has(val).length !== 0) {
+	                    _this.s.filled = false;
+	                    _this.s.dt.draw();
+	                    _this.setListeners();
+	                }
+	            }
+	            _this.s.dt.draw();
+	        });
+	    };
+	    /**
+	     * Adjusts the criteria to make SearchBuilder responsive
+	     */
+	    Criteria.prototype._adjustCriteria = function () {
+	        // If this criteria is not present then don't bother adjusting it
+	        if ($(document).has(this.dom.container).length === 0) {
+	            return;
+	        }
+	        var valRight;
+	        var valWidth;
+	        var outmostval = this.dom.value[this.dom.value.length - 1];
+	        // Calculate the width and right value of the outmost value element
+	        if ($(this.dom.container).has(outmostval).length !== 0) {
+	            valWidth = $(outmostval).outerWidth(true);
+	            valRight = $(outmostval).offset().left + valWidth;
+	        }
+	        else {
+	            return;
+	        }
+	        var leftOffset = $(this.dom.left).offset();
+	        var rightOffset = $(this.dom.right).offset();
+	        var clearOffset = $(this.dom["delete"]).offset();
+	        var hasLeft = $(this.dom.container).has(this.dom.left).length !== 0;
+	        var hasRight = $(this.dom.container).has(this.dom.right).length !== 0;
+	        var buttonsLeft = hasLeft ?
+	            leftOffset.left :
+	            hasRight ?
+	                rightOffset.left :
+	                clearOffset.left;
+	        // Perform the responsive calculations and redraw where necessary
+	        if (buttonsLeft - valRight < 15 ||
+	            (hasLeft && leftOffset.top !== clearOffset.top) ||
+	            (hasRight && rightOffset.top !== clearOffset.top)) {
+	            $(this.dom.container).parent().addClass(this.classes.vertical);
+	            $(this.s.topGroup).trigger('dtsb-redrawContents');
+	        }
+	        else if (buttonsLeft -
+	            ($(this.dom.data).offset().left +
+	                $(this.dom.data).outerWidth(true) +
+	                $(this.dom.condition).outerWidth(true) +
+	                valWidth) > 15) {
+	            $(this.dom.container).parent().removeClass(this.classes.vertical);
+	            $(this.s.topGroup).trigger('dtsb-redrawContents');
+	        }
+	    };
+	    /**
+	     * Builds the elements of the dom together
+	     */
+	    Criteria.prototype._buildCriteria = function () {
+	        // Append Titles for select elements
+	        $(this.dom.data).append(this.dom.dataTitle);
+	        $(this.dom.condition).append(this.dom.conditionTitle);
+	        // Add elements to container
+	        $(this.dom.container)
+	            .append(this.dom.data)
+	            .append(this.dom.condition);
+	        for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
+	            var val = _a[_i];
+	            $(val).append(this.dom.valueTitle);
+	            $(this.dom.container).append(val);
+	        }
+	        // Add buttons to container
+	        $(this.dom.container)
+	            .append(this.dom["delete"])
+	            .append(this.dom.right);
+	        this.setListeners();
+	    };
+	    /**
+	     * Clears the condition select element
+	     */
+	    Criteria.prototype._clearCondition = function () {
+	        $(this.dom.condition).empty();
+	        $(this.dom.conditionTitle).attr('selected', true).attr('disabled', true);
+	        $(this.dom.condition).prepend(this.dom.conditionTitle).prop('selectedIndex', 0);
+	        this.s.conditions = {};
+	        this.s.condition = undefined;
+	    };
+	    /**
+	     * Clears the value elements
+	     */
+	    Criteria.prototype._clearValue = function () {
+	        if (this.s.condition !== undefined) {
+	            // Remove all of the value elements
+	            for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
+	                var val = _a[_i];
+	                $(val).remove();
+	            }
+	            // Call the init function to get the value elements for this condition
+	            this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener));
+	            $(this.dom.value[0]).insertAfter(this.dom.condition).trigger('dtsb-inserted');
+	            // Insert all of the value elements
+	            for (var i = 1; i < this.dom.value.length; i++) {
+	                $(this.dom.value[i]).insertAfter(this.dom.value[i - 1]).trigger('dtsb-inserted');
+	            }
+	        }
+	        else {
+	            // Remove all of the value elements
+	            for (var _b = 0, _c = this.dom.value; _b < _c.length; _b++) {
+	                var val = _c[_b];
+	                $(val).remove();
+	            }
+	            // Append the default valueTitle to the default select element
+	            $(this.dom.valueTitle)
+	                .attr('selected', true);
+	            $(this.dom.defaultValue)
+	                .append(this.dom.valueTitle)
+	                .insertAfter(this.dom.condition);
+	        }
+	        this.s.value = [];
+	    };
+	    /**
+	     * Gets the options for the column
+	     * @returns {object} The options for the column
+	     */
+	    Criteria.prototype._getOptions = function () {
+	        var table = this.s.dt;
+	        return $.extend(true, {}, Criteria.defaults, table.settings()[0].aoColumns[this.s.dataIdx].searchBuilder);
+	    };
+	    /**
+	     * Populates the condition dropdown
+	     */
+	    Criteria.prototype._populateCondition = function () {
+	        var conditionOpts = [];
+	        var conditionsLength = Object.keys(this.s.conditions).length;
+	        // If there are no conditions stored then we need to get them from the appropriate type
+	        if (conditionsLength === 0) {
+	            var column = $(this.dom.data).children('option:selected').val();
+	            this.s.type = this.s.dt.columns().type().toArray()[column];
+	            // If the column type is unknown, call a draw to try reading it again
+	            if (this.s.type === null) {
+	                this.s.dt.draw();
+	                this.setListeners();
+	                this.s.type = this.s.dt.columns().type().toArray()[column];
+	            }
+	            // Enable the condition element
+	            $(this.dom.condition)
+	                .attr('disabled', false)
+	                .empty()
+	                .append(this.dom.conditionTitle)
+	                .addClass(this.classes.italic);
+	            $(this.dom.conditionTitle)
+	                .attr('selected', true);
+	            var decimal = this.s.dt.settings()[0].oLanguage.sDecimal;
+	            // This check is in place for if a custom decimal character is in place
+	            if (decimal !== '' && this.s.type.indexOf(decimal) === this.s.type.length - decimal.length) {
+	                if (this.s.type.indexOf('num-fmt') !== -1) {
+	                    this.s.type = this.s.type.replace(decimal, '');
+	                }
+	                else if (this.s.type.indexOf('num') !== -1) {
+	                    this.s.type = this.s.type.replace(decimal, '');
+	                }
+	            }
+	            // Select which conditions are going to be used based on the column type
+	            var conditionObj = this.c.conditions[this.s.type] !== undefined ?
+	                this.c.conditions[this.s.type] :
+	                this.s.type.indexOf('moment') !== -1 ?
+	                    this.c.conditions.moment :
+	                    this.c.conditions.string;
+	            // If it is a moment format then extract the date format
+	            if (this.s.type.indexOf('moment') !== -1) {
+	                this.s.momentFormat = this.s.type.replace(/moment\-/g, '');
+	            }
+	            // Add all of the conditions to the select element
+	            for (var _i = 0, _a = Object.keys(conditionObj); _i < _a.length; _i++) {
+	                var condition = _a[_i];
+	                if (conditionObj[condition] !== null) {
+	                    this.s.conditions[condition] = conditionObj[condition];
+	                    var condName = conditionObj[condition].conditionName;
+	                    if (typeof condName === 'function') {
+	                        condName = condName(this.s.dt, this.c.i18n);
+	                    }
+	                    conditionOpts.push($('<option>', {
+	                        text: condName,
+	                        value: condition
+	                    })
+	                        .addClass(this.classes.option)
+	                        .addClass(this.classes.notItalic));
+	                }
+	            }
+	        }
+	        // Otherwise we can just load them in
+	        else if (conditionsLength > 0) {
+	            $(this.dom.condition).empty().attr('disabled', false).addClass(this.classes.italic);
+	            for (var _b = 0, _c = Object.keys(this.s.conditions); _b < _c.length; _b++) {
+	                var condition = _c[_b];
+	                var condName = this.s.conditions[condition].conditionName;
+	                if (typeof condName === 'function') {
+	                    condName = condName(this.s.dt, this.c.i18n);
+	                }
+	                var newOpt = $('<option>', {
+	                    text: condName,
+	                    value: condition
+	                })
+	                    .addClass(this.classes.option)
+	                    .addClass(this.classes.notItalic);
+	                if (this.s.condition !== undefined && this.s.condition === condName) {
+	                    $(newOpt).attr('selected', true);
+	                    $(this.dom.condition).removeClass(this.classes.italic);
+	                }
+	                conditionOpts.push(newOpt);
+	            }
+	        }
+	        else {
+	            $(this.dom.condition)
+	                .attr('disabled', true)
+	                .addClass(this.classes.italic);
+	            return;
+	        }
+	        for (var _d = 0, conditionOpts_1 = conditionOpts; _d < conditionOpts_1.length; _d++) {
+	            var opt = conditionOpts_1[_d];
+	            $(this.dom.condition).append(opt);
+	        }
+	        $(this.dom.condition).prop('selectedIndex', 0);
+	    };
+	    /**
+	     * Populates the data select element
+	     */
+	    Criteria.prototype._populateData = function () {
+	        var _this = this;
+	        $(this.dom.data).empty().append(this.dom.dataTitle);
+	        // If there are no datas stored then we need to get them from the table
+	        if (this.s.dataPoints.length === 0) {
+	            this.s.dt.columns().every(function (index) {
+	                // Need to check that the column can be filtered on before adding it
+	                if (_this.c.columns === true ||
+	                    (_this.s.dt.columns(_this.c.columns).indexes().toArray().indexOf(index) !== -1)) {
+	                    var found = false;
+	                    for (var _i = 0, _a = _this.s.dataPoints; _i < _a.length; _i++) {
+	                        var val = _a[_i];
+	                        if (val.index === index) {
+	                            found = true;
+	                            break;
+	                        }
+	                    }
+	                    if (!found) {
+	                        var opt = { text: _this.s.dt.settings()[0].aoColumns[index].sTitle, index: index };
+	                        _this.s.dataPoints.push(opt);
+	                        $(_this.dom.data).append($('<option>', {
+	                            text: opt.text,
+	                            value: opt.index
+	                        })
+	                            .addClass(_this.classes.option)
+	                            .addClass(_this.classes.notItalic));
+	                    }
+	                }
+	            });
+	        }
+	        // Otherwise we can just load them in
+	        else {
+	            var _loop_1 = function (data) {
+	                this_1.s.dt.columns().every(function (index) {
+	                    if (_this.s.dt.settings()[0].aoColumns[index].sTitle === data.text) {
+	                        data.index = index;
+	                    }
+	                });
+	                var newOpt = $('<option>', {
+	                    text: data.text,
+	                    value: data.index
+	                })
+	                    .addClass(this_1.classes.option)
+	                    .addClass(this_1.classes.notItalic);
+	                if (this_1.s.data === data.text) {
+	                    this_1.s.dataIdx = data.index;
+	                    $(newOpt).attr('selected', true);
+	                    $(this_1.dom.data).removeClass(this_1.classes.italic);
+	                }
+	                $(this_1.dom.data).append(newOpt);
+	            };
+	            var this_1 = this;
+	            for (var _i = 0, _a = this.s.dataPoints; _i < _a.length; _i++) {
+	                var data = _a[_i];
+	                _loop_1(data);
+	            }
+	        }
+	    };
+	    /**
+	     * Populates the Value select element
+	     * @param loadedCriteria optional, used to reload criteria from predefined filters
+	     */
+	    Criteria.prototype._populateValue = function (loadedCriteria) {
+	        var _this = this;
+	        var prevFilled = this.s.filled;
+	        this.s.filled = false;
+	        // Remove any previous value elements
+	        $(this.dom.defaultValue).remove();
+	        for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
+	            var val = _a[_i];
+	            $(val).remove();
+	        }
+	        var children = $(this.dom.container).children();
+	        if (children.length > 3) {
+	            for (var i = 2; i < children.length - 1; i++) {
+	                $(children[i]).remove();
+	            }
+	        }
+	        // Find the column with the title matching the data for the criteria and take note of the index
+	        if (loadedCriteria !== undefined) {
+	            this.s.dt.columns().every(function (index) {
+	                if (_this.s.dt.settings()[0].aoColumns[index].sTitle === loadedCriteria.data) {
+	                    _this.s.dataIdx = index;
+	                }
+	            });
+	        }
+	        // Initialise the value elements based on the condition
+	        this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener, loadedCriteria !== undefined ? loadedCriteria.value : undefined));
+	        if (loadedCriteria !== undefined && loadedCriteria.value !== undefined) {
+	            this.s.value = loadedCriteria.value;
+	        }
+	        // Insert value elements and trigger the inserted event
+	        $(this.dom.value[0])
+	            .insertAfter(this.dom.condition)
+	            .trigger('dtsb-inserted');
+	        for (var i = 1; i < this.dom.value.length; i++) {
+	            $(this.dom.value[i])
+	                .insertAfter(this.dom.value[i - 1])
+	                .trigger('dtsb-inserted');
+	        }
+	        // Check if the criteria can be used in a search
+	        this.s.filled = this.s.conditions[this.s.condition].isInputValid(this.dom.value, this);
+	        this.setListeners();
+	        // If it can and this is different to before then trigger a draw
+	        if (prevFilled !== this.s.filled) {
+	            this.s.dt.draw();
+	            this.setListeners();
+	        }
+	    };
+	    Criteria.version = '1.0.0';
+	    Criteria.classes = {
+	        button: 'dtsb-button',
+	        buttonContainer: 'dtsb-buttonContainer',
+	        condition: 'dtsb-condition',
+	        container: 'dtsb-criteria',
+	        data: 'dtsb-data',
+	        "delete": 'dtsb-delete',
+	        dropDown: 'dtsb-dropDown',
+	        greyscale: 'dtsb-greyscale',
+	        input: 'dtsb-input',
+	        italic: 'dtsb-italic',
+	        joiner: 'dtsp-joiner',
+	        left: 'dtsb-left',
+	        notItalic: 'dtsb-notItalic',
+	        option: 'dtsb-option',
+	        right: 'dtsb-right',
+	        value: 'dtsb-value',
+	        vertical: 'dtsb-vertical'
+	    };
+	    /**
+	     * Default initialisation function for select conditions
+	     */
+	    Criteria.initSelect = function (that, fn, preDefined, array) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        if (array === void 0) { array = false; }
+	        var column = $(that.dom.data).children('option:selected').val();
+	        var indexArray = that.s.dt.rows().indexes().toArray();
+	        var settings = that.s.dt.settings()[0];
+	        // Declare select element to be used with all of the default classes and listeners.
+	        var el = $('<select/>')
+	            .addClass(Criteria.classes.value)
+	            .addClass(Criteria.classes.dropDown)
+	            .addClass(Criteria.classes.italic)
+	            .append(that.dom.valueTitle)
+	            .on('input change', function () {
+	            $(this).removeClass(Criteria.classes.italic);
+	            fn(that, this);
+	        });
+	        if (that.c.greyscale) {
+	            $(el).addClass(Criteria.classes.greyscale);
+	        }
+	        var added = [];
+	        var options = [];
+	        // Add all of the options from the table to the select element.
+	        // Only add one option for each possible value
+	        for (var _i = 0, indexArray_1 = indexArray; _i < indexArray_1.length; _i++) {
+	            var index = indexArray_1[_i];
+	            var filter = settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?
+	                that.c.orthogonal :
+	                that.c.orthogonal.search);
+	            var value = {
+	                filter: typeof filter === 'string' ?
+	                    filter.replace(/[\r\n\u2028]/g, ' ') : // Need to replace certain characters to match the search values
+	                    filter,
+	                index: index,
+	                text: settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?
+	                    that.c.orthogonal :
+	                    that.c.orthogonal.display)
+	            };
+	            // If we are dealing with an array type, either make sure we are working with arrays, or sort them
+	            if (that.s.type === 'array') {
+	                value.filter = !Array.isArray(value.filter) ?
+	                    [value.filter] :
+	                    value.filter = value.filter.sort();
+	                value.text = !Array.isArray(value.text) ?
+	                    [value.text] :
+	                    value.text = value.text.sort();
+	            }
+	            // Function to add an option to the select element
+	            var addOption = function (filt, text) {
+	                // Add text and value, stripping out any html if that is the column type
+	                var opt = $('<option>', {
+	                    text: typeof text === 'string' ?
+	                        text.replace(/(<([^>]+)>)/ig, '') :
+	                        text,
+	                    type: Array.isArray(filt) ? 'Array' : 'String',
+	                    value: that.s.type.indexOf('html') !== -1 && filt !== null && typeof filt === 'string' ?
+	                        filt.replace(/(<([^>]+)>)/ig, '') :
+	                        filt
+	                })
+	                    .addClass(that.classes.option)
+	                    .addClass(that.classes.notItalic);
+	                var val = $(opt).val();
+	                // Check that this value has not already been added
+	                if (added.indexOf(val) === -1) {
+	                    added.push(val);
+	                    options.push(opt);
+	                    if (preDefined !== null && Array.isArray(preDefined[0])) {
+	                        preDefined[0] = preDefined[0].sort().join(',');
+	                    }
+	                    // If this value was previously selected as indicated by preDefined, then select it again
+	                    if (preDefined !== null && opt.val() === preDefined[0]) {
+	                        opt.attr('selected', true);
+	                        $(el).removeClass(Criteria.classes.italic);
+	                    }
+	                }
+	            };
+	            // If this is to add the individual values within the array we need to loop over the array
+	            if (array) {
+	                for (var i = 0; i < value.filter.length; i++) {
+	                    addOption(value.filter[i], value.text[i]);
+	                }
+	            }
+	            // Otherwise the value that is in the cell is to be added
+	            else {
+	                addOption(value.filter, value.text);
+	            }
+	        }
+	        options.sort(function (a, b) {
+	            if (that.s.type === 'string' || that.s.type === 'num' || that.s.type === 'html' || that.s.type === 'html-num') {
+	                if ($(a).val() < $(b).val()) {
+	                    return -1;
+	                }
+	                else if ($(a).val() < $(b).val()) {
+	                    return 1;
+	                }
+	                else {
+	                    return 0;
+	                }
+	            }
+	            else if (that.s.type === 'num-fmt' || that.s.type === 'html-num-fmt') {
+	                if (+$(a).val().replace(/[^0-9.]/g, '') < +$(b).val().replace(/[^0-9.]/g, '')) {
+	                    return -1;
+	                }
+	                else if (+$(a).val().replace(/[^0-9.]/g, '') < +$(b).val().replace(/[^0-9.]/g, '')) {
+	                    return 1;
+	                }
+	                else {
+	                    return 0;
+	                }
+	            }
+	        });
+	        for (var _a = 0, options_1 = options; _a < options_1.length; _a++) {
+	            var opt = options_1[_a];
+	            $(el).append(opt);
+	        }
+	        return el;
+	    };
+	    /**
+	     * Default initialisation function for select array conditions
+	     *
+	     * This exists because there needs to be different select functionality for contains/without and equals/not
+	     */
+	    Criteria.initSelectArray = function (that, fn, preDefined) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        return Criteria.initSelect(that, fn, preDefined, true);
+	    };
+	    /**
+	     * Default initialisation function for input conditions
+	     */
+	    Criteria.initInput = function (that, fn, preDefined) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        // Declare the input element
+	        var el = $('<input/>')
+	            .addClass(Criteria.classes.value)
+	            .addClass(Criteria.classes.input)
+	            .on('input', function () { fn(that, this); });
+	        if (that.c.greyscale) {
+	            $(el).addClass(Criteria.classes.greyscale);
+	        }
+	        // If there is a preDefined value then add it
+	        if (preDefined !== null) {
+	            $(el).val(preDefined[0]);
+	        }
+	        return el;
+	    };
+	    /**
+	     * Default initialisation function for conditions requiring 2 inputs
+	     */
+	    Criteria.init2Input = function (that, fn, preDefined) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        // Declare all of the necessary jQuery elements
+	        var els = [
+	            $('<input/>')
+	                .addClass(Criteria.classes.value)
+	                .addClass(Criteria.classes.input)
+	                .on('input', function () { fn(that, this); }),
+	            $('<span>')
+	                .addClass(that.classes.joiner).text(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
+	            $('<input/>')
+	                .addClass(Criteria.classes.value)
+	                .addClass(Criteria.classes.input)
+	                .on('input', function () { fn(that, this); })
+	        ];
+	        if (that.c.greyscale) {
+	            $(els[0]).addClass(Criteria.classes.greyscale);
+	            $(els[2]).addClass(Criteria.classes.greyscale);
+	        }
+	        // If there is a preDefined value then add it
+	        if (preDefined !== null) {
+	            $(els[0]).val(preDefined[0]);
+	            $(els[2]).val(preDefined[1]);
+	        }
+	        that.s.dt.off('draw');
+	        that.s.dt.one('draw', function () {
+	            $(that.s.topGroup).trigger('dtsb-redrawContents');
+	        });
+	        return els;
+	    };
+	    /**
+	     * Default initialisation function for date conditions
+	     */
+	    Criteria.initDate = function (that, fn, preDefined) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        // Declare date element using DataTables dateTime plugin
+	        var el = $('<input/>')
+	            .addClass(Criteria.classes.value)
+	            .addClass(Criteria.classes.input)
+	            .dtDateTime({
+	            attachTo: 'input',
+	            format: that.s.momentFormat ? that.s.momentFormat : undefined
+	        })
+	            .on('input change', function () { fn(that, this); });
+	        if (that.c.greyscale) {
+	            $(el).addClass(Criteria.classes.greyscale);
+	        }
+	        // If there is a preDefined value then add it
+	        if (preDefined !== null) {
+	            $(el).val(preDefined[0]);
+	        }
+	        return el;
+	    };
+	    Criteria.initNoValue = function (that) {
+	        that.s.dt.off('draw');
+	        that.s.dt.one('draw', function () {
+	            $(that.s.topGroup).trigger('dtsb-redrawContents');
+	        });
+	    };
+	    Criteria.init2Date = function (that, fn, preDefined) {
+	        if (preDefined === void 0) { preDefined = null; }
+	        // Declare all of the date elements that are required using DataTables dateTime plugin
+	        var els = [
+	            $('<input/>')
+	                .addClass(Criteria.classes.value)
+	                .addClass(Criteria.classes.input)
+	                .dtDateTime({
+	                attachTo: 'input',
+	                format: that.s.momentFormat ? that.s.momentFormat : undefined
+	            })
+	                .on('input change', function () { fn(that, this); }),
+	            $('<span>')
+	                .addClass(that.classes.joiner)
+	                .text(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
+	            $('<input/>')
+	                .addClass(Criteria.classes.value)
+	                .addClass(Criteria.classes.input)
+	                .dtDateTime({
+	                attachTo: 'input',
+	                format: that.s.momentFormat ? that.s.momentFormat : undefined
+	            })
+	                .on('input change', function () { fn(that, this); })
+	        ];
+	        if (that.c.greyscale) {
+	            $(els[0]).addClass(Criteria.classes.greyscale);
+	            $(els[2]).addClass(Criteria.classes.greyscale);
+	        }
+	        // If there are and preDefined values then add them
+	        if (preDefined !== null && preDefined.length > 0) {
+	            $(els[0]).val(preDefined[0]);
+	            $(els[2]).val(preDefined[1]);
+	        }
+	        that.s.dt.off('draw');
+	        that.s.dt.one('draw', function () {
+	            $(that.s.topGroup).trigger('dtsb-redrawContents');
+	        });
+	        return els;
+	    };
+	    /**
+	     * Default function for select elements to validate condition
+	     */
+	    Criteria.isInputValidSelect = function (el) {
+	        var allFilled = true;
+	        // Check each element to make sure that the selections are valid
+	        for (var _i = 0, el_1 = el; _i < el_1.length; _i++) {
+	            var element = el_1[_i];
+	            if ($(element).children('option:selected').length === $(element).children('option').length - $(element).children('option.' + Criteria.classes.notItalic).length &&
+	                $(element).children('option:selected').length === 1 &&
+	                $(element).children('option:selected')[0] === $(element).children('option:hidden')[0]) {
+	                allFilled = false;
+	            }
+	        }
+	        return allFilled;
+	    };
+	    /**
+	     * Default function for input and date elements to validate condition
+	     */
+	    Criteria.isInputValidInput = function (el) {
+	        var allFilled = true;
+	        // Check each element to make sure that the inputs are valid
+	        for (var _i = 0, el_2 = el; _i < el_2.length; _i++) {
+	            var element = el_2[_i];
+	            if ($(element).is('input') && $(element).val().length === 0) {
+	                allFilled = false;
+	            }
+	        }
+	        return allFilled;
+	    };
+	    /**
+	     * Default function for getting select conditions
+	     */
+	    Criteria.inputValueSelect = function (el) {
+	        var values = [];
+	        // Go through the select elements and push each selected option to the return array
+	        for (var _i = 0, el_3 = el; _i < el_3.length; _i++) {
+	            var element = el_3[_i];
+	            if ($(element).is('select')) {
+	                var val = $(element).children('option:selected').val();
+	                // If the type of the option is an array we need to split it up and sort it
+	                values.push($(element).children('option:selected').attr('type') === 'Array' ?
+	                    val.split(',').sort() :
+	                    val);
+	            }
+	        }
+	        return values;
+	    };
+	    /**
+	     * Default function for getting input conditions
+	     */
+	    Criteria.inputValueInput = function (el) {
+	        var values = [];
+	        // Go through the input elements and push each value to the return array
+	        for (var _i = 0, el_4 = el; _i < el_4.length; _i++) {
+	            var element = el_4[_i];
+	            if ($(element).is('input')) {
+	                values.push($(element).val());
+	            }
+	        }
+	        return values;
+	    };
+	    /**
+	     * Function that is run on each element as a call back when a search should be triggered
+	     */
+	    Criteria.updateListener = function (that, el) {
+	        // When the value is changed the criteria is now complete so can be included in searches
+	        // Get the condition from the map based on the key that has been selected for the condition
+	        var condition = that.s.conditions[that.s.condition];
+	        that.s.filled = condition.isInputValid(that.dom.value, that);
+	        that.s.value = condition.inputValue(that.dom.value, that);
+	        if (!Array.isArray(that.s.value)) {
+	            that.s.value = [that.s.value];
+	        }
+	        for (var i = 0; i < that.s.value.length; i++) {
+	            // If the value is an array we need to sort it
+	            if (Array.isArray(that.s.value[i])) {
+	                that.s.value[i].sort();
+	            }
+	            // Otherwise replace the decimal place character for i18n
+	            else if (that.s.dt.settings()[0].oLanguage.sDecimal !== '') {
+	                that.s.value[i] = that.s.value[i].replace(that.s.dt.settings()[0].oLanguage.sDecimal, '.');
+	            }
+	        }
+	        // Take note of the cursor position so that we can refocus there later
+	        var idx = null;
+	        var cursorPos = null;
+	        for (var i = 0; i < that.dom.value.length; i++) {
+	            if (el === that.dom.value[i][0]) {
+	                idx = i;
+	                if (el.selectionStart !== undefined) {
+	                    cursorPos = el.selectionStart;
+	                }
+	            }
+	        }
+	        // Trigger a search
+	        that.s.dt.draw();
+	        // Refocus the element and set the correct cursor position
+	        if (idx !== null) {
+	            $(that.dom.value[idx]).removeClass(that.classes.italic);
+	            $(that.dom.value[idx]).focus();
+	            if (cursorPos !== null) {
+	                $(that.dom.value[idx])[0].setSelectionRange(cursorPos, cursorPos);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.dateConditions = {
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                return value === comparison[0];
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                return value !== comparison[0];
+	            }
+	        },
+	        '<': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                return value < comparison[0];
+	            }
+	        },
+	        '>': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                return value > comparison[0];
+	            }
+	        },
+	        'between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);
+	            },
+	            init: Criteria.init2Date,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                if (comparison[0] < comparison[1]) {
+	                    return comparison[0] <= value && value <= comparison[1];
+	                }
+	                else {
+	                    return comparison[1] <= value && value <= comparison[0];
+	                }
+	            }
+	        },
+	        '!between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);
+	            },
+	            init: Criteria.init2Date,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                value = value.replace(/(\/|\-|\,)/g, '-');
+	                if (comparison[0] < comparison[1]) {
+	                    return !(comparison[0] <= value && value <= comparison[1]);
+	                }
+	                else {
+	                    return !(comparison[1] <= value && value <= comparison[0]);
+	                }
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return !(value === null || value === undefined || value.length === 0);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.momentDateConditions = {
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.equals', i18n.conditions.moment.equals);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                return moment(value, that.s.momentFormat).valueOf() === moment(comparison[0], that.s.momentFormat).valueOf();
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.not', i18n.conditions.moment.not);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                return moment(value, that.s.momentFormat).valueOf() !== moment(comparison[0], that.s.momentFormat).valueOf();
+	            }
+	        },
+	        '<': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.before', i18n.conditions.moment.before);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                return moment(value, that.s.momentFormat).valueOf() < moment(comparison[0], that.s.momentFormat).valueOf();
+	            }
+	        },
+	        '>': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.after', i18n.conditions.moment.after);
+	            },
+	            init: Criteria.initDate,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                return moment(value, that.s.momentFormat).valueOf() > moment(comparison[0], that.s.momentFormat).valueOf();
+	            }
+	        },
+	        'between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.between', i18n.conditions.moment.between);
+	            },
+	            init: Criteria.init2Date,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                var val = moment(value, that.s.momentFormat).valueOf();
+	                var comp0 = moment(comparison[0], that.s.momentFormat).valueOf();
+	                var comp1 = moment(comparison[1], that.s.momentFormat).valueOf();
+	                if (comp0 < comp1) {
+	                    return comp0 <= val && val <= comp1;
+	                }
+	                else {
+	                    return comp1 <= val && val <= comp0;
+	                }
+	            }
+	        },
+	        '!between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.notBetween', i18n.conditions.moment.notBetween);
+	            },
+	            init: Criteria.init2Date,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison, that) {
+	                var val = moment(value, that.s.momentFormat).valueOf();
+	                var comp0 = moment(comparison[0], that.s.momentFormat).valueOf();
+	                var comp1 = moment(comparison[1], that.s.momentFormat).valueOf();
+	                if (comp0 < comp1) {
+	                    return !(+comp0 <= +val && +val <= +comp1);
+	                }
+	                else {
+	                    return !(+comp1 <= +val && +val <= +comp0);
+	                }
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.empty', i18n.conditions.moment.empty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.moment.notEmpty', i18n.conditions.moment.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return !(value === null || value === undefined || value.length === 0);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.numConditions = {
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                return +value === +comparison[0];
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                return +value !== +comparison[0];
+	            }
+	        },
+	        '<': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return +value < +comparison[0];
+	            }
+	        },
+	        '<=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return +value <= +comparison[0];
+	            }
+	        },
+	        '>=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return +value >= +comparison[0];
+	            }
+	        },
+	        '>': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return +value > +comparison[0];
+	            }
+	        },
+	        'between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);
+	            },
+	            init: Criteria.init2Input,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                if (+comparison[0] < +comparison[1]) {
+	                    return +comparison[0] <= +value && +value <= +comparison[1];
+	                }
+	                else {
+	                    return +comparison[1] <= +value && +value <= +comparison[0];
+	                }
+	            }
+	        },
+	        '!between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);
+	            },
+	            init: Criteria.init2Input,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                if (+comparison[0] < +comparison[1]) {
+	                    return !(+comparison[0] <= +value && +value <= +comparison[1]);
+	                }
+	                else {
+	                    return !(+comparison[1] <= +value && +value <= +comparison[0]);
+	                }
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);
+	            },
+	            init: Criteria.initNoValue,
+	            inputValue: function () { return; },
+	            isInputValid: function () { return true; },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return !(value === null || value === undefined || value.length === 0);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.numFmtConditions = {
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val === +comp;
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val !== +comp;
+	            }
+	        },
+	        '<': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val < +comp;
+	            }
+	        },
+	        '<=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val <= +comp;
+	            }
+	        },
+	        '>=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val >= +comp;
+	            }
+	        },
+	        '>': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                return +val > +comp;
+	            }
+	        },
+	        'between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);
+	            },
+	            init: Criteria.init2Input,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp0 = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                var comp1 = comparison[1].indexOf('-') === 0 ?
+	                    '-' + comparison[1].replace(/[^0-9.]/g, '') :
+	                    comparison[1].replace(/[^0-9.]/g, '');
+	                if (+comp0 < +comp1) {
+	                    return +comp0 <= +val && +val <= +comp1;
+	                }
+	                else {
+	                    return +comp1 <= +val && +val <= +comp0;
+	                }
+	            }
+	        },
+	        '!between': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);
+	            },
+	            init: Criteria.init2Input,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                var val = value.indexOf('-') === 0 ?
+	                    '-' + value.replace(/[^0-9.]/g, '') :
+	                    value.replace(/[^0-9.]/g, '');
+	                var comp0 = comparison[0].indexOf('-') === 0 ?
+	                    '-' + comparison[0].replace(/[^0-9.]/g, '') :
+	                    comparison[0].replace(/[^0-9.]/g, '');
+	                var comp1 = comparison[1].indexOf('-') === 0 ?
+	                    '-' + comparison[1].replace(/[^0-9.]/g, '') :
+	                    comparison[1].replace(/[^0-9.]/g, '');
+	                if (+comp0 < +comp1) {
+	                    return !(+comp0 <= +val && +val <= +comp1);
+	                }
+	                else {
+	                    return !(+comp1 <= +val && +val <= +comp0);
+	                }
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);
+	            },
+	            init: Criteria.initNoValue,
+	            inputValue: function () { return; },
+	            isInputValid: function () { return true; },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return !(value === null || value === undefined || value.length === 0);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.stringConditions = {
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.equals', i18n.conditions.string.equals);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                return value === comparison[0];
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.not', i18n.conditions.string.not);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return value !== comparison[0];
+	            }
+	        },
+	        'starts': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.startsWith', i18n.conditions.string.startsWith);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return value.toLowerCase().indexOf(comparison[0].toLowerCase()) === 0;
+	            }
+	        },
+	        'contains': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.contains', i18n.conditions.string.contains);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return value.toLowerCase().indexOf(comparison[0].toLowerCase()) !== -1;
+	            }
+	        },
+	        'ends': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.endsWith', i18n.conditions.string.endsWith);
+	            },
+	            init: Criteria.initInput,
+	            inputValue: Criteria.inputValueInput,
+	            isInputValid: Criteria.isInputValidInput,
+	            search: function (value, comparison) {
+	                return value.toLowerCase().endsWith(comparison[0].toLowerCase());
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.empty', i18n.conditions.string.empty);
+	            },
+	            init: Criteria.initNoValue,
+	            inputValue: function () { return; },
+	            isInputValid: function () { return true; },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.string.notEmpty', i18n.conditions.string.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () {
+	                return;
+	            },
+	            search: function (value) {
+	                return !(value === null || value === undefined || value.length === 0);
+	            }
+	        }
+	    };
+	    // The order of the conditions will make tslint sad :(
+	    Criteria.arrayConditions = {
+	        'contains': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.contains', i18n.conditions.array.contains);
+	            },
+	            init: Criteria.initSelectArray,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                return value.indexOf(comparison[0]) !== -1;
+	            }
+	        },
+	        'without': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.without', i18n.conditions.array.without);
+	            },
+	            init: Criteria.initSelectArray,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                return value.indexOf(comparison[0]) === -1;
+	            }
+	        },
+	        '=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.equals', i18n.conditions.array.equals);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                if (value.length === comparison[0].length) {
+	                    for (var i = 0; i < value.length; i++) {
+	                        if (value[i] !== comparison[0][i]) {
+	                            return false;
+	                        }
+	                    }
+	                    return true;
+	                }
+	                return false;
+	            }
+	        },
+	        '!=': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.not', i18n.conditions.array.not);
+	            },
+	            init: Criteria.initSelect,
+	            inputValue: Criteria.inputValueSelect,
+	            isInputValid: Criteria.isInputValidSelect,
+	            search: function (value, comparison) {
+	                if (value.length === comparison[0].length) {
+	                    for (var i = 0; i < value.length; i++) {
+	                        if (value[i] !== comparison[0][i]) {
+	                            return true;
+	                        }
+	                    }
+	                    return false;
+	                }
+	                return true;
+	            }
+	        },
+	        'null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.empty', i18n.conditions.array.empty);
+	            },
+	            init: Criteria.initNoValue,
+	            isInputValid: function () { return true; },
+	            inputValue: function () { return; },
+	            search: function (value) {
+	                return (value === null || value === undefined || value.length === 0);
+	            }
+	        },
+	        '!null': {
+	            conditionName: function (dt, i18n) {
+	                return dt.i18n('searchBuilder.conditions.array.notEmpty', i18n.conditions.array.notEmpty);
+	            },
+	            isInputValid: function () { return true; },
+	            init: Criteria.initNoValue,
+	            inputValue: function () { return; },
+	            search: function (value) {
+	                return (value !== null && value !== undefined && value.length !== 0);
+	            }
+	        }
+	    };
+	    Criteria.defaults = {
+	        columns: true,
+	        conditions: {
+	            'array': Criteria.arrayConditions,
+	            'date': Criteria.dateConditions,
+	            'html': Criteria.stringConditions,
+	            'html-num': Criteria.numConditions,
+	            'html-num-fmt': Criteria.numFmtConditions,
+	            'moment': Criteria.momentDateConditions,
+	            'num': Criteria.numConditions,
+	            'num-fmt': Criteria.numFmtConditions,
+	            'string': Criteria.stringConditions
+	        },
+	        depthLimit: false,
+	        filterChanged: undefined,
+	        greyscale: false,
+	        i18n: {
+	            add: 'Add Condition',
+	            button: {
+	                0: 'Search Builder',
+	                _: 'Search Builder (%d)'
+	            },
+	            clearAll: 'Clear All',
+	            condition: 'Condition',
+	            data: 'Data',
+	            deleteTitle: 'Delete filtering rule',
+	            leftTitle: 'Outdent criteria',
+	            logicAnd: 'And',
+	            logicOr: 'Or',
+	            rightTitle: 'Indent criteria',
+	            title: {
+	                0: 'Custom Search Builder',
+	                _: 'Custom Search Builder (%d)'
+	            },
+	            value: 'Value',
+	            valueJoiner: 'and'
+	        },
+	        logic: 'AND',
+	        orthogonal: {
+	            display: 'display',
+	            search: 'filter'
+	        },
+	        preDefined: false
+	    };
+	    return Criteria;
+	}());
+
+	var $$1;
+	var DataTable$1;
+	/**
+	 * Sets the value of jQuery for use in the file
+	 * @param jq the instance of jQuery to be set
+	 */
+	function setJQuery$1(jq) {
+	    $$1 = jq;
+	    DataTable$1 = jq.fn.dataTable;
+	}
+	/**
+	 * The Group class is used within SearchBuilder to represent a group of criteria
+	 */
+	var Group = /** @class */ (function () {
+	    function Group(table, opts, topGroup, index, isChild, depth) {
+	        if (index === void 0) { index = 0; }
+	        if (isChild === void 0) { isChild = false; }
+	        if (depth === void 0) { depth = 1; }
+	        // Check that the required version of DataTables is included
+	        if (!DataTable$1 || !DataTable$1.versionCheck || !DataTable$1.versionCheck('1.10.0')) {
+	            throw new Error('SearchBuilder requires DataTables 1.10 or newer');
+	        }
+	        this.classes = $$1.extend(true, {}, Group.classes);
+	        // Get options from user
+	        this.c = $$1.extend(true, {}, Group.defaults, opts);
+	        this.s = {
+	            criteria: [],
+	            depth: depth,
+	            dt: table,
+	            index: index,
+	            isChild: isChild,
+	            logic: undefined,
+	            opts: opts,
+	            toDrop: undefined,
+	            topGroup: topGroup
+	        };
+	        this.dom = {
+	            add: $$1('<button/>')
+	                .addClass(this.classes.add)
+	                .addClass(this.classes.button)
+	                .attr('type', 'button'),
+	            clear: $$1('<button>&times</button>')
+	                .addClass(this.classes.button)
+	                .addClass(this.classes.clearGroup)
+	                .attr('type', 'button'),
+	            container: $$1('<div/>')
+	                .addClass(this.classes.group),
+	            logic: $$1('<button/>')
+	                .addClass(this.classes.logic)
+	                .addClass(this.classes.button)
+	                .attr('type', 'button'),
+	            logicContainer: $$1('<div/>')
+	                .addClass(this.classes.logicContainer)
+	        };
+	        // A reference to the top level group is maintained throughout any subgroups and criteria that may be created
+	        if (this.s.topGroup === undefined) {
+	            this.s.topGroup = this.dom.container;
+	        }
+	        this._setup();
+	        return this;
+	    }
+	    /**
+	     * Destroys the groups buttons, clears the internal criteria and removes it from the dom
+	     */
+	    Group.prototype.destroy = function () {
+	        // Turn off listeners
+	        $$1(this.dom.add).off('.dtsb');
+	        $$1(this.dom.logic).off('.dtsb');
+	        // Trigger event for groups at a higher level to pick up on
+	        $$1(this.dom.container)
+	            .trigger('dtsb-destroy')
+	            .remove();
+	        this.s.criteria = [];
+	    };
+	    /**
+	     * Gets the details required to rebuild the group
+	     */
+	    Group.prototype.getDetails = function () {
+	        if (this.s.criteria.length === 0) {
+	            return {};
+	        }
+	        var details = {
+	            criteria: [],
+	            logic: this.s.logic
+	        };
+	        // NOTE here crit could be either a subgroup or a criteria
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            details.criteria.push(crit.criteria.getDetails());
+	        }
+	        return details;
+	    };
+	    /**
+	     * Getter for the node for the container of the group
+	     * @returns Node for the container of the group
+	     */
+	    Group.prototype.getNode = function () {
+	        return this.dom.container;
+	    };
+	    /**
+	     * Rebuilds the group based upon the details passed in
+	     * @param loadedDetails the details required to rebuild the group
+	     */
+	    Group.prototype.rebuild = function (loadedDetails) {
+	        // If no criteria are stored then just return
+	        if (loadedDetails.criteria === undefined || loadedDetails.criteria === null || loadedDetails.criteria.length === 0) {
+	            return;
+	        }
+	        this.s.logic = loadedDetails.logic;
+	        $$1(this.dom.logic).text(this.s.logic === 'OR'
+	            ? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
+	            : this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
+	        // Add all of the criteria, be it a sub group or a criteria
+	        for (var _i = 0, _a = loadedDetails.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            if (crit.logic !== undefined) {
+	                this._addPrevGroup(crit);
+	            }
+	            else if (crit.logic === undefined) {
+	                this._addPrevCriteria(crit);
+	            }
+	        }
+	        // For all of the criteria children, update the arrows incase they require changing and set the listeners
+	        for (var _b = 0, _c = this.s.criteria; _b < _c.length; _b++) {
+	            var crit = _c[_b];
+	            if (crit.criteria instanceof Criteria) {
+	                crit.criteria.updateArrows(this.s.criteria.length > 1, false);
+	                this._setCriteriaListeners(crit.criteria);
+	            }
+	        }
+	    };
+	    /**
+	     * Redraws the Contents of the searchBuilder Groups and Criteria
+	     */
+	    Group.prototype.redrawContents = function () {
+	        // Clear the container out and add the basic elements
+	        $$1(this.dom.container)
+	            .empty()
+	            .append(this.dom.logicContainer)
+	            .append(this.dom.add);
+	        // Sort the criteria by index so that they appear in the correct order
+	        this.s.criteria.sort(function (a, b) {
+	            if (a.criteria.s.index < b.criteria.s.index) {
+	                return -1;
+	            }
+	            else if (a.criteria.s.index > b.criteria.s.index) {
+	                return 1;
+	            }
+	            return 0;
+	        });
+	        this.setListeners();
+	        for (var i = 0; i < this.s.criteria.length; i++) {
+	            var crit = this.s.criteria[i].criteria;
+	            if (crit instanceof Criteria) {
+	                // Reset the index to the new value
+	                this.s.criteria[i].index = i;
+	                this.s.criteria[i].criteria.s.index = i;
+	                // Add to the group
+	                $$1(this.s.criteria[i].criteria.dom.container).insertBefore(this.dom.add);
+	                // Set listeners for various points
+	                this._setCriteriaListeners(crit);
+	                this.s.criteria[i].criteria.rebuild(this.s.criteria[i].criteria.getDetails());
+	            }
+	            else if (crit instanceof Group && crit.s.criteria.length > 0) {
+	                // Reset the index to the new value
+	                this.s.criteria[i].index = i;
+	                this.s.criteria[i].criteria.s.index = i;
+	                // Add the sub group to the group
+	                $$1(this.s.criteria[i].criteria.dom.container).insertBefore(this.dom.add);
+	                // Redraw the contents of the group
+	                crit.redrawContents();
+	                this._setGroupListeners(crit);
+	            }
+	            else {
+	                // The group is empty so remove it
+	                this.s.criteria.splice(i, 1);
+	                i--;
+	            }
+	        }
+	        this.setupLogic();
+	    };
+	    /**
+	     * Search method, checking the row data against the criteria in the group
+	     * @param rowData The row data to be compared
+	     * @returns boolean The result of the search
+	     */
+	    Group.prototype.search = function (rowData, rowIdx) {
+	        if (this.s.logic === 'AND') {
+	            return this._andSearch(rowData, rowIdx);
+	        }
+	        else if (this.s.logic === 'OR') {
+	            return this._orSearch(rowData, rowIdx);
+	        }
+	        return true;
+	    };
+	    /**
+	     * Locates the groups logic button to the correct location on the page
+	     */
+	    Group.prototype.setupLogic = function () {
+	        // Remove logic button
+	        $$1(this.dom.logicContainer).remove();
+	        $$1(this.dom.clear).remove();
+	        // If there are no criteria in the group then keep the logic removed and return
+	        if (this.s.criteria.length < 1) {
+	            if (!this.s.isChild) {
+	                $$1(this.dom.container).trigger('dtsb-destroy');
+	                // Set criteria left margin
+	                $$1(this.dom.container).css('margin-left', 0);
+	            }
+	            return;
+	        }
+	        // Set width, take 2 for the border
+	        var height = $$1(this.dom.container).height() - 2;
+	        $$1(this.dom.clear).height('0px');
+	        $$1(this.dom.logicContainer).append(this.dom.clear).width(height);
+	        // Prepend logic button
+	        $$1(this.dom.container).prepend(this.dom.logicContainer);
+	        this._setLogicListener();
+	        // Set criteria left margin
+	        $$1(this.dom.container).css('margin-left', $$1(this.dom.logicContainer).outerHeight(true));
+	        var logicOffset = $$1(this.dom.logicContainer).offset();
+	        // Set horizontal alignment
+	        var currentLeft = logicOffset.left;
+	        var groupLeft = $$1(this.dom.container).offset().left;
+	        var shuffleLeft = currentLeft - groupLeft;
+	        var newPos = currentLeft - shuffleLeft - $$1(this.dom.logicContainer).outerHeight(true);
+	        $$1(this.dom.logicContainer).offset({ left: newPos });
+	        // Set vertical alignment
+	        var firstCrit = $$1(this.dom.logicContainer).next();
+	        var currentTop = logicOffset.top;
+	        var firstTop = $$1(firstCrit).offset().top;
+	        var shuffleTop = currentTop - firstTop;
+	        var newTop = currentTop - shuffleTop;
+	        $$1(this.dom.logicContainer).offset({ top: newTop });
+	        $$1(this.dom.clear).outerHeight($$1(this.dom.logicContainer).height());
+	        this._setClearListener();
+	    };
+	    /**
+	     * Sets listeners on the groups elements
+	     */
+	    Group.prototype.setListeners = function () {
+	        var _this = this;
+	        $$1(this.dom.add).unbind('click');
+	        $$1(this.dom.add).on('click', function () {
+	            // If this is the parent group then the logic button has not been added yet
+	            if (!_this.s.isChild) {
+	                $$1(_this.dom.container).prepend(_this.dom.logicContainer);
+	            }
+	            _this.addCriteria();
+	            $$1(_this.dom.container).trigger('dtsb-add');
+	            _this.s.dt.state.save();
+	            return false;
+	        });
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            crit.criteria.setListeners();
+	        }
+	        this._setClearListener();
+	        this._setLogicListener();
+	    };
+	    /**
+	     * Adds a criteria to the group
+	     * @param crit Instance of Criteria to be added to the group
+	     */
+	    Group.prototype.addCriteria = function (crit, redraw) {
+	        if (crit === void 0) { crit = null; }
+	        if (redraw === void 0) { redraw = true; }
+	        var index = crit === null ? this.s.criteria.length : crit.s.index;
+	        var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth);
+	        // If a Criteria has been passed in then set the values to continue that
+	        if (crit !== null) {
+	            criteria.c = crit.c;
+	            criteria.s = crit.s;
+	            criteria.s.depth = this.s.depth;
+	            criteria.classes = crit.classes;
+	        }
+	        criteria.populate();
+	        var inserted = false;
+	        for (var i = 0; i < this.s.criteria.length; i++) {
+	            if (i === 0 && this.s.criteria[i].criteria.s.index > criteria.s.index) {
+	                // Add the node for the criteria at the start of the group
+	                $$1(criteria.getNode()).insertBefore(this.s.criteria[i].criteria.dom.container);
+	                inserted = true;
+	            }
+	            else if (i < this.s.criteria.length - 1 &&
+	                this.s.criteria[i].criteria.s.index < criteria.s.index &&
+	                this.s.criteria[i + 1].criteria.s.index > criteria.s.index) {
+	                // Add the node for the criteria in the correct location
+	                $$1(criteria.getNode()).insertAfter(this.s.criteria[i].criteria.dom.container);
+	                inserted = true;
+	            }
+	        }
+	        if (!inserted) {
+	            $$1(criteria.getNode()).insertBefore(this.dom.add);
+	        }
+	        // Add the details for this criteria to the array
+	        this.s.criteria.push({
+	            criteria: criteria,
+	            index: index
+	        });
+	        this.s.criteria = this.s.criteria.sort(function (a, b) {
+	            return a.criteria.s.index - b.criteria.s.index;
+	        });
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var opt = _a[_i];
+	            if (opt.criteria instanceof Criteria) {
+	                opt.criteria.updateArrows(this.s.criteria.length > 1, redraw);
+	            }
+	        }
+	        this._setCriteriaListeners(criteria);
+	        criteria.setListeners();
+	        this.setupLogic();
+	    };
+	    /**
+	     * Checks the group to see if it has any filled criteria
+	     */
+	    Group.prototype.checkFilled = function () {
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            if ((crit.criteria instanceof Criteria && crit.criteria.s.filled) ||
+	                (crit.criteria instanceof Group && crit.criteria.checkFilled())) {
+	                return true;
+	            }
+	        }
+	        return false;
+	    };
+	    /**
+	     * Gets the count for the number of criteria in this group and any sub groups
+	     */
+	    Group.prototype.count = function () {
+	        var count = 0;
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            if (crit.criteria instanceof Group) {
+	                count += crit.criteria.count();
+	            }
+	            else {
+	                count++;
+	            }
+	        }
+	        return count;
+	    };
+	    /**
+	     * Rebuilds a sub group that previously existed
+	     * @param loadedGroup The details of a group within this group
+	     */
+	    Group.prototype._addPrevGroup = function (loadedGroup) {
+	        var idx = this.s.criteria.length;
+	        var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1);
+	        // Add the new group to the criteria array
+	        this.s.criteria.push({
+	            criteria: group,
+	            index: idx,
+	            logic: group.s.logic
+	        });
+	        // Rebuild it with the previous conditions for that group
+	        group.rebuild(loadedGroup);
+	        this.s.criteria[idx].criteria = group;
+	        $$1(this.s.topGroup).trigger('dtsb-redrawContents');
+	        this._setGroupListeners(group);
+	    };
+	    /**
+	     * Rebuilds a criteria of this group that previously existed
+	     * @param loadedCriteria The details of a criteria within the group
+	     */
+	    Group.prototype._addPrevCriteria = function (loadedCriteria) {
+	        var idx = this.s.criteria.length;
+	        var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth);
+	        criteria.populate();
+	        // Add the new criteria to the criteria array
+	        this.s.criteria.push({
+	            criteria: criteria,
+	            index: idx
+	        });
+	        // Rebuild it with the previous conditions for that criteria
+	        criteria.rebuild(loadedCriteria);
+	        this.s.criteria[idx].criteria = criteria;
+	        $$1(this.s.topGroup).trigger('dtsb-redrawContents');
+	    };
+	    /**
+	     * Checks And the criteria using AND logic
+	     * @param rowData The row data to be checked against the search criteria
+	     * @returns boolean The result of the AND search
+	     */
+	    Group.prototype._andSearch = function (rowData, rowIdx) {
+	        // If there are no criteria then return true for this group
+	        if (this.s.criteria.length === 0) {
+	            return true;
+	        }
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            // If the criteria is not complete then skip it
+	            if (crit.criteria instanceof Criteria && !crit.criteria.s.filled) {
+	                continue;
+	            }
+	            // Otherwise if a single one fails return false
+	            else if (!crit.criteria.search(rowData, rowIdx)) {
+	                return false;
+	            }
+	        }
+	        // If we get to here then everything has passed, so return true for the group
+	        return true;
+	    };
+	    /**
+	     * Checks And the criteria using OR logic
+	     * @param rowData The row data to be checked against the search criteria
+	     * @returns boolean The result of the OR search
+	     */
+	    Group.prototype._orSearch = function (rowData, rowIdx) {
+	        // If there are no criteria in the group then return true
+	        if (this.s.criteria.length === 0) {
+	            return true;
+	        }
+	        // This will check to make sure that at least one criteria in the group is complete
+	        var filledfound = false;
+	        for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            if (crit.criteria instanceof Criteria && crit.criteria.s.filled) {
+	                // A completed criteria has been found so set the flag
+	                filledfound = true;
+	                // If the search passes then return true
+	                if (crit.criteria.search(rowData, rowIdx)) {
+	                    return true;
+	                }
+	            }
+	            else if (crit.criteria instanceof Group && crit.criteria.checkFilled()) {
+	                filledfound = true;
+	                if (crit.criteria.search(rowData, rowIdx)) {
+	                    return true;
+	                }
+	            }
+	        }
+	        // If we get here we need to return the inverse of filledfound,
+	        //  as if any have been found and we are here then none have passed
+	        return !filledfound;
+	    };
+	    /**
+	     * Removes a criteria from the group
+	     * @param criteria The criteria instance to be removed
+	     */
+	    Group.prototype._removeCriteria = function (criteria, group) {
+	        if (group === void 0) { group = false; }
+	        // If removing a criteria and there is only then then just destroy the group
+	        if (this.s.criteria.length <= 1 && this.s.isChild) {
+	            this.destroy();
+	        }
+	        else {
+	            // Otherwise splice the given criteria out and redo the indexes
+	            var last = void 0;
+	            for (var i = 0; i < this.s.criteria.length; i++) {
+	                if (this.s.criteria[i].index === criteria.s.index && (!group || this.s.criteria[i].criteria instanceof Group)) {
+	                    last = i;
+	                }
+	            }
+	            // We want to remove the last element with the desired index, as its replacement will be inserted before it
+	            if (last !== undefined) {
+	                this.s.criteria.splice(last, 1);
+	            }
+	            for (var i = 0; i < this.s.criteria.length; i++) {
+	                this.s.criteria[i].index = i;
+	                this.s.criteria[i].criteria.s.index = i;
+	            }
+	        }
+	    };
+	    /**
+	     * Sets the listeners in group for a criteria
+	     * @param criteria The criteria for the listeners to be set on
+	     */
+	    Group.prototype._setCriteriaListeners = function (criteria) {
+	        var _this = this;
+	        $$1(criteria.dom["delete"])
+	            .unbind('click')
+	            .on('click', function () {
+	            _this._removeCriteria(criteria);
+	            $$1(criteria.dom.container).remove();
+	            for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {
+	                var crit = _a[_i];
+	                if (crit.criteria instanceof Criteria) {
+	                    crit.criteria.updateArrows(_this.s.criteria.length > 1);
+	                }
+	            }
+	            criteria.destroy();
+	            _this.s.dt.draw();
+	            $$1(_this.s.topGroup).trigger('dtsb-redrawContents');
+	            $$1(_this.s.topGroup).trigger('dtsb-updateTitle');
+	            return false;
+	        });
+	        $$1(criteria.dom.right)
+	            .unbind('click')
+	            .on('click', function () {
+	            var idx = criteria.s.index;
+	            var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1);
+	            // Add the criteria that is to be moved to the new group
+	            group.addCriteria(criteria);
+	            // Update the details in the current groups criteria array
+	            _this.s.criteria[idx].criteria = group;
+	            _this.s.criteria[idx].logic = 'AND';
+	            $$1(_this.s.topGroup).trigger('dtsb-redrawContents');
+	            _this._setGroupListeners(group);
+	            return false;
+	        });
+	        $$1(criteria.dom.left)
+	            .unbind('click')
+	            .on('click', function () {
+	            _this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index);
+	            _this.s.toDrop.s = criteria.s;
+	            _this.s.toDrop.c = criteria.c;
+	            _this.s.toDrop.classes = criteria.classes;
+	            _this.s.toDrop.populate();
+	            // The dropCriteria event mutates the reference to the index so need to store it
+	            var index = _this.s.toDrop.s.index;
+	            $$1(_this.dom.container).trigger('dtsb-dropCriteria');
+	            criteria.s.index = index;
+	            _this._removeCriteria(criteria);
+	            // By tracking the top level group we can directly trigger a redraw on it,
+	            //  bubbling is also possible, but that is slow with deep levelled groups
+	            $$1(_this.s.topGroup).trigger('dtsb-redrawContents');
+	            _this.s.dt.draw();
+	            return false;
+	        });
+	    };
+	    /**
+	     * Set's the listeners for the group clear button
+	     */
+	    Group.prototype._setClearListener = function () {
+	        var _this = this;
+	        $$1(this.dom.clear)
+	            .unbind('click')
+	            .on('click', function () {
+	            if (!_this.s.isChild) {
+	                $$1(_this.dom.container).trigger('dtsb-clearContents');
+	                return false;
+	            }
+	            _this.destroy();
+	            $$1(_this.s.topGroup).trigger('dtsb-updateTitle');
+	            $$1(_this.s.topGroup).trigger('dtsb-redrawContents');
+	            return false;
+	        });
+	    };
+	    /**
+	     * Sets listeners for sub groups of this group
+	     * @param group The sub group that the listeners are to be set on
+	     */
+	    Group.prototype._setGroupListeners = function (group) {
+	        var _this = this;
+	        // Set listeners for the new group
+	        $$1(group.dom.add)
+	            .unbind('click')
+	            .on('click', function () {
+	            _this.setupLogic();
+	            $$1(_this.dom.container).trigger('dtsb-add');
+	            return false;
+	        });
+	        $$1(group.dom.container)
+	            .unbind('dtsb-add')
+	            .on('dtsb-add', function () {
+	            _this.setupLogic();
+	            $$1(_this.dom.container).trigger('dtsb-add');
+	            return false;
+	        });
+	        $$1(group.dom.container)
+	            .unbind('dtsb-destroy')
+	            .on('dtsb-destroy', function () {
+	            _this._removeCriteria(group, true);
+	            $$1(group.dom.container).remove();
+	            _this.setupLogic();
+	            return false;
+	        });
+	        $$1(group.dom.container)
+	            .unbind('dtsb-dropCriteria')
+	            .on('dtsb-dropCriteria', function () {
+	            var toDrop = group.s.toDrop;
+	            toDrop.s.index = group.s.index;
+	            toDrop.updateArrows(_this.s.criteria.length > 1, false);
+	            _this.addCriteria(toDrop, false);
+	            return false;
+	        });
+	        group.setListeners();
+	    };
+	    /**
+	     * Sets up the Group instance, setting listeners and appending elements
+	     */
+	    Group.prototype._setup = function () {
+	        this.setListeners();
+	        $$1(this.dom.add).text(this.s.dt.i18n('searchBuilder.add', this.c.i18n.add));
+	        $$1(this.dom.logic).text(this.c.logic === 'OR'
+	            ? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
+	            : this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
+	        this.s.logic = this.c.logic === 'OR' ? 'OR' : 'AND';
+	        if (this.c.greyscale) {
+	            $$1(this.dom.logic).addClass(this.classes.greyscale);
+	        }
+	        $$1(this.dom.logicContainer).append(this.dom.logic).append(this.dom.clear);
+	        // Only append the logic button immediately if this is a sub group,
+	        //  otherwise it will be prepended later when adding a criteria
+	        if (this.s.isChild) {
+	            $$1(this.dom.container).append(this.dom.logicContainer);
+	        }
+	        $$1(this.dom.container).append(this.dom.add);
+	    };
+	    /**
+	     * Sets the listener for the logic button
+	     */
+	    Group.prototype._setLogicListener = function () {
+	        var _this = this;
+	        $$1(this.dom.logic)
+	            .unbind('click')
+	            .on('click', function () {
+	            _this._toggleLogic();
+	            _this.s.dt.draw();
+	            for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {
+	                var crit = _a[_i];
+	                crit.criteria.setListeners();
+	            }
+	        });
+	    };
+	    /**
+	     * Toggles the logic for the group
+	     */
+	    Group.prototype._toggleLogic = function () {
+	        if (this.s.logic === 'OR') {
+	            this.s.logic = 'AND';
+	            $$1(this.dom.logic).text(this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
+	        }
+	        else if (this.s.logic === 'AND') {
+	            this.s.logic = 'OR';
+	            $$1(this.dom.logic).text(this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr));
+	        }
+	    };
+	    Group.version = '1.0.0';
+	    Group.classes = {
+	        add: 'dtsb-add',
+	        button: 'dtsb-button',
+	        clearGroup: 'dtsb-clearGroup',
+	        greyscale: 'dtsb-greyscale',
+	        group: 'dtsb-group',
+	        inputButton: 'dtsb-iptbtn',
+	        logic: 'dtsb-logic',
+	        logicContainer: 'dtsb-logicContainer'
+	    };
+	    Group.defaults = {
+	        columns: true,
+	        conditions: {
+	            'date': Criteria.dateConditions,
+	            'html': Criteria.stringConditions,
+	            'html-num': Criteria.numConditions,
+	            'html-num-fmt': Criteria.numFmtConditions,
+	            'moment': Criteria.momentDateConditions,
+	            'num': Criteria.numConditions,
+	            'num-fmt': Criteria.numFmtConditions,
+	            'string': Criteria.stringConditions
+	        },
+	        depthLimit: false,
+	        filterChanged: undefined,
+	        greyscale: false,
+	        i18n: {
+	            add: 'Add Condition',
+	            button: {
+	                0: 'Search Builder',
+	                _: 'Search Builder (%d)'
+	            },
+	            clearAll: 'Clear All',
+	            condition: 'Condition',
+	            data: 'Data',
+	            deleteTitle: 'Delete filtering rule',
+	            leftTitle: 'Outdent criteria',
+	            logicAnd: 'And',
+	            logicOr: 'Or',
+	            rightTitle: 'Indent criteria',
+	            title: {
+	                0: 'Custom Search Builder',
+	                _: 'Custom Search Builder (%d)'
+	            },
+	            value: 'Value',
+	            valueJoiner: 'and'
+	        },
+	        logic: 'AND',
+	        orthogonal: {
+	            display: 'display',
+	            search: 'filter'
+	        },
+	        preDefined: false
+	    };
+	    return Group;
+	}());
+
+	var $$2;
+	var DataTable$2;
+	/**
+	 * Sets the value of jQuery for use in the file
+	 * @param jq the instance of jQuery to be set
+	 */
+	function setJQuery$2(jq) {
+	    $$2 = jq;
+	    DataTable$2 = jq.fn.DataTable;
+	}
+	/**
+	 * SearchBuilder class for DataTables.
+	 * Allows for complex search queries to be constructed and implemented on a DataTable
+	 */
+	var SearchBuilder = /** @class */ (function () {
+	    function SearchBuilder(builderSettings, opts) {
+	        var _this = this;
+	        // Check that the required version of DataTables is included
+	        if (!DataTable$2 || !DataTable$2.versionCheck || !DataTable$2.versionCheck('1.10.0')) {
+	            throw new Error('SearchBuilder requires DataTables 1.10 or newer');
+	        }
+	        var table = new DataTable$2.Api(builderSettings);
+	        this.classes = $$2.extend(true, {}, SearchBuilder.classes);
+	        // Get options from user
+	        this.c = $$2.extend(true, {}, SearchBuilder.defaults, opts);
+	        this.dom = {
+	            clearAll: $$2('<button type="button">' + table.i18n('searchBuilder.clearAll', this.c.i18n.clearAll) + '</button>')
+	                .addClass(this.classes.clearAll)
+	                .addClass(this.classes.button)
+	                .attr('type', 'button'),
+	            container: $$2('<div/>')
+	                .addClass(this.classes.container),
+	            title: $$2('<div/>')
+	                .addClass(this.classes.title),
+	            titleRow: $$2('<div/>')
+	                .addClass(this.classes.titleRow),
+	            topGroup: undefined
+	        };
+	        this.s = {
+	            dt: table,
+	            opts: opts,
+	            search: undefined,
+	            topGroup: undefined
+	        };
+	        // If searchbuilder is already defined for this table then return
+	        if (table.settings()[0]._searchBuilder !== undefined) {
+	            return;
+	        }
+	        table.settings()[0]._searchBuilder = this;
+	        // Run the remaining setup when the table is initialised
+	        if (this.s.dt.settings()[0]._bInitComplete) {
+	            this._setUp();
+	        }
+	        else {
+	            table.one('init.dt', function () {
+	                _this._setUp();
+	            });
+	        }
+	        return this;
+	    }
+	    /**
+	     * Gets the details required to rebuild the SearchBuilder as it currently is
+	     */
+	    SearchBuilder.prototype.getDetails = function () {
+	        return this.s.topGroup.getDetails();
+	    };
+	    /**
+	     * Getter for the node of the container for the searchBuilder
+	     * @returns JQuery<HTMLElement> the node of the container
+	     */
+	    SearchBuilder.prototype.getNode = function () {
+	        return this.dom.container;
+	    };
+	    /**
+	     * Rebuilds the SearchBuilder to a state that is provided
+	     * @param details The details required to perform a rebuild
+	     */
+	    SearchBuilder.prototype.rebuild = function (details) {
+	        $$2(this.dom.clearAll).click();
+	        // If there are no details to rebuild then return
+	        if (details === undefined || details === null) {
+	            return this;
+	        }
+	        this.s.topGroup.rebuild(details);
+	        this.s.dt.draw();
+	        this.s.topGroup.setListeners();
+	        return this;
+	    };
+	    /**
+	     * Applies the defaults to preDefined criteria
+	     * @param preDef the array of criteria to be processed.
+	     */
+	    SearchBuilder.prototype._applyPreDefDefaults = function (preDef) {
+	        var _this = this;
+	        if (preDef.criteria !== undefined && preDef.logic === undefined) {
+	            preDef.logic = 'AND';
+	        }
+	        var _loop_1 = function (crit) {
+	            // Apply the defaults to any further criteria
+	            if (crit.criteria !== undefined) {
+	                crit = this_1._applyPreDefDefaults(crit);
+	            }
+	            else {
+	                this_1.s.dt.columns().every(function (index) {
+	                    if (_this.s.dt.settings()[0].aoColumns[index].sTitle === crit.data) {
+	                        crit.dataIdx = index;
+	                    }
+	                });
+	            }
+	        };
+	        var this_1 = this;
+	        for (var _i = 0, _a = preDef.criteria; _i < _a.length; _i++) {
+	            var crit = _a[_i];
+	            _loop_1(crit);
+	        }
+	        return preDef;
+	    };
+	    /**
+	     * Set's up the SearchBuilder
+	     */
+	    SearchBuilder.prototype._setUp = function (loadState) {
+	        var _this = this;
+	        if (loadState === void 0) { loadState = true; }
+	        this.s.topGroup = new Group(this.s.dt, this.c, undefined);
+	        this._setClearListener();
+	        this.s.dt.on('stateSaveParams', function (e, settings, data) {
+	            data.searchBuilder = _this.getDetails();
+	            data.page = _this.s.dt.page();
+	        });
+	        this._build();
+	        if (loadState) {
+	            var loadedState = this.s.dt.state.loaded();
+	            // If the loaded State is not null rebuild based on it for statesave
+	            if (loadedState !== null && loadedState.searchBuilder !== undefined) {
+	                this.s.topGroup.rebuild(loadedState.searchBuilder);
+	                $$2(this.s.topGroup.dom.container).trigger('dtsb-redrawContents');
+	                this.s.dt.page(loadedState.page).draw('page');
+	                this.s.topGroup.setListeners();
+	            }
+	            // Otherwise load any predefined options
+	            else if (this.c.preDefined !== false) {
+	                this.c.preDefined = this._applyPreDefDefaults(this.c.preDefined);
+	                this.rebuild(this.c.preDefined);
+	            }
+	        }
+	        this._setEmptyListener();
+	        this.s.dt.state.save();
+	    };
+	    /**
+	     * Updates the title of the SearchBuilder
+	     * @param count the number of filters in the SearchBuilder
+	     */
+	    SearchBuilder.prototype._updateTitle = function (count) {
+	        $$2(this.dom.title).text(this.s.dt.i18n('searchBuilder.title', this.c.i18n.title, count));
+	    };
+	    /**
+	     * Builds all of the dom elements together
+	     */
+	    SearchBuilder.prototype._build = function () {
+	        var _this = this;
+	        // Empty and setup the container
+	        $$2(this.dom.clearAll).remove();
+	        $$2(this.dom.container).empty();
+	        var count = this.s.topGroup.count();
+	        this._updateTitle(count);
+	        $$2(this.dom.titleRow).append(this.dom.title);
+	        $$2(this.dom.container).append(this.dom.titleRow);
+	        this.dom.topGroup = this.s.topGroup.getNode();
+	        $$2(this.dom.container).append(this.dom.topGroup);
+	        this._setRedrawListener();
+	        var tableNode = this.s.dt.table(0).node();
+	        if ($$2.fn.dataTable.ext.search.indexOf(this.s.search) === -1) {
+	            // Custom search function for SearchBuilder
+	            this.s.search = function (settings, searchData, dataIndex, origData) {
+	                if (settings.nTable !== tableNode) {
+	                    return true;
+	                }
+	                return _this.s.topGroup.search(searchData, dataIndex);
+	            };
+	            // Add SearchBuilder search function to the dataTables search array
+	            $$2.fn.dataTable.ext.search.push(this.s.search);
+	        }
+	        // Register an Api method for getting the column type
+	        $$2.fn.DataTable.Api.registerPlural('columns().type()', 'column().type()', function (selector, opts) {
+	            return this.iterator('column', function (settings, column) {
+	                return settings.aoColumns[column].sType;
+	            }, 1);
+	        });
+	        this.s.dt.on('destroy.dt', function () {
+	            $$2(_this.dom.container).remove();
+	            $$2(_this.dom.clearAll).remove();
+	            var searchIdx = $$2.fn.dataTable.ext.search.indexOf(_this.s.search);
+	            while (searchIdx !== -1) {
+	                $$2.fn.dataTable.ext.search.splice(searchIdx, 1);
+	                searchIdx = $$2.fn.dataTable.ext.search.indexOf(_this.s.search);
+	            }
+	        });
+	    };
+	    /**
+	     * Checks if the clearAll button should be added or not
+	     */
+	    SearchBuilder.prototype._checkClear = function () {
+	        if (this.s.topGroup.s.criteria.length > 0) {
+	            $$2(this.dom.clearAll).insertAfter(this.dom.title);
+	            this._setClearListener();
+	        }
+	        else {
+	            $$2(this.dom.clearAll).remove();
+	        }
+	    };
+	    /**
+	     * Update the count in the title/button
+	     * @param count Number of filters applied
+	     */
+	    SearchBuilder.prototype._filterChanged = function (count) {
+	        var fn = this.c.filterChanged;
+	        if (typeof fn === 'function') {
+	            fn(count, this.s.dt.i18n('searchBuilder.button', this.c.i18n.button, count));
+	        }
+	    };
+	    /**
+	     * Set the listener for the clear button
+	     */
+	    SearchBuilder.prototype._setClearListener = function () {
+	        var _this = this;
+	        $$2(this.dom.clearAll).unbind('click');
+	        $$2(this.dom.clearAll).on('click', function () {
+	            _this.s.topGroup = new Group(_this.s.dt, _this.c, undefined);
+	            _this._build();
+	            _this.s.dt.draw();
+	            _this.s.topGroup.setListeners();
+	            $$2(_this.dom.clearAll).remove();
+	            _this._setEmptyListener();
+	            _this._filterChanged(0);
+	            return false;
+	        });
+	    };
+	    /**
+	     * Set the listener for the Redraw event
+	     */
+	    SearchBuilder.prototype._setRedrawListener = function () {
+	        var _this = this;
+	        $$2(this.s.topGroup.dom.container).unbind('dtsb-redrawContents');
+	        $$2(this.s.topGroup.dom.container).on('dtsb-redrawContents', function () {
+	            _this._checkClear();
+	            _this.s.topGroup.redrawContents();
+	            _this.s.topGroup.setupLogic();
+	            _this._setEmptyListener();
+	            var count = _this.s.topGroup.count();
+	            _this._updateTitle(count);
+	            _this._filterChanged(count);
+	            _this.s.dt.state.save();
+	        });
+	        $$2(this.s.topGroup.dom.container).unbind('dtsb-clearContents');
+	        $$2(this.s.topGroup.dom.container).on('dtsb-clearContents', function () {
+	            _this._setUp(false);
+	            _this._filterChanged(0);
+	            _this.s.dt.draw();
+	        });
+	        $$2(this.s.topGroup.dom.container).on('dtsb-updateTitle', function () {
+	            var count = _this.s.topGroup.count();
+	            _this._updateTitle(count);
+	            _this._filterChanged(count);
+	        });
+	    };
+	    /**
+	     * Sets listeners to check whether clearAll should be added or removed
+	     */
+	    SearchBuilder.prototype._setEmptyListener = function () {
+	        var _this = this;
+	        $$2(this.s.topGroup.dom.add).on('click', function () {
+	            _this._checkClear();
+	        });
+	        $$2(this.s.topGroup.dom.container).on('dtsb-destroy', function () {
+	            $$2(_this.dom.clearAll).remove();
+	        });
+	    };
+	    SearchBuilder.version = '1.0.1';
+	    SearchBuilder.classes = {
+	        button: 'dtsb-button',
+	        clearAll: 'dtsb-clearAll',
+	        container: 'dtsb-searchBuilder',
+	        inputButton: 'dtsb-iptbtn',
+	        title: 'dtsb-title',
+	        titleRow: 'dtsb-titleRow'
+	    };
+	    SearchBuilder.defaults = {
+	        columns: true,
+	        conditions: {
+	            'date': Criteria.dateConditions,
+	            'html': Criteria.stringConditions,
+	            'html-num': Criteria.numConditions,
+	            'html-num-fmt': Criteria.numFmtConditions,
+	            'moment': Criteria.momentDateConditions,
+	            'num': Criteria.numConditions,
+	            'num-fmt': Criteria.numFmtConditions,
+	            'string': Criteria.stringConditions
+	        },
+	        depthLimit: false,
+	        filterChanged: undefined,
+	        greyscale: false,
+	        i18n: {
+	            add: 'Add Condition',
+	            button: {
+	                0: 'Search Builder',
+	                _: 'Search Builder (%d)'
+	            },
+	            clearAll: 'Clear All',
+	            condition: 'Condition',
+	            conditions: {
+	                array: {
+	                    contains: 'Contains',
+	                    empty: 'Empty',
+	                    equals: 'Equals',
+	                    not: 'Not',
+	                    notEmpty: 'Not Empty',
+	                    without: 'Without'
+	                },
+	                date: {
+	                    after: 'After',
+	                    before: 'Before',
+	                    between: 'Between',
+	                    empty: 'Empty',
+	                    equals: 'Equals',
+	                    not: 'Not',
+	                    notBetween: 'Not Between',
+	                    notEmpty: 'Not Empty'
+	                },
+	                moment: {
+	                    after: 'After',
+	                    before: 'Before',
+	                    between: 'Between',
+	                    empty: 'Empty',
+	                    equals: 'Equals',
+	                    not: 'Not',
+	                    notBetween: 'Not Between',
+	                    notEmpty: 'Not Empty'
+	                },
+	                number: {
+	                    between: 'Between',
+	                    empty: 'Empty',
+	                    equals: 'Equals',
+	                    gt: 'Greater Than',
+	                    gte: 'Greater Than Equal To',
+	                    lt: 'Less Than',
+	                    lte: 'Less Than Equal To',
+	                    not: 'Not',
+	                    notBetween: 'Not Between',
+	                    notEmpty: 'Not Empty'
+	                },
+	                string: {
+	                    contains: 'Contains',
+	                    empty: 'Empty',
+	                    endsWith: 'Ends With',
+	                    equals: 'Equals',
+	                    not: 'Not',
+	                    notEmpty: 'Not Empty',
+	                    startsWith: 'Starts With'
+	                }
+	            },
+	            data: 'Data',
+	            deleteTitle: 'Delete filtering rule',
+	            leftTitle: 'Outdent criteria',
+	            logicAnd: 'And',
+	            logicOr: 'Or',
+	            rightTitle: 'Indent criteria',
+	            title: {
+	                0: 'Custom Search Builder',
+	                _: 'Custom Search Builder (%d)'
+	            },
+	            value: 'Value',
+	            valueJoiner: 'and'
+	        },
+	        logic: 'AND',
+	        orthogonal: {
+	            display: 'display',
+	            search: 'filter'
+	        },
+	        preDefined: false
+	    };
+	    return SearchBuilder;
+	}());
+
+	/*! SearchBuilder 1.0.1
+	 * ©2020 SpryMedia Ltd - datatables.net/license/mit
+	 */
+	// DataTables extensions common UMD. Note that this allows for AMD, CommonJS
+	// (with window and jQuery being allowed as parameters to the returned
+	// function) or just default browser loading.
+	(function (factory) {
+	    if (typeof define === 'function' && define.amd) {
+	        // AMD
+	        define(['jquery', 'datatables.net'], function ($) {
+	            return factory($, window, document);
+	        });
+	    }
+	    else if (typeof exports === 'object') {
+	        // CommonJS
+	        module.exports = function (root, $) {
+	            if (!root) {
+	                root = window;
+	            }
+	            if (!$ || !$.fn.dataTable) {
+	                $ = require('datatables.net')(root, $).$;
+	            }
+	            return factory($, root, root.document);
+	        };
+	    }
+	    else {
+	        // Browser - assume jQuery has already been loaded
+	        factory(window.jQuery, window, document);
+	    }
+	}(function ($, window, document) {
+	    setJQuery$2($);
+	    setJQuery$1($);
+	    setJQuery($);
+	    var DataTable = $.fn.dataTable;
+	    $.fn.dataTable.SearchBuilder = SearchBuilder;
+	    $.fn.DataTable.SearchBuilder = SearchBuilder;
+	    $.fn.dataTable.Group = Group;
+	    $.fn.DataTable.Group = Group;
+	    $.fn.dataTable.Criteria = Criteria;
+	    $.fn.DataTable.Criteria = Criteria;
+	    var apiRegister = $.fn.dataTable.Api.register;
+	    // Set up object for plugins
+	    $.fn.dataTable.ext.searchBuilder = {
+	        conditions: {}
+	    };
+	    $.fn.dataTable.ext.buttons.searchBuilder = {
+	        action: function (e, dt, node, config) {
+	            e.stopPropagation();
+	            this.popover(config._searchBuilder.getNode(), {
+	                align: 'dt-container'
+	            });
+	        },
+	        config: {},
+	        init: function (dt, node, config) {
+	            var sb = new $.fn.dataTable.SearchBuilder(dt, $.extend({
+	                filterChanged: function (count, text) {
+	                    dt.button(node).text(text);
+	                }
+	            }, config.config));
+	            dt.button(node).text(config.text || dt.i18n('searchBuilder.button', sb.c.i18n.button, 0));
+	            config._searchBuilder = sb;
+	        },
+	        text: null
+	    };
+	    apiRegister('searchBuilder.getDetails()', function () {
+	        var ctx = this.context[0];
+	        return ctx._searchBuilder.getDetails();
+	    });
+	    apiRegister('searchBuilder.rebuild()', function (details) {
+	        var ctx = this.context[0];
+	        ctx._searchBuilder.rebuild(details);
+	        return this;
+	    });
+	    apiRegister('searchBuilder.container()', function () {
+	        var ctx = this.context[0];
+	        return ctx._searchBuilder.getNode();
+	    });
+	    /**
+	     * Init function for SearchBuilder
+	     * @param settings the settings to be applied
+	     * @param options the options for SearchBuilder
+	     * @returns JQUERY<HTMLElement> Returns the node of the SearchBuilder
+	     */
+	    function _init(settings, options) {
+	        var api = new DataTable.Api(settings);
+	        var opts = options
+	            ? options
+	            : api.init().searchBuilder || DataTable.defaults.searchBuilder;
+	        var searchBuilder = new SearchBuilder(api, opts);
+	        var node = searchBuilder.getNode();
+	        return node;
+	    }
+	    // Attach a listener to the document which listens for DataTables initialisation
+	    // events so we can automatically initialise
+	    $(document).on('preInit.dt.dtsp', function (e, settings, json) {
+	        if (e.namespace !== 'dt') {
+	            return;
+	        }
+	        if (settings.oInit.searchBuilder ||
+	            DataTable.defaults.searchBuilder) {
+	            if (!settings._searchBuilder) {
+	                _init(settings);
+	            }
+	        }
+	    });
+	    // DataTables `dom` feature option
+	    DataTable.ext.feature.push({
+	        cFeature: 'Q',
+	        fnInit: _init
+	    });
+	    // DataTables 2 layout feature
+	    if (DataTable.ext.features) {
+	        DataTable.ext.features.register('searchBuilder', _init);
+	    }
+	}));
+
+}());

+ 131 - 0
plugins/datatables-searchbuilder/js/dataTables.searchBuilder.min.js

@@ -0,0 +1,131 @@
+(function(){var x=function(a,b,d,c){var e=b.moment?b.moment:b.dayjs?b.dayjs:null,i=function(b,d){this.c=a.extend(!0,{},i.defaults,d);var c=this.c.classPrefix,g=this.c.i18n;if(!e&&"YYYY-MM-DD"!==this.c.format)throw"DateTime: Without momentjs or dayjs only the format 'YYYY-MM-DD' can be used";"string"===typeof this.c.minDate&&(this.c.minDate=new Date(this.c.minDate));"string"===typeof this.c.maxDate&&(this.c.maxDate=new Date(this.c.maxDate));g=a('<div class="'+c+'"><div class="'+c+'-date"><div class="'+
+c+'-title"><div class="'+c+'-iconLeft"><button>'+g.previous+'</button></div><div class="'+c+'-iconRight"><button>'+g.next+'</button></div><div class="'+c+'-label"><span></span><select class="'+c+'-month"></select></div><div class="'+c+'-label"><span></span><select class="'+c+'-year"></select></div></div><div class="'+c+'-calendar"></div></div><div class="'+c+'-time"><div class="'+c+'-hours"></div><div class="'+c+'-minutes"></div><div class="'+c+'-seconds"></div></div><div class="'+c+'-error"></div></div>');
+this.dom={container:g,date:g.find("."+c+"-date"),title:g.find("."+c+"-title"),calendar:g.find("."+c+"-calendar"),time:g.find("."+c+"-time"),error:g.find("."+c+"-error"),input:a(b)};this.s={d:null,display:null,minutesRange:null,secondsRange:null,namespace:"dateime-"+i._instance++,parts:{date:null!==this.c.format.match(/[YMD]|L(?!T)|l/),time:null!==this.c.format.match(/[Hhm]|LT|LTS/),seconds:-1!==this.c.format.indexOf("s"),hours12:null!==this.c.format.match(/[haA]/)}};this.dom.container.append(this.dom.date).append(this.dom.time).append(this.dom.error);
+this.dom.date.append(this.dom.title).append(this.dom.calendar);this._constructor()};a.extend(i.prototype,{destroy:function(){this._hide(!0);this.dom.container.off().empty();this.dom.input.off(".datetime")},errorMsg:function(a){var b=this.dom.error;a?b.html(a):b.empty();return this},hide:function(){this._hide();return this},max:function(a){this.c.maxDate="string"===typeof a?new Date(a):a;this._optionsTitle();this._setCalander();return this},min:function(a){this.c.minDate="string"===typeof a?new Date(a):
+a;this._optionsTitle();this._setCalander();return this},owns:function(b){return 0<a(b).parents().filter(this.dom.container).length},val:function(a,b){if(a===c)return this.s.d;if(a instanceof Date)this.s.d=this._dateToUtc(a);else if(null===a||""===a)this.s.d=null;else if("--now"===a)this.s.d=new Date;else if("string"===typeof a)if(e){var d=e.utc(a,this.c.format,this.c.locale,this.c.strict);this.s.d=d.isValid()?d.toDate():null}else d=a.match(/(\d{4})\-(\d{2})\-(\d{2})/),this.s.d=d?new Date(Date.UTC(d[1],
+d[2]-1,d[3])):null;if(b||b===c)this.s.d?this._writeOutput():this.dom.input.val(a);this.s.d||(this.s.d=this._dateToUtc(new Date));this.s.display=new Date(this.s.d.toString());this.s.display.setUTCDate(1);this._setTitle();this._setCalander();this._setTime();return this},_constructor:function(){var d=this,c=this.c.classPrefix,g=function(){d.c.onChange.call(d,d.dom.input.val(),d.s.d,d.dom.input)};this.s.parts.date||this.dom.date.css("display","none");this.s.parts.time||this.dom.time.css("display","none");
+this.s.parts.seconds||(this.dom.time.children("div."+c+"-seconds").remove(),this.dom.time.children("span").eq(1).remove());this._optionsTitle();b.allan=this;"hidden"===this.dom.input.attr("type")&&(this.dom.container.addClass("inline"),this.c.attachTo="input",this.val(this.dom.input.val(),!1),this._show());this.dom.input.attr("autocomplete","off").on("focus.datetime click.datetime",function(){if(!d.dom.container.is(":visible")&&!d.dom.input.is(":disabled")){d.val(d.dom.input.val(),false);d._show()}}).on("keyup.datetime",
+function(){d.dom.container.is(":visible")&&d.val(d.dom.input.val(),false)});this.dom.container.on("change","select",function(){var b=a(this),e=b.val();if(b.hasClass(c+"-month")){d._correctMonth(d.s.display,e);d._setTitle();d._setCalander()}else if(b.hasClass(c+"-year")){d.s.display.setUTCFullYear(e);d._setTitle();d._setCalander()}else if(b.hasClass(c+"-hours")||b.hasClass(c+"-ampm")){if(d.s.parts.hours12){b=a(d.dom.container).find("."+c+"-hours").val()*1;e=a(d.dom.container).find("."+c+"-ampm").val()===
+"pm";d.s.d.setUTCHours(b===12&&!e?0:e&&b!==12?b+12:b)}else d.s.d.setUTCHours(e);d._setTime();d._writeOutput(true);g()}else if(b.hasClass(c+"-minutes")){d.s.d.setUTCMinutes(e);d._setTime();d._writeOutput(true);g()}else if(b.hasClass(c+"-seconds")){d.s.d.setSeconds(e);d._setTime();d._writeOutput(true);g()}d.dom.input.focus();d._position()}).on("click",function(b){var e=d.s.d,i=b.target.nodeName.toLowerCase(),h=i==="span"?b.target.parentNode:b.target,i=h.nodeName.toLowerCase();if(i!=="select"){b.stopPropagation();
+if(i==="button"){h=a(h);b=h.parent();if(b.hasClass("disabled")&&!b.hasClass("range"))h.blur();else if(b.hasClass(c+"-iconLeft")){d.s.display.setUTCMonth(d.s.display.getUTCMonth()-1);d._setTitle();d._setCalander();d.dom.input.focus()}else if(b.hasClass(c+"-iconRight")){d._correctMonth(d.s.display,d.s.display.getUTCMonth()+1);d._setTitle();d._setCalander();d.dom.input.focus()}else{if(h.parents("."+c+"-time").length){i=h.data("value");h=h.data("unit");if(h==="minutes"){if(b.hasClass("disabled")&&b.hasClass("range")){d.s.minutesRange=
+i;d._setTime();return}d.s.minutesRange=null}if(h==="seconds"){if(b.hasClass("disabled")&&b.hasClass("range")){d.s.secondsRange=i;d._setTime();return}d.s.secondsRange=null}if(i==="am")if(e.getUTCHours()>=12)i=e.getUTCHours()-12;else return;else if(i==="pm")if(e.getUTCHours()<12)i=e.getUTCHours()+12;else return;e[h==="hours"?"setUTCHours":h==="minutes"?"setUTCMinutes":"setSeconds"](i);d._setTime();d._writeOutput(true)}else{e||(e=d._dateToUtc(new Date));e.setUTCDate(1);e.setUTCFullYear(h.data("year"));
+e.setUTCMonth(h.data("month"));e.setUTCDate(h.data("day"));d._writeOutput(true);d.s.parts.time?d._setCalander():setTimeout(function(){d._hide()},10)}g()}}else d.dom.input.focus()}})},_compareDates:function(a,b){return this._dateToUtcString(a)===this._dateToUtcString(b)},_correctMonth:function(a,b){var d=this._daysInMonth(a.getUTCFullYear(),b),c=a.getUTCDate()>d;a.setUTCMonth(b);c&&(a.setUTCDate(d),a.setUTCMonth(b))},_daysInMonth:function(a,b){return[31,0===a%4&&(0!==a%100||0===a%400)?29:28,31,30,
+31,30,31,31,30,31,30,31][b]},_dateToUtc:function(a){return new Date(Date.UTC(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds()))},_dateToUtcString:function(a){return a.getUTCFullYear()+"-"+this._pad(a.getUTCMonth()+1)+"-"+this._pad(a.getUTCDate())},_hide:function(c){if(c||"hidden"!==this.dom.input.attr("type"))c=this.s.namespace,this.dom.container.detach(),a(b).off("."+c),a(d).off("keydown."+c),a("div.dataTables_scrollBody").off("scroll."+c),a("div.DTE_Body_Content").off("scroll."+
+c),a("body").off("click."+c)},_hours24To12:function(a){return 0===a?12:12<a?a-12:a},_htmlDay:function(a){if(a.empty)return'<td class="empty"></td>';var b=["selectable"],d=this.c.classPrefix;a.disabled&&b.push("disabled");a.today&&b.push("now");a.selected&&b.push("selected");return'<td data-day="'+a.day+'" class="'+b.join(" ")+'"><button class="'+d+"-button "+d+'-day" type="button" data-year="'+a.year+'" data-month="'+a.month+'" data-day="'+a.day+'"><span>'+a.day+"</span></button></td>"},_htmlMonth:function(b,
+d){var c=this._dateToUtc(new Date),g=this._daysInMonth(b,d),e=(new Date(Date.UTC(b,d,1))).getUTCDay(),i=[],h=[];0<this.c.firstDay&&(e-=this.c.firstDay,0>e&&(e+=7));for(var f=g+e,j=f;7<j;)j-=7;var f=f+(7-j),k=this.c.minDate,j=this.c.maxDate;k&&(k.setUTCHours(0),k.setUTCMinutes(0),k.setSeconds(0));j&&(j.setUTCHours(23),j.setUTCMinutes(59),j.setSeconds(59));for(var l=0,n=0;l<f;l++){var m=new Date(Date.UTC(b,d,1+(l-e))),o=this.s.d?this._compareDates(m,this.s.d):!1,z=this._compareDates(m,c),q=l<e||l>=
+g+e,w=k&&m<k||j&&m>j,t=this.c.disableDays;Array.isArray(t)&&-1!==a.inArray(m.getUTCDay(),t)?w=!0:"function"===typeof t&&!0===t(m)&&(w=!0);h.push(this._htmlDay({day:1+(l-e),month:d,year:b,selected:o,today:z,disabled:w,empty:q}));7===++n&&(this.c.showWeekNumber&&h.unshift(this._htmlWeekOfYear(l-e,d,b)),i.push("<tr>"+h.join("")+"</tr>"),h=[],n=0)}c=this.c.classPrefix;g=c+"-table";this.c.showWeekNumber&&(g+=" weekNumber");k&&(k=k>=new Date(Date.UTC(b,d,1,0,0,0)),this.dom.title.find("div."+c+"-iconLeft").css("display",
+k?"none":"block"));j&&(j=j<new Date(Date.UTC(b,d+1,1,0,0,0)),this.dom.title.find("div."+c+"-iconRight").css("display",j?"none":"block"));return'<table class="'+g+'"><thead>'+this._htmlMonthHead()+"</thead><tbody>"+i.join("")+"</tbody></table>"},_htmlMonthHead:function(){var a=[],b=this.c.firstDay,d=this.c.i18n,c=function(a){for(a+=b;7<=a;)a-=7;return d.weekdays[a]};this.c.showWeekNumber&&a.push("<th></th>");for(var g=0;7>g;g++)a.push("<th>"+c(g)+"</th>");return a.join("")},_htmlWeekOfYear:function(a,
+b,d){a=new Date(d,b,a,0,0,0,0);a.setDate(a.getDate()+4-(a.getDay()||7));d=Math.ceil(((a-new Date(d,0,1))/864E5+1)/7);return'<td class="'+this.c.classPrefix+'-week">'+d+"</td>"},_options:function(a,b,d){d||(d=b);a=this.dom.container.find("select."+this.c.classPrefix+"-"+a);a.empty();for(var c=0,g=b.length;c<g;c++)a.append('<option value="'+b[c]+'">'+d[c]+"</option>")},_optionSet:function(a,b){var d=this.dom.container.find("select."+this.c.classPrefix+"-"+a),c=d.parent().children("span");d.val(b);d=
+d.find("option:selected");c.html(0!==d.length?d.text():this.c.i18n.unknown)},_optionsTime:function(b,d,c,g,e){var i=this.c.classPrefix,h=this.dom.container.find("div."+i+"-"+b),f,j=12===d?function(a){return a}:this._pad,i=this.c.classPrefix,k=i+"-table",l=this.c.i18n;if(h.length){var n="";f=10;var m=function(e,h,f){12===d&&"number"===typeof e&&(12<=c&&(e+=12),12==e?e=0:24==e&&(e=12));var j=c===e||"am"===e&&12>c||"pm"===e&&12<=c?"selected":"";g&&-1===a.inArray(e,g)&&(j+=" disabled");f&&(j+=" "+f);
+return'<td class="selectable '+j+'"><button class="'+i+"-button "+i+'-day" type="button" data-unit="'+b+'" data-value="'+e+'"><span>'+h+"</span></button></td>"};if(12===d){n+="<tr>";for(e=1;6>=e;e++)n+=m(e,j(e));n+=m("am",l.amPm[0]);n+="</tr><tr>";for(e=7;12>=e;e++)n+=m(e,j(e));n+=m("pm",l.amPm[1]);n+="</tr>";f=7}else{if(24===d){var o=0;for(f=0;4>f;f++){n+="<tr>";for(e=0;6>e;e++)n+=m(o,j(o)),o++;n+="</tr>"}}else{n+="<tr>";for(f=0;60>f;f+=10)n+=m(f,j(f),"range");e=null!==e?e:10*Math.floor(c/10);n=
+n+"</tr>"+('</tbody></thead><table class="'+k+" "+k+'-nospace"><tbody>')+"<tr>";for(f=e+1;f<e+10;f++)n+=m(f,j(f));n+="</tr>"}f=6}h.empty().append('<table class="'+k+'"><thead><tr><th colspan="'+f+'">'+l[b]+"</th></tr></thead><tbody>"+n+"</tbody></table>")}},_optionsTitle:function(){var a=this.c.i18n,b=this.c.minDate,d=this.c.maxDate,b=b?b.getFullYear():null,d=d?d.getFullYear():null,b=null!==b?b:(new Date).getFullYear()-this.c.yearRange,d=null!==d?d:(new Date).getFullYear()+this.c.yearRange;this._options("month",
+this._range(0,11),a.months);this._options("year",this._range(b,d))},_pad:function(a){return 10>a?"0"+a:a},_position:function(){var d="input"===this.c.attachTo?this.dom.input.position():this.dom.input.offset(),c=this.dom.container,e=this.dom.input.outerHeight();if(c.hasClass("inline"))c.insertAfter(this.dom.input);else{this.s.parts.date&&this.s.parts.time&&550<a(b).width()?c.addClass("horizontal"):c.removeClass("horizontal");"input"===this.c.attachTo?c.css({top:d.top+e,left:d.left}).insertAfter(this.dom.input):
+c.css({top:d.top+e,left:d.left}).appendTo("body");var g=c.outerHeight(),i=c.outerWidth(),h=a(b).scrollTop();d.top+e+g-h>a(b).height()&&(e=d.top-g,c.css("top",0>e?0:e));i+d.left>a(b).width()&&(d=a(b).width()-i,"input"===this.c.attachTo&&(d-=a(c).offsetParent().offset().left),c.css("left",0>d?0:d))}},_range:function(a,b,d){var c=[];for(d||(d=1);a<=b;a+=d)c.push(a);return c},_setCalander:function(){this.s.display&&this.dom.calendar.empty().append(this._htmlMonth(this.s.display.getUTCFullYear(),this.s.display.getUTCMonth()))},
+_setTitle:function(){this._optionSet("month",this.s.display.getUTCMonth());this._optionSet("year",this.s.display.getUTCFullYear())},_setTime:function(){var a=this,b=this.s.d,d=b?b.getUTCHours():0,c=function(b){return a.c[b+"Available"]?a.c[b+"Available"]:a._range(0,59,a.c[b+"Increment"])};this._optionsTime("hours",this.s.parts.hours12?12:24,d,this.c.hoursAvailable);this._optionsTime("minutes",60,b?b.getUTCMinutes():0,c("minutes"),this.s.minutesRange);this._optionsTime("seconds",60,b?b.getSeconds():
+0,c("seconds"),this.s.secondsRange)},_show:function(){var c=this,e=this.s.namespace;this._position();a(b).on("scroll."+e+" resize."+e,function(){c._hide()});a("div.DTE_Body_Content").on("scroll."+e,function(){c._hide()});a("div.dataTables_scrollBody").on("scroll."+e,function(){c._hide()});var g=this.dom.input[0].offsetParent;if(g!==d.body)a(g).on("scroll."+e,function(){c._hide()});a(d).on("keydown."+e,function(a){(9===a.keyCode||27===a.keyCode||13===a.keyCode)&&c._hide()});setTimeout(function(){a("body").on("click."+
+e,function(b){!a(b.target).parents().filter(c.dom.container).length&&b.target!==c.dom.input[0]&&c._hide()})},10)},_writeOutput:function(a){var b=this.s.d,d=e?e.utc(b,c,this.c.locale,this.c.strict).format(this.c.format):b.getUTCFullYear()+"-"+this._pad(b.getUTCMonth()+1)+"-"+this._pad(b.getUTCDate());this.dom.input.val(d).trigger("change",{write:b});"hidden"===this.dom.input.attr("type")&&this.val(d,!1);a&&this.dom.input.focus()}});i.use=function(a){e=a};i._instance=0;i.defaults={attachTo:"body",classPrefix:"dt-datetime",
+disableDays:null,firstDay:1,format:"YYYY-MM-DD",hoursAvailable:null,i18n:{previous:"Previous",next:"Next",months:"January February March April May June July August September October November December".split(" "),weekdays:"Sun Mon Tue Wed Thu Fri Sat".split(" "),amPm:["am","pm"],hours:"Hour",minutes:"Minute",seconds:"Second",unknown:"-"},maxDate:null,minDate:null,minutesAvailable:null,minutesIncrement:1,strict:!0,locale:"en",onChange:function(){},secondsAvailable:null,secondsIncrement:1,showWeekNumber:!1,
+yearRange:25};i.version="1.0.1";b.DateTime||(b.DateTime=i);a.fn.dtDateTime=function(a){return this.each(function(){new i(this,a)})};a.fn.dataTable&&(a.fn.dataTable.DateTime=i,a.fn.DataTable.DateTime=i);return i};"function"===typeof define&&define.amd?define(["jquery"],function(a){return x(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);return x(b,a,a.document)}:x(jQuery,window,document);var e,q,o=window.moment,l,c=function(a,b,d,g,h){var i=this;void 0===g&&
+(g=0);void 0===h&&(h=1);if(!q||!q.versionCheck||!q.versionCheck("1.10.0"))throw Error("SearchPane requires DataTables 1.10 or newer");this.classes=e.extend(!0,{},c.classes);this.c=e.extend(!0,{},c.defaults,e.fn.dataTable.ext.searchBuilder,b);b=this.c.i18n;this.s={condition:void 0,conditions:{},data:void 0,dataIdx:-1,dataPoints:[],depth:h,dt:a,filled:!1,index:g,momentFormat:!1,topGroup:d,type:"",value:[]};this.dom={buttons:e("<div/>").addClass(this.classes.buttonContainer),condition:e("<select disabled/>").addClass(this.classes.condition).addClass(this.classes.dropDown).addClass(this.classes.italic).attr("autocomplete",
+"hacking"),conditionTitle:e('<option value="" disabled selected hidden/>').text(this.s.dt.i18n("searchBuilder.condition",b.condition)),container:e("<div/>").addClass(this.classes.container),data:e("<select/>").addClass(this.classes.data).addClass(this.classes.dropDown).addClass(this.classes.italic),dataTitle:e('<option value="" disabled selected hidden/>').text(this.s.dt.i18n("searchBuilder.data",b.data)),defaultValue:e("<select disabled/>").addClass(this.classes.value).addClass(this.classes.dropDown),
+"delete":e("<button>&times</button>").addClass(this.classes["delete"]).addClass(this.classes.button).attr("title",this.s.dt.i18n("searchBuilder.deleteTitle",b.deleteTitle)).attr("type","button"),left:e("<button><</button>").addClass(this.classes.left).addClass(this.classes.button).attr("title",this.s.dt.i18n("searchBuilder.leftTitle",b.leftTitle)).attr("type","button"),right:e("<button>></button>").addClass(this.classes.right).addClass(this.classes.button).attr("title",this.s.dt.i18n("searchBuilder.rightTitle",
+b.rightTitle)).attr("type","button"),value:[e("<select disabled/>").addClass(this.classes.value).addClass(this.classes.dropDown).addClass(this.classes.italic)],valueTitle:e('<option value="--valueTitle--" selected/>').text(this.s.dt.i18n("searchBuilder.value",b.value))};if(this.c.greyscale){e(this.dom.data).addClass(this.classes.greyscale);e(this.dom.condition).addClass(this.classes.greyscale);e(this.dom.defaultValue).addClass(this.classes.greyscale);a=0;for(d=this.dom.value;a<d.length;a++)e(d[a]).addClass(this.classes.greyscale)}this.s.dt.on("draw.dtsp",
+function(){i._adjustCriteria()});this.s.dt.on("buttons-action",function(){i._adjustCriteria()});e(window).on("resize.dtsp",q.util.throttle(function(){i._adjustCriteria()}));this._buildCriteria();return this};c.prototype.updateArrows=function(a,b){void 0===a&&(a=!1);void 0===b&&(b=!0);e(this.dom.container).empty().append(this.dom.data).append(this.dom.condition).append(this.dom.value[0]);e(this.dom.value[0]).trigger("dtsb-inserted");for(var d=1;d<this.dom.value.length;d++)e(this.dom.container).append(this.dom.value[d]),
+e(this.dom.value[d]).trigger("dtsb-inserted");1<this.s.depth&&e(this.dom.buttons).append(this.dom.left);(!1===this.c.depthLimit||this.s.depth<this.c.depthLimit)&&a?e(this.dom.buttons).append(this.dom.right):e(this.dom.right).remove();e(this.dom.buttons).append(this.dom["delete"]);e(this.dom.container).append(this.dom.buttons);b&&this._adjustCriteria()};c.prototype.destroy=function(){e(this.dom.data).off(".dtsb");e(this.dom.condition).off(".dtsb");e(this.dom["delete"]).off(".dtsb");for(var a=0,b=this.dom.value;a<
+b.length;a++)e(b[a]).off(".dtsb");e(this.dom.container).remove()};c.prototype.search=function(a,b){var d=this.s.conditions[this.s.condition];if(void 0!==this.s.condition&&void 0!==d){-1!==this.s.type.indexOf("num")&&""!==this.s.dt.settings()[0].oLanguage.sDecimal&&(a[this.s.dataIdx]=a[this.s.dataIdx].replace(this.s.dt.settings()[0].oLanguage.sDecimal,"."));var c=a[this.s.dataIdx];"search"!==this.c.orthogonal.search&&(c=this.s.dt.settings()[0],c=c.oApi._fnGetCellData(c,b,this.s.dataIdx,"string"===
+typeof this.c.orthogonal?this.c.orthogonal:this.c.orthogonal.search));"array"===this.s.type&&(Array.isArray(c)||(c=[c]),c.sort());return d.search(c,this.s.value,this)}};c.prototype.getDetails=function(){var a=this.s.value;if(-1!==this.s.type.indexOf("num")&&""!==this.s.dt.settings()[0].oLanguage.sDecimal)for(var b=0;b<this.s.value.length;b++)-1!==this.s.value[b].indexOf(".")&&(a[b]=this.s.value[b].replace(".",this.s.dt.settings()[0].oLanguage.sDecimal));return{condition:this.s.condition,data:this.s.data,
+value:a}};c.prototype.getNode=function(){return this.dom.container};c.prototype.populate=function(){this._populateData();-1!==this.s.dataIdx&&(this._populateCondition(),void 0!==this.s.condition&&this._populateValue())};c.prototype.rebuild=function(a){var b=!1,d;this._populateData();if(void 0!==a.data){var c=this.classes.italic,h=this.dom.data;e(this.dom.data).children("option").each(function(){e(this).text()===a.data&&(e(this).attr("selected",!0),e(h).removeClass(c),b=!0,d=e(this).val())})}if(b){this.s.data=
+a.data;this.s.dataIdx=d;e(this.dom.dataTitle).remove();this._populateCondition();e(this.dom.conditionTitle).remove();var i;e(this.dom.condition).children("option").each(function(){void 0!==a.condition&&(e(this).val()===a.condition&&"string"===typeof a.condition)&&(e(this).attr("selected",!0),i=e(this).val())});this.s.condition=i;void 0!==this.s.condition?(e(this.dom.conditionTitle).remove(),e(this.dom.condition).removeClass(this.classes.italic),this._populateValue(a)):e(this.dom.conditionTitle).prependTo(this.dom.condition).attr("selected",
+!0)}};c.prototype.setListeners=function(){var a=this;e(this.dom.data).unbind("input change").on("input change",function(){e(a.dom.dataTitle).attr("selected",!1);e(a.dom.data).removeClass(a.classes.italic);a.s.dataIdx=e(a.dom.data).children("option:selected").val();a.s.data=e(a.dom.data).children("option:selected").text();a.c.orthogonal=a._getOptions().orthogonal;a._clearCondition();a._clearValue();a._populateCondition();a.s.filled&&(a.s.filled=!1,a.s.dt.draw(),a.setListeners());a.s.dt.state.save()});
+e(this.dom.condition).unbind("input change").on("input change",function(){e(a.dom.conditionTitle).attr("selected",!1);e(a.dom.condition).removeClass(a.classes.italic);for(var b=e(a.dom.condition).children("option:selected").val(),d=0,c=Object.keys(a.s.conditions);d<c.length;d++)if(c[d]===b){a.s.condition=b;break}a._clearValue();a._populateValue();b=0;for(d=a.dom.value;b<d.length;b++)c=d[b],a.s.filled&&0!==e(a.dom.container).has(c).length&&(a.s.filled=!1,a.s.dt.draw(),a.setListeners());a.s.dt.draw()})};
+c.prototype._adjustCriteria=function(){if(0!==e(document).has(this.dom.container).length){var a,b;a=this.dom.value[this.dom.value.length-1];if(0!==e(this.dom.container).has(a).length){b=e(a).outerWidth(!0);a=e(a).offset().left+b;var d=e(this.dom.left).offset(),c=e(this.dom.right).offset(),h=e(this.dom["delete"]).offset(),i=0!==e(this.dom.container).has(this.dom.left).length,f=0!==e(this.dom.container).has(this.dom.right).length,j=i?d.left:f?c.left:h.left;15>j-a||i&&d.top!==h.top||f&&c.top!==h.top?
+(e(this.dom.container).parent().addClass(this.classes.vertical),e(this.s.topGroup).trigger("dtsb-redrawContents")):15<j-(e(this.dom.data).offset().left+e(this.dom.data).outerWidth(!0)+e(this.dom.condition).outerWidth(!0)+b)&&(e(this.dom.container).parent().removeClass(this.classes.vertical),e(this.s.topGroup).trigger("dtsb-redrawContents"))}}};c.prototype._buildCriteria=function(){e(this.dom.data).append(this.dom.dataTitle);e(this.dom.condition).append(this.dom.conditionTitle);e(this.dom.container).append(this.dom.data).append(this.dom.condition);
+for(var a=0,b=this.dom.value;a<b.length;a++){var d=b[a];e(d).append(this.dom.valueTitle);e(this.dom.container).append(d)}e(this.dom.container).append(this.dom["delete"]).append(this.dom.right);this.setListeners()};c.prototype._clearCondition=function(){e(this.dom.condition).empty();e(this.dom.conditionTitle).attr("selected",!0).attr("disabled",!0);e(this.dom.condition).prepend(this.dom.conditionTitle).prop("selectedIndex",0);this.s.conditions={};this.s.condition=void 0};c.prototype._clearValue=function(){if(void 0!==
+this.s.condition){for(var a=0,b=this.dom.value;a<b.length;a++){var d=b[a];e(d).remove()}this.dom.value=[].concat(this.s.conditions[this.s.condition].init(this,c.updateListener));e(this.dom.value[0]).insertAfter(this.dom.condition).trigger("dtsb-inserted");for(d=1;d<this.dom.value.length;d++)e(this.dom.value[d]).insertAfter(this.dom.value[d-1]).trigger("dtsb-inserted")}else{a=0;for(b=this.dom.value;a<b.length;a++)d=b[a],e(d).remove();e(this.dom.valueTitle).attr("selected",!0);e(this.dom.defaultValue).append(this.dom.valueTitle).insertAfter(this.dom.condition)}this.s.value=
+[]};c.prototype._getOptions=function(){return e.extend(!0,{},c.defaults,this.s.dt.settings()[0].aoColumns[this.s.dataIdx].searchBuilder)};c.prototype._populateCondition=function(){var a=[],b=Object.keys(this.s.conditions).length;if(0===b){b=e(this.dom.data).children("option:selected").val();this.s.type=this.s.dt.columns().type().toArray()[b];null===this.s.type&&(this.s.dt.draw(),this.setListeners(),this.s.type=this.s.dt.columns().type().toArray()[b]);e(this.dom.condition).attr("disabled",!1).empty().append(this.dom.conditionTitle).addClass(this.classes.italic);
+e(this.dom.conditionTitle).attr("selected",!0);b=this.s.dt.settings()[0].oLanguage.sDecimal;""!==b&&this.s.type.indexOf(b)===this.s.type.length-b.length&&(-1!==this.s.type.indexOf("num-fmt")?this.s.type=this.s.type.replace(b,""):-1!==this.s.type.indexOf("num")&&(this.s.type=this.s.type.replace(b,"")));var d=void 0!==this.c.conditions[this.s.type]?this.c.conditions[this.s.type]:-1!==this.s.type.indexOf("moment")?this.c.conditions.moment:this.c.conditions.string;-1!==this.s.type.indexOf("moment")&&
+(this.s.momentFormat=this.s.type.replace(/moment\-/g,""));for(var c=0,h=Object.keys(d);c<h.length;c++){var i=h[c];null!==d[i]&&(this.s.conditions[i]=d[i],b=d[i].conditionName,"function"===typeof b&&(b=b(this.s.dt,this.c.i18n)),a.push(e("<option>",{text:b,value:i}).addClass(this.classes.option).addClass(this.classes.notItalic)))}}else if(0<b){e(this.dom.condition).empty().attr("disabled",!1).addClass(this.classes.italic);d=0;for(c=Object.keys(this.s.conditions);d<c.length;d++)i=c[d],b=this.s.conditions[i].conditionName,
+"function"===typeof b&&(b=b(this.s.dt,this.c.i18n)),i=e("<option>",{text:b,value:i}).addClass(this.classes.option).addClass(this.classes.notItalic),void 0!==this.s.condition&&this.s.condition===b&&(e(i).attr("selected",!0),e(this.dom.condition).removeClass(this.classes.italic)),a.push(i)}else{e(this.dom.condition).attr("disabled",!0).addClass(this.classes.italic);return}for(b=0;b<a.length;b++)i=a[b],e(this.dom.condition).append(i);e(this.dom.condition).prop("selectedIndex",0)};c.prototype._populateData=
+function(){var a=this;e(this.dom.data).empty().append(this.dom.dataTitle);if(0===this.s.dataPoints.length)this.s.dt.columns().every(function(b){if(!0===a.c.columns||-1!==a.s.dt.columns(a.c.columns).indexes().toArray().indexOf(b)){for(var d=!1,c=0,g=a.s.dataPoints;c<g.length;c++)if(g[c].index===b){d=!0;break}d||(b={text:a.s.dt.settings()[0].aoColumns[b].sTitle,index:b},a.s.dataPoints.push(b),e(a.dom.data).append(e("<option>",{text:b.text,value:b.index}).addClass(a.classes.option).addClass(a.classes.notItalic)))}});
+else for(var b=function(b){d.s.dt.columns().every(function(d){a.s.dt.settings()[0].aoColumns[d].sTitle===b.text&&(b.index=d)});var c=e("<option>",{text:b.text,value:b.index}).addClass(d.classes.option).addClass(d.classes.notItalic);d.s.data===b.text&&(d.s.dataIdx=b.index,e(c).attr("selected",!0),e(d.dom.data).removeClass(d.classes.italic));e(d.dom.data).append(c)},d=this,c=0,h=this.s.dataPoints;c<h.length;c++)b(h[c])};c.prototype._populateValue=function(a){var b=this,d=this.s.filled;this.s.filled=
+!1;e(this.dom.defaultValue).remove();for(var g=0,h=this.dom.value;g<h.length;g++)e(h[g]).remove();g=e(this.dom.container).children();if(3<g.length)for(h=2;h<g.length-1;h++)e(g[h]).remove();void 0!==a&&this.s.dt.columns().every(function(d){b.s.dt.settings()[0].aoColumns[d].sTitle===a.data&&(b.s.dataIdx=d)});this.dom.value=[].concat(this.s.conditions[this.s.condition].init(this,c.updateListener,void 0!==a?a.value:void 0));void 0!==a&&void 0!==a.value&&(this.s.value=a.value);e(this.dom.value[0]).insertAfter(this.dom.condition).trigger("dtsb-inserted");
+for(h=1;h<this.dom.value.length;h++)e(this.dom.value[h]).insertAfter(this.dom.value[h-1]).trigger("dtsb-inserted");this.s.filled=this.s.conditions[this.s.condition].isInputValid(this.dom.value,this);this.setListeners();d!==this.s.filled&&(this.s.dt.draw(),this.setListeners())};c.version="1.0.0";c.classes={button:"dtsb-button",buttonContainer:"dtsb-buttonContainer",condition:"dtsb-condition",container:"dtsb-criteria",data:"dtsb-data","delete":"dtsb-delete",dropDown:"dtsb-dropDown",greyscale:"dtsb-greyscale",
+input:"dtsb-input",italic:"dtsb-italic",joiner:"dtsp-joiner",left:"dtsb-left",notItalic:"dtsb-notItalic",option:"dtsb-option",right:"dtsb-right",value:"dtsb-value",vertical:"dtsb-vertical"};c.initSelect=function(a,b,d,g){void 0===d&&(d=null);void 0===g&&(g=!1);var h=e(a.dom.data).children("option:selected").val(),i=a.s.dt.rows().indexes().toArray(),f=a.s.dt.settings()[0],j=e("<select/>").addClass(c.classes.value).addClass(c.classes.dropDown).addClass(c.classes.italic).append(a.dom.valueTitle).on("input change",
+function(){e(this).removeClass(c.classes.italic);b(a,this)});a.c.greyscale&&e(j).addClass(c.classes.greyscale);for(var k=[],l=[],m=0;m<i.length;m++){var o=i[m],p=f.oApi._fnGetCellData(f,o,h,"string"===typeof a.c.orthogonal?a.c.orthogonal:a.c.orthogonal.search),p="string"===typeof p?p.replace(/[\r\n\u2028]/g," "):p,o=f.oApi._fnGetCellData(f,o,h,"string"===typeof a.c.orthogonal?a.c.orthogonal:a.c.orthogonal.display);"array"===a.s.type&&(p=!Array.isArray(p)?[p]:p=p.sort(),o=!Array.isArray(o)?[o]:o=o.sort());
+var q=function(b,g){var h=e("<option>",{text:typeof g==="string"?g.replace(/(<([^>]+)>)/ig,""):g,type:Array.isArray(b)?"Array":"String",value:a.s.type.indexOf("html")!==-1&&b!==null&&typeof b==="string"?b.replace(/(<([^>]+)>)/ig,""):b}).addClass(a.classes.option).addClass(a.classes.notItalic),f=e(h).val();if(k.indexOf(f)===-1){k.push(f);l.push(h);d!==null&&Array.isArray(d[0])&&(d[0]=d[0].sort().join(","));if(d!==null&&h.val()===d[0]){h.attr("selected",true);e(j).removeClass(c.classes.italic)}}};if(g)for(var r=
+0;r<p.length;r++)q(p[r],o[r]);else q(p,o)}l.sort(function(b,d){if("string"===a.s.type||"num"===a.s.type||"html"===a.s.type||"html-num"===a.s.type)return e(b).val()<e(d).val()?-1:e(b).val()<e(d).val()?1:0;if("num-fmt"===a.s.type||"html-num-fmt"===a.s.type)return+e(b).val().replace(/[^0-9.]/g,"")<+e(d).val().replace(/[^0-9.]/g,"")?-1:+e(b).val().replace(/[^0-9.]/g,"")<+e(d).val().replace(/[^0-9.]/g,"")?1:0});for(g=0;g<l.length;g++)h=l[g],e(j).append(h);return j};c.initSelectArray=function(a,b,d){void 0===
+d&&(d=null);return c.initSelect(a,b,d,!0)};c.initInput=function(a,b,d){void 0===d&&(d=null);var g=e("<input/>").addClass(c.classes.value).addClass(c.classes.input).on("input",function(){b(a,this)});a.c.greyscale&&e(g).addClass(c.classes.greyscale);null!==d&&e(g).val(d[0]);return g};c.init2Input=function(a,b,d){void 0===d&&(d=null);var g=[e("<input/>").addClass(c.classes.value).addClass(c.classes.input).on("input",function(){b(a,this)}),e("<span>").addClass(a.classes.joiner).text(a.s.dt.i18n("searchBuilder.valueJoiner",
+a.c.i18n.valueJoiner)),e("<input/>").addClass(c.classes.value).addClass(c.classes.input).on("input",function(){b(a,this)})];a.c.greyscale&&(e(g[0]).addClass(c.classes.greyscale),e(g[2]).addClass(c.classes.greyscale));null!==d&&(e(g[0]).val(d[0]),e(g[2]).val(d[1]));a.s.dt.off("draw");a.s.dt.one("draw",function(){e(a.s.topGroup).trigger("dtsb-redrawContents")});return g};c.initDate=function(a,b,d){void 0===d&&(d=null);var g=e("<input/>").addClass(c.classes.value).addClass(c.classes.input).dtDateTime({attachTo:"input",
+format:a.s.momentFormat?a.s.momentFormat:void 0}).on("input change",function(){b(a,this)});a.c.greyscale&&e(g).addClass(c.classes.greyscale);null!==d&&e(g).val(d[0]);return g};c.initNoValue=function(a){a.s.dt.off("draw");a.s.dt.one("draw",function(){e(a.s.topGroup).trigger("dtsb-redrawContents")})};c.init2Date=function(a,b,d){void 0===d&&(d=null);var g=[e("<input/>").addClass(c.classes.value).addClass(c.classes.input).dtDateTime({attachTo:"input",format:a.s.momentFormat?a.s.momentFormat:void 0}).on("input change",
+function(){b(a,this)}),e("<span>").addClass(a.classes.joiner).text(a.s.dt.i18n("searchBuilder.valueJoiner",a.c.i18n.valueJoiner)),e("<input/>").addClass(c.classes.value).addClass(c.classes.input).dtDateTime({attachTo:"input",format:a.s.momentFormat?a.s.momentFormat:void 0}).on("input change",function(){b(a,this)})];a.c.greyscale&&(e(g[0]).addClass(c.classes.greyscale),e(g[2]).addClass(c.classes.greyscale));null!==d&&0<d.length&&(e(g[0]).val(d[0]),e(g[2]).val(d[1]));a.s.dt.off("draw");a.s.dt.one("draw",
+function(){e(a.s.topGroup).trigger("dtsb-redrawContents")});return g};c.isInputValidSelect=function(a){for(var b=!0,d=0;d<a.length;d++){var g=a[d];e(g).children("option:selected").length===e(g).children("option").length-e(g).children("option."+c.classes.notItalic).length&&(1===e(g).children("option:selected").length&&e(g).children("option:selected")[0]===e(g).children("option:hidden")[0])&&(b=!1)}return b};c.isInputValidInput=function(a){for(var b=!0,d=0;d<a.length;d++){var c=a[d];e(c).is("input")&&
+0===e(c).val().length&&(b=!1)}return b};c.inputValueSelect=function(a){for(var b=[],d=0;d<a.length;d++){var c=a[d];if(e(c).is("select")){var h=e(c).children("option:selected").val();b.push("Array"===e(c).children("option:selected").attr("type")?h.split(",").sort():h)}}return b};c.inputValueInput=function(a){for(var b=[],d=0;d<a.length;d++){var c=a[d];e(c).is("input")&&b.push(e(c).val())}return b};c.updateListener=function(a,b){var d=a.s.conditions[a.s.condition];a.s.filled=d.isInputValid(a.dom.value,
+a);a.s.value=d.inputValue(a.dom.value,a);Array.isArray(a.s.value)||(a.s.value=[a.s.value]);for(d=0;d<a.s.value.length;d++)Array.isArray(a.s.value[d])?a.s.value[d].sort():""!==a.s.dt.settings()[0].oLanguage.sDecimal&&(a.s.value[d]=a.s.value[d].replace(a.s.dt.settings()[0].oLanguage.sDecimal,"."));for(var c=null,h=null,d=0;d<a.dom.value.length;d++)b===a.dom.value[d][0]&&(c=d,void 0!==b.selectionStart&&(h=b.selectionStart));a.s.dt.draw();null!==c&&(e(a.dom.value[c]).removeClass(a.classes.italic),e(a.dom.value[c]).focus(),
+null!==h&&e(a.dom.value[c])[0].setSelectionRange(h,h))};c.dateConditions={"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.equals",b.conditions.date.equals)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return a===b[0]}},"!=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.not",b.conditions.date.not)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return a!==b[0]}},"<":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.before",b.conditions.date.before)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return a<b[0]}},">":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.after",b.conditions.date.after)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return a>b[0]}},between:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.between",b.conditions.date.between)},init:c.init2Date,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return b[0]<b[1]?b[0]<=a&&a<=b[1]:b[1]<=a&&a<=b[0]}},"!between":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.notBetween",b.conditions.date.notBetween)},init:c.init2Date,
+inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){a=a.replace(/(\/|\-|\,)/g,"-");return b[0]<b[1]?!(b[0]<=a&&a<=b[1]):!(b[1]<=a&&a<=b[0])}},"null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.empty",b.conditions.date.empty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.date.notEmpty",
+b.conditions.date.notEmpty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return!(null===a||void 0===a||0===a.length)}}};c.momentDateConditions={"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.equals",b.conditions.moment.equals)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b,d){return o(a,d.s.momentFormat).valueOf()===o(b[0],d.s.momentFormat).valueOf()}},"!=":{conditionName:function(a,
+b){return a.i18n("searchBuilder.conditions.moment.not",b.conditions.moment.not)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b,d){return o(a,d.s.momentFormat).valueOf()!==o(b[0],d.s.momentFormat).valueOf()}},"<":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.before",b.conditions.moment.before)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b,d){return o(a,d.s.momentFormat).valueOf()<
+o(b[0],d.s.momentFormat).valueOf()}},">":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.after",b.conditions.moment.after)},init:c.initDate,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b,d){return o(a,d.s.momentFormat).valueOf()>o(b[0],d.s.momentFormat).valueOf()}},between:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.between",b.conditions.moment.between)},init:c.init2Date,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b,d){var a=o(a,d.s.momentFormat).valueOf(),c=o(b[0],d.s.momentFormat).valueOf(),b=o(b[1],d.s.momentFormat).valueOf();return c<b?c<=a&&a<=b:b<=a&&a<=c}},"!between":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.notBetween",b.conditions.moment.notBetween)},init:c.init2Date,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b,d){var a=o(a,d.s.momentFormat).valueOf(),c=o(b[0],d.s.momentFormat).valueOf(),b=o(b[1],d.s.momentFormat).valueOf();
+return c<b?!(+c<=+a&&+a<=+b):!(+b<=+a&&+a<=+c)}},"null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.empty",b.conditions.moment.empty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.moment.notEmpty",b.conditions.moment.notEmpty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},
+search:function(a){return!(null===a||void 0===a||0===a.length)}}};c.numConditions={"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.equals",b.conditions.number.equals)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){return+a===+b[0]}},"!=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.not",b.conditions.number.not)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,
+search:function(a,b){return+a!==+b[0]}},"<":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.lt",b.conditions.number.lt)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+a<+b[0]}},"<=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.lte",b.conditions.number.lte)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+a<=+b[0]}},">=":{conditionName:function(a,
+b){return a.i18n("searchBuilder.conditions.number.gte",b.conditions.number.gte)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+a>=+b[0]}},">":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.gt",b.conditions.number.gt)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+a>+b[0]}},between:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.between",
+b.conditions.number.between)},init:c.init2Input,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+b[0]<+b[1]?+b[0]<=+a&&+a<=+b[1]:+b[1]<=+a&&+a<=+b[0]}},"!between":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.notBetween",b.conditions.number.notBetween)},init:c.init2Input,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return+b[0]<+b[1]?!(+b[0]<=+a&&+a<=+b[1]):!(+b[1]<=+a&&+a<=+b[0])}},"null":{conditionName:function(a,
+b){return a.i18n("searchBuilder.conditions.number.empty",b.conditions.number.empty)},init:c.initNoValue,inputValue:function(){},isInputValid:function(){return!0},search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.notEmpty",b.conditions.number.notEmpty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return!(null===a||void 0===a||0===a.length)}}};c.numFmtConditions=
+{"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.equals",b.conditions.number.equals)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,"");return+d===+c}},"!=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.not",b.conditions.number.not)},
+init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,"");return+d!==+c}},"<":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.lt",b.conditions.number.lt)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){var d=0===
+a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,"");return+d<+c}},"<=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.lte",b.conditions.number.lte)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,
+""):b[0].replace(/[^0-9.]/g,"");return+d<=+c}},">=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.gte",b.conditions.number.gte)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,"");return+d>=+c}},">":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.gt",
+b.conditions.number.gt)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,"");return+d>+c}},between:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.between",b.conditions.number.between)},init:c.init2Input,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,""),e=0===b[1].indexOf("-")?"-"+b[1].replace(/[^0-9.]/g,""):b[1].replace(/[^0-9.]/g,"");return+c<+e?+c<=+d&&+d<=+e:+e<=+d&&+d<=+c}},"!between":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.notBetween",b.conditions.number.notBetween)},init:c.init2Input,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b){var d=0===a.indexOf("-")?"-"+a.replace(/[^0-9.]/g,""):a.replace(/[^0-9.]/g,""),c=0===b[0].indexOf("-")?"-"+b[0].replace(/[^0-9.]/g,""):b[0].replace(/[^0-9.]/g,""),e=0===b[1].indexOf("-")?"-"+b[1].replace(/[^0-9.]/g,""):b[1].replace(/[^0-9.]/g,"");return+c<+e?!(+c<=+d&&+d<=+e):!(+e<=+d&&+d<=+c)}},"null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.empty",b.conditions.number.empty)},init:c.initNoValue,inputValue:function(){},isInputValid:function(){return!0},
+search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.number.notEmpty",b.conditions.number.notEmpty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return!(null===a||void 0===a||0===a.length)}}};c.stringConditions={"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.equals",b.conditions.string.equals)},init:c.initSelect,inputValue:c.inputValueSelect,
+isInputValid:c.isInputValidSelect,search:function(a,b){return a===b[0]}},"!=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.not",b.conditions.string.not)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidInput,search:function(a,b){return a!==b[0]}},starts:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.startsWith",b.conditions.string.startsWith)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,
+search:function(a,b){return 0===a.toLowerCase().indexOf(b[0].toLowerCase())}},contains:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.contains",b.conditions.string.contains)},init:c.initInput,inputValue:c.inputValueInput,isInputValid:c.isInputValidInput,search:function(a,b){return-1!==a.toLowerCase().indexOf(b[0].toLowerCase())}},ends:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.endsWith",b.conditions.string.endsWith)},init:c.initInput,inputValue:c.inputValueInput,
+isInputValid:c.isInputValidInput,search:function(a,b){return a.toLowerCase().endsWith(b[0].toLowerCase())}},"null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.empty",b.conditions.string.empty)},init:c.initNoValue,inputValue:function(){},isInputValid:function(){return!0},search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.string.notEmpty",b.conditions.string.notEmpty)},isInputValid:function(){return!0},
+init:c.initNoValue,inputValue:function(){},search:function(a){return!(null===a||void 0===a||0===a.length)}}};c.arrayConditions={contains:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.array.contains",b.conditions.array.contains)},init:c.initSelectArray,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){return-1!==a.indexOf(b[0])}},without:{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.array.without",b.conditions.array.without)},
+init:c.initSelectArray,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){return-1===a.indexOf(b[0])}},"=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.array.equals",b.conditions.array.equals)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){if(a.length===b[0].length){for(var d=0;d<a.length;d++)if(a[d]!==b[0][d])return!1;return!0}return!1}},"!=":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.array.not",
+b.conditions.array.not)},init:c.initSelect,inputValue:c.inputValueSelect,isInputValid:c.isInputValidSelect,search:function(a,b){if(a.length===b[0].length){for(var d=0;d<a.length;d++)if(a[d]!==b[0][d])return!0;return!1}return!0}},"null":{conditionName:function(a,b){return a.i18n("searchBuilder.conditions.array.empty",b.conditions.array.empty)},init:c.initNoValue,isInputValid:function(){return!0},inputValue:function(){},search:function(a){return null===a||void 0===a||0===a.length}},"!null":{conditionName:function(a,
+b){return a.i18n("searchBuilder.conditions.array.notEmpty",b.conditions.array.notEmpty)},isInputValid:function(){return!0},init:c.initNoValue,inputValue:function(){},search:function(a){return null!==a&&void 0!==a&&0!==a.length}}};c.defaults={columns:!0,conditions:{array:c.arrayConditions,date:c.dateConditions,html:c.stringConditions,"html-num":c.numConditions,"html-num-fmt":c.numFmtConditions,moment:c.momentDateConditions,num:c.numConditions,"num-fmt":c.numFmtConditions,string:c.stringConditions},
+depthLimit:!1,filterChanged:void 0,greyscale:!1,i18n:{add:"Add Condition",button:{"0":"Search Builder",_:"Search Builder (%d)"},clearAll:"Clear All",condition:"Condition",data:"Data",deleteTitle:"Delete filtering rule",leftTitle:"Outdent criteria",logicAnd:"And",logicOr:"Or",rightTitle:"Indent criteria",title:{"0":"Custom Search Builder",_:"Custom Search Builder (%d)"},value:"Value",valueJoiner:"and"},logic:"AND",orthogonal:{display:"display",search:"filter"},preDefined:!1};l=c;var f,u,r,k=function(a,
+b,d,c,e,i){void 0===c&&(c=0);void 0===e&&(e=!1);void 0===i&&(i=1);if(!u||!u.versionCheck||!u.versionCheck("1.10.0"))throw Error("SearchBuilder requires DataTables 1.10 or newer");this.classes=f.extend(!0,{},k.classes);this.c=f.extend(!0,{},k.defaults,b);this.s={criteria:[],depth:i,dt:a,index:c,isChild:e,logic:void 0,opts:b,toDrop:void 0,topGroup:d};this.dom={add:f("<button/>").addClass(this.classes.add).addClass(this.classes.button).attr("type","button"),clear:f("<button>&times</button>").addClass(this.classes.button).addClass(this.classes.clearGroup).attr("type",
+"button"),container:f("<div/>").addClass(this.classes.group),logic:f("<button/>").addClass(this.classes.logic).addClass(this.classes.button).attr("type","button"),logicContainer:f("<div/>").addClass(this.classes.logicContainer)};void 0===this.s.topGroup&&(this.s.topGroup=this.dom.container);this._setup();return this};k.prototype.destroy=function(){f(this.dom.add).off(".dtsb");f(this.dom.logic).off(".dtsb");f(this.dom.container).trigger("dtsb-destroy").remove();this.s.criteria=[]};k.prototype.getDetails=
+function(){if(0===this.s.criteria.length)return{};for(var a={criteria:[],logic:this.s.logic},b=0,d=this.s.criteria;b<d.length;b++)a.criteria.push(d[b].criteria.getDetails());return a};k.prototype.getNode=function(){return this.dom.container};k.prototype.rebuild=function(a){if(!(void 0===a.criteria||null===a.criteria||0===a.criteria.length)){this.s.logic=a.logic;f(this.dom.logic).text("OR"===this.s.logic?this.s.dt.i18n("searchBuilder.logicOr",this.c.i18n.logicOr):this.s.dt.i18n("searchBuilder.logicAnd",
+this.c.i18n.logicAnd));for(var b=0,d=a.criteria;b<d.length;b++)a=d[b],void 0!==a.logic?this._addPrevGroup(a):void 0===a.logic&&this._addPrevCriteria(a);b=0;for(d=this.s.criteria;b<d.length;b++)a=d[b],a.criteria instanceof l&&(a.criteria.updateArrows(1<this.s.criteria.length,!1),this._setCriteriaListeners(a.criteria))}};k.prototype.redrawContents=function(){f(this.dom.container).empty().append(this.dom.logicContainer).append(this.dom.add);this.s.criteria.sort(function(a,b){return a.criteria.s.index<
+b.criteria.s.index?-1:a.criteria.s.index>b.criteria.s.index?1:0});this.setListeners();for(var a=0;a<this.s.criteria.length;a++){var b=this.s.criteria[a].criteria;b instanceof l?(this.s.criteria[a].index=a,this.s.criteria[a].criteria.s.index=a,f(this.s.criteria[a].criteria.dom.container).insertBefore(this.dom.add),this._setCriteriaListeners(b),this.s.criteria[a].criteria.rebuild(this.s.criteria[a].criteria.getDetails())):b instanceof k&&0<b.s.criteria.length?(this.s.criteria[a].index=a,this.s.criteria[a].criteria.s.index=
+a,f(this.s.criteria[a].criteria.dom.container).insertBefore(this.dom.add),b.redrawContents(),this._setGroupListeners(b)):(this.s.criteria.splice(a,1),a--)}this.setupLogic()};k.prototype.search=function(a,b){return"AND"===this.s.logic?this._andSearch(a,b):"OR"===this.s.logic?this._orSearch(a,b):!0};k.prototype.setupLogic=function(){f(this.dom.logicContainer).remove();f(this.dom.clear).remove();if(1>this.s.criteria.length)this.s.isChild||(f(this.dom.container).trigger("dtsb-destroy"),f(this.dom.container).css("margin-left",
+0));else{var a=f(this.dom.container).height()-2;f(this.dom.clear).height("0px");f(this.dom.logicContainer).append(this.dom.clear).width(a);f(this.dom.container).prepend(this.dom.logicContainer);this._setLogicListener();f(this.dom.container).css("margin-left",f(this.dom.logicContainer).outerHeight(!0));var a=f(this.dom.logicContainer).offset(),b=a.left,d=f(this.dom.container).offset().left,b=b-(b-d)-f(this.dom.logicContainer).outerHeight(!0);f(this.dom.logicContainer).offset({left:b});b=f(this.dom.logicContainer).next();
+a=a.top;b=f(b).offset().top;a-=a-b;f(this.dom.logicContainer).offset({top:a});f(this.dom.clear).outerHeight(f(this.dom.logicContainer).height());this._setClearListener()}};k.prototype.setListeners=function(){var a=this;f(this.dom.add).unbind("click");f(this.dom.add).on("click",function(){a.s.isChild||f(a.dom.container).prepend(a.dom.logicContainer);a.addCriteria();f(a.dom.container).trigger("dtsb-add");a.s.dt.state.save();return!1});for(var b=0,d=this.s.criteria;b<d.length;b++)d[b].criteria.setListeners();
+this._setClearListener();this._setLogicListener()};k.prototype.addCriteria=function(a,b){void 0===a&&(a=null);void 0===b&&(b=!0);var d=null===a?this.s.criteria.length:a.s.index,c=new l(this.s.dt,this.s.opts,this.s.topGroup,d,this.s.depth);null!==a&&(c.c=a.c,c.s=a.s,c.s.depth=this.s.depth,c.classes=a.classes);c.populate();for(var e=!1,i=0;i<this.s.criteria.length;i++)0===i&&this.s.criteria[i].criteria.s.index>c.s.index?(f(c.getNode()).insertBefore(this.s.criteria[i].criteria.dom.container),e=!0):i<
+this.s.criteria.length-1&&(this.s.criteria[i].criteria.s.index<c.s.index&&this.s.criteria[i+1].criteria.s.index>c.s.index)&&(f(c.getNode()).insertAfter(this.s.criteria[i].criteria.dom.container),e=!0);e||f(c.getNode()).insertBefore(this.dom.add);this.s.criteria.push({criteria:c,index:d});this.s.criteria=this.s.criteria.sort(function(a,b){return a.criteria.s.index-b.criteria.s.index});d=0;for(e=this.s.criteria;d<e.length;d++)i=e[d],i.criteria instanceof l&&i.criteria.updateArrows(1<this.s.criteria.length,
+b);this._setCriteriaListeners(c);c.setListeners();this.setupLogic()};k.prototype.checkFilled=function(){for(var a=0,b=this.s.criteria;a<b.length;a++){var d=b[a];if(d.criteria instanceof l&&d.criteria.s.filled||d.criteria instanceof k&&d.criteria.checkFilled())return!0}return!1};k.prototype.count=function(){for(var a=0,b=0,d=this.s.criteria;b<d.length;b++){var c=d[b];c.criteria instanceof k?a+=c.criteria.count():a++}return a};k.prototype._addPrevGroup=function(a){var b=this.s.criteria.length,d=new k(this.s.dt,
+this.c,this.s.topGroup,b,!0,this.s.depth+1);this.s.criteria.push({criteria:d,index:b,logic:d.s.logic});d.rebuild(a);this.s.criteria[b].criteria=d;f(this.s.topGroup).trigger("dtsb-redrawContents");this._setGroupListeners(d)};k.prototype._addPrevCriteria=function(a){var b=this.s.criteria.length,d=new l(this.s.dt,this.s.opts,this.s.topGroup,b,this.s.depth);d.populate();this.s.criteria.push({criteria:d,index:b});d.rebuild(a);this.s.criteria[b].criteria=d;f(this.s.topGroup).trigger("dtsb-redrawContents")};
+k.prototype._andSearch=function(a,b){if(0===this.s.criteria.length)return!0;for(var d=0,c=this.s.criteria;d<c.length;d++){var e=c[d];if((!(e.criteria instanceof l)||e.criteria.s.filled)&&!e.criteria.search(a,b))return!1}return!0};k.prototype._orSearch=function(a,b){if(0===this.s.criteria.length)return!0;for(var d=!1,c=0,e=this.s.criteria;c<e.length;c++){var f=e[c];if(f.criteria instanceof l&&f.criteria.s.filled){if(d=!0,f.criteria.search(a,b))return!0}else if(f.criteria instanceof k&&f.criteria.checkFilled()&&
+(d=!0,f.criteria.search(a,b)))return!0}return!d};k.prototype._removeCriteria=function(a,b){void 0===b&&(b=!1);if(1>=this.s.criteria.length&&this.s.isChild)this.destroy();else{for(var d=void 0,c=0;c<this.s.criteria.length;c++)if(this.s.criteria[c].index===a.s.index&&(!b||this.s.criteria[c].criteria instanceof k))d=c;void 0!==d&&this.s.criteria.splice(d,1);for(c=0;c<this.s.criteria.length;c++)this.s.criteria[c].index=c,this.s.criteria[c].criteria.s.index=c}};k.prototype._setCriteriaListeners=function(a){var b=
+this;f(a.dom["delete"]).unbind("click").on("click",function(){b._removeCriteria(a);f(a.dom.container).remove();for(var c=0,e=b.s.criteria;c<e.length;c++){var h=e[c];h.criteria instanceof l&&h.criteria.updateArrows(1<b.s.criteria.length)}a.destroy();b.s.dt.draw();f(b.s.topGroup).trigger("dtsb-redrawContents");f(b.s.topGroup).trigger("dtsb-updateTitle");return!1});f(a.dom.right).unbind("click").on("click",function(){var c=a.s.index,e=new k(b.s.dt,b.s.opts,b.s.topGroup,a.s.index,!0,b.s.depth+1);e.addCriteria(a);
+b.s.criteria[c].criteria=e;b.s.criteria[c].logic="AND";f(b.s.topGroup).trigger("dtsb-redrawContents");b._setGroupListeners(e);return!1});f(a.dom.left).unbind("click").on("click",function(){b.s.toDrop=new l(b.s.dt,b.s.opts,b.s.topGroup,a.s.index);b.s.toDrop.s=a.s;b.s.toDrop.c=a.c;b.s.toDrop.classes=a.classes;b.s.toDrop.populate();var c=b.s.toDrop.s.index;f(b.dom.container).trigger("dtsb-dropCriteria");a.s.index=c;b._removeCriteria(a);f(b.s.topGroup).trigger("dtsb-redrawContents");b.s.dt.draw();return!1})};
+k.prototype._setClearListener=function(){var a=this;f(this.dom.clear).unbind("click").on("click",function(){if(!a.s.isChild)return f(a.dom.container).trigger("dtsb-clearContents"),!1;a.destroy();f(a.s.topGroup).trigger("dtsb-updateTitle");f(a.s.topGroup).trigger("dtsb-redrawContents");return!1})};k.prototype._setGroupListeners=function(a){var b=this;f(a.dom.add).unbind("click").on("click",function(){b.setupLogic();f(b.dom.container).trigger("dtsb-add");return!1});f(a.dom.container).unbind("dtsb-add").on("dtsb-add",
+function(){b.setupLogic();f(b.dom.container).trigger("dtsb-add");return!1});f(a.dom.container).unbind("dtsb-destroy").on("dtsb-destroy",function(){b._removeCriteria(a,!0);f(a.dom.container).remove();b.setupLogic();return!1});f(a.dom.container).unbind("dtsb-dropCriteria").on("dtsb-dropCriteria",function(){var c=a.s.toDrop;c.s.index=a.s.index;c.updateArrows(1<b.s.criteria.length,!1);b.addCriteria(c,!1);return!1});a.setListeners()};k.prototype._setup=function(){this.setListeners();f(this.dom.add).text(this.s.dt.i18n("searchBuilder.add",
+this.c.i18n.add));f(this.dom.logic).text("OR"===this.c.logic?this.s.dt.i18n("searchBuilder.logicOr",this.c.i18n.logicOr):this.s.dt.i18n("searchBuilder.logicAnd",this.c.i18n.logicAnd));this.s.logic="OR"===this.c.logic?"OR":"AND";this.c.greyscale&&f(this.dom.logic).addClass(this.classes.greyscale);f(this.dom.logicContainer).append(this.dom.logic).append(this.dom.clear);this.s.isChild&&f(this.dom.container).append(this.dom.logicContainer);f(this.dom.container).append(this.dom.add)};k.prototype._setLogicListener=
+function(){var a=this;f(this.dom.logic).unbind("click").on("click",function(){a._toggleLogic();a.s.dt.draw();for(var b=0,c=a.s.criteria;b<c.length;b++)c[b].criteria.setListeners()})};k.prototype._toggleLogic=function(){"OR"===this.s.logic?(this.s.logic="AND",f(this.dom.logic).text(this.s.dt.i18n("searchBuilder.logicAnd",this.c.i18n.logicAnd))):"AND"===this.s.logic&&(this.s.logic="OR",f(this.dom.logic).text(this.s.dt.i18n("searchBuilder.logicOr",this.c.i18n.logicOr)))};k.version="1.0.0";k.classes=
+{add:"dtsb-add",button:"dtsb-button",clearGroup:"dtsb-clearGroup",greyscale:"dtsb-greyscale",group:"dtsb-group",inputButton:"dtsb-iptbtn",logic:"dtsb-logic",logicContainer:"dtsb-logicContainer"};k.defaults={columns:!0,conditions:{date:l.dateConditions,html:l.stringConditions,"html-num":l.numConditions,"html-num-fmt":l.numFmtConditions,moment:l.momentDateConditions,num:l.numConditions,"num-fmt":l.numFmtConditions,string:l.stringConditions},depthLimit:!1,filterChanged:void 0,greyscale:!1,i18n:{add:"Add Condition",
+button:{"0":"Search Builder",_:"Search Builder (%d)"},clearAll:"Clear All",condition:"Condition",data:"Data",deleteTitle:"Delete filtering rule",leftTitle:"Outdent criteria",logicAnd:"And",logicOr:"Or",rightTitle:"Indent criteria",title:{"0":"Custom Search Builder",_:"Custom Search Builder (%d)"},value:"Value",valueJoiner:"and"},logic:"AND",orthogonal:{display:"display",search:"filter"},preDefined:!1};r=k;var j,s,v,m=function(a,b){var c=this;if(!s||!s.versionCheck||!s.versionCheck("1.10.0"))throw Error("SearchBuilder requires DataTables 1.10 or newer");
+var e=new s.Api(a);this.classes=j.extend(!0,{},m.classes);this.c=j.extend(!0,{},m.defaults,b);this.dom={clearAll:j('<button type="button">'+e.i18n("searchBuilder.clearAll",this.c.i18n.clearAll)+"</button>").addClass(this.classes.clearAll).addClass(this.classes.button).attr("type","button"),container:j("<div/>").addClass(this.classes.container),title:j("<div/>").addClass(this.classes.title),titleRow:j("<div/>").addClass(this.classes.titleRow),topGroup:void 0};this.s={dt:e,opts:b,search:void 0,topGroup:void 0};
+if(void 0===e.settings()[0]._searchBuilder){e.settings()[0]._searchBuilder=this;if(this.s.dt.settings()[0]._bInitComplete)this._setUp();else e.one("init.dt",function(){c._setUp()});return this}};m.prototype.getDetails=function(){return this.s.topGroup.getDetails()};m.prototype.getNode=function(){return this.dom.container};m.prototype.rebuild=function(a){j(this.dom.clearAll).click();if(void 0===a||null===a)return this;this.s.topGroup.rebuild(a);this.s.dt.draw();this.s.topGroup.setListeners();return this};
+m.prototype._applyPreDefDefaults=function(a){var b=this;void 0!==a.criteria&&void 0===a.logic&&(a.logic="AND");for(var c=function(a){a.criteria!==void 0?a=e._applyPreDefDefaults(a):e.s.dt.columns().every(function(c){if(b.s.dt.settings()[0].aoColumns[c].sTitle===a.data)a.dataIdx=c})},e=this,f=0,i=a.criteria;f<i.length;f++)c(i[f]);return a};m.prototype._setUp=function(a){var b=this;void 0===a&&(a=!0);this.s.topGroup=new r(this.s.dt,this.c,void 0);this._setClearListener();this.s.dt.on("stateSaveParams",
+function(a,c,e){e.searchBuilder=b.getDetails();e.page=b.s.dt.page()});this._build();a&&(a=this.s.dt.state.loaded(),null!==a&&void 0!==a.searchBuilder?(this.s.topGroup.rebuild(a.searchBuilder),j(this.s.topGroup.dom.container).trigger("dtsb-redrawContents"),this.s.dt.page(a.page).draw("page"),this.s.topGroup.setListeners()):!1!==this.c.preDefined&&(this.c.preDefined=this._applyPreDefDefaults(this.c.preDefined),this.rebuild(this.c.preDefined)));this._setEmptyListener();this.s.dt.state.save()};m.prototype._updateTitle=
+function(a){j(this.dom.title).text(this.s.dt.i18n("searchBuilder.title",this.c.i18n.title,a))};m.prototype._build=function(){var a=this;j(this.dom.clearAll).remove();j(this.dom.container).empty();var b=this.s.topGroup.count();this._updateTitle(b);j(this.dom.titleRow).append(this.dom.title);j(this.dom.container).append(this.dom.titleRow);this.dom.topGroup=this.s.topGroup.getNode();j(this.dom.container).append(this.dom.topGroup);this._setRedrawListener();var c=this.s.dt.table(0).node();-1===j.fn.dataTable.ext.search.indexOf(this.s.search)&&
+(this.s.search=function(b,e,f){return b.nTable!==c?!0:a.s.topGroup.search(e,f)},j.fn.dataTable.ext.search.push(this.s.search));j.fn.DataTable.Api.registerPlural("columns().type()","column().type()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].sType},1)});this.s.dt.on("destroy.dt",function(){j(a.dom.container).remove();j(a.dom.clearAll).remove();for(var b=j.fn.dataTable.ext.search.indexOf(a.s.search);b!==-1;){j.fn.dataTable.ext.search.splice(b,1);b=j.fn.dataTable.ext.search.indexOf(a.s.search)}})};
+m.prototype._checkClear=function(){0<this.s.topGroup.s.criteria.length?(j(this.dom.clearAll).insertAfter(this.dom.title),this._setClearListener()):j(this.dom.clearAll).remove()};m.prototype._filterChanged=function(a){var b=this.c.filterChanged;"function"===typeof b&&b(a,this.s.dt.i18n("searchBuilder.button",this.c.i18n.button,a))};m.prototype._setClearListener=function(){var a=this;j(this.dom.clearAll).unbind("click");j(this.dom.clearAll).on("click",function(){a.s.topGroup=new r(a.s.dt,a.c,void 0);
+a._build();a.s.dt.draw();a.s.topGroup.setListeners();j(a.dom.clearAll).remove();a._setEmptyListener();a._filterChanged(0);return!1})};m.prototype._setRedrawListener=function(){var a=this;j(this.s.topGroup.dom.container).unbind("dtsb-redrawContents");j(this.s.topGroup.dom.container).on("dtsb-redrawContents",function(){a._checkClear();a.s.topGroup.redrawContents();a.s.topGroup.setupLogic();a._setEmptyListener();var b=a.s.topGroup.count();a._updateTitle(b);a._filterChanged(b);a.s.dt.state.save()});j(this.s.topGroup.dom.container).unbind("dtsb-clearContents");
+j(this.s.topGroup.dom.container).on("dtsb-clearContents",function(){a._setUp(!1);a._filterChanged(0);a.s.dt.draw()});j(this.s.topGroup.dom.container).on("dtsb-updateTitle",function(){var b=a.s.topGroup.count();a._updateTitle(b);a._filterChanged(b)})};m.prototype._setEmptyListener=function(){var a=this;j(this.s.topGroup.dom.add).on("click",function(){a._checkClear()});j(this.s.topGroup.dom.container).on("dtsb-destroy",function(){j(a.dom.clearAll).remove()})};m.version="1.0.1";m.classes={button:"dtsb-button",
+clearAll:"dtsb-clearAll",container:"dtsb-searchBuilder",inputButton:"dtsb-iptbtn",title:"dtsb-title",titleRow:"dtsb-titleRow"};m.defaults={columns:!0,conditions:{date:l.dateConditions,html:l.stringConditions,"html-num":l.numConditions,"html-num-fmt":l.numFmtConditions,moment:l.momentDateConditions,num:l.numConditions,"num-fmt":l.numFmtConditions,string:l.stringConditions},depthLimit:!1,filterChanged:void 0,greyscale:!1,i18n:{add:"Add Condition",button:{"0":"Search Builder",_:"Search Builder (%d)"},
+clearAll:"Clear All",condition:"Condition",conditions:{array:{contains:"Contains",empty:"Empty",equals:"Equals",not:"Not",notEmpty:"Not Empty",without:"Without"},date:{after:"After",before:"Before",between:"Between",empty:"Empty",equals:"Equals",not:"Not",notBetween:"Not Between",notEmpty:"Not Empty"},moment:{after:"After",before:"Before",between:"Between",empty:"Empty",equals:"Equals",not:"Not",notBetween:"Not Between",notEmpty:"Not Empty"},number:{between:"Between",empty:"Empty",equals:"Equals",
+gt:"Greater Than",gte:"Greater Than Equal To",lt:"Less Than",lte:"Less Than Equal To",not:"Not",notBetween:"Not Between",notEmpty:"Not Empty"},string:{contains:"Contains",empty:"Empty",endsWith:"Ends With",equals:"Equals",not:"Not",notEmpty:"Not Empty",startsWith:"Starts With"}},data:"Data",deleteTitle:"Delete filtering rule",leftTitle:"Outdent criteria",logicAnd:"And",logicOr:"Or",rightTitle:"Indent criteria",title:{"0":"Custom Search Builder",_:"Custom Search Builder (%d)"},value:"Value",valueJoiner:"and"},
+logic:"AND",orthogonal:{display:"display",search:"filter"},preDefined:!1};v=m;var y=function(a,b,c){function g(a,b){var c=new h.Api(a),d=b?b:c.init().searchBuilder||h.defaults.searchBuilder;return(new v(c,d)).getNode()}j=a;s=a.fn.DataTable;f=a;u=a.fn.dataTable;e=a;var h=q=a.fn.dataTable;a.fn.dataTable.SearchBuilder=v;a.fn.DataTable.SearchBuilder=v;a.fn.dataTable.Group=r;a.fn.DataTable.Group=r;a.fn.dataTable.Criteria=l;a.fn.DataTable.Criteria=l;b=a.fn.dataTable.Api.register;a.fn.dataTable.ext.searchBuilder=
+{conditions:{}};a.fn.dataTable.ext.buttons.searchBuilder={action:function(a,b,c,d){a.stopPropagation();this.popover(d._searchBuilder.getNode(),{align:"dt-container"})},config:{},init:function(b,c,d){var e=new a.fn.dataTable.SearchBuilder(b,a.extend({filterChanged:function(a,d){b.button(c).text(d)}},d.config));b.button(c).text(d.text||b.i18n("searchBuilder.button",e.c.i18n.button,0));d._searchBuilder=e},text:null};b("searchBuilder.getDetails()",function(){return this.context[0]._searchBuilder.getDetails()});
+b("searchBuilder.rebuild()",function(a){this.context[0]._searchBuilder.rebuild(a);return this});b("searchBuilder.container()",function(){return this.context[0]._searchBuilder.getNode()});a(c).on("preInit.dt.dtsp",function(a,b){if("dt"===a.namespace&&(b.oInit.searchBuilder||h.defaults.searchBuilder))b._searchBuilder||g(b)});h.ext.feature.push({cFeature:"Q",fnInit:g});h.ext.features&&h.ext.features.register("searchBuilder",g)};"function"===typeof define&&define.amd?define(["jquery","datatables.net"],
+function(a){return y(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);if(!b||!b.fn.dataTable)b=require("datatables.net")(a,b).$;return y(b,a,a.document)}:y(window.jQuery,window,document)})();

+ 51 - 0
plugins/datatables-searchbuilder/js/searchBuilder.bootstrap4.js

@@ -0,0 +1,51 @@
+(function () {
+    'use strict';
+
+    (function (factory) {
+        if (typeof define === 'function' && define.amd) {
+            // AMD
+            define(['jquery', 'datatables.net-bs4', 'datatables.net-searchbuilder'], function ($) {
+                return factory($, window, document);
+            });
+        }
+        else if (typeof exports === 'object') {
+            // CommonJS
+            module.exports = function (root, $) {
+                if (!root) {
+                    root = window;
+                }
+                if (!$ || !$.fn.dataTable) {
+                    $ = require('datatables.net-bs4')(root, $).$;
+                }
+                if (!$.fn.dataTable.searchBuilder) {
+                    require('datatables.net-searchbuilder')(root, $);
+                }
+                return factory($, root, root.document);
+            };
+        }
+        else {
+            // Browser
+            factory(jQuery, window, document);
+        }
+    }(function ($, window, document) {
+        var DataTable = $.fn.dataTable;
+        $.extend(true, DataTable.SearchBuilder.classes, {
+            clearAll: 'btn btn-light dtsb-clearAll'
+        });
+        $.extend(true, DataTable.Group.classes, {
+            add: 'btn btn-light dtsb-add',
+            clearGroup: 'btn btn-light dtsb-clearGroup',
+            logic: 'btn btn-light dtsb-logic'
+        });
+        $.extend(true, DataTable.Criteria.classes, {
+            condition: 'form-control dtsb-condition',
+            data: 'form-control dtsb-data',
+            "delete": 'btn btn-light dtsb-delete',
+            left: 'btn btn-light dtsb-left',
+            right: 'btn btn-light dtsb-right',
+            value: 'form-control dtsb-value'
+        });
+        return DataTable.searchPanes;
+    }));
+
+}());

+ 2 - 0
plugins/datatables-searchbuilder/js/searchBuilder.bootstrap4.min.js

@@ -0,0 +1,2 @@
+(function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net-bs4","datatables.net-searchbuilder"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,c){a||(a=window);if(!c||!c.fn.dataTable)c=require("datatables.net-bs4")(a,c).$;c.fn.dataTable.searchBuilder||require("datatables.net-searchbuilder")(a,c);return b(c,a,a.document)}:b(jQuery,window,document)})(function(b){var a=b.fn.dataTable;b.extend(!0,a.SearchBuilder.classes,{clearAll:"btn btn-light dtsb-clearAll"});
+b.extend(!0,a.Group.classes,{add:"btn btn-light dtsb-add",clearGroup:"btn btn-light dtsb-clearGroup",logic:"btn btn-light dtsb-logic"});b.extend(!0,a.Criteria.classes,{condition:"form-control dtsb-condition",data:"form-control dtsb-data","delete":"btn btn-light dtsb-delete",left:"btn btn-light dtsb-left",right:"btn btn-light dtsb-right",value:"form-control dtsb-value"});return a.searchPanes});

+ 3 - 3
plugins/sweetalert2/sweetalert2.all.js

@@ -1,5 +1,5 @@
 /*!
-* sweetalert2 v10.13.0
+* sweetalert2 v10.13.1
 * Released under the MIT License.
 */
 (function (global, factory) {
@@ -2650,7 +2650,7 @@
 
   var showWarningsForElements = function showWarningsForElements(template) {
     var allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
-    toArray(template.querySelectorAll('*')).forEach(function (el) {
+    toArray(template.children).forEach(function (el) {
       var tagName = el.tagName.toLowerCase();
 
       if (allowedElements.indexOf(tagName) === -1) {
@@ -3617,7 +3617,7 @@
     };
   });
   SweetAlert.DismissReason = DismissReason;
-  SweetAlert.version = '10.13.0';
+  SweetAlert.version = '10.13.1';
 
   var Swal = SweetAlert;
   Swal["default"] = Swal;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
plugins/sweetalert2/sweetalert2.all.min.js


+ 3 - 3
plugins/sweetalert2/sweetalert2.js

@@ -1,5 +1,5 @@
 /*!
-* sweetalert2 v10.13.0
+* sweetalert2 v10.13.1
 * Released under the MIT License.
 */
 (function (global, factory) {
@@ -2650,7 +2650,7 @@
 
   var showWarningsForElements = function showWarningsForElements(template) {
     var allowedElements = swalStringParams.concat(['swal-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
-    toArray(template.querySelectorAll('*')).forEach(function (el) {
+    toArray(template.children).forEach(function (el) {
       var tagName = el.tagName.toLowerCase();
 
       if (allowedElements.indexOf(tagName) === -1) {
@@ -3617,7 +3617,7 @@
     };
   });
   SweetAlert.DismissReason = DismissReason;
-  SweetAlert.version = '10.13.0';
+  SweetAlert.version = '10.13.1';
 
   var Swal = SweetAlert;
   Swal["default"] = Swal;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
plugins/sweetalert2/sweetalert2.min.js


+ 62 - 88
plugins/uplot/uPlot.cjs.js

@@ -4,7 +4,7 @@
 *
 * uPlot.js (μPlot)
 * A small, fast chart for time series, lines, areas, ohlc & bars
-* https://github.com/leeoniya/uPlot (v1.6.1)
+* https://github.com/leeoniya/uPlot (v1.6.3)
 */
 
 'use strict';
@@ -336,21 +336,33 @@ function assign(targ) {
 }
 
 // nullModes
-const NULL_IGNORE = 0;  // all nulls are ignored by isGap
-const NULL_GAP    = 1;  // alignment nulls are ignored by isGap (default)
-const NULL_EXPAND = 2;  // nulls are expand to include adjacent alignment nulls
+const NULL_IGNORE = 0;  // all nulls are ignored, converted to undefined (e.g. spanGaps: true)
+const NULL_GAP    = 1;  // nulls are retained, alignment artifacts = undefined values (default)
+const NULL_EXPAND = 2;  // nulls are expanded to include adjacent alignment artifacts (undefined values)
+
+// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
+function nullExpand(yVals, nullIdxs, alignedLen) {
+	for (let i = 0, xi, lastNullIdx = -inf; i < nullIdxs.length; i++) {
+		let nullIdx = nullIdxs[i];
+
+		if (nullIdx > lastNullIdx) {
+			xi = nullIdx - 1;
+			while (xi >= 0 && yVals[xi] == null)
+				yVals[xi--] = null;
+
+			xi = nullIdx + 1;
+			while (xi < alignedLen && yVals[xi] == null)
+				yVals[lastNullIdx = xi++] = null;
+		}
+	}
+}
 
 // nullModes is a tables-matched array indicating how to treat nulls in each series
 function join(tables, nullModes) {
-	if (tables.length == 1) {
-		return {
-			data: tables[0],
-			isGap: nullModes ? (u, seriesIdx, dataIdx) => nullModes[0][seriesIdx] != NULL_IGNORE : () => true,
-		};
-	}
+	if (tables.length == 1)
+		return tables[0];
 
 	let xVals = new Set();
-	let xNulls = [new Set()];
 
 	for (let ti = 0; ti < tables.length; ti++) {
 		let t = tables[ti];
@@ -359,22 +371,6 @@ function join(tables, nullModes) {
 
 		for (let i = 0; i < len; i++)
 			xVals.add(xs[i]);
-
-		for (let si = 1; si < t.length; si++) {
-			let nulls = new Set();
-
-			// cache original nulls for isGap lookup
-			if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
-				let ys = t[si];
-
-				for (let i = 0; i < len; i++) {
-					if (ys[i] == null)
-						nulls.add(xs[i]);
-				}
-			}
-
-			xNulls.push(nulls);
-		}
 	}
 
 	let data = [Array.from(xVals).sort((a, b) => a - b)];
@@ -386,8 +382,6 @@ function join(tables, nullModes) {
 	for (let i = 0; i < alignedLen; i++)
 		xIdxs.set(data[0][i], i);
 
-	let gsi = 1;
-
 	for (let ti = 0; ti < tables.length; ti++) {
 		let t = tables[ti];
 		let xs = t[0];
@@ -395,55 +389,35 @@ function join(tables, nullModes) {
 		for (let si = 1; si < t.length; si++) {
 			let ys = t[si];
 
-			let yVals = Array(alignedLen).fill(null);
-
-			for (let i = 0; i < ys.length; i++)
-				yVals[xIdxs.get(xs[i])] = ys[i];
-
-			// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
-			if (nullModes && nullModes[ti][si] == NULL_EXPAND) {
-				let nulls = xNulls[gsi];
-				let size = nulls.size;
-				let	i = 0;
-				let xi;
+			let yVals = Array(alignedLen).fill(undefined);
 
-				let lastAddedX = -inf;
+			let nullMode = nullModes ? nullModes[ti][si] : NULL_GAP;
 
-				for (let xVal of nulls.values()) {
-					if (i++ == size)
-						break;
+			let nullIdxs = [];
 
-					if (xVal > lastAddedX) {
-						let xIdx = xIdxs.get(xVal);
+			for (let i = 0; i < ys.length; i++) {
+				let yVal = ys[i];
+				let alignedIdx = xIdxs.get(xs[i]);
 
-						xi = xIdx - 1;
-						while (yVals[xi] === null) {
-							nulls.add(data[0][xi]);
-							xi--;
-						}
+				if (yVal == null) {
+					if (nullMode != NULL_IGNORE) {
+						yVals[alignedIdx] = yVal;
 
-						xi = xIdx + 1;
-						while (yVals[xi] === null) {
-							nulls.add(lastAddedX = data[0][xi]);
-							xi++;
-						}
+						if (nullMode == NULL_EXPAND)
+							nullIdxs.push(alignedIdx);
 					}
 				}
+				else
+					yVals[alignedIdx] = yVal;
 			}
 
-			data.push(yVals);
+			nullExpand(yVals, nullIdxs, alignedLen);
 
-			gsi++;
+			data.push(yVals);
 		}
 	}
 
-	return {
-		data: data,
-		isGap(u, seriesIdx, dataIdx) {
-			let xVal = u._data[0][dataIdx];
-			return xNulls[seriesIdx].has(xVal);
-		},
-	};
+	return data;
 }
 
 const microTask = typeof queueMicrotask == "undefined" ? fn => Promise.resolve().then(fn) : queueMicrotask;
@@ -1122,6 +1096,7 @@ const lineMult = 1.5;		// font-size multiplier
 const xAxisOpts = {
 	show: true,
 	scale: "x",
+	stroke: hexBlack,
 	space: 50,
 	gap: 5,
 	size: 50,
@@ -1235,6 +1210,7 @@ function numSeriesVal(self, val) {
 const yAxisOpts = {
 	show: true,
 	scale: "y",
+	stroke: hexBlack,
 	space: 30,
 	gap: 5,
 	size: 50,
@@ -1269,7 +1245,8 @@ function seriesPoints(self, si) {
 
 function seriesFillTo(self, seriesIdx, dataMin, dataMax) {
 	let scale = self.scales[self.series[seriesIdx].scale];
-	return scale.distr == 3 ? scale.min : 0;
+	let isUpperBandEdge = self.bands && self.bands.some(b => b.series[0] == seriesIdx);
+	return scale.distr == 3 || isUpperBandEdge ? scale.min : 0;
 }
 
 const ySeriesOpts = {
@@ -1279,7 +1256,6 @@ const ySeriesOpts = {
 	show: true,
 	band: false,
 	spanGaps: false,
-	isGap: (self, seriesIdx, dataIdx) => true,
 	alpha: 1,
 	points: {
 		show: seriesPoints,
@@ -1515,8 +1491,6 @@ function linear() {
 				drawAcc = drawAccV;
 			}
 
-			const isGap = series.isGap;
-
 			const dir = scaleX.dir * (scaleX.ori == 0 ? 1 : -1);
 
 			const _paths = {stroke: new Path2D(), fill: null, clip: null, band: null};
@@ -1553,7 +1527,7 @@ function linear() {
 						minY = min(outY, minY);
 						maxY = max(outY, maxY);
 					}
-					else if (!accGaps && isGap(u, seriesIdx, i))
+					else if (!accGaps && dataY[i] === null)
 						accGaps = true;
 				}
 				else {
@@ -1574,14 +1548,14 @@ function linear() {
 						minY = maxY = outY;
 
 						// prior pixel can have data but still start a gap if ends with null
-						if (x - accX > 1 && dataY[i - dir] == null && isGap(u, seriesIdx, i - dir))
+						if (x - accX > 1 && dataY[i - dir] === null)
 							_addGap = true;
 					}
 					else {
 						minY = inf;
 						maxY = -inf;
 
-						if (!accGaps && isGap(u, seriesIdx, i))
+						if (!accGaps && dataY[i] === null)
 							accGaps = true;
 					}
 
@@ -1655,7 +1629,7 @@ function spline(opts) {
 				let xPos = valToPosX(xVal, scaleX, xDim, xOff);
 
 				if (yVal == null) {
-					if (series.isGap(u, seriesIdx, i)) {
+					if (yVal === null) {
 						addGap(gaps, prevXPos, xPos);
 						inGap = true;
 					}
@@ -1857,7 +1831,7 @@ function stepped(opts) {
 				let x1 = round(valToPosX(dataX[i], scaleX, xDim, xOff));
 
 				if (yVal1 == null) {
-					if (series.isGap(u, seriesIdx, i)) {
+					if (yVal1 === null) {
 						addGap(gaps, prevXPos, x1);
 						inGap = true;
 					}
@@ -2580,7 +2554,7 @@ function uPlot(opts, data, then) {
 			s.paths  = s.paths || linearPath || retNull;
 			s.fillTo = fnOrSelf(s.fillTo || seriesFillTo);
 
-			s.stroke = fnOrSelf(s.stroke || hexBlack);
+			s.stroke = fnOrSelf(s.stroke || null);
 			s.fill   = fnOrSelf(s.fill || null);
 			s._stroke = s._fill = s._paths = null;
 
@@ -2654,7 +2628,12 @@ function uPlot(opts, data, then) {
 			axis.incrs  = fnOrSelf(axis.incrs  || (          sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
 			axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
 
+			axis.stroke       = fnOrSelf(axis.stroke);
+			axis.grid.stroke  = fnOrSelf(axis.grid.stroke);
+			axis.ticks.stroke = fnOrSelf(axis.ticks.stroke);
+
 			let av = axis.values;
+
 			axis.values = (
 				isTime ? (
 					isArr(av) ?
@@ -2716,11 +2695,6 @@ function uPlot(opts, data, then) {
 	let viaAutoScaleX = false;
 
 	function setData(_data, _resetScales) {
-		if (!isArr(_data) && isObj(_data)) {
-			_data.isGap && series.forEach(s => { s.isGap = _data.isGap; });
-			_data = _data.data;
-		}
-
 		_data = _data || [];
 		_data[0] = _data[0] || [];
 
@@ -3081,13 +3055,13 @@ function uPlot(opts, data, then) {
 		ctx.rect(lft, top, wid, hgt);
 		ctx.clip();
 
-		if (clip != null)
-			ctx.clip(clip);
+		clip && ctx.clip(clip);
+
+		let isUpperEdge = fillBands(si, _fill);
 
-		if (!fillBands(si, _fill) && _fill != null)
-			ctx.fill(fill);
+		!isUpperEdge && _fill   && fill   && ctx.fill(fill);
 
-		width && ctx.stroke(stroke);
+		width        && _stroke && stroke && ctx.stroke(stroke);
 
 		ctx.restore();
 
@@ -3290,7 +3264,7 @@ function uPlot(opts, data, then) {
 			let x        = ori == 1 ? finalPos : 0;
 
 			ctx.font         = axis.font[0];
-			ctx.fillStyle    = axis.stroke || hexBlack;									// rgba?
+			ctx.fillStyle    = axis.stroke(self, i);									// rgba?
 			ctx.textAlign    = axis.align == 1 ? LEFT :
 			                   axis.align == 2 ? RIGHT :
 			                   angle > 0 ? LEFT :
@@ -3366,7 +3340,7 @@ function uPlot(opts, data, then) {
 					basePos,
 					tickSize,
 					roundDec(ticks.width * pxRatio, 3),
-					ticks.stroke,
+					ticks.stroke(self, i),
 					ticks.dash,
 					ticks.cap,
 				);
@@ -3384,7 +3358,7 @@ function uPlot(opts, data, then) {
 					ori == 0 ? plotTop : plotLft,
 					ori == 0 ? plotHgt : plotWid,
 					roundDec(grid.width * pxRatio, 3),
-					grid.stroke,
+					grid.stroke(self, i),
 					grid.dash,
 					grid.cap,
 				);

+ 62 - 88
plugins/uplot/uPlot.esm.js

@@ -4,7 +4,7 @@
 *
 * uPlot.js (μPlot)
 * A small, fast chart for time series, lines, areas, ohlc & bars
-* https://github.com/leeoniya/uPlot (v1.6.1)
+* https://github.com/leeoniya/uPlot (v1.6.3)
 */
 
 const FEAT_TIME          = true;
@@ -334,21 +334,33 @@ function assign(targ) {
 }
 
 // nullModes
-const NULL_IGNORE = 0;  // all nulls are ignored by isGap
-const NULL_GAP    = 1;  // alignment nulls are ignored by isGap (default)
-const NULL_EXPAND = 2;  // nulls are expand to include adjacent alignment nulls
+const NULL_IGNORE = 0;  // all nulls are ignored, converted to undefined (e.g. spanGaps: true)
+const NULL_GAP    = 1;  // nulls are retained, alignment artifacts = undefined values (default)
+const NULL_EXPAND = 2;  // nulls are expanded to include adjacent alignment artifacts (undefined values)
+
+// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
+function nullExpand(yVals, nullIdxs, alignedLen) {
+	for (let i = 0, xi, lastNullIdx = -inf; i < nullIdxs.length; i++) {
+		let nullIdx = nullIdxs[i];
+
+		if (nullIdx > lastNullIdx) {
+			xi = nullIdx - 1;
+			while (xi >= 0 && yVals[xi] == null)
+				yVals[xi--] = null;
+
+			xi = nullIdx + 1;
+			while (xi < alignedLen && yVals[xi] == null)
+				yVals[lastNullIdx = xi++] = null;
+		}
+	}
+}
 
 // nullModes is a tables-matched array indicating how to treat nulls in each series
 function join(tables, nullModes) {
-	if (tables.length == 1) {
-		return {
-			data: tables[0],
-			isGap: nullModes ? (u, seriesIdx, dataIdx) => nullModes[0][seriesIdx] != NULL_IGNORE : () => true,
-		};
-	}
+	if (tables.length == 1)
+		return tables[0];
 
 	let xVals = new Set();
-	let xNulls = [new Set()];
 
 	for (let ti = 0; ti < tables.length; ti++) {
 		let t = tables[ti];
@@ -357,22 +369,6 @@ function join(tables, nullModes) {
 
 		for (let i = 0; i < len; i++)
 			xVals.add(xs[i]);
-
-		for (let si = 1; si < t.length; si++) {
-			let nulls = new Set();
-
-			// cache original nulls for isGap lookup
-			if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
-				let ys = t[si];
-
-				for (let i = 0; i < len; i++) {
-					if (ys[i] == null)
-						nulls.add(xs[i]);
-				}
-			}
-
-			xNulls.push(nulls);
-		}
 	}
 
 	let data = [Array.from(xVals).sort((a, b) => a - b)];
@@ -384,8 +380,6 @@ function join(tables, nullModes) {
 	for (let i = 0; i < alignedLen; i++)
 		xIdxs.set(data[0][i], i);
 
-	let gsi = 1;
-
 	for (let ti = 0; ti < tables.length; ti++) {
 		let t = tables[ti];
 		let xs = t[0];
@@ -393,55 +387,35 @@ function join(tables, nullModes) {
 		for (let si = 1; si < t.length; si++) {
 			let ys = t[si];
 
-			let yVals = Array(alignedLen).fill(null);
-
-			for (let i = 0; i < ys.length; i++)
-				yVals[xIdxs.get(xs[i])] = ys[i];
-
-			// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
-			if (nullModes && nullModes[ti][si] == NULL_EXPAND) {
-				let nulls = xNulls[gsi];
-				let size = nulls.size;
-				let	i = 0;
-				let xi;
+			let yVals = Array(alignedLen).fill(undefined);
 
-				let lastAddedX = -inf;
+			let nullMode = nullModes ? nullModes[ti][si] : NULL_GAP;
 
-				for (let xVal of nulls.values()) {
-					if (i++ == size)
-						break;
+			let nullIdxs = [];
 
-					if (xVal > lastAddedX) {
-						let xIdx = xIdxs.get(xVal);
+			for (let i = 0; i < ys.length; i++) {
+				let yVal = ys[i];
+				let alignedIdx = xIdxs.get(xs[i]);
 
-						xi = xIdx - 1;
-						while (yVals[xi] === null) {
-							nulls.add(data[0][xi]);
-							xi--;
-						}
+				if (yVal == null) {
+					if (nullMode != NULL_IGNORE) {
+						yVals[alignedIdx] = yVal;
 
-						xi = xIdx + 1;
-						while (yVals[xi] === null) {
-							nulls.add(lastAddedX = data[0][xi]);
-							xi++;
-						}
+						if (nullMode == NULL_EXPAND)
+							nullIdxs.push(alignedIdx);
 					}
 				}
+				else
+					yVals[alignedIdx] = yVal;
 			}
 
-			data.push(yVals);
+			nullExpand(yVals, nullIdxs, alignedLen);
 
-			gsi++;
+			data.push(yVals);
 		}
 	}
 
-	return {
-		data: data,
-		isGap(u, seriesIdx, dataIdx) {
-			let xVal = u._data[0][dataIdx];
-			return xNulls[seriesIdx].has(xVal);
-		},
-	};
+	return data;
 }
 
 const microTask = typeof queueMicrotask == "undefined" ? fn => Promise.resolve().then(fn) : queueMicrotask;
@@ -1120,6 +1094,7 @@ const lineMult = 1.5;		// font-size multiplier
 const xAxisOpts = {
 	show: true,
 	scale: "x",
+	stroke: hexBlack,
 	space: 50,
 	gap: 5,
 	size: 50,
@@ -1233,6 +1208,7 @@ function numSeriesVal(self, val) {
 const yAxisOpts = {
 	show: true,
 	scale: "y",
+	stroke: hexBlack,
 	space: 30,
 	gap: 5,
 	size: 50,
@@ -1267,7 +1243,8 @@ function seriesPoints(self, si) {
 
 function seriesFillTo(self, seriesIdx, dataMin, dataMax) {
 	let scale = self.scales[self.series[seriesIdx].scale];
-	return scale.distr == 3 ? scale.min : 0;
+	let isUpperBandEdge = self.bands && self.bands.some(b => b.series[0] == seriesIdx);
+	return scale.distr == 3 || isUpperBandEdge ? scale.min : 0;
 }
 
 const ySeriesOpts = {
@@ -1277,7 +1254,6 @@ const ySeriesOpts = {
 	show: true,
 	band: false,
 	spanGaps: false,
-	isGap: (self, seriesIdx, dataIdx) => true,
 	alpha: 1,
 	points: {
 		show: seriesPoints,
@@ -1513,8 +1489,6 @@ function linear() {
 				drawAcc = drawAccV;
 			}
 
-			const isGap = series.isGap;
-
 			const dir = scaleX.dir * (scaleX.ori == 0 ? 1 : -1);
 
 			const _paths = {stroke: new Path2D(), fill: null, clip: null, band: null};
@@ -1551,7 +1525,7 @@ function linear() {
 						minY = min(outY, minY);
 						maxY = max(outY, maxY);
 					}
-					else if (!accGaps && isGap(u, seriesIdx, i))
+					else if (!accGaps && dataY[i] === null)
 						accGaps = true;
 				}
 				else {
@@ -1572,14 +1546,14 @@ function linear() {
 						minY = maxY = outY;
 
 						// prior pixel can have data but still start a gap if ends with null
-						if (x - accX > 1 && dataY[i - dir] == null && isGap(u, seriesIdx, i - dir))
+						if (x - accX > 1 && dataY[i - dir] === null)
 							_addGap = true;
 					}
 					else {
 						minY = inf;
 						maxY = -inf;
 
-						if (!accGaps && isGap(u, seriesIdx, i))
+						if (!accGaps && dataY[i] === null)
 							accGaps = true;
 					}
 
@@ -1653,7 +1627,7 @@ function spline(opts) {
 				let xPos = valToPosX(xVal, scaleX, xDim, xOff);
 
 				if (yVal == null) {
-					if (series.isGap(u, seriesIdx, i)) {
+					if (yVal === null) {
 						addGap(gaps, prevXPos, xPos);
 						inGap = true;
 					}
@@ -1855,7 +1829,7 @@ function stepped(opts) {
 				let x1 = round(valToPosX(dataX[i], scaleX, xDim, xOff));
 
 				if (yVal1 == null) {
-					if (series.isGap(u, seriesIdx, i)) {
+					if (yVal1 === null) {
 						addGap(gaps, prevXPos, x1);
 						inGap = true;
 					}
@@ -2578,7 +2552,7 @@ function uPlot(opts, data, then) {
 			s.paths  = s.paths || linearPath || retNull;
 			s.fillTo = fnOrSelf(s.fillTo || seriesFillTo);
 
-			s.stroke = fnOrSelf(s.stroke || hexBlack);
+			s.stroke = fnOrSelf(s.stroke || null);
 			s.fill   = fnOrSelf(s.fill || null);
 			s._stroke = s._fill = s._paths = null;
 
@@ -2652,7 +2626,12 @@ function uPlot(opts, data, then) {
 			axis.incrs  = fnOrSelf(axis.incrs  || (          sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
 			axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
 
+			axis.stroke       = fnOrSelf(axis.stroke);
+			axis.grid.stroke  = fnOrSelf(axis.grid.stroke);
+			axis.ticks.stroke = fnOrSelf(axis.ticks.stroke);
+
 			let av = axis.values;
+
 			axis.values = (
 				isTime ? (
 					isArr(av) ?
@@ -2714,11 +2693,6 @@ function uPlot(opts, data, then) {
 	let viaAutoScaleX = false;
 
 	function setData(_data, _resetScales) {
-		if (!isArr(_data) && isObj(_data)) {
-			_data.isGap && series.forEach(s => { s.isGap = _data.isGap; });
-			_data = _data.data;
-		}
-
 		_data = _data || [];
 		_data[0] = _data[0] || [];
 
@@ -3079,13 +3053,13 @@ function uPlot(opts, data, then) {
 		ctx.rect(lft, top, wid, hgt);
 		ctx.clip();
 
-		if (clip != null)
-			ctx.clip(clip);
+		clip && ctx.clip(clip);
+
+		let isUpperEdge = fillBands(si, _fill);
 
-		if (!fillBands(si, _fill) && _fill != null)
-			ctx.fill(fill);
+		!isUpperEdge && _fill   && fill   && ctx.fill(fill);
 
-		width && ctx.stroke(stroke);
+		width        && _stroke && stroke && ctx.stroke(stroke);
 
 		ctx.restore();
 
@@ -3288,7 +3262,7 @@ function uPlot(opts, data, then) {
 			let x        = ori == 1 ? finalPos : 0;
 
 			ctx.font         = axis.font[0];
-			ctx.fillStyle    = axis.stroke || hexBlack;									// rgba?
+			ctx.fillStyle    = axis.stroke(self, i);									// rgba?
 			ctx.textAlign    = axis.align == 1 ? LEFT :
 			                   axis.align == 2 ? RIGHT :
 			                   angle > 0 ? LEFT :
@@ -3364,7 +3338,7 @@ function uPlot(opts, data, then) {
 					basePos,
 					tickSize,
 					roundDec(ticks.width * pxRatio, 3),
-					ticks.stroke,
+					ticks.stroke(self, i),
 					ticks.dash,
 					ticks.cap,
 				);
@@ -3382,7 +3356,7 @@ function uPlot(opts, data, then) {
 					ori == 0 ? plotTop : plotLft,
 					ori == 0 ? plotHgt : plotWid,
 					roundDec(grid.width * pxRatio, 3),
-					grid.stroke,
+					grid.stroke(self, i),
 					grid.dash,
 					grid.cap,
 				);

+ 66 - 92
plugins/uplot/uPlot.iife.js

@@ -4,7 +4,7 @@
 *
 * uPlot.js (μPlot)
 * A small, fast chart for time series, lines, areas, ohlc & bars
-* https://github.com/leeoniya/uPlot (v1.6.1)
+* https://github.com/leeoniya/uPlot (v1.6.3)
 */
 
 var uPlot = (function () {
@@ -336,21 +336,33 @@ var uPlot = (function () {
 	}
 
 	// nullModes
-	var NULL_IGNORE = 0;  // all nulls are ignored by isGap
-	var NULL_GAP    = 1;  // alignment nulls are ignored by isGap (default)
-	var NULL_EXPAND = 2;  // nulls are expand to include adjacent alignment nulls
+	var NULL_IGNORE = 0;  // all nulls are ignored, converted to undefined (e.g. spanGaps: true)
+	var NULL_GAP    = 1;  // nulls are retained, alignment artifacts = undefined values (default)
+	var NULL_EXPAND = 2;  // nulls are expanded to include adjacent alignment artifacts (undefined values)
+
+	// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
+	function nullExpand(yVals, nullIdxs, alignedLen) {
+		for (var i = 0, xi = (void 0), lastNullIdx = -inf; i < nullIdxs.length; i++) {
+			var nullIdx = nullIdxs[i];
+
+			if (nullIdx > lastNullIdx) {
+				xi = nullIdx - 1;
+				while (xi >= 0 && yVals[xi] == null)
+					{ yVals[xi--] = null; }
+
+				xi = nullIdx + 1;
+				while (xi < alignedLen && yVals[xi] == null)
+					{ yVals[lastNullIdx = xi++] = null; }
+			}
+		}
+	}
 
 	// nullModes is a tables-matched array indicating how to treat nulls in each series
 	function join(tables, nullModes) {
-		if (tables.length == 1) {
-			return {
-				data: tables[0],
-				isGap: nullModes ? (u, seriesIdx, dataIdx) => nullModes[0][seriesIdx] != NULL_IGNORE : () => true,
-			};
-		}
+		if (tables.length == 1)
+			{ return tables[0]; }
 
 		var xVals = new Set();
-		var xNulls = [new Set()];
 
 		for (var ti = 0; ti < tables.length; ti++) {
 			var t = tables[ti];
@@ -359,22 +371,6 @@ var uPlot = (function () {
 
 			for (var i = 0; i < len; i++)
 				{ xVals.add(xs[i]); }
-
-			for (var si = 1; si < t.length; si++) {
-				var nulls = new Set();
-
-				// cache original nulls for isGap lookup
-				if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
-					var ys = t[si];
-
-					for (var i$1 = 0; i$1 < len; i$1++) {
-						if (ys[i$1] == null)
-							{ nulls.add(xs[i$1]); }
-					}
-				}
-
-				xNulls.push(nulls);
-			}
 		}
 
 		var data = [Array.from(xVals).sort((a, b) => a - b)];
@@ -383,67 +379,45 @@ var uPlot = (function () {
 
 		var xIdxs = new Map();
 
-		for (var i$2 = 0; i$2 < alignedLen; i$2++)
-			{ xIdxs.set(data[0][i$2], i$2); }
-
-		var gsi = 1;
+		for (var i$1 = 0; i$1 < alignedLen; i$1++)
+			{ xIdxs.set(data[0][i$1], i$1); }
 
 		for (var ti$1 = 0; ti$1 < tables.length; ti$1++) {
 			var t$1 = tables[ti$1];
 			var xs$1 = t$1[0];
 
-			for (var si$1 = 1; si$1 < t$1.length; si$1++) {
-				var ys$1 = t$1[si$1];
-
-				var yVals = Array(alignedLen).fill(null);
+			for (var si = 1; si < t$1.length; si++) {
+				var ys = t$1[si];
 
-				for (var i$3 = 0; i$3 < ys$1.length; i$3++)
-					{ yVals[xIdxs.get(xs$1[i$3])] = ys$1[i$3]; }
+				var yVals = Array(alignedLen).fill(undefined);
 
-				// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
-				if (nullModes && nullModes[ti$1][si$1] == NULL_EXPAND) {
-					var nulls$1 = xNulls[gsi];
-					var size = nulls$1.size;
-					var	i$4 = 0;
-					var xi = (void 0);
+				var nullMode = nullModes ? nullModes[ti$1][si] : NULL_GAP;
 
-					var lastAddedX = -inf;
-
-					for (var xVal of nulls$1.values()) {
-						if (i$4++ == size)
-							{ break; }
+				var nullIdxs = [];
 
-						if (xVal > lastAddedX) {
-							var xIdx = xIdxs.get(xVal);
+				for (var i$2 = 0; i$2 < ys.length; i$2++) {
+					var yVal = ys[i$2];
+					var alignedIdx = xIdxs.get(xs$1[i$2]);
 
-							xi = xIdx - 1;
-							while (yVals[xi] === null) {
-								nulls$1.add(data[0][xi]);
-								xi--;
-							}
+					if (yVal == null) {
+						if (nullMode != NULL_IGNORE) {
+							yVals[alignedIdx] = yVal;
 
-							xi = xIdx + 1;
-							while (yVals[xi] === null) {
-								nulls$1.add(lastAddedX = data[0][xi]);
-								xi++;
-							}
+							if (nullMode == NULL_EXPAND)
+								{ nullIdxs.push(alignedIdx); }
 						}
 					}
+					else
+						{ yVals[alignedIdx] = yVal; }
 				}
 
-				data.push(yVals);
+				nullExpand(yVals, nullIdxs, alignedLen);
 
-				gsi++;
+				data.push(yVals);
 			}
 		}
 
-		return {
-			data: data,
-			isGap: function isGap(u, seriesIdx, dataIdx) {
-				var xVal = u._data[0][dataIdx];
-				return xNulls[seriesIdx].has(xVal);
-			},
-		};
+		return data;
 	}
 
 	var microTask = typeof queueMicrotask == "undefined" ? fn => Promise.resolve().then(fn) : queueMicrotask;
@@ -1123,6 +1097,7 @@ var uPlot = (function () {
 	var xAxisOpts = {
 		show: true,
 		scale: "x",
+		stroke: hexBlack,
 		space: 50,
 		gap: 5,
 		size: 50,
@@ -1236,6 +1211,7 @@ var uPlot = (function () {
 	var yAxisOpts = {
 		show: true,
 		scale: "y",
+		stroke: hexBlack,
 		space: 30,
 		gap: 5,
 		size: 50,
@@ -1270,7 +1246,8 @@ var uPlot = (function () {
 
 	function seriesFillTo(self, seriesIdx, dataMin, dataMax) {
 		var scale = self.scales[self.series[seriesIdx].scale];
-		return scale.distr == 3 ? scale.min : 0;
+		var isUpperBandEdge = self.bands && self.bands.some(b => b.series[0] == seriesIdx);
+		return scale.distr == 3 || isUpperBandEdge ? scale.min : 0;
 	}
 
 	var ySeriesOpts = {
@@ -1280,7 +1257,6 @@ var uPlot = (function () {
 		show: true,
 		band: false,
 		spanGaps: false,
-		isGap: (self, seriesIdx, dataIdx) => true,
 		alpha: 1,
 		points: {
 			show: seriesPoints,
@@ -1516,8 +1492,6 @@ var uPlot = (function () {
 					drawAcc = drawAccV;
 				}
 
-				var isGap = series.isGap;
-
 				var dir = scaleX.dir * (scaleX.ori == 0 ? 1 : -1);
 
 				var _paths = {stroke: new Path2D(), fill: null, clip: null, band: null};
@@ -1554,7 +1528,7 @@ var uPlot = (function () {
 							minY = min(outY, minY);
 							maxY = max(outY, maxY);
 						}
-						else if (!accGaps && isGap(u, seriesIdx, i))
+						else if (!accGaps && dataY[i] === null)
 							{ accGaps = true; }
 					}
 					else {
@@ -1575,14 +1549,14 @@ var uPlot = (function () {
 							minY = maxY = outY;
 
 							// prior pixel can have data but still start a gap if ends with null
-							if (x - accX > 1 && dataY[i - dir] == null && isGap(u, seriesIdx, i - dir))
+							if (x - accX > 1 && dataY[i - dir] === null)
 								{ _addGap = true; }
 						}
 						else {
 							minY = inf;
 							maxY = -inf;
 
-							if (!accGaps && isGap(u, seriesIdx, i))
+							if (!accGaps && dataY[i] === null)
 								{ accGaps = true; }
 						}
 
@@ -1656,7 +1630,7 @@ var uPlot = (function () {
 					var xPos = valToPosX(xVal, scaleX, xDim, xOff);
 
 					if (yVal == null) {
-						if (series.isGap(u, seriesIdx, i)) {
+						if (yVal === null) {
 							addGap(gaps, prevXPos, xPos);
 							inGap = true;
 						}
@@ -1851,7 +1825,7 @@ var uPlot = (function () {
 					var x1 = round(valToPosX(dataX[i], scaleX, xDim, xOff));
 
 					if (yVal1 == null) {
-						if (series.isGap(u, seriesIdx, i)) {
+						if (yVal1 === null) {
 							addGap(gaps, prevXPos, x1);
 							inGap = true;
 						}
@@ -2578,7 +2552,7 @@ var uPlot = (function () {
 				s.paths  = s.paths || linearPath || retNull;
 				s.fillTo = fnOrSelf(s.fillTo || seriesFillTo);
 
-				s.stroke = fnOrSelf(s.stroke || hexBlack);
+				s.stroke = fnOrSelf(s.stroke || null);
 				s.fill   = fnOrSelf(s.fill || null);
 				s._stroke = s._fill = s._paths = null;
 
@@ -2652,7 +2626,12 @@ var uPlot = (function () {
 				axis.incrs  = fnOrSelf(axis.incrs  || (          sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
 				axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
 
+				axis.stroke       = fnOrSelf(axis.stroke);
+				axis.grid.stroke  = fnOrSelf(axis.grid.stroke);
+				axis.ticks.stroke = fnOrSelf(axis.ticks.stroke);
+
 				var av = axis.values;
+
 				axis.values = (
 					isTime ? (
 						isArr(av) ?
@@ -2717,11 +2696,6 @@ var uPlot = (function () {
 		var viaAutoScaleX = false;
 
 		function setData(_data, _resetScales) {
-			if (!isArr(_data) && isObj(_data)) {
-				_data.isGap && series.forEach(s => { s.isGap = _data.isGap; });
-				_data = _data.data;
-			}
-
 			_data = _data || [];
 			_data[0] = _data[0] || [];
 
@@ -3087,13 +3061,13 @@ var uPlot = (function () {
 			ctx.rect(lft, top, wid, hgt);
 			ctx.clip();
 
-			if (clip != null)
-				{ ctx.clip(clip); }
+			clip && ctx.clip(clip);
+
+			var isUpperEdge = fillBands(si, _fill);
 
-			if (!fillBands(si, _fill) && _fill != null)
-				{ ctx.fill(fill); }
+			!isUpperEdge && _fill   && fill   && ctx.fill(fill);
 
-			width && ctx.stroke(stroke);
+			width        && _stroke && stroke && ctx.stroke(stroke);
 
 			ctx.restore();
 
@@ -3301,7 +3275,7 @@ var uPlot = (function () {
 				var x        = ori == 1 ? finalPos : 0;
 
 				ctx.font         = axis.font[0];
-				ctx.fillStyle    = axis.stroke || hexBlack;									// rgba?
+				ctx.fillStyle    = axis.stroke(self, i);									// rgba?
 				ctx.textAlign    = axis.align == 1 ? LEFT :
 				                   axis.align == 2 ? RIGHT :
 				                   angle > 0 ? LEFT :
@@ -3377,7 +3351,7 @@ var uPlot = (function () {
 						basePos,
 						tickSize,
 						roundDec(ticks.width * pxRatio, 3),
-						ticks.stroke,
+						ticks.stroke(self, i),
 						ticks.dash,
 						ticks.cap
 					);
@@ -3395,7 +3369,7 @@ var uPlot = (function () {
 						ori == 0 ? plotTop : plotLft,
 						ori == 0 ? plotHgt : plotWid,
 						roundDec(grid.width * pxRatio, 3),
-						grid.stroke,
+						grid.stroke(self, i),
 						grid.dash,
 						grid.cap
 					);

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
plugins/uplot/uPlot.iife.min.js


Некоторые файлы не были показаны из-за большого количества измененных файлов