From 87092c4da6fc4a64136a9f7d3227714433bed87b Mon Sep 17 00:00:00 2001 From: Junichi Yamamoto Date: Tue, 25 Apr 2023 20:27:16 +0900 Subject: [PATCH] Fix the error when a single quote is escaped in the Latte template #5862 - https://github.com/apache/netbeans/issues/5862 - https://latte.nette.org/en/tags#toc-translation - Fix the lexer (Fix the regex for the single quote string) - Fix the braces matcher - Add unit tests --- php/php.latte/build.xml | 48 ++ .../php/latte/braces/LatteBracesMatcher.java | 30 +- .../latte/lexer/LatteMarkupColoringLexer.java | 479 +++++++++--------- .../testIssueGH5862_01.pass | 2 + .../LatteTopLexerTest/testIssueGH5862_01.pass | 37 ++ ...stIssueGH5862_02.testIssueGH5862_02.braces | 3 + ...stIssueGH5862_03.testIssueGH5862_03.braces | 3 + ...stIssueGH5862_04.testIssueGH5862_04.braces | 3 + ...stIssueGH5862_05.testIssueGH5862_05.braces | 3 + .../markup/testIssueGH5862_01.latte-markup | 1 + .../lexer/top/testIssueGH5862_01.latte | 26 + .../latte/braces/LatteBracesMatcherTest.java | 49 ++ .../php/latte/lexer/LatteMarkupLexerTest.java | 4 + .../php/latte/lexer/LatteTopLexerTest.java | 4 + .../tools/LatteMarkupColoringLexer.flex | 6 +- 15 files changed, 459 insertions(+), 239 deletions(-) create mode 100644 php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest/testIssueGH5862_01.pass create mode 100644 php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest/testIssueGH5862_01.pass create mode 100644 php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_02.testIssueGH5862_02.braces create mode 100644 php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_03.testIssueGH5862_03.braces create mode 100644 php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_04.testIssueGH5862_04.braces create mode 100644 php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_05.testIssueGH5862_05.braces create mode 100644 php/php.latte/test/unit/data/testfiles/lexer/markup/testIssueGH5862_01.latte-markup create mode 100644 php/php.latte/test/unit/data/testfiles/lexer/top/testIssueGH5862_01.latte diff --git a/php/php.latte/build.xml b/php/php.latte/build.xml index 5a5d9290f3cb..28ac32de7bce 100644 --- a/php/php.latte/build.xml +++ b/php/php.latte/build.xml @@ -32,5 +32,53 @@ + + + + + + + + + + + + + + + + + diff --git a/php/php.latte/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcher.java b/php/php.latte/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcher.java index aa7bbbcd56ba..5246055b1e30 100644 --- a/php/php.latte/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcher.java +++ b/php/php.latte/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcher.java @@ -25,6 +25,7 @@ import javax.swing.text.BadLocationException; import org.netbeans.api.lexer.Token; import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.api.lexer.TokenUtilities; import org.netbeans.editor.BaseDocument; import org.netbeans.modules.csl.api.OffsetRange; import org.netbeans.modules.php.latte.lexer.LatteMarkupTokenId; @@ -57,6 +58,7 @@ public class LatteBracesMatcher implements BracesMatcher { MATCHERS.add(new StartEndMacroMatcher("form")); //NOI18N MATCHERS.add(new StartEndMacroMatcher("label")); //NOI18N MATCHERS.add(new StartEndMacroMatcher("snippet")); //NOI18N + MATCHERS.add(new StartEndMacroMatcher("translate")); //NOI18N MATCHERS.add(new IfMatcher()); MATCHERS.add(new IfsetMatcher()); MATCHERS.add(new EndIfMatcher()); @@ -100,7 +102,8 @@ private int[] findOriginInSequence(TokenSequence t Token currentToken = ts.token(); if (currentToken != null) { LatteMarkupTokenId currentTokenId = currentToken.id(); - if (currentTokenId == LatteMarkupTokenId.T_MACRO_START || currentTokenId == LatteMarkupTokenId.T_MACRO_END) { + if ((currentTokenId == LatteMarkupTokenId.T_MACRO_START || currentTokenId == LatteMarkupTokenId.T_MACRO_END) + && !isUnderscoreTranslationTag(ts)) { result = new int[] {ts.offset(), ts.offset() + currentToken.length()}; } } @@ -108,6 +111,31 @@ private int[] findOriginInSequence(TokenSequence t return result; } + private boolean isUnderscoreTranslationTag(TokenSequence ts) { + // check {_'text'} + // see: https://latte.nette.org/en/tags#toc-translation + int originalOffset = ts.offset(); + boolean isTranslationTag = false; + if (TokenUtilities.textEquals("_", ts.token().text())) { // NOI18N + while(ts.moveNext()) { + Token token = ts.token(); + if (token == null) { + break; + } + if (token.id() == LatteMarkupTokenId.T_WHITESPACE) { + continue; + } + if (token.id() == LatteMarkupTokenId.T_STRING) { + isTranslationTag = true; + } + break; + } + } + ts.move(originalOffset); + ts.moveNext(); + return isTranslationTag; + } + @Override public int[] findMatches() throws InterruptedException, BadLocationException { int[] result = null; diff --git a/php/php.latte/src/org/netbeans/modules/php/latte/lexer/LatteMarkupColoringLexer.java b/php/php.latte/src/org/netbeans/modules/php/latte/lexer/LatteMarkupColoringLexer.java index a569359cc20b..2605321fb186 100644 --- a/php/php.latte/src/org/netbeans/modules/php/latte/lexer/LatteMarkupColoringLexer.java +++ b/php/php.latte/src/org/netbeans/modules/php/latte/lexer/LatteMarkupColoringLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 1.6.16 7:36 */ +/* The following code was generated by JFlex 1.4.3 on 2023/04/25 20:22 */ /* * Licensed to the Apache Software Foundation (ASF) under one @@ -31,8 +31,8 @@ /** * This class is a scanner generated by * JFlex 1.4.3 - * on 1.6.16 7:36 from the specification file - * /home/gapon/worx/sun/nb-main/php.latte/tools/LatteMarkupColoringLexer.flex + * on 2023/04/25 20:22 from the specification file + * /home/junichi11/NetBeansProjects/netbeans/php/php.latte/tools/LatteMarkupColoringLexer.flex */ public class LatteMarkupColoringLexer { @@ -63,15 +63,15 @@ public class LatteMarkupColoringLexer { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\11\0\1\1\1\53\2\0\1\1\22\0\1\1\1\0\1\2\1\0"+ - "\1\4\2\0\1\6\1\30\1\35\1\0\1\37\1\0\1\45\1\41"+ - "\1\52\12\40\1\42\2\0\1\43\1\44\2\0\1\14\1\26\1\23"+ - "\1\20\1\12\1\13\1\32\1\46\1\25\1\34\1\27\1\15\1\50"+ - "\1\17\1\21\1\31\1\36\1\10\1\16\1\7\1\11\1\51\1\24"+ - "\1\22\1\33\1\36\4\0\1\47\1\0\1\14\1\26\1\23\1\20"+ - "\1\12\1\13\1\32\1\46\1\25\1\34\1\27\1\15\1\50\1\17"+ - "\1\21\1\31\1\36\1\10\1\16\1\7\1\11\1\51\1\24\1\22"+ - "\1\33\1\36\1\3\1\0\1\5\uff82\0"; + "\11\0\1\1\1\54\2\0\1\1\22\0\1\1\1\0\1\2\1\0"+ + "\1\4\2\0\1\6\1\31\1\36\1\0\1\40\1\0\1\46\1\42"+ + "\1\53\12\41\1\43\2\0\1\44\1\45\2\0\1\15\1\27\1\24"+ + "\1\21\1\13\1\14\1\33\1\47\1\26\1\35\1\30\1\16\1\51"+ + "\1\20\1\22\1\32\1\37\1\11\1\17\1\10\1\12\1\52\1\25"+ + "\1\23\1\34\1\37\1\0\1\7\2\0\1\50\1\0\1\15\1\27"+ + "\1\24\1\21\1\13\1\14\1\33\1\47\1\26\1\35\1\30\1\16"+ + "\1\51\1\20\1\22\1\32\1\37\1\11\1\17\1\10\1\12\1\52"+ + "\1\25\1\23\1\34\1\37\1\3\1\0\1\5\uff82\0"; /** * Translates characters to character classes @@ -84,19 +84,20 @@ public class LatteMarkupColoringLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\5\0\1\1\1\2\1\3\3\1\1\3\10\1\1\4"+ - "\1\5\1\6\1\5\1\6\13\7\2\5\1\10\3\5"+ - "\1\11\1\6\1\12\2\6\1\0\1\13\1\14\21\0"+ - "\1\3\6\0\1\15\1\16\1\0\1\12\1\7\1\0"+ - "\2\7\1\5\3\7\1\17\4\7\7\0\1\10\1\7"+ - "\11\0\1\11\1\20\4\0\1\12\3\0\1\3\25\0"+ - "\10\7\10\0\2\10\11\0\1\11\2\0\2\21\1\12"+ - "\1\0\1\3\16\0\4\7\7\0\1\10\1\11\14\0"+ - "\1\20\16\0\3\7\6\0\1\22\12\0\1\3\7\0"+ - "\1\7\15\0\1\3\1\7\7\0\1\7\2\0\1\7"; + "\5\0\1\1\1\2\1\1\1\3\3\1\1\3\10\1"+ + "\1\4\1\5\1\6\1\5\1\6\13\7\2\5\1\10"+ + "\3\5\1\11\1\6\1\12\2\6\1\0\1\13\1\14"+ + "\22\0\1\3\6\0\1\15\1\16\1\0\1\12\1\0"+ + "\1\7\1\0\2\7\1\5\3\7\1\17\4\7\7\0"+ + "\1\10\1\7\12\0\1\11\1\20\4\0\1\12\4\0"+ + "\1\3\25\0\10\7\10\0\2\10\12\0\1\11\2\0"+ + "\2\21\1\12\2\0\1\3\16\0\4\7\7\0\1\10"+ + "\1\0\1\11\14\0\1\20\17\0\3\7\6\0\1\22"+ + "\14\0\1\3\7\0\1\7\17\0\1\3\1\7\10\0"+ + "\1\7\3\0\1\7"; private static int [] zzUnpackAction() { - int [] result = new int[285]; + int [] result = new int[300]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -121,45 +122,47 @@ private static int zzUnpackAction(String packed, int offset, int [] result) { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\54\0\130\0\204\0\260\0\334\0\u0108\0\334"+ - "\0\u0134\0\u0160\0\u018c\0\u01b8\0\u01e4\0\u0210\0\u023c\0\u0268"+ - "\0\u0294\0\u02c0\0\u02ec\0\u0318\0\334\0\334\0\u0344\0\u0370"+ - "\0\u039c\0\u03c8\0\u03f4\0\u0420\0\u044c\0\u0478\0\u04a4\0\u04d0"+ - "\0\u04fc\0\u0528\0\u0554\0\u0580\0\u05ac\0\u05d8\0\u0604\0\u0630"+ - "\0\u065c\0\u0688\0\u06b4\0\u06e0\0\u070c\0\u0738\0\u0764\0\u06e0"+ - "\0\334\0\u0790\0\u07bc\0\u07e8\0\u0814\0\u0840\0\u086c\0\u0898"+ - "\0\u08c4\0\u08f0\0\u091c\0\u0948\0\u0974\0\u09a0\0\u09cc\0\u09f8"+ - "\0\u0a24\0\u0a50\0\u0a7c\0\u0aa8\0\u0ad4\0\u0b00\0\u0b2c\0\u0b58"+ - "\0\u0b84\0\u0344\0\334\0\u0370\0\u039c\0\334\0\u0bb0\0\u0bdc"+ - "\0\u0c08\0\u0c34\0\u0420\0\u0c60\0\u0c8c\0\u0cb8\0\u0420\0\u0ce4"+ - "\0\u0d10\0\u0d3c\0\u0d68\0\u0d94\0\u0dc0\0\u0dec\0\u0e18\0\u0e44"+ - "\0\u0e70\0\u0e9c\0\u0ec8\0\u0ef4\0\u0f20\0\u0f4c\0\u0f78\0\u0fa4"+ - "\0\u0fd0\0\u0ffc\0\u1028\0\u1054\0\u1080\0\334\0\u10ac\0\u10d8"+ - "\0\u1104\0\u10ac\0\u1130\0\u115c\0\u1188\0\u11b4\0\u11e0\0\u120c"+ - "\0\u1238\0\u1264\0\u1290\0\u12bc\0\u12e8\0\u1314\0\u1340\0\u136c"+ - "\0\u1398\0\u13c4\0\u13f0\0\u141c\0\u1448\0\u1474\0\u14a0\0\u14cc"+ - "\0\u14f8\0\u1524\0\u1550\0\u157c\0\u15a8\0\u15d4\0\u1600\0\u162c"+ - "\0\u1658\0\u1684\0\u16b0\0\u16dc\0\u1708\0\u1734\0\u1760\0\u178c"+ - "\0\u17b8\0\u17e4\0\u1810\0\u183c\0\u1868\0\u0ef4\0\u1894\0\u18c0"+ - "\0\u18ec\0\u1918\0\u1944\0\u1970\0\u199c\0\u19c8\0\u19f4\0\u1a20"+ - "\0\u1a4c\0\u1a78\0\u1aa4\0\u1188\0\334\0\u1ad0\0\u1afc\0\u1b28"+ - "\0\u1b54\0\u1b80\0\u1bac\0\u1bd8\0\u1c04\0\u1c30\0\u1c5c\0\u1c88"+ - "\0\u1cb4\0\u1ce0\0\u1d0c\0\u1d38\0\u1d64\0\u1d90\0\u1dbc\0\u1de8"+ - "\0\u1e14\0\u1e40\0\u1e6c\0\u1e98\0\u1ec4\0\u1ef0\0\u1f1c\0\u1f48"+ - "\0\u1f74\0\u1868\0\u1fa0\0\u1fcc\0\u1ff8\0\u2024\0\u2050\0\u207c"+ - "\0\u20a8\0\u20d4\0\u2100\0\u212c\0\u2158\0\u2184\0\u21b0\0\334"+ - "\0\u21dc\0\u2208\0\u2234\0\u2260\0\u228c\0\u22b8\0\u22e4\0\u2310"+ - "\0\u233c\0\u2368\0\u2394\0\u23c0\0\u23ec\0\u2418\0\u2444\0\u2470"+ - "\0\u249c\0\u24c8\0\u24f4\0\u2520\0\u254c\0\u2578\0\u25a4\0\334"+ - "\0\u25d0\0\u25fc\0\u2628\0\u2654\0\u2680\0\u26ac\0\u26d8\0\u2704"+ - "\0\u2730\0\u275c\0\u2788\0\u27b4\0\u27e0\0\u280c\0\u2838\0\u2864"+ - "\0\u2890\0\u28bc\0\u28e8\0\u2914\0\u2940\0\u296c\0\u2998\0\u29c4"+ - "\0\u29f0\0\u2a1c\0\u2a48\0\u2a74\0\u2aa0\0\u2acc\0\u2af8\0\u2b24"+ - "\0\u2b50\0\u2b7c\0\u2ba8\0\u2bd4\0\u2c00\0\u2c2c\0\u2c58\0\u2c84"+ - "\0\u2cb0\0\u2cdc\0\u2d08\0\u2d34\0\u2d60"; + "\0\0\0\55\0\132\0\207\0\264\0\341\0\u010e\0\u013b"+ + "\0\341\0\u0168\0\u0195\0\u01c2\0\u01ef\0\u021c\0\u0249\0\u0276"+ + "\0\u02a3\0\u02d0\0\u02fd\0\u032a\0\u0357\0\341\0\341\0\u0384"+ + "\0\u03b1\0\u03de\0\u040b\0\u0438\0\u0465\0\u0492\0\u04bf\0\u04ec"+ + "\0\u0519\0\u0546\0\u0573\0\u05a0\0\u05cd\0\u05fa\0\u0627\0\u0654"+ + "\0\u0681\0\u06ae\0\u06db\0\u0708\0\u0735\0\u0762\0\u078f\0\u07bc"+ + "\0\u0735\0\341\0\u07e9\0\u0816\0\u0843\0\u0870\0\u089d\0\u08ca"+ + "\0\u08f7\0\u0924\0\u0951\0\u097e\0\u09ab\0\u09d8\0\u0a05\0\u0a32"+ + "\0\u0a5f\0\u0a8c\0\u0ab9\0\u0ae6\0\u0b13\0\u0b40\0\u0b6d\0\u0b9a"+ + "\0\u0bc7\0\u0bf4\0\u0c21\0\u0384\0\341\0\u03b1\0\u03de\0\341"+ + "\0\u0c4e\0\u0c7b\0\u0ca8\0\u0cd5\0\u0d02\0\u0465\0\u0d2f\0\u0d5c"+ + "\0\u0d89\0\u0465\0\u0db6\0\u0de3\0\u0e10\0\u0e3d\0\u0e6a\0\u0e97"+ + "\0\u0ec4\0\u0ef1\0\u0f1e\0\u0f4b\0\u0f78\0\u0fa5\0\u0fd2\0\u0fff"+ + "\0\u102c\0\u1059\0\u1086\0\u10b3\0\u10e0\0\u110d\0\u113a\0\u1167"+ + "\0\u1194\0\341\0\u11c1\0\u11ee\0\u121b\0\u11c1\0\u1248\0\u1275"+ + "\0\u12a2\0\u12cf\0\u12fc\0\u1329\0\u1356\0\u1383\0\u13b0\0\u13dd"+ + "\0\u140a\0\u1437\0\u1464\0\u1491\0\u14be\0\u14eb\0\u1518\0\u1545"+ + "\0\u1572\0\u159f\0\u15cc\0\u15f9\0\u1626\0\u1653\0\u1680\0\u16ad"+ + "\0\u16da\0\u1707\0\u1734\0\u1761\0\u178e\0\u17bb\0\u17e8\0\u1815"+ + "\0\u1842\0\u186f\0\u189c\0\u18c9\0\u18f6\0\u1923\0\u1950\0\u197d"+ + "\0\u19aa\0\u19d7\0\u0fd2\0\u1a04\0\u1a31\0\u1a5e\0\u1a8b\0\u1ab8"+ + "\0\u1ae5\0\u1b12\0\u1b3f\0\u1b6c\0\u1b99\0\u1bc6\0\u1bf3\0\u1c20"+ + "\0\u1c4d\0\u12a2\0\341\0\u1c7a\0\u1ca7\0\u1cd4\0\u1d01\0\u1d2e"+ + "\0\u1d5b\0\u1d88\0\u1db5\0\u1de2\0\u1e0f\0\u1e3c\0\u1e69\0\u1e96"+ + "\0\u1ec3\0\u1ef0\0\u1f1d\0\u1f4a\0\u1f77\0\u1fa4\0\u1fd1\0\u1ffe"+ + "\0\u202b\0\u2058\0\u2085\0\u20b2\0\u20df\0\u210c\0\u2139\0\u2166"+ + "\0\u19d7\0\u2193\0\u21c0\0\u21ed\0\u221a\0\u2247\0\u2274\0\u22a1"+ + "\0\u22ce\0\u22fb\0\u2328\0\u2355\0\u2382\0\u23af\0\u23dc\0\341"+ + "\0\u2409\0\u2436\0\u2463\0\u2490\0\u24bd\0\u24ea\0\u2517\0\u2544"+ + "\0\u2571\0\u259e\0\u25cb\0\u25f8\0\u2625\0\u2652\0\u267f\0\u26ac"+ + "\0\u26d9\0\u2706\0\u2733\0\u2760\0\u278d\0\u27ba\0\u27e7\0\u2814"+ + "\0\341\0\u2841\0\u286e\0\u289b\0\u28c8\0\u28f5\0\u2922\0\u294f"+ + "\0\u297c\0\u29a9\0\u29d6\0\u2a03\0\u2a30\0\u2a5d\0\u2a8a\0\u2ab7"+ + "\0\u2ae4\0\u2b11\0\u2b3e\0\u2b6b\0\u2b98\0\u2bc5\0\u2bf2\0\u2c1f"+ + "\0\u2c4c\0\u2c79\0\u2ca6\0\u2cd3\0\u2d00\0\u2d2d\0\u2d5a\0\u2d87"+ + "\0\u2db4\0\u2de1\0\u2e0e\0\u2e3b\0\u2e68\0\u2e95\0\u2ec2\0\u2eef"+ + "\0\u2f1c\0\u2f49\0\u2f76\0\u2fa3\0\u2fd0\0\u2ffd\0\u302a\0\u3057"+ + "\0\u3084\0\u30b1\0\u30de\0\u310b"; private static int [] zzUnpackRowMap() { - int [] result = new int[285]; + int [] result = new int[300]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -182,160 +185,164 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\1\6\1\7\6\6\1\10\1\11\1\12\1\13\1\6"+ - "\1\14\1\15\1\6\1\16\2\6\1\17\1\20\1\21"+ - "\1\22\2\6\1\23\15\6\1\10\1\6\1\24\1\25"+ - "\1\7\1\26\1\7\1\27\1\26\1\30\1\26\1\31"+ - "\1\32\1\33\2\34\1\35\1\36\2\34\1\37\1\34"+ - "\1\40\1\41\1\42\1\34\1\43\1\44\1\34\1\45"+ - "\4\34\1\26\1\34\1\46\1\47\1\26\1\50\1\51"+ - "\1\26\1\52\4\34\1\26\1\7\1\6\1\7\50\6"+ - "\1\53\1\7\2\54\1\55\1\56\1\57\46\54\1\60"+ - "\1\61\1\62\51\61\1\62\55\0\1\7\51\0\1\7"+ - "\16\0\1\63\52\0\1\64\4\0\1\65\52\0\1\66"+ - "\3\0\1\67\42\0\1\70\10\0\1\71\35\0\1\72"+ - "\2\0\1\73\4\0\1\74\13\0\1\75\31\0\1\76"+ - "\1\77\55\0\1\100\4\0\1\101\57\0\1\102\20\0"+ - "\1\103\20\0\1\104\3\0\1\105\44\0\1\106\4\0"+ - "\1\107\53\0\1\110\52\0\1\111\37\0\2\112\1\113"+ - "\51\112\7\0\21\114\1\0\4\114\1\0\1\114\1\0"+ - "\1\114\5\0\4\114\2\0\6\115\1\116\45\115\7\0"+ - "\1\34\1\117\17\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\3\34\1\121\15\34"+ - "\1\0\4\34\1\0\1\34\1\0\1\34\4\0\1\120"+ - "\4\34\11\0\21\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\5\34\1\122\13\34"+ - "\1\0\4\34\1\0\1\34\1\0\1\34\4\0\1\120"+ - "\4\34\11\0\7\34\1\123\1\124\10\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\11\0"+ - "\2\34\1\125\1\126\15\34\1\0\4\34\1\0\1\34"+ - "\1\0\1\34\4\0\1\120\4\34\11\0\1\34\1\127"+ - "\17\34\1\0\4\34\1\0\1\34\1\0\1\34\4\0"+ - "\1\120\4\34\11\0\12\34\1\40\6\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\11\0"+ - "\6\34\1\130\3\34\1\131\6\34\1\0\4\34\1\0"+ - "\1\34\1\0\1\34\4\0\1\120\4\34\11\0\10\34"+ - "\1\132\10\34\1\0\4\34\1\0\1\34\1\0\1\34"+ - "\4\0\1\120\4\34\11\0\1\34\1\133\17\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\14\0\1\134\1\135\1\136\1\0\1\137\2\0\1\140"+ - "\3\0\1\141\1\142\65\0\1\143\22\0\3\34\1\144"+ - "\15\34\1\0\4\34\1\0\1\34\1\0\1\47\1\145"+ - "\3\0\1\120\4\34\44\0\1\26\55\0\1\26\47\0"+ - "\1\143\3\0\1\26\22\0\1\146\1\0\1\147\1\150"+ - "\1\0\1\151\2\0\1\152\1\153\1\154\1\155\20\0"+ - "\1\156\4\0\2\60\1\157\1\160\1\161\47\60\2\55"+ - "\1\162\1\163\1\164\47\55\2\60\1\157\1\60\1\165"+ - "\47\60\5\0\1\60\1\0\21\114\1\0\4\114\1\0"+ - "\1\114\1\0\1\114\5\0\4\114\3\0\1\62\51\0"+ - "\1\62\12\0\1\10\57\0\1\166\44\0\1\167\54\0"+ - "\1\170\53\0\1\171\61\0\1\172\7\0\1\173\4\0"+ - "\1\174\37\0\1\175\50\0\1\176\70\0\1\10\47\0"+ - "\1\177\45\0\1\200\104\0\1\73\16\0\1\201\12\0"+ - "\1\202\50\0\1\203\5\0\1\204\41\0\1\205\54\0"+ - "\1\206\60\0\1\207\44\0\1\210\4\0\1\211\53\0"+ - "\1\212\5\0\1\213\34\0\1\214\62\0\1\215\57\0"+ - "\1\71\36\0\1\10\52\0\2\34\1\216\16\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\11\0\21\34\1\0\4\34\1\0\1\34\1\0\1\34"+ - "\5\0\4\34\11\0\1\217\20\34\1\0\4\34\1\0"+ - "\1\34\1\0\1\34\4\0\1\120\4\34\11\0\6\34"+ - "\1\220\12\34\1\0\4\34\1\0\1\34\1\0\1\34"+ - "\4\0\1\120\4\34\11\0\11\34\1\127\7\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\11\0\6\34\1\221\12\34\1\0\4\34\1\0\1\34"+ - "\1\0\1\34\4\0\1\120\4\34\11\0\15\34\1\127"+ - "\3\34\1\0\4\34\1\0\1\34\1\0\1\34\4\0"+ - "\1\120\4\34\11\0\12\34\1\222\6\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\11\0"+ - "\10\34\1\223\10\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\7\34\1\224\11\34"+ - "\1\0\4\34\1\0\1\34\1\0\1\34\4\0\1\120"+ - "\4\34\11\0\3\34\1\225\15\34\1\0\4\34\1\0"+ - "\1\34\1\0\1\34\4\0\1\120\4\34\24\0\1\226"+ - "\46\0\1\227\46\0\1\230\52\0\1\231\72\0\1\232"+ - "\44\0\1\233\55\0\1\234\44\0\1\235\25\0\1\143"+ - "\1\145\21\0\21\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\236\4\0\1\120\4\34\42\0\1\237\34\0\1\240"+ - "\3\0\1\241\42\0\1\242\51\0\1\243\4\0\1\244"+ - "\13\0\1\245\32\0\1\246\55\0\1\247\105\0\1\250"+ - "\20\0\1\251\55\0\1\252\36\0\3\162\1\163\1\253"+ - "\47\162\2\60\1\157\1\60\1\254\47\60\5\0\1\60"+ - "\46\0\4\162\1\255\47\162\2\256\2\0\1\256\1\55"+ - "\46\256\5\0\1\257\60\0\1\260\53\0\1\261\53\0"+ - "\1\262\35\0\1\10\21\0\1\172\44\0\1\10\56\0"+ - "\1\263\62\0\1\213\61\0\1\10\33\0\1\264\75\0"+ - "\1\265\31\0\1\266\60\0\1\267\10\0\1\270\37\0"+ - "\1\271\110\0\1\63\14\0\1\272\53\0\1\273\76\0"+ - "\1\210\36\0\1\63\50\0\1\172\52\0\1\274\57\0"+ - "\1\275\47\0\1\172\56\0\1\276\62\0\1\175\37\0"+ - "\3\34\1\127\15\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\2\34\1\277\16\34"+ - "\1\0\4\34\1\0\1\34\1\0\1\34\4\0\1\120"+ - "\4\34\11\0\7\34\1\216\11\34\1\0\4\34\1\0"+ - "\1\34\1\0\1\34\4\0\1\120\4\34\11\0\6\34"+ - "\1\127\12\34\1\0\4\34\1\0\1\34\1\0\1\34"+ - "\4\0\1\120\4\34\11\0\10\34\1\216\10\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\11\0\1\300\20\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\1\301\20\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\11\0\5\34\1\302\13\34\1\0\4\34\1\0\1\34"+ - "\1\0\1\34\4\0\1\120\4\34\33\0\1\303\43\0"+ - "\1\304\42\0\1\305\53\0\1\306\77\0\1\307\26\0"+ - "\1\310\65\0\1\311\72\0\1\312\25\0\1\235\25\0"+ - "\1\237\23\0\1\313\53\0\1\314\61\0\1\315\7\0"+ - "\1\316\56\0\1\156\47\0\1\317\45\0\1\320\47\0"+ - "\1\321\63\0\1\322\5\0\1\323\47\0\1\324\44\0"+ - "\1\325\4\0\1\326\51\0\1\327\37\0\1\162\46\0"+ - "\2\256\2\0\50\256\2\257\1\330\1\257\1\165\47\257"+ - "\25\0\1\331\45\0\1\332\50\0\1\333\54\0\1\10"+ - "\47\0\1\334\73\0\1\210\36\0\1\335\50\0\1\336"+ - "\61\0\1\63\66\0\1\337\32\0\1\340\52\0\1\341"+ - "\1\0\1\342\12\0\1\343\36\0\1\344\54\0\1\345"+ - "\71\0\1\346\33\0\1\34\1\347\17\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\11\0"+ - "\16\34\1\350\2\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\11\0\5\34\1\351\13\34"+ - "\1\0\4\34\1\0\1\34\1\0\1\34\4\0\1\120"+ - "\4\34\11\0\20\34\1\127\1\0\4\34\1\0\1\34"+ - "\1\0\1\34\4\0\1\120\4\34\16\0\1\352\53\0"+ - "\1\353\53\0\1\354\64\0\1\355\40\0\1\356\53\0"+ - "\1\357\22\0\1\360\33\0\1\361\50\0\1\362\35\0"+ - "\1\156\21\0\1\315\44\0\1\156\56\0\1\363\72\0"+ - "\1\364\31\0\1\365\71\0\1\366\74\0\1\367\14\0"+ - "\1\370\61\0\1\367\50\0\1\315\52\0\1\371\65\0"+ - "\1\372\43\0\1\373\60\0\1\334\56\0\1\374\46\0"+ - "\1\10\57\0\1\10\46\0\1\172\64\0\1\375\35\0"+ - "\1\63\64\0\1\263\51\0\1\376\53\0\1\377\44\0"+ - "\1\u0100\63\0\1\u0101\60\0\1\u0102\35\0\10\34\1\127"+ - "\10\34\1\0\4\34\1\0\1\34\1\0\1\34\4\0"+ - "\1\120\4\34\11\0\10\34\1\117\10\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\11\0"+ - "\10\34\1\u0103\10\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\21\0\1\u0104\43\0\1\u0105"+ - "\77\0\1\u0105\37\0\1\u0106\57\0\1\353\62\0\1\u0107"+ - "\33\0\1\u0108\22\0\1\360\32\0\1\u0109\54\0\1\156"+ - "\67\0\1\325\36\0\1\u010a\56\0\1\367\46\0\1\156"+ - "\52\0\1\u010b\52\0\1\u010c\72\0\1\156\42\0\1\210"+ - "\103\0\1\10\15\0\1\u010d\52\0\1\u010e\55\0\1\u010f"+ - "\54\0\1\u0110\53\0\1\u0111\54\0\1\10\47\0\14\34"+ - "\1\u0112\4\34\1\0\4\34\1\0\1\34\1\0\1\34"+ - "\4\0\1\120\4\34\22\0\1\u0105\70\0\1\360\50\0"+ - "\1\u0105\33\0\1\u0113\55\0\1\u0114\62\0\1\u0115\52\0"+ - "\1\156\41\0\1\367\53\0\1\u0116\55\0\1\u0117\50\0"+ - "\1\u0118\56\0\1\346\60\0\1\172\62\0\1\u0119\34\0"+ - "\3\34\1\u011a\15\34\1\0\4\34\1\0\1\34\1\0"+ - "\1\34\4\0\1\120\4\34\12\0\1\u0105\62\0\1\u0105"+ - "\102\0\1\156\17\0\1\u011b\55\0\1\175\72\0\1\u011c"+ - "\35\0\1\107\45\0\12\34\1\u011d\6\34\1\0\4\34"+ - "\1\0\1\34\1\0\1\34\4\0\1\120\4\34\21\0"+ - "\1\315\65\0\1\63\31\0\4\34\1\127\14\34\1\0"+ - "\4\34\1\0\1\34\1\0\1\34\4\0\1\120\4\34"+ - "\2\0"; + "\1\6\1\7\6\6\1\10\1\11\1\12\1\13\1\14"+ + "\1\6\1\15\1\16\1\6\1\17\2\6\1\20\1\21"+ + "\1\22\1\23\2\6\1\24\15\6\1\11\1\6\1\25"+ + "\1\26\1\7\1\27\1\7\1\30\1\27\1\31\1\27"+ + "\1\32\1\27\1\33\1\34\2\35\1\36\1\37\2\35"+ + "\1\40\1\35\1\41\1\42\1\43\1\35\1\44\1\45"+ + "\1\35\1\46\4\35\1\27\1\35\1\47\1\50\1\27"+ + "\1\51\1\52\1\27\1\53\4\35\1\27\1\7\1\6"+ + "\1\7\51\6\1\54\1\7\2\55\1\56\1\57\1\60"+ + "\47\55\1\61\1\62\1\63\52\62\1\63\56\0\1\7"+ + "\52\0\1\7\11\0\1\64\62\0\1\65\53\0\1\66"+ + "\4\0\1\67\53\0\1\70\3\0\1\71\43\0\1\72"+ + "\10\0\1\73\36\0\1\74\2\0\1\75\4\0\1\76"+ + "\13\0\1\77\32\0\1\100\1\101\56\0\1\102\4\0"+ + "\1\103\60\0\1\104\20\0\1\105\21\0\1\106\3\0"+ + "\1\107\45\0\1\110\4\0\1\111\54\0\1\112\53\0"+ + "\1\113\37\0\2\114\1\115\52\114\10\0\21\116\1\0"+ + "\4\116\1\0\1\116\1\0\1\116\5\0\4\116\2\0"+ + "\6\117\1\120\1\121\45\117\10\0\1\35\1\122\17\35"+ + "\1\0\4\35\1\0\1\35\1\0\1\35\4\0\1\123"+ + "\4\35\12\0\3\35\1\124\15\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\4\0\1\123\4\35\12\0\21\35"+ + "\1\0\4\35\1\0\1\35\1\0\1\35\4\0\1\123"+ + "\4\35\12\0\5\35\1\125\13\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\4\0\1\123\4\35\12\0\7\35"+ + "\1\126\1\127\10\35\1\0\4\35\1\0\1\35\1\0"+ + "\1\35\4\0\1\123\4\35\12\0\2\35\1\130\1\131"+ + "\15\35\1\0\4\35\1\0\1\35\1\0\1\35\4\0"+ + "\1\123\4\35\12\0\1\35\1\132\17\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\4\0\1\123\4\35\12\0"+ + "\12\35\1\41\6\35\1\0\4\35\1\0\1\35\1\0"+ + "\1\35\4\0\1\123\4\35\12\0\6\35\1\133\3\35"+ + "\1\134\6\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\12\0\10\35\1\135\10\35\1\0"+ + "\4\35\1\0\1\35\1\0\1\35\4\0\1\123\4\35"+ + "\12\0\1\35\1\136\17\35\1\0\4\35\1\0\1\35"+ + "\1\0\1\35\4\0\1\123\4\35\15\0\1\137\1\140"+ + "\1\141\1\0\1\142\2\0\1\143\3\0\1\144\1\145"+ + "\66\0\1\146\23\0\3\35\1\147\15\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\50\1\150\3\0\1\123\4\35"+ + "\45\0\1\27\56\0\1\27\50\0\1\146\3\0\1\27"+ + "\17\0\1\151\3\0\1\152\1\0\1\153\1\154\1\0"+ + "\1\155\2\0\1\156\1\157\1\160\1\161\20\0\1\162"+ + "\4\0\2\61\1\163\1\164\1\165\50\61\2\56\1\166"+ + "\1\167\1\170\50\56\2\61\1\163\1\61\1\171\50\61"+ + "\5\0\1\61\2\0\21\116\1\0\4\116\1\0\1\116"+ + "\1\0\1\116\5\0\4\116\3\0\1\63\52\0\1\63"+ + "\15\0\1\172\52\0\1\11\60\0\1\173\45\0\1\174"+ + "\55\0\1\175\54\0\1\176\62\0\1\177\7\0\1\200"+ + "\4\0\1\201\40\0\1\202\51\0\1\203\71\0\1\11"+ + "\50\0\1\204\46\0\1\205\105\0\1\75\17\0\1\206"+ + "\12\0\1\207\51\0\1\210\5\0\1\211\42\0\1\212"+ + "\55\0\1\213\61\0\1\214\45\0\1\215\4\0\1\216"+ + "\54\0\1\217\5\0\1\220\35\0\1\221\63\0\1\222"+ + "\60\0\1\73\37\0\1\11\43\0\55\117\10\0\2\35"+ + "\1\223\16\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\12\0\21\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\5\0\4\35\12\0\1\224\20\35"+ + "\1\0\4\35\1\0\1\35\1\0\1\35\4\0\1\123"+ + "\4\35\12\0\6\35\1\225\12\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\4\0\1\123\4\35\12\0\11\35"+ + "\1\132\7\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\12\0\6\35\1\226\12\35\1\0"+ + "\4\35\1\0\1\35\1\0\1\35\4\0\1\123\4\35"+ + "\12\0\15\35\1\132\3\35\1\0\4\35\1\0\1\35"+ + "\1\0\1\35\4\0\1\123\4\35\12\0\12\35\1\227"+ + "\6\35\1\0\4\35\1\0\1\35\1\0\1\35\4\0"+ + "\1\123\4\35\12\0\10\35\1\230\10\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\4\0\1\123\4\35\12\0"+ + "\7\35\1\231\11\35\1\0\4\35\1\0\1\35\1\0"+ + "\1\35\4\0\1\123\4\35\12\0\3\35\1\232\15\35"+ + "\1\0\4\35\1\0\1\35\1\0\1\35\4\0\1\123"+ + "\4\35\25\0\1\233\47\0\1\234\47\0\1\235\53\0"+ + "\1\236\73\0\1\237\45\0\1\240\56\0\1\241\45\0"+ + "\1\242\25\0\1\146\1\150\22\0\21\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\243\4\0\1\123\4\35\43\0"+ + "\1\244\24\0\1\245\65\0\1\246\3\0\1\247\43\0"+ + "\1\250\52\0\1\251\4\0\1\252\13\0\1\253\33\0"+ + "\1\254\56\0\1\255\106\0\1\256\21\0\1\257\56\0"+ + "\1\260\36\0\3\166\1\167\1\261\50\166\2\61\1\163"+ + "\1\61\1\262\50\61\5\0\1\61\47\0\4\166\1\263"+ + "\50\166\2\264\2\0\1\264\1\56\47\264\5\0\1\265"+ + "\67\0\1\266\47\0\1\267\54\0\1\270\54\0\1\271"+ + "\35\0\1\11\22\0\1\177\45\0\1\11\57\0\1\272"+ + "\63\0\1\220\62\0\1\11\34\0\1\273\76\0\1\274"+ + "\32\0\1\275\61\0\1\276\10\0\1\277\40\0\1\300"+ + "\111\0\1\65\15\0\1\301\54\0\1\302\77\0\1\215"+ + "\37\0\1\65\51\0\1\177\53\0\1\303\60\0\1\304"+ + "\50\0\1\177\57\0\1\305\63\0\1\202\40\0\3\35"+ + "\1\132\15\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\12\0\2\35\1\306\16\35\1\0"+ + "\4\35\1\0\1\35\1\0\1\35\4\0\1\123\4\35"+ + "\12\0\7\35\1\223\11\35\1\0\4\35\1\0\1\35"+ + "\1\0\1\35\4\0\1\123\4\35\12\0\6\35\1\132"+ + "\12\35\1\0\4\35\1\0\1\35\1\0\1\35\4\0"+ + "\1\123\4\35\12\0\10\35\1\223\10\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\4\0\1\123\4\35\12\0"+ + "\1\307\20\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\12\0\1\310\20\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\4\0\1\123\4\35\12\0"+ + "\5\35\1\311\13\35\1\0\4\35\1\0\1\35\1\0"+ + "\1\35\4\0\1\123\4\35\34\0\1\312\44\0\1\313"+ + "\43\0\1\314\54\0\1\315\100\0\1\316\27\0\1\317"+ + "\66\0\1\320\73\0\1\321\26\0\1\242\25\0\1\244"+ + "\30\0\1\322\50\0\1\323\54\0\1\324\62\0\1\325"+ + "\7\0\1\326\57\0\1\162\50\0\1\327\46\0\1\330"+ + "\50\0\1\331\64\0\1\332\5\0\1\333\50\0\1\334"+ + "\45\0\1\335\4\0\1\336\52\0\1\337\37\0\1\166"+ + "\47\0\2\264\2\0\51\264\2\265\1\340\1\265\1\171"+ + "\50\265\17\0\1\341\63\0\1\342\46\0\1\343\51\0"+ + "\1\344\55\0\1\11\50\0\1\345\74\0\1\215\37\0"+ + "\1\346\51\0\1\347\62\0\1\65\67\0\1\350\33\0"+ + "\1\351\53\0\1\352\1\0\1\353\12\0\1\354\37\0"+ + "\1\355\55\0\1\356\72\0\1\357\34\0\1\35\1\360"+ + "\17\35\1\0\4\35\1\0\1\35\1\0\1\35\4\0"+ + "\1\123\4\35\12\0\16\35\1\361\2\35\1\0\4\35"+ + "\1\0\1\35\1\0\1\35\4\0\1\123\4\35\12\0"+ + "\5\35\1\362\13\35\1\0\4\35\1\0\1\35\1\0"+ + "\1\35\4\0\1\123\4\35\12\0\20\35\1\132\1\0"+ + "\4\35\1\0\1\35\1\0\1\35\4\0\1\123\4\35"+ + "\17\0\1\363\54\0\1\364\54\0\1\365\65\0\1\366"+ + "\41\0\1\367\54\0\1\370\22\0\1\371\34\0\1\372"+ + "\56\0\1\373\47\0\1\374\35\0\1\162\22\0\1\325"+ + "\45\0\1\162\57\0\1\375\73\0\1\376\32\0\1\377"+ + "\72\0\1\u0100\75\0\1\u0101\15\0\1\u0102\62\0\1\u0101"+ + "\51\0\1\325\53\0\1\u0103\66\0\1\u0104\46\0\1\u0105"+ + "\52\0\1\u0106\61\0\1\345\57\0\1\u0107\47\0\1\11"+ + "\60\0\1\11\47\0\1\177\65\0\1\u0108\36\0\1\65"+ + "\65\0\1\272\52\0\1\u0109\54\0\1\u010a\45\0\1\u010b"+ + "\64\0\1\u010c\61\0\1\u010d\36\0\10\35\1\132\10\35"+ + "\1\0\4\35\1\0\1\35\1\0\1\35\4\0\1\123"+ + "\4\35\12\0\10\35\1\122\10\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\4\0\1\123\4\35\12\0\10\35"+ + "\1\u010e\10\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\22\0\1\u010f\44\0\1\u0110\100\0"+ + "\1\u0110\40\0\1\u0111\60\0\1\364\63\0\1\u0112\34\0"+ + "\1\u0113\22\0\1\371\35\0\1\u0114\52\0\1\u0115\55\0"+ + "\1\162\70\0\1\335\37\0\1\u0116\57\0\1\u0101\47\0"+ + "\1\162\53\0\1\u0117\53\0\1\u0118\73\0\1\162\41\0"+ + "\1\u0119\56\0\1\215\104\0\1\11\16\0\1\u011a\53\0"+ + "\1\u011b\56\0\1\u011c\55\0\1\u011d\54\0\1\u011e\55\0"+ + "\1\11\50\0\14\35\1\u011f\4\35\1\0\4\35\1\0"+ + "\1\35\1\0\1\35\4\0\1\123\4\35\23\0\1\u0110"+ + "\71\0\1\371\51\0\1\u0110\34\0\1\u0120\56\0\1\u0121"+ + "\55\0\1\u0122\62\0\1\u0123\53\0\1\162\42\0\1\u0101"+ + "\54\0\1\u0124\53\0\1\65\57\0\1\u0125\51\0\1\u0126"+ + "\57\0\1\357\61\0\1\177\63\0\1\u0127\35\0\3\35"+ + "\1\u0128\15\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\13\0\1\u0110\63\0\1\u0110\51\0"+ + "\1\u0129\106\0\1\162\20\0\1\u012a\56\0\1\202\73\0"+ + "\1\u012b\36\0\1\111\46\0\12\35\1\u012c\6\35\1\0"+ + "\4\35\1\0\1\35\1\0\1\35\4\0\1\123\4\35"+ + "\12\0\1\u0101\64\0\1\325\66\0\1\65\32\0\4\35"+ + "\1\132\14\35\1\0\4\35\1\0\1\35\1\0\1\35"+ + "\4\0\1\123\4\35\2\0"; private static int [] zzUnpackTrans() { - int [] result = new int[11660]; + int [] result = new int[12600]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -373,17 +380,17 @@ private static int zzUnpackTrans(String packed, int offset, int [] result) { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\5\0\1\11\1\1\1\11\14\1\2\11\31\1\1\0"+ - "\1\11\1\1\21\0\1\1\6\0\1\11\1\1\1\0"+ - "\1\11\1\1\1\0\13\1\7\0\2\1\11\0\1\11"+ - "\1\1\4\0\1\1\3\0\1\1\25\0\10\1\10\0"+ - "\2\1\11\0\1\1\2\0\1\1\1\11\1\1\1\0"+ - "\1\1\16\0\4\1\7\0\2\1\14\0\1\11\16\0"+ - "\3\1\6\0\1\11\12\0\1\1\7\0\1\1\15\0"+ - "\2\1\7\0\1\1\2\0\1\1"; + "\5\0\1\11\2\1\1\11\14\1\2\11\31\1\1\0"+ + "\1\11\1\1\22\0\1\1\6\0\1\11\1\1\1\0"+ + "\1\11\1\0\1\1\1\0\13\1\7\0\2\1\12\0"+ + "\1\11\1\1\4\0\1\1\4\0\1\1\25\0\10\1"+ + "\10\0\2\1\12\0\1\1\2\0\1\1\1\11\1\1"+ + "\2\0\1\1\16\0\4\1\7\0\1\1\1\0\1\1"+ + "\14\0\1\11\17\0\3\1\6\0\1\11\14\0\1\1"+ + "\7\0\1\1\17\0\2\1\10\0\1\1\3\0\1\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[285]; + int [] result = new int[300]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -577,7 +584,7 @@ public LatteMarkupColoringLexer(java.io.InputStream in) { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 172) { + while (i < 176) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -860,19 +867,21 @@ public LatteMarkupTokenId findNextToken() throws java.io.IOException { } case 36: break; default: - if (zzInput == YYEOF) //zzAtEOF = true; - { - if (input.readLength() > 0) { - // backup eof - input.backup(1); - //and return the text as error token - return LatteMarkupTokenId.T_ERROR; - } else { - return null; - } - } else { - zzScanError(ZZ_NO_MATCH); - } + if (zzInput == YYEOF) + //zzAtEOF = true; + { if(input.readLength() > 0) { + // backup eof + input.backup(1); + //and return the text as error token + return LatteMarkupTokenId.T_ERROR; + } else { + return null; + } + } + + else { + zzScanError(ZZ_NO_MATCH); + } } } } diff --git a/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest/testIssueGH5862_01.pass b/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest/testIssueGH5862_01.pass new file mode 100644 index 000000000000..efb1850ed89e --- /dev/null +++ b/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest/testIssueGH5862_01.pass @@ -0,0 +1,2 @@ +token #0 T_MACRO_START [_] +token #1 T_STRING ['escase \' quote'] diff --git a/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest/testIssueGH5862_01.pass b/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest/testIssueGH5862_01.pass new file mode 100644 index 000000000000..766e901fa869 --- /dev/null +++ b/php/php.latte/test/unit/data/goldenfiles/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest/testIssueGH5862_01.pass @@ -0,0 +1,37 @@ +token #0 T_LATTE_COMMENT_DELIMITER [{*] +token #1 T_LATTE_COMMENT [\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * "License"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n ] +token #2 T_LATTE_COMMENT_DELIMITER [*}] +token #3 T_HTML [\n\n

] +token #4 T_LATTE_OPEN_DELIMITER [{] +token #5 T_LATTE [_'test escaped \' quote'] +token #6 T_LATTE_CLOSE_DELIMITER [}] +token #7 T_HTML [

\n

] +token #8 T_LATTE_OPEN_DELIMITER [{] +token #9 T_LATTE [_] +token #10 T_LATTE_CLOSE_DELIMITER [}] +token #11 T_HTML [text] +token #12 T_LATTE_OPEN_DELIMITER [{] +token #13 T_LATTE [/_] +token #14 T_LATTE_CLOSE_DELIMITER [}] +token #15 T_HTML [

\n] +token #16 T_LATTE_OPEN_DELIMITER [{] +token #17 T_LATTE [_$test] +token #18 T_LATTE_CLOSE_DELIMITER [}] +token #19 T_HTML [\nTest\n\n

] +token #22 T_LATTE_OPEN_DELIMITER [{] +token #23 T_LATTE [translate] +token #24 T_LATTE_CLOSE_DELIMITER [}] +token #25 T_HTML [test] +token #26 T_LATTE_OPEN_DELIMITER [{] +token #27 T_LATTE [/translate] +token #28 T_LATTE_CLOSE_DELIMITER [}] +token #29 T_HTML [

\n] +token #30 T_LATTE_OPEN_DELIMITER [{] +token #31 T_LATTE [translate domain: order] +token #32 T_LATTE_CLOSE_DELIMITER [}] +token #33 T_HTML [test ...] +token #34 T_LATTE_OPEN_DELIMITER [{] +token #35 T_LATTE [/translate] +token #36 T_LATTE_CLOSE_DELIMITER [}] diff --git a/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_02.testIssueGH5862_02.braces b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_02.testIssueGH5862_02.braces new file mode 100644 index 000000000000..8678c6e99809 --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_02.testIssueGH5862_02.braces @@ -0,0 +1,3 @@ + +

{*tr^anslate*}Test{*/translate*}

+ \ No newline at end of file diff --git a/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_03.testIssueGH5862_03.braces b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_03.testIssueGH5862_03.braces new file mode 100644 index 000000000000..d9740ab9163d --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_03.testIssueGH5862_03.braces @@ -0,0 +1,3 @@ + +

{*translate*}Test{*/transl^ate*}

+ \ No newline at end of file diff --git a/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_04.testIssueGH5862_04.braces b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_04.testIssueGH5862_04.braces new file mode 100644 index 000000000000..4502aab38fb8 --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_04.testIssueGH5862_04.braces @@ -0,0 +1,3 @@ + +

{*transl^ate* domain: order}Test{*/translate*}

+ \ No newline at end of file diff --git a/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_05.testIssueGH5862_05.braces b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_05.testIssueGH5862_05.braces new file mode 100644 index 000000000000..235d54aefe43 --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/braces/testIssueGH5862_05.testIssueGH5862_05.braces @@ -0,0 +1,3 @@ + +

{*translate* domain: order}Test{*/transla^te*}

+ \ No newline at end of file diff --git a/php/php.latte/test/unit/data/testfiles/lexer/markup/testIssueGH5862_01.latte-markup b/php/php.latte/test/unit/data/testfiles/lexer/markup/testIssueGH5862_01.latte-markup new file mode 100644 index 000000000000..2e3163dc3702 --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/lexer/markup/testIssueGH5862_01.latte-markup @@ -0,0 +1 @@ +_'escase \' quote' \ No newline at end of file diff --git a/php/php.latte/test/unit/data/testfiles/lexer/top/testIssueGH5862_01.latte b/php/php.latte/test/unit/data/testfiles/lexer/top/testIssueGH5862_01.latte new file mode 100644 index 000000000000..02bcc2c4c515 --- /dev/null +++ b/php/php.latte/test/unit/data/testfiles/lexer/top/testIssueGH5862_01.latte @@ -0,0 +1,26 @@ +{* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *} + +

{_'test escaped \' quote'}

+

{_}text{/_}

+{_$test} +Test + +

{translate}test{/translate}

+{translate domain: order}test ...{/translate} diff --git a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcherTest.java b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcherTest.java index 4dda9818d27b..c5b9f74515ad 100644 --- a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcherTest.java +++ b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/braces/LatteBracesMatcherTest.java @@ -503,7 +503,53 @@ public void testNested_10() throws Exception { + ""); } + public void testIssueGH5862_01() throws Exception { + // no golden file + testMatches("\n" + + "

{^_'test'}

\n" + + "", + true + ); + } + + public void testIssueGH5862_02() throws Exception { + testMatches("\n" + + "

{tr^anslate}Test{/translate}

\n" + + ""); + } + + public void testIssueGH5862_03() throws Exception { + testMatches("\n" + + "

{translate}Test{/transl^ate}

\n" + + ""); + } + + public void testIssueGH5862_04() throws Exception { + testMatches("\n" + + "

{transl^ate domain: order}Test{/translate}

\n" + + ""); + } + + public void testIssueGH5862_05() throws Exception { + testMatches("\n" + + "

{translate domain: order}Test{/transla^te}

\n" + + ""); + } + + public void testIssueGH5862_06() throws Exception { + // no goleden file + testMatches("\n" + + "

{translate dom^ain: order}Test{/translate}

\n" + + "", + true + ); + } + private void testMatches(String originalWithCaret) throws Exception { + testMatches(originalWithCaret, false); + } + + private void testMatches(String originalWithCaret, boolean notFoundOrigin) throws Exception { BracesMatcherFactory factory = MimeLookup.getLookup(getPreferredMimeType()).lookup(BracesMatcherFactory.class); int caretPosition = originalWithCaret.indexOf('^'); assert caretPosition != -1; @@ -519,6 +565,9 @@ private void testMatches(String originalWithCaret) throws Exception { matches = matcher.findMatches(); } catch (InterruptedException ex) { } + if (notFoundOrigin && origin == null) { + return; + } assertNotNull("Did not find origin", origin); assertEquals("Wrong origin length", 2, origin.length); diff --git a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest.java b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest.java index aad4475785af..2699dea226e2 100644 --- a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest.java +++ b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteMarkupLexerTest.java @@ -46,6 +46,10 @@ public void testIssue2340146_03() throws Exception { performTest("testIssue2340146_03"); } + public void testIssueGH5862_01() throws Exception { + performTest("testIssueGH5862_01"); + } + @Override protected String getTestResult(String filename) throws Exception { String content = TestUtils.getFileContent(new File(getDataDir(), "testfiles/lexer/markup/" + filename + ".latte-markup")); diff --git a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest.java b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest.java index 5001d3aa8f02..97c80518c8ac 100644 --- a/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest.java +++ b/php/php.latte/test/unit/src/org/netbeans/modules/php/latte/lexer/LatteTopLexerTest.java @@ -139,6 +139,10 @@ public void testIssue246488() throws Exception { performTest("testIssue246488"); } + public void testIssueGH5862_01() throws Exception { + performTest("testIssueGH5862_01"); + } + @Override protected String getTestResult(String filename) throws Exception { String content = TestUtils.getFileContent(new File(getDataDir(), "testfiles/lexer/top/" + filename + ".latte")); diff --git a/php/php.latte/tools/LatteMarkupColoringLexer.flex b/php/php.latte/tools/LatteMarkupColoringLexer.flex index 6695ca675880..c4f44fe366e5 100644 --- a/php/php.latte/tools/LatteMarkupColoringLexer.flex +++ b/php/php.latte/tools/LatteMarkupColoringLexer.flex @@ -147,7 +147,7 @@ WHITESPACE=[ \t\r\n]+ D_STRING_START="\""([^"\"""{"])* D_STRING_END=([^"\"""$"] | "$}")*"\"" D_STRING="\""([^"\""])*"\"" -S_STRING="'"([^"'"])*"'" +S_STRING="'"([^'\\]|("\\"[^]))*"'" KEYWORD="true"|"false"|"null"|"and"|"or"|"xor"|"clone"|"new"|"instanceof"|"return"|"continue"|"break" CAST="(" ("expand"|"string"|"array"|"int"|"integer"|"float"|"bool"|"boolean"|"object") ")" VARIABLE="$"[a-zA-Z0-9_]+ @@ -158,9 +158,9 @@ SYMBOL=[a-zA-Z0-9_]+(\-[a-zA-Z0-9_]+)* MACRO="if" | "elseif" | "else" | "ifset" | "elseifset" | "ifCurrent" | "for" | "foreach" | "while" | "first" | "last" | "sep" | "capture" | "cache" | "syntax" | "_" | "block" | "form" | "label" | "snippet" | "continueIf" | "breakIf" | "var" | "default" | "include" | "use" | "l" | "r" | "contentType" | "status" | "define" | "includeblock" | "layout" | "extends" | "link" | "plink" | - "control" | "input" | "dump" | "debugbreak" | "widget" + "control" | "input" | "dump" | "debugbreak" | "widget" | "translate" END_MACRO="if" | "ifset" | "ifCurrent" | "for" | "foreach" | "while" | "first" | "last" | "sep" | "capture" | "cache" | - "syntax" | "_" | "block" | "form" | "label" | "snippet" | "define" + "syntax" | "_" | "block" | "form" | "label" | "snippet" | "define" | "translate" %state ST_OTHER