Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/css-what/lib/index.d.ts b/node_modules/css-what/lib/index.d.ts
new file mode 100644
index 0000000..d474fa1
--- /dev/null
+++ b/node_modules/css-what/lib/index.d.ts
@@ -0,0 +1,4 @@
+export * from "./parse";
+export { default as parse } from "./parse";
+export { default as stringify } from "./stringify";
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/node_modules/css-what/lib/index.d.ts.map b/node_modules/css-what/lib/index.d.ts.map
new file mode 100644
index 0000000..4191999
--- /dev/null
+++ b/node_modules/css-what/lib/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC"}
\ No newline at end of file
diff --git a/node_modules/css-what/lib/index.js b/node_modules/css-what/lib/index.js
new file mode 100644
index 0000000..5095250
--- /dev/null
+++ b/node_modules/css-what/lib/index.js
@@ -0,0 +1,21 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.stringify = exports.parse = void 0;
+__exportStar(require("./parse"), exports);
+var parse_1 = require("./parse");
+Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return __importDefault(parse_1).default; } });
+var stringify_1 = require("./stringify");
+Object.defineProperty(exports, "stringify", { enumerable: true, get: function () { return __importDefault(stringify_1).default; } });
diff --git a/node_modules/css-what/lib/parse.d.ts b/node_modules/css-what/lib/parse.d.ts
new file mode 100644
index 0000000..7e03a58
--- /dev/null
+++ b/node_modules/css-what/lib/parse.d.ts
@@ -0,0 +1,38 @@
+export default parse;
+export interface Options {
+    lowerCaseAttributeNames?: boolean;
+    lowerCaseTags?: boolean;
+    xmlMode?: boolean;
+}
+export declare type Selector = PseudoSelector | PseudoElement | AttributeSelector | TagSelector | UniversalSelector | Traversal;
+export interface AttributeSelector {
+    type: "attribute";
+    name: string;
+    action: AttributeAction;
+    value: string;
+    ignoreCase: boolean;
+}
+declare type DataType = Selector[][] | null | string;
+export interface PseudoSelector {
+    type: "pseudo";
+    name: string;
+    data: DataType;
+}
+export interface PseudoElement {
+    type: "pseudo-element";
+    name: string;
+}
+export interface TagSelector {
+    type: "tag";
+    name: string;
+}
+export interface UniversalSelector {
+    type: "universal";
+}
+export interface Traversal {
+    type: TraversalType;
+}
+export declare type AttributeAction = "any" | "element" | "end" | "equals" | "exists" | "hyphen" | "not" | "start";
+export declare type TraversalType = "adjacent" | "child" | "descendant" | "parent" | "sibling";
+declare function parse(selector: string, options?: Options): Selector[][];
+//# sourceMappingURL=parse.d.ts.map
\ No newline at end of file
diff --git a/node_modules/css-what/lib/parse.d.ts.map b/node_modules/css-what/lib/parse.d.ts.map
new file mode 100644
index 0000000..027b657
--- /dev/null
+++ b/node_modules/css-what/lib/parse.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAEA,eAAe,KAAK,CAAC;AAErB,MAAM,WAAW,OAAO;IACpB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,oBAAY,QAAQ,GACd,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,WAAW,GACX,iBAAiB,GACjB,SAAS,CAAC;AAEhB,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,aAAK,QAAQ,GAAG,QAAQ,EAAE,EAAE,GAAG,IAAI,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,aAAa,CAAC;CACvB;AAED,oBAAY,eAAe,GACrB,KAAK,GACL,SAAS,GACT,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,OAAO,CAAC;AAEd,oBAAY,aAAa,GACnB,UAAU,GACV,OAAO,GACP,YAAY,GACZ,QAAQ,GACR,SAAS,CAAC;AAkEhB,iBAAS,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,EAAE,CAUhE"}
\ No newline at end of file
diff --git a/node_modules/css-what/lib/parse.js b/node_modules/css-what/lib/parse.js
new file mode 100644
index 0000000..abe4471
--- /dev/null
+++ b/node_modules/css-what/lib/parse.js
@@ -0,0 +1,239 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = parse;
+var reName = /^[^\\]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
+var reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
+// Modified version of https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L87
+var reAttr = /^\s*((?:\\.|[\w\u00b0-\uFFFF-])+)\s*(?:(\S?)=\s*(?:(['"])((?:[^\\]|\\[^])*?)\3|(#?(?:\\.|[\w\u00b0-\uFFFF-])*)|)|)\s*(i)?\]/;
+var actionTypes = {
+    undefined: "exists",
+    "": "equals",
+    "~": "element",
+    "^": "start",
+    $: "end",
+    "*": "any",
+    "!": "not",
+    "|": "hyphen",
+};
+var Traversals = {
+    ">": "child",
+    "<": "parent",
+    "~": "sibling",
+    "+": "adjacent",
+};
+var attribSelectors = {
+    "#": ["id", "equals"],
+    ".": ["class", "element"],
+};
+// Pseudos, whose data property is parsed as well.
+var unpackPseudos = new Set([
+    "has",
+    "not",
+    "matches",
+    "is",
+    "host",
+    "host-context",
+]);
+var stripQuotesFromPseudos = new Set(["contains", "icontains"]);
+var quotes = new Set(['"', "'"]);
+// Unescape function taken from https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L152
+function funescape(_, escaped, escapedWhitespace) {
+    var high = parseInt(escaped, 16) - 0x10000;
+    // NaN means non-codepoint
+    return high !== high || escapedWhitespace
+        ? escaped
+        : high < 0
+            ? // BMP codepoint
+                String.fromCharCode(high + 0x10000)
+            : // Supplemental Plane codepoint (surrogate pair)
+                String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
+}
+function unescapeCSS(str) {
+    return str.replace(reEscape, funescape);
+}
+function isWhitespace(c) {
+    return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
+}
+function parse(selector, options) {
+    var subselects = [];
+    selector = parseSelector(subselects, "" + selector, options);
+    if (selector !== "") {
+        throw new Error("Unmatched selector: " + selector);
+    }
+    return subselects;
+}
+function parseSelector(subselects, selector, options) {
+    var _a, _b;
+    if (options === void 0) { options = {}; }
+    var tokens = [];
+    var sawWS = false;
+    function getName() {
+        var match = selector.match(reName);
+        if (!match) {
+            throw new Error("Expected name, found " + selector);
+        }
+        var sub = match[0];
+        selector = selector.substr(sub.length);
+        return unescapeCSS(sub);
+    }
+    function stripWhitespace(start) {
+        while (isWhitespace(selector.charAt(start)))
+            start++;
+        selector = selector.substr(start);
+    }
+    function isEscaped(pos) {
+        var slashCount = 0;
+        while (selector.charAt(--pos) === "\\")
+            slashCount++;
+        return (slashCount & 1) === 1;
+    }
+    stripWhitespace(0);
+    while (selector !== "") {
+        var firstChar = selector.charAt(0);
+        if (isWhitespace(firstChar)) {
+            sawWS = true;
+            stripWhitespace(1);
+        }
+        else if (firstChar in Traversals) {
+            tokens.push({ type: Traversals[firstChar] });
+            sawWS = false;
+            stripWhitespace(1);
+        }
+        else if (firstChar === ",") {
+            if (tokens.length === 0) {
+                throw new Error("Empty sub-selector");
+            }
+            subselects.push(tokens);
+            tokens = [];
+            sawWS = false;
+            stripWhitespace(1);
+        }
+        else {
+            if (sawWS) {
+                if (tokens.length > 0) {
+                    tokens.push({ type: "descendant" });
+                }
+                sawWS = false;
+            }
+            if (firstChar === "*") {
+                selector = selector.substr(1);
+                tokens.push({ type: "universal" });
+            }
+            else if (firstChar in attribSelectors) {
+                var _c = attribSelectors[firstChar], name_1 = _c[0], action = _c[1];
+                selector = selector.substr(1);
+                tokens.push({
+                    type: "attribute",
+                    name: name_1,
+                    action: action,
+                    value: getName(),
+                    ignoreCase: false,
+                });
+            }
+            else if (firstChar === "[") {
+                selector = selector.substr(1);
+                var attributeMatch = selector.match(reAttr);
+                if (!attributeMatch) {
+                    throw new Error("Malformed attribute selector: " + selector);
+                }
+                var completeSelector = attributeMatch[0], baseName = attributeMatch[1], actionType = attributeMatch[2], _d = attributeMatch[4], quotedValue = _d === void 0 ? "" : _d, _e = attributeMatch[5], value = _e === void 0 ? quotedValue : _e, ignoreCase = attributeMatch[6];
+                selector = selector.substr(completeSelector.length);
+                var name_2 = unescapeCSS(baseName);
+                if ((_a = options.lowerCaseAttributeNames) !== null && _a !== void 0 ? _a : !options.xmlMode) {
+                    name_2 = name_2.toLowerCase();
+                }
+                tokens.push({
+                    type: "attribute",
+                    name: name_2,
+                    action: actionTypes[actionType],
+                    value: unescapeCSS(value),
+                    ignoreCase: !!ignoreCase,
+                });
+            }
+            else if (firstChar === ":") {
+                if (selector.charAt(1) === ":") {
+                    selector = selector.substr(2);
+                    tokens.push({
+                        type: "pseudo-element",
+                        name: getName().toLowerCase(),
+                    });
+                    continue;
+                }
+                selector = selector.substr(1);
+                var name_3 = getName().toLowerCase();
+                var data = null;
+                if (selector.startsWith("(")) {
+                    if (unpackPseudos.has(name_3)) {
+                        var quot = selector.charAt(1);
+                        var quoted = quotes.has(quot);
+                        selector = selector.substr(quoted ? 2 : 1);
+                        data = [];
+                        selector = parseSelector(data, selector, options);
+                        if (quoted) {
+                            if (!selector.startsWith(quot)) {
+                                throw new Error("Unmatched quotes in :" + name_3);
+                            }
+                            else {
+                                selector = selector.substr(1);
+                            }
+                        }
+                        if (!selector.startsWith(")")) {
+                            throw new Error("Missing closing parenthesis in :" + name_3 + " (" + selector + ")");
+                        }
+                        selector = selector.substr(1);
+                    }
+                    else {
+                        var pos = 1;
+                        var counter = 1;
+                        for (; counter > 0 && pos < selector.length; pos++) {
+                            if (selector.charAt(pos) === "(" &&
+                                !isEscaped(pos)) {
+                                counter++;
+                            }
+                            else if (selector.charAt(pos) === ")" &&
+                                !isEscaped(pos)) {
+                                counter--;
+                            }
+                        }
+                        if (counter) {
+                            throw new Error("Parenthesis not matched");
+                        }
+                        data = selector.substr(1, pos - 2);
+                        selector = selector.substr(pos);
+                        if (stripQuotesFromPseudos.has(name_3)) {
+                            var quot = data.charAt(0);
+                            if (quot === data.slice(-1) && quotes.has(quot)) {
+                                data = data.slice(1, -1);
+                            }
+                            data = unescapeCSS(data);
+                        }
+                    }
+                }
+                tokens.push({ type: "pseudo", name: name_3, data: data });
+            }
+            else if (reName.test(selector)) {
+                var name_4 = getName();
+                if ((_b = options.lowerCaseTags) !== null && _b !== void 0 ? _b : !options.xmlMode) {
+                    name_4 = name_4.toLowerCase();
+                }
+                tokens.push({ type: "tag", name: name_4 });
+            }
+            else {
+                if (tokens.length &&
+                    tokens[tokens.length - 1].type === "descendant") {
+                    tokens.pop();
+                }
+                addToken(subselects, tokens);
+                return selector;
+            }
+        }
+    }
+    addToken(subselects, tokens);
+    return selector;
+}
+function addToken(subselects, tokens) {
+    if (subselects.length > 0 && tokens.length === 0) {
+        throw new Error("Empty sub-selector");
+    }
+    subselects.push(tokens);
+}
diff --git a/node_modules/css-what/lib/stringify.d.ts b/node_modules/css-what/lib/stringify.d.ts
new file mode 100644
index 0000000..99509d1
--- /dev/null
+++ b/node_modules/css-what/lib/stringify.d.ts
@@ -0,0 +1,3 @@
+import { Selector } from "./parse";
+export default function stringify(token: Selector[][]): string;
+//# sourceMappingURL=stringify.d.ts.map
\ No newline at end of file
diff --git a/node_modules/css-what/lib/stringify.d.ts.map b/node_modules/css-what/lib/stringify.d.ts.map
new file mode 100644
index 0000000..c2809ab
--- /dev/null
+++ b/node_modules/css-what/lib/stringify.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"stringify.d.ts","sourceRoot":"","sources":["../src/stringify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAuBnC,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,MAAM,CAE7D"}
\ No newline at end of file
diff --git a/node_modules/css-what/lib/stringify.js b/node_modules/css-what/lib/stringify.js
new file mode 100644
index 0000000..b496ff1
--- /dev/null
+++ b/node_modules/css-what/lib/stringify.js
@@ -0,0 +1,83 @@
+"use strict";
+var __spreadArrays = (this && this.__spreadArrays) || function () {
+    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+    for (var r = Array(s), k = 0, i = 0; i < il; i++)
+        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+            r[k] = a[j];
+    return r;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var actionTypes = {
+    equals: "",
+    element: "~",
+    start: "^",
+    end: "$",
+    any: "*",
+    not: "!",
+    hyphen: "|",
+};
+var charsToEscape = new Set(__spreadArrays(Object.keys(actionTypes)
+    .map(function (typeKey) { return actionTypes[typeKey]; })
+    .filter(Boolean), [
+    ":",
+    "[",
+    "]",
+    " ",
+    "\\",
+]));
+function stringify(token) {
+    return token.map(stringifySubselector).join(", ");
+}
+exports.default = stringify;
+function stringifySubselector(token) {
+    return token.map(stringifyToken).join("");
+}
+function stringifyToken(token) {
+    switch (token.type) {
+        // Simple types
+        case "child":
+            return " > ";
+        case "parent":
+            return " < ";
+        case "sibling":
+            return " ~ ";
+        case "adjacent":
+            return " + ";
+        case "descendant":
+            return " ";
+        case "universal":
+            return "*";
+        case "tag":
+            return escapeName(token.name);
+        case "pseudo-element":
+            return "::" + escapeName(token.name);
+        case "pseudo":
+            if (token.data === null)
+                return ":" + escapeName(token.name);
+            if (typeof token.data === "string") {
+                return ":" + escapeName(token.name) + "(" + token.data + ")";
+            }
+            return ":" + escapeName(token.name) + "(" + stringify(token.data) + ")";
+        case "attribute":
+            if (token.action === "exists") {
+                return "[" + escapeName(token.name) + "]";
+            }
+            if (token.name === "id" &&
+                token.action === "equals" &&
+                !token.ignoreCase) {
+                return "#" + escapeName(token.value);
+            }
+            if (token.name === "class" &&
+                token.action === "element" &&
+                !token.ignoreCase) {
+                return "." + escapeName(token.value);
+            }
+            return "[" + escapeName(token.name) + actionTypes[token.action] + "='" + escapeName(token.value) + "'" + (token.ignoreCase ? "i" : "") + "]";
+    }
+}
+function escapeName(str) {
+    return str
+        .split("")
+        .map(function (c) { return (charsToEscape.has(c) ? "\\" + c : c); })
+        .join("");
+}