// THIS FILE WAS AUTO GENERATED
/* eslint-disable */
// @ts-nocheck

// Generated by PEG.js v. 0.10.0 (ts-pegjs plugin v. 0.3.1 )
//
// https://pegjs.org/   https://github.com/metadevpro/ts-pegjs

export interface IFilePosition {
	offset: number;
	line: number;
	column: number;
}

export interface IFileRange {
	start: IFilePosition;
	end: IFilePosition;
}

export interface ILiteralExpectation {
	type: "literal";
	text: string;
	ignoreCase: boolean;
}

export interface IClassParts extends Array<string | IClassParts> {}

export interface IClassExpectation {
	type: "class";
	parts: IClassParts;
	inverted: boolean;
	ignoreCase: boolean;
}

export interface IAnyExpectation {
	type: "any";
}

export interface IEndExpectation {
	type: "end";
}

export interface IOtherExpectation {
	type: "other";
	description: string;
}

export type Expectation =
	| ILiteralExpectation
	| IClassExpectation
	| IAnyExpectation
	| IEndExpectation
	| IOtherExpectation;

export class SyntaxError extends Error {
	public static buildMessage(expected: Expectation[], found: string | null) {
		function hex(ch: string): string {
			return ch.charCodeAt(0).toString(16).toUpperCase();
		}

		function literalEscape(s: string): string {
			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, (ch) => "\\x0" + hex(ch))
				.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch));
		}

		function classEscape(s: string): string {
			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, (ch) => "\\x0" + hex(ch))
				.replace(/[\x10-\x1F\x7F-\x9F]/g, (ch) => "\\x" + hex(ch));
		}

		function describeExpectation(expectation: Expectation) {
			switch (expectation.type) {
				case "literal":
					return '"' + literalEscape(expectation.text) + '"';
				case "class":
					const escapedParts = expectation.parts.map((part) => {
						return Array.isArray(part)
							? classEscape(part[0] as string) +
									"-" +
									classEscape(part[1] as string)
							: classEscape(part);
					});

					return (
						"[" +
						(expectation.inverted ? "^" : "") +
						escapedParts +
						"]"
					);
				case "any":
					return "any character";
				case "end":
					return "end of input";
				case "other":
					return expectation.description;
			}
		}

		function describeExpected(expected1: Expectation[]) {
			const descriptions = expected1.map(describeExpectation);
			let i: number;
			let j: number;

			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(found1: string | null) {
			return found1 ? '"' + literalEscape(found1) + '"' : "end of input";
		}

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

	public message: string;
	public expected: Expectation[];
	public found: string | null;
	public location: IFileRange;
	public name: string;

	constructor(
		message: string,
		expected: Expectation[],
		found: string | null,
		location: IFileRange,
	) {
		super();
		this.message = message;
		this.expected = expected;
		this.found = found;
		this.location = location;
		this.name = "SyntaxError";

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

function peg$parse(input: string, options?: IParseOptions) {
	options = options !== undefined ? options : {};

	const peg$FAILED: Readonly<any> = {};

	const peg$startRuleFunctions: { [id: string]: any } = {
		start: peg$parsestart,
	};
	let peg$startRuleFunction: () => any = peg$parsestart;

	const peg$c0 = peg$otherExpectation("grouped expression");
	const peg$c1 = "(";
	const peg$c2 = peg$literalExpectation("(", false);
	const peg$c3 = ")";
	const peg$c4 = peg$literalExpectation(")", false);
	const peg$c5 = function (group: any): any {
		return group;
	};
	const peg$c6 = peg$otherExpectation("logical OR");
	const peg$c7 = function (head: any, tails: any): any {
		return { or: [head, ...tails] };
	};
	const peg$c8 = "||";
	const peg$c9 = peg$literalExpectation("||", false);
	const peg$c10 = function (tail: any): any {
		return tail;
	};
	const peg$c11 = peg$otherExpectation("logical AND");
	const peg$c12 = function (head: any, tails: any): any {
		return { and: [head, ...tails] };
	};
	const peg$c13 = "&&";
	const peg$c14 = peg$literalExpectation("&&", false);
	const peg$c15 = peg$otherExpectation("numeric comparison");
	const peg$c16 = ">=";
	const peg$c17 = peg$literalExpectation(">=", false);
	const peg$c18 = ">";
	const peg$c19 = peg$literalExpectation(">", false);
	const peg$c20 = "<=";
	const peg$c21 = peg$literalExpectation("<=", false);
	const peg$c22 = "<";
	const peg$c23 = peg$literalExpectation("<", false);
	const peg$c24 = "===";
	const peg$c25 = peg$literalExpectation("===", false);
	const peg$c26 = function (head: any, expr: any, tail: any): any {
		return { [expr]: [head, tail] };
	};
	const peg$c27 = peg$otherExpectation("version comparison");
	const peg$c28 = function (head: any, expr: any, tail: any): any {
		return { ["ver " + expr]: [head, tail] };
	};
	const peg$c29 = peg$otherExpectation("variable");
	const peg$c30 = /^[a-zA-Z]/;
	const peg$c31 = peg$classExpectation(
		[
			["a", "z"],
			["A", "Z"],
		],
		false,
		false,
	);
	const peg$c32 = /^[a-zA-Z0-9]/;
	const peg$c33 = peg$classExpectation(
		[
			["a", "z"],
			["A", "Z"],
			["0", "9"],
		],
		false,
		false,
	);
	const peg$c34 = function (variable: any): any {
		return { var: variable[1].join("") };
	};
	const peg$c35 = peg$otherExpectation("number");
	const peg$c36 = "-";
	const peg$c37 = peg$literalExpectation("-", false);
	const peg$c38 = /^[0-9]/;
	const peg$c39 = peg$classExpectation([["0", "9"]], false, false);
	const peg$c40 = function (): any {
		return parseInt(text(), 10);
	};
	const peg$c41 = peg$otherExpectation("hex number");
	const peg$c42 = "0x";
	const peg$c43 = peg$literalExpectation("0x", false);
	const peg$c44 = /^[0-9a-f]/i;
	const peg$c45 = peg$classExpectation(
		[
			["0", "9"],
			["a", "f"],
		],
		false,
		true,
	);
	const peg$c46 = function (): any {
		return parseInt(text(), 16);
	};
	const peg$c47 = peg$otherExpectation("version string");
	const peg$c48 = ".";
	const peg$c49 = peg$literalExpectation(".", false);
	const peg$c50 = function (version: any): any {
		return text();
	};
	const peg$c51 = peg$otherExpectation("string");
	const peg$c52 = '"';
	const peg$c53 = peg$literalExpectation('"', false);
	const peg$c54 = /^[^"]/;
	const peg$c55 = peg$classExpectation(['"'], true, false);
	const peg$c56 = function (): any {
		return text();
	};
	const peg$c57 = "'";
	const peg$c58 = peg$literalExpectation("'", false);
	const peg$c59 = /^[^']/;
	const peg$c60 = peg$classExpectation(["'"], true, false);
	const peg$c61 = peg$otherExpectation("whitespace");
	const peg$c62 = /^[ \t\n\r]/;
	const peg$c63 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false);

	let peg$currPos = 0;
	let peg$savedPos = 0;
	const peg$posDetailsCache = [{ line: 1, column: 1 }];
	let peg$maxFailPos = 0;
	let peg$maxFailExpected: Expectation[] = [];
	let peg$silentFails = 0;

	let peg$result;

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

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

	function text(): string {
		return input.substring(peg$savedPos, peg$currPos);
	}

	function location(): IFileRange {
		return peg$computeLocation(peg$savedPos, peg$currPos);
	}

	function expected(description: string, location1?: IFileRange) {
		location1 =
			location1 !== undefined
				? location1
				: peg$computeLocation(peg$savedPos, peg$currPos);

		throw peg$buildStructuredError(
			[peg$otherExpectation(description)],
			input.substring(peg$savedPos, peg$currPos),
			location1,
		);
	}

	function error(message: string, location1?: IFileRange) {
		location1 =
			location1 !== undefined
				? location1
				: peg$computeLocation(peg$savedPos, peg$currPos);

		throw peg$buildSimpleError(message, location1);
	}

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

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

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

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

	function peg$otherExpectation(description: string): IOtherExpectation {
		return { type: "other", description: description };
	}

	function peg$computePosDetails(pos: number) {
		let details = peg$posDetailsCache[pos];
		let 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: number, endPos: number): IFileRange {
		const startPosDetails = peg$computePosDetails(startPos);
		const 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(expected1: Expectation) {
		if (peg$currPos < peg$maxFailPos) {
			return;
		}

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

		peg$maxFailExpected.push(expected1);
	}

	function peg$buildSimpleError(message: string, location1: IFileRange) {
		return new SyntaxError(message, [], "", location1);
	}

	function peg$buildStructuredError(
		expected1: Expectation[],
		found: string | null,
		location1: IFileRange,
	) {
		return new SyntaxError(
			SyntaxError.buildMessage(expected1, found),
			expected1,
			found,
			location1,
		);
	}

	function peg$parsestart(): any {
		let s0;

		s0 = peg$parsegroup();
		if (s0 === peg$FAILED) {
			s0 = peg$parseor();
			if (s0 === peg$FAILED) {
				s0 = peg$parseand();
				if (s0 === peg$FAILED) {
					s0 = peg$parsecomparison();
				}
			}
		}

		return s0;
	}

	function peg$parsegroup(): any {
		let s0, s1, s2, s3, s4, s5, s6;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			if (input.charCodeAt(peg$currPos) === 40) {
				s2 = peg$c1;
				peg$currPos++;
			} else {
				s2 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c2);
				}
			}
			if (s2 !== peg$FAILED) {
				s3 = peg$parse_();
				if (s3 !== peg$FAILED) {
					s4 = peg$parseor();
					if (s4 !== peg$FAILED) {
						s5 = peg$parse_();
						if (s5 !== peg$FAILED) {
							if (input.charCodeAt(peg$currPos) === 41) {
								s6 = peg$c3;
								peg$currPos++;
							} else {
								s6 = peg$FAILED;
								if (peg$silentFails === 0) {
									peg$fail(peg$c4);
								}
							}
							if (s6 !== peg$FAILED) {
								peg$savedPos = s0;
								s1 = peg$c5(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;
				}
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c0);
			}
		}

		return s0;
	}

	function peg$parseor(): any {
		let s0, s1, s2, s3, s4;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$parseand();
			if (s2 === peg$FAILED) {
				s2 = peg$parsecomparison();
			}
			if (s2 !== peg$FAILED) {
				s3 = [];
				s4 = peg$parseor_tails();
				if (s4 !== peg$FAILED) {
					while (s4 !== peg$FAILED) {
						s3.push(s4);
						s4 = peg$parseor_tails();
					}
				} else {
					s3 = peg$FAILED;
				}
				if (s3 !== peg$FAILED) {
					peg$savedPos = s0;
					s1 = peg$c7(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$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c6);
			}
		}

		return s0;
	}

	function peg$parseor_tails(): any {
		let s0, s1, s2, s3, s4;

		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			if (input.substr(peg$currPos, 2) === peg$c8) {
				s2 = peg$c8;
				peg$currPos += 2;
			} else {
				s2 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c9);
				}
			}
			if (s2 !== peg$FAILED) {
				s3 = peg$parse_();
				if (s3 !== peg$FAILED) {
					s4 = peg$parseand();
					if (s4 === peg$FAILED) {
						s4 = peg$parsecomparison();
					}
					if (s4 !== peg$FAILED) {
						peg$savedPos = s0;
						s1 = peg$c10(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;
		}

		return s0;
	}

	function peg$parseand(): any {
		let s0, s1, s2, s3, s4;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$parsegroup();
			if (s2 === peg$FAILED) {
				s2 = peg$parsecomparison();
			}
			if (s2 !== peg$FAILED) {
				s3 = [];
				s4 = peg$parseand_tails();
				if (s4 !== peg$FAILED) {
					while (s4 !== peg$FAILED) {
						s3.push(s4);
						s4 = peg$parseand_tails();
					}
				} else {
					s3 = peg$FAILED;
				}
				if (s3 !== peg$FAILED) {
					peg$savedPos = s0;
					s1 = peg$c12(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$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c11);
			}
		}

		return s0;
	}

	function peg$parseand_tails(): any {
		let s0, s1, s2, s3, s4;

		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			if (input.substr(peg$currPos, 2) === peg$c13) {
				s2 = peg$c13;
				peg$currPos += 2;
			} else {
				s2 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c14);
				}
			}
			if (s2 !== peg$FAILED) {
				s3 = peg$parse_();
				if (s3 !== peg$FAILED) {
					s4 = peg$parsegroup();
					if (s4 === peg$FAILED) {
						s4 = peg$parsecomparison();
					}
					if (s4 !== peg$FAILED) {
						peg$savedPos = s0;
						s1 = peg$c10(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;
		}

		return s0;
	}

	function peg$parsecomparison(): any {
		let s0;

		s0 = peg$parsever_comparison();
		if (s0 === peg$FAILED) {
			s0 = peg$parseint_comparison();
		}

		return s0;
	}

	function peg$parseint_comparison(): any {
		let s0, s1, s2, s3, s4, s5, s6, s7;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$parseterm();
			if (s2 !== peg$FAILED) {
				s3 = peg$parse_();
				if (s3 !== peg$FAILED) {
					if (input.substr(peg$currPos, 2) === peg$c16) {
						s4 = peg$c16;
						peg$currPos += 2;
					} else {
						s4 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c17);
						}
					}
					if (s4 === peg$FAILED) {
						if (input.charCodeAt(peg$currPos) === 62) {
							s4 = peg$c18;
							peg$currPos++;
						} else {
							s4 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c19);
							}
						}
						if (s4 === peg$FAILED) {
							if (input.substr(peg$currPos, 2) === peg$c20) {
								s4 = peg$c20;
								peg$currPos += 2;
							} else {
								s4 = peg$FAILED;
								if (peg$silentFails === 0) {
									peg$fail(peg$c21);
								}
							}
							if (s4 === peg$FAILED) {
								if (input.charCodeAt(peg$currPos) === 60) {
									s4 = peg$c22;
									peg$currPos++;
								} else {
									s4 = peg$FAILED;
									if (peg$silentFails === 0) {
										peg$fail(peg$c23);
									}
								}
								if (s4 === peg$FAILED) {
									if (
										input.substr(peg$currPos, 3) === peg$c24
									) {
										s4 = peg$c24;
										peg$currPos += 3;
									} else {
										s4 = peg$FAILED;
										if (peg$silentFails === 0) {
											peg$fail(peg$c25);
										}
									}
								}
							}
						}
					}
					if (s4 !== peg$FAILED) {
						s5 = peg$parse_();
						if (s5 !== peg$FAILED) {
							s6 = peg$parseterm();
							if (s6 !== peg$FAILED) {
								s7 = peg$parse_();
								if (s7 !== peg$FAILED) {
									peg$savedPos = s0;
									s1 = peg$c26(s2, s4, s6);
									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;
				}
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c15);
			}
		}

		return s0;
	}

	function peg$parsever_comparison(): any {
		let s0, s1, s2, s3, s4, s5, s6, s7;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$parseterm();
			if (s2 !== peg$FAILED) {
				s3 = peg$parse_();
				if (s3 !== peg$FAILED) {
					if (input.substr(peg$currPos, 2) === peg$c16) {
						s4 = peg$c16;
						peg$currPos += 2;
					} else {
						s4 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c17);
						}
					}
					if (s4 === peg$FAILED) {
						if (input.charCodeAt(peg$currPos) === 62) {
							s4 = peg$c18;
							peg$currPos++;
						} else {
							s4 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c19);
							}
						}
						if (s4 === peg$FAILED) {
							if (input.substr(peg$currPos, 2) === peg$c20) {
								s4 = peg$c20;
								peg$currPos += 2;
							} else {
								s4 = peg$FAILED;
								if (peg$silentFails === 0) {
									peg$fail(peg$c21);
								}
							}
							if (s4 === peg$FAILED) {
								if (input.charCodeAt(peg$currPos) === 60) {
									s4 = peg$c22;
									peg$currPos++;
								} else {
									s4 = peg$FAILED;
									if (peg$silentFails === 0) {
										peg$fail(peg$c23);
									}
								}
								if (s4 === peg$FAILED) {
									if (
										input.substr(peg$currPos, 3) === peg$c24
									) {
										s4 = peg$c24;
										peg$currPos += 3;
									} else {
										s4 = peg$FAILED;
										if (peg$silentFails === 0) {
											peg$fail(peg$c25);
										}
									}
								}
							}
						}
					}
					if (s4 !== peg$FAILED) {
						s5 = peg$parse_();
						if (s5 !== peg$FAILED) {
							s6 = peg$parseversion();
							if (s6 !== peg$FAILED) {
								s7 = peg$parse_();
								if (s7 !== peg$FAILED) {
									peg$savedPos = s0;
									s1 = peg$c28(s2, s4, s6);
									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;
				}
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c27);
			}
		}

		return s0;
	}

	function peg$parseterm(): any {
		let s0;

		s0 = peg$parseconst();
		if (s0 === peg$FAILED) {
			s0 = peg$parsestring();
			if (s0 === peg$FAILED) {
				s0 = peg$parsehex();
				if (s0 === peg$FAILED) {
					s0 = peg$parseinteger();
				}
			}
		}

		return s0;
	}

	function peg$parseconst(): any {
		let s0, s1, s2, s3, s4, s5;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$currPos;
			s3 = peg$currPos;
			peg$silentFails++;
			if (peg$c30.test(input.charAt(peg$currPos))) {
				s4 = input.charAt(peg$currPos);
				peg$currPos++;
			} else {
				s4 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c31);
				}
			}
			peg$silentFails--;
			if (s4 !== peg$FAILED) {
				peg$currPos = s3;
				s3 = undefined;
			} else {
				s3 = peg$FAILED;
			}
			if (s3 !== peg$FAILED) {
				s4 = [];
				if (peg$c32.test(input.charAt(peg$currPos))) {
					s5 = input.charAt(peg$currPos);
					peg$currPos++;
				} else {
					s5 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c33);
					}
				}
				if (s5 !== peg$FAILED) {
					while (s5 !== peg$FAILED) {
						s4.push(s5);
						if (peg$c32.test(input.charAt(peg$currPos))) {
							s5 = input.charAt(peg$currPos);
							peg$currPos++;
						} else {
							s5 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c33);
							}
						}
					}
				} else {
					s4 = peg$FAILED;
				}
				if (s4 !== peg$FAILED) {
					s3 = [s3, s4];
					s2 = s3;
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
			} else {
				peg$currPos = s2;
				s2 = peg$FAILED;
			}
			if (s2 !== peg$FAILED) {
				peg$savedPos = s0;
				s1 = peg$c34(s2);
				s0 = s1;
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c29);
			}
		}

		return s0;
	}

	function peg$parseinteger(): any {
		let s0, s1, s2, s3, s4, s5;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$currPos;
			if (input.charCodeAt(peg$currPos) === 45) {
				s3 = peg$c36;
				peg$currPos++;
			} else {
				s3 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c37);
				}
			}
			if (s3 === peg$FAILED) {
				s3 = null;
			}
			if (s3 !== peg$FAILED) {
				s4 = [];
				if (peg$c38.test(input.charAt(peg$currPos))) {
					s5 = input.charAt(peg$currPos);
					peg$currPos++;
				} else {
					s5 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c39);
					}
				}
				if (s5 !== peg$FAILED) {
					while (s5 !== peg$FAILED) {
						s4.push(s5);
						if (peg$c38.test(input.charAt(peg$currPos))) {
							s5 = input.charAt(peg$currPos);
							peg$currPos++;
						} else {
							s5 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c39);
							}
						}
					}
				} else {
					s4 = peg$FAILED;
				}
				if (s4 !== peg$FAILED) {
					s3 = [s3, s4];
					s2 = s3;
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
			} else {
				peg$currPos = s2;
				s2 = peg$FAILED;
			}
			if (s2 !== peg$FAILED) {
				peg$savedPos = s0;
				s1 = peg$c40();
				s0 = s1;
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c35);
			}
		}

		return s0;
	}

	function peg$parsehex(): any {
		let s0, s1, s2, s3, s4, s5;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$currPos;
			if (input.substr(peg$currPos, 2) === peg$c42) {
				s3 = peg$c42;
				peg$currPos += 2;
			} else {
				s3 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c43);
				}
			}
			if (s3 !== peg$FAILED) {
				s4 = [];
				if (peg$c44.test(input.charAt(peg$currPos))) {
					s5 = input.charAt(peg$currPos);
					peg$currPos++;
				} else {
					s5 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c45);
					}
				}
				if (s5 !== peg$FAILED) {
					while (s5 !== peg$FAILED) {
						s4.push(s5);
						if (peg$c44.test(input.charAt(peg$currPos))) {
							s5 = input.charAt(peg$currPos);
							peg$currPos++;
						} else {
							s5 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c45);
							}
						}
					}
				} else {
					s4 = peg$FAILED;
				}
				if (s4 !== peg$FAILED) {
					s3 = [s3, s4];
					s2 = s3;
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
			} else {
				peg$currPos = s2;
				s2 = peg$FAILED;
			}
			if (s2 !== peg$FAILED) {
				peg$savedPos = s0;
				s1 = peg$c46();
				s0 = s1;
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c41);
			}
		}

		return s0;
	}

	function peg$parseversion(): any {
		let s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$currPos;
			s3 = [];
			if (peg$c38.test(input.charAt(peg$currPos))) {
				s4 = input.charAt(peg$currPos);
				peg$currPos++;
			} else {
				s4 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c39);
				}
			}
			if (s4 !== peg$FAILED) {
				while (s4 !== peg$FAILED) {
					s3.push(s4);
					if (peg$c38.test(input.charAt(peg$currPos))) {
						s4 = input.charAt(peg$currPos);
						peg$currPos++;
					} else {
						s4 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c39);
						}
					}
				}
			} else {
				s3 = peg$FAILED;
			}
			if (s3 !== peg$FAILED) {
				if (input.charCodeAt(peg$currPos) === 46) {
					s4 = peg$c48;
					peg$currPos++;
				} else {
					s4 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c49);
					}
				}
				if (s4 !== peg$FAILED) {
					s5 = [];
					if (peg$c38.test(input.charAt(peg$currPos))) {
						s6 = input.charAt(peg$currPos);
						peg$currPos++;
					} else {
						s6 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c39);
						}
					}
					if (s6 !== peg$FAILED) {
						while (s6 !== peg$FAILED) {
							s5.push(s6);
							if (peg$c38.test(input.charAt(peg$currPos))) {
								s6 = input.charAt(peg$currPos);
								peg$currPos++;
							} else {
								s6 = peg$FAILED;
								if (peg$silentFails === 0) {
									peg$fail(peg$c39);
								}
							}
						}
					} else {
						s5 = peg$FAILED;
					}
					if (s5 !== peg$FAILED) {
						s6 = peg$currPos;
						if (input.charCodeAt(peg$currPos) === 46) {
							s7 = peg$c48;
							peg$currPos++;
						} else {
							s7 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c49);
							}
						}
						if (s7 !== peg$FAILED) {
							s8 = [];
							if (peg$c38.test(input.charAt(peg$currPos))) {
								s9 = input.charAt(peg$currPos);
								peg$currPos++;
							} else {
								s9 = peg$FAILED;
								if (peg$silentFails === 0) {
									peg$fail(peg$c39);
								}
							}
							if (s9 !== peg$FAILED) {
								while (s9 !== peg$FAILED) {
									s8.push(s9);
									if (
										peg$c38.test(input.charAt(peg$currPos))
									) {
										s9 = input.charAt(peg$currPos);
										peg$currPos++;
									} else {
										s9 = peg$FAILED;
										if (peg$silentFails === 0) {
											peg$fail(peg$c39);
										}
									}
								}
							} else {
								s8 = peg$FAILED;
							}
							if (s8 !== peg$FAILED) {
								s7 = [s7, s8];
								s6 = s7;
							} else {
								peg$currPos = s6;
								s6 = peg$FAILED;
							}
						} else {
							peg$currPos = s6;
							s6 = peg$FAILED;
						}
						if (s6 === peg$FAILED) {
							s6 = null;
						}
						if (s6 !== peg$FAILED) {
							s3 = [s3, s4, s5, s6];
							s2 = s3;
						} else {
							peg$currPos = s2;
							s2 = peg$FAILED;
						}
					} else {
						peg$currPos = s2;
						s2 = peg$FAILED;
					}
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
			} else {
				peg$currPos = s2;
				s2 = peg$FAILED;
			}
			if (s2 !== peg$FAILED) {
				peg$savedPos = s0;
				s1 = peg$c50(s2);
				s0 = s1;
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		} else {
			peg$currPos = s0;
			s0 = peg$FAILED;
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c47);
			}
		}

		return s0;
	}

	function peg$parsestring(): any {
		let s0, s1, s2, s3, s4, s5;

		peg$silentFails++;
		s0 = peg$currPos;
		s1 = peg$parse_();
		if (s1 !== peg$FAILED) {
			s2 = peg$currPos;
			if (input.charCodeAt(peg$currPos) === 34) {
				s3 = peg$c52;
				peg$currPos++;
			} else {
				s3 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c53);
				}
			}
			if (s3 !== peg$FAILED) {
				s4 = [];
				if (peg$c54.test(input.charAt(peg$currPos))) {
					s5 = input.charAt(peg$currPos);
					peg$currPos++;
				} else {
					s5 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c55);
					}
				}
				while (s5 !== peg$FAILED) {
					s4.push(s5);
					if (peg$c54.test(input.charAt(peg$currPos))) {
						s5 = input.charAt(peg$currPos);
						peg$currPos++;
					} else {
						s5 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c55);
						}
					}
				}
				if (s4 !== peg$FAILED) {
					if (input.charCodeAt(peg$currPos) === 34) {
						s5 = peg$c52;
						peg$currPos++;
					} else {
						s5 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c53);
						}
					}
					if (s5 !== peg$FAILED) {
						s3 = [s3, s4, s5];
						s2 = s3;
					} else {
						peg$currPos = s2;
						s2 = peg$FAILED;
					}
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
			} else {
				peg$currPos = s2;
				s2 = peg$FAILED;
			}
			if (s2 !== peg$FAILED) {
				peg$savedPos = s0;
				s1 = peg$c56();
				s0 = s1;
			} 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) {
				s2 = peg$currPos;
				if (input.charCodeAt(peg$currPos) === 39) {
					s3 = peg$c57;
					peg$currPos++;
				} else {
					s3 = peg$FAILED;
					if (peg$silentFails === 0) {
						peg$fail(peg$c58);
					}
				}
				if (s3 !== peg$FAILED) {
					s4 = [];
					if (peg$c59.test(input.charAt(peg$currPos))) {
						s5 = input.charAt(peg$currPos);
						peg$currPos++;
					} else {
						s5 = peg$FAILED;
						if (peg$silentFails === 0) {
							peg$fail(peg$c60);
						}
					}
					while (s5 !== peg$FAILED) {
						s4.push(s5);
						if (peg$c59.test(input.charAt(peg$currPos))) {
							s5 = input.charAt(peg$currPos);
							peg$currPos++;
						} else {
							s5 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c60);
							}
						}
					}
					if (s4 !== peg$FAILED) {
						if (input.charCodeAt(peg$currPos) === 39) {
							s5 = peg$c57;
							peg$currPos++;
						} else {
							s5 = peg$FAILED;
							if (peg$silentFails === 0) {
								peg$fail(peg$c58);
							}
						}
						if (s5 !== peg$FAILED) {
							s3 = [s3, s4, s5];
							s2 = s3;
						} else {
							peg$currPos = s2;
							s2 = peg$FAILED;
						}
					} else {
						peg$currPos = s2;
						s2 = peg$FAILED;
					}
				} else {
					peg$currPos = s2;
					s2 = peg$FAILED;
				}
				if (s2 !== peg$FAILED) {
					peg$savedPos = s0;
					s1 = peg$c56();
					s0 = s1;
				} else {
					peg$currPos = s0;
					s0 = peg$FAILED;
				}
			} else {
				peg$currPos = s0;
				s0 = peg$FAILED;
			}
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c51);
			}
		}

		return s0;
	}

	function peg$parse_(): any {
		let s0, s1;

		peg$silentFails++;
		s0 = [];
		if (peg$c62.test(input.charAt(peg$currPos))) {
			s1 = input.charAt(peg$currPos);
			peg$currPos++;
		} else {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c63);
			}
		}
		while (s1 !== peg$FAILED) {
			s0.push(s1);
			if (peg$c62.test(input.charAt(peg$currPos))) {
				s1 = input.charAt(peg$currPos);
				peg$currPos++;
			} else {
				s1 = peg$FAILED;
				if (peg$silentFails === 0) {
					peg$fail(peg$c63);
				}
			}
		}
		peg$silentFails--;
		if (s0 === peg$FAILED) {
			s1 = peg$FAILED;
			if (peg$silentFails === 0) {
				peg$fail(peg$c61);
			}
		}

		return s0;
	}

	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),
		);
	}
}

export interface IParseOptions {
	filename?: string;
	startRule?: string;
	tracer?: any;
	[key: string]: any;
}
export type ParseFunction = (input: string, options?: IParseOptions) => any;
export const parse: ParseFunction = peg$parse;
