From 5403728c6f0975814b34f1b6c9a802a1cd4edb1e Mon Sep 17 00:00:00 2001 From: bobbylight Date: Sun, 20 Nov 2022 12:46:14 -0500 Subject: [PATCH] Fix #419: Adding Handlebars syntax highlighting --- .../DefaultTokenMakerFactory.java | 1 + .../fife/ui/rsyntaxtextarea/FileTypeUtil.java | 1 + .../ui/rsyntaxtextarea/SyntaxConstants.java | 6 + .../modes/HandlebarsTokenMaker.flex | 1616 +++++++ .../modes/HandlebarsTokenMaker.java | 3704 +++++++++++++++++ .../modes/AbstractCDerivedTokenMakerTest.java | 25 +- .../modes/AbstractTokenMakerTest.java | 43 +- .../modes/CSSTokenMakerTest.java | 7 - .../modes/HTMLTokenMakerTest.java | 21 +- .../modes/HandlebarsTokenMakerTest.java | 1949 +++++++++ .../modes/JSPTokenMakerTest.java | 20 +- .../modes/JshintrcTokenMakerTest.java | 2 + .../modes/JsonTokenMakerTest.java | 4 +- .../modes/LessTokenMakerTest.java | 7 - .../modes/PhpTokenMakerTest.java | 22 +- .../modes/SQLTokenMakerTest.java | 8 + .../ui/rsyntaxtextarea/demo/DemoRootPane.java | 1 + .../demo/HandlebarsExample.txt | 32 + 18 files changed, 7421 insertions(+), 48 deletions(-) create mode 100644 RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex create mode 100644 RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java create mode 100644 RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMakerTest.java create mode 100644 RSyntaxTextAreaDemo/src/main/resources/org/fife/ui/rsyntaxtextarea/demo/HandlebarsExample.txt diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/DefaultTokenMakerFactory.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/DefaultTokenMakerFactory.java index 65d7f5091..5f6400395 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/DefaultTokenMakerFactory.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/DefaultTokenMakerFactory.java @@ -45,6 +45,7 @@ protected void initTokenMakerMap() { putMapping(SYNTAX_STYLE_FORTRAN, pkg + "FortranTokenMaker"); putMapping(SYNTAX_STYLE_GO, pkg + "GoTokenMaker"); putMapping(SYNTAX_STYLE_GROOVY, pkg + "GroovyTokenMaker"); + putMapping(SYNTAX_STYLE_HANDLEBARS, pkg + "HandlebarsTokenMaker"); putMapping(SYNTAX_STYLE_HOSTS, pkg + "HostsTokenMaker"); putMapping(SYNTAX_STYLE_HTACCESS, pkg + "HtaccessTokenMaker"); putMapping(SYNTAX_STYLE_HTML, pkg + "HTMLTokenMaker"); diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java index d10e7538c..b94354a47 100644 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java @@ -405,6 +405,7 @@ private void initializeFilters() { initFiltersImpl(map, SYNTAX_STYLE_FORTRAN, "*.f", "*.for", "*.fort", "*.f77", "*.f90"); initFiltersImpl(map, SYNTAX_STYLE_GO, "*.go"); initFiltersImpl(map, SYNTAX_STYLE_GROOVY, "*.groovy", "*.gradle", "*.grv", "*.gy", "*.gvy", "*.gsh"); + initFiltersImpl(map, SYNTAX_STYLE_HANDLEBARS, "*.hbs", "*.handlebars"); initFiltersImpl(map, SYNTAX_STYLE_HOSTS, "hosts"); initFiltersImpl(map, SYNTAX_STYLE_HTACCESS, ".htaccess"); initFiltersImpl(map, SYNTAX_STYLE_HTML, "*.htm", "*.html"); diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxConstants.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxConstants.java index 4ba82a3cf..319a232b6 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxConstants.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxConstants.java @@ -142,6 +142,12 @@ public interface SyntaxConstants { String SYNTAX_STYLE_GROOVY = "text/groovy"; + /** + * Style for highlighting Handlebars files. + */ + String SYNTAX_STYLE_HANDLEBARS = "text/handlebars"; + + /** * Style for highlighting hosts files. */ diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex new file mode 100644 index 000000000..e31e1c374 --- /dev/null +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex @@ -0,0 +1,1616 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea.modes; + +import java.io.*; +import javax.swing.text.Segment; +import java.util.Stack; + +import org.fife.ui.rsyntaxtextarea.*; + + +/** + * Scanner for Handlebars. + * + * This implementation was created using + * JFlex 1.4.1; however, the generated file + * was modified for performance. Memory allocation needs to be almost + * completely removed to be competitive with the handwritten lexers (subclasses + * of AbstractTokenMaker), so this class has been modified so that + * Strings are never allocated (via yytext()), and the scanner never has to + * worry about refilling its buffer (needlessly copying chars around). + * We can achieve this because RText always scans exactly 1 line of tokens at a + * time, and hands the scanner this line as an array of characters (a Segment + * really). Since tokens contain pointers to char arrays instead of Strings + * holding their contents, there is no need for allocating new memory for + * Strings.

+ * + * The actual algorithm generated for scanning has, of course, not been + * modified.

+ * + * If you wish to regenerate this file yourself, keep in mind the following: + *

+ * + * @author Robert Futrell + * @version 0.9 + */ +%% + +%public +%class HandlebarsTokenMaker +%extends AbstractMarkupTokenMaker +%unicode +%type org.fife.ui.rsyntaxtextarea.Token + + +%{ + + /** + * Type specific to XMLTokenMaker denoting a line ending with an unclosed + * double-quote attribute. + */ + public static final int INTERNAL_ATTR_DOUBLE = -1; + + + /** + * Type specific to XMLTokenMaker denoting a line ending with an unclosed + * single-quote attribute. + */ + public static final int INTERNAL_ATTR_SINGLE = -2; + + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed HTML tag; thus a new line is beginning + * still inside of the tag. + */ + public static final int INTERNAL_INTAG = -3; + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed <script> tag. + */ + public static final int INTERNAL_INTAG_SCRIPT = -4; + + /** + * Token type specifying we're in a double-quoted attribute in a + * script tag. + */ + public static final int INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT = -5; + + /** + * Token type specifying we're in a single-quoted attribute in a + * script tag. + */ + public static final int INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT = -6; + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed <style> tag. + */ + public static final int INTERNAL_INTAG_STYLE = -7; + + /** + * Token type specifying we're in a double-quoted attribute in a + * style tag. + */ + public static final int INTERNAL_ATTR_DOUBLE_QUOTE_STYLE = -8; + + /** + * Token type specifying we're in a single-quoted attribute in a + * style tag. + */ + public static final int INTERNAL_ATTR_SINGLE_QUOTE_STYLE = -9; + + /** + * Token type specifying we're in JavaScript. + */ + public static final int INTERNAL_IN_JS = -10; + + /** + * Token type specifying we're in a JavaScript multiline comment. + */ + public static final int INTERNAL_IN_JS_MLC = -11; + + /** + * Token type specifying we're in an invalid multi-line JS string. + */ + public static final int INTERNAL_IN_JS_STRING_INVALID = -12; + + /** + * Token type specifying we're in a valid multi-line JS string. + */ + public static final int INTERNAL_IN_JS_STRING_VALID = -13; + + /** + * Token type specifying we're in an invalid multi-line JS single-quoted string. + */ + public static final int INTERNAL_IN_JS_CHAR_INVALID = -14; + + /** + * Token type specifying we're in a valid multi-line JS single-quoted string. + */ + public static final int INTERNAL_IN_JS_CHAR_VALID = -15; + + /** + * Internal type denoting a line ending in CSS. + */ + public static final int INTERNAL_CSS = -16; + + /** + * Internal type denoting a line ending in a CSS property. + */ + public static final int INTERNAL_CSS_PROPERTY = -17; + + /** + * Internal type denoting a line ending in a CSS property value. + */ + public static final int INTERNAL_CSS_VALUE = -18; + + /** + * Token type specifying we're in a valid multi-line template literal. + */ + static final int INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID = -23; + + /** + * Token type specifying we're in an invalid multi-line template literal. + */ + static final int INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID = -24; + + /** + * Internal type denoting line ending in a CSS double-quote string. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_STRING = -(1<<11); + + /** + * Internal type denoting line ending in a CSS single-quote string. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_CHAR = -(2<<11); + + /** + * Internal type denoting line ending in a CSS multi-line comment. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_MLC = -(3<<11); + + /** + * Token type specifying we're in a Handlebars expression. This particular field is public so + * that we can hack and key off of it for code completion. + */ + static final int INTERNAL_IN_HB = -(4<<11); + + /** + * Token type specifying we're in a Handlebars multiline comment starting with {@code "{{!"}. + */ + static final int INTERNAL_IN_HB_MLC_1 = -(5<<11); + + /** + * Token type specifying we're in a Handlebars multiline comment starting with {@code "{{!--"}. + */ + static final int INTERNAL_IN_HB_MLC_2 = -(6<<11); + + /** + * Token type specifying we're in a Handlebars multiline string. + */ + static final int INTERNAL_IN_HB_STRING = -(7<<11); + + /** + * Token type specifying we're in a Handlebars multiline char. + */ + static final int INTERNAL_IN_HB_CHAR = -(8<<11); + + /** + * The state previous CSS-related state we were in before going into a CSS + * string, multi-line comment, etc. + */ + private int cssPrevState; + + /** + * Whether closing markup tags are automatically completed for HTML. + */ + private static boolean completeCloseTags; + + /** + * When in the JS_STRING state, whether the current string is valid. + */ + private boolean validJSString; + + /** + * When in the HB state, whether the current string is valid. + */ + private boolean validHandlebarsString; + + /** + * The number of curly braces to look for to denote the close of the current Handlebars expression. + */ + private int hbCurlyCount; + + /** + * The state Handlebars was started in (YYINITIAL, INTERNAL_IN_JS, etc.). + */ + private int hbInState; + + /** + * The language index we were in when Handlebars was started. + */ + private int hbInLangIndex; + + /** + * Language state set on HTML tokens. Must be 0. + */ + static final int LANG_INDEX_DEFAULT = 0; + + /** + * Language state set on JavaScript tokens. + */ + static final int LANG_INDEX_JS = 1; + + /** + * Language state set on CSS tokens. + */ + static final int LANG_INDEX_CSS = 2; + + /** + * Language state set on Handlebars tokens. + */ + static final int LANG_INDEX_HANDLEBARS = 3; + + private Stack varDepths; + + + /** + * Constructor. This must be here because JFlex does not generate a + * no-parameter constructor. + */ + public HandlebarsTokenMaker() { + super(); + } + + + /** + * Adds the token specified to the current linked list of tokens as an + * "end token;" that is, at zzMarkedPos. + * + * @param tokenType The token's type. + */ + private void addEndToken(int tokenType) { + addToken(zzMarkedPos,zzMarkedPos, tokenType); + } + + + /** + * Adds an end token that encodes the information necessary to return + * to the pre-Handlebars state and language index. + * + * @param endTokenState The Handlebars-related end-token state. + */ + private void addHandlebarsEndToken(int endTokenState) { + addEndToken(endTokenState - hbInState - (hbInLangIndex<<16)); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + * @see #addToken(int, int, int) + */ + private void addHyperlinkToken(int start, int end, int tokenType) { + int so = start + offsetShift; + addToken(zzBuffer, start,end, tokenType, so, true); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + */ + private void addToken(int tokenType) { + addToken(zzStartRead, zzMarkedPos-1, tokenType); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + */ + private void addToken(int start, int end, int tokenType) { + int so = start + offsetShift; + addToken(zzBuffer, start,end, tokenType, so); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param array The character array. + * @param start The starting offset in the array. + * @param end The ending offset in the array. + * @param tokenType The token's type. + * @param startOffset The offset in the document at which this token + * occurs. + */ + @Override + public void addToken(char[] array, int start, int end, int tokenType, int startOffset) { + super.addToken(array, start,end, tokenType, startOffset); + zzStartRead = zzMarkedPos; + } + + + @Override + protected OccurrenceMarker createOccurrenceMarker() { + return new HtmlOccurrenceMarker(); + } + + + /** + * Sets whether markup close tags should be completed. You might not want + * this to be the case, since some tags in standard HTML aren't usually + * closed. + * + * @return Whether closing markup tags are completed. + * @see #setCompleteCloseTags(boolean) + */ + @Override + public boolean getCompleteCloseTags() { + return completeCloseTags; + } + + + @Override + public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) { + return languageIndex==LANG_INDEX_CSS || languageIndex==LANG_INDEX_JS; + } + + + @Override + public String[] getLineCommentStartAndEnd(int languageIndex) { + switch (languageIndex) { + case LANG_INDEX_JS: + return new String[] { "//", null }; + case LANG_INDEX_CSS: + return new String[] { "/*", "*/" }; + case LANG_INDEX_HANDLEBARS: + return new String[] { "{{!--", "--}}" }; + default: + return new String[] { "" }; + } + } + + + /** + * Returns TokenTypes.MARKUP_TAG_NAME. + * + * @param type The token type. + * @return Whether tokens of this type should have "mark occurrences" + * enabled. + */ + @Override + public boolean getMarkOccurrencesOfTokenType(int type) { + return type==TokenTypes.MARKUP_TAG_NAME; + } + + + /** + * Overridden to handle newlines in JS and CSS differently than those in + * markup. + */ + @Override + public boolean getShouldIndentNextLineAfter(Token token) { + int languageIndex = token==null ? 0 : token.getLanguageIndex(); + if (getCurlyBracesDenoteCodeBlocks(languageIndex)) { + if (token!=null && token.length()==1) { + char ch = token.charAt(0); + return ch=='{' || ch=='('; + } + } + return false; + } + + + /** + * Returns the first token in the linked list of tokens generated + * from text. This method must be implemented by + * subclasses so they can correctly implement syntax highlighting. + * + * @param text The text from which to get tokens. + * @param initialTokenType The token type we should start with. + * @param startOffset The offset into the document at which + * text starts. + * @return The first Token in a linked list representing + * the syntax highlighted text. + */ + @Override + public Token getTokenList(Segment text, int initialTokenType, int startOffset) { + + resetTokenList(); + this.offsetShift = -text.offset + startOffset; + hbInState = YYINITIAL; // Shouldn't be necessary + cssPrevState = CSS; // Shouldn't be necessary + int languageIndex = 0; + + // Start off in the proper state. + int state; + switch (initialTokenType) { + case TokenTypes.MARKUP_COMMENT: + state = COMMENT; + break; + case INTERNAL_INTAG: + state = INTAG; + break; + case INTERNAL_INTAG_SCRIPT: + state = INTAG_SCRIPT; + break; + case INTERNAL_INTAG_STYLE: + state = INTAG_STYLE; + break; + case INTERNAL_ATTR_DOUBLE: + state = INATTR_DOUBLE; + break; + case INTERNAL_ATTR_SINGLE: + state = INATTR_SINGLE; + break; + case INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT: + state = INATTR_DOUBLE_SCRIPT; + break; + case INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT: + state = INATTR_SINGLE_SCRIPT; + break; + case INTERNAL_ATTR_DOUBLE_QUOTE_STYLE: + state = INATTR_DOUBLE_STYLE; + break; + case INTERNAL_ATTR_SINGLE_QUOTE_STYLE: + state = INATTR_SINGLE_STYLE; + break; + case INTERNAL_IN_JS: + state = JAVASCRIPT; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_MLC: + state = JS_MLC; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_STRING_INVALID: + state = JS_STRING; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_STRING_VALID: + state = JS_STRING; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_CHAR_INVALID: + state = JS_CHAR; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_CHAR_VALID: + state = JS_CHAR; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_CSS: + state = CSS; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_PROPERTY: + state = CSS_PROPERTY; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_VALUE: + state = CSS_VALUE; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID: + state = JS_TEMPLATE_LITERAL; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID: + state = JS_TEMPLATE_LITERAL; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + default: + if (initialTokenType<-1024) { + int main = -(-initialTokenType & 0xffffff00); + switch (main) { + default: // Should never happen + case INTERNAL_IN_HB: + state = HB; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_CHAR: + state = HB_CHAR_LITERAL; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_STRING: + state = HB_STRING; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_MLC_1: + state = HB_COMMENT_1; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_MLC_2: + state = HB_COMMENT_2; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_CSS_STRING: + state = CSS_STRING; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_CHAR: + state = CSS_CHAR_LITERAL; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_MLC: + state = CSS_C_STYLE_COMMENT; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + } + } + else { + state = YYINITIAL; + } + break; + } + + setLanguageIndex(languageIndex); + start = text.offset; + s = text; + try { + yyreset(zzReader); + yybegin(state); + return yylex(); + } catch (IOException ioe) { + ioe.printStackTrace(); + return new TokenImpl(); + } + + } + + + /** + * Overridden to accept letters, digits, underscores, and hyphens. + */ + @Override + public boolean isIdentifierChar(int languageIndex, char ch) { + switch (languageIndex) { + case LANG_INDEX_CSS: + case LANG_INDEX_HANDLEBARS: + case LANG_INDEX_DEFAULT: + return Character.isLetterOrDigit(ch) || ch=='-' || ch=='.' || ch=='_'; + case LANG_INDEX_JS: + default: + return super.isIdentifierChar(languageIndex, ch); + } + } + + + /** + * Sets whether markup close tags should be completed. You might not want + * this to be the case, since some tags in standard HTML aren't usually + * closed. + * + * @param complete Whether closing markup tags are completed. + * @see #getCompleteCloseTags() + */ + public static void setCompleteCloseTags(boolean complete) { + completeCloseTags = complete; + } + + + /** + * Overridden to remember the language index we're leaving. + */ + @Override + protected void yybegin(int state, int languageIndex) { + hbInLangIndex = getLanguageIndex(); + yybegin(state); + setLanguageIndex(languageIndex); + } + + + /** + * Refills the input buffer. + * + * @return true if EOF was reached, otherwise + * false. + */ + private boolean zzRefill() { + return zzCurrentPos>=s.offset+s.count; + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to YY_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + // 's' has been updated. + zzBuffer = s.array; + /* + * We replaced the line below with the two below it because zzRefill + * no longer "refills" the buffer (since the way we do it, it's always + * "full" the first time through, since it points to the segment's + * array). So, we assign zzEndRead here. + */ + //zzStartRead = zzEndRead = s.offset; + zzStartRead = s.offset; + zzEndRead = zzStartRead + s.count - 1; + zzCurrentPos = zzMarkedPos = zzPushbackPos = s.offset; + zzLexicalState = YYINITIAL; + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + } + + +%} + +// HTML-specific stuff. +Whitespace = ([ \t\f]+) +LineTerminator = ([\n]) +Identifier = ([^ \t\n<&{}]+) // '{' and '}' added for Handlebars +EntityReference = ([&][^; \t]*[;]?) +InTagIdentifier = ([^ \t\n\"\'/=>]+) +EndScriptTag = ("") +EndStyleTag = ("") + +// General stuff. +Letter = [A-Za-z] +NonzeroDigit = [1-9] +Digit = ("0"|{NonzeroDigit}) +HexDigit = ({Digit}|[A-Fa-f]) +OctalDigit = ([0-7]) +LetterOrUnderscore = ({Letter}|[_]) +LetterOrUnderscoreOrDash = ({LetterOrUnderscore}|[\-]) + + +// JavaScript stuff. +EscapedSourceCharacter = ("u"{HexDigit}{HexDigit}{HexDigit}{HexDigit}) +NonSeparator = ([^\t\f\r\n\ \(\)\{\}\[\]\;\,\.\=\>\<\!\~\?\:\+\-\*\/\&\|\^\%\"\'\`]|"#"|"\\") +IdentifierStart = ({Letter}|"_"|"$") +IdentifierPart = ({IdentifierStart}|{Digit}|("\\"{EscapedSourceCharacter})) +JS_MLCBegin = "/*" +JS_MLCEnd = "*/" +JS_LineCommentBegin = "//" +JS_IntegerHelper1 = (({NonzeroDigit}{Digit}*)|"0") +JS_IntegerHelper2 = ("0"(([xX]{HexDigit}+)|({OctalDigit}*))) +JS_IntegerLiteral = ({JS_IntegerHelper1}[lL]?) +JS_HexLiteral = ({JS_IntegerHelper2}[lL]?) +JS_FloatHelper1 = ([fFdD]?) +JS_FloatHelper2 = ([eE][+-]?{Digit}+{JS_FloatHelper1}) +JS_FloatLiteral1 = ({Digit}+"."({JS_FloatHelper1}|{JS_FloatHelper2}|{Digit}+({JS_FloatHelper1}|{JS_FloatHelper2}))) +JS_FloatLiteral2 = ("."{Digit}+({JS_FloatHelper1}|{JS_FloatHelper2})) +JS_FloatLiteral3 = ({Digit}+{JS_FloatHelper2}) +JS_FloatLiteral = ({JS_FloatLiteral1}|{JS_FloatLiteral2}|{JS_FloatLiteral3}|({Digit}+[fFdD])) +JS_ErrorNumberFormat = (({JS_IntegerLiteral}|{JS_HexLiteral}|{JS_FloatLiteral}){NonSeparator}+) +JS_Separator = ([\(\)\{\}\[\]\]]) +JS_Separator2 = ([\;,.]) +JS_NonAssignmentOperator = ("+"|"-"|"<="|"^"|"++"|"<"|"*"|">="|"%"|"--"|">"|"/"|"!="|"?"|">>"|"!"|"&"|"=="|":"|">>"|"~"|"||"|"&&"|">>>") +JS_AssignmentOperator = ("="|"-="|"*="|"/="|"|="|"&="|"^="|"+="|"%="|"<<="|">>="|">>>=") +JS_Operator = ({JS_NonAssignmentOperator}|{JS_AssignmentOperator}) +JS_Identifier = ({IdentifierStart}{IdentifierPart}*) +JS_ErrorIdentifier = ({NonSeparator}+) +JS_Regex = ("/"([^\*\\/]|\\.)([^/\\]|\\.)*"/"[gim]*) + +JS_TemplateLiteralExprStart = ("${") + +// CSS stuff. +CSS_SelectorPiece = (("*"|"."|{LetterOrUnderscoreOrDash})({LetterOrUnderscoreOrDash}|"."|{Digit})*) +CSS_PseudoClass = (":"("root"|"nth-child"|"nth-last-child"|"nth-of-type"|"nth-last-of-type"|"first-child"|"last-child"|"first-of-type"|"last-of-type"|"only-child"|"only-of-type"|"empty"|"link"|"visited"|"active"|"hover"|"focus"|"target"|"lang"|"enabled"|"disabled"|"checked"|":first-line"|":first-letter"|":before"|":after"|"not")) +CSS_AtKeyword = ("@"{CSS_SelectorPiece}) +CSS_Id = ("#"{CSS_SelectorPiece}) +CSS_Separator = ([;\(\)\[\]]) +CSS_MlcStart = ({JS_MLCBegin}) +CSS_MlcEnd = ({JS_MLCEnd}) +CSS_Property = ([\*]?{LetterOrUnderscoreOrDash}({LetterOrUnderscoreOrDash}|{Digit})*) +CSS_ValueChar = ({LetterOrUnderscoreOrDash}|[\\/]) +CSS_Value = ({CSS_ValueChar}*) +CSS_Function = ({CSS_Value}\() +CSS_Digits = ([\-]?{Digit}+([0-9\.]+)?(pt|pc|in|mm|cm|em|ex|px|ms|s|%)?) +CSS_Hex = ("#"[0-9a-fA-F]+) +CSS_Number = ({CSS_Digits}|{CSS_Hex}) + +// Handlebars stuff. +HB_IdentifierStart = ([^ \t\n!%&*+,./;<=>@`|{}\[\]\(\)\"\'\^~0123456789]+) +HB_IdentifierPart = ([^ \t\n!%&*+,./;<=>@`|{}\[\]\(\)\"\'\^~]+) +HB_Identifier = ({HB_IdentifierStart}{HB_IdentifierPart}*) +HB_CommentStart1 = ("{{!") +HB_CommentEnd1 = ("}}") +HB_CommentStart2 = ("{{!--") +HB_CommentEnd2 = ("--}}") +HB_Operator = ([!%&*+,./;<=>@`|\^~]) +HB_Separator = ([\[\]\{\}\(\)]) + +URLGenDelim = ([:\/\?#\[\]@]) +URLSubDelim = ([\!\$&'\(\)\*\+,;=]) +URLUnreserved = ({LetterOrUnderscore}|{Digit}|[\-\.\~]) +URLCharacter = ({URLGenDelim}|{URLSubDelim}|{URLUnreserved}|[%]) +URLCharacters = ({URLCharacter}*) +URLEndCharacter = ([\/\$]|{Letter}|{Digit}) +URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?) + + +%state COMMENT +%state PI +%state DTD +%state INTAG +%state INTAG_CHECK_TAG_NAME +%state INATTR_DOUBLE +%state INATTR_SINGLE +%state INTAG_SCRIPT +%state INATTR_DOUBLE_SCRIPT +%state INATTR_SINGLE_SCRIPT +%state INTAG_STYLE +%state INATTR_DOUBLE_STYLE +%state INATTR_SINGLE_STYLE +%state JAVASCRIPT +%state JS_STRING +%state JS_CHAR +%state JS_MLC +%state JS_EOL_COMMENT +%state CSS +%state CSS_PROPERTY +%state CSS_VALUE +%state CSS_STRING +%state CSS_CHAR_LITERAL +%state CSS_C_STYLE_COMMENT +%state JS_TEMPLATE_LITERAL +%state JS_TEMPLATE_LITERAL_EXPR +%state HB +%state HB_STRING +%state HB_CHAR_LITERAL +%state HB_COMMENT_1 +%state HB_COMMENT_2 + +%% + + { + "" { yybegin(YYINITIAL); addToken(start,zzStartRead+2, TokenTypes.MARKUP_COMMENT); } + "-" {} + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_COMMENT); return firstToken; } +} + + { + [^\n\?]+ {} + {LineTerminator} { addToken(start,zzStartRead-1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); return firstToken; } + "?>" { yybegin(YYINITIAL); addToken(start,zzStartRead+1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); } + "?" {} + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); return firstToken; } +} + + { + [^\n>]+ {} + ">" { yybegin(YYINITIAL); addToken(start,zzStartRead, TokenTypes.MARKUP_DTD); } + {LineTerminator} | + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_DTD); return firstToken; } +} + + { + [Aa] | + [aA][bB][bB][rR] | + [aA][cC][rR][oO][nN][yY][mM] | + [aA][dD][dD][rR][eE][sS][sS] | + [aA][pP][pP][lL][eE][tT] | + [aA][rR][eE][aA] | + [aA][rR][tT][iI][cC][lL][eE] | + [aA][sS][iI][dD][eE] | + [aA][uU][dD][iI][oO] | + [bB] | + [bB][aA][sS][eE] | + [bB][aA][sS][eE][fF][oO][nN][tT] | + [bB][dD][oO] | + [bB][gG][sS][oO][uU][nN][dD] | + [bB][iI][gG] | + [bB][lL][iI][nN][kK] | + [bB][lL][oO][cC][kK][qQ][uU][oO][tT][eE] | + [bB][oO][dD][yY] | + [bB][rR] | + [bB][uU][tT][tT][oO][nN] | + [cC][aA][nN][vV][aA][sS] | + [cC][aA][pP][tT][iI][oO][nN] | + [cC][eE][nN][tT][eE][rR] | + [cC][iI][tT][eE] | + [cC][oO][dD][eE] | + [cC][oO][lL] | + [cC][oO][lL][gG][rR][oO][uU][pP] | + [cC][oO][mM][mM][aA][nN][dD] | + [cC][oO][mM][mM][eE][nN][tT] | + [dD][dD] | + [dD][aA][tT][aA][gG][rR][iI][dD] | + [dD][aA][tT][aA][lL][iI][sS][tT] | + [dD][aA][tT][aA][tT][eE][mM][pP][lL][aA][tT][eE] | + [dD][eE][lL] | + [dD][eE][tT][aA][iI][lL][sS] | + [dD][fF][nN] | + [dD][iI][aA][lL][oO][gG] | + [dD][iI][rR] | + [dD][iI][vV] | + [dD][lL] | + [dD][tT] | + [eE][mM] | + [eE][mM][bB][eE][dD] | + [eE][vV][eE][nN][tT][sS][oO][uU][rR][cC][eE] | + [fF][iI][eE][lL][dD][sS][eE][tT] | + [fF][iI][gG][uU][rR][eE] | + [fF][oO][nN][tT] | + [fF][oO][oO][tT][eE][rR] | + [fF][oO][rR][mM] | + [fF][rR][aA][mM][eE] | + [fF][rR][aA][mM][eE][sS][eE][tT] | + [hH][123456] | + [hH][eE][aA][dD] | + [hH][eE][aA][dD][eE][rR] | + [hH][rR] | + [hH][tT][mM][lL] | + [iI] | + [iI][fF][rR][aA][mM][eE] | + [iI][lL][aA][yY][eE][rR] | + [iI][mM][gG] | + [iI][nN][pP][uU][tT] | + [iI][nN][sS] | + [iI][sS][iI][nN][dD][eE][xX] | + [kK][bB][dD] | + [kK][eE][yY][gG][eE][nN] | + [lL][aA][bB][eE][lL] | + [lL][aA][yY][eE][rR] | + [lL][eE][gG][eE][nN][dD] | + [lL][iI] | + [lL][iI][nN][kK] | + [mM][aA][pP] | + [mM][aA][rR][kK] | + [mM][aA][rR][qQ][uU][eE][eE] | + [mM][eE][nN][uU] | + [mM][eE][tT][aA] | + [mM][eE][tT][eE][rR] | + [mM][uU][lL][tT][iI][cC][oO][lL] | + [nN][aA][vV] | + [nN][eE][sS][tT] | + [nN][oO][bB][rR] | + [nN][oO][eE][mM][bB][eE][dD] | + [nN][oO][fF][rR][aA][mM][eE][sS] | + [nN][oO][lL][aA][yY][eE][rR] | + [nN][oO][sS][cC][rR][iI][pP][tT] | + [oO][bB][jJ][eE][cC][tT] | + [oO][lL] | + [oO][pP][tT][gG][rR][oO][uU][pP] | + [oO][pP][tT][iI][oO][nN] | + [oO][uU][tT][pP][uU][tT] | + [pP] | + [pP][aA][rR][aA][mM] | + [pP][lL][aA][iI][nN][tT][eE][xX][tT] | + [pP][rR][eE] | + [pP][rR][oO][gG][rR][eE][sS][sS] | + [qQ] | + [rR][uU][lL][eE] | + [sS] | + [sS][aA][mM][pP] | + [sS][cC][rR][iI][pP][tT] | + [sS][eE][cC][tT][iI][oO][nN] | + [sS][eE][lL][eE][cC][tT] | + [sS][eE][rR][vV][eE][rR] | + [sS][mM][aA][lL][lL] | + [sS][oO][uU][rR][cC][eE] | + [sS][pP][aA][cC][eE][rR] | + [sS][pP][aA][nN] | + [sS][tT][rR][iI][kK][eE] | + [sS][tT][rR][oO][nN][gG] | + [sS][tT][yY][lL][eE] | + [sS][uU][bB] | + [sS][uU][pP] | + [tT][aA][bB][lL][eE] | + [tT][bB][oO][dD][yY] | + [tT][dD] | + [tT][eE][xX][tT][aA][rR][eE][aA] | + [tT][fF][oO][oO][tT] | + [tT][hH] | + [tT][hH][eE][aA][dD] | + [tT][iI][mM][eE] | + [tT][iI][tT][lL][eE] | + [tT][rR] | + [tT][tT] | + [uU] | + [uU][lL] | + [vV][aA][rR] | + [vV][iI][dD][eE][oO] { addToken(TokenTypes.MARKUP_TAG_NAME); } + {InTagIdentifier} { /* A non-recognized HTML tag name */ yypushback(yylength()); yybegin(INTAG); } + . { /* Shouldn't happen */ yypushback(1); yybegin(INTAG); } + <> { addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG); return firstToken; } +} + + { + /* Handlebars states */ + "{{{{" | + "{{{" | + "{{" { hbCurlyCount = zzMarkedPos - zzStartRead; addToken(Token.SEPARATOR); hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); } + "{" { addToken(TokenTypes.MARKUP_TAG_ATTRIBUTE); } + + "/" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); } + {InTagIdentifier} { addToken(TokenTypes.MARKUP_TAG_ATTRIBUTE); } + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + "=" { addToken(TokenTypes.OPERATOR); } + "/>" { yybegin(YYINITIAL); addToken(TokenTypes.MARKUP_TAG_DELIMITER); } + ">" { yybegin(YYINITIAL); addToken(TokenTypes.MARKUP_TAG_DELIMITER); } + [\"] { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE); } + [\'] { start = zzMarkedPos-1; yybegin(INATTR_SINGLE); } + <> { addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG); return firstToken; } +} + + { + /* Handlebars states */ + "{{{{" | + "{{{" | + "{{" { int temp=zzStartRead; if (zzStartRead>start) addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); hbCurlyCount = zzMarkedPos - temp; addToken(temp, zzMarkedPos-1, Token.SEPARATOR); hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); } + "{" {} + + [^\"{]* {} + [\"] { yybegin(INTAG); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE); return firstToken; } +} + + { + /* Handlebars states */ + "{{{{" | + "{{{" | + "{{" { int temp=zzStartRead; if (zzStartRead>start) addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); hbCurlyCount = zzMarkedPos - temp; addToken(temp, zzMarkedPos-1, Token.SEPARATOR); hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); } + "{" {} + + [^\'{]* {} + [\'] { yybegin(INTAG); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE); return firstToken; } +} + + { + {InTagIdentifier} { addToken(TokenTypes.MARKUP_TAG_ATTRIBUTE); } + "/>" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(YYINITIAL); } + "/" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); } // Won't appear in valid HTML. + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + "=" { addToken(TokenTypes.OPERATOR); } + ">" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(JAVASCRIPT, LANG_INDEX_JS); } + [\"] { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE_SCRIPT); } + [\'] { start = zzMarkedPos-1; yybegin(INATTR_SINGLE_SCRIPT); } + <> { addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG_SCRIPT); return firstToken; } +} + + { + [^\"]* {} + [\"] { yybegin(INTAG_SCRIPT); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT); return firstToken; } +} + + { + [^\']* {} + [\'] { yybegin(INTAG_SCRIPT); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT); return firstToken; } +} + + { + {InTagIdentifier} { addToken(TokenTypes.MARKUP_TAG_ATTRIBUTE); } + "/>" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(YYINITIAL); } + "/" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); } // Won't appear in valid HTML. + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + "=" { addToken(TokenTypes.OPERATOR); } + ">" { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(CSS, LANG_INDEX_CSS); } + [\"] { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE_STYLE); } + [\'] { start = zzMarkedPos-1; yybegin(INATTR_SINGLE_STYLE); } + <> { addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG_STYLE); return firstToken; } +} + + { + [^\"]* {} + [\"] { yybegin(INTAG_STYLE); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE_QUOTE_STYLE); return firstToken; } +} + + { + [^\']* {} + [\'] { yybegin(INTAG_STYLE); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); } + <> { addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE_QUOTE_STYLE); return firstToken; } +} + + { + + {EndScriptTag} { + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + + // Keywords + "async" | + "await" | + "break" | + "case" | + "catch" | + "class" | + "const" | + "continue" | + "debugger" | + "delete" | + "do" | + "else" | + "export" | + "extends" | + "finally" | + "for" | + "function" | + "if" | + "import" | + "in" | + "instanceof" | + "new" | + "null" | + "of" | + "static" | + "super" | + "switch" | + "this" | + "throw" | + "try" | + "typeof" | + "var" | + "void" | + "while" | + "with" | + "yield" { addToken(Token.RESERVED_WORD); } + "return" { addToken(Token.RESERVED_WORD_2); } + + //JavaScript 1.6 + "each" {if(JavaScriptTokenMaker.isJavaScriptCompatible("1.6")){ addToken(TokenTypes.RESERVED_WORD);} else {addToken(TokenTypes.IDENTIFIER);} } + //JavaScript 1.7 + "let" {if(JavaScriptTokenMaker.isJavaScriptCompatible("1.7")){ addToken(TokenTypes.RESERVED_WORD);} else {addToken(TokenTypes.IDENTIFIER);} } + + // Reserved (but not yet used) ECMA keywords. + "abstract" { addToken(Token.RESERVED_WORD); } + "boolean" { addToken(Token.DATA_TYPE); } + "byte" { addToken(Token.DATA_TYPE); } + "char" { addToken(Token.DATA_TYPE); } + "default" { addToken(Token.RESERVED_WORD); } + "double" { addToken(Token.DATA_TYPE); } + "enum" { addToken(Token.RESERVED_WORD); } + "final" { addToken(Token.RESERVED_WORD); } + "float" { addToken(Token.DATA_TYPE); } + "goto" { addToken(Token.RESERVED_WORD); } + "implements" { addToken(Token.RESERVED_WORD); } + "int" { addToken(Token.DATA_TYPE); } + "interface" { addToken(Token.RESERVED_WORD); } + "long" { addToken(Token.DATA_TYPE); } + "native" { addToken(Token.RESERVED_WORD); } + "package" { addToken(Token.RESERVED_WORD); } + "private" { addToken(Token.RESERVED_WORD); } + "protected" { addToken(Token.RESERVED_WORD); } + "public" { addToken(Token.RESERVED_WORD); } + "short" { addToken(Token.DATA_TYPE); } + "synchronized" { addToken(Token.RESERVED_WORD); } + "throws" { addToken(Token.RESERVED_WORD); } + "transient" { addToken(Token.RESERVED_WORD); } + "volatile" { addToken(Token.RESERVED_WORD); } + + // Literals. + "false" | + "true" { addToken(TokenTypes.LITERAL_BOOLEAN); } + "NaN" { addToken(TokenTypes.RESERVED_WORD); } + "Infinity" { addToken(TokenTypes.RESERVED_WORD); } + + // Functions. + "eval" | + "parseInt" | + "parseFloat" | + "escape" | + "unescape" | + "isNaN" | + "isFinite" { addToken(TokenTypes.FUNCTION); } + + {LineTerminator} { addEndToken(INTERNAL_IN_JS); return firstToken; } + {JS_Identifier} { addToken(TokenTypes.IDENTIFIER); } + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + + /* String/Character literals. */ + [\'] { start = zzMarkedPos-1; validJSString = true; yybegin(JS_CHAR); } + [\"] { start = zzMarkedPos-1; validJSString = true; yybegin(JS_STRING); } + [\`] { start = zzMarkedPos-1; validJSString = true; yybegin(JS_TEMPLATE_LITERAL); } + + /* Comment literals. */ + "/**/" { addToken(TokenTypes.COMMENT_MULTILINE); } + {JS_MLCBegin} { start = zzMarkedPos-2; yybegin(JS_MLC); } + {JS_LineCommentBegin} { start = zzMarkedPos-2; yybegin(JS_EOL_COMMENT); } + + /* Attempt to identify regular expressions (not foolproof) - do after comments! */ + {JS_Regex} { + boolean highlightedAsRegex = false; + if (firstToken==null) { + addToken(TokenTypes.REGEX); + highlightedAsRegex = true; + } + else { + // If this is *likely* to be a regex, based on + // the previous token, highlight it as such. + Token t = firstToken.getLastNonCommentNonWhitespaceToken(); + if (RSyntaxUtilities.regexCanFollowInJavaScript(t)) { + addToken(TokenTypes.REGEX); + highlightedAsRegex = true; + } + } + // If it doesn't *appear* to be a regex, highlight it as + // individual tokens. + if (!highlightedAsRegex) { + int temp = zzStartRead + 1; + addToken(zzStartRead, zzStartRead, TokenTypes.OPERATOR); + zzStartRead = zzCurrentPos = zzMarkedPos = temp; + } + } + + /* Separators. */ + {JS_Separator} { addToken(TokenTypes.SEPARATOR); } + {JS_Separator2} { addToken(TokenTypes.IDENTIFIER); } + + /* Operators. */ + {JS_Operator} { addToken(TokenTypes.OPERATOR); } + + /* Numbers */ + {JS_IntegerLiteral} { addToken(TokenTypes.LITERAL_NUMBER_DECIMAL_INT); } + {JS_HexLiteral} { addToken(TokenTypes.LITERAL_NUMBER_HEXADECIMAL); } + {JS_FloatLiteral} { addToken(TokenTypes.LITERAL_NUMBER_FLOAT); } + {JS_ErrorNumberFormat} { addToken(TokenTypes.ERROR_NUMBER_FORMAT); } + + {JS_ErrorIdentifier} { addToken(TokenTypes.ERROR_IDENTIFIER); } + + /* Ended with a line not in a string or comment. */ + <> { addEndToken(INTERNAL_IN_JS); return firstToken; } + + /* Catch any other (unhandled) characters and flag them as bad. */ + . { addToken(TokenTypes.ERROR_IDENTIFIER); } + +} + + { + [^\n\\\"]+ {} + \\x{HexDigit}{2} {} + \\x { /* Invalid latin-1 character \xXX */ validJSString = false; } + \\u{HexDigit}{4} {} + \\u { /* Invalid Unicode character \\uXXXX */ validJSString = false; } + \\. { /* Skip all escaped chars. */ } + \\ { /* Line ending in '\' => continue to next line. */ + if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); + addEndToken(INTERNAL_IN_JS_STRING_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_STRING_INVALID); + } + return firstToken; + } + \" { int type = validJSString ? TokenTypes.LITERAL_STRING_DOUBLE_QUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addEndToken(INTERNAL_IN_JS); return firstToken; } +} + + { + [^\n\\\']+ {} + \\x{HexDigit}{2} {} + \\x { /* Invalid latin-1 character \xXX */ validJSString = false; } + \\u{HexDigit}{4} {} + \\u { /* Invalid Unicode character \\uXXXX */ validJSString = false; } + \\. { /* Skip all escaped chars. */ } + \\ { /* Line ending in '\' => continue to next line. */ + if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_CHAR); + addEndToken(INTERNAL_IN_JS_CHAR_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_CHAR); + addEndToken(INTERNAL_IN_JS_CHAR_INVALID); + } + return firstToken; + } + \' { int type = validJSString ? TokenTypes.LITERAL_CHAR : TokenTypes.ERROR_CHAR; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addEndToken(INTERNAL_IN_JS); return firstToken; } +} + + { + [^\n\\\$\`]+ {} + \\x{HexDigit}{2} {} + \\x { /* Invalid latin-1 character \xXX */ validJSString = false; } + \\u{HexDigit}{4} {} + \\u { /* Invalid Unicode character \\uXXXX */ validJSString = false; } + \\. { /* Skip all escaped chars. */ } + + {JS_TemplateLiteralExprStart} { + addToken(start, zzStartRead - 1, TokenTypes.LITERAL_BACKQUOTE); + start = zzMarkedPos-2; + if (varDepths==null) { + varDepths = new Stack<>(); + } + else { + varDepths.clear(); + } + varDepths.push(Boolean.TRUE); + yybegin(JS_TEMPLATE_LITERAL_EXPR); + } + "$" { /* Skip valid '$' that is not part of template literal expression start */ } + + \` { int type = validJSString ? TokenTypes.LITERAL_BACKQUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); } + + /* Line ending in '\' => continue to next line, though not necessary in template strings. */ + \\ { + if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_BACKQUOTE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); + } + return firstToken; + } + \n | + <> { + if (validJSString) { + addToken(start, zzStartRead - 1, TokenTypes.LITERAL_BACKQUOTE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID); + } + else { + addToken(start,zzStartRead - 1, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); + } + return firstToken; + } +} + + { + [^\}\$\n]+ {} + "}" { + if (!varDepths.empty()) { + varDepths.pop(); + if (varDepths.empty()) { + addToken(start,zzStartRead, TokenTypes.VARIABLE); + start = zzMarkedPos; + yybegin(JS_TEMPLATE_LITERAL); + } + } + } + {JS_TemplateLiteralExprStart} { varDepths.push(Boolean.TRUE); } + "$" {} + \n | + <> { + // TODO: This isn't right. The expression and its depth should continue to the next line. + addToken(start,zzStartRead-1, TokenTypes.VARIABLE); addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); return firstToken; + } +} + + { + // JavaScript MLC's. This state is essentially Java's MLC state. + [^hwf<\n\*]+ {} + {URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); start = zzMarkedPos; } + [hwf] {} + {EndScriptTag} { + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + int temp = zzStartRead; + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); + addToken(temp,temp+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + "<" {} + {JS_MLCEnd} { yybegin(JAVASCRIPT); addToken(start,zzStartRead+1, TokenTypes.COMMENT_MULTILINE); } + \* {} + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_IN_JS_MLC); return firstToken; } +} + + { + [^hwf<\n]+ {} + {URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.COMMENT_EOL); start = zzMarkedPos; } + [hwf] {} + {EndScriptTag} { + int temp = zzStartRead; + addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(temp,temp+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + "<" {} + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); addEndToken(INTERNAL_IN_JS); return firstToken; } + +} + + { + {EndStyleTag} { + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-6,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + {CSS_SelectorPiece} { addToken(TokenTypes.DATA_TYPE); } + {CSS_PseudoClass} { addToken(TokenTypes.RESERVED_WORD); } + ":" { /* Unknown pseudo class */ addToken(TokenTypes.DATA_TYPE); } + {CSS_AtKeyword} { addToken(TokenTypes.REGEX); } + {CSS_Id} { addToken(TokenTypes.VARIABLE); } + "{" { addToken(TokenTypes.SEPARATOR); yybegin(CSS_PROPERTY); } + [,] { addToken(TokenTypes.IDENTIFIER); } + \" { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_STRING); } + \' { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_CHAR_LITERAL); } + [+>~\^$\|=] { addToken(TokenTypes.OPERATOR); } + {CSS_Separator} { addToken(TokenTypes.SEPARATOR); } + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + {CSS_MlcStart} { start = zzMarkedPos-2; cssPrevState = zzLexicalState; yybegin(CSS_C_STYLE_COMMENT); } + . { /*System.out.println("CSS: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); } + "\n" | + <> { addEndToken(INTERNAL_CSS); return firstToken; } +} + + { + {EndStyleTag} { + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-6,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + {CSS_Property} { addToken(TokenTypes.RESERVED_WORD); } + "{" { addToken(TokenTypes.SEPARATOR); /* helps with auto-closing curlies when editing CSS */ } + "}" { addToken(TokenTypes.SEPARATOR); yybegin(CSS); } + ":" { addToken(TokenTypes.OPERATOR); yybegin(CSS_VALUE); } + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + {CSS_MlcStart} { start = zzMarkedPos-2; cssPrevState = zzLexicalState; yybegin(CSS_C_STYLE_COMMENT); } + . { /*System.out.println("css_property: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); } + "\n" | + <> { addEndToken(INTERNAL_CSS_PROPERTY); return firstToken; } +} + + { + {EndStyleTag} { + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-6,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + {CSS_Value} { addToken(TokenTypes.IDENTIFIER); } + "!important" { addToken(TokenTypes.PREPROCESSOR); } + {CSS_Function} { int temp = zzMarkedPos - 2; + addToken(zzStartRead, temp, TokenTypes.FUNCTION); + addToken(zzMarkedPos-1, zzMarkedPos-1, TokenTypes.SEPARATOR); + zzStartRead = zzCurrentPos = zzMarkedPos; + } + {CSS_Number} { addToken(TokenTypes.LITERAL_NUMBER_DECIMAL_INT); } + \" { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_STRING); } + \' { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_CHAR_LITERAL); } + ")" { /* End of a function */ addToken(TokenTypes.SEPARATOR); } + [;] { addToken(TokenTypes.OPERATOR); yybegin(CSS_PROPERTY); } + [,\.] { addToken(TokenTypes.IDENTIFIER); } + "}" { addToken(TokenTypes.SEPARATOR); yybegin(CSS); } + {Whitespace} { addToken(TokenTypes.WHITESPACE); } + {CSS_MlcStart} { start = zzMarkedPos-2; cssPrevState = zzLexicalState; yybegin(CSS_C_STYLE_COMMENT); } + . { /*System.out.println("css_value: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); } + "\n" | + <> { addEndToken(INTERNAL_CSS_VALUE); return firstToken; } +} + + { + [^\n\\\"]+ {} + \\.? { /* Skip escaped chars. */ } + \" { addToken(start,zzStartRead, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); yybegin(cssPrevState); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); addEndToken(INTERNAL_CSS_STRING - cssPrevState); return firstToken; } +} + + { + [^\n\\\']+ {} + \\.? { /* Skip escaped chars. */ } + \' { addToken(start,zzStartRead, TokenTypes.LITERAL_CHAR); yybegin(cssPrevState); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.LITERAL_CHAR); addEndToken(INTERNAL_CSS_CHAR - cssPrevState); return firstToken; } +} + + { + [^hwf\n\*]+ {} + {URL} { int temp=zzStartRead; addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); start = zzMarkedPos; } + [hwf] {} + {CSS_MlcEnd} { addToken(start,zzStartRead+1, TokenTypes.COMMENT_MULTILINE); yybegin(cssPrevState); } + \* {} + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_CSS_MLC - cssPrevState); return firstToken; } +} + + { + "}}}}" { + yybegin(hbInState, hbInLangIndex); + if (hbCurlyCount == 4) { + addToken(TokenTypes.SEPARATOR); + } + else if (hbCurlyCount == 3) { + addToken(zzStartRead, zzStartRead + 2, TokenTypes.SEPARATOR); + zzMarkedPos--; // Effectively push back the final '}' to be reread + } + // If curly count is 2, read the third curly as outside of the Handlebars expression + else { + addToken(zzStartRead, zzStartRead + 1, TokenTypes.SEPARATOR); + zzMarkedPos -= 2; // Effectively push back the final two '}' to be reread + } + start = zzMarkedPos; + } + "}}}" { + if (hbCurlyCount == 4) { + addToken(TokenTypes.IDENTIFIER); + } + else if (hbCurlyCount == 3) { + yybegin(hbInState, hbInLangIndex); + addToken(TokenTypes.SEPARATOR); + start = zzMarkedPos; + } + // If curly count is 2, read the third curly as outside of the Handlebars expression + else { + yybegin(hbInState, hbInLangIndex); + addToken(zzStartRead, zzStartRead + 1, TokenTypes.SEPARATOR); + zzMarkedPos--; // Effectively push back the final '}' to be reread + start = zzMarkedPos; + } + } + "}}" { + // If in triple-curlies, render as TokenTypes.IDENTIFIER + if (hbCurlyCount == 2) { + yybegin(hbInState, hbInLangIndex); + addToken(TokenTypes.SEPARATOR); + start = zzMarkedPos; + } + else { + addToken(TokenTypes.IDENTIFIER); + } + } + \" { start = zzMarkedPos-1; validHandlebarsString = true; yybegin(HB_STRING); } + \' { start = zzMarkedPos-1; validHandlebarsString = true; yybegin(HB_CHAR_LITERAL); } + [-]?{Digit}+([.]{Digit}+)? { addToken(TokenTypes.LITERAL_NUMBER_FLOAT); } + + "false" | + "true" { addToken(TokenTypes.LITERAL_BOOLEAN); } + "else" | + "null" | + "undefined" { addToken(TokenTypes.RESERVED_WORD); } + + [#\/](if|unless|each|with) { addToken(TokenTypes.FUNCTION); } + "lookup" | + "log" { addToken(TokenTypes.FUNCTION); } + + {HB_Identifier} { addToken(TokenTypes.IDENTIFIER); } + {HB_Operator} { addToken(TokenTypes.OPERATOR); } + {HB_Separator} { addToken(TokenTypes.SEPARATOR); } + . { /*System.out.println("HB unhandled: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); } + "\n" | + <> { addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; } +} + + { + [^\n}] {} + "}}" { addToken(start,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); yybegin(YYINITIAL, LANG_INDEX_DEFAULT); } + [}] {} + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_1); return firstToken; } +} + + { + [^\n-] {} + "--}}" { addToken(start,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); yybegin(YYINITIAL, LANG_INDEX_DEFAULT); } + [-] {} + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_2); return firstToken; } +} + + { + [^\n\\\"]+ {} + \\[\"] {} + \\ { validHandlebarsString = false; /* Skip all escaped chars. */ } + \" { int type = validHandlebarsString ? TokenTypes.LITERAL_STRING_DOUBLE_QUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(HB); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; } +} + + { + [^\n\\\']+ {} + \\[\'] {} + \\ { validHandlebarsString = false; /* Skip all escaped chars. */ } + \' { int type = validHandlebarsString ? TokenTypes.LITERAL_CHAR : TokenTypes.ERROR_CHAR; addToken(start,zzStartRead, type); yybegin(HB); } + \n | + <> { addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; } +} diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java new file mode 100644 index 000000000..20346e90a --- /dev/null +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java @@ -0,0 +1,3704 @@ +/* The following code was generated by JFlex 1.4.1 on 11/20/22, 11:19 AM */ + +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea.modes; + +import java.io.*; +import javax.swing.text.Segment; +import java.util.Stack; + +import org.fife.ui.rsyntaxtextarea.*; + + +/** + * Scanner for Handlebars. + * + * This implementation was created using + * JFlex 1.4.1; however, the generated file + * was modified for performance. Memory allocation needs to be almost + * completely removed to be competitive with the handwritten lexers (subclasses + * of AbstractTokenMaker), so this class has been modified so that + * Strings are never allocated (via yytext()), and the scanner never has to + * worry about refilling its buffer (needlessly copying chars around). + * We can achieve this because RText always scans exactly 1 line of tokens at a + * time, and hands the scanner this line as an array of characters (a Segment + * really). Since tokens contain pointers to char arrays instead of Strings + * holding their contents, there is no need for allocating new memory for + * Strings.

+ * + * The actual algorithm generated for scanning has, of course, not been + * modified.

+ * + * If you wish to regenerate this file yourself, keep in mind the following: + *

    + *
  • The generated HandlebarsTokenMaker.java file will contain two + * definitions of both zzRefill and yyreset. + * You should hand-delete the second of each definition (the ones + * generated by the lexer), as these generated methods modify the input + * buffer, which we'll never have to do.
  • + *
  • You should also change the declaration/definition of zzBuffer to NOT + * be initialized. This is a needless memory allocation for us since we + * will be pointing the array somewhere else anyway.
  • + *
  • You should NOT call yylex() on the generated scanner + * directly; rather, you should use getTokenList as you would + * with any other TokenMaker instance.
  • + *
+ * + * @author Robert Futrell + * @version 0.9 + */ + +public class HandlebarsTokenMaker extends AbstractMarkupTokenMaker { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** lexical states */ + public static final int INATTR_SINGLE_SCRIPT = 10; + public static final int HB = 27; + public static final int JS_CHAR = 16; + public static final int CSS_STRING = 22; + public static final int JS_MLC = 17; + public static final int CSS_CHAR_LITERAL = 23; + public static final int INTAG_SCRIPT = 8; + public static final int JS_TEMPLATE_LITERAL_EXPR = 26; + public static final int CSS_PROPERTY = 20; + public static final int CSS_C_STYLE_COMMENT = 24; + public static final int CSS = 19; + public static final int CSS_VALUE = 21; + public static final int COMMENT = 1; + public static final int INATTR_DOUBLE_SCRIPT = 9; + public static final int PI = 2; + public static final int JAVASCRIPT = 14; + public static final int INTAG = 4; + public static final int INTAG_CHECK_TAG_NAME = 5; + public static final int INATTR_SINGLE_STYLE = 13; + public static final int DTD = 3; + public static final int JS_EOL_COMMENT = 18; + public static final int INATTR_DOUBLE_STYLE = 12; + public static final int HB_COMMENT_2 = 31; + public static final int HB_CHAR_LITERAL = 29; + public static final int INATTR_SINGLE = 7; + public static final int HB_COMMENT_1 = 30; + public static final int JS_TEMPLATE_LITERAL = 25; + public static final int YYINITIAL = 0; + public static final int INATTR_DOUBLE = 6; + public static final int JS_STRING = 15; + public static final int HB_STRING = 28; + public static final int INTAG_STYLE = 11; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\4\1\2\1\0\1\1\1\34\22\0\1\4\1\52\1\7"+ + "\1\35\1\37\1\51\1\5\1\111\1\105\1\45\1\40\1\43\1\46"+ + "\1\32\1\44\1\11\1\26\6\126\1\30\2\25\1\54\1\6\1\10"+ + "\1\47\1\20\1\53\1\104\1\113\1\27\1\13\1\117\1\23\1\42"+ + "\1\121\1\125\1\15\1\127\1\122\1\22\1\116\1\115\1\114\1\16"+ + "\1\123\1\14\1\12\1\17\1\120\1\124\1\24\1\41\1\21\1\24"+ + "\1\110\1\36\1\110\1\50\1\31\1\107\1\72\1\103\1\67\1\71"+ + "\1\77\1\74\1\60\1\66\1\57\1\127\1\101\1\70\1\100\1\65"+ + "\1\63\1\76\1\123\1\62\1\73\1\64\1\33\1\102\1\112\1\106"+ + "\1\75\1\130\1\61\1\56\1\3\1\55\uff81\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\6\0\2\1\1\0\2\1\1\0\2\1\7\0\1\2"+ + "\12\0\2\2\1\3\1\2\1\4\1\5\1\6\1\2"+ + "\1\1\1\7\5\1\1\10\2\1\1\11\1\12\2\13"+ + "\1\14\1\15\1\16\1\17\1\13\1\20\1\21\1\22"+ + "\1\23\2\21\2\23\3\21\2\23\5\21\1\23\3\21"+ + "\1\23\1\1\1\24\2\1\1\25\1\15\1\26\1\27"+ + "\1\1\1\30\1\1\1\31\1\32\1\33\1\34\1\35"+ + "\1\36\1\37\1\17\1\2\1\40\2\17\2\2\1\17"+ + "\2\41\1\17\1\2\1\35\2\17\1\2\1\35\21\2"+ + "\1\42\1\43\2\2\1\1\1\44\1\45\1\46\1\1"+ + "\1\47\1\50\1\51\1\1\1\52\6\1\1\53\4\1"+ + "\1\54\1\55\1\56\2\54\1\57\1\54\1\60\1\61"+ + "\1\54\1\62\1\63\1\64\1\65\2\63\1\66\1\63"+ + "\1\67\1\70\1\71\1\72\1\73\1\71\2\2\1\41"+ + "\1\2\1\71\1\74\1\71\1\75\1\76\1\77\1\100"+ + "\1\101\1\102\1\1\1\103\2\1\1\104\1\105\1\106"+ + "\1\107\1\1\1\110\1\111\1\1\1\2\1\112\1\37"+ + "\1\113\1\114\1\17\1\115\10\2\1\116\1\117\1\120"+ + "\1\121\1\122\1\121\1\123\1\1\1\124\1\1\1\125"+ + "\1\1\1\5\1\6\2\126\1\127\1\130\1\131\5\0"+ + "\1\132\1\133\31\21\1\23\1\21\1\23\2\21\1\23"+ + "\44\21\1\134\1\135\3\0\1\136\1\0\1\137\1\17"+ + "\1\35\1\2\1\17\1\140\1\41\1\140\2\115\1\140"+ + "\1\141\1\140\1\2\1\142\1\2\1\142\17\2\1\142"+ + "\37\2\1\143\1\144\1\145\1\0\1\146\12\0\1\147"+ + "\1\150\15\0\1\151\1\41\5\0\1\41\1\0\1\100"+ + "\1\152\1\153\1\154\1\155\5\0\1\115\12\2\1\156"+ + "\1\0\1\157\2\126\1\0\1\160\1\161\1\162\4\0"+ + "\1\133\13\21\1\23\64\21\1\134\1\0\1\163\1\0"+ + "\1\35\1\2\1\115\1\0\2\141\1\2\1\164\23\2"+ + "\1\165\43\2\1\66\41\0\1\166\1\0\1\167\2\0"+ + "\1\115\2\2\1\167\7\2\1\0\2\126\1\170\1\0"+ + "\1\171\2\0\1\172\1\133\22\21\1\23\5\21\1\23"+ + "\12\21\1\134\1\0\1\173\1\35\10\2\1\174\6\2"+ + "\1\164\17\2\1\175\1\2\1\167\4\2\4\0\1\176"+ + "\3\0\1\177\6\0\1\66\15\0\1\200\2\0\3\2"+ + "\1\174\1\66\1\2\2\126\1\201\2\0\11\21\1\23"+ + "\12\21\1\0\1\35\7\2\1\142\6\2\1\142\6\2"+ + "\25\0\3\2\1\126\1\202\12\21\1\0\1\35\5\2"+ + "\1\203\12\2\15\0\2\2\1\204\3\21\1\0\11\2"+ + "\10\0\1\2\1\21\1\0\3\2\2\0\1\205\4\0"+ + "\1\2\1\21\1\206\1\2\1\207\1\210\6\0\1\211"; + + private static int [] zzUnpackAction() { + int [] result = new int[932]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\131\0\262\0\u010b\0\u0164\0\u01bd\0\u0216\0\u026f"+ + "\0\u02c8\0\u0321\0\u037a\0\u03d3\0\u042c\0\u0485\0\u04de\0\u0537"+ + "\0\u0590\0\u05e9\0\u0642\0\u069b\0\u06f4\0\u074d\0\u07a6\0\u07ff"+ + "\0\u0858\0\u08b1\0\u090a\0\u0963\0\u09bc\0\u0a15\0\u0a6e\0\u0ac7"+ + "\0\u0b20\0\u0b79\0\u0bd2\0\u0c2b\0\u0c84\0\u0cdd\0\u0d36\0\u0d8f"+ + "\0\u0de8\0\u0bd2\0\u0e41\0\u0e9a\0\u0ef3\0\u0f4c\0\u0fa5\0\u0bd2"+ + "\0\u0ffe\0\u1057\0\u0bd2\0\u0bd2\0\u10b0\0\u1109\0\u0bd2\0\u1162"+ + "\0\u0bd2\0\u0bd2\0\u11bb\0\u0bd2\0\u1214\0\u0bd2\0\u126d\0\u12c6"+ + "\0\u131f\0\u1378\0\u13d1\0\u142a\0\u1483\0\u14dc\0\u1535\0\u158e"+ + "\0\u15e7\0\u1640\0\u1699\0\u16f2\0\u174b\0\u17a4\0\u17fd\0\u1856"+ + "\0\u18af\0\u1214\0\u1908\0\u0bd2\0\u1961\0\u19ba\0\u0bd2\0\u1a13"+ + "\0\u0bd2\0\u0bd2\0\u1a6c\0\u0bd2\0\u1ac5\0\u0bd2\0\u0bd2\0\u0bd2"+ + "\0\u0bd2\0\u1b1e\0\u0bd2\0\u0bd2\0\u1b77\0\u0bd2\0\u0bd2\0\u1bd0"+ + "\0\u1c29\0\u1c82\0\u1cdb\0\u1d34\0\u1d8d\0\u1de6\0\u1e3f\0\u1e98"+ + "\0\u0bd2\0\u1ef1\0\u1f4a\0\u1fa3\0\u1ffc\0\u2055\0\u20ae\0\u2107"+ + "\0\u2160\0\u21b9\0\u2212\0\u226b\0\u22c4\0\u231d\0\u2376\0\u23cf"+ + "\0\u2428\0\u2481\0\u24da\0\u2533\0\u258c\0\u25e5\0\u0bd2\0\u0bd2"+ + "\0\u263e\0\u2697\0\u26f0\0\u0bd2\0\u0bd2\0\u2749\0\u27a2\0\u0bd2"+ + "\0\u2749\0\u0bd2\0\u27fb\0\u0bd2\0\u2854\0\u28ad\0\u2906\0\u295f"+ + "\0\u29b8\0\u2a11\0\u0bd2\0\u2a6a\0\u2ac3\0\u2b1c\0\u2b75\0\u0bd2"+ + "\0\u0bd2\0\u0bd2\0\u2bce\0\u2c27\0\u2c80\0\u2cd9\0\u2d32\0\u0bd2"+ + "\0\u2d8b\0\u0bd2\0\u0bd2\0\u0bd2\0\u0bd2\0\u2bce\0\u2c27\0\u2de4"+ + "\0\u2e3d\0\u0bd2\0\u0bd2\0\u0bd2\0\u0bd2\0\u0bd2\0\u2bce\0\u2e96"+ + "\0\u2eef\0\u2f48\0\u2fa1\0\u2ffa\0\u0bd2\0\u3053\0\u0bd2\0\u0bd2"+ + "\0\u0bd2\0\u30ac\0\u0bd2\0\u0bd2\0\u3105\0\u0bd2\0\u315e\0\u31b7"+ + "\0\u0bd2\0\u2749\0\u3210\0\u0bd2\0\u3269\0\u0bd2\0\u0bd2\0\u32c2"+ + "\0\u331b\0\u0bd2\0\u3374\0\u0bd2\0\u0bd2\0\u33cd\0\u3426\0\u347f"+ + "\0\u34d8\0\u3531\0\u358a\0\u35e3\0\u363c\0\u3695\0\u36ee\0\u0bd2"+ + "\0\u0bd2\0\u0bd2\0\u3747\0\u0bd2\0\u37a0\0\u0bd2\0\u0bd2\0\u0bd2"+ + "\0\u37f9\0\u0bd2\0\u3852\0\u0bd2\0\u38ab\0\u3904\0\u395d\0\u39b6"+ + "\0\u0bd2\0\u3a0f\0\u3a68\0\u3ac1\0\u3b1a\0\u3b73\0\u3bcc\0\u0bd2"+ + "\0\u3c25\0\u3c7e\0\u3cd7\0\u3d30\0\u3d89\0\u3de2\0\u3e3b\0\u3e94"+ + "\0\u3eed\0\u3f46\0\u3f9f\0\u3ff8\0\u4051\0\u40aa\0\u4103\0\u415c"+ + "\0\u41b5\0\u420e\0\u4267\0\u42c0\0\u4319\0\u4372\0\u43cb\0\u4424"+ + "\0\u447d\0\u44d6\0\u452f\0\u4588\0\u45e1\0\u463a\0\u4693\0\u46ec"+ + "\0\u4745\0\u479e\0\u47f7\0\u4850\0\u48a9\0\u4902\0\u495b\0\u49b4"+ + "\0\u4a0d\0\u4a66\0\u4abf\0\u4b18\0\u4b71\0\u4bca\0\u4c23\0\u4c7c"+ + "\0\u4cd5\0\u4d2e\0\u4d87\0\u4de0\0\u4e39\0\u4e92\0\u4eeb\0\u4f44"+ + "\0\u4f9d\0\u4ff6\0\u504f\0\u50a8\0\u5101\0\u515a\0\u51b3\0\u520c"+ + "\0\u5265\0\u52be\0\u5317\0\u5370\0\u53c9\0\u0bd2\0\u1ef1\0\u5422"+ + "\0\u547b\0\u0bd2\0\u54d4\0\u552d\0\u547b\0\u5586\0\u55df\0\u5638"+ + "\0\u5691\0\u5691\0\u56ea\0\u5691\0\u5743\0\u579c\0\u57f5\0\u584e"+ + "\0\u58a7\0\u5900\0\u5959\0\u1c82\0\u59b2\0\u5a0b\0\u5a64\0\u5abd"+ + "\0\u5b16\0\u5b6f\0\u5bc8\0\u5c21\0\u5c7a\0\u5cd3\0\u5d2c\0\u5d85"+ + "\0\u5dde\0\u5e37\0\u5e90\0\u5ee9\0\u5f42\0\u5f9b\0\u5ff4\0\u604d"+ + "\0\u60a6\0\u60ff\0\u6158\0\u61b1\0\u620a\0\u6263\0\u62bc\0\u6315"+ + "\0\u636e\0\u63c7\0\u6420\0\u6479\0\u64d2\0\u652b\0\u6584\0\u65dd"+ + "\0\u6636\0\u668f\0\u66e8\0\u6741\0\u679a\0\u67f3\0\u684c\0\u68a5"+ + "\0\u68fe\0\u6957\0\u69b0\0\u0bd2\0\u6a09\0\u6a62\0\u6abb\0\u0bd2"+ + "\0\u6b14\0\u6b6d\0\u6bc6\0\u6c1f\0\u6c78\0\u6cd1\0\u6d2a\0\u6d83"+ + "\0\u6ddc\0\u6e35\0\u0bd2\0\u6e8e\0\u6ee7\0\u6f40\0\u6f99\0\u6ff2"+ + "\0\u704b\0\u70a4\0\u70fd\0\u7156\0\u71af\0\u7208\0\u7261\0\u72ba"+ + "\0\u7313\0\u736c\0\u0bd2\0\u73c5\0\u741e\0\u7477\0\u74d0\0\u7529"+ + "\0\u2ffa\0\u7582\0\u0bd2\0\u0bd2\0\u0bd2\0\u0bd2\0\u75db\0\u7634"+ + "\0\u768d\0\u76e6\0\u773f\0\u7798\0\u77f1\0\u784a\0\u78a3\0\u78fc"+ + "\0\u7955\0\u79ae\0\u7a07\0\u7a60\0\u7ab9\0\u7b12\0\u7b6b\0\u0bd2"+ + "\0\u7bc4\0\u38ab\0\u7c1d\0\u7c76\0\u7ccf\0\u7d28\0\u7d81\0\u0bd2"+ + "\0\u7dda\0\u7e33\0\u7e8c\0\u7ee5\0\u7f3e\0\u7f97\0\u7ff0\0\u8049"+ + "\0\u80a2\0\u80fb\0\u8154\0\u81ad\0\u8206\0\u825f\0\u82b8\0\u8311"+ + "\0\u836a\0\u83c3\0\u841c\0\u8475\0\u84ce\0\u8527\0\u8580\0\u85d9"+ + "\0\u8632\0\u868b\0\u86e4\0\u873d\0\u8796\0\u87ef\0\u8848\0\u88a1"+ + "\0\u88fa\0\u8953\0\u89ac\0\u45e1\0\u8a05\0\u8a5e\0\u8ab7\0\u8b10"+ + "\0\u8b69\0\u8bc2\0\u8c1b\0\u8c74\0\u8ccd\0\u8d26\0\u8d7f\0\u8dd8"+ + "\0\u8e31\0\u8e8a\0\u8ee3\0\u158e\0\u8f3c\0\u8f95\0\u8fee\0\u9047"+ + "\0\u90a0\0\u90f9\0\u9152\0\u91ab\0\u9204\0\u925d\0\u92b6\0\u930f"+ + "\0\u9368\0\u93c1\0\u941a\0\u9473\0\u94cc\0\u9525\0\u957e\0\u95d7"+ + "\0\u9630\0\u9689\0\u96e2\0\u973b\0\u9794\0\u5691\0\u97ed\0\u9846"+ + "\0\u989f\0\u98f8\0\u9951\0\u99aa\0\u9a03\0\u9a5c\0\u9ab5\0\u9b0e"+ + "\0\u9b67\0\u9bc0\0\u9c19\0\u9c72\0\u9ccb\0\u9d24\0\u9d7d\0\u9dd6"+ + "\0\u9e2f\0\u9e88\0\u9ee1\0\u9f3a\0\u1c82\0\u9f93\0\u9fec\0\ua045"+ + "\0\ua09e\0\ua0f7\0\ua150\0\ua1a9\0\ua202\0\ua25b\0\ua2b4\0\ua30d"+ + "\0\ua366\0\ua3bf\0\ua418\0\ua471\0\ua4ca\0\ua523\0\ua57c\0\ua5d5"+ + "\0\ua62e\0\ua687\0\ua6e0\0\ua739\0\ua792\0\ua7eb\0\ua844\0\ua89d"+ + "\0\ua8f6\0\ua94f\0\ua9a8\0\uaa01\0\uaa5a\0\uaab3\0\uab0c\0\uab65"+ + "\0\u1c82\0\uabbe\0\uac17\0\uac70\0\uacc9\0\uad22\0\uad7b\0\uadd4"+ + "\0\uae2d\0\uae86\0\uaedf\0\uaf38\0\uaf91\0\uafea\0\ub043\0\ub09c"+ + "\0\ub0f5\0\ub14e\0\ub1a7\0\ub200\0\ub259\0\ub2b2\0\ub30b\0\ub364"+ + "\0\ub3bd\0\ub416\0\ub46f\0\ub4c8\0\ub521\0\ub57a\0\ub5d3\0\ub62c"+ + "\0\ub685\0\ub6de\0\ub737\0\ub790\0\u0bd2\0\ub7e9\0\ub842\0\u7798"+ + "\0\ub89b\0\ub8f4\0\u331b\0\ub94d\0\ub9a6\0\ub9ff\0\uba58\0\ubab1"+ + "\0\ubb0a\0\ubb63\0\u37f9\0\ubbbc\0\ubc15\0\u0bd2\0\ubc6e\0\u0bd2"+ + "\0\ubcc7\0\ubd20\0\ubd79\0\u10b0\0\ubdd2\0\ube2b\0\ube84\0\ubedd"+ + "\0\ubf36\0\ubf8f\0\ubfe8\0\uc041\0\uc09a\0\uc0f3\0\uc14c\0\uc1a5"+ + "\0\uc1fe\0\uc257\0\uc2b0\0\uc309\0\uc362\0\uc3bb\0\uc414\0\uc46d"+ + "\0\uc4c6\0\uc51f\0\u46ec\0\uc578\0\u88a1\0\uc5d1\0\uc62a\0\uc683"+ + "\0\uc6dc\0\uc735\0\uc78e\0\uc7e7\0\uc840\0\uc899\0\uc8f2\0\u0bd2"+ + "\0\uc94b\0\u0bd2\0\uc9a4\0\uc9fd\0\uca56\0\ucaaf\0\ucb08\0\ucb61"+ + "\0\ucbba\0\ucc13\0\ucc6c\0\u1c82\0\uccc5\0\ucd1e\0\ucd77\0\ucdd0"+ + "\0\uce29\0\uce82\0\u1c82\0\ucedb\0\ucf34\0\ucf8d\0\ucfe6\0\ud03f"+ + "\0\ud098\0\ud0f1\0\ud14a\0\ud1a3\0\ud1fc\0\ud255\0\ud2ae\0\ud307"+ + "\0\ud360\0\ud3b9\0\u1c82\0\ud412\0\u1c82\0\ud46b\0\ud4c4\0\ud51d"+ + "\0\ud576\0\u6a62\0\ud5cf\0\ud628\0\ud681\0\ud6da\0\ud733\0\ud78c"+ + "\0\ud7e5\0\ud83e\0\ud897\0\ud8f0\0\ud949\0\ud9a2\0\ud9fb\0\uda54"+ + "\0\u0bd2\0\udaad\0\udb06\0\udb5f\0\udbb8\0\udc11\0\udc6a\0\udcc3"+ + "\0\udd1c\0\udd75\0\uddce\0\ude27\0\ude80\0\uded9\0\u0bd2\0\udf32"+ + "\0\udf8b\0\udfe4\0\ue03d\0\ue096\0\u331b\0\u331b\0\ue0ef\0\ue148"+ + "\0\ue1a1\0\u0bd2\0\ue1fa\0\ubd79\0\ue253\0\ue2ac\0\ue305\0\ue35e"+ + "\0\ue3b7\0\ue410\0\ue469\0\ue4c2\0\ue51b\0\ue574\0\ue574\0\ue5cd"+ + "\0\ue626\0\ue67f\0\ue6d8\0\ue731\0\ue78a\0\ue7e3\0\ue83c\0\ue895"+ + "\0\ue8ee\0\ue947\0\ue9a0\0\ue9f9\0\uea52\0\ueaab\0\ueb04\0\ueb5d"+ + "\0\uebb6\0\u9bc0\0\uec0f\0\uec68\0\uecc1\0\ued1a\0\ued73\0\uedcc"+ + "\0\uee25\0\uee7e\0\ueed7\0\uef30\0\uef89\0\uefe2\0\uf03b\0\uf094"+ + "\0\uf0ed\0\ud6da\0\uf146\0\uf19f\0\ud83e\0\uf1f8\0\uf251\0\uf2aa"+ + "\0\uf303\0\uf35c\0\uf3b5\0\uf40e\0\uf467\0\uf4c0\0\uf519\0\uf572"+ + "\0\uf5cb\0\uf624\0\uf67d\0\uf6d6\0\uf72f\0\uf788\0\uf7e1\0\uf83a"+ + "\0\u395d\0\uf893\0\uf8ec\0\uf945\0\uf99e\0\uf9f7\0\ufa50\0\ufaa9"+ + "\0\ufb02\0\ufb5b\0\ufbb4\0\ufc0d\0\ufc66\0\ufcbf\0\ufd18\0\ufd71"+ + "\0\ufdca\0\ufe23\0\u1c82\0\ufe7c\0\ufed5\0\uff2e\0\uff87\0\uffe0"+ + "\1\71\1\222\1\353\1\u0144\1\u019d\1\u01f6\1\u024f\1\u02a8"+ + "\1\u0301\1\u035a\1\u03b3\1\u040c\1\u0465\1\u04be\1\u0517\1\u0570"+ + "\1\u05c9\1\u0622\1\u067b\1\u06d4\0\u395d\1\u072d\1\u0786\1\u07df"+ + "\1\u0838\1\u0891\1\u08ea\1\u0943\1\u099c\1\u09f5\1\u0a4e\1\u0aa7"+ + "\1\u0b00\1\u0b59\1\u0bb2\1\u0c0b\1\u0c64\1\u0cbd\1\u0d16\1\u0d6f"+ + "\1\u0dc8\1\u0e21\1\u0e7a\1\u0ed3\1\u0f2c\1\u0f85\1\u0fde\1\u1037"+ + "\1\u1090\1\u10e9\0\u0bd2\1\u1142\1\u119b\1\u11f4\1\u124d\1\u12a6"+ + "\1\u12ff\0\u0bd2\1\u1358\0\u0bd2\0\u0bd2\1\u13b1\1\u140a\1\u1463"+ + "\1\u14bc\1\u1515\1\u156e\0\u0bd2"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[932]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\41\1\42\1\43\1\44\1\45\1\46\2\41\1\47"+ + "\50\41\1\50\47\41\2\51\1\52\27\51\1\53\33\51"+ + "\1\54\5\51\1\55\15\51\1\56\16\51\2\57\1\60"+ + "\50\57\1\61\55\57\2\62\1\63\15\62\1\64\110\62"+ + "\1\65\1\66\1\0\1\65\1\45\2\65\1\67\1\65"+ + "\1\70\6\65\1\71\26\65\1\72\11\65\1\73\27\65"+ + "\1\74\17\65\2\75\1\0\1\75\1\76\2\75\1\76"+ + "\1\75\1\76\1\77\1\100\1\101\1\102\1\103\1\104"+ + "\1\76\1\75\1\105\1\106\3\75\1\107\3\75\1\110"+ + "\6\75\1\111\4\75\1\76\7\75\1\102\2\75\1\101"+ + "\1\112\1\104\1\113\1\114\1\100\1\105\1\115\1\116"+ + "\1\77\1\111\1\75\1\103\1\106\1\117\1\120\1\121"+ + "\1\107\5\75\1\76\1\75\1\116\1\112\1\113\1\117"+ + "\1\115\1\110\1\75\1\120\1\122\1\121\1\114\3\75"+ + "\7\123\1\124\51\123\1\125\47\123\61\126\1\125\27\126"+ + "\1\124\17\126\1\65\1\66\1\0\1\65\1\45\2\65"+ + "\1\127\1\65\1\130\6\65\1\131\26\65\1\72\41\65"+ + "\1\132\17\65\7\133\1\134\121\133\111\135\1\134\17\135"+ + "\1\65\1\66\1\0\1\65\1\45\2\65\1\136\1\65"+ + "\1\130\6\65\1\137\26\65\1\72\41\65\1\140\17\65"+ + "\7\133\1\141\121\133\111\135\1\141\17\135\1\142\1\45"+ + "\1\143\1\144\1\45\1\145\1\146\1\147\1\150\1\151"+ + "\3\152\1\153\2\152\1\154\4\152\1\155\1\156\1\152"+ + "\1\155\1\152\1\157\1\160\1\161\2\142\1\152\1\162"+ + "\2\152\1\163\1\164\1\144\1\146\4\162\3\72\1\165"+ + "\1\166\1\167\1\144\1\170\1\171\1\172\1\173\1\152"+ + "\1\174\1\175\1\176\1\177\1\200\1\201\1\202\1\203"+ + "\1\204\2\152\1\205\1\206\1\142\1\144\1\152\1\207"+ + "\1\144\1\210\1\211\2\152\1\212\10\152\1\155\2\152"+ + "\2\213\1\214\4\213\1\215\26\213\1\216\72\213\2\217"+ + "\1\220\33\217\1\221\52\217\1\222\17\217\2\223\1\224"+ + "\5\223\1\225\27\223\1\226\25\223\1\227\5\223\1\230"+ + "\15\223\1\231\16\223\2\232\1\233\5\232\1\234\55\232"+ + "\1\235\5\232\1\236\15\232\1\237\16\232\1\240\1\45"+ + "\1\241\1\240\1\45\1\240\1\144\1\242\1\243\1\244"+ + "\6\245\1\72\4\245\2\240\1\245\1\240\3\245\1\240"+ + "\1\246\1\240\1\72\3\245\1\72\1\245\1\144\1\146"+ + "\2\72\3\240\1\247\2\72\2\245\1\250\22\245\1\251"+ + "\1\144\1\245\1\240\1\144\1\252\14\245\1\240\2\245"+ + "\1\253\1\45\1\254\1\255\1\45\3\253\1\256\1\257"+ + "\6\260\1\253\4\260\2\253\1\260\1\253\3\260\4\253"+ + "\1\261\2\260\11\253\1\262\2\253\2\260\1\263\22\260"+ + "\2\253\1\260\3\253\14\260\1\253\2\260\1\264\1\45"+ + "\1\265\1\255\1\45\1\264\1\266\1\242\1\267\1\270"+ + "\6\271\1\264\4\271\2\272\1\271\1\272\1\271\1\273"+ + "\1\271\1\264\1\274\1\271\2\264\2\271\1\264\1\146"+ + "\1\275\1\146\3\264\1\276\4\264\2\271\1\264\22\271"+ + "\1\264\1\277\1\271\2\264\1\252\14\271\1\272\2\271"+ + "\2\213\1\300\4\213\1\301\26\213\1\302\72\213\2\217"+ + "\1\303\33\217\1\302\52\217\1\304\17\217\2\305\1\306"+ + "\35\305\1\307\25\305\1\227\5\305\1\230\15\305\1\231"+ + "\16\305\2\310\1\311\33\310\1\312\1\313\47\310\1\314"+ + "\21\310\2\315\1\316\1\317\33\315\1\320\71\315\2\321"+ + "\1\322\1\323\1\324\2\72\1\325\1\72\1\326\6\321"+ + "\1\72\4\321\2\327\1\321\1\327\1\321\1\330\1\331"+ + "\1\321\1\332\2\321\1\72\2\321\2\72\1\144\5\72"+ + "\2\321\2\72\2\321\1\144\2\321\1\333\1\334\2\321"+ + "\1\335\3\321\1\336\2\321\1\337\4\321\1\72\1\144"+ + "\1\321\1\72\1\144\1\340\14\321\1\327\2\321\2\213"+ + "\1\341\4\213\1\342\26\213\1\343\72\213\2\217\1\344"+ + "\33\217\1\345\52\217\1\346\17\217\2\347\1\350\1\351"+ + "\127\347\1\352\27\347\1\353\76\347\2\41\4\0\2\41"+ + "\1\0\50\41\1\0\50\41\1\42\2\0\1\45\1\0"+ + "\2\41\1\0\50\41\1\0\47\41\134\0\1\44\126\0"+ + "\1\45\2\0\1\45\124\0\4\46\1\0\1\46\1\354"+ + "\122\46\11\0\1\355\1\356\5\357\1\0\10\357\2\0"+ + "\1\357\5\0\2\357\7\0\1\360\1\361\3\0\2\357"+ + "\1\0\11\357\1\356\10\357\2\0\1\357\3\0\17\357"+ + "\61\0\1\362\47\0\2\51\1\0\27\51\1\0\33\51"+ + "\1\0\5\51\1\0\15\51\1\0\16\51\32\0\1\363"+ + "\162\0\1\364\123\0\1\365\4\0\1\366\156\0\1\367"+ + "\16\0\2\57\1\0\50\57\1\0\55\57\20\0\1\370"+ + "\110\0\2\62\1\0\15\62\1\0\110\62\2\65\1\0"+ + "\1\65\1\0\2\65\1\0\1\65\1\0\6\65\1\0"+ + "\26\65\1\0\41\65\1\0\20\65\1\66\1\0\1\65"+ + "\1\45\2\65\1\0\1\65\1\0\6\65\1\0\26\65"+ + "\1\0\41\65\1\0\17\65\20\0\1\71\110\0\2\65"+ + "\1\0\1\65\1\0\2\65\1\0\1\65\1\0\6\65"+ + "\1\0\26\65\1\0\11\65\1\371\27\65\1\0\17\65"+ + "\2\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\41\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\1\75\1\372"+ + "\2\75\1\373\1\374\1\0\2\75\1\375\7\75\1\376"+ + "\13\75\1\0\13\75\1\377\1\374\2\75\1\372\2\75"+ + "\1\u0100\3\75\1\373\1\375\1\u0101\10\75\1\0\1\75"+ + "\1\u0100\1\377\1\75\1\u0101\1\75\1\376\12\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\3\75\1\u0102"+ + "\2\75\1\0\2\75\1\u0103\23\75\1\0\7\75\1\u0102"+ + "\3\75\1\u0104\6\75\1\u0105\4\75\1\u0103\11\75\1\0"+ + "\1\75\1\u0105\1\u0104\16\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\12\75\1\u0106\13\75"+ + "\1\0\41\75\1\0\6\75\1\u0106\12\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\1\u0107\5\75\1\0"+ + "\1\75\1\u0108\17\75\1\u0109\4\75\1\0\15\75\1\u010a"+ + "\2\75\1\u0108\2\75\1\u0107\1\u0109\3\75\1\u010b\10\75"+ + "\1\0\3\75\1\u010a\1\u010b\14\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\2\75\1\u010c\3\75\1\0"+ + "\1\75\1\u010d\24\75\1\0\12\75\1\u010c\5\75\1\u010d"+ + "\1\75\1\u010e\16\75\1\0\1\75\1\u010e\17\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\2\75\1\122"+ + "\1\u010f\1\75\1\122\1\0\2\75\1\u0110\3\75\1\u0111"+ + "\12\75\1\u0112\4\75\1\0\7\75\1\u010f\2\75\1\122"+ + "\1\75\1\122\1\75\1\u0113\2\75\1\122\1\u0114\1\75"+ + "\1\u0112\2\75\1\u0110\3\75\1\u0111\5\75\1\0\1\75"+ + "\1\u0114\3\75\1\122\5\75\1\u0113\5\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\3\75\1\u0115\2\75"+ + "\1\0\2\75\1\u0116\23\75\1\0\7\75\1\u0115\12\75"+ + "\1\u0117\4\75\1\u0116\11\75\1\0\1\75\1\u0117\17\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\30\75\1\u0118\1\75\1\u0119\6\75"+ + "\1\0\4\75\1\u0118\5\75\1\u0119\6\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\2\75\1\122\1\u010b"+ + "\2\75\1\0\1\75\1\u011a\10\75\1\u011b\13\75\1\0"+ + "\7\75\1\u010b\1\u011c\1\75\1\122\1\u011d\4\75\1\u011a"+ + "\1\u011e\1\u011f\16\75\1\0\1\75\1\u011f\1\u011d\2\75"+ + "\1\u011e\1\u011b\1\u011c\11\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\1\75\1\122\24\75"+ + "\1\0\20\75\1\122\20\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\2\75\1\u0120\1\u0121"+ + "\2\75\1\0\26\75\1\0\7\75\1\u0121\2\75\1\u0120"+ + "\1\u0122\25\75\1\0\2\75\1\u0122\16\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\4\75\1\u0123\1\75"+ + "\1\0\1\75\1\122\4\75\1\u0124\3\75\1\u0125\13\75"+ + "\1\0\20\75\1\122\5\75\1\u0123\4\75\1\u0124\5\75"+ + "\1\0\6\75\1\u0125\12\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\2\75\1\u0126\23\75"+ + "\1\0\13\75\1\u0127\6\75\1\u0128\4\75\1\u0126\11\75"+ + "\1\0\1\75\1\u0128\1\u0127\16\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\2\75\1\122\2\75\1\u0129"+ + "\1\0\2\75\1\u012a\23\75\1\0\12\75\1\122\1\75"+ + "\1\u0129\12\75\1\u012a\11\75\1\0\14\75\1\122\4\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\3\75"+ + "\1\u012b\1\75\1\122\1\0\1\75\1\122\1\u012c\16\75"+ + "\1\u012d\4\75\1\0\7\75\1\u012b\4\75\1\122\3\75"+ + "\2\122\1\u012e\1\75\1\u012d\2\75\1\u012c\11\75\1\0"+ + "\1\75\1\u012e\3\75\1\122\13\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\1\u012f\1\u0130\1\u0131\1\75"+ + "\1\u0132\1\75\1\0\6\75\1\u0133\3\75\1\u0134\13\75"+ + "\1\0\12\75\1\u0131\4\75\1\u0130\1\75\1\u0135\1\75"+ + "\1\u012f\2\75\1\u0132\4\75\1\u0133\5\75\1\0\5\75"+ + "\1\u0135\1\u0134\12\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u0136\7\75\1\u0137"+ + "\13\75\1\0\22\75\1\u0138\4\75\1\u0136\11\75\1\0"+ + "\1\75\1\u0138\4\75\1\u0137\12\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\2\75\1\u0139"+ + "\3\75\1\u013a\17\75\1\0\27\75\1\u0139\3\75\1\u013a"+ + "\5\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\3\75\1\u013b\2\75\1\0\26\75\1\0"+ + "\7\75\1\u013b\12\75\1\u013c\16\75\1\0\1\75\1\u013c"+ + "\15\75\7\123\1\0\51\123\1\0\47\123\61\0\1\u013d"+ + "\47\0\61\126\1\0\27\126\1\0\17\126\20\0\1\u013e"+ + "\110\0\7\133\1\0\121\133\111\135\1\0\17\135\1\142"+ + "\11\0\6\142\1\0\11\142\1\0\1\142\1\0\3\142"+ + "\1\0\2\142\14\0\2\142\1\0\23\142\1\0\1\142"+ + "\3\0\17\142\5\0\1\72\41\0\1\72\71\0\1\u013f"+ + "\1\u0140\35\0\1\72\61\0\11\u0141\1\u0142\24\u0141\1\u0143"+ + "\1\u0141\1\u0144\6\u0141\1\u0145\61\u0141\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\22\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u0147\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\20\0\1\u0148\26\0\1\72\61\0"+ + "\1\u0149\11\0\6\u0149\1\0\1\u0149\1\u014a\1\u014b\1\u0149"+ + "\2\155\1\u0149\1\155\1\u0149\1\0\1\u0149\1\0\3\u0149"+ + "\1\0\1\u0149\1\u014c\1\0\1\u014d\12\0\2\u0149\1\0"+ + "\6\u0149\1\u014a\1\u014c\2\u0149\1\u014c\2\u0149\1\u014b\5\u0149"+ + "\1\0\1\u0149\3\0\5\u0149\1\u014c\6\u0149\1\155\3\u0149"+ + "\11\0\6\u0149\1\0\1\u0149\1\u014a\1\u014b\1\u0149\1\u014e"+ + "\1\u014f\1\u0149\1\u014f\1\u0149\1\0\1\u0149\1\0\3\u0149"+ + "\1\0\1\u0150\1\u014c\1\0\1\u014d\12\0\2\u0149\1\0"+ + "\6\u0149\1\u014a\1\u014c\2\u0149\1\u014c\2\u0149\1\u014b\5\u0149"+ + "\1\0\1\u0150\3\0\5\u0149\1\u014c\6\u0149\1\u014f\2\u0149"+ + "\32\0\1\72\14\0\1\72\61\0\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\3\152\1\u0151\16\152"+ + "\1\142\1\0\1\152\3\0\17\152\47\0\1\72\124\0"+ + "\1\72\3\0\1\72\106\0\2\u014d\1\0\1\u014d\75\0"+ + "\1\u014d\51\0\1\72\6\0\1\72\52\0\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\3\152\1\u0152"+ + "\5\152\1\u0153\1\u0154\3\152\1\u0155\3\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\1\152\1\u0156\20\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\15\152\1\u0157\4\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\12\152\1\u0154\7\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\1\u0158\3\152\1\u0159\6\152\1\u015a"+ + "\6\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\u015b\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\10\152\1\u015c"+ + "\4\152\1\u015d\4\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\1\152\1\u015e\2\152\1\u015f\1\152\1\u0160\1\152\1\u0161"+ + "\11\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\1\152\1\u0162"+ + "\13\152\1\u0163\4\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\1\152\1\u0164\13\152\1\u0165\4\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\11\152\1\u0166\7\152\1\u0167\1\142\1\0"+ + "\1\152\3\0\1\u0168\16\152\1\142\11\0\6\152\1\0"+ + "\11\152\1\0\1\u0169\1\0\1\142\1\u0146\1\152\1\0"+ + "\2\152\14\0\2\152\1\0\2\152\1\u016a\1\152\1\u016b"+ + "\6\152\1\u016c\6\152\1\142\1\0\1\152\3\0\1\u016d"+ + "\16\152\1\142\11\0\6\152\1\0\11\152\1\0\1\u016e"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u016f"+ + "\1\152\1\0\1\152\1\u0170\4\152\1\u0171\1\152\1\u0172"+ + "\11\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\1\u0173\1\152\1\0\22\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\u0174\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\1\u0175\7\152\1\u0176"+ + "\11\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\3\152\1\u0177"+ + "\2\152\1\u0178\1\152\1\u0179\1\u017a\6\152\1\u017b\1\152"+ + "\1\142\1\0\1\u017c\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\1\152\1\u017d\6\152"+ + "\1\u0170\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\u017e"+ + "\1\u017f\11\152\1\u0180\6\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u0181"+ + "\1\152\1\0\4\152\1\u0182\15\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\10\152\1\u0183\11\152\1\142\1\0\1\152"+ + "\3\0\17\152\2\213\1\0\4\213\1\0\26\213\1\0"+ + "\72\213\2\u0184\1\0\30\u0184\1\u0185\52\u0184\1\u0186\22\u0184"+ + "\2\217\1\0\33\217\1\0\52\217\1\0\17\217\2\223"+ + "\1\0\5\223\1\0\27\223\1\0\25\223\1\0\5\223"+ + "\1\0\15\223\1\0\16\223\11\0\1\u0187\130\0\1\u0188"+ + "\203\0\1\u0189\123\0\1\u018a\4\0\1\u018b\156\0\1\u018c"+ + "\16\0\2\232\1\0\5\232\1\0\55\232\1\0\5\232"+ + "\1\0\15\232\1\0\16\232\11\0\1\u018d\203\0\1\u018e"+ + "\123\0\1\u018f\4\0\1\u0190\156\0\1\u0191\27\0\1\u0192"+ + "\157\0\1\u0193\102\0\6\245\1\0\13\245\5\0\2\245"+ + "\1\0\1\245\12\0\2\245\1\0\22\245\2\0\1\245"+ + "\3\0\17\245\12\0\6\u0194\1\0\4\u0194\2\0\1\u0194"+ + "\1\0\3\u0194\4\0\3\u0194\1\0\1\u0194\12\0\2\u0194"+ + "\1\0\22\u0194\2\0\1\u0194\3\0\14\u0194\1\0\2\u0194"+ + "\54\0\1\u0195\5\0\1\u0196\1\u0197\1\u0198\1\u0199\1\u019a"+ + "\1\u019b\1\u019c\1\u019d\1\u019e\1\0\1\u019f\2\0\1\u01a0"+ + "\2\0\1\u01a1\40\0\6\u01a2\1\0\4\u01a2\2\0\1\u01a2"+ + "\1\0\3\u01a2\4\0\3\u01a2\1\0\1\u01a2\12\0\2\u01a2"+ + "\1\0\22\u01a2\2\0\1\u01a2\3\0\14\u01a2\1\0\2\u01a2"+ + "\12\0\6\260\1\0\13\260\5\0\2\260\14\0\2\260"+ + "\1\0\22\260\2\0\1\260\3\0\17\260\12\0\6\260"+ + "\1\0\4\260\2\0\1\260\1\0\3\260\5\0\2\260"+ + "\14\0\2\260\1\0\22\260\2\0\1\260\3\0\14\260"+ + "\1\0\2\260\11\0\7\271\1\0\4\271\2\0\1\271"+ + "\1\0\3\271\2\0\1\271\1\0\1\u0193\2\271\14\0"+ + "\2\271\1\0\22\271\1\0\1\277\1\271\3\0\14\271"+ + "\1\0\2\271\11\0\7\271\1\0\4\271\2\0\1\271"+ + "\1\0\3\271\2\0\1\271\2\0\2\271\14\0\2\271"+ + "\1\0\22\271\1\0\1\277\1\271\3\0\14\271\1\0"+ + "\2\271\25\0\2\272\1\0\1\272\13\0\1\272\4\0"+ + "\1\u01a3\5\0\1\u01a4\7\0\1\u01a5\3\0\1\u01a3\2\0"+ + "\1\u01a6\1\u01a7\1\u01a8\25\0\1\272\13\0\7\271\1\0"+ + "\4\271\2\272\1\271\1\272\3\271\2\0\1\271\2\0"+ + "\2\271\14\0\2\271\1\0\22\271\1\0\1\277\1\271"+ + "\3\0\14\271\1\272\2\271\13\0\1\u01a9\7\0\1\u01a9"+ + "\1\0\4\u01a9\11\0\1\u01a9\24\0\1\u01a9\1\0\2\u01a9"+ + "\1\0\1\u01a9\2\0\1\u01a9\3\0\1\u01a9\7\0\1\u01a9"+ + "\3\0\1\u01a9\6\0\1\u01a9\61\0\1\u01aa\51\0\2\u01ab"+ + "\1\0\126\u01ab\2\305\1\0\35\305\1\0\25\305\1\0"+ + "\5\305\1\0\15\305\1\0\16\305\11\0\1\u01ac\117\0"+ + "\2\310\1\0\33\310\2\0\47\310\1\0\21\310\61\0"+ + "\1\u01ad\47\0\2\315\2\0\33\315\1\0\71\315\61\0"+ + "\1\u01ae\47\0\2\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\22\321\2\0"+ + "\1\321\3\0\17\321\3\0\1\u01af\160\0\1\u01b0\23\0"+ + "\1\u01b1\17\0\1\u01b2\12\0\1\u01b3\43\0\2\327\1\0"+ + "\1\327\13\0\1\u01b4\61\0\1\327\2\0\2\321\10\0"+ + "\6\321\1\0\4\321\2\u01b5\1\321\1\u01b5\7\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\22\321\2\0"+ + "\1\321\3\0\14\321\1\u01b5\4\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\3\321\1\u01b6\16\321\2\0\1\321\3\0\21\321\10\0"+ + "\6\321\1\0\12\321\1\u01b7\4\321\1\0\2\321\10\0"+ + "\2\321\2\0\1\u01b8\1\321\1\0\15\321\1\u01b9\4\321"+ + "\2\0\1\321\3\0\1\u01ba\20\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\1\u01bb\21\321\2\0\1\321\3\0\21\321\10\0\6\321"+ + "\1\0\12\321\1\u01bc\4\321\1\0\2\321\10\0\2\321"+ + "\2\0\2\321\1\0\22\321\2\0\1\321\3\0\21\321"+ + "\10\0\6\321\1\0\17\321\1\0\2\321\10\0\2\321"+ + "\2\0\2\321\1\0\1\321\1\u01bd\20\321\2\0\1\321"+ + "\3\0\21\321\10\0\6\321\1\0\17\321\1\0\2\321"+ + "\10\0\2\321\2\0\2\321\1\0\10\321\1\u01be\11\321"+ + "\2\0\1\321\3\0\21\321\10\0\6\321\1\0\17\321"+ + "\1\0\2\321\10\0\2\321\2\0\2\321\1\0\6\321"+ + "\1\u01bf\13\321\2\0\1\321\3\0\17\321\7\0\1\347"+ + "\232\0\1\347\22\0\1\u01c0\157\0\1\u01c1\110\0\6\u01c2"+ + "\1\0\10\u01c2\2\0\1\u01c2\5\0\2\u01c2\14\0\2\u01c2"+ + "\1\0\22\u01c2\2\0\1\u01c2\3\0\17\u01c2\12\0\1\357"+ + "\1\u01c3\3\357\1\u01c4\1\0\10\357\2\0\1\357\5\0"+ + "\2\357\14\0\2\357\1\0\2\357\1\u01c4\2\357\1\u01c3"+ + "\14\357\2\0\1\357\3\0\17\357\12\0\6\357\1\0"+ + "\10\357\2\0\1\357\5\0\2\357\14\0\2\357\1\0"+ + "\22\357\2\0\1\357\3\0\17\357\32\0\1\u01c5\150\0"+ + "\1\u01c6\6\0\1\u01c7\67\0\1\u01c8\174\0\1\u01c9\134\0"+ + "\1\u01ca\136\0\1\u01cb\144\0\1\u01cc\16\0\2\65\1\0"+ + "\1\65\1\0\2\65\1\0\1\65\1\0\6\65\1\0"+ + "\26\65\1\0\11\65\1\u01cd\27\65\1\0\17\65\2\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\2\75"+ + "\1\u01ce\3\75\1\0\26\75\1\0\12\75\1\u01ce\26\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\22\75\1\u01cf\16\75"+ + "\1\0\1\75\1\u01cf\17\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\2\75\1\u01d0\3\75\1\0\1\u0106"+ + "\25\75\1\0\12\75\1\u01d0\12\75\1\u0106\13\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\1\75\1\u01d1\1\u01d2\3\75\1\0\1\75\1\u01d3\24\75"+ + "\1\0\12\75\1\u01d2\4\75\1\u01d1\1\u01d3\20\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\4\75\1\122\1\75\1\0\6\75\1\122\17\75\1\0"+ + "\26\75\1\122\4\75\1\122\5\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\12\75\1\u01d4\13\75\1\0\41\75\1\0\6\75\1\u01d4"+ + "\12\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\30\75\1\u01d5\10\75\1\0"+ + "\4\75\1\u01d5\14\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\22\75\1\u01d6"+ + "\16\75\1\0\1\75\1\u01d6\17\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\5\75\1\u01d7\1\0\26\75"+ + "\1\0\14\75\1\u01d7\24\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\15\75\1\u01d8\23\75\1\0\3\75\1\u01d8\15\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\1\75\1\u01d9\24\75\1\0\20\75\1\u01d9\1\u01d7"+ + "\6\75\1\u01da\10\75\1\0\4\75\1\u01da\1\u01d7\13\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\4\75"+ + "\1\u01d1\1\75\1\0\26\75\1\0\15\75\1\u01db\10\75"+ + "\1\u01d1\12\75\1\0\3\75\1\u01db\15\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\1\75"+ + "\1\u01d7\24\75\1\0\20\75\1\u01d7\20\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\3\75"+ + "\1\u01dc\2\75\1\0\26\75\1\0\7\75\1\u01dc\31\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\22\75\1\u01dd\16\75"+ + "\1\0\1\75\1\u01dd\17\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\2\75\1\u01de\3\75\1\0\26\75"+ + "\1\0\12\75\1\u01de\26\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\1\122\3\75\1\u01df"+ + "\1\75\1\0\26\75\1\0\23\75\1\122\2\75\1\u01df"+ + "\12\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\10\75\1\122"+ + "\30\75\1\0\7\75\1\122\11\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\2\75\1\122"+ + "\23\75\1\0\13\75\1\u01e0\13\75\1\122\11\75\1\0"+ + "\2\75\1\u01e0\16\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\22\75\1\u01e1"+ + "\16\75\1\0\1\75\1\u01e1\17\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\2\75\1\u01e2\3\75\1\0"+ + "\26\75\1\0\12\75\1\u01e2\26\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\5\75\1\u0106"+ + "\1\0\26\75\1\0\14\75\1\u0106\13\75\1\u01d7\10\75"+ + "\1\0\4\75\1\u01d7\14\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\20\75\1\u01e3\5\75"+ + "\1\0\36\75\1\u01e3\2\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\13\75\1\u011d\25\75\1\0\2\75\1\u011d\16\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\13\75\1\u01e4\25\75\1\0\2\75"+ + "\1\u01e4\16\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\2\75\1\u01e5\23\75\1\0\27\75"+ + "\1\u01e5\11\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\6\75\1\u0106\17\75"+ + "\1\0\33\75\1\u0106\5\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\15\75\1\u01e6\23\75\1\0\3\75\1\u01e6\15\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\10\75\1\u01e7\30\75\1\0\7\75"+ + "\1\u01e7\11\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\1\u01e8\5\75\1\u01e9\17\75\1\0"+ + "\25\75\1\u01e8\5\75\1\u01e9\5\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\6\75\1\u01ea\17\75\1\0\33\75\1\u01ea\5\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\2\75\1\u01eb\23\75\1\0\27\75\1\u01eb"+ + "\11\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\3\75\1\u01ec\2\75\1\0\26\75\1\0"+ + "\7\75\1\u01ec\3\75\1\u01ed\25\75\1\0\2\75\1\u01ed"+ + "\16\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\5\75\1\u01ee\1\0\26\75\1\0\14\75\1\u01ee\24\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\1\u01ef\5\75\1\0\26\75\1\0\23\75\1\u01ef"+ + "\15\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\21\75\1\u01f0"+ + "\17\75\1\0\5\75\1\u01f0\13\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\13\75\1\122\25\75\1\0\2\75\1\122\16\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\1\u01f1\5\75"+ + "\1\0\26\75\1\0\23\75\1\u01f1\15\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\22\75\1\u01f2\16\75\1\0\1\75"+ + "\1\u01f2\17\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\2\75\1\u01f3\23\75\1\0\10\75"+ + "\1\u01f4\16\75\1\u01f3\11\75\1\0\7\75\1\u01f4\11\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\2\75"+ + "\1\u01f5\3\75\1\0\26\75\1\0\12\75\1\u01f5\1\u01d8"+ + "\1\75\1\u01f6\23\75\1\0\2\75\1\u01d8\1\u01f6\15\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\5\75"+ + "\1\u01f7\1\0\26\75\1\0\14\75\1\u01f7\24\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\41\75\1\0\15\75\1\u01d3"+ + "\3\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\5\75\1\u01f8\1\0\26\75\1\0\14\75\1\u01f8\24\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\1\u01f6\5\75\1\0\26\75\1\0\23\75\1\u01f6"+ + "\15\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\1\u01f9\5\75\1\0\1\75\1\u0108\1\u01fa"+ + "\3\75\1\u013c\12\75\1\u01fb\4\75\1\0\20\75\1\u0108"+ + "\2\75\1\u01f9\1\u01fb\2\75\1\u01fa\3\75\1\u013c\5\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\32\75\1\122\6\75"+ + "\1\0\12\75\1\122\6\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\26\75\1\0\30\75"+ + "\1\u01fc\10\75\1\0\4\75\1\u01fc\14\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\22\75\1\u01fd\16\75\1\0\1\75\1\u01fd\17\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\2\75"+ + "\1\122\3\75\1\0\26\75\1\0\12\75\1\122\7\75"+ + "\1\u01fe\7\75\1\122\6\75\1\0\1\75\1\u01fe\10\75"+ + "\1\122\6\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\5\75\1\u01ff\1\0\1\75\1\122\24\75\1\0"+ + "\14\75\1\u01ff\3\75\1\122\20\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\15\75\1\122\23\75\1\0\3\75\1\122"+ + "\15\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\5\75\1\u0200\1\0\26\75\1\0\14\75\1\u0200\24\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\3\75\1\u0201\2\75\1\0\26\75\1\0\7\75"+ + "\1\u0201\31\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\2\75\1\u0202\3\75\1\0\26\75"+ + "\1\0\12\75\1\u0202\26\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\5\75\1\u0203\1\0"+ + "\2\75\1\u0204\23\75\1\0\14\75\1\u0203\12\75\1\u0204"+ + "\11\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\4\75\1\u0205\1\75\1\0\26\75\1\0"+ + "\26\75\1\u0205\12\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\6\75\1\u013c"+ + "\17\75\1\0\33\75\1\u013c\5\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\21\75\1\u0206\17\75\1\0\5\75\1\u0206"+ + "\13\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\21\75\1\u0207\17\75\1\0"+ + "\5\75\1\u0207\13\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\5\75\1\u0208\1\0\26\75\1\0\14\75"+ + "\1\u0208\1\u0209\23\75\1\0\3\75\1\u0209\15\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\1\75\1\u020a\24\75\1\0\20\75\1\u020a\20\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\2\75\1\u020b\1\75\1\122\1\75\1\0\26\75\1\0"+ + "\12\75\1\u020b\13\75\1\122\12\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\1\u020c\25\75\1\0\25\75\1\u020c\13\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\21\75\1\122\17\75\1\0\5\75"+ + "\1\122\13\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\21\75\1\u020d\17\75"+ + "\1\0\5\75\1\u020d\13\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\2\75\1\122\3\75\1\0\26\75"+ + "\1\0\12\75\1\122\26\75\1\0\17\75\61\0\1\u020e"+ + "\61\0\1\u020f\60\0\1\u020f\35\0\11\u0141\1\u0210\24\u0141"+ + "\1\u0143\74\u0141\1\0\126\u0141\40\0\1\u0211\70\0\1\142"+ + "\11\0\6\142\1\0\11\142\1\0\1\u0212\1\0\3\142"+ + "\1\0\2\142\14\0\2\142\1\0\23\142\1\0\1\142"+ + "\3\0\20\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\12\152\1\u0213\7\152\1\142\1\0\1\152\3\0"+ + "\17\152\20\0\1\162\26\0\1\72\61\0\1\u0149\11\0"+ + "\6\u0149\1\0\11\u0149\1\0\1\u0149\1\0\3\u0149\1\0"+ + "\2\u0149\14\0\2\u0149\1\0\23\u0149\1\0\1\u0149\3\0"+ + "\20\u0149\11\0\6\u0149\1\0\4\u0149\2\u0214\1\u0149\1\u0214"+ + "\1\u0149\1\u0215\1\u0149\1\0\3\u0149\1\0\2\u0149\1\u0215"+ + "\13\0\2\u0149\1\0\23\u0149\1\0\1\u0149\3\0\14\u0149"+ + "\1\u0214\3\u0149\11\0\6\u0149\1\0\2\u0149\1\u014b\1\u0149"+ + "\2\u014d\1\u0149\1\u014d\1\u0149\1\0\1\u0149\1\0\3\u0149"+ + "\1\0\1\u0149\1\u014c\14\0\2\u0149\1\0\7\u0149\1\u014c"+ + "\2\u0149\1\u014c\2\u0149\1\u014b\5\u0149\1\0\1\u0149\3\0"+ + "\5\u0149\1\u014c\6\u0149\1\u014d\3\u0149\11\0\6\u0149\1\0"+ + "\2\u0149\1\u014b\1\u0149\2\u014e\1\u0149\1\u014e\1\u0149\1\0"+ + "\1\u0149\1\0\3\u0149\1\0\1\u0149\1\u014c\1\0\1\u014d"+ + "\12\0\2\u0149\1\0\7\u0149\1\u014c\2\u0149\1\u014c\2\u0149"+ + "\1\u014b\5\u0149\1\0\1\u0149\3\0\5\u0149\1\u014c\6\u0149"+ + "\1\u014e\3\u0149\11\0\6\u0149\1\0\1\u0149\1\u0216\1\u014b"+ + "\1\u0149\1\u014e\1\u014f\1\u0149\1\u014f\1\u0149\1\0\1\u0149"+ + "\1\0\3\u0149\1\0\1\u0149\1\u014c\1\0\1\u014d\12\0"+ + "\2\u0149\1\0\6\u0149\1\u0216\1\u014c\2\u0149\1\u014c\2\u0149"+ + "\1\u014b\5\u0149\1\0\1\u0149\3\0\5\u0149\1\u014c\6\u0149"+ + "\1\u014f\3\u0149\11\0\1\u0149\1\u0217\4\u0149\1\0\2\u0149"+ + "\1\u0217\1\u0149\4\u0217\1\u0149\1\0\1\u0149\1\0\3\u0149"+ + "\1\0\1\u0149\1\u0217\14\0\2\u0149\1\0\5\u0149\1\u0217"+ + "\1\u0149\2\u0217\1\u0149\1\u0217\2\u0149\1\u0217\3\u0149\1\u0217"+ + "\1\u0149\1\0\1\u0149\3\0\1\u0149\1\u0217\3\u0149\1\u0217"+ + "\6\u0149\1\u0217\2\u0149\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\15\152\1\u0218\4\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\2\152\1\u0219\6\152\1\u021a\10\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\1\152\1\u021b\14\0\2\152\1\0\22\152\1\142"+ + "\1\0\1\152\3\0\3\152\1\u021c\13\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\14\152\1\u021d"+ + "\5\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\2\152\1\u021e"+ + "\17\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\2\152\1\u021f"+ + "\17\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\u0220\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\10\152\1\u0221"+ + "\2\152\1\u0154\6\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u0222\1\152"+ + "\1\0\1\u0223\21\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\14\152\1\u0224\5\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\6\152\1\u0225\13\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\2\152\1\u0226\17\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\22\152\1\142\1\0\1\152\3\0\1\u0154\16\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\3\152"+ + "\1\u0227\16\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\10\152"+ + "\1\u0228\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\10\152"+ + "\1\u0229\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\2\152"+ + "\1\u022a\6\152\1\u022b\10\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\3\152\1\u022c\16\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u022d\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\u022e"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\6\152"+ + "\1\u022f\3\152\1\u0230\6\152\1\u0231\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\13\152\1\u0232\6\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\11\152\1\u0233\10\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\10\152\1\u0234\11\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\14\152\1\u0235\5\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\10\152\1\u0236\11\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\1\152\1\u0237\20\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\3\152\1\u0238\16\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\1\u0239\1\152\1\0\22\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\3\152\1\u023a\16\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\3\152\1\u023b\16\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\1\u0154\21\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\1\152\1\u023c\20\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\6\152\1\u023d\13\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\15\152\1\u023e\4\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\21\152\1\u023f\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\1\u0240\1\152\1\0"+ + "\1\152\1\u0241\20\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\1\u0242\4\152\1\u0243\14\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\u0244"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\11\152"+ + "\1\u022b\10\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\5\152"+ + "\1\u0245\14\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\5\152"+ + "\1\u0246\14\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\10\152"+ + "\1\u0247\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\2\152"+ + "\1\u0248\11\152\1\u0249\5\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u024a"+ + "\1\152\1\0\6\152\1\u024b\13\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\15\152\1\u024c\4\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\1\152\1\u024d\20\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\2\152\1\u024e\17\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\2\152\1\u024f\17\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\1\u0250\1\152\1\0\22\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\3\152\1\u0251"+ + "\13\152\13\0\1\u0252\7\0\1\u0252\1\0\4\u0252\11\0"+ + "\1\u0252\24\0\1\u0252\1\0\2\u0252\1\0\1\u0252\2\0"+ + "\1\u0252\3\0\1\u0252\7\0\1\u0252\3\0\1\u0252\6\0"+ + "\1\u0252\15\0\1\u0253\7\0\1\u0253\1\0\4\u0253\11\0"+ + "\1\u0253\24\0\1\u0253\1\0\2\u0253\1\0\1\u0253\2\0"+ + "\1\u0253\3\0\1\u0253\7\0\1\u0253\3\0\1\u0253\6\0"+ + "\1\u0253\14\0\1\u0254\60\0\1\u0254\121\0\1\u0255\134\0"+ + "\1\u0256\136\0\1\u0257\144\0\1\u0258\30\0\1\u0259\60\0"+ + "\1\u0259\121\0\1\u025a\134\0\1\u025b\136\0\1\u025c\144\0"+ + "\1\u025d\30\0\1\u025e\60\0\1\u025e\47\0\6\u0194\1\0"+ + "\13\u0194\5\0\2\u0194\1\0\1\u0194\12\0\2\u0194\1\0"+ + "\22\u0194\2\0\1\u0194\3\0\17\u0194\72\0\1\u025f\1\0"+ + "\1\u0260\6\0\1\u0261\110\0\1\u0262\132\0\1\u0263\135\0"+ + "\1\u0264\121\0\1\u0265\1\u0266\127\0\1\u0267\133\0\1\u0268"+ + "\121\0\1\u0269\12\0\1\u026a\115\0\1\u026b\140\0\1\u026c"+ + "\120\0\1\u026d\3\0\1\u026e\132\0\1\u026f\12\0\1\u0270"+ + "\107\0\1\u0271\63\0\6\u01a2\1\0\13\u01a2\5\0\2\u01a2"+ + "\1\0\1\u01a2\12\0\2\u01a2\1\0\22\u01a2\2\0\1\u01a2"+ + "\3\0\17\u01a2\65\0\1\u01a3\143\0\1\u01a3\114\0\1\u01a3"+ + "\2\0\1\u01a3\16\0\1\u01a3\122\0\1\u01a3\5\0\1\u01a3"+ + "\115\0\1\u01a3\4\0\1\u01a3\130\0\1\u0272\33\0\1\u0273"+ + "\212\0\1\u0274\137\0\1\u0275\126\0\1\u0276\115\0\1\u0277"+ + "\76\0\2\u0278\1\0\1\u0278\75\0\1\u0278\2\0\2\321"+ + "\10\0\6\321\1\0\4\321\2\u01b5\1\321\1\u01b5\7\321"+ + "\1\0\2\321\1\0\1\u01b4\6\0\2\321\2\0\2\321"+ + "\1\0\22\321\2\0\1\321\3\0\14\321\1\u01b5\4\321"+ + "\10\0\6\321\1\0\17\321\1\0\2\321\10\0\2\321"+ + "\2\0\2\321\1\0\7\321\1\u0279\12\321\2\0\1\321"+ + "\3\0\21\321\10\0\6\321\1\0\17\321\1\0\2\321"+ + "\10\0\2\321\2\0\2\321\1\0\3\321\1\u027a\16\321"+ + "\2\0\1\321\3\0\21\321\10\0\6\321\1\0\17\321"+ + "\1\0\2\321\10\0\2\321\2\0\2\321\1\0\12\321"+ + "\1\u027b\7\321\2\0\1\321\3\0\21\321\10\0\6\321"+ + "\1\0\17\321\1\0\2\321\10\0\2\321\2\0\2\321"+ + "\1\0\10\321\1\u027c\11\321\2\0\1\321\3\0\21\321"+ + "\10\0\6\321\1\0\17\321\1\0\2\321\10\0\2\321"+ + "\2\0\1\u027d\1\321\1\0\22\321\2\0\1\321\3\0"+ + "\21\321\10\0\6\321\1\0\12\321\1\u027e\4\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\22\321\2\0"+ + "\1\321\3\0\21\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\6\321\1\u027f"+ + "\13\321\2\0\1\321\3\0\21\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\1\321\1\u027b"+ + "\1\0\1\321\1\u0280\20\321\2\0\1\321\3\0\21\321"+ + "\10\0\6\321\1\0\17\321\1\0\2\321\10\0\2\321"+ + "\2\0\2\321\1\0\6\321\1\u0281\13\321\2\0\1\321"+ + "\3\0\21\321\10\0\6\321\1\0\17\321\1\0\2\321"+ + "\10\0\2\321\2\0\2\321\1\0\11\321\1\u0282\10\321"+ + "\2\0\1\321\3\0\17\321\3\0\1\u0283\137\0\2\357"+ + "\1\u0284\3\357\1\0\10\357\2\0\1\357\5\0\2\357"+ + "\14\0\2\357\1\0\1\u0284\21\357\2\0\1\357\3\0"+ + "\17\357\12\0\6\357\1\0\1\u0285\7\357\2\0\1\357"+ + "\5\0\2\357\14\0\2\357\1\0\13\357\1\u0285\6\357"+ + "\2\0\1\357\3\0\17\357\32\0\1\u0286\130\0\1\u0287"+ + "\157\0\1\u0288\145\0\1\u0289\131\0\1\u01cb\105\0\1\u028a"+ + "\120\0\1\u028b\64\0\2\65\1\0\1\65\1\0\2\65"+ + "\1\0\1\65\1\0\6\65\1\0\26\65\1\0\11\65"+ + "\1\u028c\27\65\1\0\17\65\2\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\3\75\1\u028d\2\75\1\0"+ + "\26\75\1\0\7\75\1\u028d\31\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\1\75\1\u01e8"+ + "\4\75\1\0\26\75\1\0\15\75\1\122\1\75\1\u01e8"+ + "\21\75\1\0\3\75\1\122\15\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\3\75\1\u028e\2\75\1\0"+ + "\26\75\1\0\7\75\1\u028e\3\75\1\u028f\25\75\1\0"+ + "\2\75\1\u028f\16\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\5\75\1\u0290\1\0\26\75\1\0\14\75"+ + "\1\u0290\24\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\26\75\1\0\32\75"+ + "\1\u01e8\6\75\1\0\12\75\1\u01e8\6\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\2\75"+ + "\1\u0291\23\75\1\0\27\75\1\u0291\11\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\2\75"+ + "\1\u0292\3\75\1\0\26\75\1\0\12\75\1\u0292\26\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\4\75\1\122\1\75\1\0\26\75\1\0\26\75"+ + "\1\122\12\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\1\75\1\u01fc\24\75"+ + "\1\0\20\75\1\u01fc\20\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\2\75"+ + "\1\122\23\75\1\0\27\75\1\122\11\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\5\75"+ + "\1\u01e8\1\0\26\75\1\0\14\75\1\u01e8\24\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\10\75\1\u0293\30\75\1\0"+ + "\7\75\1\u0293\11\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\30\75\1\u0294"+ + "\10\75\1\0\4\75\1\u0294\14\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\32\75\1\u0295\6\75\1\0\12\75\1\u0295\6\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\15\75\1\u0296\23\75\1\0\3\75\1\u0296"+ + "\15\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\1\u01e8\25\75\1\0\25\75\1\u01e8\13\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\22\75\1\u0297\16\75"+ + "\1\0\1\75\1\u0297\17\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\12\75\1\u01f6\13\75"+ + "\1\0\41\75\1\0\6\75\1\u01f6\12\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\10\75\1\u0207\30\75\1\0\7\75\1\u0207\11\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\3\75"+ + "\1\u0298\2\75\1\0\26\75\1\0\7\75\1\u0298\31\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\22\75\1\u01f5\16\75"+ + "\1\0\1\75\1\u01f5\17\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\5\75\1\u0299\1\0\26\75\1\0"+ + "\14\75\1\u0299\24\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\13\75\1\u01f6\25\75\1\0\2\75\1\u01f6\16\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\22\75\1\u013a\16\75\1\0\1\75\1\u013a"+ + "\17\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\31\75\1\122\7\75\1\0"+ + "\10\75\1\122\10\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u029a\23\75\1\0"+ + "\27\75\1\u029a\11\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\2\75\1\u013c"+ + "\23\75\1\0\27\75\1\u013c\11\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\2\75\1\u01fc\23\75\1\0\27\75\1\u01fc\11\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\2\75\1\u013a\23\75\1\0\27\75\1\u013a"+ + "\11\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\15\75\1\u029b"+ + "\23\75\1\0\3\75\1\u029b\15\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\1\75\1\u029c\4\75\1\0"+ + "\26\75\1\0\17\75\1\u029c\21\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\5\75\1\u029d"+ + "\1\0\26\75\1\0\14\75\1\u029d\24\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\13\75\1\u029e\25\75\1\0\2\75"+ + "\1\u029e\16\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\1\122\25\75\1\0\25\75\1\122"+ + "\13\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u029f\23\75\1\0"+ + "\27\75\1\u029f\11\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\30\75\1\u02a0\10\75\1\0\4\75\1\u02a0\14\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\1\75\1\u02a1\24\75\1\0\20\75\1\u02a1\20\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\12\75\1\u02a2\13\75\1\0\41\75\1\0"+ + "\6\75\1\u02a2\12\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\30\75\1\122"+ + "\10\75\1\0\4\75\1\122\14\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\5\75\1\122\1\0\26\75"+ + "\1\0\14\75\1\122\24\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\3\75\1\u029d\2\75"+ + "\1\0\26\75\1\0\7\75\1\u029d\1\u0293\30\75\1\0"+ + "\7\75\1\u0293\11\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\4\75\1\u01df\1\75\1\0\26\75\1\0"+ + "\26\75\1\u01df\12\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\1\75\1\372\4\75\1\0"+ + "\26\75\1\0\17\75\1\372\21\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\30\75\1\u02a3\10\75\1\0\4\75\1\u02a3"+ + "\14\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\2\75\1\u02a4\3\75\1\0\26\75\1\0\12\75\1\u02a4"+ + "\26\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\21\75\1\u02a5"+ + "\17\75\1\0\5\75\1\u02a5\13\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\1\75\1\u02a6"+ + "\24\75\1\0\20\75\1\u02a6\20\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\22\75\1\u02a7\16\75\1\0\1\75\1\u02a7"+ + "\17\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\22\75\1\u02a8\16\75\1\0"+ + "\1\75\1\u02a8\17\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\21\75\1\u01d7"+ + "\17\75\1\0\5\75\1\u01d7\13\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\13\75\1\u02a9\25\75\1\0\2\75\1\u02a9\16\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\3\75\1\u02aa"+ + "\2\75\1\0\26\75\1\0\7\75\1\u02aa\31\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\22\75\1\122\16\75\1\0"+ + "\1\75\1\122\17\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\1\75\1\u02ab\24\75\1\0"+ + "\20\75\1\u02ab\20\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\3\75\1\u011e\2\75\1\0"+ + "\26\75\1\0\7\75\1\u011e\31\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\2\75\1\u02ac"+ + "\3\75\1\0\26\75\1\0\12\75\1\u02ac\26\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\2\75\1\u013c\23\75\1\0\22\75\1\122"+ + "\4\75\1\u013c\11\75\1\0\1\75\1\122\17\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\12\75\1\122\13\75\1\0\41\75\1\0\6\75\1\122"+ + "\12\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\5\75\1\u02ad\1\0\26\75\1\0\14\75\1\u02ad\24\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\31\75\1\122\7\75"+ + "\1\0\10\75\1\122\1\u02ae\7\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\10\75\1\u02af\30\75\1\0\7\75\1\u02af\11\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\2\75\1\u011e\23\75\1\0\27\75\1\u011e\11\75\1\0"+ + "\17\75\61\0\1\u02b0\62\0\1\u02b1\53\0\1\u02b1\120\0"+ + "\2\u0210\17\0\1\u0210\41\0\1\u02b2\117\0\1\142\11\0"+ + "\1\142\1\u02b3\4\142\1\0\2\142\1\u02b3\1\142\4\u02b3"+ + "\1\142\1\0\1\142\1\0\3\142\1\0\1\142\1\u02b3"+ + "\14\0\2\142\1\0\5\142\1\u02b3\1\142\2\u02b3\1\142"+ + "\1\u02b3\2\142\1\u02b3\3\142\1\u02b3\1\142\1\0\1\142"+ + "\3\0\1\142\1\u02b3\3\142\1\u02b3\6\142\1\u02b3\3\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\1\u02b4\1\152\1\0"+ + "\22\152\1\142\1\0\1\152\3\0\17\152\1\u0149\11\0"+ + "\6\u0149\1\0\4\u0149\2\u0214\1\u0149\1\u0214\1\u0149\1\0"+ + "\1\u0149\1\0\3\u0149\1\0\1\u0149\1\u014c\14\0\2\u0149"+ + "\1\0\7\u0149\1\u014c\2\u0149\1\u014c\10\u0149\1\0\1\u0149"+ + "\3\0\5\u0149\1\u014c\6\u0149\1\u0214\2\u0149\25\0\2\u0214"+ + "\1\0\1\u0214\75\0\1\u0214\2\0\1\u0149\11\0\1\u0149"+ + "\1\u0217\4\u0149\1\0\1\u0149\1\u0216\1\u0217\1\u0149\4\u0217"+ + "\1\u0149\1\0\1\u0149\1\0\3\u0149\1\0\1\u0149\1\u0217"+ + "\14\0\2\u0149\1\0\5\u0149\1\u0217\1\u0216\2\u0217\1\u0149"+ + "\1\u0217\2\u0149\1\u0217\3\u0149\1\u0217\1\u0149\1\0\1\u0149"+ + "\3\0\1\u0149\1\u0217\3\u0149\1\u0217\6\u0149\1\u0217\2\u0149"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\11\152\1\u017a\10\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\15\152\1\u02b5\4\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\2\152\1\u02b6\17\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u02b7\1\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\10\152"+ + "\1\u02b8\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\152"+ + "\1\u02b9\4\152\1\u02ba\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\1\152\1\u0154\20\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\u02bb"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\15\152"+ + "\1\u02bc\4\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\3\152"+ + "\1\u02bd\16\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\11\152"+ + "\1\u0154\10\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\152"+ + "\1\u02be\20\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\15\152"+ + "\1\u02bf\4\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\6\152"+ + "\1\u0154\13\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\1\u02c0\1\152\1\0"+ + "\22\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\2\152\1\u02c1"+ + "\6\152\1\u02c2\10\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\1\u02c3\21\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\11\152"+ + "\1\u0222\10\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\5\152"+ + "\1\u024f\14\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\15\152"+ + "\1\u0154\4\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\1\152\1\u02c3\1\0"+ + "\22\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\21\152\1\u02c4"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u02c5\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\10\152\1\u02c6\11\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\u02c7\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\22\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u02c8\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\2\152\1\u02c9\17\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\1\u02c2\1\152\1\0\22\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\15\152\1\u0170\4\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\2\152\1\u02ca\17\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\1\u02cb\21\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\5\152\1\u02cc\14\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u022a\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\5\152\1\u02cd\14\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u02ce\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u02cb\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\11\152\1\u0220\10\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\6\152\1\u024a\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\6\152\1\u02ca\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\20\152\1\u02cf\1\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u02d0\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\11\152\1\u02d1\10\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\17\152\1\u02d2\2\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\16\152\1\u0154\3\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\4\152\1\u02d3\15\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u02d4\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\6\152\1\u02d5\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\15\152\1\u02d6\4\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\1\152\1\u02b9\20\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\7\152\1\u0154\12\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u02d7\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u02d8\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\6\152\1\u02d9\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\15\152\1\u02c3\4\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\4\152\1\u0154\15\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\6\152\1\u022b\13\152\1\142\1\0\1\152\3\0"+ + "\17\152\13\0\1\u02da\7\0\1\u02da\1\0\4\u02da\11\0"+ + "\1\u02da\24\0\1\u02da\1\0\2\u02da\1\0\1\u02da\2\0"+ + "\1\u02da\3\0\1\u02da\7\0\1\u02da\3\0\1\u02da\6\0"+ + "\1\u02da\15\0\1\347\7\0\1\347\1\0\4\347\11\0"+ + "\1\347\24\0\1\347\1\0\2\347\1\0\1\347\2\0"+ + "\1\347\3\0\1\347\7\0\1\347\3\0\1\347\6\0"+ + "\1\347\15\0\1\u02db\53\0\1\u02db\137\0\1\u02dc\131\0"+ + "\1\u0257\105\0\1\u02dd\120\0\1\u02de\77\0\1\u02df\53\0"+ + "\1\u02df\137\0\1\u02e0\131\0\1\u025c\105\0\1\u02e1\120\0"+ + "\1\u02e2\103\0\1\u02e3\44\0\1\u02e3\140\0\1\u02e4\113\0"+ + "\1\u02e5\150\0\1\u02e6\114\0\1\u0265\135\0\1\u02e7\122\0"+ + "\1\u02e8\132\0\1\u02e9\132\0\1\u02ea\144\0\1\u02eb\125\0"+ + "\1\u02ec\116\0\1\u02ed\130\0\1\u02ee\5\0\1\u02ef\130\0"+ + "\1\u026f\121\0\1\u02f0\126\0\1\u02f1\135\0\1\u02f2\133\0"+ + "\1\u02f3\134\0\1\u02f4\125\0\1\u02f5\133\0\1\u02f6\35\0"+ + "\1\u02f7\215\0\1\u02f8\127\0\1\u02f9\125\0\1\u02f9\44\0"+ + "\2\321\10\0\6\321\1\0\17\321\1\0\2\321\10\0"+ + "\2\321\2\0\2\321\1\0\15\321\1\u02fa\4\321\2\0"+ + "\1\321\3\0\21\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\6\321\1\u02fb"+ + "\13\321\2\0\1\321\3\0\21\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\5\321\1\u02fc\14\321\2\0\1\321\3\0\21\321\10\0"+ + "\6\321\1\0\17\321\1\0\2\321\10\0\2\321\2\0"+ + "\2\321\1\0\2\321\1\u02fc\17\321\2\0\1\321\3\0"+ + "\21\321\10\0\6\321\1\0\17\321\1\0\2\321\10\0"+ + "\2\321\2\0\2\321\1\0\15\321\1\u02fd\4\321\2\0"+ + "\1\321\3\0\21\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\6\321\1\u02fe"+ + "\13\321\2\0\1\321\3\0\21\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\17\321\1\u02ff\2\321\2\0\1\321\3\0\21\321\10\0"+ + "\6\321\1\0\17\321\1\0\2\321\10\0\2\321\2\0"+ + "\2\321\1\0\11\321\1\u027e\10\321\2\0\1\321\3\0"+ + "\21\321\10\0\6\321\1\0\17\321\1\0\2\321\10\0"+ + "\2\321\2\0\2\321\1\0\15\321\1\u02fe\4\321\2\0"+ + "\1\321\3\0\17\321\12\0\3\357\1\u0300\2\357\1\0"+ + "\10\357\2\0\1\357\5\0\2\357\14\0\1\u0300\1\357"+ + "\1\0\22\357\2\0\1\357\3\0\17\357\12\0\6\357"+ + "\1\0\1\357\1\u0301\6\357\2\0\1\357\5\0\2\357"+ + "\14\0\2\357\1\0\6\357\1\u0301\13\357\2\0\1\357"+ + "\3\0\17\357\32\0\1\u0302\152\0\1\u028a\16\0\1\u01cb"+ + "\46\0\1\u0303\124\0\2\u0304\2\0\7\u028b\1\0\10\u028b"+ + "\2\u0304\1\u028b\1\0\1\u0304\1\0\1\u028b\1\u0304\2\u028b"+ + "\5\u0304\1\0\5\u0304\1\0\2\u028b\1\0\22\u028b\2\u0304"+ + "\1\u028b\1\0\2\u0304\17\u028b\2\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\4\75\1\u01f6\1\75\1\0"+ + "\26\75\1\0\26\75\1\u01f6\12\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\31\75\1\u01d7\7\75\1\0\10\75\1\u01d7"+ + "\10\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\15\75\1\u010b\23\75\1\0"+ + "\3\75\1\u010b\15\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\3\75\1\u029d\2\75\1\0\26\75\1\0"+ + "\7\75\1\u029d\31\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\1\75\1\u01f6\4\75\1\0"+ + "\26\75\1\0\17\75\1\u01f6\21\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\1\75\1\u01d7"+ + "\4\75\1\0\26\75\1\0\17\75\1\u01d7\21\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\2\75\1\u0305\3\75\1\0\26\75\1\0\12\75\1\u0305"+ + "\26\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u0306\23\75\1\0"+ + "\22\75\1\u029a\4\75\1\u0306\11\75\1\0\1\75\1\u029a"+ + "\17\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\22\75\1\u0307\16\75\1\0"+ + "\1\75\1\u0307\17\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\21\75\1\u0308"+ + "\17\75\1\0\5\75\1\u0308\13\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\30\75\1\u01d7\10\75\1\0\4\75\1\u01d7\14\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\15\75\1\u0309\23\75\1\0\3\75\1\u0309"+ + "\15\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\22\75\1\u030a\16\75\1\0"+ + "\1\75\1\u030a\17\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\15\75\1\u013a"+ + "\23\75\1\0\3\75\1\u013a\15\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\5\75\1\u030b\1\0\26\75"+ + "\1\0\14\75\1\u030b\24\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\31\75\1\u030c\7\75\1\0\10\75\1\u030c\10\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\13\75\1\u012d\25\75\1\0\2\75"+ + "\1\u012d\16\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\12\75\1\u029a\13\75\1\0\41\75"+ + "\1\0\6\75\1\u029a\12\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\21\75\1\u030d\4\75"+ + "\1\0\24\75\1\u030d\14\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\2\75"+ + "\1\u030e\23\75\1\0\27\75\1\u030e\11\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\26\75\1\0\21\75\1\u030f\17\75\1\0\5\75"+ + "\1\u030f\13\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\2\75\1\u01d7\3\75\1\0\26\75\1\0\12\75"+ + "\1\u01d7\26\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\26\75\1\0\22\75"+ + "\1\u0310\16\75\1\0\1\75\1\u0310\17\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\6\75\1\0\26\75"+ + "\1\0\13\75\1\u010b\25\75\1\0\2\75\1\u010b\16\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\3\75"+ + "\1\u0311\2\75\1\0\26\75\1\0\7\75\1\u0311\31\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\5\75\1\u0312\1\0\1\75\1\u0313\24\75\1\0"+ + "\10\75\1\u0314\3\75\1\u0312\3\75\1\u0313\20\75\1\0"+ + "\7\75\1\u0314\11\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\26\75\1\0\15\75\1\u0315"+ + "\23\75\1\0\3\75\1\u0315\15\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\1\75\1\u0106\4\75\1\0"+ + "\26\75\1\0\17\75\1\u0106\21\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\2\75\1\u01f6\23\75\1\0\27\75\1\u01f6\11\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\2\75\1\u0316\23\75\1\0\27\75\1\u0316"+ + "\11\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\3\75\1\u0317\2\75\1\0\26\75\1\0"+ + "\7\75\1\u0317\31\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\12\75\1\u0318"+ + "\13\75\1\0\41\75\1\0\6\75\1\u0318\12\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\2\75\1\u012d\23\75\1\0\27\75\1\u012d\11\75\1\0"+ + "\17\75\14\0\1\u0319\45\0\1\u0319\46\0\1\142\11\0"+ + "\1\142\1\u031a\4\142\1\0\2\142\1\u031a\1\142\4\u031a"+ + "\1\142\1\0\1\142\1\0\3\142\1\0\1\142\1\u031a"+ + "\14\0\2\142\1\0\5\142\1\u031a\1\142\2\u031a\1\142"+ + "\1\u031a\2\142\1\u031a\3\142\1\u031a\1\142\1\0\1\142"+ + "\3\0\1\142\1\u031a\3\142\1\u031a\6\142\1\u031a\3\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\3\152"+ + "\1\u031b\16\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\u031c"+ + "\21\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\10\152\1\u031d"+ + "\11\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\3\152\1\u031e"+ + "\16\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\22\152\1\142"+ + "\1\0\1\152\3\0\3\152\1\u02d5\13\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\2\152\1\0\1\u02c2\21\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u031f\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\1\u0320\21\152\1\142"+ + "\1\0\1\152\3\0\17\152\1\142\11\0\6\152\1\0"+ + "\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0"+ + "\2\152\14\0\2\152\1\0\11\152\1\u0321\10\152\1\142"+ + "\1\0\1\152\3\0\17\152\1\142\11\0\6\152\1\0"+ + "\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0"+ + "\2\152\14\0\2\152\1\0\22\152\1\142\1\0\1\152"+ + "\3\0\1\u0322\16\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\1\152\1\171\20\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\20\152\1\u022b\1\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\1\u0323\1\152\1\0\22\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\2\152\1\u0154\17\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\6\152\1\u024e\13\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\2\152\1\u022b\17\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\u0324\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\22\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\1\152\1\u0325"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\5\152"+ + "\1\u0154\14\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\u0326"+ + "\21\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\1\u02c8\1\152\1\0\22\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\2\152\1\u02c3\17\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\4\152\1\u0327\15\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\2\152\1\u0328\17\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\6\152\1\u0329\13\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\10\152\1\u02c5\11\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u032a\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u032b\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\10\152\1\u032c\11\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\14\152\1\u032d\5\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\3\152\1\u032e\16\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\2\152\1\u0182\17\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\17\152\1\u0154\2\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u032f\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\14\0\1\u0330\45\0"+ + "\1\u0330\122\0\1\u02dd\16\0\1\u0257\46\0\1\u0331\124\0"+ + "\2\u0332\2\0\7\u02de\1\0\10\u02de\2\u0332\1\u02de\1\0"+ + "\1\u0332\1\0\1\u02de\1\u0332\2\u02de\5\u0332\1\0\5\u0332"+ + "\1\0\2\u02de\1\0\22\u02de\2\u0332\1\u02de\1\0\2\u0332"+ + "\17\u02de\14\0\1\u0333\45\0\1\u0333\122\0\1\u02e1\16\0"+ + "\1\u025c\46\0\1\u0334\124\0\2\u0335\2\0\7\u02e2\1\0"+ + "\10\u02e2\2\u0335\1\u02e2\1\0\1\u0335\1\0\1\u02e2\1\u0335"+ + "\2\u02e2\5\u0335\1\0\5\u0335\1\0\2\u02e2\1\0\22\u02e2"+ + "\2\u0335\1\u02e2\1\0\2\u0335\17\u02e2\21\0\1\u0336\53\0"+ + "\1\u0336\117\0\1\u02eb\126\0\1\u0337\142\0\1\u0338\131\0"+ + "\1\u0339\113\0\1\u033a\102\0\1\u033b\175\0\1\u033c\120\0"+ + "\1\u033d\142\0\1\u02e9\107\0\1\u02e9\134\0\1\u0339\123\0"+ + "\1\u033e\144\0\1\u02ef\70\0\1\u033f\200\0\1\u0340\111\0"+ + "\1\u0341\123\0\1\u0342\134\0\1\u0343\144\0\1\u0344\117\0"+ + "\1\u0275\42\0\2\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\12\321\1\u0345"+ + "\7\321\2\0\1\321\3\0\21\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\15\321\1\u0346\4\321\2\0\1\321\3\0\21\321\10\0"+ + "\6\321\1\0\17\321\1\0\2\321\10\0\2\321\2\0"+ + "\2\321\1\0\4\321\1\u027b\15\321\2\0\1\321\3\0"+ + "\21\321\10\0\6\321\1\0\12\321\1\u0347\4\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\22\321\2\0"+ + "\1\321\3\0\17\321\12\0\4\357\1\u0348\1\357\1\0"+ + "\10\357\2\0\1\357\5\0\2\357\14\0\2\357\1\0"+ + "\14\357\1\u0348\5\357\2\0\1\357\3\0\17\357\12\0"+ + "\6\357\1\0\2\357\1\u0349\5\357\2\0\1\357\5\0"+ + "\2\357\14\0\2\357\1\0\15\357\1\u0349\4\357\2\0"+ + "\1\357\3\0\17\357\11\0\1\u028b\117\0\2\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\13\75\1\u034a\25\75\1\0\2\75\1\u034a"+ + "\16\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\15\75\1\u01f6\23\75\1\0"+ + "\3\75\1\u01f6\15\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\1\122\5\75\1\0\26\75\1\0\23\75"+ + "\1\122\15\75\1\0\21\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\2\75\1\u034b\23\75"+ + "\1\0\27\75\1\u034b\11\75\1\0\21\75\1\0\1\75"+ + "\1\0\2\75\1\0\1\75\1\0\5\75\1\u034c\1\0"+ + "\26\75\1\0\14\75\1\u034c\24\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\2\75\1\u034d"+ + "\3\75\1\0\26\75\1\0\12\75\1\u034d\26\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\1\u034e\5\75\1\0\26\75\1\0\23\75\1\u034e\15\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\41\75\1\0\11\75"+ + "\1\u034f\7\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\13\75\1\u0306\25\75"+ + "\1\0\2\75\1\u0306\16\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\1\u02ab\5\75\1\0\26\75\1\0"+ + "\23\75\1\u02ab\15\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\30\75\1\u0350\10\75\1\0\4\75\1\u0350\14\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\1\75\1\u0307\24\75\1\0\20\75\1\u0307\20\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\2\75\1\u0351\23\75\1\0\27\75\1\u0351"+ + "\11\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\3\75\1\u0126\2\75\1\0\26\75\1\0"+ + "\7\75\1\u0126\31\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\2\75\1\u0352\3\75\1\0"+ + "\26\75\1\0\12\75\1\u0352\26\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\1\u01f5\25\75\1\0\25\75\1\u01f5\13\75\1\0\21\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\1\u0307"+ + "\5\75\1\0\26\75\1\0\23\75\1\u0307\15\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\1\75\1\u0353\4\75\1\0\26\75\1\0\17\75\1\u0353"+ + "\21\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u01d7\23\75\1\0"+ + "\27\75\1\u01d7\11\75\1\0\17\75\15\0\1\u0354\41\0"+ + "\1\u0354\51\0\1\142\11\0\1\142\1\u0355\4\142\1\0"+ + "\2\142\1\u0355\1\142\4\u0355\1\142\1\0\1\142\1\0"+ + "\3\142\1\0\1\142\1\u0355\14\0\2\142\1\0\5\142"+ + "\1\u0355\1\142\2\u0355\1\142\1\u0355\2\142\1\u0355\3\142"+ + "\1\u0355\1\142\1\0\1\142\3\0\1\142\1\u0355\3\142"+ + "\1\u0355\6\142\1\u0355\3\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\1\u0356\1\152\1\0\22\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\12\152\1\u0357\7\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\2\152\1\0\3\152\1\u0358\16\152\1\142\1\0\1\152"+ + "\3\0\17\152\1\142\11\0\6\152\1\0\11\152\1\0"+ + "\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0"+ + "\1\u0359\1\152\1\0\22\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\16\152\1\u035a\3\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\3\152\1\u035b\16\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u035c"+ + "\1\152\1\0\22\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\3\152\1\u035d\16\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\6\152\1\u02c2\13\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\1\152\1\u0235"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\10\152"+ + "\1\u035e\11\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\u035f"+ + "\21\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\1\u0360\1\152\1\0\22\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\6\152\1\u0361\13\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\5\152\1\u0362\14\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\3\152"+ + "\1\u0363\2\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\1\152\1\u0364\14\0\2\152\1\0"+ + "\22\152\1\142\1\0\1\152\3\0\17\152\1\142\11\0"+ + "\6\152\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146"+ + "\1\152\1\0\2\152\14\0\1\152\1\u022b\1\0\22\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\15\152\1\u02d5\4\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\7\152\1\u0222\12\152"+ + "\1\142\1\0\1\152\3\0\17\152\1\142\11\0\6\152"+ + "\1\0\11\152\1\0\1\152\1\0\1\142\1\u0146\1\152"+ + "\1\0\2\152\14\0\2\152\1\0\10\152\1\u0365\11\152"+ + "\1\142\1\0\1\152\3\0\17\152\15\0\1\u0366\41\0"+ + "\1\u0366\62\0\1\u02de\134\0\1\u0367\41\0\1\u0367\62\0"+ + "\1\u02e2\141\0\1\u0368\45\0\1\u0368\133\0\1\u0369\120\0"+ + "\1\u036a\77\0\1\u036b\175\0\1\u0265\114\0\1\u036c\3\0"+ + "\1\u036d\1\u036e\122\0\1\u02e9\147\0\1\u036f\131\0\1\u0370"+ + "\121\0\1\u02e9\125\0\1\u036f\135\0\1\u02e9\117\0\1\u036f"+ + "\126\0\1\u0371\141\0\1\u0372\35\0\2\321\10\0\6\321"+ + "\1\0\17\321\1\0\2\321\10\0\2\321\2\0\1\u0373"+ + "\1\321\1\0\22\321\2\0\1\321\3\0\21\321\10\0"+ + "\6\321\1\0\17\321\1\0\2\321\10\0\2\321\2\0"+ + "\2\321\1\0\11\321\1\u0374\10\321\2\0\1\321\3\0"+ + "\21\321\10\0\6\321\1\0\17\321\1\0\2\321\10\0"+ + "\2\321\2\0\2\321\1\0\14\321\1\u027b\5\321\2\0"+ + "\1\321\3\0\17\321\12\0\5\357\1\u0375\1\0\10\357"+ + "\2\0\1\357\5\0\2\357\14\0\2\357\1\0\2\357"+ + "\1\u0375\17\357\2\0\1\357\3\0\17\357\2\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\12\75\1\u01d5\13\75\1\0\41\75\1\0\6\75\1\u01d5"+ + "\12\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\20\75\1\122\5\75\1\0\36\75\1\122"+ + "\2\75\1\0\21\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u0376\23\75\1\0"+ + "\27\75\1\u0376\11\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\2\75\1\u0204"+ + "\23\75\1\0\27\75\1\u0204\11\75\1\0\21\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\6\75\1\0"+ + "\26\75\1\0\13\75\1\377\25\75\1\0\2\75\1\377"+ + "\16\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\12\75\1\u0377\13\75\1\0\41\75\1\0"+ + "\6\75\1\u0377\12\75\1\0\1\75\1\0\2\75\1\0"+ + "\1\75\1\0\6\75\1\0\2\75\1\u0307\23\75\1\0"+ + "\27\75\1\u0307\11\75\1\0\21\75\1\0\1\75\1\0"+ + "\2\75\1\0\1\75\1\0\6\75\1\0\26\75\1\0"+ + "\30\75\1\u0378\10\75\1\0\4\75\1\u0378\14\75\1\0"+ + "\1\75\1\0\2\75\1\0\1\75\1\0\3\75\1\u013a"+ + "\2\75\1\0\26\75\1\0\7\75\1\u013a\31\75\1\0"+ + "\21\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\13\75\1\u01fc\25\75\1\0"+ + "\2\75\1\u01fc\14\75\16\0\1\u0379\57\0\1\u0379\32\0"+ + "\1\142\11\0\1\142\1\152\4\142\1\0\2\142\1\152"+ + "\1\142\4\152\1\142\1\0\1\142\1\0\3\142\1\0"+ + "\1\142\1\152\14\0\2\142\1\0\5\142\1\152\1\142"+ + "\2\152\1\142\1\152\2\142\1\152\3\142\1\152\1\142"+ + "\1\0\1\142\3\0\1\142\1\152\3\142\1\152\6\142"+ + "\1\152\3\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u037a\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\10\152\1\u037b\11\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\5\152\1\u0224\14\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u032d\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\15\152\1\u037c\4\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\15\152\1\u037d\4\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\u022b"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\22\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\5\152"+ + "\1\u02c2\14\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\152"+ + "\1\u037e\20\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\1\152"+ + "\1\u037f\20\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\13\152"+ + "\1\u0154\6\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\2\152"+ + "\1\u0380\17\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\3\152"+ + "\1\u0381\16\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\6\152"+ + "\1\u0382\13\152\1\142\1\0\1\152\3\0\17\152\1\142"+ + "\11\0\6\152\1\0\11\152\1\0\1\152\1\0\1\142"+ + "\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0\3\152"+ + "\1\u02c3\16\152\1\142\1\0\1\152\3\0\17\152\16\0"+ + "\1\u0383\57\0\1\u0383\50\0\1\u0384\57\0\1\u0384\55\0"+ + "\1\u0385\53\0\1\u0385\115\0\1\u0386\126\0\1\u0370\131\0"+ + "\1\u036c\3\0\1\u036d\135\0\1\u0387\122\0\1\u0388\134\0"+ + "\1\u02f1\135\0\1\u0389\130\0\1\u02e9\115\0\1\u038a\137\0"+ + "\1\u0275\35\0\2\321\10\0\6\321\1\0\17\321\1\0"+ + "\2\321\10\0\2\321\2\0\2\321\1\0\3\321\1\u038b"+ + "\16\321\2\0\1\321\3\0\21\321\10\0\6\321\1\0"+ + "\17\321\1\0\2\321\10\0\2\321\2\0\2\321\1\0"+ + "\11\321\1\u027b\10\321\2\0\1\321\3\0\17\321\2\75"+ + "\1\0\1\75\1\0\2\75\1\0\1\75\1\0\6\75"+ + "\1\0\20\75\1\u01f6\5\75\1\0\36\75\1\u01f6\2\75"+ + "\1\0\21\75\1\0\1\75\1\0\2\75\1\0\1\75"+ + "\1\0\6\75\1\0\26\75\1\0\13\75\1\u0102\25\75"+ + "\1\0\2\75\1\u0102\16\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\4\75\1\u038c\1\75\1\0\26\75"+ + "\1\0\26\75\1\u038c\12\75\1\0\17\75\17\0\1\u038d"+ + "\44\0\1\u038d\44\0\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\13\152\1\u0251\6\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\5\152\1\u022b\14\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u038e\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u02c2\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u038f\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\3\152\1\u0154\16\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\15\152\1\u024a\4\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\2\152\1\u02d5\17\152\1\142\1\0"+ + "\1\152\3\0\17\152\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\1\152\1\u0390\20\152\1\142\1\0"+ + "\1\152\3\0\17\152\17\0\1\u0391\44\0\1\u0391\63\0"+ + "\1\u0392\44\0\1\u0392\64\0\1\u0393\142\0\1\u0394\130\0"+ + "\1\u0395\155\0\1\u0396\142\0\1\u02e9\131\0\1\u0397\36\0"+ + "\2\321\10\0\6\321\1\0\17\321\1\0\2\321\10\0"+ + "\2\321\2\0\2\321\1\0\15\321\1\u0398\4\321\2\0"+ + "\1\321\3\0\17\321\2\75\1\0\1\75\1\0\2\75"+ + "\1\0\1\75\1\0\6\75\1\0\1\75\1\u0399\24\75"+ + "\1\0\20\75\1\u0399\20\75\1\0\17\75\20\0\1\u039a"+ + "\110\0\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152"+ + "\1\0\2\152\1\u0222\17\152\1\142\1\0\1\152\3\0"+ + "\17\152\1\142\11\0\6\152\1\0\11\152\1\0\1\152"+ + "\1\0\1\142\1\u0146\1\152\1\0\2\152\14\0\1\u039b"+ + "\1\152\1\0\22\152\1\142\1\0\1\152\3\0\17\152"+ + "\1\142\11\0\6\152\1\0\11\152\1\0\1\152\1\0"+ + "\1\142\1\u0146\1\152\1\0\2\152\14\0\2\152\1\0"+ + "\10\152\1\u0381\11\152\1\142\1\0\1\152\3\0\17\152"+ + "\20\0\1\u039c\130\0\1\u039d\200\0\1\u039e\124\0\1\u039f"+ + "\134\0\1\u0389\125\0\1\u03a0\43\0\2\321\10\0\6\321"+ + "\1\0\17\321\1\0\2\321\10\0\2\321\2\0\2\321"+ + "\1\0\7\321\1\u02fe\12\321\2\0\1\321\3\0\17\321"+ + "\2\75\1\0\1\75\1\0\2\75\1\0\1\75\1\0"+ + "\6\75\1\0\26\75\1\0\22\75\1\u0102\16\75\1\0"+ + "\1\75\1\u0102\15\75\1\142\11\0\6\152\1\0\11\152"+ + "\1\0\1\152\1\0\1\142\1\u0146\1\152\1\0\2\152"+ + "\14\0\2\152\1\0\22\152\1\142\1\0\1\152\3\0"+ + "\16\152\1\u0380\57\0\1\u03a1\17\0\1\u03a2\126\0\1\u03a3"+ + "\117\0\1\u03a4\131\0\1\u0370\127\0\1\u02e4\142\0\1\u0370"+ + "\32\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[71111]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\6\0\2\1\1\0\2\1\1\0\2\1\7\0\1\1"+ + "\12\0\2\1\1\11\6\1\1\11\5\1\1\11\2\1"+ + "\2\11\2\1\1\11\1\1\2\11\1\1\1\11\1\1"+ + "\1\11\25\1\1\11\2\1\1\11\1\1\2\11\1\1"+ + "\1\11\1\1\4\11\1\1\2\11\1\1\2\11\11\1"+ + "\1\11\25\1\2\11\3\1\2\11\2\1\1\11\1\1"+ + "\1\11\1\1\1\11\6\1\1\11\4\1\3\11\5\1"+ + "\1\11\1\1\4\11\4\1\5\11\6\1\1\11\1\1"+ + "\3\11\1\1\2\11\1\1\1\11\2\1\1\11\2\1"+ + "\1\11\1\1\2\11\2\1\1\11\1\1\2\11\12\1"+ + "\3\11\1\1\1\11\1\1\3\11\1\1\1\11\1\1"+ + "\1\11\4\1\1\11\1\1\5\0\1\11\105\1\1\11"+ + "\3\0\1\11\1\0\100\1\1\11\2\1\1\0\1\11"+ + "\12\0\1\11\1\1\15\0\1\1\1\11\5\0\1\1"+ + "\1\0\4\11\1\1\5\0\13\1\1\11\1\0\3\1"+ + "\1\0\2\1\1\11\4\0\102\1\1\0\1\1\1\0"+ + "\3\1\1\0\74\1\41\0\1\1\1\0\1\11\2\0"+ + "\13\1\1\0\2\1\1\11\1\0\1\11\2\0\45\1"+ + "\1\11\1\0\1\11\47\1\4\0\1\1\3\0\1\1"+ + "\6\0\1\11\15\0\1\11\2\0\10\1\1\11\2\0"+ + "\24\1\1\0\26\1\25\0\17\1\1\0\21\1\15\0"+ + "\6\1\1\0\11\1\10\0\2\1\1\0\3\1\2\0"+ + "\1\11\4\0\2\1\1\11\1\1\2\11\6\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[932]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ + + /** + * Type specific to XMLTokenMaker denoting a line ending with an unclosed + * double-quote attribute. + */ + public static final int INTERNAL_ATTR_DOUBLE = -1; + + + /** + * Type specific to XMLTokenMaker denoting a line ending with an unclosed + * single-quote attribute. + */ + public static final int INTERNAL_ATTR_SINGLE = -2; + + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed HTML tag; thus a new line is beginning + * still inside of the tag. + */ + public static final int INTERNAL_INTAG = -3; + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed <script> tag. + */ + public static final int INTERNAL_INTAG_SCRIPT = -4; + + /** + * Token type specifying we're in a double-quoted attribute in a + * script tag. + */ + public static final int INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT = -5; + + /** + * Token type specifying we're in a single-quoted attribute in a + * script tag. + */ + public static final int INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT = -6; + + /** + * Token type specific to HTMLTokenMaker; this signals that the user has + * ended a line with an unclosed <style> tag. + */ + public static final int INTERNAL_INTAG_STYLE = -7; + + /** + * Token type specifying we're in a double-quoted attribute in a + * style tag. + */ + public static final int INTERNAL_ATTR_DOUBLE_QUOTE_STYLE = -8; + + /** + * Token type specifying we're in a single-quoted attribute in a + * style tag. + */ + public static final int INTERNAL_ATTR_SINGLE_QUOTE_STYLE = -9; + + /** + * Token type specifying we're in JavaScript. + */ + public static final int INTERNAL_IN_JS = -10; + + /** + * Token type specifying we're in a JavaScript multiline comment. + */ + public static final int INTERNAL_IN_JS_MLC = -11; + + /** + * Token type specifying we're in an invalid multi-line JS string. + */ + public static final int INTERNAL_IN_JS_STRING_INVALID = -12; + + /** + * Token type specifying we're in a valid multi-line JS string. + */ + public static final int INTERNAL_IN_JS_STRING_VALID = -13; + + /** + * Token type specifying we're in an invalid multi-line JS single-quoted string. + */ + public static final int INTERNAL_IN_JS_CHAR_INVALID = -14; + + /** + * Token type specifying we're in a valid multi-line JS single-quoted string. + */ + public static final int INTERNAL_IN_JS_CHAR_VALID = -15; + + /** + * Internal type denoting a line ending in CSS. + */ + public static final int INTERNAL_CSS = -16; + + /** + * Internal type denoting a line ending in a CSS property. + */ + public static final int INTERNAL_CSS_PROPERTY = -17; + + /** + * Internal type denoting a line ending in a CSS property value. + */ + public static final int INTERNAL_CSS_VALUE = -18; + + /** + * Token type specifying we're in a valid multi-line template literal. + */ + static final int INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID = -23; + + /** + * Token type specifying we're in an invalid multi-line template literal. + */ + static final int INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID = -24; + + /** + * Internal type denoting line ending in a CSS double-quote string. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_STRING = -(1<<11); + + /** + * Internal type denoting line ending in a CSS single-quote string. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_CHAR = -(2<<11); + + /** + * Internal type denoting line ending in a CSS multi-line comment. + * The state to return to is embedded in the actual end token type. + */ + public static final int INTERNAL_CSS_MLC = -(3<<11); + + /** + * Token type specifying we're in a Handlebars expression. This particular field is public so + * that we can hack and key off of it for code completion. + */ + static final int INTERNAL_IN_HB = -(4<<11); + + /** + * Token type specifying we're in a Handlebars multiline comment starting with {@code "{{!"}. + */ + static final int INTERNAL_IN_HB_MLC_1 = -(5<<11); + + /** + * Token type specifying we're in a Handlebars multiline comment starting with {@code "{{!--"}. + */ + static final int INTERNAL_IN_HB_MLC_2 = -(6<<11); + + /** + * Token type specifying we're in a Handlebars multiline string. + */ + static final int INTERNAL_IN_HB_STRING = -(7<<11); + + /** + * Token type specifying we're in a Handlebars multiline char. + */ + static final int INTERNAL_IN_HB_CHAR = -(8<<11); + + /** + * The state previous CSS-related state we were in before going into a CSS + * string, multi-line comment, etc. + */ + private int cssPrevState; + + /** + * Whether closing markup tags are automatically completed for HTML. + */ + private static boolean completeCloseTags; + + /** + * When in the JS_STRING state, whether the current string is valid. + */ + private boolean validJSString; + + /** + * When in the HB state, whether the current string is valid. + */ + private boolean validHandlebarsString; + + /** + * The number of curly braces to look for to denote the close of the current Handlebars expression. + */ + private int hbCurlyCount; + + /** + * The state Handlebars was started in (YYINITIAL, INTERNAL_IN_JS, etc.). + */ + private int hbInState; + + /** + * The language index we were in when Handlebars was started. + */ + private int hbInLangIndex; + + /** + * Language state set on HTML tokens. Must be 0. + */ + static final int LANG_INDEX_DEFAULT = 0; + + /** + * Language state set on JavaScript tokens. + */ + static final int LANG_INDEX_JS = 1; + + /** + * Language state set on CSS tokens. + */ + static final int LANG_INDEX_CSS = 2; + + /** + * Language state set on Handlebars tokens. + */ + static final int LANG_INDEX_HANDLEBARS = 3; + + private Stack varDepths; + + + /** + * Constructor. This must be here because JFlex does not generate a + * no-parameter constructor. + */ + public HandlebarsTokenMaker() { + super(); + } + + + /** + * Adds the token specified to the current linked list of tokens as an + * "end token;" that is, at zzMarkedPos. + * + * @param tokenType The token's type. + */ + private void addEndToken(int tokenType) { + addToken(zzMarkedPos,zzMarkedPos, tokenType); + } + + + /** + * Adds an end token that encodes the information necessary to return + * to the pre-Handlebars state and language index. + * + * @param endTokenState The Handlebars-related end-token state. + */ + private void addHandlebarsEndToken(int endTokenState) { + addEndToken(endTokenState - hbInState - (hbInLangIndex<<16)); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + * @see #addToken(int, int, int) + */ + private void addHyperlinkToken(int start, int end, int tokenType) { + int so = start + offsetShift; + addToken(zzBuffer, start,end, tokenType, so, true); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + */ + private void addToken(int tokenType) { + addToken(zzStartRead, zzMarkedPos-1, tokenType); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param tokenType The token's type. + */ + private void addToken(int start, int end, int tokenType) { + int so = start + offsetShift; + addToken(zzBuffer, start,end, tokenType, so); + } + + + /** + * Adds the token specified to the current linked list of tokens. + * + * @param array The character array. + * @param start The starting offset in the array. + * @param end The ending offset in the array. + * @param tokenType The token's type. + * @param startOffset The offset in the document at which this token + * occurs. + */ + @Override + public void addToken(char[] array, int start, int end, int tokenType, int startOffset) { + super.addToken(array, start,end, tokenType, startOffset); + zzStartRead = zzMarkedPos; + } + + + @Override + protected OccurrenceMarker createOccurrenceMarker() { + return new HtmlOccurrenceMarker(); + } + + + /** + * Sets whether markup close tags should be completed. You might not want + * this to be the case, since some tags in standard HTML aren't usually + * closed. + * + * @return Whether closing markup tags are completed. + * @see #setCompleteCloseTags(boolean) + */ + @Override + public boolean getCompleteCloseTags() { + return completeCloseTags; + } + + + @Override + public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) { + return languageIndex==LANG_INDEX_CSS || languageIndex==LANG_INDEX_JS; + } + + + @Override + public String[] getLineCommentStartAndEnd(int languageIndex) { + switch (languageIndex) { + case LANG_INDEX_JS: + return new String[] { "//", null }; + case LANG_INDEX_CSS: + return new String[] { "/*", "*/" }; + case LANG_INDEX_HANDLEBARS: + return new String[] { "{{!--", "--}}" }; + default: + return new String[] { "" }; + } + } + + + /** + * Returns TokenTypes.MARKUP_TAG_NAME. + * + * @param type The token type. + * @return Whether tokens of this type should have "mark occurrences" + * enabled. + */ + @Override + public boolean getMarkOccurrencesOfTokenType(int type) { + return type==TokenTypes.MARKUP_TAG_NAME; + } + + + /** + * Overridden to handle newlines in JS and CSS differently than those in + * markup. + */ + @Override + public boolean getShouldIndentNextLineAfter(Token token) { + int languageIndex = token==null ? 0 : token.getLanguageIndex(); + if (getCurlyBracesDenoteCodeBlocks(languageIndex)) { + if (token!=null && token.length()==1) { + char ch = token.charAt(0); + return ch=='{' || ch=='('; + } + } + return false; + } + + + /** + * Returns the first token in the linked list of tokens generated + * from text. This method must be implemented by + * subclasses so they can correctly implement syntax highlighting. + * + * @param text The text from which to get tokens. + * @param initialTokenType The token type we should start with. + * @param startOffset The offset into the document at which + * text starts. + * @return The first Token in a linked list representing + * the syntax highlighted text. + */ + @Override + public Token getTokenList(Segment text, int initialTokenType, int startOffset) { + + resetTokenList(); + this.offsetShift = -text.offset + startOffset; + hbInState = YYINITIAL; // Shouldn't be necessary + cssPrevState = CSS; // Shouldn't be necessary + int languageIndex = 0; + + // Start off in the proper state. + int state; + switch (initialTokenType) { + case TokenTypes.MARKUP_COMMENT: + state = COMMENT; + break; + case INTERNAL_INTAG: + state = INTAG; + break; + case INTERNAL_INTAG_SCRIPT: + state = INTAG_SCRIPT; + break; + case INTERNAL_INTAG_STYLE: + state = INTAG_STYLE; + break; + case INTERNAL_ATTR_DOUBLE: + state = INATTR_DOUBLE; + break; + case INTERNAL_ATTR_SINGLE: + state = INATTR_SINGLE; + break; + case INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT: + state = INATTR_DOUBLE_SCRIPT; + break; + case INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT: + state = INATTR_SINGLE_SCRIPT; + break; + case INTERNAL_ATTR_DOUBLE_QUOTE_STYLE: + state = INATTR_DOUBLE_STYLE; + break; + case INTERNAL_ATTR_SINGLE_QUOTE_STYLE: + state = INATTR_SINGLE_STYLE; + break; + case INTERNAL_IN_JS: + state = JAVASCRIPT; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_MLC: + state = JS_MLC; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_STRING_INVALID: + state = JS_STRING; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_STRING_VALID: + state = JS_STRING; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_CHAR_INVALID: + state = JS_CHAR; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_CHAR_VALID: + state = JS_CHAR; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_CSS: + state = CSS; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_PROPERTY: + state = CSS_PROPERTY; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_VALUE: + state = CSS_VALUE; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID: + state = JS_TEMPLATE_LITERAL; + validJSString = true; + languageIndex = LANG_INDEX_JS; + break; + case INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID: + state = JS_TEMPLATE_LITERAL; + validJSString = false; + languageIndex = LANG_INDEX_JS; + break; + default: + if (initialTokenType<-1024) { + int main = -(-initialTokenType & 0xffffff00); + switch (main) { + default: // Should never happen + case INTERNAL_IN_HB: + state = HB; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_CHAR: + state = HB_CHAR_LITERAL; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_STRING: + state = HB_STRING; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_MLC_1: + state = HB_COMMENT_1; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_IN_HB_MLC_2: + state = HB_COMMENT_2; + languageIndex = LANG_INDEX_HANDLEBARS; + hbInState = -initialTokenType&0xff; + hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; + break; + case INTERNAL_CSS_STRING: + state = CSS_STRING; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_CHAR: + state = CSS_CHAR_LITERAL; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + case INTERNAL_CSS_MLC: + state = CSS_C_STYLE_COMMENT; + cssPrevState = -initialTokenType&0xff; + languageIndex = LANG_INDEX_CSS; + break; + } + } + else { + state = YYINITIAL; + } + break; + } + + setLanguageIndex(languageIndex); + start = text.offset; + s = text; + try { + yyreset(zzReader); + yybegin(state); + return yylex(); + } catch (IOException ioe) { + ioe.printStackTrace(); + return new TokenImpl(); + } + + } + + + /** + * Overridden to accept letters, digits, underscores, and hyphens. + */ + @Override + public boolean isIdentifierChar(int languageIndex, char ch) { + switch (languageIndex) { + case LANG_INDEX_CSS: + case LANG_INDEX_HANDLEBARS: + case LANG_INDEX_DEFAULT: + return Character.isLetterOrDigit(ch) || ch=='-' || ch=='.' || ch=='_'; + case LANG_INDEX_JS: + default: + return super.isIdentifierChar(languageIndex, ch); + } + } + + + /** + * Sets whether markup close tags should be completed. You might not want + * this to be the case, since some tags in standard HTML aren't usually + * closed. + * + * @param complete Whether closing markup tags are completed. + * @see #getCompleteCloseTags() + */ + public static void setCompleteCloseTags(boolean complete) { + completeCloseTags = complete; + } + + + /** + * Overridden to remember the language index we're leaving. + */ + @Override + protected void yybegin(int state, int languageIndex) { + hbInLangIndex = getLanguageIndex(); + yybegin(state); + setLanguageIndex(languageIndex); + } + + + /** + * Refills the input buffer. + * + * @return true if EOF was reached, otherwise + * false. + */ + private boolean zzRefill() { + return zzCurrentPos>=s.offset+s.count; + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to YY_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + // 's' has been updated. + zzBuffer = s.array; + /* + * We replaced the line below with the two below it because zzRefill + * no longer "refills" the buffer (since the way we do it, it's always + * "full" the first time through, since it points to the segment's + * array). So, we assign zzEndRead here. + */ + //zzStartRead = zzEndRead = s.offset; + zzStartRead = s.offset; + zzEndRead = zzStartRead + s.count - 1; + zzCurrentPos = zzMarkedPos = s.offset; + zzLexicalState = YYINITIAL; + zzReader = reader; + zzAtEOF = false; + } + + + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public HandlebarsTokenMaker(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public HandlebarsTokenMaker(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 194) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public org.fife.ui.rsyntaxtextarea.Token yylex() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 78: + { start = zzMarkedPos-1; validHandlebarsString = true; yybegin(HB_CHAR_LITERAL); + } + case 138: break; + case 36: + { addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 139: break; + case 119: + { addToken(TokenTypes.FUNCTION); + } + case 140: break; + case 47: + { addToken(TokenTypes.DATA_TYPE); + } + case 141: break; + case 23: + { start = zzMarkedPos-1; yybegin(INATTR_SINGLE_SCRIPT); + } + case 142: break; + case 105: + { addToken(TokenTypes.REGEX); + } + case 143: break; + case 31: + { addToken(TokenTypes.SEPARATOR); + } + case 144: break; + case 131: + { addToken(Token.RESERVED_WORD_2); + } + case 145: break; + case 103: + { start = zzMarkedPos-2; cssPrevState = zzLexicalState; yybegin(CSS_C_STYLE_COMMENT); + } + case 146: break; + case 85: + { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_2); return firstToken; + } + case 147: break; + case 124: + { addToken(TokenTypes.LITERAL_BOOLEAN); + } + case 148: break; + case 128: + { yybegin(hbInState, hbInLangIndex); + if (hbCurlyCount == 4) { + addToken(TokenTypes.SEPARATOR); + } + else if (hbCurlyCount == 3) { + addToken(zzStartRead, zzStartRead + 2, TokenTypes.SEPARATOR); + zzMarkedPos--; // Effectively push back the final '}' to be reread + } + // If curly count is 2, read the third curly as outside of the Handlebars expression + else { + addToken(zzStartRead, zzStartRead + 1, TokenTypes.SEPARATOR); + zzMarkedPos -= 2; // Effectively push back the final two '}' to be reread + } + start = zzMarkedPos; + } + case 149: break; + case 117: + { if(JavaScriptTokenMaker.isJavaScriptCompatible("1.7")){ addToken(TokenTypes.RESERVED_WORD);} else {addToken(TokenTypes.IDENTIFIER);} + } + case 150: break; + case 61: + { int temp = zzMarkedPos - 2; + addToken(zzStartRead, temp, TokenTypes.FUNCTION); + addToken(zzMarkedPos-1, zzMarkedPos-1, TokenTypes.SEPARATOR); + zzStartRead = zzCurrentPos = zzMarkedPos; + } + case 151: break; + case 44: + { /*System.out.println("CSS: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); + } + case 152: break; + case 89: + { addToken(TokenTypes.SEPARATOR); hbCurlyCount = 2; hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); + } + case 153: break; + case 56: + { addToken(TokenTypes.SEPARATOR); /* helps with auto-closing curlies when editing CSS */ + } + case 154: break; + case 72: + { // TODO: This isn't right. The expression and its depth should continue to the next line. + addToken(start,zzStartRead-1, TokenTypes.VARIABLE); addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); return firstToken; + } + case 155: break; + case 11: + { addToken(TokenTypes.MARKUP_TAG_ATTRIBUTE); + } + case 156: break; + case 46: + { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_STRING); + } + case 157: break; + case 33: + { addToken(TokenTypes.LITERAL_NUMBER_DECIMAL_INT); + } + case 158: break; + case 70: + { /* Skip valid '$' that is not part of template literal expression start */ + } + case 159: break; + case 84: + { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_1); return firstToken; + } + case 160: break; + case 20: + { yybegin(INTAG); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); + } + case 161: break; + case 25: + { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE_STYLE); + } + case 162: break; + case 34: + { start = zzMarkedPos-1; validJSString = true; yybegin(JS_TEMPLATE_LITERAL); + } + case 163: break; + case 127: + { int temp=zzStartRead; addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.COMMENT_EOL); start = zzMarkedPos; + } + case 164: break; + case 77: + { addToken(TokenTypes.LITERAL_NUMBER_FLOAT); + } + case 165: break; + case 99: + { /* Skip all escaped chars. */ + } + case 166: break; + case 55: + { addToken(TokenTypes.OPERATOR); yybegin(CSS_VALUE); + } + case 167: break; + case 13: + { addToken(TokenTypes.MARKUP_TAG_DELIMITER); + } + case 168: break; + case 62: + { addToken(start,zzStartRead-1, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); addEndToken(INTERNAL_CSS_STRING - cssPrevState); return firstToken; + } + case 169: break; + case 66: + { addToken(start,zzStartRead, TokenTypes.LITERAL_CHAR); yybegin(cssPrevState); + } + case 170: break; + case 60: + { /* End of a function */ addToken(TokenTypes.SEPARATOR); + } + case 171: break; + case 135: + { yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + int temp = zzStartRead; + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); + addToken(temp,temp+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + case 172: break; + case 42: + { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_IN_JS_MLC); return firstToken; + } + case 173: break; + case 93: + { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(YYINITIAL); + } + case 174: break; + case 126: + { int temp=zzStartRead; addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); start = zzMarkedPos; + } + case 175: break; + case 22: + { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(JAVASCRIPT, LANG_INDEX_JS); + } + case 176: break; + case 17: + { /* A non-recognized HTML tag name */ yypushback(yylength()); yybegin(INTAG); + } + case 177: break; + case 112: + { start = zzMarkedPos-3; yybegin(HB_COMMENT_1, LANG_INDEX_HANDLEBARS); + } + case 178: break; + case 71: + { int type = validJSString ? TokenTypes.LITERAL_BACKQUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); + } + case 179: break; + case 59: + { addToken(TokenTypes.OPERATOR); yybegin(CSS_PROPERTY); + } + case 180: break; + case 114: + { yybegin(YYINITIAL); addToken(start,zzStartRead+2, TokenTypes.MARKUP_COMMENT); + } + case 181: break; + case 75: + { /*System.out.println("HB unhandled: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); + } + case 182: break; + case 108: + { varDepths.push(Boolean.TRUE); + } + case 183: break; + case 107: + { addToken(start, zzStartRead - 1, TokenTypes.LITERAL_BACKQUOTE); + start = zzMarkedPos-2; + if (varDepths==null) { + varDepths = new Stack<>(); + } + else { + varDepths.clear(); + } + varDepths.push(Boolean.TRUE); + yybegin(JS_TEMPLATE_LITERAL_EXPR); + } + case 184: break; + case 27: + { start = zzMarkedPos-1; yybegin(INATTR_SINGLE_STYLE); + } + case 185: break; + case 29: + { addToken(TokenTypes.ERROR_IDENTIFIER); + } + case 186: break; + case 67: + { addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_CSS_MLC - cssPrevState); return firstToken; + } + case 187: break; + case 101: + { /* Invalid latin-1 character \xXX */ validJSString = false; + } + case 188: break; + case 113: + { addToken(TokenTypes.SEPARATOR); hbCurlyCount = 3; hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); + } + case 189: break; + case 109: + { // If in triple-curlies, render as TokenTypes.IDENTIFIER + if (hbCurlyCount == 2) { + yybegin(hbInState, hbInLangIndex); + addToken(TokenTypes.SEPARATOR); + start = zzMarkedPos; + } + else { + addToken(TokenTypes.IDENTIFIER); + } + } + case 190: break; + case 19: + { addToken(TokenTypes.MARKUP_TAG_NAME); + } + case 191: break; + case 110: + { addToken(start,zzMarkedPos-1, TokenTypes.COMMENT_MULTILINE); yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + } + case 192: break; + case 88: + { start = zzMarkedPos-2; yybegin(PI); + } + case 193: break; + case 9: + { addToken(start,zzStartRead-1, TokenTypes.MARKUP_DTD); return firstToken; + } + case 194: break; + case 137: + { addToken(TokenTypes.PREPROCESSOR); + } + case 195: break; + case 76: + { start = zzMarkedPos-1; validHandlebarsString = true; yybegin(HB_STRING); + } + case 196: break; + case 65: + { addToken(start,zzStartRead-1, TokenTypes.LITERAL_CHAR); addEndToken(INTERNAL_CSS_CHAR - cssPrevState); return firstToken; + } + case 197: break; + case 106: + { addToken(start,zzStartRead+1, TokenTypes.COMMENT_MULTILINE); yybegin(cssPrevState); + } + case 198: break; + case 15: + { addToken(TokenTypes.OPERATOR); + } + case 199: break; + case 121: + { addToken(TokenTypes.SEPARATOR); hbCurlyCount = 4; hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); + } + case 200: break; + case 64: + { /* Skip escaped chars. */ + } + case 201: break; + case 100: + { /* Invalid Unicode character \\uXXXX */ validJSString = false; + } + case 202: break; + case 90: + { yybegin(YYINITIAL); addToken(start,zzStartRead+1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); + } + case 203: break; + case 57: + { /*System.out.println("css_value: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); + } + case 204: break; + case 51: + { /*System.out.println("css_property: " + yytext());*/ addToken(TokenTypes.IDENTIFIER); + } + case 205: break; + case 104: + { addToken(TokenTypes.VARIABLE); + } + case 206: break; + case 30: + { addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 207: break; + case 53: + { addToken(TokenTypes.SEPARATOR); yybegin(CSS); + } + case 208: break; + case 122: + { int temp = zzStartRead; + if (start <= zzStartRead - 1) { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_COMMENT); + } + addHyperlinkToken(temp,zzMarkedPos-1, TokenTypes.MARKUP_COMMENT); + start = zzMarkedPos; + } + case 209: break; + case 74: + { addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 210: break; + case 4: + { addToken(TokenTypes.WHITESPACE); + } + case 211: break; + case 120: + { start = zzMarkedPos-4; yybegin(COMMENT); + } + case 212: break; + case 69: + { if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_BACKQUOTE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); + } + return firstToken; + } + case 213: break; + case 102: + { yybegin(JAVASCRIPT); addToken(start,zzStartRead+1, TokenTypes.COMMENT_MULTILINE); + } + case 214: break; + case 24: + { yybegin(INTAG_SCRIPT); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); + } + case 215: break; + case 54: + { addToken(TokenTypes.RESERVED_WORD); + } + case 216: break; + case 96: + { addToken(TokenTypes.ERROR_NUMBER_FORMAT); + } + case 217: break; + case 43: + { addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 218: break; + case 91: + { hbCurlyCount = zzMarkedPos - zzStartRead; addToken(Token.SEPARATOR); hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); + } + case 219: break; + case 32: + { start = zzMarkedPos-1; validJSString = true; yybegin(JS_STRING); + } + case 220: break; + case 136: + { int temp = zzStartRead; + addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); + yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(temp,temp+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + case 221: break; + case 52: + { addEndToken(INTERNAL_CSS_PROPERTY); return firstToken; + } + case 222: break; + case 132: + { addToken(zzStartRead,zzStartRead, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-6,zzMarkedPos-1, TokenTypes.MARKUP_TAG_NAME); + start = zzMarkedPos; yybegin(INTAG_SCRIPT); + } + case 223: break; + case 82: + { addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 224: break; + case 68: + { if (validJSString) { + addToken(start, zzStartRead - 1, TokenTypes.LITERAL_BACKQUOTE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID); + } + else { + addToken(start,zzStartRead - 1, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); + } + return firstToken; + } + case 225: break; + case 73: + { if (!varDepths.empty()) { + varDepths.pop(); + if (varDepths.empty()) { + addToken(start,zzStartRead, TokenTypes.VARIABLE); + start = zzMarkedPos; + yybegin(JS_TEMPLATE_LITERAL); + } + } + } + case 226: break; + case 118: + { if (hbCurlyCount == 4) { + addToken(TokenTypes.IDENTIFIER); + } + else if (hbCurlyCount == 3) { + yybegin(hbInState, hbInLangIndex); + addToken(TokenTypes.SEPARATOR); + start = zzMarkedPos; + } + // If curly count is 2, read the third curly as outside of the Handlebars expression + else { + yybegin(hbInState, hbInLangIndex); + addToken(zzStartRead, zzStartRead + 1, TokenTypes.SEPARATOR); + zzMarkedPos--; // Effectively push back the final '}' to be reread + start = zzMarkedPos; + } + } + case 227: break; + case 35: + { start = zzMarkedPos-1; validJSString = true; yybegin(JS_CHAR); + } + case 228: break; + case 49: + { addToken(TokenTypes.SEPARATOR); yybegin(CSS_PROPERTY); + } + case 229: break; + case 86: + { int count = yylength(); + addToken(zzStartRead,zzStartRead, TokenTypes.MARKUP_TAG_DELIMITER); + zzMarkedPos -= (count-1); //yypushback(count-1); + yybegin(INTAG_CHECK_TAG_NAME); + } + case 230: break; + case 14: + { yybegin(YYINITIAL); addToken(TokenTypes.MARKUP_TAG_DELIMITER); + } + case 231: break; + case 81: + { validHandlebarsString = false; /* Skip all escaped chars. */ + } + case 232: break; + case 125: + { if(JavaScriptTokenMaker.isJavaScriptCompatible("1.6")){ addToken(TokenTypes.RESERVED_WORD);} else {addToken(TokenTypes.IDENTIFIER);} + } + case 233: break; + case 95: + { start = zzMarkedPos-2; yybegin(JS_MLC); + } + case 234: break; + case 80: + { int type = validHandlebarsString ? TokenTypes.LITERAL_STRING_DOUBLE_QUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(HB); + } + case 235: break; + case 10: + { yybegin(YYINITIAL); addToken(start,zzStartRead, TokenTypes.MARKUP_DTD); + } + case 236: break; + case 48: + { /* Unknown pseudo class */ addToken(TokenTypes.DATA_TYPE); + } + case 237: break; + case 63: + { addToken(start,zzStartRead, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); yybegin(cssPrevState); + } + case 238: break; + case 5: + { addToken(TokenTypes.MARKUP_ENTITY_REFERENCE); + } + case 239: break; + case 58: + { addEndToken(INTERNAL_CSS_VALUE); return firstToken; + } + case 240: break; + case 133: + { yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-6,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + case 241: break; + case 83: + { int type = validHandlebarsString ? TokenTypes.LITERAL_CHAR : TokenTypes.ERROR_CHAR; addToken(start,zzStartRead, type); yybegin(HB); + } + case 242: break; + case 111: + { int count = yylength(); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + zzMarkedPos -= (count-2); //yypushback(count-2); + yybegin(INTAG_CHECK_TAG_NAME); + } + case 243: break; + case 92: + { int temp=zzStartRead; if (zzStartRead>start) addToken(start,zzStartRead-1, Token.MARKUP_TAG_ATTRIBUTE_VALUE); hbCurlyCount = zzMarkedPos - temp; addToken(temp, zzMarkedPos-1, Token.SEPARATOR); hbInState = zzLexicalState; yybegin(HB, LANG_INDEX_HANDLEBARS); + } + case 244: break; + case 18: + { /* Shouldn't happen */ yypushback(1); yybegin(INTAG); + } + case 245: break; + case 3: + { addNullToken(); return firstToken; + } + case 246: break; + case 45: + { addEndToken(INTERNAL_CSS); return firstToken; + } + case 247: break; + case 6: + { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(INTAG); + } + case 248: break; + case 40: + { /* Line ending in '\' => continue to next line. */ + if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_CHAR); + addEndToken(INTERNAL_IN_JS_CHAR_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_CHAR); + addEndToken(INTERNAL_IN_JS_CHAR_INVALID); + } + return firstToken; + } + case 249: break; + case 50: + { start = zzMarkedPos-1; cssPrevState = zzLexicalState; yybegin(CSS_CHAR_LITERAL); + } + case 250: break; + case 98: + { addToken(Token.RESERVED_WORD); + } + case 251: break; + case 115: + { boolean highlightedAsRegex = false; + if (firstToken==null) { + addToken(TokenTypes.REGEX); + highlightedAsRegex = true; + } + else { + // If this is *likely* to be a regex, based on + // the previous token, highlight it as such. + Token t = firstToken.getLastNonCommentNonWhitespaceToken(); + if (RSyntaxUtilities.regexCanFollowInJavaScript(t)) { + addToken(TokenTypes.REGEX); + highlightedAsRegex = true; + } + } + // If it doesn't *appear* to be a regex, highlight it as + // individual tokens. + if (!highlightedAsRegex) { + int temp = zzStartRead + 1; + addToken(zzStartRead, zzStartRead, TokenTypes.OPERATOR); + zzStartRead = zzCurrentPos = zzMarkedPos = temp; + } + } + case 252: break; + case 12: + { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE); + } + case 253: break; + case 28: + { yybegin(INTAG_STYLE); addToken(start,zzStartRead, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); + } + case 254: break; + case 79: + { addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 255: break; + case 39: + { addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 256: break; + case 130: + { addToken(zzStartRead,zzStartRead, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-5,zzMarkedPos-1, TokenTypes.MARKUP_TAG_NAME); + start = zzMarkedPos; cssPrevState = zzLexicalState; yybegin(INTAG_STYLE); + } + case 257: break; + case 116: + { addToken(Token.DATA_TYPE); + } + case 258: break; + case 97: + { addToken(TokenTypes.LITERAL_NUMBER_HEXADECIMAL); + } + case 259: break; + case 7: + { addToken(start,zzStartRead-1, TokenTypes.MARKUP_COMMENT); return firstToken; + } + case 260: break; + case 94: + { start = zzMarkedPos-2; yybegin(JS_EOL_COMMENT); + } + case 261: break; + case 129: + { start = zzMarkedPos-5; yybegin(HB_COMMENT_2, LANG_INDEX_HANDLEBARS); + } + case 262: break; + case 26: + { addToken(TokenTypes.MARKUP_TAG_DELIMITER); yybegin(CSS, LANG_INDEX_CSS); + } + case 263: break; + case 16: + { start = zzMarkedPos-1; yybegin(INATTR_SINGLE); + } + case 264: break; + case 8: + { addToken(start,zzStartRead-1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); return firstToken; + } + case 265: break; + case 2: + { addToken(TokenTypes.IDENTIFIER); + } + case 266: break; + case 87: + { start = zzMarkedPos-2; yybegin(DTD); + } + case 267: break; + case 37: + { int type = validJSString ? TokenTypes.LITERAL_STRING_DOUBLE_QUOTE : TokenTypes.ERROR_STRING_DOUBLE; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); + } + case 268: break; + case 123: + { addToken(TokenTypes.COMMENT_MULTILINE); + } + case 269: break; + case 38: + { /* Line ending in '\' => continue to next line. */ + if (validJSString) { + addToken(start,zzStartRead, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); + addEndToken(INTERNAL_IN_JS_STRING_VALID); + } + else { + addToken(start,zzStartRead, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_STRING_INVALID); + } + return firstToken; + } + case 270: break; + case 41: + { int type = validJSString ? TokenTypes.LITERAL_CHAR : TokenTypes.ERROR_CHAR; addToken(start,zzStartRead, type); yybegin(JAVASCRIPT); + } + case 271: break; + case 21: + { start = zzMarkedPos-1; yybegin(INATTR_DOUBLE_SCRIPT); + } + case 272: break; + case 134: + { yybegin(YYINITIAL, LANG_INDEX_DEFAULT); + addToken(zzStartRead,zzStartRead+1, TokenTypes.MARKUP_TAG_DELIMITER); + addToken(zzMarkedPos-7,zzMarkedPos-2, TokenTypes.MARKUP_TAG_NAME); + addToken(zzMarkedPos-1,zzMarkedPos-1, TokenTypes.MARKUP_TAG_DELIMITER); + } + case 273: break; + case 1: + { + } + case 274: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + switch (zzLexicalState) { + case INATTR_SINGLE_SCRIPT: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT); return firstToken; + } + case 933: break; + case HB: { + addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 934: break; + case JS_CHAR: { + addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 935: break; + case CSS_STRING: { + addToken(start,zzStartRead-1, TokenTypes.LITERAL_STRING_DOUBLE_QUOTE); addEndToken(INTERNAL_CSS_STRING - cssPrevState); return firstToken; + } + case 936: break; + case JS_MLC: { + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_IN_JS_MLC); return firstToken; + } + case 937: break; + case CSS_CHAR_LITERAL: { + addToken(start,zzStartRead-1, TokenTypes.LITERAL_CHAR); addEndToken(INTERNAL_CSS_CHAR - cssPrevState); return firstToken; + } + case 938: break; + case INTAG_SCRIPT: { + addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG_SCRIPT); return firstToken; + } + case 939: break; + case JS_TEMPLATE_LITERAL_EXPR: { + // TODO: This isn't right. The expression and its depth should continue to the next line. + addToken(start,zzStartRead-1, TokenTypes.VARIABLE); addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); return firstToken; + } + case 940: break; + case CSS_PROPERTY: { + addEndToken(INTERNAL_CSS_PROPERTY); return firstToken; + } + case 941: break; + case CSS_C_STYLE_COMMENT: { + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addEndToken(INTERNAL_CSS_MLC - cssPrevState); return firstToken; + } + case 942: break; + case CSS: { + addEndToken(INTERNAL_CSS); return firstToken; + } + case 943: break; + case CSS_VALUE: { + addEndToken(INTERNAL_CSS_VALUE); return firstToken; + } + case 944: break; + case COMMENT: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_COMMENT); return firstToken; + } + case 945: break; + case INATTR_DOUBLE_SCRIPT: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT); return firstToken; + } + case 946: break; + case PI: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_PROCESSING_INSTRUCTION); return firstToken; + } + case 947: break; + case JAVASCRIPT: { + addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 948: break; + case INTAG: { + addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG); return firstToken; + } + case 949: break; + case INTAG_CHECK_TAG_NAME: { + addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG); return firstToken; + } + case 950: break; + case INATTR_SINGLE_STYLE: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE_QUOTE_STYLE); return firstToken; + } + case 951: break; + case DTD: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_DTD); return firstToken; + } + case 952: break; + case JS_EOL_COMMENT: { + addToken(start,zzStartRead-1, TokenTypes.COMMENT_EOL); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 953: break; + case INATTR_DOUBLE_STYLE: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE_QUOTE_STYLE); return firstToken; + } + case 954: break; + case HB_COMMENT_2: { + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_2); return firstToken; + } + case 955: break; + case HB_CHAR_LITERAL: { + addToken(start,zzStartRead-1, TokenTypes.ERROR_CHAR); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 956: break; + case INATTR_SINGLE: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_SINGLE); return firstToken; + } + case 957: break; + case HB_COMMENT_1: { + addToken(start,zzStartRead-1, TokenTypes.COMMENT_MULTILINE); addHandlebarsEndToken(INTERNAL_IN_HB_MLC_1); return firstToken; + } + case 958: break; + case JS_TEMPLATE_LITERAL: { + if (validJSString) { + addToken(start, zzStartRead - 1, TokenTypes.LITERAL_BACKQUOTE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID); + } + else { + addToken(start,zzStartRead - 1, TokenTypes.ERROR_STRING_DOUBLE); + addEndToken(INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID); + } + return firstToken; + } + case 959: break; + case YYINITIAL: { + addNullToken(); return firstToken; + } + case 960: break; + case INATTR_DOUBLE: { + addToken(start,zzStartRead-1, TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE); addEndToken(INTERNAL_ATTR_DOUBLE); return firstToken; + } + case 961: break; + case JS_STRING: { + addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addEndToken(INTERNAL_IN_JS); return firstToken; + } + case 962: break; + case HB_STRING: { + addToken(start,zzStartRead-1, TokenTypes.ERROR_STRING_DOUBLE); addHandlebarsEndToken(INTERNAL_IN_HB); return firstToken; + } + case 963: break; + case INTAG_STYLE: { + addToken(zzMarkedPos,zzMarkedPos, INTERNAL_INTAG_STYLE); return firstToken; + } + case 964: break; + default: + return null; + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractCDerivedTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractCDerivedTokenMakerTest.java index c29ddf3e5..fc73faa77 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractCDerivedTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractCDerivedTokenMakerTest.java @@ -24,19 +24,24 @@ abstract class AbstractCDerivedTokenMakerTest extends AbstractTokenMakerTest { /** - * Overridden to verify that indentation of the next line is done after curly braces - * and open parens. + * Overridden to assert {@code true} for the default language index. If + * subclasses have additional sub-languages, they should override this method. */ @Test @Override - public void testCommon_getShouldIndentNextLineAfter() { + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { TokenMaker tm = createTokenMaker(); - Token[] indentAfter = { - new TokenImpl("{".toCharArray(), 0, 0, 0, TokenTypes.SEPARATOR, 0), - new TokenImpl("(".toCharArray(), 0, 0, 0, TokenTypes.SEPARATOR, 0), - }; - for (Token token : indentAfter) { - Assertions.assertTrue(tm.getShouldIndentNextLineAfter(token)); - } + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(0)); + } + + + /** + * Overridden to verify that indentation of the next line is done after curly braces + * and open parens for the default language index. + */ + @Test + @Override + protected void testCommon_getShouldIndentNextLineAfter() { + testCommonHelper_getShouldIndentNextLineAfterCurliesAndParensForLanguageIndex(0); } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java index 1b5a03efd..8b9de5026 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java @@ -112,6 +112,18 @@ protected Segment createSegment(String code) { protected abstract TokenMaker createTokenMaker(); + /** + * Verifies whether curly braces denote code blocks for the default language of + * this token maker. The default implementation checks for {@code false}; + * subclasses should override appropriately. + */ + @Test + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks(0)); + } + + /** * Verifies whether the line comment delimiters returned by this token maker are * correct for the primary language. @@ -133,11 +145,22 @@ public void testCommon_getMarkOccurrencesOfTokenType() { } + /** + * Verifies whether the line comment delimiters returned by this token maker are + * correct for the primary language. + */ + @Test + void testCommon_GetOccurrenceMarker() { + TokenMaker tm = createTokenMaker(); + Assertions.assertNotNull(tm.getOccurrenceMarker()); + } + + /** * Verifies the {@code getShouldIndentNextLineAfter()} method. */ @Test - public void testCommon_getShouldIndentNextLineAfter() { + protected void testCommon_getShouldIndentNextLineAfter() { // NOTE: This is a pretty sorry test, but it's hard to test "no token implies indent the next // line," which is the default behavior. @@ -149,6 +172,24 @@ public void testCommon_getShouldIndentNextLineAfter() { } + /** + * Helper method for {@link #testCommon_getShouldIndentNextLineAfter()} to verify that indentation of + * the next ine is done after curly braces and open parens for a specific language index. + * + * @param languageIndex The language index to check. + */ + protected void testCommonHelper_getShouldIndentNextLineAfterCurliesAndParensForLanguageIndex(int languageIndex) { + TokenMaker tm = createTokenMaker(); + Token[] indentAfter = { + new TokenImpl("{".toCharArray(), 0, 0, 0, TokenTypes.SEPARATOR, languageIndex), + new TokenImpl("(".toCharArray(), 0, 0, 0, TokenTypes.SEPARATOR, languageIndex), + }; + for (Token token : indentAfter) { + Assertions.assertTrue(tm.getShouldIndentNextLineAfter(token)); + } + } + + @Test void testCommon_yyclose() throws IOException { TokenMaker tm = createTokenMaker(); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/CSSTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/CSSTokenMakerTest.java index 8627d73b2..6c2aa40ae 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/CSSTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/CSSTokenMakerTest.java @@ -161,13 +161,6 @@ void testCss_char_continuedFromPreviousLine() { } - @Test - void testCss_getCurlyBracesDenoteCodeBlocks() { - TokenMaker tm = createTokenMaker(); - Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(0)); - } - - @Test protected void testCss_getLineCommentStartAndEnd() { String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd(0); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java index 3a07c724b..339d35065 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java @@ -124,6 +124,19 @@ protected TokenMaker createTokenMaker() { } + @Test + @Override + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks( + HTMLTokenMaker.LANG_INDEX_DEFAULT)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + HTMLTokenMaker.LANG_INDEX_CSS)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + HTMLTokenMaker.LANG_INDEX_JS)); + } + + @Test @Override public void testCommon_GetLineCommentStartAndEnd() { @@ -216,14 +229,6 @@ void testCss_char_continuedFromPreviousLine() { } - @Test - void testCss_getCurlyBracesDenoteCodeBlocks() { - TokenMaker tm = createTokenMaker(); - Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( - HTMLTokenMaker.LANG_INDEX_CSS)); - } - - @Test void testCss_happyPath_stateContinuesToNextLine_mainState() { TokenMaker tm = createTokenMaker(); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMakerTest.java new file mode 100644 index 000000000..1fb8aeced --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMakerTest.java @@ -0,0 +1,1949 @@ +/* + * 03/23/2015 + * + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea.modes; + +import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.TokenMaker; +import org.fife.ui.rsyntaxtextarea.TokenTypes; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import javax.swing.text.Segment; + + +/** + * Unit tests for the {@link HandlebarsTokenMaker} class. + * + * @author Robert Futrell + * @version 1.0 + */ +class HandlebarsTokenMakerTest extends AbstractTokenMakerTest { + + /** + * The last token type on the previous line for this token maker to + * start parsing a new line as CSS. This constant is only here so we can + * copy and paste tests from this class into others, such as HTML, PHP, and + * JSP token maker tests, with as little change as possible. + */ + private static final int CSS_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS; + + /** + * The last token type on the previous line for this token maker to + * start parsing a new line as part of a CSS multi-line comment. This constant + * is only here so we can copy and paste tests from this class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as possible. + */ + private static final int CSS_MLC_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS_MLC; + + /** + * The last token type on the previous line for this token maker to start + * parsing a new line as part of a CSS property key/value block. This constant + * is only here so we can copy and paste tests from this class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as possible. + */ + private static final int CSS_PROPERTY_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS_PROPERTY; + + /** + * The last token type on the previous line for this token maker to start + * parsing a new line as part of a CSS property key/value block. This constant + * is only here so we can copy and paste tests from this class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as possible. + */ + private static final int CSS_VALUE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS_VALUE; + + /** + * The last token type on the previous line for this token maker to start + * parsing a new line as part of a string property value. This constant + * is only here so we can copy and paste tests from this class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as possible. + */ + private static final int CSS_STRING_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS_STRING; + + /** + * The last token type on the previous line for this token maker to start + * parsing a new line as part of a char property value. This constant + * is only here so we can copy and paste tests from this class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as possible. + */ + private static final int CSS_CHAR_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_CSS_CHAR; + + private static final int HTML_ATTR_DOUBLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_DOUBLE; + + private static final int HTML_ATTR_SINGLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_SINGLE; + + private static final int HTML_ATTR_SCRIPT_DOUBLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_DOUBLE_QUOTE_SCRIPT; + + private static final int HTML_ATTR_SCRIPT_SINGLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_SINGLE_QUOTE_SCRIPT; + + private static final int HTML_ATTR_STYLE_DOUBLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_DOUBLE_QUOTE_STYLE; + + private static final int HTML_ATTR_STYLE_SINGLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_ATTR_SINGLE_QUOTE_STYLE; + + private static final int HTML_INTAG_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_INTAG; + + private static final int HTML_INTAG_SCRIPT_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_INTAG_SCRIPT; + + private static final int HTML_INTAG_STYLE_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_INTAG_STYLE; + + /** + * The last token type on the previous line for this token maker to + * start parsing a new line as JS. This constant is only here so we can + * copy and paste tests from the JavaScriptTokenMakerTest class into others, + * such as HTML, PHP, and JSP token maker tests, with as little change as + * possible. + */ + private static final int JS_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS; + + private static final int JS_MLC_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_MLC; + + private static final int JS_INVALID_STRING_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_STRING_INVALID; + + private static final int JS_VALID_STRING_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_STRING_VALID; + + private static final int JS_INVALID_CHAR_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_CHAR_INVALID; + + private static final int JS_VALID_CHAR_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_CHAR_VALID; + + private static final int JS_INVALID_TEMPLATE_LITERAL_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_TEMPLATE_LITERAL_INVALID; + + private static final int JS_VALID_TEMPLATE_LITERAL_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_JS_TEMPLATE_LITERAL_VALID; + + private static final int HB_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_HB; + + private static final int HB_MLC_1_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_HB_MLC_1; + + private static final int HB_MLC_2_PREV_TOKEN_TYPE = HandlebarsTokenMaker.INTERNAL_IN_HB_MLC_2; + + /** + * Returns a new instance of the TokenMaker to test. + * + * @return The TokenMaker to test. + */ + @Override + protected TokenMaker createTokenMaker() { + return new HandlebarsTokenMaker(); + } + + + @Test + @Override + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks( + HandlebarsTokenMaker.LANG_INDEX_DEFAULT)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + HandlebarsTokenMaker.LANG_INDEX_CSS)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + HandlebarsTokenMaker.LANG_INDEX_JS)); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks( + HandlebarsTokenMaker.LANG_INDEX_HANDLEBARS)); + } + + + @Test + @Override + public void testCommon_GetLineCommentStartAndEnd() { + String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( + HandlebarsTokenMaker.LANG_INDEX_DEFAULT); + Assertions.assertEquals("", startAndEnd[1]); + } + + + @Test + void testCommon_getLineCommentStartAndEnd_css() { + String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( + HandlebarsTokenMaker.LANG_INDEX_CSS); + Assertions.assertEquals("/*", startAndEnd[0]); + Assertions.assertEquals("*/", startAndEnd[1]); + } + + + @Test + void testCommon_getLineCommentStartAndEnd_js() { + String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( + HandlebarsTokenMaker.LANG_INDEX_JS); + Assertions.assertEquals("//", startAndEnd[0]); + Assertions.assertNull(startAndEnd[1]); + } + + + @Test + void testCommon_getLineCommentStartAndEnd_handlebars() { + String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( + HandlebarsTokenMaker.LANG_INDEX_HANDLEBARS); + Assertions.assertEquals("{{!--", startAndEnd[0]); + Assertions.assertEquals("--}}", startAndEnd[1]); + } + + + @Test + void testCommon_getSetCloseCompleteTags() { + HandlebarsTokenMaker tm = (HandlebarsTokenMaker)createTokenMaker(); + Assertions.assertFalse(tm.getCompleteCloseTags()); + try { + HandlebarsTokenMaker.setCompleteCloseTags(true); + Assertions.assertTrue(tm.getCompleteCloseTags()); + } finally { + HandlebarsTokenMaker.setCompleteCloseTags(false); + } + } + + + @Test + @Override + public void testCommon_getMarkOccurrencesOfTokenType() { + + TokenMaker tm = createTokenMaker(); + + for (int i = 0; i < TokenTypes.DEFAULT_NUM_TOKEN_TYPES; i++) { + boolean expected = i == TokenTypes.MARKUP_TAG_NAME; + Assertions.assertEquals(expected, tm.getMarkOccurrencesOfTokenType(i)); + } + } + + + @Test + @Override + protected void testCommon_getShouldIndentNextLineAfter() { + testCommonHelper_getShouldIndentNextLineAfterCurliesAndParensForLanguageIndex( + HandlebarsTokenMaker.LANG_INDEX_CSS); + testCommonHelper_getShouldIndentNextLineAfterCurliesAndParensForLanguageIndex( + HandlebarsTokenMaker.LANG_INDEX_JS); + } + + + @Test + void testCss_atRule() { + assertAllTokensOfType(TokenTypes.REGEX, + CSS_PREV_TOKEN_TYPE, + "@charset", + "@import", + "@namespace", + "@media", + "@document", + "@page", + "@font-face", + "@keyframes", + "@viewport" + ); + } + + + @Test + void testCss_chars() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + CSS_PREV_TOKEN_TYPE, + "'Hello world'", + "'Hello \\'world\\''" + ); + } + + + @Test + void testCss_char_continuedFromPreviousLine() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + CSS_CHAR_PREV_TOKEN_TYPE, + "world'", + "and \\'he\\' said so'", + "continuation from a prior line" + ); + } + + + @Test + void testCss_happyPath_stateContinuesToNextLine_mainState() { + TokenMaker tm = createTokenMaker(); + Segment segment = createSegment(""); + Token token = tm.getTokenList(segment, CSS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(CSS_PREV_TOKEN_TYPE, token.getType()); + } + + + @Test + void testCss_happyPath_stateContinuesToNextLine_valueState() { + TokenMaker tm = createTokenMaker(); + Segment segment = createSegment(""); + Token token = tm.getTokenList(segment, CSS_VALUE_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(CSS_VALUE_PREV_TOKEN_TYPE, token.getType()); + } + + + @Test + void testCss_happyPath_styleEndTagSwitchesState() { + Segment segment = createSegment(""); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, CSS_PREV_TOKEN_TYPE, 0); + + Assertions.assertEquals(TokenTypes.MARKUP_TAG_DELIMITER, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.MARKUP_TAG_NAME, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.MARKUP_TAG_DELIMITER, token.getType()); + } + + + @Test + void testCss_happyPath_simpleSelector() { + + String code = "body { padding: 0; }"; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, CSS_PREV_TOKEN_TYPE, 0); + + Assertions.assertTrue(token.is(TokenTypes.DATA_TYPE, "body")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, "{")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.RESERVED_WORD, "padding")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ":")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, "0")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ";")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, "}")); + + } + + + @Test + void testCss_id() { + + String code = "#mainContent"; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, CSS_PREV_TOKEN_TYPE, 0); + + Assertions.assertTrue(token.is(TokenTypes.VARIABLE, "#mainContent")); + + } + + @Test + void testCss_isIdentifierChar() { + + TokenMaker tm = createTokenMaker(); + int langIndex = HandlebarsTokenMaker.LANG_INDEX_CSS; + + for (int ch = 'A'; ch <= 'Z'; ch++) { + Assertions.assertTrue(tm.isIdentifierChar(langIndex, (char)ch)); + Assertions.assertTrue(tm.isIdentifierChar(langIndex, (char)(ch+('a'-'A')))); + } + Assertions.assertTrue(tm.isIdentifierChar(langIndex, '-')); + Assertions.assertTrue(tm.isIdentifierChar(langIndex, '_')); + Assertions.assertTrue(tm.isIdentifierChar(langIndex, '.')); + } + + + @Test + void testCss_lessLineComment_noLess() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + CSS_PREV_TOKEN_TYPE, + false, + "//" + ); + } + + + @Test + void testCss_lessVar_noLess() { + assertAllTokensOfType(TokenTypes.REGEX, + CSS_PREV_TOKEN_TYPE, + "@something", + "@something-else" + ); + } + + + @Test + void testCss_multiLineComment() { + + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, CSS_PREV_TOKEN_TYPE, + "/* Hello world */", + "/* unterminated", + "/**/" + ); + } + + + @Test + void testCss_multiLineComment_continuedFromPreviousLine() { + + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, CSS_MLC_PREV_TOKEN_TYPE, + " world */", + "still unterminated" + ); + } + + + @Test + void testCss_multiLineComment_URL() { + + String[] comments = { + "/* Hello world file://test.txt */", + "/* Hello world ftp://ftp.google.com */", + "/* Hello world https://www.google.com */", + "/* Hello world https://www.google.com */", + "/* Hello world www.google.com */" + }; + + for (String comment : comments) { + + Segment segment = createSegment(comment); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, CSS_PREV_TOKEN_TYPE, 0); + + Assertions.assertFalse(token.isHyperlink()); + Assertions.assertTrue(token.is(TokenTypes.COMMENT_MULTILINE, "/* Hello world ")); + + token = token.getNextToken(); + Assertions.assertTrue(token.isHyperlink()); + + token = token.getNextToken(); + Assertions.assertFalse(token.isHyperlink()); + Assertions.assertTrue(token.is(TokenTypes.COMMENT_MULTILINE, " */")); + } + } + + + @Test + void testCss_operators() { + assertAllTokensOfType(TokenTypes.OPERATOR, + CSS_PREV_TOKEN_TYPE, + "+", + ">", + "~", + "^", + "$", + "|", + "=" + ); + } + + + @Test + void testCss_propertyBlock_property_multiLineComment() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + CSS_PROPERTY_PREV_TOKEN_TYPE, + "/* Hello world */", + "/* unterminated", + "/**/" + ); + } + + + @Test + void testCss_propertyBlock_property_properties() { + assertAllTokensOfType(TokenTypes.RESERVED_WORD, + CSS_PROPERTY_PREV_TOKEN_TYPE, + "*foo", + "foo", + "_", + "*_", + "foo9" + ); + } + + + @Test + void testCss_propertyBlock_property_operators() { + assertAllTokensOfType(TokenTypes.OPERATOR, + CSS_PROPERTY_PREV_TOKEN_TYPE, + ":" + ); + } + + + @Test + void testCss_propertyBlock_property_separators() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + CSS_PROPERTY_PREV_TOKEN_TYPE, + "{", + "}" + ); + } + + + @Test + void testCss_propertyBlock_value_charLiteral() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + CSS_VALUE_PREV_TOKEN_TYPE, + "'foobar'" + ); + } + + + @Test + void testCss_propertyBlock_value_function() { + assertAllTokensOfType(TokenTypes.FUNCTION, + CSS_VALUE_PREV_TOKEN_TYPE, + false, + "func(" + ); + } + + + @Test + void testCss_propertyBlock_value_identifier() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + CSS_VALUE_PREV_TOKEN_TYPE, + "foobar", + ",", + "." + ); + } + + + @Test + void testCss_propertyBlock_value_important() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + CSS_VALUE_PREV_TOKEN_TYPE, + "!important" + ); + } + + + @Test + void testCss_propertyBlock_value_multiLineComment() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + CSS_VALUE_PREV_TOKEN_TYPE, + "/* Hello world */", + "/* unterminated", + "/**/" + ); + } + + + @Test + void testCss_propertyBlock_value_number() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, + CSS_VALUE_PREV_TOKEN_TYPE, + "42", + "42.", + "42.3", + "-42", + "-42.", + "-42.3", + "4pt", + "4pc", + "4in", + "4mm", + "4cm", + "4em", + "4ex", + "4px", + "4ms", + "4s", + "4%", + "#0", + "#0A", + "#0a", + "#ff00ff" + ); + } + + + @Test + void testCss_propertyBlock_value_operators() { + assertAllTokensOfType(TokenTypes.OPERATOR, + CSS_VALUE_PREV_TOKEN_TYPE, + ";" + ); + } + + + @Test + void testCss_propertyBlock_value_separators() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + CSS_VALUE_PREV_TOKEN_TYPE, + ")", + "}" + ); + } + + + @Test + void testCss_propertyBlock_value_string() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + CSS_VALUE_PREV_TOKEN_TYPE, + "\"foobar\"" + ); + } + + + @Test + void testCss_propertyValue_function() { + + String code = "background-image: url(\"test.png\");"; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, HandlebarsTokenMaker.INTERNAL_CSS_PROPERTY, 0); + + Assertions.assertTrue(token.is(TokenTypes.RESERVED_WORD, "background-image")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ":")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.FUNCTION, "url")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, "(")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, "\"test.png\"")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, ")")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ";")); + + code = "background-image: url('test.png');"; + segment = createSegment(code); + tm = createTokenMaker(); + token = tm.getTokenList(segment, HandlebarsTokenMaker.INTERNAL_CSS_PROPERTY, 0); + + Assertions.assertTrue(token.is(TokenTypes.RESERVED_WORD, "background-image")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ":")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.FUNCTION, "url")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, "(")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.LITERAL_CHAR, "'test.png'")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.SEPARATOR, ")")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.OPERATOR, ";")); + + } + + + @Test + void testCss_pseudoClass() { + assertAllTokensOfType(TokenTypes.RESERVED_WORD, + CSS_PREV_TOKEN_TYPE, + ":root", + ":nth-child", + ":nth-last-child", + ":nth-of-type", + ":nth-last-of-type", + ":first-child", + ":last-child", + ":first-of-type", + ":last-of-type", + ":only-child", + ":only-of-type", + ":empty", + ":link", + ":visited", + ":active", + ":hover", + ":focus", + ":target", + ":lang", + ":enabled", + ":disabled", + ":checked", + "::first-line", + "::first-letter", + "::before", + "::after", + ":not" + ); + } + + + @Test + void testCss_pseudoClass_unknown() { + assertAllTokensOfType(TokenTypes.DATA_TYPE, + CSS_PREV_TOKEN_TYPE, + ":" + ); + } + + + @Test + void testCss_selectors() { + assertAllTokensOfType(TokenTypes.DATA_TYPE, + CSS_PREV_TOKEN_TYPE, + "*", + ".", + ".foo", + ".foo-bar", + "foo", + "-foo-bar", + "foo-bar"); + } + + + @Test + void testCss_separators() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + CSS_PREV_TOKEN_TYPE, + ";", + "(", + ")", + "[", + "]" + ); + } + + + @Test + void testCss_strings() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + CSS_PREV_TOKEN_TYPE, + "\"Hello world\"", + "\"Hello \\\"world\\\"", + "\"Unterminated string" + ); + } + + + @Test + void testCss_string_continuedFromPreviousLine() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + CSS_STRING_PREV_TOKEN_TYPE, + "world\"", + "and \\\"he\\\" said so\"" + ); + } + + + @Test + void testHandlebars_blockEnd_twoCurliesBlock() { + + // Because of the internal state tracking the number of curlies, we need + // separate setup for each scenario + + TokenMaker tm = createTokenMaker(); + + Token t = tm.getTokenList(createSegment("{{}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}")); + + t = tm.getTokenList(createSegment("{{}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}")); + + t = tm.getTokenList(createSegment("{{}}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}}")); + } + + + @Test + void testHandlebars_blockEnd_threeCurliesBlock() { + + // Because of the internal state tracking the number of curlies, we need + // separate setup for each scenario + + TokenMaker tm = createTokenMaker(); + + Token t = tm.getTokenList(createSegment("{{{}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}}")); + + t = tm.getTokenList(createSegment("{{{}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}}")); + + t = tm.getTokenList(createSegment("{{{}}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}}")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}")); + } + + + @Test + void testHandlebars_blockEnd_fourCurliesBlock() { + + // Because of the internal state tracking the number of curlies, we need + // separate setup for each scenario + + TokenMaker tm = createTokenMaker(); + + Token t = tm.getTokenList(createSegment("{{{{}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}}")); + + t = tm.getTokenList(createSegment("{{{{}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.IDENTIFIER, "}}}")); + + t = tm.getTokenList(createSegment("{{{{}}}}"), 0, 0); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "{{{{")); + t = t.getNextToken(); + Assertions.assertTrue(t.is(TokenTypes.SEPARATOR, "}}}}")); + } + + + @Test + void testHandlebars_blockStart() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + "{{", + "{{{", + "{{{{" + ); + } + + + @Test + void testHandlebars_booleanLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_BOOLEAN, + HB_PREV_TOKEN_TYPE, + "true", + "false" + ); + } + + + @Test + void testHandlebars_comments_type1() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + "{{! This is a comment }}", + "{{! This is an unterminated comment", + "{{!" + ); + } + + + @Test + void testHandlebars_comments_type1_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + HB_MLC_1_PREV_TOKEN_TYPE, + "continued from a previous line and unterminated", + "continued from a previous line}}" + ); + } + + + @Test + void testHandlebars_comments_type2() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + "{{!-- This is a comment --}}", + "{{!-- This is a comment with }} embedded curlies --}}", + "{{!-- This is an unterminated comment", + "{{!--" + ); + } + + + @Test + void testHandlebars_comments_type2_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + HB_MLC_2_PREV_TOKEN_TYPE, + "continued from a previous line and unterminated", + "continued from a previous line and unterminated with }} embedded curlies", + "continued from a previous line--}}" + ); + } + + + @Test + void testHandlebars_functions() { + assertAllTokensOfType(TokenTypes.FUNCTION, + HB_PREV_TOKEN_TYPE, + "#if", + "#unless", + "#each", + "#with", + "/if", + "/unless", + "/each", + "/with", + "lookup", + "log" + ); + } + + + @Test + void testHandlebars_identifiers() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + HB_PREV_TOKEN_TYPE, + "foo", + "snake_case" + ); + } + + + @Test + void testHandlebars_keywords() { + assertAllTokensOfType(TokenTypes.RESERVED_WORD, + HB_PREV_TOKEN_TYPE, + "else", + "null", + "undefined" + ); + } + + @Test + void testHandlebars_numericLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_FLOAT, + HB_PREV_TOKEN_TYPE, + "0", + "42", + "3.987", + "-42", + "-3.987" + ); + } + + + @Test + void testHandlebars_operators() { + assertAllTokensOfType(TokenTypes.OPERATOR, + HB_PREV_TOKEN_TYPE, + "!", + "%", + "&", + "*", + "+", + ",", + ".", + "/", + ";", + "<", + "=", + ">", + "@", + "`", + "|", + "^", + "~" + ); + } + + + @Test + void testHandlebars_separators() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + HB_PREV_TOKEN_TYPE, + "{", + "}", + "[", + "]", + "(", + ")" + ); + } + + + @Test + void testHandlebars_strings_doubleQuotes() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + HB_PREV_TOKEN_TYPE, + "\"This is a string\"", + "\"This is a \\\"string\\\" with escapes\"" + ); + } + + + @Test + void testHandlebars_strings_doubleQuotes_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + HB_PREV_TOKEN_TYPE, + "\"Terminated with \\iinvalid escape\"", + "\"Unterminated string", + "\"Unterminated with \\iinvalid escape" + ); + } + + + @Test + void testHandlebars_strings_singleQuotes() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + HB_PREV_TOKEN_TYPE, + "'This is a string'", + "'This is a \\'string\\' with escapes'" + ); + } + + + @Test + void testHandlebars_strings_singleQuotes_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + HB_PREV_TOKEN_TYPE, + "'Terminated with \\iinvalid escape'", + "'Unterminated string", + "'Unterminated with \\iinvalid escape" + ); + } + + + @Test + void testHtml_attribute_doubleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_INTAG_PREV_TOKEN_TYPE, + "\"attribute value\"", + "\"unclosed attribute value" + ); + } + + + @Test + void testHtml_attribute_doubleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_DOUBLE_PREV_TOKEN_TYPE, + "continued from prior line\"", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_attribute_singleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HandlebarsTokenMaker.INTERNAL_INTAG, + "'attribute value'", + "'unclosed attribute value" + ); + } + + + @Test + void testHtml_attribute_singleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_SINGLE_PREV_TOKEN_TYPE, + "continued from prior line'", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_attributeScriptTag_doubleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_INTAG_SCRIPT_PREV_TOKEN_TYPE, + "\"attribute value\"", + "\"unclosed attribute value" + ); + } + + + @Test + void testHtml_attributeScriptTag_doubleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_SCRIPT_DOUBLE_PREV_TOKEN_TYPE, + "continued from prior line\"", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_attributeScriptTag_singleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HandlebarsTokenMaker.INTERNAL_INTAG_SCRIPT, + "'attribute value'", + "'unclosed attribute value" + ); + } + + + @Test + void testHtml_attributeScriptTag_singleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_SCRIPT_SINGLE_PREV_TOKEN_TYPE, + "continued from prior line'", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_attributeStyleTag_doubleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_INTAG_STYLE_PREV_TOKEN_TYPE, + "\"attribute value\"", + "\"unclosed attribute value" + ); + } + + + @Test + void testHtml_attributeStyleTag_doubleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_STYLE_DOUBLE_PREV_TOKEN_TYPE, + "continued from prior line\"", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_attributeStyleTag_singleQuote() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_INTAG_STYLE_PREV_TOKEN_TYPE, + "'attribute value'", + "'unclosed attribute value" + ); + } + + + @Test + void testHtml_attributeStyleTag_singleQuote_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, + HTML_ATTR_STYLE_SINGLE_PREV_TOKEN_TYPE, + "continued from prior line'", + "continued and still unterminated" + ); + } + + + @Test + void testHtml_comment() { + assertAllTokensOfType(TokenTypes.MARKUP_COMMENT, + TokenTypes.NULL, + "", + "" + ); + } + + + @Test + void testHtml_comment_URL() { + + String[] urls = { + "file://test.txt", + "ftp://ftp.google.com", + "https://www.google.com", + "https://www.google.com", + "www.google.com" + }; + + for (String literal : urls) { + + Segment segment = createSegment(literal); + TokenMaker tm = createTokenMaker(); + + Token token = tm.getTokenList(segment, TokenTypes.MARKUP_COMMENT, 0); + Assertions.assertTrue(token.isHyperlink()); + Assertions.assertEquals(TokenTypes.MARKUP_COMMENT, token.getType()); + Assertions.assertEquals(literal, token.getLexeme()); + } + } + + + @Test + void testHtml_doctype() { + + String[] doctypes = { + "", + "", + "", + ""; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); + + Assertions.assertTrue(token.isSingleChar(TokenTypes.MARKUP_TAG_DELIMITER, '<')); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_NAME, "body")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE, "onload")); + token = token.getNextToken(); + Assertions.assertTrue(token.isSingleChar(TokenTypes.OPERATOR, '=')); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, "\"doSomething()\""), "Unexpected token: " + token); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE, "data-extra")); + token = token.getNextToken(); + Assertions.assertTrue(token.isSingleChar(TokenTypes.OPERATOR, '=')); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, "'true'")); + token = token.getNextToken(); + Assertions.assertTrue(token.isSingleChar(TokenTypes.MARKUP_TAG_DELIMITER, '>')); + + } + + + @Test + void testHtml_happyPath_closedTag() { + + String code = ""; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); + + Assertions.assertTrue(token.isSingleChar(TokenTypes.MARKUP_TAG_DELIMITER, '<')); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_NAME, "img")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE, "src")); + token = token.getNextToken(); + Assertions.assertTrue(token.isSingleChar(TokenTypes.OPERATOR, '=')); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_ATTRIBUTE_VALUE, "'foo.png'"), "Unexpected token: " + token); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_DELIMITER, "/>")); + + } + + + @Test + void testHtml_happyPath_closingTag() { + + String code = ""; + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); + + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_DELIMITER, "')); + + } + + + @Test + void testHtml_inTag_unterminatedOnThisLine() { + Segment segment = createSegment(""); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, HandlebarsTokenMaker.INTERNAL_INTAG, 0); + Assertions.assertEquals(HandlebarsTokenMaker.INTERNAL_INTAG, token.getType()); + } + + + @Test + void testHtml_inTagScript_unterminatedOnThisLine() { + Segment segment = createSegment(""); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, HandlebarsTokenMaker.INTERNAL_INTAG_SCRIPT, 0); + Assertions.assertEquals(HandlebarsTokenMaker.INTERNAL_INTAG_SCRIPT, token.getType()); + } + + + @Test + void testHtml_inTagStyle_unterminatedOnThisLine() { + Segment segment = createSegment(""); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, HandlebarsTokenMaker.INTERNAL_INTAG_STYLE, 0); + Assertions.assertEquals(HandlebarsTokenMaker.INTERNAL_INTAG_STYLE, token.getType()); + } + + + @Test + void testHtml_processingInstructions() { + + String[] doctypes = { + "", + "", + "", + " 0) { + tagName = tagName.substring(0, i).toUpperCase() + + tagName.substring(i); + } + + String code = "<" + tagName; + Segment segment = createSegment(code); + Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); + Assertions.assertTrue(token.isSingleChar(TokenTypes.MARKUP_TAG_DELIMITER, '<')); + token = token.getNextToken(); + Assertions.assertEquals(token.getType(), TokenTypes.MARKUP_TAG_NAME); + + } + + } + + } + + + @Test + void testHtml_loneIdentifier() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + "foo", + "123" + ); + } + + + @Test + void testJS_BooleanLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_BOOLEAN, + JS_PREV_TOKEN_TYPE, + "true", + "false" + ); + } + + + @Test + void testJS_CharLiterals_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + JS_PREV_TOKEN_TYPE, + "'\\xG7'", // Invalid hex/octal escape + "'foo\\ubar'", "'\\u00fg'", // Invalid Unicode escape + "'My name is \\ubar and I \\", // Continued onto another line + "'This is unterminated and " // Unterminated string + ); + } + + + @Test + void testJS_CharLiterals_valid() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + JS_PREV_TOKEN_TYPE, "'a'", "'\\b'", "'\\t'", "'\\r'", "'\\f'", "'\\n'", "'\\u00fe'", + "'\\u00FE'", "'\\111'", "'\\222'", "'\\333'", + "'\\x77'", + "'\\11'", "'\\22'", "'\\33'", + "'\\1'", + "'My name is Robert and I \\" // Continued onto another line + ); + } + + + @Test + void testJS_CharLiterals_fromPriorLine_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + JS_INVALID_CHAR_PREV_TOKEN_TYPE, + "still an invalid char literal", + "still an invalid char literal even though terminated'" + ); + } + + + @Test + void testJS_CharLiterals_fromPriorLine_valid() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + JS_VALID_CHAR_PREV_TOKEN_TYPE, + "still a valid char literal'" + ); + } + + + @Test + void testJS_DataTypes() { + assertAllTokensOfType(TokenTypes.DATA_TYPE, + JS_PREV_TOKEN_TYPE, + "boolean", + "byte", + "char", + "double", + "float", + "int", + "long", + "short" + ); + } + + + @Test + void testJS_EolComments() { + + String[] eolCommentLiterals = { + "// Hello world", + }; + + for (String code : eolCommentLiterals) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.COMMENT_EOL, token.getType()); + } + + } + + + @Test + void testJS_EolComments_URL() { + + String[] eolCommentLiterals = { + // Note: The 0-length token at the end of the first example is a + // minor bug/performance thing + "// Hello world https://www.sas.com", + "// Hello world https://www.sas.com extra", + "// Hello world https://www.sas.com", + "// Hello world www.sas.com", + "// Hello world ftp://sas.com", + "// Hello world file://test.txt", + }; + + for (String code : eolCommentLiterals) { + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.COMMENT_EOL, token.getType()); + + token = token.getNextToken(); + Assertions.assertTrue(token.isHyperlink()); + Assertions.assertEquals(TokenTypes.COMMENT_EOL, token.getType()); + + token = token.getNextToken(); + // Note: The 0-length token at the end of the first example is a + // minor bug/performance thing + if (token != null && token.isPaintable() && token.length() > 0) { + Assertions.assertFalse(token.isHyperlink()); + Assertions.assertTrue(token.is(TokenTypes.COMMENT_EOL, " extra")); + } + + } + + } + + + @Test + void testJS_FloatingPointLiterals() { + + String code = + // Basic doubles + "3.0 4.2 3.0 4.2 .111 " + + // Basic floats ending in f, F, d, or D + "3f 3F 3d 3D 3.f 3.F 3.d 3.D 3.0f 3.0F 3.0d 3.0D .111f .111F .111d .111D " + + // lower-case exponent, no sign + "3e7f 3e7F 3e7d 3e7D 3.e7f 3.e7F 3.e7d 3.e7D 3.0e7f 3.0e7F 3.0e7d 3.0e7D .111e7f .111e7F .111e7d .111e7D " + + // Upper-case exponent, no sign + "3E7f 3E7F 3E7d 3E7D 3.E7f 3.E7F 3.E7d 3.E7D 3.0E7f 3.0E7F 3.0E7d 3.0E7D .111E7f .111E7F .111E7d .111E7D " + + // Lower-case exponent, positive + "3e+7f 3e+7F 3e+7d 3e+7D 3.e+7f 3.e+7F 3.e+7d 3.e+7D 3.0e+7f 3.0e+7F 3.0e+7d 3.0e+7D .111e+7f .111e+7F .111e+7d .111e+7D " + + // Upper-case exponent, positive + "3E+7f 3E+7F 3E+7d 3E+7D 3.E+7f 3.E+7F 3.E+7d 3.E+7D 3.0E+7f 3.0E+7F 3.0E+7d 3.0E+7D .111E+7f .111E+7F .111E+7d .111E+7D " + + // Lower-case exponent, negative + "3e-7f 3e-7F 3e-7d 3e-7D 3.e-7f 3.e-7F 3.e-7d 3.e-7D 3.0e-7f 3.0e-7F 3.0e-7d 3.0e-7D .111e-7f .111e-7F .111e-7d .111e-7D " + + // Upper-case exponent, negative + "3E-7f 3E-7F 3E-7d 3E-7D 3.E-7f 3.E-7F 3.E-7d 3.E-7D 3.0E-7f 3.0E-7F 3.0E-7d 3.0E-7D .111E-7f .111E-7F .111E-7d .111E-7D"; + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + + String[] numbers = code.split(" +"); + for (int i = 0; i < numbers.length; i++) { + Assertions.assertEquals(numbers[i], token.getLexeme()); + Assertions.assertEquals(TokenTypes.LITERAL_NUMBER_FLOAT, token.getType()); + if (i < numbers.length - 1) { + token = token.getNextToken(); + Assertions.assertTrue(token.isWhitespace(), "Not a whitespace token: " + token); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + } + token = token.getNextToken(); + } + + Assertions.assertEquals(JS_PREV_TOKEN_TYPE, token.getType(), "Wrong type for " + token); + + } + + + @Test + void testJS_Functions() { + assertAllTokensOfType(TokenTypes.FUNCTION, + JS_PREV_TOKEN_TYPE, + "eval", + "parseInt", + "parseFloat", + "escape", + "unescape", + "isNaN", + "isFinite" + ); + } + + + @Test + void testJS_HexLiterals() { + + String code = "0x1 0xfe 0x333333333333 0X1 0Xfe 0X33333333333 0xFE 0XFE " + + "0x1l 0xfel 0x333333333333l 0X1l 0Xfel 0X33333333333l 0xFEl 0XFEl " + + "0x1L 0xfeL 0x333333333333L 0X1L 0XfeL 0X33333333333L 0xFEL 0XFEL "; + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + + String[] literals = code.split(" +"); + for (int i = 0; i < literals.length; i++) { + Assertions.assertEquals(literals[i], token.getLexeme()); + Assertions.assertEquals(TokenTypes.LITERAL_NUMBER_HEXADECIMAL, token.getType(), "Not a hex number: " + token); + if (i < literals.length - 1) { + token = token.getNextToken(); + Assertions.assertTrue(token.isWhitespace(), "Not a whitespace token: " + token); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " ")); + } + token = token.getNextToken(); + } + + } + + + @Test + void testJS_Identifiers() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + JS_PREV_TOKEN_TYPE, + "foo", + "$bar", + "var1" + ); + } + + + @Test + void testJS_Identifiers_errors() { + assertAllTokensOfType(TokenTypes.ERROR_IDENTIFIER, + JS_PREV_TOKEN_TYPE, + "\\" + ); + } + + + @Test + void testJS_Keywords() { + assertAllTokensOfType(TokenTypes.RESERVED_WORD, + JS_PREV_TOKEN_TYPE, + "async", "await", + "break", "case", "catch", "class", "const", "continue", + "debugger", "default", "delete", "do", "else", "export", "extends", "finally", "for", "function", "if", + "import", "in", "instanceof", "let", "new", "of", "super", "switch", + "this", "throw", "try", "typeof", "void", "while", "with", "yield", + "NaN", "Infinity", + "let" // As of 1.7, which is our default version + ); + + assertAllTokensOfType(TokenTypes.RESERVED_WORD_2, + JS_PREV_TOKEN_TYPE, + "return" + ); + } + + + @Test + void testJS_MultiLineComments() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + JS_PREV_TOKEN_TYPE, + "/* Hello world */", + "/* Hello world unterminated", + "/**/" + ); + } + + + @Test + void testJS_MultiLineComments_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + JS_MLC_PREV_TOKEN_TYPE, + " this is continued from a prior line */", + " this is also continued, but not terminated" + ); + } + + + @Test + void testJS_MultiLineComments_URL() { + String[] mlcLiterals = { + "/* Hello world file://test.txt */", + "/* Hello world ftp://ftp.google.com */", + "/* Hello world https://www.google.com */", + "/* Hello world https://www.google.com */", + "/* Hello world www.google.com */" + }; + + for (String code : mlcLiterals) { + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); + + token = token.getNextToken(); + Assertions.assertTrue(token.isHyperlink()); + Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); + + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); + Assertions.assertEquals(" */", token.getLexeme()); + + } + + } + + + @Test + void testJS_Numbers() { + + String[] ints = { + "0", "42", /*"-7",*/ + "0l", "42l", + "0L", "42L", + }; + + for (String code : ints) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, token.getType()); + } + + String[] floats = { + "1e17", "3.14159", "5.7e-8", "2f", "2d", + }; + + for (String code : floats) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.LITERAL_NUMBER_FLOAT, token.getType()); + } + + String[] hex = { + "0x1f", "0X1f", "0x1F", "0X1F", + }; + + for (String code : hex) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.LITERAL_NUMBER_HEXADECIMAL, token.getType()); + } + + String[] errors = { + "42foo", "1e17foo", "0x1ffoo", + }; + + for (String code : errors) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.ERROR_NUMBER_FORMAT, token.getType()); + } + + } + + + @Test + void testJS_Operators() { + + String assignmentOperators = "+ - <= ^ ++ < * >= % -- > / != ? >> ! & == : >> ~ && >>>"; + String nonAssignmentOperators = "= -= *= /= |= &= ^= += %= <<= >>= >>>="; + String code = assignmentOperators + " " + nonAssignmentOperators; + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + + String[] keywords = code.split(" +"); + for (int i = 0; i < keywords.length; i++) { + Assertions.assertEquals(keywords[i], token.getLexeme()); + Assertions.assertEquals(TokenTypes.OPERATOR, token.getType(), "Not an operator: " + token); + if (i < keywords.length - 1) { + token = token.getNextToken(); + Assertions.assertTrue(token.isWhitespace(), "Not a whitespace token: " + token); + Assertions.assertTrue(token.is(TokenTypes.WHITESPACE, " "), "Not a single space: " + token); + } + token = token.getNextToken(); + } + + Assertions.assertEquals(JS_PREV_TOKEN_TYPE, token.getType()); + + } + + + @Test + void testJS_Regexes() { + assertAllTokensOfType(TokenTypes.REGEX, + JS_PREV_TOKEN_TYPE, + "/foobar/", + "/foobar/gim", + "/foo\\/bar\\/bas/g" + ); + } + + + @Test + void testJS_Separators() { + assertAllTokensOfType(TokenTypes.SEPARATOR, + JS_PREV_TOKEN_TYPE, + "(", + ")", + "[", + "]", + "{", + "}" + ); + } + + + @Test + void testJS_Separators_renderedAsIdentifiers() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + JS_PREV_TOKEN_TYPE, + ";", + ",", + "." + ); + } + + + @Test + void testJS_StringLiterals_invalid() { + + String[] stringLiterals = { + "\"\\xG7\"", // Invalid hex/octal escape + "\"foo\\ubar\"", "\"\\u00fg\"", // Invalid Unicode escape + "\"My name is \\ubar and I \\", // Continued onto another line + "\"This is unterminated and ", // Unterminated string + }; + + for (String code : stringLiterals) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.ERROR_STRING_DOUBLE, token.getType(), "Not an ERROR_STRING_DOUBLE: " + token); + } + + } + + + @Test + void testJS_StringLiterals_valid() { + + String[] stringLiterals = { + "\"\"", "\"hi\"", "\"\\x77\"", "\"\\u00fe\"", "\"\\\"\"", + "\"My name is Robert and I \\", // String continued on another line + }; + + for (String code : stringLiterals) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, token.getType()); + } + + } + + + @Test + void testJS_StringLiteralsFromPreviousLine_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + JS_INVALID_STRING_PREV_TOKEN_TYPE, + "this is the rest of the string\"", + "the rest of the string but still unterminated" + ); + } + + + @Test + void testJS_StringLiteralsFromPreviousLine_valid() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + JS_VALID_STRING_PREV_TOKEN_TYPE, + "this is the rest of the string\"" + ); + } + + + @Test + void testJS_TemplateLiterals_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + JS_PREV_TOKEN_TYPE, + "`\\xG7`", // Invalid hex/octal escape + "`foo\\ubar`", "`\\u00fg`", // Invalid Unicode escape + "`My name is \\ubar and I " // Continued onto another line + ); + } + + + @Test + void testJS_TemplateLiterals_valid_noInterpolatedExpression() { + assertAllTokensOfType(TokenTypes.LITERAL_BACKQUOTE, + JS_PREV_TOKEN_TYPE, + "``", "`hi`", "`\\x77`", "`\\u00fe`", "`\\\"`", + "`My name is Robert and I", // String continued on another line + "`My name is Robert and I \\" // String continued on another line + ); + } + + + @Test + void testJS_TemplateLiterals_valid_withInterpolatedExpression() { + + // Strings with tokens: template, interpolated expression, template + String[] templateLiterals = { + "`My name is ${name}`", + "`My name is ${'\"' + name + '\"'}`", + "`Embedded example: ${2 + ${!!func()}}, wow", + }; + + for (String code : templateLiterals) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.LITERAL_BACKQUOTE, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.VARIABLE, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.LITERAL_BACKQUOTE, token.getType()); + } + + } + + + @Test + void testJS_TemplateLiterals_valid_continuedFromPriorLine() { + + String[] templateLiterals = { + "and my name is ${name}`" + }; + + for (String code : templateLiterals) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_VALID_TEMPLATE_LITERAL_PREV_TOKEN_TYPE, + 0); + Assertions.assertEquals(TokenTypes.LITERAL_BACKQUOTE, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.VARIABLE, token.getType()); + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.LITERAL_BACKQUOTE, token.getType()); + } + + } + + + @Test + void testJS_TemplateLiterals_invalid_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + JS_INVALID_TEMPLATE_LITERAL_PREV_TOKEN_TYPE, + "this is still an invalid template literal`"); + } + + + @Test + void testJS_Whitespace() { + + String[] whitespace = { + " ", "\t", "\f", " \t ", + }; + + for (String code : whitespace) { + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, JS_PREV_TOKEN_TYPE, 0); + Assertions.assertEquals(TokenTypes.WHITESPACE, token.getType()); + } + + } + + +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMakerTest.java index bee585f42..c232045fa 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMakerTest.java @@ -119,6 +119,19 @@ protected TokenMaker createTokenMaker() { } + @Test + @Override + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks( + JSPTokenMaker.LANG_INDEX_DEFAULT)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + JSPTokenMaker.LANG_INDEX_CSS)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + JSPTokenMaker.LANG_INDEX_JS)); + } + + @Test @Override public void testCommon_GetLineCommentStartAndEnd() { @@ -178,13 +191,6 @@ void testCss_char_continuedFromPreviousLine() { } - @Test - void testCss_getCurlyBracesDenoteCodeBlocks() { - TokenMaker tm = createTokenMaker(); - Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(JSPTokenMaker.LANG_INDEX_CSS)); - } - - @Test void testCss_getLineCommentStartAndEnd() { String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JshintrcTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JshintrcTokenMakerTest.java index a3440d363..ea2c55a2b 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JshintrcTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JshintrcTokenMakerTest.java @@ -46,6 +46,8 @@ public void testCommon_getMarkOccurrencesOfTokenType() { Assertions.assertFalse(tm.getMarkOccurrencesOfTokenType(i)); } } + + @Test @Override public void testCommon_getShouldIndentNextLineAfter() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JsonTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JsonTokenMakerTest.java index 851d06fa2..f9bdc5794 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JsonTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/JsonTokenMakerTest.java @@ -46,9 +46,11 @@ public void testCommon_getMarkOccurrencesOfTokenType() { Assertions.assertFalse(tm.getMarkOccurrencesOfTokenType(i)); } } + + @Test @Override - public void testCommon_getShouldIndentNextLineAfter() { + protected void testCommon_getShouldIndentNextLineAfter() { TokenMaker tm = createTokenMaker(); Token[] indentAfter = { new TokenImpl("{".toCharArray(), 0, 0, 0, TokenTypes.SEPARATOR, 0), diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/LessTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/LessTokenMakerTest.java index 236f9dd00..a0ef90612 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/LessTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/LessTokenMakerTest.java @@ -95,13 +95,6 @@ void testCss_comment_URL() { } - @Test - void testCss_getCurlyBracesDenoteCodeBlocks() { - TokenMaker tm = createTokenMaker(); - Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(0)); - } - - @Test void testCss_happyPath_simpleSelector() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/PhpTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/PhpTokenMakerTest.java index 200672f5c..aadcbdc91 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/PhpTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/PhpTokenMakerTest.java @@ -122,6 +122,21 @@ protected TokenMaker createTokenMaker() { } + @Test + @Override + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertFalse(tm.getCurlyBracesDenoteCodeBlocks( + PHPTokenMaker.LANG_INDEX_DEFAULT)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + PHPTokenMaker.LANG_INDEX_CSS)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + PHPTokenMaker.LANG_INDEX_JS)); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks( + PHPTokenMaker.LANG_INDEX_PHP)); + } + + @Test @Override public void testCommon_GetLineCommentStartAndEnd() { @@ -1609,13 +1624,6 @@ void testCss_char_continuedFromPreviousLine() { } - @Test - void testCss_getCurlyBracesDenoteCodeBlocks() { - TokenMaker tm = createTokenMaker(); - Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(PHPTokenMaker.LANG_INDEX_CSS)); - } - - @Test void testCss_getLineCommentStartAndEnd() { String[] startAndEnd = createTokenMaker().getLineCommentStartAndEnd( diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/SQLTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/SQLTokenMakerTest.java index abc131624..c8d6b647a 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/SQLTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/SQLTokenMakerTest.java @@ -27,6 +27,14 @@ protected TokenMaker createTokenMaker() { } + @Test + @Override + protected void testCommon_getCurlyBracesDenoteCodeBlocks() { + TokenMaker tm = createTokenMaker(); + Assertions.assertTrue(tm.getCurlyBracesDenoteCodeBlocks(0)); + } + + @Test void testCharLiterals() { assertAllTokensOfType(TokenTypes.LITERAL_CHAR, diff --git a/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java b/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java index f4afae747..9b6097fb3 100755 --- a/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java +++ b/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java @@ -104,6 +104,7 @@ private JMenuBar createMenuBar() { addSyntaxItem("CSS", "CssExample.txt", SYNTAX_STYLE_CSS, bg, menu); addSyntaxItem("Dockerfile", "DockerfileExample.txt", SYNTAX_STYLE_DOCKERFILE, bg, menu); addSyntaxItem("Go", "GoExample.txt", SYNTAX_STYLE_GO, bg, menu); + addSyntaxItem("Handlebars", "HandlebarsExample.txt", SYNTAX_STYLE_HANDLEBARS, bg, menu); addSyntaxItem("Hosts", "HostsExample.txt", SYNTAX_STYLE_HOSTS, bg, menu); addSyntaxItem("HTML", "HtmlExample.txt", SYNTAX_STYLE_HTML, bg, menu); addSyntaxItem("INI", "IniExample.txt", SYNTAX_STYLE_INI, bg, menu); diff --git a/RSyntaxTextAreaDemo/src/main/resources/org/fife/ui/rsyntaxtextarea/demo/HandlebarsExample.txt b/RSyntaxTextAreaDemo/src/main/resources/org/fife/ui/rsyntaxtextarea/demo/HandlebarsExample.txt new file mode 100644 index 000000000..ee8116272 --- /dev/null +++ b/RSyntaxTextAreaDemo/src/main/resources/org/fife/ui/rsyntaxtextarea/demo/HandlebarsExample.txt @@ -0,0 +1,32 @@ +{{> header}} + +{{#each records }} + {{#if valid}} +
+ {{else}} +
+ {{/if}} + + {{! This is a comment for a raw block }} + {{{raw}}} + + {{outer-helper (inner-helper 'abc') 'def'}} + + {{!-- This is another comment, this one for a sub-expression --}} + {{#if (equal user.status "busy")}} +

{{name}} is busy.

+ {{else}} +

{{name}} is not busy.

+ {{/if}} +{{/each}} + +{{! Whitespace control }} +{{#each nav ~}} + + {{~#if test}} + {{~title}} + {{~^~}} + Empty + {{~/if~}} + +{{~/each}}