HOME


Mini Shell 1.0
Redirecting to https://devs.lapieza.net/iniciar-sesion Redirecting to https://devs.lapieza.net/iniciar-sesion.
DIR: /proc/self/root/usr/share/node_modules/esquery/dist/
Upload File :
Current File : //proc/self/root/usr/share/node_modules/esquery/dist/esquery.esm.js
import estraverse from 'estraverse';

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

var parser$1 = {exports: {}};

/*
 * Generated by PEG.js 0.10.0.
 *
 * http://pegjs.org/
 */

(function (module) {
	(function(root, factory) {
	  if (module.exports) {
	    module.exports = factory();
	  }
	})(commonjsGlobal, function() {

	  function peg$subclass(child, parent) {
	    function ctor() { this.constructor = child; }
	    ctor.prototype = parent.prototype;
	    child.prototype = new ctor();
	  }

	  function peg$SyntaxError(message, expected, found, location) {
	    this.message  = message;
	    this.expected = expected;
	    this.found    = found;
	    this.location = location;
	    this.name     = "SyntaxError";

	    if (typeof Error.captureStackTrace === "function") {
	      Error.captureStackTrace(this, peg$SyntaxError);
	    }
	  }

	  peg$subclass(peg$SyntaxError, Error);

	  peg$SyntaxError.buildMessage = function(expected, found) {
	    var DESCRIBE_EXPECTATION_FNS = {
	          literal: function(expectation) {
	            return "\"" + literalEscape(expectation.text) + "\"";
	          },

	          "class": function(expectation) {
	            var escapedParts = "",
	                i;

	            for (i = 0; i < expectation.parts.length; i++) {
	              escapedParts += expectation.parts[i] instanceof Array
	                ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])
	                : classEscape(expectation.parts[i]);
	            }

	            return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
	          },

	          any: function(expectation) {
	            return "any character";
	          },

	          end: function(expectation) {
	            return "end of input";
	          },

	          other: function(expectation) {
	            return expectation.description;
	          }
	        };

	    function hex(ch) {
	      return ch.charCodeAt(0).toString(16).toUpperCase();
	    }

	    function literalEscape(s) {
	      return s
	        .replace(/\\/g, '\\\\')
	        .replace(/"/g,  '\\"')
	        .replace(/\0/g, '\\0')
	        .replace(/\t/g, '\\t')
	        .replace(/\n/g, '\\n')
	        .replace(/\r/g, '\\r')
	        .replace(/[\x00-\x0F]/g,          function(ch) { return '\\x0' + hex(ch); })
	        .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x'  + hex(ch); });
	    }

	    function classEscape(s) {
	      return s
	        .replace(/\\/g, '\\\\')
	        .replace(/\]/g, '\\]')
	        .replace(/\^/g, '\\^')
	        .replace(/-/g,  '\\-')
	        .replace(/\0/g, '\\0')
	        .replace(/\t/g, '\\t')
	        .replace(/\n/g, '\\n')
	        .replace(/\r/g, '\\r')
	        .replace(/[\x00-\x0F]/g,          function(ch) { return '\\x0' + hex(ch); })
	        .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x'  + hex(ch); });
	    }

	    function describeExpectation(expectation) {
	      return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
	    }

	    function describeExpected(expected) {
	      var descriptions = new Array(expected.length),
	          i, j;

	      for (i = 0; i < expected.length; i++) {
	        descriptions[i] = describeExpectation(expected[i]);
	      }

	      descriptions.sort();

	      if (descriptions.length > 0) {
	        for (i = 1, j = 1; i < descriptions.length; i++) {
	          if (descriptions[i - 1] !== descriptions[i]) {
	            descriptions[j] = descriptions[i];
	            j++;
	          }
	        }
	        descriptions.length = j;
	      }

	      switch (descriptions.length) {
	        case 1:
	          return descriptions[0];

	        case 2:
	          return descriptions[0] + " or " + descriptions[1];

	        default:
	          return descriptions.slice(0, -1).join(", ")
	            + ", or "
	            + descriptions[descriptions.length - 1];
	      }
	    }

	    function describeFound(found) {
	      return found ? "\"" + literalEscape(found) + "\"" : "end of input";
	    }

	    return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
	  };

	  function peg$parse(input, options) {
	    options = options !== void 0 ? options : {};

	    var peg$FAILED = {},

	        peg$startRuleFunctions = { start: peg$parsestart },
	        peg$startRuleFunction  = peg$parsestart,

	        peg$c0 = function(ss) {
	            return ss.length === 1 ? ss[0] : { type: 'matches', selectors: ss };
	          },
	        peg$c1 = function() { return void 0; },
	        peg$c2 = " ",
	        peg$c3 = peg$literalExpectation(" ", false),
	        peg$c4 = /^[^ [\],():#!=><~+.]/,
	        peg$c5 = peg$classExpectation([" ", "[", "]", ",", "(", ")", ":", "#", "!", "=", ">", "<", "~", "+", "."], true, false),
	        peg$c6 = function(i) { return i.join(''); },
	        peg$c7 = ">",
	        peg$c8 = peg$literalExpectation(">", false),
	        peg$c9 = function() { return 'child'; },
	        peg$c10 = "~",
	        peg$c11 = peg$literalExpectation("~", false),
	        peg$c12 = function() { return 'sibling'; },
	        peg$c13 = "+",
	        peg$c14 = peg$literalExpectation("+", false),
	        peg$c15 = function() { return 'adjacent'; },
	        peg$c16 = function() { return 'descendant'; },
	        peg$c17 = ",",
	        peg$c18 = peg$literalExpectation(",", false),
	        peg$c19 = function(s, ss) {
	          return [s].concat(ss.map(function (s) { return s[3]; }));
	        },
	        peg$c20 = function(a, ops) {
	            return ops.reduce(function (memo, rhs) {
	              return { type: rhs[0], left: memo, right: rhs[1] };
	            }, a);
	          },
	        peg$c21 = "!",
	        peg$c22 = peg$literalExpectation("!", false),
	        peg$c23 = function(subject, as) {
	            const b = as.length === 1 ? as[0] : { type: 'compound', selectors: as };
	            if(subject) b.subject = true;
	            return b;
	          },
	        peg$c24 = "*",
	        peg$c25 = peg$literalExpectation("*", false),
	        peg$c26 = function(a) { return { type: 'wildcard', value: a }; },
	        peg$c27 = "#",
	        peg$c28 = peg$literalExpectation("#", false),
	        peg$c29 = function(i) { return { type: 'identifier', value: i }; },
	        peg$c30 = "[",
	        peg$c31 = peg$literalExpectation("[", false),
	        peg$c32 = "]",
	        peg$c33 = peg$literalExpectation("]", false),
	        peg$c34 = function(v) { return v; },
	        peg$c35 = /^[><!]/,
	        peg$c36 = peg$classExpectation([">", "<", "!"], false, false),
	        peg$c37 = "=",
	        peg$c38 = peg$literalExpectation("=", false),
	        peg$c39 = function(a) { return (a || '') + '='; },
	        peg$c40 = /^[><]/,
	        peg$c41 = peg$classExpectation([">", "<"], false, false),
	        peg$c42 = ".",
	        peg$c43 = peg$literalExpectation(".", false),
	        peg$c44 = function(a, as) {
	            return [].concat.apply([a], as).join('');
	          },
	        peg$c45 = function(name, op, value) {
	              return { type: 'attribute', name: name, operator: op, value: value };
	            },
	        peg$c46 = function(name) { return { type: 'attribute', name: name }; },
	        peg$c47 = "\"",
	        peg$c48 = peg$literalExpectation("\"", false),
	        peg$c49 = /^[^\\"]/,
	        peg$c50 = peg$classExpectation(["\\", "\""], true, false),
	        peg$c51 = "\\",
	        peg$c52 = peg$literalExpectation("\\", false),
	        peg$c53 = peg$anyExpectation(),
	        peg$c54 = function(a, b) { return a + b; },
	        peg$c55 = function(d) {
	                return { type: 'literal', value: strUnescape(d.join('')) };
	              },
	        peg$c56 = "'",
	        peg$c57 = peg$literalExpectation("'", false),
	        peg$c58 = /^[^\\']/,
	        peg$c59 = peg$classExpectation(["\\", "'"], true, false),
	        peg$c60 = /^[0-9]/,
	        peg$c61 = peg$classExpectation([["0", "9"]], false, false),
	        peg$c62 = function(a, b) {
	                // Can use `a.flat().join('')` once supported
	                const leadingDecimals = a ? [].concat.apply([], a).join('') : '';
	                return { type: 'literal', value: parseFloat(leadingDecimals + b.join('')) };
	              },
	        peg$c63 = function(i) { return { type: 'literal', value: i }; },
	        peg$c64 = "type(",
	        peg$c65 = peg$literalExpectation("type(", false),
	        peg$c66 = /^[^ )]/,
	        peg$c67 = peg$classExpectation([" ", ")"], true, false),
	        peg$c68 = ")",
	        peg$c69 = peg$literalExpectation(")", false),
	        peg$c70 = function(t) { return { type: 'type', value: t.join('') }; },
	        peg$c71 = /^[imsu]/,
	        peg$c72 = peg$classExpectation(["i", "m", "s", "u"], false, false),
	        peg$c73 = "/",
	        peg$c74 = peg$literalExpectation("/", false),
	        peg$c75 = /^[^\/]/,
	        peg$c76 = peg$classExpectation(["/"], true, false),
	        peg$c77 = function(d, flgs) { return {
	              type: 'regexp', value: new RegExp(d.join(''), flgs ? flgs.join('') : '') };
	            },
	        peg$c78 = function(i, is) {
	          return { type: 'field', name: is.reduce(function(memo, p){ return memo + p[0] + p[1]; }, i)};
	        },
	        peg$c79 = ":not(",
	        peg$c80 = peg$literalExpectation(":not(", false),
	        peg$c81 = function(ss) { return { type: 'not', selectors: ss }; },
	        peg$c82 = ":matches(",
	        peg$c83 = peg$literalExpectation(":matches(", false),
	        peg$c84 = function(ss) { return { type: 'matches', selectors: ss }; },
	        peg$c85 = ":has(",
	        peg$c86 = peg$literalExpectation(":has(", false),
	        peg$c87 = function(ss) { return { type: 'has', selectors: ss }; },
	        peg$c88 = ":first-child",
	        peg$c89 = peg$literalExpectation(":first-child", false),
	        peg$c90 = function() { return nth(1); },
	        peg$c91 = ":last-child",
	        peg$c92 = peg$literalExpectation(":last-child", false),
	        peg$c93 = function() { return nthLast(1); },
	        peg$c94 = ":nth-child(",
	        peg$c95 = peg$literalExpectation(":nth-child(", false),
	        peg$c96 = function(n) { return nth(parseInt(n.join(''), 10)); },
	        peg$c97 = ":nth-last-child(",
	        peg$c98 = peg$literalExpectation(":nth-last-child(", false),
	        peg$c99 = function(n) { return nthLast(parseInt(n.join(''), 10)); },
	        peg$c100 = ":",
	        peg$c101 = peg$literalExpectation(":", false),
	        peg$c102 = "statement",
	        peg$c103 = peg$literalExpectation("statement", true),
	        peg$c104 = "expression",
	        peg$c105 = peg$literalExpectation("expression", true),
	        peg$c106 = "declaration",
	        peg$c107 = peg$literalExpectation("declaration", true),
	        peg$c108 = "function",
	        peg$c109 = peg$literalExpectation("function", true),
	        peg$c110 = "pattern",
	        peg$c111 = peg$literalExpectation("pattern", true),
	        peg$c112 = function(c) {
	          return { type: 'class', name: c };
	        },

	        peg$currPos          = 0,
	        peg$posDetailsCache  = [{ line: 1, column: 1 }],
	        peg$maxFailPos       = 0,
	        peg$maxFailExpected  = [],
	        peg$resultsCache = {},

	        peg$result;

	    if ("startRule" in options) {
	      if (!(options.startRule in peg$startRuleFunctions)) {
	        throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
	      }

	      peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
	    }

	    function peg$literalExpectation(text, ignoreCase) {
	      return { type: "literal", text: text, ignoreCase: ignoreCase };
	    }

	    function peg$classExpectation(parts, inverted, ignoreCase) {
	      return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
	    }

	    function peg$anyExpectation() {
	      return { type: "any" };
	    }

	    function peg$endExpectation() {
	      return { type: "end" };
	    }

	    function peg$computePosDetails(pos) {
	      var details = peg$posDetailsCache[pos], p;

	      if (details) {
	        return details;
	      } else {
	        p = pos - 1;
	        while (!peg$posDetailsCache[p]) {
	          p--;
	        }

	        details = peg$posDetailsCache[p];
	        details = {
	          line:   details.line,
	          column: details.column
	        };

	        while (p < pos) {
	          if (input.charCodeAt(p) === 10) {
	            details.line++;
	            details.column = 1;
	          } else {
	            details.column++;
	          }

	          p++;
	        }

	        peg$posDetailsCache[pos] = details;
	        return details;
	      }
	    }

	    function peg$computeLocation(startPos, endPos) {
	      var startPosDetails = peg$computePosDetails(startPos),
	          endPosDetails   = peg$computePosDetails(endPos);

	      return {
	        start: {
	          offset: startPos,
	          line:   startPosDetails.line,
	          column: startPosDetails.column
	        },
	        end: {
	          offset: endPos,
	          line:   endPosDetails.line,
	          column: endPosDetails.column
	        }
	      };
	    }

	    function peg$fail(expected) {
	      if (peg$currPos < peg$maxFailPos) { return; }

	      if (peg$currPos > peg$maxFailPos) {
	        peg$maxFailPos = peg$currPos;
	        peg$maxFailExpected = [];
	      }

	      peg$maxFailExpected.push(expected);
	    }

	    function peg$buildStructuredError(expected, found, location) {
	      return new peg$SyntaxError(
	        peg$SyntaxError.buildMessage(expected, found),
	        expected,
	        found,
	        location
	      );
	    }

	    function peg$parsestart() {
	      var s0, s1, s2, s3;

	      var key    = peg$currPos * 30 + 0,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parse_();
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parseselectors();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parse_();
	          if (s3 !== peg$FAILED) {
	            s1 = peg$c0(s2);
	            s0 = s1;
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }
	      if (s0 === peg$FAILED) {
	        s0 = peg$currPos;
	        s1 = peg$parse_();
	        if (s1 !== peg$FAILED) {
	          s1 = peg$c1();
	        }
	        s0 = s1;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parse_() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 1,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = [];
	      if (input.charCodeAt(peg$currPos) === 32) {
	        s1 = peg$c2;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c3); }
	      }
	      while (s1 !== peg$FAILED) {
	        s0.push(s1);
	        if (input.charCodeAt(peg$currPos) === 32) {
	          s1 = peg$c2;
	          peg$currPos++;
	        } else {
	          s1 = peg$FAILED;
	          { peg$fail(peg$c3); }
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseidentifierName() {
	      var s0, s1, s2;

	      var key    = peg$currPos * 30 + 2,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = [];
	      if (peg$c4.test(input.charAt(peg$currPos))) {
	        s2 = input.charAt(peg$currPos);
	        peg$currPos++;
	      } else {
	        s2 = peg$FAILED;
	        { peg$fail(peg$c5); }
	      }
	      if (s2 !== peg$FAILED) {
	        while (s2 !== peg$FAILED) {
	          s1.push(s2);
	          if (peg$c4.test(input.charAt(peg$currPos))) {
	            s2 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s2 = peg$FAILED;
	            { peg$fail(peg$c5); }
	          }
	        }
	      } else {
	        s1 = peg$FAILED;
	      }
	      if (s1 !== peg$FAILED) {
	        s1 = peg$c6(s1);
	      }
	      s0 = s1;

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsebinaryOp() {
	      var s0, s1, s2, s3;

	      var key    = peg$currPos * 30 + 3,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parse_();
	      if (s1 !== peg$FAILED) {
	        if (input.charCodeAt(peg$currPos) === 62) {
	          s2 = peg$c7;
	          peg$currPos++;
	        } else {
	          s2 = peg$FAILED;
	          { peg$fail(peg$c8); }
	        }
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parse_();
	          if (s3 !== peg$FAILED) {
	            s1 = peg$c9();
	            s0 = s1;
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }
	      if (s0 === peg$FAILED) {
	        s0 = peg$currPos;
	        s1 = peg$parse_();
	        if (s1 !== peg$FAILED) {
	          if (input.charCodeAt(peg$currPos) === 126) {
	            s2 = peg$c10;
	            peg$currPos++;
	          } else {
	            s2 = peg$FAILED;
	            { peg$fail(peg$c11); }
	          }
	          if (s2 !== peg$FAILED) {
	            s3 = peg$parse_();
	            if (s3 !== peg$FAILED) {
	              s1 = peg$c12();
	              s0 = s1;
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	        if (s0 === peg$FAILED) {
	          s0 = peg$currPos;
	          s1 = peg$parse_();
	          if (s1 !== peg$FAILED) {
	            if (input.charCodeAt(peg$currPos) === 43) {
	              s2 = peg$c13;
	              peg$currPos++;
	            } else {
	              s2 = peg$FAILED;
	              { peg$fail(peg$c14); }
	            }
	            if (s2 !== peg$FAILED) {
	              s3 = peg$parse_();
	              if (s3 !== peg$FAILED) {
	                s1 = peg$c15();
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	          if (s0 === peg$FAILED) {
	            s0 = peg$currPos;
	            if (input.charCodeAt(peg$currPos) === 32) {
	              s1 = peg$c2;
	              peg$currPos++;
	            } else {
	              s1 = peg$FAILED;
	              { peg$fail(peg$c3); }
	            }
	            if (s1 !== peg$FAILED) {
	              s2 = peg$parse_();
	              if (s2 !== peg$FAILED) {
	                s1 = peg$c16();
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          }
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseselectors() {
	      var s0, s1, s2, s3, s4, s5, s6, s7;

	      var key    = peg$currPos * 30 + 4,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parseselector();
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        s3 = peg$currPos;
	        s4 = peg$parse_();
	        if (s4 !== peg$FAILED) {
	          if (input.charCodeAt(peg$currPos) === 44) {
	            s5 = peg$c17;
	            peg$currPos++;
	          } else {
	            s5 = peg$FAILED;
	            { peg$fail(peg$c18); }
	          }
	          if (s5 !== peg$FAILED) {
	            s6 = peg$parse_();
	            if (s6 !== peg$FAILED) {
	              s7 = peg$parseselector();
	              if (s7 !== peg$FAILED) {
	                s4 = [s4, s5, s6, s7];
	                s3 = s4;
	              } else {
	                peg$currPos = s3;
	                s3 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s3;
	          s3 = peg$FAILED;
	        }
	        while (s3 !== peg$FAILED) {
	          s2.push(s3);
	          s3 = peg$currPos;
	          s4 = peg$parse_();
	          if (s4 !== peg$FAILED) {
	            if (input.charCodeAt(peg$currPos) === 44) {
	              s5 = peg$c17;
	              peg$currPos++;
	            } else {
	              s5 = peg$FAILED;
	              { peg$fail(peg$c18); }
	            }
	            if (s5 !== peg$FAILED) {
	              s6 = peg$parse_();
	              if (s6 !== peg$FAILED) {
	                s7 = peg$parseselector();
	                if (s7 !== peg$FAILED) {
	                  s4 = [s4, s5, s6, s7];
	                  s3 = s4;
	                } else {
	                  peg$currPos = s3;
	                  s3 = peg$FAILED;
	                }
	              } else {
	                peg$currPos = s3;
	                s3 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c19(s1, s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseselector() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 5,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parsesequence();
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        s3 = peg$currPos;
	        s4 = peg$parsebinaryOp();
	        if (s4 !== peg$FAILED) {
	          s5 = peg$parsesequence();
	          if (s5 !== peg$FAILED) {
	            s4 = [s4, s5];
	            s3 = s4;
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s3;
	          s3 = peg$FAILED;
	        }
	        while (s3 !== peg$FAILED) {
	          s2.push(s3);
	          s3 = peg$currPos;
	          s4 = peg$parsebinaryOp();
	          if (s4 !== peg$FAILED) {
	            s5 = peg$parsesequence();
	            if (s5 !== peg$FAILED) {
	              s4 = [s4, s5];
	              s3 = s4;
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c20(s1, s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsesequence() {
	      var s0, s1, s2, s3;

	      var key    = peg$currPos * 30 + 6,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 33) {
	        s1 = peg$c21;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c22); }
	      }
	      if (s1 === peg$FAILED) {
	        s1 = null;
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        s3 = peg$parseatom();
	        if (s3 !== peg$FAILED) {
	          while (s3 !== peg$FAILED) {
	            s2.push(s3);
	            s3 = peg$parseatom();
	          }
	        } else {
	          s2 = peg$FAILED;
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c23(s1, s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseatom() {
	      var s0;

	      var key    = peg$currPos * 30 + 7,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$parsewildcard();
	      if (s0 === peg$FAILED) {
	        s0 = peg$parseidentifier();
	        if (s0 === peg$FAILED) {
	          s0 = peg$parseattr();
	          if (s0 === peg$FAILED) {
	            s0 = peg$parsefield();
	            if (s0 === peg$FAILED) {
	              s0 = peg$parsenegation();
	              if (s0 === peg$FAILED) {
	                s0 = peg$parsematches();
	                if (s0 === peg$FAILED) {
	                  s0 = peg$parsehas();
	                  if (s0 === peg$FAILED) {
	                    s0 = peg$parsefirstChild();
	                    if (s0 === peg$FAILED) {
	                      s0 = peg$parselastChild();
	                      if (s0 === peg$FAILED) {
	                        s0 = peg$parsenthChild();
	                        if (s0 === peg$FAILED) {
	                          s0 = peg$parsenthLastChild();
	                          if (s0 === peg$FAILED) {
	                            s0 = peg$parseclass();
	                          }
	                        }
	                      }
	                    }
	                  }
	                }
	              }
	            }
	          }
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsewildcard() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 8,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 42) {
	        s1 = peg$c24;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c25); }
	      }
	      if (s1 !== peg$FAILED) {
	        s1 = peg$c26(s1);
	      }
	      s0 = s1;

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseidentifier() {
	      var s0, s1, s2;

	      var key    = peg$currPos * 30 + 9,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 35) {
	        s1 = peg$c27;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c28); }
	      }
	      if (s1 === peg$FAILED) {
	        s1 = null;
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parseidentifierName();
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c29(s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseattr() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 10,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 91) {
	        s1 = peg$c30;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c31); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parseattrValue();
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 93) {
	                s5 = peg$c32;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c33); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c34(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseattrOps() {
	      var s0, s1, s2;

	      var key    = peg$currPos * 30 + 11,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (peg$c35.test(input.charAt(peg$currPos))) {
	        s1 = input.charAt(peg$currPos);
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c36); }
	      }
	      if (s1 === peg$FAILED) {
	        s1 = null;
	      }
	      if (s1 !== peg$FAILED) {
	        if (input.charCodeAt(peg$currPos) === 61) {
	          s2 = peg$c37;
	          peg$currPos++;
	        } else {
	          s2 = peg$FAILED;
	          { peg$fail(peg$c38); }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c39(s1);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }
	      if (s0 === peg$FAILED) {
	        if (peg$c40.test(input.charAt(peg$currPos))) {
	          s0 = input.charAt(peg$currPos);
	          peg$currPos++;
	        } else {
	          s0 = peg$FAILED;
	          { peg$fail(peg$c41); }
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseattrEqOps() {
	      var s0, s1, s2;

	      var key    = peg$currPos * 30 + 12,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 33) {
	        s1 = peg$c21;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c22); }
	      }
	      if (s1 === peg$FAILED) {
	        s1 = null;
	      }
	      if (s1 !== peg$FAILED) {
	        if (input.charCodeAt(peg$currPos) === 61) {
	          s2 = peg$c37;
	          peg$currPos++;
	        } else {
	          s2 = peg$FAILED;
	          { peg$fail(peg$c38); }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c39(s1);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseattrName() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 13,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parseidentifierName();
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        s3 = peg$currPos;
	        if (input.charCodeAt(peg$currPos) === 46) {
	          s4 = peg$c42;
	          peg$currPos++;
	        } else {
	          s4 = peg$FAILED;
	          { peg$fail(peg$c43); }
	        }
	        if (s4 !== peg$FAILED) {
	          s5 = peg$parseidentifierName();
	          if (s5 !== peg$FAILED) {
	            s4 = [s4, s5];
	            s3 = s4;
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s3;
	          s3 = peg$FAILED;
	        }
	        while (s3 !== peg$FAILED) {
	          s2.push(s3);
	          s3 = peg$currPos;
	          if (input.charCodeAt(peg$currPos) === 46) {
	            s4 = peg$c42;
	            peg$currPos++;
	          } else {
	            s4 = peg$FAILED;
	            { peg$fail(peg$c43); }
	          }
	          if (s4 !== peg$FAILED) {
	            s5 = peg$parseidentifierName();
	            if (s5 !== peg$FAILED) {
	              s4 = [s4, s5];
	              s3 = s4;
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c44(s1, s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseattrValue() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 14,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parseattrName();
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parseattrEqOps();
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              s5 = peg$parsetype();
	              if (s5 === peg$FAILED) {
	                s5 = peg$parseregex();
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c45(s1, s3, s5);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }
	      if (s0 === peg$FAILED) {
	        s0 = peg$currPos;
	        s1 = peg$parseattrName();
	        if (s1 !== peg$FAILED) {
	          s2 = peg$parse_();
	          if (s2 !== peg$FAILED) {
	            s3 = peg$parseattrOps();
	            if (s3 !== peg$FAILED) {
	              s4 = peg$parse_();
	              if (s4 !== peg$FAILED) {
	                s5 = peg$parsestring();
	                if (s5 === peg$FAILED) {
	                  s5 = peg$parsenumber();
	                  if (s5 === peg$FAILED) {
	                    s5 = peg$parsepath();
	                  }
	                }
	                if (s5 !== peg$FAILED) {
	                  s1 = peg$c45(s1, s3, s5);
	                  s0 = s1;
	                } else {
	                  peg$currPos = s0;
	                  s0 = peg$FAILED;
	                }
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	        if (s0 === peg$FAILED) {
	          s0 = peg$currPos;
	          s1 = peg$parseattrName();
	          if (s1 !== peg$FAILED) {
	            s1 = peg$c46(s1);
	          }
	          s0 = s1;
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsestring() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 15,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 34) {
	        s1 = peg$c47;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c48); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        if (peg$c49.test(input.charAt(peg$currPos))) {
	          s3 = input.charAt(peg$currPos);
	          peg$currPos++;
	        } else {
	          s3 = peg$FAILED;
	          { peg$fail(peg$c50); }
	        }
	        if (s3 === peg$FAILED) {
	          s3 = peg$currPos;
	          if (input.charCodeAt(peg$currPos) === 92) {
	            s4 = peg$c51;
	            peg$currPos++;
	          } else {
	            s4 = peg$FAILED;
	            { peg$fail(peg$c52); }
	          }
	          if (s4 !== peg$FAILED) {
	            if (input.length > peg$currPos) {
	              s5 = input.charAt(peg$currPos);
	              peg$currPos++;
	            } else {
	              s5 = peg$FAILED;
	              { peg$fail(peg$c53); }
	            }
	            if (s5 !== peg$FAILED) {
	              s4 = peg$c54(s4, s5);
	              s3 = s4;
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s3;
	            s3 = peg$FAILED;
	          }
	        }
	        while (s3 !== peg$FAILED) {
	          s2.push(s3);
	          if (peg$c49.test(input.charAt(peg$currPos))) {
	            s3 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s3 = peg$FAILED;
	            { peg$fail(peg$c50); }
	          }
	          if (s3 === peg$FAILED) {
	            s3 = peg$currPos;
	            if (input.charCodeAt(peg$currPos) === 92) {
	              s4 = peg$c51;
	              peg$currPos++;
	            } else {
	              s4 = peg$FAILED;
	              { peg$fail(peg$c52); }
	            }
	            if (s4 !== peg$FAILED) {
	              if (input.length > peg$currPos) {
	                s5 = input.charAt(peg$currPos);
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c53); }
	              }
	              if (s5 !== peg$FAILED) {
	                s4 = peg$c54(s4, s5);
	                s3 = s4;
	              } else {
	                peg$currPos = s3;
	                s3 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          }
	        }
	        if (s2 !== peg$FAILED) {
	          if (input.charCodeAt(peg$currPos) === 34) {
	            s3 = peg$c47;
	            peg$currPos++;
	          } else {
	            s3 = peg$FAILED;
	            { peg$fail(peg$c48); }
	          }
	          if (s3 !== peg$FAILED) {
	            s1 = peg$c55(s2);
	            s0 = s1;
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }
	      if (s0 === peg$FAILED) {
	        s0 = peg$currPos;
	        if (input.charCodeAt(peg$currPos) === 39) {
	          s1 = peg$c56;
	          peg$currPos++;
	        } else {
	          s1 = peg$FAILED;
	          { peg$fail(peg$c57); }
	        }
	        if (s1 !== peg$FAILED) {
	          s2 = [];
	          if (peg$c58.test(input.charAt(peg$currPos))) {
	            s3 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s3 = peg$FAILED;
	            { peg$fail(peg$c59); }
	          }
	          if (s3 === peg$FAILED) {
	            s3 = peg$currPos;
	            if (input.charCodeAt(peg$currPos) === 92) {
	              s4 = peg$c51;
	              peg$currPos++;
	            } else {
	              s4 = peg$FAILED;
	              { peg$fail(peg$c52); }
	            }
	            if (s4 !== peg$FAILED) {
	              if (input.length > peg$currPos) {
	                s5 = input.charAt(peg$currPos);
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c53); }
	              }
	              if (s5 !== peg$FAILED) {
	                s4 = peg$c54(s4, s5);
	                s3 = s4;
	              } else {
	                peg$currPos = s3;
	                s3 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s3;
	              s3 = peg$FAILED;
	            }
	          }
	          while (s3 !== peg$FAILED) {
	            s2.push(s3);
	            if (peg$c58.test(input.charAt(peg$currPos))) {
	              s3 = input.charAt(peg$currPos);
	              peg$currPos++;
	            } else {
	              s3 = peg$FAILED;
	              { peg$fail(peg$c59); }
	            }
	            if (s3 === peg$FAILED) {
	              s3 = peg$currPos;
	              if (input.charCodeAt(peg$currPos) === 92) {
	                s4 = peg$c51;
	                peg$currPos++;
	              } else {
	                s4 = peg$FAILED;
	                { peg$fail(peg$c52); }
	              }
	              if (s4 !== peg$FAILED) {
	                if (input.length > peg$currPos) {
	                  s5 = input.charAt(peg$currPos);
	                  peg$currPos++;
	                } else {
	                  s5 = peg$FAILED;
	                  { peg$fail(peg$c53); }
	                }
	                if (s5 !== peg$FAILED) {
	                  s4 = peg$c54(s4, s5);
	                  s3 = s4;
	                } else {
	                  peg$currPos = s3;
	                  s3 = peg$FAILED;
	                }
	              } else {
	                peg$currPos = s3;
	                s3 = peg$FAILED;
	              }
	            }
	          }
	          if (s2 !== peg$FAILED) {
	            if (input.charCodeAt(peg$currPos) === 39) {
	              s3 = peg$c56;
	              peg$currPos++;
	            } else {
	              s3 = peg$FAILED;
	              { peg$fail(peg$c57); }
	            }
	            if (s3 !== peg$FAILED) {
	              s1 = peg$c55(s2);
	              s0 = s1;
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsenumber() {
	      var s0, s1, s2, s3;

	      var key    = peg$currPos * 30 + 16,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$currPos;
	      s2 = [];
	      if (peg$c60.test(input.charAt(peg$currPos))) {
	        s3 = input.charAt(peg$currPos);
	        peg$currPos++;
	      } else {
	        s3 = peg$FAILED;
	        { peg$fail(peg$c61); }
	      }
	      while (s3 !== peg$FAILED) {
	        s2.push(s3);
	        if (peg$c60.test(input.charAt(peg$currPos))) {
	          s3 = input.charAt(peg$currPos);
	          peg$currPos++;
	        } else {
	          s3 = peg$FAILED;
	          { peg$fail(peg$c61); }
	        }
	      }
	      if (s2 !== peg$FAILED) {
	        if (input.charCodeAt(peg$currPos) === 46) {
	          s3 = peg$c42;
	          peg$currPos++;
	        } else {
	          s3 = peg$FAILED;
	          { peg$fail(peg$c43); }
	        }
	        if (s3 !== peg$FAILED) {
	          s2 = [s2, s3];
	          s1 = s2;
	        } else {
	          peg$currPos = s1;
	          s1 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s1;
	        s1 = peg$FAILED;
	      }
	      if (s1 === peg$FAILED) {
	        s1 = null;
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        if (peg$c60.test(input.charAt(peg$currPos))) {
	          s3 = input.charAt(peg$currPos);
	          peg$currPos++;
	        } else {
	          s3 = peg$FAILED;
	          { peg$fail(peg$c61); }
	        }
	        if (s3 !== peg$FAILED) {
	          while (s3 !== peg$FAILED) {
	            s2.push(s3);
	            if (peg$c60.test(input.charAt(peg$currPos))) {
	              s3 = input.charAt(peg$currPos);
	              peg$currPos++;
	            } else {
	              s3 = peg$FAILED;
	              { peg$fail(peg$c61); }
	            }
	          }
	        } else {
	          s2 = peg$FAILED;
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c62(s1, s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsepath() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 17,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      s1 = peg$parseidentifierName();
	      if (s1 !== peg$FAILED) {
	        s1 = peg$c63(s1);
	      }
	      s0 = s1;

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsetype() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 18,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 5) === peg$c64) {
	        s1 = peg$c64;
	        peg$currPos += 5;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c65); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = [];
	          if (peg$c66.test(input.charAt(peg$currPos))) {
	            s4 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s4 = peg$FAILED;
	            { peg$fail(peg$c67); }
	          }
	          if (s4 !== peg$FAILED) {
	            while (s4 !== peg$FAILED) {
	              s3.push(s4);
	              if (peg$c66.test(input.charAt(peg$currPos))) {
	                s4 = input.charAt(peg$currPos);
	                peg$currPos++;
	              } else {
	                s4 = peg$FAILED;
	                { peg$fail(peg$c67); }
	              }
	            }
	          } else {
	            s3 = peg$FAILED;
	          }
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c70(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseflags() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 19,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = [];
	      if (peg$c71.test(input.charAt(peg$currPos))) {
	        s1 = input.charAt(peg$currPos);
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c72); }
	      }
	      if (s1 !== peg$FAILED) {
	        while (s1 !== peg$FAILED) {
	          s0.push(s1);
	          if (peg$c71.test(input.charAt(peg$currPos))) {
	            s1 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s1 = peg$FAILED;
	            { peg$fail(peg$c72); }
	          }
	        }
	      } else {
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseregex() {
	      var s0, s1, s2, s3, s4;

	      var key    = peg$currPos * 30 + 20,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 47) {
	        s1 = peg$c73;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c74); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = [];
	        if (peg$c75.test(input.charAt(peg$currPos))) {
	          s3 = input.charAt(peg$currPos);
	          peg$currPos++;
	        } else {
	          s3 = peg$FAILED;
	          { peg$fail(peg$c76); }
	        }
	        if (s3 !== peg$FAILED) {
	          while (s3 !== peg$FAILED) {
	            s2.push(s3);
	            if (peg$c75.test(input.charAt(peg$currPos))) {
	              s3 = input.charAt(peg$currPos);
	              peg$currPos++;
	            } else {
	              s3 = peg$FAILED;
	              { peg$fail(peg$c76); }
	            }
	          }
	        } else {
	          s2 = peg$FAILED;
	        }
	        if (s2 !== peg$FAILED) {
	          if (input.charCodeAt(peg$currPos) === 47) {
	            s3 = peg$c73;
	            peg$currPos++;
	          } else {
	            s3 = peg$FAILED;
	            { peg$fail(peg$c74); }
	          }
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parseflags();
	            if (s4 === peg$FAILED) {
	              s4 = null;
	            }
	            if (s4 !== peg$FAILED) {
	              s1 = peg$c77(s2, s4);
	              s0 = s1;
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsefield() {
	      var s0, s1, s2, s3, s4, s5, s6;

	      var key    = peg$currPos * 30 + 21,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 46) {
	        s1 = peg$c42;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c43); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parseidentifierName();
	        if (s2 !== peg$FAILED) {
	          s3 = [];
	          s4 = peg$currPos;
	          if (input.charCodeAt(peg$currPos) === 46) {
	            s5 = peg$c42;
	            peg$currPos++;
	          } else {
	            s5 = peg$FAILED;
	            { peg$fail(peg$c43); }
	          }
	          if (s5 !== peg$FAILED) {
	            s6 = peg$parseidentifierName();
	            if (s6 !== peg$FAILED) {
	              s5 = [s5, s6];
	              s4 = s5;
	            } else {
	              peg$currPos = s4;
	              s4 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s4;
	            s4 = peg$FAILED;
	          }
	          while (s4 !== peg$FAILED) {
	            s3.push(s4);
	            s4 = peg$currPos;
	            if (input.charCodeAt(peg$currPos) === 46) {
	              s5 = peg$c42;
	              peg$currPos++;
	            } else {
	              s5 = peg$FAILED;
	              { peg$fail(peg$c43); }
	            }
	            if (s5 !== peg$FAILED) {
	              s6 = peg$parseidentifierName();
	              if (s6 !== peg$FAILED) {
	                s5 = [s5, s6];
	                s4 = s5;
	              } else {
	                peg$currPos = s4;
	                s4 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s4;
	              s4 = peg$FAILED;
	            }
	          }
	          if (s3 !== peg$FAILED) {
	            s1 = peg$c78(s2, s3);
	            s0 = s1;
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsenegation() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 22,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 5) === peg$c79) {
	        s1 = peg$c79;
	        peg$currPos += 5;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c80); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parseselectors();
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c81(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsematches() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 23,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 9) === peg$c82) {
	        s1 = peg$c82;
	        peg$currPos += 9;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c83); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parseselectors();
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c84(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsehas() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 24,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 5) === peg$c85) {
	        s1 = peg$c85;
	        peg$currPos += 5;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c86); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = peg$parseselectors();
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c87(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsefirstChild() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 25,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 12) === peg$c88) {
	        s1 = peg$c88;
	        peg$currPos += 12;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c89); }
	      }
	      if (s1 !== peg$FAILED) {
	        s1 = peg$c90();
	      }
	      s0 = s1;

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parselastChild() {
	      var s0, s1;

	      var key    = peg$currPos * 30 + 26,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 11) === peg$c91) {
	        s1 = peg$c91;
	        peg$currPos += 11;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c92); }
	      }
	      if (s1 !== peg$FAILED) {
	        s1 = peg$c93();
	      }
	      s0 = s1;

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsenthChild() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 27,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 11) === peg$c94) {
	        s1 = peg$c94;
	        peg$currPos += 11;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c95); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = [];
	          if (peg$c60.test(input.charAt(peg$currPos))) {
	            s4 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s4 = peg$FAILED;
	            { peg$fail(peg$c61); }
	          }
	          if (s4 !== peg$FAILED) {
	            while (s4 !== peg$FAILED) {
	              s3.push(s4);
	              if (peg$c60.test(input.charAt(peg$currPos))) {
	                s4 = input.charAt(peg$currPos);
	                peg$currPos++;
	              } else {
	                s4 = peg$FAILED;
	                { peg$fail(peg$c61); }
	              }
	            }
	          } else {
	            s3 = peg$FAILED;
	          }
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c96(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parsenthLastChild() {
	      var s0, s1, s2, s3, s4, s5;

	      var key    = peg$currPos * 30 + 28,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.substr(peg$currPos, 16) === peg$c97) {
	        s1 = peg$c97;
	        peg$currPos += 16;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c98); }
	      }
	      if (s1 !== peg$FAILED) {
	        s2 = peg$parse_();
	        if (s2 !== peg$FAILED) {
	          s3 = [];
	          if (peg$c60.test(input.charAt(peg$currPos))) {
	            s4 = input.charAt(peg$currPos);
	            peg$currPos++;
	          } else {
	            s4 = peg$FAILED;
	            { peg$fail(peg$c61); }
	          }
	          if (s4 !== peg$FAILED) {
	            while (s4 !== peg$FAILED) {
	              s3.push(s4);
	              if (peg$c60.test(input.charAt(peg$currPos))) {
	                s4 = input.charAt(peg$currPos);
	                peg$currPos++;
	              } else {
	                s4 = peg$FAILED;
	                { peg$fail(peg$c61); }
	              }
	            }
	          } else {
	            s3 = peg$FAILED;
	          }
	          if (s3 !== peg$FAILED) {
	            s4 = peg$parse_();
	            if (s4 !== peg$FAILED) {
	              if (input.charCodeAt(peg$currPos) === 41) {
	                s5 = peg$c68;
	                peg$currPos++;
	              } else {
	                s5 = peg$FAILED;
	                { peg$fail(peg$c69); }
	              }
	              if (s5 !== peg$FAILED) {
	                s1 = peg$c99(s3);
	                s0 = s1;
	              } else {
	                peg$currPos = s0;
	                s0 = peg$FAILED;
	              }
	            } else {
	              peg$currPos = s0;
	              s0 = peg$FAILED;
	            }
	          } else {
	            peg$currPos = s0;
	            s0 = peg$FAILED;
	          }
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }

	    function peg$parseclass() {
	      var s0, s1, s2;

	      var key    = peg$currPos * 30 + 29,
	          cached = peg$resultsCache[key];

	      if (cached) {
	        peg$currPos = cached.nextPos;

	        return cached.result;
	      }

	      s0 = peg$currPos;
	      if (input.charCodeAt(peg$currPos) === 58) {
	        s1 = peg$c100;
	        peg$currPos++;
	      } else {
	        s1 = peg$FAILED;
	        { peg$fail(peg$c101); }
	      }
	      if (s1 !== peg$FAILED) {
	        if (input.substr(peg$currPos, 9).toLowerCase() === peg$c102) {
	          s2 = input.substr(peg$currPos, 9);
	          peg$currPos += 9;
	        } else {
	          s2 = peg$FAILED;
	          { peg$fail(peg$c103); }
	        }
	        if (s2 === peg$FAILED) {
	          if (input.substr(peg$currPos, 10).toLowerCase() === peg$c104) {
	            s2 = input.substr(peg$currPos, 10);
	            peg$currPos += 10;
	          } else {
	            s2 = peg$FAILED;
	            { peg$fail(peg$c105); }
	          }
	          if (s2 === peg$FAILED) {
	            if (input.substr(peg$currPos, 11).toLowerCase() === peg$c106) {
	              s2 = input.substr(peg$currPos, 11);
	              peg$currPos += 11;
	            } else {
	              s2 = peg$FAILED;
	              { peg$fail(peg$c107); }
	            }
	            if (s2 === peg$FAILED) {
	              if (input.substr(peg$currPos, 8).toLowerCase() === peg$c108) {
	                s2 = input.substr(peg$currPos, 8);
	                peg$currPos += 8;
	              } else {
	                s2 = peg$FAILED;
	                { peg$fail(peg$c109); }
	              }
	              if (s2 === peg$FAILED) {
	                if (input.substr(peg$currPos, 7).toLowerCase() === peg$c110) {
	                  s2 = input.substr(peg$currPos, 7);
	                  peg$currPos += 7;
	                } else {
	                  s2 = peg$FAILED;
	                  { peg$fail(peg$c111); }
	                }
	              }
	            }
	          }
	        }
	        if (s2 !== peg$FAILED) {
	          s1 = peg$c112(s2);
	          s0 = s1;
	        } else {
	          peg$currPos = s0;
	          s0 = peg$FAILED;
	        }
	      } else {
	        peg$currPos = s0;
	        s0 = peg$FAILED;
	      }

	      peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };

	      return s0;
	    }


	      function nth(n) { return { type: 'nth-child', index: { type: 'literal', value: n } }; }
	      function nthLast(n) { return { type: 'nth-last-child', index: { type: 'literal', value: n } }; }
	      function strUnescape(s) {
	        return s.replace(/\\(.)/g, function(match, ch) {
	          switch(ch) {
	            case 'b': return '\b';
	            case 'f': return '\f';
	            case 'n': return '\n';
	            case 'r': return '\r';
	            case 't': return '\t';
	            case 'v': return '\v';
	            default: return ch;
	          }
	        });
	      }


	    peg$result = peg$startRuleFunction();

	    if (peg$result !== peg$FAILED && peg$currPos === input.length) {
	      return peg$result;
	    } else {
	      if (peg$result !== peg$FAILED && peg$currPos < input.length) {
	        peg$fail(peg$endExpectation());
	      }

	      throw peg$buildStructuredError(
	        peg$maxFailExpected,
	        peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
	        peg$maxFailPos < input.length
	          ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
	          : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
	      );
	    }
	  }

	  return {
	    SyntaxError: peg$SyntaxError,
	    parse:       peg$parse
	  };
	});
} (parser$1));

var parser = parser$1.exports;

/* vim: set sw=4 sts=4 : */

/**
* @typedef {"LEFT_SIDE"|"RIGHT_SIDE"} Side
*/

const LEFT_SIDE = 'LEFT_SIDE';
const RIGHT_SIDE = 'RIGHT_SIDE';

/**
 * @external AST
 * @see https://esprima.readthedocs.io/en/latest/syntax-tree-format.html
 */

/**
 * One of the rules of `grammar.pegjs`
 * @typedef {PlainObject} SelectorAST
 * @see grammar.pegjs
*/

/**
 * The `sequence` production of `grammar.pegjs`
 * @typedef {PlainObject} SelectorSequenceAST
*/

/**
 * Get the value of a property which may be multiple levels down
 * in the object.
 * @param {?PlainObject} obj
 * @param {string[]} keys
 * @returns {undefined|boolean|string|number|external:AST}
 */
function getPath(obj, keys) {
    for (let i = 0; i < keys.length; ++i) {
        if (obj == null) { return obj; }
        obj = obj[keys[i]];
    }
    return obj;
}

/**
 * Determine whether `node` can be reached by following `path`,
 * starting at `ancestor`.
 * @param {?external:AST} node
 * @param {?external:AST} ancestor
 * @param {string[]} path
 * @param {Integer} fromPathIndex
 * @returns {boolean}
 */
function inPath(node, ancestor, path, fromPathIndex) {
    let current = ancestor;
    for (let i = fromPathIndex; i < path.length; ++i) {
        if (current == null) {
            return false;
        }
        const field = current[path[i]];
        if (Array.isArray(field)) {
            for (let k = 0; k < field.length; ++k) {
                if (inPath(node, field[k], path, i + 1)) {
                    return true;
                }
            }
            return false;
        }
        current = field;
    }
    return node === current;
}

/**
 * A generated matcher function for a selector.
 * @typedef {function} SelectorMatcher
*/

/**
 * A WeakMap for holding cached matcher functions for selectors.
 * @type {WeakMap<SelectorAST, SelectorMatcher>}
*/
const MATCHER_CACHE = typeof WeakMap === 'function' ? new WeakMap : null;

/**
 * Look up a matcher function for `selector` in the cache.
 * If it does not exist, generate it with `generateMatcher` and add it to the cache.
 * In engines without WeakMap, the caching is skipped and matchers are generated with every call.
 * @param {?SelectorAST} selector
 * @returns {SelectorMatcher}
 */
function getMatcher(selector) {
    if (selector == null) {
        return () => true;
    }

    if (MATCHER_CACHE != null) {
        let matcher = MATCHER_CACHE.get(selector);
        if (matcher != null) {
            return matcher;
        }
        matcher = generateMatcher(selector);
        MATCHER_CACHE.set(selector, matcher);
        return matcher;
    }

    return generateMatcher(selector);
}

/**
 * Create a matcher function for `selector`,
 * @param {?SelectorAST} selector
 * @returns {SelectorMatcher}
 */
function generateMatcher(selector) {
    switch(selector.type) {
        case 'wildcard':
            return () => true;

        case 'identifier': {
            const value = selector.value.toLowerCase();
            return (node) => value === node.type.toLowerCase();
        }

        case 'field': {
            const path = selector.name.split('.');
            return (node, ancestry) => {
                const ancestor = ancestry[path.length - 1];
                return inPath(node, ancestor, path, 0);
            };
        }

        case 'matches': {
            const matchers = selector.selectors.map(getMatcher);
            return (node, ancestry, options) => {
                for (let i = 0; i < matchers.length; ++i) {
                    if (matchers[i](node, ancestry, options)) { return true; }
                }
                return false;
            };
        }

        case 'compound': {
            const matchers = selector.selectors.map(getMatcher);
            return (node, ancestry, options) => {
                for (let i = 0; i < matchers.length; ++i) {
                    if (!matchers[i](node, ancestry, options)) { return false; }
                }
                return true;
            };
        }

        case 'not': {
            const matchers = selector.selectors.map(getMatcher);
            return (node, ancestry, options) => {
                for (let i = 0; i < matchers.length; ++i) {
                    if (matchers[i](node, ancestry, options)) { return false; }
                }
                return true;
            };
        }

        case 'has': {
            const matchers = selector.selectors.map(getMatcher);
            return (node, ancestry, options) => {
                let result = false;

                const a = [];
                estraverse.traverse(node, {
                    enter (node, parent) {
                        if (parent != null) { a.unshift(parent); }

                        for (let i = 0; i < matchers.length; ++i) {
                            if (matchers[i](node, a, options)) {
                                result = true;
                                this.break();
                                return;
                            }
                        }
                    },
                    leave () { a.shift(); },
                    keys: options && options.visitorKeys,
                    fallback: options && options.fallback || 'iteration'
                });

                return result;
            };
        }

        case 'child': {
            const left = getMatcher(selector.left);
            const right = getMatcher(selector.right);
            return (node, ancestry, options) => {
                if (ancestry.length > 0 && right(node, ancestry, options)) {
                    return left(ancestry[0], ancestry.slice(1), options);
                }
                return false;
            };
        }

        case 'descendant': {
            const left = getMatcher(selector.left);
            const right = getMatcher(selector.right);
            return (node, ancestry, options) => {
                if (right(node, ancestry, options)) {
                    for (let i = 0, l = ancestry.length; i < l; ++i) {
                        if (left(ancestry[i], ancestry.slice(i + 1), options)) {
                            return true;
                        }
                    }
                }
                return false;
            };
        }

        case 'attribute': {
            const path = selector.name.split('.');
            switch (selector.operator) {
                case void 0:
                    return (node) => getPath(node, path) != null;
                case '=':
                    switch (selector.value.type) {
                        case 'regexp':
                            return (node) => {
                                const p = getPath(node, path);
                                return typeof p === 'string' && selector.value.value.test(p);
                            };
                        case 'literal': {
                            const literal = `${selector.value.value}`;
                            return (node) => literal === `${getPath(node, path)}`;
                        }
                        case 'type':
                            return (node) => selector.value.value === typeof getPath(node, path);
                    }
                    throw new Error(`Unknown selector value type: ${selector.value.type}`);
                case '!=':
                    switch (selector.value.type) {
                        case 'regexp':
                            return (node) => !selector.value.value.test(getPath(node, path));
                        case 'literal': {
                            const literal = `${selector.value.value}`;
                            return (node) => literal !== `${getPath(node, path)}`;
                        }
                        case 'type':
                            return (node) => selector.value.value !== typeof getPath(node, path);
                    }
                    throw new Error(`Unknown selector value type: ${selector.value.type}`);
                case '<=':
                    return (node) => getPath(node, path) <= selector.value.value;
                case '<':
                    return (node) => getPath(node, path) < selector.value.value;
                case '>':
                    return (node) => getPath(node, path) > selector.value.value;
                case '>=':
                    return (node) => getPath(node, path) >= selector.value.value;
            }
            throw new Error(`Unknown operator: ${selector.operator}`);
        }

        case 'sibling': {
            const left = getMatcher(selector.left);
            const right = getMatcher(selector.right);
            return (node, ancestry, options) =>
                right(node, ancestry, options) &&
                    sibling(node, left, ancestry, LEFT_SIDE, options) ||
                    selector.left.subject &&
                    left(node, ancestry, options) &&
                    sibling(node, right, ancestry, RIGHT_SIDE, options);
        }

        case 'adjacent': {
            const left = getMatcher(selector.left);
            const right = getMatcher(selector.right);
            return (node, ancestry, options) =>
                right(node, ancestry, options) &&
                    adjacent(node, left, ancestry, LEFT_SIDE, options) ||
                    selector.right.subject &&
                    left(node, ancestry, options) &&
                    adjacent(node, right, ancestry, RIGHT_SIDE, options);
        }

        case 'nth-child': {
            const nth = selector.index.value;
            const right = getMatcher(selector.right);
            return (node, ancestry, options) =>
                right(node, ancestry, options) &&
                    nthChild(node, ancestry, nth, options);
        }

        case 'nth-last-child': {
            const nth = -selector.index.value;
            const right = getMatcher(selector.right);
            return (node, ancestry, options) =>
                right(node, ancestry, options) &&
                    nthChild(node, ancestry, nth, options);
        }

        case 'class': {
            const name = selector.name.toLowerCase();
            return (node, ancestry) => {
                switch(name){
                    case 'statement':
                        if(node.type.slice(-9) === 'Statement') return true;
                        // fallthrough: interface Declaration <: Statement { }
                    case 'declaration':
                        return node.type.slice(-11) === 'Declaration';
                    case 'pattern':
                        if(node.type.slice(-7) === 'Pattern') return true;
                        // fallthrough: interface Expression <: Node, Pattern { }
                    case 'expression':
                        return node.type.slice(-10) === 'Expression' ||
                            node.type.slice(-7) === 'Literal' ||
                            (
                                node.type === 'Identifier' &&
                                (ancestry.length === 0 || ancestry[0].type !== 'MetaProperty')
                            ) ||
                            node.type === 'MetaProperty';
                    case 'function':
                        return node.type === 'FunctionDeclaration' ||
                            node.type === 'FunctionExpression' ||
                            node.type === 'ArrowFunctionExpression';
                }
                throw new Error(`Unknown class name: ${selector.name}`);
            };
        }
    }

    throw new Error(`Unknown selector type: ${selector.type}`);
}

/**
 * @callback TraverseOptionFallback
 * @param {external:AST} node The given node.
 * @returns {string[]} An array of visitor keys for the given node.
 */
/**
 * @typedef {object} ESQueryOptions
 * @property { { [nodeType: string]: string[] } } [visitorKeys] By passing `visitorKeys` mapping, we can extend the properties of the nodes that traverse the node.
 * @property {TraverseOptionFallback} [fallback] By passing `fallback` option, we can control the properties of traversing nodes when encountering unknown nodes.
 */

/**
 * Given a `node` and its ancestors, determine if `node` is matched
 * by `selector`.
 * @param {?external:AST} node
 * @param {?SelectorAST} selector
 * @param {external:AST[]} [ancestry=[]]
 * @param {ESQueryOptions} [options]
 * @throws {Error} Unknowns (operator, class name, selector type, or
 * selector value type)
 * @returns {boolean}
 */
function matches(node, selector, ancestry, options) {
    if (!selector) { return true; }
    if (!node) { return false; }
    if (!ancestry) { ancestry = []; }

    return getMatcher(selector)(node, ancestry, options);
}

/**
 * Get visitor keys of a given node.
 * @param {external:AST} node The AST node to get keys.
 * @param {ESQueryOptions|undefined} options
 * @returns {string[]} Visitor keys of the node.
 */
function getVisitorKeys(node, options) {
    const nodeType = node.type;
    if (options && options.visitorKeys && options.visitorKeys[nodeType]) {
        return options.visitorKeys[nodeType];
    }
    if (estraverse.VisitorKeys[nodeType]) {
        return estraverse.VisitorKeys[nodeType];
    }
    if (options && typeof options.fallback === 'function') {
        return options.fallback(node);
    }
    // 'iteration' fallback
    return Object.keys(node).filter(function (key) {
        return key !== 'type';
    });
}


/**
 * Check whether the given value is an ASTNode or not.
 * @param {any} node The value to check.
 * @returns {boolean} `true` if the value is an ASTNode.
 */
function isNode(node) {
    return node !== null && typeof node === 'object' && typeof node.type === 'string';
}

/**
 * Determines if the given node has a sibling that matches the
 * given selector matcher.
 * @param {external:AST} node
 * @param {SelectorMatcher} matcher
 * @param {external:AST[]} ancestry
 * @param {Side} side
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */
function sibling(node, matcher, ancestry, side, options) {
    const [parent] = ancestry;
    if (!parent) { return false; }
    const keys = getVisitorKeys(parent, options);
    for (let i = 0; i < keys.length; ++i) {
        const listProp = parent[keys[i]];
        if (Array.isArray(listProp)) {
            const startIndex = listProp.indexOf(node);
            if (startIndex < 0) { continue; }
            let lowerBound, upperBound;
            if (side === LEFT_SIDE) {
                lowerBound = 0;
                upperBound = startIndex;
            } else {
                lowerBound = startIndex + 1;
                upperBound = listProp.length;
            }
            for (let k = lowerBound; k < upperBound; ++k) {
                if (isNode(listProp[k]) && matcher(listProp[k], ancestry, options)) {
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 * Determines if the given node has an adjacent sibling that matches
 * the given selector matcher.
 * @param {external:AST} node
 * @param {SelectorMatcher} matcher
 * @param {external:AST[]} ancestry
 * @param {Side} side
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */
function adjacent(node, matcher, ancestry, side, options) {
    const [parent] = ancestry;
    if (!parent) { return false; }
    const keys = getVisitorKeys(parent, options);
    for (let i = 0; i < keys.length; ++i) {
        const listProp = parent[keys[i]];
        if (Array.isArray(listProp)) {
            const idx = listProp.indexOf(node);
            if (idx < 0) { continue; }
            if (side === LEFT_SIDE && idx > 0 && isNode(listProp[idx - 1]) && matcher(listProp[idx - 1], ancestry, options)) {
                return true;
            }
            if (side === RIGHT_SIDE && idx < listProp.length - 1 && isNode(listProp[idx + 1]) &&  matcher(listProp[idx + 1], ancestry, options)) {
                return true;
            }
        }
    }
    return false;
}

/**
 * Determines if the given node is the `nth` child.
 * If `nth` is negative then the position is counted
 * from the end of the list of children.
 * @param {external:AST} node
 * @param {external:AST[]} ancestry
 * @param {Integer} nth
 * @param {ESQueryOptions|undefined} options
 * @returns {boolean}
 */
function nthChild(node, ancestry, nth, options) {
    if (nth === 0) { return false; }
    const [parent] = ancestry;
    if (!parent) { return false; }
    const keys = getVisitorKeys(parent, options);
    for (let i = 0; i < keys.length; ++i) {
        const listProp = parent[keys[i]];
        if (Array.isArray(listProp)){
            const idx = nth < 0 ? listProp.length + nth : nth - 1;
            if (idx >= 0 && idx < listProp.length && listProp[idx] === node) {
                return true;
            }
        }
    }
    return false;
}

/**
 * For each selector node marked as a subject, find the portion of the
 * selector that the subject must match.
 * @param {SelectorAST} selector
 * @param {SelectorAST} [ancestor] Defaults to `selector`
 * @returns {SelectorAST[]}
 */
function subjects(selector, ancestor) {
    if (selector == null || typeof selector != 'object') { return []; }
    if (ancestor == null) { ancestor = selector; }
    const results = selector.subject ? [ancestor] : [];
    const keys = Object.keys(selector);
    for (let i = 0; i < keys.length; ++i) {
        const p = keys[i];
        const sel = selector[p];
        results.push(...subjects(sel, p === 'left' ? sel : ancestor));
    }
    return results;
}

/**
* @callback TraverseVisitor
* @param {?external:AST} node
* @param {?external:AST} parent
* @param {external:AST[]} ancestry
*/

/**
 * From a JS AST and a selector AST, collect all JS AST nodes that
 * match the selector.
 * @param {external:AST} ast
 * @param {?SelectorAST} selector
 * @param {TraverseVisitor} visitor
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */
function traverse(ast, selector, visitor, options) {
    if (!selector) { return; }
    const ancestry = [];
    const matcher = getMatcher(selector);
    const altSubjects = subjects(selector).map(getMatcher);
    estraverse.traverse(ast, {
        enter (node, parent) {
            if (parent != null) { ancestry.unshift(parent); }
            if (matcher(node, ancestry, options)) {
                if (altSubjects.length) {
                    for (let i = 0, l = altSubjects.length; i < l; ++i) {
                        if (altSubjects[i](node, ancestry, options)) {
                            visitor(node, parent, ancestry);
                        }
                        for (let k = 0, m = ancestry.length; k < m; ++k) {
                            const succeedingAncestry = ancestry.slice(k + 1);
                            if (altSubjects[i](ancestry[k], succeedingAncestry, options)) {
                                visitor(ancestry[k], parent, succeedingAncestry);
                            }
                        }
                    }
                } else {
                    visitor(node, parent, ancestry);
                }
            }
        },
        leave () { ancestry.shift(); },
        keys: options && options.visitorKeys,
        fallback: options && options.fallback || 'iteration'
    });
}


/**
 * From a JS AST and a selector AST, collect all JS AST nodes that
 * match the selector.
 * @param {external:AST} ast
 * @param {?SelectorAST} selector
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */
function match(ast, selector, options) {
    const results = [];
    traverse(ast, selector, function (node) {
        results.push(node);
    }, options);
    return results;
}

/**
 * Parse a selector string and return its AST.
 * @param {string} selector
 * @returns {SelectorAST}
 */
function parse(selector) {
    return parser.parse(selector);
}

/**
 * Query the code AST using the selector string.
 * @param {external:AST} ast
 * @param {string} selector
 * @param {ESQueryOptions} [options]
 * @returns {external:AST[]}
 */
function query(ast, selector, options) {
    return match(ast, parse(selector), options);
}

query.parse = parse;
query.match = match;
query.traverse = traverse;
query.matches = matches;
query.query = query;

export { query as default };