Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/expand-brackets/lib/compilers.js b/node_modules/expand-brackets/lib/compilers.js
new file mode 100644
index 0000000..fbf7fe8
--- /dev/null
+++ b/node_modules/expand-brackets/lib/compilers.js
@@ -0,0 +1,87 @@
+'use strict';
+
+var posix = require('posix-character-classes');
+
+module.exports = function(brackets) {
+  brackets.compiler
+
+    /**
+     * Escaped characters
+     */
+
+    .set('escape', function(node) {
+      return this.emit('\\' + node.val.replace(/^\\/, ''), node);
+    })
+
+    /**
+     * Text
+     */
+
+    .set('text', function(node) {
+      return this.emit(node.val.replace(/([{}])/g, '\\$1'), node);
+    })
+
+    /**
+     * POSIX character classes
+     */
+
+    .set('posix', function(node) {
+      if (node.val === '[::]') {
+        return this.emit('\\[::\\]', node);
+      }
+
+      var val = posix[node.inner];
+      if (typeof val === 'undefined') {
+        val = '[' + node.inner + ']';
+      }
+      return this.emit(val, node);
+    })
+
+    /**
+     * Non-posix brackets
+     */
+
+    .set('bracket', function(node) {
+      return this.mapVisit(node.nodes);
+    })
+    .set('bracket.open', function(node) {
+      return this.emit(node.val, node);
+    })
+    .set('bracket.inner', function(node) {
+      var inner = node.val;
+
+      if (inner === '[' || inner === ']') {
+        return this.emit('\\' + node.val, node);
+      }
+      if (inner === '^]') {
+        return this.emit('^\\]', node);
+      }
+      if (inner === '^') {
+        return this.emit('^', node);
+      }
+
+      if (/-/.test(inner) && !/(\d-\d|\w-\w)/.test(inner)) {
+        inner = inner.split('-').join('\\-');
+      }
+
+      var isNegated = inner.charAt(0) === '^';
+      // add slashes to negated brackets, per spec
+      if (isNegated && inner.indexOf('/') === -1) {
+        inner += '/';
+      }
+      if (isNegated && inner.indexOf('.') === -1) {
+        inner += '.';
+      }
+
+      // don't unescape `0` (octal literal)
+      inner = inner.replace(/\\([1-9])/g, '$1');
+      return this.emit(inner, node);
+    })
+    .set('bracket.close', function(node) {
+      var val = node.val.replace(/^\\/, '');
+      if (node.parent.escaped === true) {
+        return this.emit('\\' + val, node);
+      }
+      return this.emit(val, node);
+    });
+};
diff --git a/node_modules/expand-brackets/lib/parsers.js b/node_modules/expand-brackets/lib/parsers.js
new file mode 100644
index 0000000..450a512
--- /dev/null
+++ b/node_modules/expand-brackets/lib/parsers.js
@@ -0,0 +1,219 @@
+'use strict';
+
+var utils = require('./utils');
+var define = require('define-property');
+
+/**
+ * Text regex
+ */
+
+var TEXT_REGEX = '(\\[(?=.*\\])|\\])+';
+var not = utils.createRegex(TEXT_REGEX);
+
+/**
+ * Brackets parsers
+ */
+
+function parsers(brackets) {
+  brackets.state = brackets.state || {};
+  brackets.parser.sets.bracket = brackets.parser.sets.bracket || [];
+  brackets.parser
+
+    .capture('escape', function() {
+      if (this.isInside('bracket')) return;
+      var pos = this.position();
+      var m = this.match(/^\\(.)/);
+      if (!m) return;
+
+      return pos({
+        type: 'escape',
+        val: m[0]
+      });
+    })
+
+    /**
+     * Text parser
+     */
+
+    .capture('text', function() {
+      if (this.isInside('bracket')) return;
+      var pos = this.position();
+      var m = this.match(not);
+      if (!m || !m[0]) return;
+
+      return pos({
+        type: 'text',
+        val: m[0]
+      });
+    })
+
+    /**
+     * POSIX character classes: "[[:alpha:][:digits:]]"
+     */
+
+    .capture('posix', function() {
+      var pos = this.position();
+      var m = this.match(/^\[:(.*?):\](?=.*\])/);
+      if (!m) return;
+
+      var inside = this.isInside('bracket');
+      if (inside) {
+        brackets.posix++;
+      }
+
+      return pos({
+        type: 'posix',
+        insideBracket: inside,
+        inner: m[1],
+        val: m[0]
+      });
+    })
+
+    /**
+     * Bracket (noop)
+     */
+
+    .capture('bracket', function() {})
+
+    /**
+     * Open: '['
+     */
+
+    .capture('bracket.open', function() {
+      var parsed = this.parsed;
+      var pos = this.position();
+      var m = this.match(/^\[(?=.*\])/);
+      if (!m) return;
+
+      var prev = this.prev();
+      var last = utils.last(prev.nodes);
+
+      if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) {
+        last.val = last.val.slice(0, last.val.length - 1);
+        return pos({
+          type: 'escape',
+          val: m[0]
+        });
+      }
+
+      var open = pos({
+        type: 'bracket.open',
+        val: m[0]
+      });
+
+      if (last.type === 'bracket.open' || this.isInside('bracket')) {
+        open.val = '\\' + open.val;
+        open.type = 'bracket.inner';
+        open.escaped = true;
+        return open;
+      }
+
+      var node = pos({
+        type: 'bracket',
+        nodes: [open]
+      });
+
+      define(node, 'parent', prev);
+      define(open, 'parent', node);
+      this.push('bracket', node);
+      prev.nodes.push(node);
+    })
+
+    /**
+     * Bracket text
+     */
+
+    .capture('bracket.inner', function() {
+      if (!this.isInside('bracket')) return;
+      var pos = this.position();
+      var m = this.match(not);
+      if (!m || !m[0]) return;
+
+      var next = this.input.charAt(0);
+      var val = m[0];
+
+      var node = pos({
+        type: 'bracket.inner',
+        val: val
+      });
+
+      if (val === '\\\\') {
+        return node;
+      }
+
+      var first = val.charAt(0);
+      var last = val.slice(-1);
+
+      if (first === '!') {
+        val = '^' + val.slice(1);
+      }
+
+      if (last === '\\' || (val === '^' && next === ']')) {
+        val += this.input[0];
+        this.consume(1);
+      }
+
+      node.val = val;
+      return node;
+    })
+
+    /**
+     * Close: ']'
+     */
+
+    .capture('bracket.close', function() {
+      var parsed = this.parsed;
+      var pos = this.position();
+      var m = this.match(/^\]/);
+      if (!m) return;
+
+      var prev = this.prev();
+      var last = utils.last(prev.nodes);
+
+      if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) {
+        last.val = last.val.slice(0, last.val.length - 1);
+
+        return pos({
+          type: 'escape',
+          val: m[0]
+        });
+      }
+
+      var node = pos({
+        type: 'bracket.close',
+        rest: this.input,
+        val: m[0]
+      });
+
+      if (last.type === 'bracket.open') {
+        node.type = 'bracket.inner';
+        node.escaped = true;
+        return node;
+      }
+
+      var bracket = this.pop('bracket');
+      if (!this.isType(bracket, 'bracket')) {
+        if (this.options.strict) {
+          throw new Error('missing opening "["');
+        }
+        node.type = 'bracket.inner';
+        node.escaped = true;
+        return node;
+      }
+
+      bracket.nodes.push(node);
+      define(node, 'parent', bracket);
+    });
+}
+
+/**
+ * Brackets parsers
+ */
+
+module.exports = parsers;
+
+/**
+ * Expose text regex
+ */
+
+module.exports.TEXT_REGEX = TEXT_REGEX;
diff --git a/node_modules/expand-brackets/lib/utils.js b/node_modules/expand-brackets/lib/utils.js
new file mode 100644
index 0000000..599ff51
--- /dev/null
+++ b/node_modules/expand-brackets/lib/utils.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var toRegex = require('to-regex');
+var regexNot = require('regex-not');
+var cached;
+
+/**
+ * Get the last element from `array`
+ * @param {Array} `array`
+ * @return {*}
+ */
+
+exports.last = function(arr) {
+  return arr[arr.length - 1];
+};
+
+/**
+ * Create and cache regex to use for text nodes
+ */
+
+exports.createRegex = function(pattern, include) {
+  if (cached) return cached;
+  var opts = {contains: true, strictClose: false};
+  var not = regexNot.create(pattern, opts);
+  var re;
+
+  if (typeof include === 'string') {
+    re = toRegex('^(?:' + include + '|' + not + ')', opts);
+  } else {
+    re = toRegex(not, opts);
+  }
+
+  return (cached = re);
+};